@interactivethings/scripts 2.0.4 → 2.1.1
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/dist/cli.js +21 -12
- package/dist/cloudflare/cli.js +90 -0
- package/dist/cloudflare/cloudflare.js +44 -0
- package/dist/cloudflare/deployments.js +14 -0
- package/dist/config.js +13 -7
- package/dist/figma/cli.js +7 -5
- package/dist/figma/cli.test.js +8 -7
- package/dist/init/cli.js +10 -10
- package/dist/shared/cli.js +13 -0
- package/dist/shared/deployment-service.js +2 -0
- package/dist/shared/wait-deployment.js +29 -0
- package/dist/tokens-studio/cli.js +5 -3
- package/dist/tokens-studio/cli.test.js +10 -4
- package/dist/vercel/cli.js +7 -5
- package/dist/vercel/cli.test.js +9 -5
- package/dist/vercel/deployments.js +9 -36
- package/dist/vercel/vercel.js +31 -0
- package/package.json +5 -7
package/dist/cli.js
CHANGED
|
@@ -69,28 +69,37 @@ async function main() {
|
|
|
69
69
|
const vercelParser = subparsers.add_parser("vercel", {
|
|
70
70
|
help: "Vercel utilities",
|
|
71
71
|
});
|
|
72
|
+
// Cloudflare subcommand
|
|
73
|
+
const cloudflareParser = subparsers.add_parser("cloudflare", {
|
|
74
|
+
help: "Cloudflare utilities",
|
|
75
|
+
});
|
|
72
76
|
// Import and configure all subcommands
|
|
73
|
-
const {
|
|
74
|
-
const {
|
|
75
|
-
const {
|
|
76
|
-
const {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
const { default: initModule } = await Promise.resolve().then(() => __importStar(require("./init/cli")));
|
|
78
|
+
const { default: figmaModule } = await Promise.resolve().then(() => __importStar(require("./figma/cli")));
|
|
79
|
+
const { default: tokensStudioModule } = await Promise.resolve().then(() => __importStar(require("./tokens-studio/cli")));
|
|
80
|
+
const { default: vercelModule } = await Promise.resolve().then(() => __importStar(require("./vercel/cli")));
|
|
81
|
+
const { default: cloudflareModule } = await Promise.resolve().then(() => __importStar(require("./cloudflare/cli")));
|
|
82
|
+
initModule.configParser(initParser);
|
|
83
|
+
figmaModule.configParser(figmaParser);
|
|
84
|
+
tokensStudioModule.configParser(tokensStudioParser);
|
|
85
|
+
vercelModule.configParser(vercelParser);
|
|
86
|
+
cloudflareModule.configParser(cloudflareParser);
|
|
81
87
|
const args = parser.parse_args();
|
|
82
88
|
switch (args.command) {
|
|
83
89
|
case "init":
|
|
84
|
-
await
|
|
90
|
+
await initModule.run(args);
|
|
85
91
|
break;
|
|
86
92
|
case "figma":
|
|
87
|
-
await
|
|
93
|
+
await figmaModule.run(args);
|
|
88
94
|
break;
|
|
89
95
|
case "tokens-studio":
|
|
90
|
-
await
|
|
96
|
+
await tokensStudioModule.run(args);
|
|
91
97
|
break;
|
|
92
98
|
case "vercel":
|
|
93
|
-
await
|
|
99
|
+
await vercelModule.run(args);
|
|
100
|
+
break;
|
|
101
|
+
case "cloudflare":
|
|
102
|
+
await cloudflareModule.run(args);
|
|
94
103
|
break;
|
|
95
104
|
default:
|
|
96
105
|
parser.print_help();
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const deployments_1 = require("./deployments");
|
|
5
|
+
const argparse_1 = require("argparse");
|
|
6
|
+
const config_1 = require("../config");
|
|
7
|
+
const cli_1 = require("../shared/cli");
|
|
8
|
+
const configParser = (parser) => {
|
|
9
|
+
const commands = parser.add_subparsers({
|
|
10
|
+
title: "Cloudflare commands",
|
|
11
|
+
dest: "subcommand",
|
|
12
|
+
help: "Use 'ixt cloudflare <command> --help' for more information",
|
|
13
|
+
});
|
|
14
|
+
// wait-deployment subcommand
|
|
15
|
+
const waitDeploymentParser = commands.add_parser("wait-deployment", {
|
|
16
|
+
help: "Wait for a Cloudflare deployment to complete",
|
|
17
|
+
});
|
|
18
|
+
waitDeploymentParser.add_argument("commit", {
|
|
19
|
+
help: "Commit that started the deployment",
|
|
20
|
+
});
|
|
21
|
+
waitDeploymentParser.add_argument("--interval", {
|
|
22
|
+
default: 5000,
|
|
23
|
+
type: Number,
|
|
24
|
+
});
|
|
25
|
+
waitDeploymentParser.add_argument("--project", {
|
|
26
|
+
help: "Cloudflare project name",
|
|
27
|
+
});
|
|
28
|
+
waitDeploymentParser.add_argument("--email", {
|
|
29
|
+
help: "Cloudflare account email",
|
|
30
|
+
});
|
|
31
|
+
waitDeploymentParser.add_argument("--account-id", {
|
|
32
|
+
help: "Cloudflare account ID",
|
|
33
|
+
});
|
|
34
|
+
waitDeploymentParser.add_argument("--timeout", {
|
|
35
|
+
default: 10 * 60 * 1000,
|
|
36
|
+
type: Number,
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
const run = async (args) => {
|
|
40
|
+
const config = await (0, config_1.loadConfig)(args.config);
|
|
41
|
+
const apiKey = process.env.CLOUDFLARE_API_KEY;
|
|
42
|
+
if (!apiKey) {
|
|
43
|
+
throw new Error("CLOUDFLARE_API_KEY environment variable is required");
|
|
44
|
+
}
|
|
45
|
+
switch (args.subcommand) {
|
|
46
|
+
case "wait-deployment":
|
|
47
|
+
// Merge config with CLI args
|
|
48
|
+
const mergedConfig = (0, config_1.mergeConfigWithArgs)(config, args, "cloudflare");
|
|
49
|
+
// Map CLI args to match the expected format
|
|
50
|
+
const finalConfig = {
|
|
51
|
+
...mergedConfig,
|
|
52
|
+
accountId: mergedConfig.account_id || mergedConfig.accountId,
|
|
53
|
+
};
|
|
54
|
+
// Validate required fields
|
|
55
|
+
(0, config_1.validateRequiredConfig)(finalConfig, ["project", "email", "accountId"]);
|
|
56
|
+
const deployment = await (0, deployments_1.waitForDeploymentReady)({
|
|
57
|
+
accountId: finalConfig.accountId,
|
|
58
|
+
project: finalConfig.project,
|
|
59
|
+
email: finalConfig.email,
|
|
60
|
+
apiKey,
|
|
61
|
+
commitSha: args.commit,
|
|
62
|
+
interval: args.interval,
|
|
63
|
+
timeout: args.timeout,
|
|
64
|
+
});
|
|
65
|
+
if (!deployment) {
|
|
66
|
+
throw new Error("Could not retrieve deployment");
|
|
67
|
+
}
|
|
68
|
+
console.log(`DEPLOYMENT_URL=${deployment.url}`);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
exports.default = (0, cli_1.defineCLIModule)({
|
|
73
|
+
configParser,
|
|
74
|
+
run,
|
|
75
|
+
});
|
|
76
|
+
async function main() {
|
|
77
|
+
const parser = new argparse_1.ArgumentParser({
|
|
78
|
+
description: "Cloudflare deployment utilities",
|
|
79
|
+
});
|
|
80
|
+
const args = parser.parse_args();
|
|
81
|
+
configParser(parser);
|
|
82
|
+
await run(args);
|
|
83
|
+
}
|
|
84
|
+
// Only run main if this file is being executed directly
|
|
85
|
+
if (require.main === module) {
|
|
86
|
+
main().catch((e) => {
|
|
87
|
+
console.error(e);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CloudflareDeploymentService = void 0;
|
|
7
|
+
const assert_1 = __importDefault(require("assert"));
|
|
8
|
+
const getDeploymentState = (deployment) => {
|
|
9
|
+
return deployment.latest_stage.name === "deploy" &&
|
|
10
|
+
deployment.latest_stage.status === "success"
|
|
11
|
+
? "READY"
|
|
12
|
+
: "BUILDING";
|
|
13
|
+
};
|
|
14
|
+
const getDeploymentUrl = (deployment) => {
|
|
15
|
+
return deployment.url;
|
|
16
|
+
};
|
|
17
|
+
class CloudflareDeploymentService {
|
|
18
|
+
constructor(accountId, projectName, email, apiKey) {
|
|
19
|
+
this.accountId = accountId;
|
|
20
|
+
this.projectName = projectName;
|
|
21
|
+
this.email = email;
|
|
22
|
+
this.apiKey = apiKey;
|
|
23
|
+
}
|
|
24
|
+
async fetchForCommit(commitSha) {
|
|
25
|
+
const url = `https://api.cloudflare.com/client/v4/accounts/${this.accountId}/pages/projects/${this.projectName}/deployments`;
|
|
26
|
+
const headers = {
|
|
27
|
+
"X-Auth-Email": this.email,
|
|
28
|
+
"X-Auth-Key": this.apiKey,
|
|
29
|
+
};
|
|
30
|
+
const response = await fetch(url, { headers })
|
|
31
|
+
.then((x) => x.json())
|
|
32
|
+
.then((x) => x);
|
|
33
|
+
if (!response.success) {
|
|
34
|
+
throw new Error(`Cloudflare API request was not successful. Errors: ${JSON.stringify(response.errors)}`);
|
|
35
|
+
}
|
|
36
|
+
(0, assert_1.default)(response.success, "Cloudflare API request was not successful");
|
|
37
|
+
const deployments = response.result.filter((deployment) => deployment.deployment_trigger.metadata.commit_hash === commitSha);
|
|
38
|
+
return deployments.map((d) => ({
|
|
39
|
+
state: getDeploymentState(d),
|
|
40
|
+
url: getDeploymentUrl(d),
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.CloudflareDeploymentService = CloudflareDeploymentService;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.waitForDeploymentReady = waitForDeploymentReady;
|
|
4
|
+
const wait_deployment_1 = require("../shared/wait-deployment");
|
|
5
|
+
const cloudflare_1 = require("./cloudflare");
|
|
6
|
+
async function waitForDeploymentReady({ accountId, project, email, apiKey, commitSha, interval, timeout, }) {
|
|
7
|
+
const service = new cloudflare_1.CloudflareDeploymentService(accountId, project, email, apiKey);
|
|
8
|
+
return await (0, wait_deployment_1.waitForDeploymentReady)({
|
|
9
|
+
commitSha,
|
|
10
|
+
interval,
|
|
11
|
+
timeout,
|
|
12
|
+
deploymentService: service,
|
|
13
|
+
});
|
|
14
|
+
}
|
package/dist/config.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.IxtConfigSchema = exports.VercelConfigSchema = exports.TokensStudioConfigSchema = exports.FigmaConfigSchema = exports.FigmaAssetConfigSchema = void 0;
|
|
36
|
+
exports.IxtConfigSchema = exports.CloudflareConfigSchema = exports.VercelConfigSchema = exports.TokensStudioConfigSchema = exports.FigmaConfigSchema = exports.FigmaAssetConfigSchema = void 0;
|
|
37
37
|
exports.defineConfig = defineConfig;
|
|
38
38
|
exports.loadConfig = loadConfig;
|
|
39
39
|
exports.mergeConfigWithArgs = mergeConfigWithArgs;
|
|
@@ -73,11 +73,8 @@ exports.TokensStudioConfigSchema = zod_1.z.object({
|
|
|
73
73
|
output: zod_1.z
|
|
74
74
|
.string()
|
|
75
75
|
.optional()
|
|
76
|
-
.describe("
|
|
77
|
-
handler: zod_1.z
|
|
78
|
-
.string()
|
|
79
|
-
.optional()
|
|
80
|
-
.describe("Default path to the transformer handler file"),
|
|
76
|
+
.describe("Output directory for transformed tokens"),
|
|
77
|
+
handler: zod_1.z.string().describe("Path to the transformer file"),
|
|
81
78
|
});
|
|
82
79
|
/**
|
|
83
80
|
* Vercel configuration schema
|
|
@@ -86,6 +83,14 @@ exports.VercelConfigSchema = zod_1.z.object({
|
|
|
86
83
|
team: zod_1.z.string().optional().describe("Vercel team name (organization)"),
|
|
87
84
|
project: zod_1.z.string().optional().describe("Vercel project name"),
|
|
88
85
|
});
|
|
86
|
+
/**
|
|
87
|
+
* Cloudflare configuration schema
|
|
88
|
+
*/
|
|
89
|
+
exports.CloudflareConfigSchema = zod_1.z.object({
|
|
90
|
+
project: zod_1.z.string().optional().describe("Cloudflare project name"),
|
|
91
|
+
email: zod_1.z.string().optional().describe("Cloudflare account email"),
|
|
92
|
+
accountId: zod_1.z.string().optional().describe("Cloudflare account ID"),
|
|
93
|
+
});
|
|
89
94
|
/**
|
|
90
95
|
* Main IXT Scripts configuration schema
|
|
91
96
|
*/
|
|
@@ -93,6 +98,7 @@ exports.IxtConfigSchema = zod_1.z.object({
|
|
|
93
98
|
figma: exports.FigmaConfigSchema.optional().describe("Figma-related configuration"),
|
|
94
99
|
tokensStudio: exports.TokensStudioConfigSchema.optional().describe("Tokens Studio configuration"),
|
|
95
100
|
vercel: exports.VercelConfigSchema.optional().describe("Vercel deployment configuration"),
|
|
101
|
+
cloudflare: exports.CloudflareConfigSchema.optional().describe("Cloudflare deployment configuration"),
|
|
96
102
|
});
|
|
97
103
|
/**
|
|
98
104
|
* Helper function for type-safe configuration definition
|
|
@@ -141,7 +147,7 @@ async function loadConfig(configPath) {
|
|
|
141
147
|
}
|
|
142
148
|
}
|
|
143
149
|
// No config file found, return default config
|
|
144
|
-
|
|
150
|
+
throw new Error(`No configuration file found. Please create an ixt.config.ts file in the current directory.`);
|
|
145
151
|
}
|
|
146
152
|
/**
|
|
147
153
|
* Merge CLI arguments with configuration
|
package/dist/figma/cli.js
CHANGED
|
@@ -53,7 +53,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
53
53
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
54
54
|
};
|
|
55
55
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
56
|
-
exports.run = exports.configParser = void 0;
|
|
57
56
|
const fs = __importStar(require("fs/promises"));
|
|
58
57
|
const path = __importStar(require("path"));
|
|
59
58
|
const argparse_1 = require("argparse");
|
|
@@ -62,6 +61,7 @@ const api_1 = require("./api");
|
|
|
62
61
|
const utils_1 = require("./utils");
|
|
63
62
|
const config_1 = require("../config");
|
|
64
63
|
const images_1 = require("./images");
|
|
64
|
+
const cli_1 = require("../shared/cli");
|
|
65
65
|
const configParser = (parser) => {
|
|
66
66
|
parser.add_argument("--token", {
|
|
67
67
|
help: "Figma API token (can also use FIGMA_TOKEN env var)",
|
|
@@ -86,7 +86,6 @@ const configParser = (parser) => {
|
|
|
86
86
|
help: "The Figma URL to fetch the node from",
|
|
87
87
|
});
|
|
88
88
|
};
|
|
89
|
-
exports.configParser = configParser;
|
|
90
89
|
const run = async (args) => {
|
|
91
90
|
// Load configuration
|
|
92
91
|
const config = await (0, config_1.loadConfig)(args.config);
|
|
@@ -145,14 +144,17 @@ const run = async (args) => {
|
|
|
145
144
|
console.log(JSON.stringify(node, null, 2));
|
|
146
145
|
}
|
|
147
146
|
};
|
|
148
|
-
exports.
|
|
147
|
+
exports.default = (0, cli_1.defineCLIModule)({
|
|
148
|
+
configParser,
|
|
149
|
+
run,
|
|
150
|
+
});
|
|
149
151
|
const main = async () => {
|
|
150
152
|
const parser = new argparse_1.ArgumentParser({
|
|
151
153
|
description: "Download assets from Figma",
|
|
152
154
|
});
|
|
153
|
-
|
|
155
|
+
configParser(parser);
|
|
154
156
|
const args = parser.parse_args();
|
|
155
|
-
await
|
|
157
|
+
await run(args);
|
|
156
158
|
};
|
|
157
159
|
// Only run main if this file is being executed directly
|
|
158
160
|
if (require.main === module) {
|
package/dist/figma/cli.test.js
CHANGED
|
@@ -38,9 +38,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
const vitest_1 = require("vitest");
|
|
40
40
|
const argparse_1 = require("argparse");
|
|
41
|
-
const cli_1 = require("./cli");
|
|
41
|
+
const cli_1 = __importDefault(require("./cli"));
|
|
42
42
|
const fs = __importStar(require("fs/promises"));
|
|
43
43
|
const path_1 = __importDefault(require("path"));
|
|
44
|
+
const { run, configParser } = cli_1.default;
|
|
44
45
|
// Mock the API and other dependencies
|
|
45
46
|
vitest_1.vi.mock("../figma/api", () => ({
|
|
46
47
|
createAPI: vitest_1.vi.fn(),
|
|
@@ -94,7 +95,7 @@ const config_1 = require("../config");
|
|
|
94
95
|
(0, vitest_1.it)("should configure the argument parser correctly", () => {
|
|
95
96
|
const parser = new argparse_1.ArgumentParser();
|
|
96
97
|
const addSubparsersSpy = vitest_1.vi.spyOn(parser, "add_subparsers");
|
|
97
|
-
|
|
98
|
+
configParser(parser);
|
|
98
99
|
(0, vitest_1.expect)(addSubparsersSpy).toHaveBeenCalledWith({
|
|
99
100
|
title: "commands",
|
|
100
101
|
dest: "subcommand",
|
|
@@ -127,7 +128,7 @@ const config_1 = require("../config");
|
|
|
127
128
|
config: undefined,
|
|
128
129
|
token: undefined,
|
|
129
130
|
};
|
|
130
|
-
await
|
|
131
|
+
await run(args);
|
|
131
132
|
(0, vitest_1.expect)(config_1.loadConfig).toHaveBeenCalledWith(undefined);
|
|
132
133
|
(0, vitest_1.expect)(api_1.createAPI).toHaveBeenCalledWith("test-token");
|
|
133
134
|
(0, vitest_1.expect)(mockAPI.images.fetch).toHaveBeenCalled();
|
|
@@ -146,7 +147,7 @@ const config_1 = require("../config");
|
|
|
146
147
|
config: undefined,
|
|
147
148
|
token: undefined,
|
|
148
149
|
};
|
|
149
|
-
await (0, vitest_1.expect)(
|
|
150
|
+
await (0, vitest_1.expect)(run(args)).rejects.toThrow("No figma assets configured");
|
|
150
151
|
});
|
|
151
152
|
(0, vitest_1.it)("should throw error when asset is not found", async () => {
|
|
152
153
|
vitest_1.vi.mocked(config_1.mergeConfigWithArgs).mockReturnValue({
|
|
@@ -165,7 +166,7 @@ const config_1 = require("../config");
|
|
|
165
166
|
config: undefined,
|
|
166
167
|
token: undefined,
|
|
167
168
|
};
|
|
168
|
-
await (0, vitest_1.expect)(
|
|
169
|
+
await (0, vitest_1.expect)(run(args)).rejects.toThrow('No asset configuration found for name "test-assets"');
|
|
169
170
|
});
|
|
170
171
|
});
|
|
171
172
|
(0, vitest_1.describe)("get subcommand", () => {
|
|
@@ -178,7 +179,7 @@ const config_1 = require("../config");
|
|
|
178
179
|
config: undefined,
|
|
179
180
|
token: undefined,
|
|
180
181
|
};
|
|
181
|
-
await
|
|
182
|
+
await run(args);
|
|
182
183
|
(0, vitest_1.expect)(mockAPI.nodes.fetch).toHaveBeenCalled();
|
|
183
184
|
(0, vitest_1.expect)(vitest_1.vi.mocked(console.log)).toHaveBeenCalledWith(JSON.stringify(mockNodeData, null, 2));
|
|
184
185
|
});
|
|
@@ -190,7 +191,7 @@ const config_1 = require("../config");
|
|
|
190
191
|
config: undefined,
|
|
191
192
|
token: undefined,
|
|
192
193
|
};
|
|
193
|
-
await
|
|
194
|
+
await run(args);
|
|
194
195
|
(0, vitest_1.expect)(config_1.validateRequiredConfig).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ token: "test-token" }), ["token"]);
|
|
195
196
|
});
|
|
196
197
|
});
|
package/dist/init/cli.js
CHANGED
|
@@ -36,19 +36,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.configParser = configParser;
|
|
40
|
-
exports.run = run;
|
|
41
39
|
const fs = __importStar(require("fs/promises"));
|
|
42
40
|
const path = __importStar(require("path"));
|
|
43
41
|
const prompts_1 = __importDefault(require("prompts"));
|
|
44
42
|
const ora_1 = __importDefault(require("ora"));
|
|
45
|
-
|
|
43
|
+
const cli_1 = require("../shared/cli");
|
|
44
|
+
const configParser = (parser) => {
|
|
46
45
|
parser.add_argument("--force", {
|
|
47
46
|
action: "store_true",
|
|
48
47
|
help: "Overwrite existing configuration files",
|
|
49
48
|
});
|
|
50
|
-
}
|
|
51
|
-
async
|
|
49
|
+
};
|
|
50
|
+
const run = async (args) => {
|
|
52
51
|
console.log("🚀 Welcome to Interactive Things Scripts setup!\n");
|
|
53
52
|
console.log("This wizard will help you configure your project for optimal development workflow.\n");
|
|
54
53
|
// Check if config already exists
|
|
@@ -103,7 +102,11 @@ async function run(args) {
|
|
|
103
102
|
spinner.fail("Setup failed");
|
|
104
103
|
throw error;
|
|
105
104
|
}
|
|
106
|
-
}
|
|
105
|
+
};
|
|
106
|
+
exports.default = (0, cli_1.defineCLIModule)({
|
|
107
|
+
configParser,
|
|
108
|
+
run,
|
|
109
|
+
});
|
|
107
110
|
async function collectUserPreferences() {
|
|
108
111
|
const questions = [
|
|
109
112
|
{
|
|
@@ -247,11 +250,8 @@ function generateConfig(answers) {
|
|
|
247
250
|
config.tokensStudio = {
|
|
248
251
|
input: answers.tokensInputDir,
|
|
249
252
|
output: answers.tokensOutputFile,
|
|
253
|
+
handler: `./ixt/transforms/${answers.stylingFramework}-transform.ts`,
|
|
250
254
|
};
|
|
251
|
-
// Add handler path based on styling framework choice
|
|
252
|
-
if (answers.stylingFramework && answers.stylingFramework !== "custom") {
|
|
253
|
-
config.tokensStudio.handler = `./ixt/transforms/${answers.stylingFramework}-transform.ts`;
|
|
254
|
-
}
|
|
255
255
|
}
|
|
256
256
|
if (answers.useVercel && (answers.vercelTeam || answers.vercelProject)) {
|
|
257
257
|
config.vercel = {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defineCLIModule = defineCLIModule;
|
|
4
|
+
/**
|
|
5
|
+
* Type-safe factory function for creating CLI modules
|
|
6
|
+
* Provides consistent interface and utilities for all CLI modules
|
|
7
|
+
*/
|
|
8
|
+
function defineCLIModule(config) {
|
|
9
|
+
return {
|
|
10
|
+
configParser: config.configParser,
|
|
11
|
+
run: config.run,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.waitForDeploymentReady = waitForDeploymentReady;
|
|
4
|
+
const sleep = (duration) => new Promise((resolve) => setTimeout(resolve, duration));
|
|
5
|
+
async function waitForDeploymentReady({ commitSha, interval, timeout, deploymentService, }) {
|
|
6
|
+
const start = Date.now();
|
|
7
|
+
const end = start + timeout;
|
|
8
|
+
while (Date.now() < end) {
|
|
9
|
+
const deployments = await deploymentService.fetchForCommit(commitSha);
|
|
10
|
+
if (deployments.length === 0) {
|
|
11
|
+
throw new Error(`No available deployments for commit ${commitSha}`);
|
|
12
|
+
}
|
|
13
|
+
if (deployments[0].state !== "READY") {
|
|
14
|
+
const state = deployments[0].state;
|
|
15
|
+
if (state === "ERROR") {
|
|
16
|
+
throw new Error("Deployment errored");
|
|
17
|
+
}
|
|
18
|
+
console.log(`Deployment not yet ready (state: ${state}), waiting ${interval}ms for deployment with commit ${commitSha}`);
|
|
19
|
+
await sleep(Math.min(end - Date.now(), interval));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.log(`Deployment for commit ${commitSha} is READY`);
|
|
23
|
+
return deployments[0];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (Date.now() > end) {
|
|
27
|
+
throw new Error("Timeout for waitForDeploymentReady");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -38,12 +38,12 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
38
38
|
};
|
|
39
39
|
})();
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
exports.run = exports.configParser = void 0;
|
|
42
41
|
const fs = __importStar(require("fs"));
|
|
43
42
|
const path = __importStar(require("path"));
|
|
44
43
|
const config_1 = require("../config");
|
|
45
44
|
const utils_1 = require("./utils");
|
|
46
45
|
const require_1 = require("./require");
|
|
46
|
+
const cli_1 = require("../shared/cli");
|
|
47
47
|
const readJsonFile = (filePath) => {
|
|
48
48
|
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
49
49
|
};
|
|
@@ -83,7 +83,6 @@ const configParser = (parser) => {
|
|
|
83
83
|
help: "Output file path (e.g., theme.json)",
|
|
84
84
|
});
|
|
85
85
|
};
|
|
86
|
-
exports.configParser = configParser;
|
|
87
86
|
const run = async (args) => {
|
|
88
87
|
switch (args.subcommand) {
|
|
89
88
|
case "transform":
|
|
@@ -127,7 +126,10 @@ const run = async (args) => {
|
|
|
127
126
|
throw new Error(`Unknown subcommand: ${args.subcommand}`);
|
|
128
127
|
}
|
|
129
128
|
};
|
|
130
|
-
exports.
|
|
129
|
+
exports.default = (0, cli_1.defineCLIModule)({
|
|
130
|
+
configParser,
|
|
131
|
+
run,
|
|
132
|
+
});
|
|
131
133
|
const sortKeysRecursively = (obj) => {
|
|
132
134
|
if (Array.isArray(obj)) {
|
|
133
135
|
return obj.map(sortKeysRecursively);
|
|
@@ -32,15 +32,19 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
const vitest_1 = require("vitest");
|
|
37
40
|
const fs = __importStar(require("fs"));
|
|
38
41
|
const path = __importStar(require("path"));
|
|
39
42
|
const argparse_1 = require("argparse");
|
|
40
|
-
const cli_1 = require("./cli");
|
|
43
|
+
const cli_1 = __importDefault(require("./cli"));
|
|
41
44
|
const config = __importStar(require("../config"));
|
|
42
45
|
const require_1 = require("./require");
|
|
43
46
|
const testTransformer = __importStar(require("./__tests__/fixtures/test-transformer"));
|
|
47
|
+
const { run, configParser } = cli_1.default;
|
|
44
48
|
// Mock dependencies
|
|
45
49
|
vitest_1.vi.mock("fs");
|
|
46
50
|
vitest_1.vi.mock("../config");
|
|
@@ -75,6 +79,8 @@ vitest_1.vi.mock("./require", () => ({
|
|
|
75
79
|
mockedConfig.loadConfig.mockResolvedValue({
|
|
76
80
|
tokensStudio: {
|
|
77
81
|
input: "./tokens",
|
|
82
|
+
output: "./output.json",
|
|
83
|
+
handler: "./transformer.ts",
|
|
78
84
|
},
|
|
79
85
|
});
|
|
80
86
|
mockedConfig.mergeConfigWithArgs.mockReturnValue({
|
|
@@ -96,7 +102,7 @@ vitest_1.vi.mock("./require", () => ({
|
|
|
96
102
|
const parser = new argparse_1.ArgumentParser({ description: "Test parser" });
|
|
97
103
|
const addArgumentSpy = vitest_1.vi.spyOn(parser, "add_argument");
|
|
98
104
|
const addSubparsersSpy = vitest_1.vi.spyOn(parser, "add_subparsers");
|
|
99
|
-
|
|
105
|
+
configParser(parser);
|
|
100
106
|
// Check that config argument is added
|
|
101
107
|
(0, vitest_1.expect)(addArgumentSpy).toHaveBeenCalledWith("--config", {
|
|
102
108
|
help: "Path to TypeScript config file (default: looks for ixt.config.ts in current directory)",
|
|
@@ -127,7 +133,7 @@ vitest_1.vi.mock("./require", () => ({
|
|
|
127
133
|
input: tokensDir,
|
|
128
134
|
output: "./output.json",
|
|
129
135
|
};
|
|
130
|
-
await
|
|
136
|
+
await run(args);
|
|
131
137
|
// Verify transformer was called with correct structure
|
|
132
138
|
(0, vitest_1.expect)(mockTransform).toHaveBeenCalledWith({
|
|
133
139
|
metadata: { tokenSetOrder: ["base", "semantic"] },
|
|
@@ -153,7 +159,7 @@ vitest_1.vi.mock("./require", () => ({
|
|
|
153
159
|
input: tokensDir,
|
|
154
160
|
output: "./output.json",
|
|
155
161
|
};
|
|
156
|
-
await (0, vitest_1.expect)(
|
|
162
|
+
await (0, vitest_1.expect)(run(args)).rejects.toThrow("Missing required configuration: handler");
|
|
157
163
|
});
|
|
158
164
|
});
|
|
159
165
|
});
|
package/dist/vercel/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.run = exports.configParser = void 0;
|
|
5
4
|
const deployments_1 = require("./deployments");
|
|
6
5
|
const argparse_1 = require("argparse");
|
|
6
|
+
const cli_1 = require("../shared/cli");
|
|
7
7
|
const configParser = (parser) => {
|
|
8
8
|
const commands = parser.add_subparsers({
|
|
9
9
|
title: "Vercel commands",
|
|
@@ -32,7 +32,6 @@ const configParser = (parser) => {
|
|
|
32
32
|
type: Number,
|
|
33
33
|
});
|
|
34
34
|
};
|
|
35
|
-
exports.configParser = configParser;
|
|
36
35
|
const run = async (args) => {
|
|
37
36
|
const accessToken = process.env.VERCEL_TOKEN;
|
|
38
37
|
switch (args.subcommand) {
|
|
@@ -52,14 +51,17 @@ const run = async (args) => {
|
|
|
52
51
|
break;
|
|
53
52
|
}
|
|
54
53
|
};
|
|
55
|
-
exports.
|
|
54
|
+
exports.default = (0, cli_1.defineCLIModule)({
|
|
55
|
+
configParser,
|
|
56
|
+
run,
|
|
57
|
+
});
|
|
56
58
|
async function main() {
|
|
57
59
|
const parser = new argparse_1.ArgumentParser({
|
|
58
60
|
description: "Vercel deployment utilities",
|
|
59
61
|
});
|
|
60
62
|
const args = parser.parse_args();
|
|
61
|
-
|
|
62
|
-
await
|
|
63
|
+
configParser(parser);
|
|
64
|
+
await run(args);
|
|
63
65
|
}
|
|
64
66
|
// Only run main if this file is being executed directly
|
|
65
67
|
if (require.main === module) {
|
package/dist/vercel/cli.test.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
const vitest_1 = require("vitest");
|
|
4
7
|
const argparse_1 = require("argparse");
|
|
5
|
-
const cli_1 = require("./cli");
|
|
8
|
+
const cli_1 = __importDefault(require("./cli"));
|
|
9
|
+
const { run, configParser } = cli_1.default;
|
|
6
10
|
// Mock the waitForDeploymentReady function
|
|
7
11
|
vitest_1.vi.mock("@interactivethings/scripts/vercel/deployments", () => ({
|
|
8
12
|
waitForDeploymentReady: vitest_1.vi.fn(),
|
|
@@ -18,7 +22,7 @@ const deployments_1 = require("@interactivethings/scripts/vercel/deployments");
|
|
|
18
22
|
(0, vitest_1.it)("should configure the argument parser correctly", () => {
|
|
19
23
|
const parser = new argparse_1.ArgumentParser();
|
|
20
24
|
const addSubparsersSpy = vitest_1.vi.spyOn(parser, "add_subparsers");
|
|
21
|
-
|
|
25
|
+
configParser(parser);
|
|
22
26
|
(0, vitest_1.expect)(addSubparsersSpy).toHaveBeenCalledWith({
|
|
23
27
|
title: "Vercel commands",
|
|
24
28
|
dest: "subcommand",
|
|
@@ -45,7 +49,7 @@ const deployments_1 = require("@interactivethings/scripts/vercel/deployments");
|
|
|
45
49
|
team: "test-team",
|
|
46
50
|
project: "test-project",
|
|
47
51
|
};
|
|
48
|
-
await
|
|
52
|
+
await run(args);
|
|
49
53
|
(0, vitest_1.expect)(deployments_1.waitForDeploymentReady).toHaveBeenCalledWith({
|
|
50
54
|
commitSha: "test-commit-sha",
|
|
51
55
|
interval: 5000,
|
|
@@ -67,7 +71,7 @@ const deployments_1 = require("@interactivethings/scripts/vercel/deployments");
|
|
|
67
71
|
team: "test-team",
|
|
68
72
|
project: "test-project",
|
|
69
73
|
};
|
|
70
|
-
await (0, vitest_1.expect)(
|
|
74
|
+
await (0, vitest_1.expect)(run(args)).rejects.toThrow("Could not retrieve deployment");
|
|
71
75
|
});
|
|
72
76
|
(0, vitest_1.it)("should throw error when waitForDeploymentReady fails", async () => {
|
|
73
77
|
const error = new Error("Network error");
|
|
@@ -80,7 +84,7 @@ const deployments_1 = require("@interactivethings/scripts/vercel/deployments");
|
|
|
80
84
|
team: "test-team",
|
|
81
85
|
project: "test-project",
|
|
82
86
|
};
|
|
83
|
-
await (0, vitest_1.expect)(
|
|
87
|
+
await (0, vitest_1.expect)(run(args)).rejects.toThrow("Network error");
|
|
84
88
|
});
|
|
85
89
|
});
|
|
86
90
|
});
|
|
@@ -1,41 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.waitForDeploymentReady = waitForDeploymentReady;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const response = await fetch(`https://vercel.com/api/v6/deployments?limit=20&projectId=${projectId}&state=READY,ERROR,BUILDING,QUEUED&teamId=${teamId}`, {
|
|
7
|
-
headers: {
|
|
8
|
-
Authorization: `Bearer ${accessToken}`,
|
|
9
|
-
},
|
|
10
|
-
}).then((x) => x.json());
|
|
11
|
-
const deployments = response.deployments.filter((deployment) => deployment.meta.githubCommitSha === commitSha);
|
|
12
|
-
return deployments;
|
|
13
|
-
}
|
|
14
|
-
catch (error) {
|
|
15
|
-
console.error("Error:", error);
|
|
16
|
-
return [];
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
const sleep = (duration) => new Promise((resolve) => setTimeout(resolve, duration));
|
|
4
|
+
const wait_deployment_1 = require("../shared/wait-deployment");
|
|
5
|
+
const vercel_1 = require("./vercel");
|
|
20
6
|
async function waitForDeploymentReady({ team, project, commitSha, interval, timeout, accessToken, }) {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
throw new Error("Deployment errored");
|
|
29
|
-
}
|
|
30
|
-
console.log(`Deployment not yet ready (state: ${deployments[0].state}), waiting ${interval}ms for deployment with commit ${commitSha}`);
|
|
31
|
-
await sleep(Math.min(end - Date.now(), interval));
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
console.log(`Deployment for commit ${commitSha} is READY`);
|
|
35
|
-
return deployments[0];
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (Date.now() > end) {
|
|
39
|
-
throw new Error("Timeout for waitForDeploymentReady");
|
|
40
|
-
}
|
|
7
|
+
const service = new vercel_1.VercelDeploymentService(team, project, accessToken);
|
|
8
|
+
return await (0, wait_deployment_1.waitForDeploymentReady)({
|
|
9
|
+
commitSha,
|
|
10
|
+
interval,
|
|
11
|
+
timeout,
|
|
12
|
+
deploymentService: service,
|
|
13
|
+
});
|
|
41
14
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VercelDeploymentService = void 0;
|
|
4
|
+
const getDeploymentState = (deployment) => {
|
|
5
|
+
return deployment.state;
|
|
6
|
+
};
|
|
7
|
+
const getDeploymentUrl = (deployment) => {
|
|
8
|
+
return `https://${deployment.url}`;
|
|
9
|
+
};
|
|
10
|
+
class VercelDeploymentService {
|
|
11
|
+
constructor(teamId, projectId, accessToken) {
|
|
12
|
+
this.teamId = teamId;
|
|
13
|
+
this.projectId = projectId;
|
|
14
|
+
this.accessToken = accessToken;
|
|
15
|
+
}
|
|
16
|
+
async fetchForCommit(commitSha) {
|
|
17
|
+
const response = await fetch(`https://vercel.com/api/v6/deployments?limit=20&projectId=${this.projectId}&state=READY,ERROR,BUILDING,QUEUED&teamId=${this.teamId}`, {
|
|
18
|
+
headers: {
|
|
19
|
+
Authorization: `Bearer ${this.accessToken}`,
|
|
20
|
+
},
|
|
21
|
+
})
|
|
22
|
+
.then((x) => x.json())
|
|
23
|
+
.then((x) => x);
|
|
24
|
+
const deployments = response.deployments.filter((deployment) => deployment.meta.githubCommitSha === commitSha);
|
|
25
|
+
return deployments.map((d) => ({
|
|
26
|
+
state: getDeploymentState(d),
|
|
27
|
+
url: getDeploymentUrl(d),
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.VercelDeploymentService = VercelDeploymentService;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interactivethings/scripts",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dist/index.js",
|
|
@@ -28,9 +28,7 @@
|
|
|
28
28
|
"start": "bun ./dist/cli.js"
|
|
29
29
|
},
|
|
30
30
|
"bin": {
|
|
31
|
-
"ixt": "dist/cli.js"
|
|
32
|
-
"wait-for-vercel-deploy": "dist/wait-for-vercel-deploy.js",
|
|
33
|
-
"mui-tokens-studio": "dist/mui-tokens-studio.js"
|
|
31
|
+
"ixt": "dist/cli.js"
|
|
34
32
|
},
|
|
35
33
|
"files": [
|
|
36
34
|
"dist",
|
|
@@ -42,13 +40,13 @@
|
|
|
42
40
|
"@semantic-release/changelog": "^6.0.3",
|
|
43
41
|
"@semantic-release/git": "^10.0.1",
|
|
44
42
|
"@semantic-release/github": "^11.0.6",
|
|
45
|
-
"@types/argparse": "^2.0.
|
|
43
|
+
"@types/argparse": "^2.0.17",
|
|
46
44
|
"@types/jscodeshift": "^0.11.10",
|
|
47
45
|
"argparse": "^2.0.1",
|
|
48
46
|
"jiti": "^2.6.1",
|
|
49
47
|
"ora": "^9.0.0",
|
|
50
48
|
"prompts": "^2.4.2",
|
|
51
|
-
"remeda": "^
|
|
49
|
+
"remeda": "^2.32.0",
|
|
52
50
|
"zod": "^4.1.11"
|
|
53
51
|
},
|
|
54
52
|
"devDependencies": {
|
|
@@ -57,7 +55,7 @@
|
|
|
57
55
|
"jscodeshift": "^0.15.1",
|
|
58
56
|
"oxlint": "^1.19.0",
|
|
59
57
|
"typescript": "^5.9.3",
|
|
60
|
-
"vitest": "^
|
|
58
|
+
"vitest": "^3.2.4"
|
|
61
59
|
},
|
|
62
60
|
"peerDependencies": {
|
|
63
61
|
"@next/env": "^15.5.4"
|