optimize whole environment

This commit is contained in:
2025-06-02 18:13:18 +09:00
parent 4fbf2a4e81
commit 3f85eb8338
15 changed files with 578 additions and 483 deletions

23
.cspell.json Normal file
View File

@ -0,0 +1,23 @@
{
"version": "0.2",
"language": "en,en-gb",
"ignoreWords": [],
"words": [
"blankspace",
"docxtemplater",
"Heiti",
"Kaku",
"kintone",
"kintoneplugin",
"kypes",
"Ligh",
"moize",
"officedocument",
"openxmlformats",
"pizzip",
"rspack",
"SUBTABLE",
"wordprocessingml"
],
"ignorePaths": [".env"]
}

View File

@ -1,3 +1,8 @@
{
"recommendations": ["esbenp.prettier-vscode"]
"recommendations": [
"esbenp.prettier-vscode",
"streetsidesoftware.code-spell-checker",
"dbaeumer.vscode-eslint",
"jawandarajbir.react-vscode-extension-pack"
]
}

View File

@ -27,6 +27,8 @@
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
// Exteions - cSpell
// - see: .cspell.json
// Extensions - HTML
"html.format.wrapLineLength": 0,
// Extentions - Prettier

View File

@ -1,4 +1,17 @@
import presetsPrettier from "@cybozu/eslint-config/flat/presets/react-typescript-prettier.js";
import presetsPrettier from '@cybozu/eslint-config/flat/presets/react-typescript-prettier.js';
import globals from 'globals';
/** @type {import("eslint").Linter.Config[]} */
export default [...presetsPrettier];
export default [
...presetsPrettier,
{
languageOptions: {
globals: {
...globals.node,
},
},
rules: {
'spaced-comment': ['error', 'always', { markers: ['/'] }],
},
},
];

901
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
"upload": "env-cmd --silent kintone-plugin-uploader dist/plugin.zip --watch --waiting-dialog-ms 3000"
},
"dependencies": {
"@kintone/rest-api-client": "^5.7.3",
"@kintone/rest-api-client": "^5.7.4",
"angular-expressions": "^1.4.3",
"clsx": "^2.1.1",
"dayjs": "^1.11.13",
@ -42,6 +42,7 @@
"env-cmd": "^10.1.0",
"eslint": "^9.28.0",
"eslint-plugin-react": "^7.37.5",
"globals": "^16.2.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.5.3",
"style-loader": "^4.0.0",

View File

@ -20,7 +20,7 @@
"ja": "Word出力プラグイン"
},
"description": {
"en": "Data can be formatted and downloaded using WORD template files.",
"ja": "WORDテンプレートファイルを使用して、データを整形してダウンロードできます。"
"en": "Data can be formatted and downloaded using Word template files.",
"ja": "Wordテンプレートファイルを使用して、データを整形してダウンロードできます。"
}
}

View File

@ -4,12 +4,15 @@
const fs = require('fs');
const RSA = require('node-rsa');
const key = new RSA({ b: 1024 });
const privateKey = key.exportKey('pkcs1-private');
const privateKeyFile = './private.ppk';
if (!fs.existsSync(privateKeyFile)) {
const key = new RSA({ b: 1024 });
const privateKey = key.exportKey('pkcs1-private');
fs.writeFile(privateKeyFile, privateKey, (err) => {
err && console.error(err);
if (err) {
console.error(err);
process.exitCode = 1;
}
});
}

View File

@ -11,5 +11,4 @@ invariant(
`Unsupported language: ${LANGUAGE}. Supported languages are: ${KintoneUserLanguages.join(', ')}`,
);
export const DOCX_CONTENTTYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
export const DOCX_EXTENSION = 'docx';
export const DOCX_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';

View File

