@konomi-app/k2 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ import { outputManifest } from '../../lib/plugin-manifest.js';
2
+ export const getManifest = async (params) => {
3
+ const { config, port } = params;
4
+ return outputManifest('dev', {
5
+ config: {
6
+ ...config,
7
+ manifest: {
8
+ ...config.manifest,
9
+ dev: {
10
+ config: {
11
+ ...config.manifest?.dev?.config,
12
+ js: [`https://localhost:${port}/config.js`],
13
+ css: [`https://localhost:${port}/config.css`],
14
+ },
15
+ desktop: {
16
+ ...config.manifest?.dev?.desktop,
17
+ js: [`https://localhost:${port}/desktop.js`],
18
+ css: [`https://localhost:${port}/desktop.css`],
19
+ },
20
+ mobile: {
21
+ ...config.manifest?.dev?.mobile,
22
+ js: [`https://localhost:${port}/desktop.js`],
23
+ css: [`https://localhost:${port}/desktop.css`],
24
+ },
25
+ },
26
+ },
27
+ },
28
+ });
29
+ };
@@ -0,0 +1,44 @@
1
+ import { program } from 'commander';
2
+ import { importPluginConfig } from '../../lib/import.js';
3
+ import path from 'path';
4
+ import { DEFAULT_PORT, PLUGIN_DEVELOPMENT_DIRECTORY, PLUGIN_WORKSPACE_DIRECTORY, } from '../../lib/constants.js';
5
+ import base from '../dev-base-esbuild.js';
6
+ import { getManifest } from './create-manifest.js';
7
+ import { watchContentsAndUploadZip } from './upload.js';
8
+ import { watchCss } from './tailwind.js';
9
+ export default function command() {
10
+ program
11
+ .command('dev')
12
+ .option('-p, --ppk <ppk>', '.ppk file path', path.join(PLUGIN_WORKSPACE_DIRECTORY, 'private.ppk'))
13
+ .description('Start development server.')
14
+ .action(action);
15
+ }
16
+ export async function action(options) {
17
+ console.group('🍳 Start development server');
18
+ try {
19
+ const { ppk: ppkPath } = options;
20
+ const config = await importPluginConfig();
21
+ const port = config.server?.port ?? DEFAULT_PORT;
22
+ const manifest = await getManifest({ config, port });
23
+ console.log(`📝 manifest.json generated`);
24
+ Promise.all([watchContentsAndUploadZip({ manifest, ppkPath }), watchCss(config), build(port)]);
25
+ }
26
+ catch (error) {
27
+ throw error;
28
+ }
29
+ finally {
30
+ console.groupEnd();
31
+ }
32
+ }
33
+ async function build(port) {
34
+ const entryPoints = ['desktop', 'config'].map((dir) => ({
35
+ in: path.join('src', dir, 'index.ts'),
36
+ out: dir,
37
+ }));
38
+ base({
39
+ port,
40
+ entryPoints,
41
+ certDir: PLUGIN_WORKSPACE_DIRECTORY,
42
+ staticDir: PLUGIN_DEVELOPMENT_DIRECTORY,
43
+ });
44
+ }
@@ -0,0 +1,67 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import postcss from 'postcss';
4
+ import tailwindcss from 'tailwindcss';
5
+ import { PLUGIN_DEVELOPMENT_DIRECTORY } from '../../lib/constants.js';
6
+ import { esmImport } from '../../lib/import.js';
7
+ import chokidar from 'chokidar';
8
+ import chalk from 'chalk';
9
+ async function buildTailwindCSS(params) {
10
+ const { inputFile, outputFileName, config } = params;
11
+ const inputPath = path.resolve(inputFile);
12
+ const outputPath = path.join(PLUGIN_DEVELOPMENT_DIRECTORY, outputFileName);
13
+ const css = await fs.readFile(inputPath, 'utf8');
14
+ const watcher = chokidar.watch([...(config.content ?? ['./src/**/*.{ts,tsx}']), inputPath], {
15
+ ignored: /node_modules/,
16
+ persistent: true,
17
+ awaitWriteFinish: {
18
+ stabilityThreshold: 2000,
19
+ pollInterval: 100,
20
+ },
21
+ });
22
+ let initialScanComplete = false;
23
+ const listener = async (type, path) => {
24
+ try {
25
+ if (type === 'add' && !initialScanComplete) {
26
+ return;
27
+ }
28
+ const result = await postcss([tailwindcss(config)]).process(css, {
29
+ from: inputPath,
30
+ to: outputPath,
31
+ });
32
+ await fs.writeFile(outputPath, result.css);
33
+ if (result.map) {
34
+ await fs.writeFile(`${outputPath}.map`, result.map.toString());
35
+ }
36
+ console.log(chalk.hex('#e5e7eb')(`${new Date().toLocaleTimeString()} `) +
37
+ chalk.cyan(`[css] `) +
38
+ outputFileName +
39
+ (type === 'init' ? ' init' : ` rebuilt`));
40
+ }
41
+ catch (error) {
42
+ console.error('Error building Tailwind CSS:', error);
43
+ }
44
+ };
45
+ await listener('init');
46
+ watcher.on('ready', () => {
47
+ initialScanComplete = true;
48
+ });
49
+ watcher.on('change', (path) => listener('change', path));
50
+ watcher.on('add', (path) => listener('add', path));
51
+ watcher.on('unlink', () => listener('unlink'));
52
+ }
53
+ export const watchCss = async (pluginConfig) => {
54
+ if (!pluginConfig.tailwind?.css || !pluginConfig.tailwind?.config) {
55
+ return;
56
+ }
57
+ const { css, config: configPath } = pluginConfig.tailwind;
58
+ const configPathForDesktop = typeof configPath === 'string' ? configPath : configPath.desktop;
59
+ const configPathForConfig = typeof configPath === 'string' ? configPath : configPath.config;
60
+ const desktopConfig = (await esmImport(path.resolve(configPathForDesktop))).default;
61
+ const configConfig = (await esmImport(path.resolve(configPathForConfig))).default;
62
+ const inputFile = path.resolve(css);
63
+ return Promise.all([
64
+ buildTailwindCSS({ inputFile, outputFileName: 'desktop.css', config: desktopConfig }),
65
+ buildTailwindCSS({ inputFile, outputFileName: 'config.css', config: configConfig }),
66
+ ]);
67
+ };
@@ -0,0 +1,50 @@
1
+ import packer from '@kintone/plugin-packer';
2
+ import { copyPluginContents } from '../../lib/plugin-contents.js';
3
+ import { getContentsZipBuffer, getZipFileNameSuffix, outputContentsZip } from '../../lib/zip.js';
4
+ import fs from 'fs-extra';
5
+ import path from 'path';
6
+ import { PLUGIN_WORKSPACE_DIRECTORY } from '../../lib/constants.js';
7
+ import { uploadZip } from '../../lib/utils.js';
8
+ import chokider from 'chokidar';
9
+ import chalk from 'chalk';
10
+ export const watchContentsAndUploadZip = async (params) => {
11
+ const { manifest, ppkPath } = params;
12
+ let initialScanComplete = false;
13
+ const contentsListener = async () => {
14
+ try {
15
+ if (!initialScanComplete) {
16
+ return;
17
+ }
18
+ await copyPluginContents();
19
+ console.log(chalk.hex('#e5e7eb')(`${new Date().toLocaleTimeString()} `) +
20
+ chalk.cyan(`[contents] `) +
21
+ `updated`);
22
+ }
23
+ catch (error) {
24
+ console.error('Error copying plugin contents:', error);
25
+ return;
26
+ }
27
+ await outputContentsZip(manifest);
28
+ const buffer = await getContentsZipBuffer();
29
+ const pluginPrivateKey = await fs.readFile(path.resolve(ppkPath), 'utf8');
30
+ const output = await packer(buffer, pluginPrivateKey);
31
+ const zipFileName = `plugin${getZipFileNameSuffix('dev')}.zip`;
32
+ await fs.writeFile(path.join(PLUGIN_WORKSPACE_DIRECTORY, zipFileName), output.plugin);
33
+ console.log(chalk.hex('#e5e7eb')(`${new Date().toLocaleTimeString()} `) +
34
+ chalk.cyan(`[upload] `) +
35
+ `start uploading`);
36
+ await uploadZip('dev');
37
+ console.log(chalk.hex('#e5e7eb')(`${new Date().toLocaleTimeString()} `) + chalk.cyan(`[upload] `) + `done`);
38
+ };
39
+ const contentsWatcher = chokider.watch(['src/contents/**/*'], {
40
+ ignored: /node_modules/,
41
+ persistent: true,
42
+ });
43
+ contentsWatcher.on('ready', () => {
44
+ initialScanComplete = true;
45
+ contentsListener();
46
+ });
47
+ contentsWatcher.on('change', contentsListener);
48
+ contentsWatcher.on('add', contentsListener);
49
+ contentsWatcher.on('unlink', contentsListener);
50
+ };
@@ -2,10 +2,10 @@ import { program } from 'commander';
2
2
  import fs from 'fs-extra';
