kintone-migrator 0.1.2 → 0.2.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.
- package/README.md +14 -0
- package/dist/index.mjs +87 -66
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -19,19 +19,33 @@ Connection details for kintone can be specified via CLI arguments or environment
|
|
|
19
19
|
| CLI Argument | Environment Variable | Description |
|
|
20
20
|
|---------|----------|------|
|
|
21
21
|
| `--domain`, `-d` | `KINTONE_DOMAIN` | kintone domain (e.g., `example.cybozu.com`) |
|
|
22
|
+
| `--api-token`, `-t` | `KINTONE_API_TOKEN` | kintone API token |
|
|
22
23
|
| `--username`, `-u` | `KINTONE_USERNAME` | kintone username |
|
|
23
24
|
| `--password`, `-p` | `KINTONE_PASSWORD` | kintone password |
|
|
24
25
|
| `--app-id`, `-a` | `KINTONE_APP_ID` | kintone app ID |
|
|
25
26
|
| `--schema-file`, `-f` | `SCHEMA_FILE_PATH` | Schema file path (default: `schema.yaml`) |
|
|
26
27
|
|
|
28
|
+
### Authentication
|
|
29
|
+
|
|
30
|
+
Two authentication methods are supported:
|
|
31
|
+
|
|
32
|
+
- **API Token** (`KINTONE_API_TOKEN`): Recommended. Scoped per app for better security. Multiple tokens can be specified as a comma-separated string (e.g., `token1,token2`).
|
|
33
|
+
- **Username/Password** (`KINTONE_USERNAME` / `KINTONE_PASSWORD`): Basic authentication with user credentials.
|
|
34
|
+
|
|
35
|
+
If both are provided, API Token takes priority. At least one method must be configured.
|
|
36
|
+
|
|
27
37
|
### .env File
|
|
28
38
|
|
|
29
39
|
Environment variables can also be defined in a `.env` file and loaded with `dotenv-cli` or similar tools.
|
|
30
40
|
|
|
31
41
|
```env
|
|
32
42
|
KINTONE_DOMAIN=example.cybozu.com
|
|
43
|
+
|
|
44
|
+
# Authentication: Use either API Token or Username/Password (API Token takes priority)
|
|
45
|
+
# KINTONE_API_TOKEN=your_api_token
|
|
33
46
|
KINTONE_USERNAME=your_username
|
|
34
47
|
KINTONE_PASSWORD=your_password
|
|
48
|
+
|
|
35
49
|
KINTONE_APP_ID=123
|
|
36
50
|
SCHEMA_FILE_PATH=schema.yaml
|
|
37
51
|
```
|
package/dist/index.mjs
CHANGED
|
@@ -4,11 +4,95 @@ import { cli, define } from "gunshi";
|
|
|
4
4
|
import * as p from "@clack/prompts";
|
|
5
5
|
import pc from "picocolors";
|
|
6
6
|
import { KintoneRestAPIClient, KintoneRestAPIError } from "@kintone/rest-api-client";
|
|
7
|
+
import * as v from "valibot";
|
|
7
8
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
8
9
|
import { dirname } from "node:path";
|
|
9
10
|
import { parse, stringify } from "yaml";
|
|
10
|
-
import * as v from "valibot";
|
|
11
11
|
|
|
12
|
+
//#region src/cli/config.ts
|
|
13
|
+
const CliConfigSchema = v.object({
|
|
14
|
+
KINTONE_DOMAIN: v.pipe(v.string(), v.nonEmpty("KINTONE_DOMAIN is required")),
|
|
15
|
+
KINTONE_API_TOKEN: v.optional(v.string()),
|
|
16
|
+
KINTONE_USERNAME: v.optional(v.string()),
|
|
17
|
+
KINTONE_PASSWORD: v.optional(v.string()),
|
|
18
|
+
KINTONE_APP_ID: v.pipe(v.string(), v.nonEmpty("KINTONE_APP_ID is required")),
|
|
19
|
+
SCHEMA_FILE_PATH: v.optional(v.string(), "schema.yaml")
|
|
20
|
+
});
|
|
21
|
+
function buildKintoneAuth(auth) {
|
|
22
|
+
if (auth.type === "apiToken") return { apiToken: auth.apiToken };
|
|
23
|
+
return {
|
|
24
|
+
username: auth.username,
|
|
25
|
+
password: auth.password
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const kintoneArgs = {
|
|
29
|
+
domain: {
|
|
30
|
+
type: "string",
|
|
31
|
+
short: "d",
|
|
32
|
+
description: "kintone domain (overrides KINTONE_DOMAIN env var)"
|
|
33
|
+
},
|
|
34
|
+
username: {
|
|
35
|
+
type: "string",
|
|
36
|
+
short: "u",
|
|
37
|
+
description: "kintone username (overrides KINTONE_USERNAME env var)"
|
|
38
|
+
},
|
|
39
|
+
password: {
|
|
40
|
+
type: "string",
|
|
41
|
+
short: "p",
|
|
42
|
+
description: "kintone password (overrides KINTONE_PASSWORD env var)"
|
|
43
|
+
},
|
|
44
|
+
"api-token": {
|
|
45
|
+
type: "string",
|
|
46
|
+
short: "t",
|
|
47
|
+
description: "kintone API token (overrides KINTONE_API_TOKEN env var)"
|
|
48
|
+
},
|
|
49
|
+
"app-id": {
|
|
50
|
+
type: "string",
|
|
51
|
+
short: "a",
|
|
52
|
+
description: "kintone app ID (overrides KINTONE_APP_ID env var)"
|
|
53
|
+
},
|
|
54
|
+
"schema-file": {
|
|
55
|
+
type: "string",
|
|
56
|
+
short: "f",
|
|
57
|
+
description: "Schema file path (default: schema.yaml)"
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
function resolveConfig(cliValues) {
|
|
61
|
+
const result = v.safeParse(CliConfigSchema, {
|
|
62
|
+
KINTONE_DOMAIN: cliValues.domain ?? process.env.KINTONE_DOMAIN ?? "",
|
|
63
|
+
KINTONE_API_TOKEN: cliValues["api-token"] ?? process.env.KINTONE_API_TOKEN ?? void 0,
|
|
64
|
+
KINTONE_USERNAME: cliValues.username ?? process.env.KINTONE_USERNAME ?? void 0,
|
|
65
|
+
KINTONE_PASSWORD: cliValues.password ?? process.env.KINTONE_PASSWORD ?? void 0,
|
|
66
|
+
KINTONE_APP_ID: cliValues["app-id"] ?? process.env.KINTONE_APP_ID ?? "",
|
|
67
|
+
SCHEMA_FILE_PATH: cliValues["schema-file"] ?? process.env.SCHEMA_FILE_PATH
|
|
68
|
+
});
|
|
69
|
+
if (!result.success) {
|
|
70
|
+
const missing = result.issues.map((issue) => issue.message).join("\n ");
|
|
71
|
+
throw new Error(`Missing required configuration:\n ${missing}`);
|
|
72
|
+
}
|
|
73
|
+
const { output } = result;
|
|
74
|
+
const auth = resolveAuth(output.KINTONE_API_TOKEN, output.KINTONE_USERNAME, output.KINTONE_PASSWORD);
|
|
75
|
+
return {
|
|
76
|
+
baseUrl: `https://${output.KINTONE_DOMAIN}`,
|
|
77
|
+
auth,
|
|
78
|
+
appId: output.KINTONE_APP_ID,
|
|
79
|
+
schemaFilePath: output.SCHEMA_FILE_PATH
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function resolveAuth(apiToken, username, password) {
|
|
83
|
+
if (apiToken) return {
|
|
84
|
+
type: "apiToken",
|
|
85
|
+
apiToken: apiToken.includes(",") ? apiToken.split(",").map((t) => t.trim()) : apiToken
|
|
86
|
+
};
|
|
87
|
+
if (username && password) return {
|
|
88
|
+
type: "password",
|
|
89
|
+
username,
|
|
90
|
+
password
|
|
91
|
+
};
|
|
92
|
+
throw new Error("Missing required configuration:\n Either KINTONE_API_TOKEN or KINTONE_USERNAME/KINTONE_PASSWORD is required");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//#endregion
|
|
12
96
|
//#region src/lib/error.ts
|
|
13
97
|
var AnyError = class extends Error {
|
|
14
98
|
constructor(message, cause) {
|
|
@@ -548,10 +632,7 @@ function isNodeError(error) {
|
|
|
548
632
|
function createCliContainer(config) {
|
|
549
633
|
const client = new KintoneRestAPIClient({
|
|
550
634
|
baseUrl: config.baseUrl,
|
|
551
|
-
auth:
|
|
552
|
-
username: config.username,
|
|
553
|
-
password: config.password
|
|
554
|
-
}
|
|
635
|
+
auth: buildKintoneAuth(config.auth)
|
|
555
636
|
});
|
|
556
637
|
return {
|
|
557
638
|
formConfigurator: new KintoneFormConfigurator(client, config.appId),
|
|
@@ -749,63 +830,6 @@ async function saveSchema({ container, input }) {
|
|
|
749
830
|
await container.schemaStorage.update(input.schemaText);
|
|
750
831
|
}
|
|
751
832
|
|
|
752
|
-
//#endregion
|
|
753
|
-
//#region src/cli/config.ts
|
|
754
|
-
const CliConfigSchema = v.object({
|
|
755
|
-
KINTONE_DOMAIN: v.pipe(v.string(), v.nonEmpty("KINTONE_DOMAIN is required")),
|
|
756
|
-
KINTONE_USERNAME: v.pipe(v.string(), v.nonEmpty("KINTONE_USERNAME is required")),
|
|
757
|
-
KINTONE_PASSWORD: v.pipe(v.string(), v.nonEmpty("KINTONE_PASSWORD is required")),
|
|
758
|
-
KINTONE_APP_ID: v.pipe(v.string(), v.nonEmpty("KINTONE_APP_ID is required")),
|
|
759
|
-
SCHEMA_FILE_PATH: v.optional(v.string(), "schema.yaml")
|
|
760
|
-
});
|
|
761
|
-
const kintoneArgs = {
|
|
762
|
-
domain: {
|
|
763
|
-
type: "string",
|
|
764
|
-
short: "d",
|
|
765
|
-
description: "kintone domain (overrides KINTONE_DOMAIN env var)"
|
|
766
|
-
},
|
|
767
|
-
username: {
|
|
768
|
-
type: "string",
|
|
769
|
-
short: "u",
|
|
770
|
-
description: "kintone username (overrides KINTONE_USERNAME env var)"
|
|
771
|
-
},
|
|
772
|
-
password: {
|
|
773
|
-
type: "string",
|
|
774
|
-
short: "p",
|
|
775
|
-
description: "kintone password (overrides KINTONE_PASSWORD env var)"
|
|
776
|
-
},
|
|
777
|
-
"app-id": {
|
|
778
|
-
type: "string",
|
|
779
|
-
short: "a",
|
|
780
|
-
description: "kintone app ID (overrides KINTONE_APP_ID env var)"
|
|
781
|
-
},
|
|
782
|
-
"schema-file": {
|
|
783
|
-
type: "string",
|
|
784
|
-
short: "f",
|
|
785
|
-
description: "Schema file path (default: schema.yaml)"
|
|
786
|
-
}
|
|
787
|
-
};
|
|
788
|
-
function resolveConfig(cliValues) {
|
|
789
|
-
const result = v.safeParse(CliConfigSchema, {
|
|
790
|
-
KINTONE_DOMAIN: cliValues.domain ?? process.env.KINTONE_DOMAIN ?? "",
|
|
791
|
-
KINTONE_USERNAME: cliValues.username ?? process.env.KINTONE_USERNAME ?? "",
|
|
792
|
-
KINTONE_PASSWORD: cliValues.password ?? process.env.KINTONE_PASSWORD ?? "",
|
|
793
|
-
KINTONE_APP_ID: cliValues["app-id"] ?? process.env.KINTONE_APP_ID ?? "",
|
|
794
|
-
SCHEMA_FILE_PATH: cliValues["schema-file"] ?? process.env.SCHEMA_FILE_PATH
|
|
795
|
-
});
|
|
796
|
-
if (!result.success) {
|
|
797
|
-
const missing = result.issues.map((issue) => issue.message).join("\n ");
|
|
798
|
-
throw new Error(`Missing required configuration:\n ${missing}`);
|
|
799
|
-
}
|
|
800
|
-
return {
|
|
801
|
-
baseUrl: `https://${result.output.KINTONE_DOMAIN}`,
|
|
802
|
-
username: result.output.KINTONE_USERNAME,
|
|
803
|
-
password: result.output.KINTONE_PASSWORD,
|
|
804
|
-
appId: result.output.KINTONE_APP_ID,
|
|
805
|
-
schemaFilePath: result.output.SCHEMA_FILE_PATH
|
|
806
|
-
};
|
|
807
|
-
}
|
|
808
|
-
|
|
809
833
|
//#endregion
|
|
810
834
|
//#region src/cli/handleError.ts
|
|
811
835
|
function handleCliError(error) {
|
|
@@ -1492,10 +1516,7 @@ var dump_default = define({
|
|
|
1492
1516
|
const config = resolveConfig(ctx.values);
|
|
1493
1517
|
const client = new KintoneRestAPIClient({
|
|
1494
1518
|
baseUrl: config.baseUrl,
|
|
1495
|
-
auth:
|
|
1496
|
-
username: config.username,
|
|
1497
|
-
password: config.password
|
|
1498
|
-
}
|
|
1519
|
+
auth: buildKintoneAuth(config.auth)
|
|
1499
1520
|
});
|
|
1500
1521
|
const s = p.spinner();
|
|
1501
1522
|
s.start("Fetching form fields and layout...");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kintone-migrator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "kintone form schema migration tool",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Hikaru Otabe",
|
|
@@ -53,10 +53,15 @@
|
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@biomejs/biome": "^2.3.14",
|
|
56
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
57
|
+
"@semantic-release/github": "^12.0.5",
|
|
58
|
+
"@semantic-release/npm": "^13.1.4",
|
|
59
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
56
60
|
"@types/node": "^25.2.3",
|
|
57
61
|
"@typescript/native-preview": "7.0.0-dev.20260211.1",
|
|
58
62
|
"@vitest/coverage-v8": "^4.0.18",
|
|
59
63
|
"dotenv-cli": "^11.0.0",
|
|
64
|
+
"semantic-release": "^25.0.3",
|
|
60
65
|
"tsdown": "^0.20.3",
|
|
61
66
|
"tsx": "^4.21.0",
|
|
62
67
|
"typescript": "~5.9.3",
|