@ -65,7 +65,7 @@ const Settings: React.FC = () => {
<KintonePluginTitle>
Template<KintonePluginRequire>*</KintonePluginRequire>
</KintonePluginTitle>
<KintonePluginDesc>Select a file field that contains the WORD template file.</KintonePluginDesc>
<KintonePluginDesc>Select a file field that contains the Word template file.</KintonePluginDesc>
{fileFields.length === 0 ? (
<KintonePluginAlert>
No file fields found in the app. Please add a file field to use this plugin.

45
src/declaration.d.ts vendored
View File

@ -1,45 +0,0 @@
// CSS modules
type CSSModuleClasses = { readonly [key: string]: string };
declare module '*.module.css' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.scss' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.sass' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.less' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.styl' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.stylus' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.pcss' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.sss' {
const classes: CSSModuleClasses;
export default classes;
}
// CSS
declare module '*.css' {}
declare module '*.scss' {}
declare module '*.sass' {}
declare module '*.less' {}
declare module '*.styl' {}
declare module '*.stylus' {}
declare module '*.pcss' {}
declare module '*.sss' {}

View File

@ -5,8 +5,6 @@ import ErrorFallback from '../common/ErrorFallback';
import Loading from '../common/Loading';
import MenuPanel from './MenuPanel';
import '@shin-chan/kypes';
interface DesktopAppProps {
event: kintone.events.AppRecordDetailShowEvent | kintone.events.MobileAppRecordDetailShowEvent;
}

View File

@ -10,12 +10,10 @@ import { saveAs } from 'file-saver';
import moize from 'moize';
import PizZip from 'pizzip';
import invariant from 'tiny-invariant';
import { DOCX_CONTENTTYPE, LANGUAGE, PLUGIN_ID } from '../common/global';
import { DOCX_CONTENT_TYPE, LANGUAGE, PLUGIN_ID } from '../common/global';
import KintonePluginAlert from '../common/ui/KintonePluginAlert';
import KintonePluginButton from '../common/ui/KintonePluginButton';
import '@shin-chan/kypes';
interface TemplateData {
[key: string]: TemplateData | TemplateData[] | string | string[];
}
@ -191,32 +189,32 @@ const MenuPanel: React.FC<MenuPanelProps> = (props) => {
if (template === '') {
return (
<KintonePluginAlert>
WORD output plugin: Template field is not set. Please configure the plugin.
Word output plugin: Template field is not set. Please configure the plugin.
</KintonePluginAlert>
);
}
const record = event.record[template];
if (record == null) {
return <KintonePluginAlert>WORD output plugin: Template field is not available in this app.</KintonePluginAlert>;
return <KintonePluginAlert>Word output plugin: Template field is not available in this app.</KintonePluginAlert>;
}
if (record.type !== 'FILE') {
return <KintonePluginAlert>WORD output plugin: Template field must be a file field.</KintonePluginAlert>;
return <KintonePluginAlert>Word output plugin: Template field must be a file field.</KintonePluginAlert>;
}
if (record.value.length === 0) {
return <KintonePluginAlert>WORD output plugin: Template field does not contain any files.</KintonePluginAlert>;
return <KintonePluginAlert>Word output plugin: Template field does not contain any files.</KintonePluginAlert>;
}
if (record.value.length > 1) {
return (
<KintonePluginAlert>
WORD output plugin: Template field contains multiple files. Please ensure it contains only one file.
Word output plugin: Template field contains multiple files. Please ensure it contains only one file.
</KintonePluginAlert>
);
}
const { fileKey, contentType } = record.value[0];
if (contentType !== DOCX_CONTENTTYPE) {
if (contentType !== DOCX_CONTENT_TYPE) {
return (
<KintonePluginAlert>
WORD output plugin: The template file must be a DOCX file. The current file type is {contentType}.
Word output plugin: The template file must be a DOCX file. The current file type is {contentType}.
</KintonePluginAlert>
);
}
@ -233,18 +231,18 @@ const MenuPanel: React.FC<MenuPanelProps> = (props) => {
parser: expressionParser,
});
doc.render(record2data(properties, event.record));
const out = doc.getZip().generate({ type: 'blob', mimeType: DOCX_CONTENTTYPE });
const out = doc.getZip().generate({ type: 'blob', mimeType: DOCX_CONTENT_TYPE });
saveAs(out, 'output.docx');
})
.catch((error) => {
console.error('Error downloading file:', error);
alert('Failed to download the WORD template file.');
alert('Failed to download the Word template file.');
});
};
return (
<KintonePluginButton variant="normal" onClick={handleOnClickOutputButton}>
WORD出力
Word出力
</KintonePluginButton>
);
};

View File

@ -4,8 +4,6 @@ import ReactDOM from 'react-dom/client';
import invariant from 'tiny-invariant';
import DesktopApp from './DesktopApp';
import '@shin-chan/kypes';
import '../common/ui/51-modern-default.css';
kintone.events.on(

17
src/kintone-env.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
/// <reference types="@shin-chan/kypes" />
// CSS modules
type CSSModuleClasses = { readonly [key: string]: string };
declare module '*.module.css' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.scss' {
const classes: CSSModuleClasses;
export default classes;
}
// CSS
declare module '*.css' {}
declare module '*.scss' {}