3
3
  import path from 'path';
4
4
  import packer from '@kintone/plugin-packer';
5
- import { outputManifest } from '../../lib/plugin-manifest.js';
6
- import { PLUGIN_WORKSPACE_DIRECTORY } from '../../lib/constants.js';
7
- import { getContentsZipBuffer, outputContentsZip } from '../../lib/zip.js';
8
- import { copyPluginContents } from '../../lib/plugin-contents.js';
5
+ import { outputManifest } from '../lib/plugin-manifest.js';
6
+ import { PLUGIN_WORKSPACE_DIRECTORY } from '../lib/constants.js';
7
+ import { getContentsZipBuffer, outputContentsZip } from '../lib/zip.js';
8
+ import { copyPluginContents } from '../lib/plugin-contents.js';
9
9
  export default function command() {
10
10
  program.command('init').description('generate private.ppk and kitting config').action(action);
11
11
  }
@@ -26,10 +26,10 @@ export async function action() {
26
26
  const output = await packer(buffer, privateKey);
27
27
  if (!privateKey) {
28
28
  await fs.writeFile(path.join(PLUGIN_WORKSPACE_DIRECTORY, 'private.ppk'), output.privateKey);
29
- console.log('🔐 private.ppk generated');
29
+ console.log('🔑 private.ppk generated');
30
30
  }
31
31
  else {
32
- console.log('🔐 private.ppk already exists. The existing private.ppk will be used.');
32
+ console.log('🔑 private.ppk already exists. The existing private.ppk will be used.');
33
33
  }
34
34
  await fs.writeFile(path.join(PLUGIN_WORKSPACE_DIRECTORY, 'plugin.zip'), output.plugin);
35
35
  console.log('📦 plugin.zip generated');
@@ -43,9 +43,9 @@ export const getEsbuildContext = async (params) => {
43
43
  plugins: [
44
44
  {
45
45
  name: 'on-end',
46
- setup: ({ onEnd }) => onEnd(() => console.log(chalk.hex('#d1d5db')(`${new Date().toLocaleTimeString()} `) +
47
- chalk.cyan(`[content] `) +
48
- `Compiled successfully.`)),
46
+ setup: ({ onEnd }) => onEnd(() => console.log(chalk.hex('#e5e7eb')(`${new Date().toLocaleTimeString()} `) +
47
+ chalk.cyan(`[js] `) +
48
+ `rebuilt`)),
49
49
  },
50
50
  getSassPlugin(),
51
51
  ],
package/dist/lib/utils.js CHANGED
@@ -20,6 +20,5 @@ KINTONE_PASSWORD
20
20
  if (KINTONE_BASIC_AUTH_USERNAME && KINTONE_BASIC_AUTH_PASSWORD) {
21
21
  command += ` --basic-auth-username ${KINTONE_BASIC_AUTH_USERNAME} --basic-auth-password ${KINTONE_BASIC_AUTH_PASSWORD}`;
22
22
  }
23
- command += ' --watch --waiting-dialog-ms 3000';
24
23
  return exec(command);
25
24
  };
package/dist/plugin.js CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { program } from 'commander';
3
3
  import build from './commands/plugin-build.js';
4
- import dev from './commands/plugin-dev.js';
4
+ import dev from './commands/plugin-dev/index.js';
5
5
  import genkey from './commands/plugin-genkey.js';
6
- import init from './commands/init/index.js';
6
+ import init from './commands/plugin-init.js';
7
7
  import manifest from './commands/manifest/index.js';
8
8
  import test from './commands/test/index.js';
9
9
  import upload from './commands/upload/index.js';
10
10
  import zip from './commands/plugin-zip.js';
11
- program.name('plugin').version('0.0.1').description('');
11
+ program.name('plugin').version('0.7.0').description('');
12
12
  build();
13
13
  dev();
14
14
  genkey();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konomi-app/k2",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "kintone sdk",
5
5
  "main": "./dist/index.js",
6
6
  "type": "module",
@@ -37,9 +37,11 @@
37
37
  "fs-extra": "^11",
38
38
  "html-minifier": "^4",
39
39
  "mini-css-extract-plugin": "^2",
40
+ "postcss": "^8.4.38",
40
41
  "sass": "^1",
41
42
  "sass-loader": "^14",
42
43
  "style-loader": "^4",
44
+ "tailwindcss": "^3.4.4",
43
45
  "terser-webpack-plugin": "^5",
44
46
  "ts-loader": "^9",
45
47
  "tsconfig-paths-webpack-plugin": "^4",
@@ -54,4 +56,4 @@
54
56
  "@types/html-minifier": "^4",
55
57
  "typescript": "*"
56
58
  }
57
- }
59
+ }
package/types/k2.d.ts CHANGED
@@ -23,8 +23,6 @@ type Resources = {
23
23
  };
24
24
 
25
25
  declare namespace K2 {
26
- type Env = 'dev' | 'prod' | 'standalone';
27
-
28
26
  /**
29
27
  * 公開しているプラグインテンプレートで使用する設定ファイル
30
28
  */
package/types/plugin.d.ts CHANGED
@@ -64,12 +64,32 @@ declare namespace Plugin {
64
64
  * @see {@link https://github.com/local-bias/kintone-plugin-template | kintone-plugin-template}
65
65
  */
66
66
  type Config = {
67
+ /** 一意となるプラグインID */
67
68
  id: string;
69
+ /**
70
+ * プラグインのバージョン
71
+ * この設定ファイルの互換性の管理に使用されます
72
+ */
68
73
  version?: 1;
74
+ /**
75
+ * プラグインのmanifest.jsonの設定
76
+ *
77
+ * `base`プロパティを基準として、環境ごとに`dev`、`prod`、`standalone`のプロパティを上書きする形でマージされます
78
+ *
79
+ * - `dev` - 開発環境の設定
80
+ * - `prod` - 本番環境での設定
81
+ * - `standalone` - スタンドアロン環境での設定
82
+ *
83
+ * @see {@link https://cybozu.dev/ja/kintone/tips/development/plugins/development-plugin/development-kintone-plugin/#manifest | マニフェストファイルの作成}
84
+ */
69
85
  manifest: {
86
+ /** プラグインの基本設定 */
70
87
  base: Manifest;
88
+ /** 開発環境のmanifest.json */
71
89
  dev?: Partial<Manifest>;
90
+ /** 本番環境のmanifest.json */
72
91
  prod?: Partial<Manifest>;
92
+ /** スタンドアロン環境のmanifest.json */
73
93
  standalone?: Partial<Manifest>;
74
94
  };
75
95
  pluginReleasePageUrl?: string;
@@ -81,6 +101,35 @@ declare namespace Plugin {
81
101
  /** 0から65535までのポート番号 */
82
102
  port?: number;
83
103
  };
104
+ /**
105
+ * tailwindcssを使用している場合、設定ファイルのパスとCSSファイルのパスを指定することで、JavaScriptファイルのビルド時にCSSファイルを生成します
106
+ *
107
+ * @see {@link https://tailwindcss.com/docs/installation | Tailwind CSS}
108
+ * @example
109
+ * ```json
110
+ * // 共通の設定ファイルを使用する場合
111
+ * {
112
+ * "tailwind": {
113
+ * "config": "tailwind.config.js",
114
+ * "css": "src/styles/tailwind.css"
115
+ * }
116
+ *
117
+ * // 設定ファイルをプラグイン設定画面、アプリで分ける場合
118
+ * {
119
+ * "tailwind": {
120
+ * "config": {
121
+ * "config": "tailwind.config.js",
122
+ * "desktop": "src/styles/tailwind-desktop.css"
123
+ * },
124
+ * "css": "src/styles/tailwind-mobile.css"
125
+ * }
126
+ * ```
127
+ */
128
+ tailwind?: {
129
+ config?: string | { config: string; desktop: string };
130
+ /** CSSファイルのパス */
131
+ css?: string;
132
+ };
84
133
  };
85
134
  }
86
135
  }
@@ -1,98 +0,0 @@
1
- import { program } from 'commander';
2
- import { importPluginConfig } from '../lib/import.js';
3
- import path from 'path';
4
- import { DEFAULT_PORT, PLUGIN_DEVELOPMENT_DIRECTORY, PLUGIN_WORKSPACE_DIRECTORY, } from '../lib/constants.js';
5
- import fs from 'fs-extra';
6
- import { outputManifest } from '../lib/plugin-manifest.js';
7
- import { copyPluginContents } from '../lib/plugin-contents.js';
8
- import chokider from 'chokidar';
9
- import { getContentsZipBuffer, getZipFileNameSuffix, outputContentsZip } from '../lib/zip.js';
10
- import packer from '@kintone/plugin-packer';
11
- import { uploadZip } from '../lib/utils.js';
12
- import base from './dev-base-esbuild.js';
13
- export default function command() {
14
- program
15
- .command('dev')
16
- .option('-p, --ppk <ppk>', '.ppk file path', path.join(PLUGIN_WORKSPACE_DIRECTORY, 'private.ppk'))
17
- .description('Start development server.')
18
- .action(action);
19
- }
20
- export async function action(options) {
21
- console.group('🍳 Start development server');
22
- try {
23
- const { ppk: ppkPath } = options;
24
- const config = await importPluginConfig();
25
- const port = config.server?.port ?? DEFAULT_PORT;
26
- const manifest = await outputManifest('dev', {
27
- config: {
28
- ...config,
29
- manifest: {
30
- ...config.manifest,
31
- dev: {
32
- config: {
33
- ...config.manifest?.dev?.config,
34
- js: [`https://localhost:${port}/config.js`],
35
- css: [`https://localhost:${port}/config.css`],
36
- },
37
- desktop: {
38
- ...config.manifest?.dev?.desktop,
39
- js: [`https://localhost:${port}/desktop.js`],
40
- css: [`https://localhost:${port}/desktop.css`],
41
- },
42
- mobile: {
43
- ...config.manifest?.dev?.mobile,
44
- js: [`https://localhost:${port}/desktop.js`],
45
- css: [`https://localhost:${port}/desktop.css`],
46
- },
47
- },
48
- },
49
- },
50
- });
51
- console.log(`📝 manifest.json generated`);
52
- const contentsListener = async () => {
53
- try {
54
- await copyPluginContents();
55
- console.log('📁 contents updated');
56
- }
57
- catch (error) {
58
- console.error('📁 contents update failed');
59
- }
60
- };
61
- await contentsListener();
62
- const watcher = chokider.watch(['src/contents/**/*'], {
63
- ignored: /node_modules/,
64
- persistent: true,
65
- });
66
- watcher.on('change', contentsListener);
67
- watcher.on('add', contentsListener);
68
- watcher.on('unlink', contentsListener);
69
- await outputContentsZip(manifest);
70
- const buffer = await getContentsZipBuffer();
71
- const pluginPrivateKey = await fs.readFile(path.resolve(ppkPath), 'utf8');
72
- const output = await packer(buffer, pluginPrivateKey);
73
- const zipFileName = `plugin${getZipFileNameSuffix('dev')}.zip`;
74
- await fs.writeFile(path.join(PLUGIN_WORKSPACE_DIRECTORY, zipFileName), output.plugin);
75
- console.log(`📤 uploading ${zipFileName} to your kintone`);
76
- uploadZip('dev').then(({ stdout, stderr }) => {
77
- console.log(stdout);
78
- console.error(stderr);
79
- console.log('📤 Plugin uploaded');
80
- });
81
- const entryPoints = ['desktop', 'config'].map((dir) => ({
82
- in: path.join('src', dir, 'index.ts'),
83
- out: dir,
84
- }));
85
- base({
86
- port,
87
- entryPoints,
88
- certDir: PLUGIN_WORKSPACE_DIRECTORY,
89
- staticDir: PLUGIN_DEVELOPMENT_DIRECTORY,
90
- });
91
- }
92
- catch (error) {
93
- throw error;
94
- }
95
- finally {
96
- console.groupEnd();
97
- }
98
- }