@intra-mart/accel 0.2.0 → 0.3.0-dev.202606150745
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 +148 -4
- package/dist/asset/deployer.js +8 -17
- package/dist/asset/foreach-replacement.d.ts +2 -0
- package/dist/asset/foreach-replacement.js +20 -0
- package/dist/asset/github-provider.d.ts +2 -0
- package/dist/asset/github-provider.js +37 -0
- package/dist/asset/local-provider.js +1 -22
- package/dist/asset/walker.js +4 -15
- package/dist/commands/attach.d.ts +13 -1
- package/dist/commands/attach.js +33 -12
- package/dist/commands/deploy.d.ts +62 -0
- package/dist/commands/deploy.js +293 -0
- package/dist/commands/init.d.ts +13 -1
- package/dist/commands/init.js +33 -12
- package/dist/commands/login.d.ts +31 -0
- package/dist/commands/login.js +75 -0
- package/dist/core/catalog.d.ts +11 -0
- package/dist/core/catalog.js +40 -0
- package/dist/core/condition-evaluator.js +6 -3
- package/dist/core/constants.d.ts +2 -2
- package/dist/core/constants.js +4 -9
- package/dist/core/eval-context.d.ts +3 -0
- package/dist/core/eval-context.js +45 -0
- package/dist/core/types.d.ts +76 -10
- package/dist/core/types.js +2 -1
- package/dist/core/validators.d.ts +7 -2
- package/dist/core/validators.js +25 -12
- package/dist/core/variable-interpolator.d.ts +1 -1
- package/dist/core/variable-interpolator.js +19 -19
- package/dist/deploy/api-client.d.ts +16 -0
- package/dist/deploy/api-client.js +105 -0
- package/dist/deploy/target-scanner.d.ts +5 -0
- package/dist/deploy/target-scanner.js +20 -0
- package/dist/deploy/target-selector.d.ts +11 -0
- package/dist/deploy/target-selector.js +16 -0
- package/dist/i18n/en.js +53 -1
- package/dist/i18n/ja.js +53 -1
- package/dist/i18n/zh_CN.js +53 -1
- package/dist/index.js +4 -0
- package/dist/interactive/credential-auth.d.ts +15 -0
- package/dist/interactive/credential-auth.js +61 -0
- package/dist/interactive/credentials-prompts.d.ts +4 -0
- package/dist/interactive/credentials-prompts.js +85 -0
- package/dist/interactive/prompts.d.ts +3 -0
- package/dist/interactive/prompts.js +125 -26
- package/dist/interactive/summary.js +12 -0
- package/dist/juggling/extractor.d.ts +3 -2
- package/dist/juggling/extractor.js +9 -9
- package/dist/utils/args.d.ts +1 -0
- package/dist/utils/args.js +4 -0
- package/dist/utils/credentials.d.ts +12 -0
- package/dist/utils/credentials.js +46 -0
- package/dist/utils/date-formatter.d.ts +1 -0
- package/dist/utils/date-formatter.js +23 -0
- package/dist/utils/gitignore.d.ts +1 -0
- package/dist/utils/gitignore.js +23 -0
- package/dist/utils/https.d.ts +2 -0
- package/dist/utils/https.js +44 -0
- package/dist/utils/settings-io.d.ts +1 -0
- package/dist/utils/settings-io.js +8 -0
- package/package.json +5 -5
- package/assets/assets.tar.gz +0 -0
- package/dist/asset/default-source.d.ts +0 -1
- package/dist/asset/default-source.js +0 -6
- package/dist/core/module-map.d.ts +0 -3
- package/dist/core/module-map.js +0 -7
- package/dist/core/version-map.d.ts +0 -7
- package/dist/core/version-map.js +0 -45
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import * as p from "@clack/prompts";
|
|
3
|
+
import { readFile, stat } from "node:fs/promises";
|
|
4
|
+
import { basename, resolve } from "node:path";
|
|
5
|
+
import { detectLocale } from "../utils/locale-detect.js";
|
|
6
|
+
import { formatEpochMillis } from "../utils/date-formatter.js";
|
|
7
|
+
import { readSettings, readSettingsSafe } from "../utils/settings-io.js";
|
|
8
|
+
import { persistCredentials as defaultPersistCredentials, resolveCredentialInputs, } from "../utils/credentials.js";
|
|
9
|
+
import { getMessage } from "../i18n/index.js";
|
|
10
|
+
import { lastFlagValue } from "../utils/args.js";
|
|
11
|
+
import { ensureCredentials as defaultEnsureCredentials, repromptCredentials as defaultRepromptCredentials, resolveCredentialsOrThrow as defaultResolveCredentialsOrThrow, } from "../interactive/credentials-prompts.js";
|
|
12
|
+
import { scanTargets as defaultScanTargets } from "../deploy/target-scanner.js";
|
|
13
|
+
import { selectDeployTarget } from "../deploy/target-selector.js";
|
|
14
|
+
import { verifyCredentialsLoop } from "../interactive/credential-auth.js";
|
|
15
|
+
import { createApiClient as defaultApiClientFactory, isDeployError, } from "../deploy/api-client.js";
|
|
16
|
+
export const toImmFileName = (zipPath) => {
|
|
17
|
+
const base = basename(zipPath);
|
|
18
|
+
return base.replace(/\.zip$/i, "") + ".imm";
|
|
19
|
+
};
|
|
20
|
+
const defaultPrompts = {
|
|
21
|
+
selectStaging: async (stagings, locale) => {
|
|
22
|
+
const res = await p.select({
|
|
23
|
+
message: getMessage("deploy.selectStaging", locale),
|
|
24
|
+
options: stagings.map((s) => ({
|
|
25
|
+
value: s.stagingId,
|
|
26
|
+
label: s.description
|
|
27
|
+
? `${s.stagingId} (${s.description})`
|
|
28
|
+
: s.stagingId,
|
|
29
|
+
})),
|
|
30
|
+
});
|
|
31
|
+
if (p.isCancel(res))
|
|
32
|
+
process.exit(0);
|
|
33
|
+
return res;
|
|
34
|
+
},
|
|
35
|
+
selectZip: async (zips, locale) => {
|
|
36
|
+
const res = await p.select({
|
|
37
|
+
message: getMessage("deploy.selectZip", locale),
|
|
38
|
+
options: zips.map((z) => ({ value: z, label: basename(z) })),
|
|
39
|
+
});
|
|
40
|
+
if (p.isCancel(res))
|
|
41
|
+
process.exit(0);
|
|
42
|
+
return res;
|
|
43
|
+
},
|
|
44
|
+
description: async (locale) => {
|
|
45
|
+
const res = await p.text({
|
|
46
|
+
message: getMessage("deploy.descriptionPrompt", locale),
|
|
47
|
+
defaultValue: "",
|
|
48
|
+
initialValue: "",
|
|
49
|
+
});
|
|
50
|
+
if (p.isCancel(res))
|
|
51
|
+
process.exit(0);
|
|
52
|
+
return res;
|
|
53
|
+
},
|
|
54
|
+
confirm: async (info, locale) => {
|
|
55
|
+
p.note([
|
|
56
|
+
`${getMessage("deploy.confirm.endpoint", locale)}: ${info.endpoint}`,
|
|
57
|
+
`${getMessage("deploy.confirm.stagingId", locale)}: ${info.stagingId}`,
|
|
58
|
+
`${getMessage("deploy.confirm.sourceFile", locale)}: ${info.sourceFile}`,
|
|
59
|
+
`${getMessage("deploy.confirm.sentAs", locale)}: ${info.sentAs}`,
|
|
60
|
+
].join("\n"));
|
|
61
|
+
const res = await p.confirm({
|
|
62
|
+
message: getMessage("deploy.confirm", locale),
|
|
63
|
+
initialValue: true,
|
|
64
|
+
});
|
|
65
|
+
if (p.isCancel(res))
|
|
66
|
+
process.exit(0);
|
|
67
|
+
return res;
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
const resolveLocale = async (projectDir) => {
|
|
71
|
+
try {
|
|
72
|
+
const settings = await readSettings(projectDir);
|
|
73
|
+
return settings.locale ?? detectLocale();
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return detectLocale();
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const formatDeployError = (err, locale) => {
|
|
80
|
+
if (err.kind === "network") {
|
|
81
|
+
return getMessage("deploy.error.network", locale, {
|
|
82
|
+
message: err.serverMessage ?? "",
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (err.serverMessage) {
|
|
86
|
+
return getMessage("deploy.error.server", locale, {
|
|
87
|
+
message: err.serverMessage,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
switch (err.status) {
|
|
91
|
+
case 401:
|
|
92
|
+
return getMessage("deploy.error.unauthorized", locale);
|
|
93
|
+
case 403:
|
|
94
|
+
return getMessage("deploy.error.forbidden", locale);
|
|
95
|
+
case 404:
|
|
96
|
+
return getMessage("deploy.error.notFound", locale);
|
|
97
|
+
case 400:
|
|
98
|
+
return getMessage("deploy.error.badRequest", locale);
|
|
99
|
+
case 500:
|
|
100
|
+
return getMessage("deploy.error.serverError", locale);
|
|
101
|
+
default:
|
|
102
|
+
return getMessage("deploy.error.unexpectedResponse", locale, {
|
|
103
|
+
status: String(err.status ?? "?"),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const resolveZipPath = async (opts) => {
|
|
108
|
+
const { projectDir, locale, nonInteractive, fileArg, scan, selectZip } = opts;
|
|
109
|
+
if (fileArg && fileArg.length > 0) {
|
|
110
|
+
const filePath = resolve(projectDir, fileArg);
|
|
111
|
+
try {
|
|
112
|
+
const s = await stat(filePath);
|
|
113
|
+
if (!s.isFile())
|
|
114
|
+
throw new Error("not a file");
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
p.log.error(getMessage("deploy.error.fileNotFound", locale, { path: fileArg }));
|
|
118
|
+
throw new Error("file not found");
|
|
119
|
+
}
|
|
120
|
+
return filePath;
|
|
121
|
+
}
|
|
122
|
+
const zips = await scan(projectDir);
|
|
123
|
+
if (zips.length === 0) {
|
|
124
|
+
p.log.error(getMessage("deploy.error.noTargetZip", locale));
|
|
125
|
+
throw new Error("no target zip");
|
|
126
|
+
}
|
|
127
|
+
const settings = await readSettingsSafe(projectDir);
|
|
128
|
+
const selection = selectDeployTarget(zips, settings
|
|
129
|
+
? { artifactId: settings.artifactId, projectVersion: settings.projectVersion }
|
|
130
|
+
: null);
|
|
131
|
+
if ("auto" in selection)
|
|
132
|
+
return selection.auto;
|
|
133
|
+
if (nonInteractive) {
|
|
134
|
+
p.log.error(getMessage("deploy.error.zipNotResolved", locale));
|
|
135
|
+
throw new Error("zip not resolved");
|
|
136
|
+
}
|
|
137
|
+
return selection.candidates.length === 1
|
|
138
|
+
? selection.candidates[0]
|
|
139
|
+
: await selectZip(selection.candidates, locale);
|
|
140
|
+
};
|
|
141
|
+
export const runDeploy = async (deps) => {
|
|
142
|
+
const { projectDir } = deps;
|
|
143
|
+
const locale = deps.locale ?? (await resolveLocale(projectDir));
|
|
144
|
+
const ensureCreds = deps.ensureCredentials ?? defaultEnsureCredentials;
|
|
145
|
+
const reprompt = deps.repromptCredentials ?? defaultRepromptCredentials;
|
|
146
|
+
const resolveOrThrow = deps.resolveCredentialsOrThrow ?? defaultResolveCredentialsOrThrow;
|
|
147
|
+
const persist = deps.persistCredentials ?? defaultPersistCredentials;
|
|
148
|
+
const scan = deps.scanTargets ?? defaultScanTargets;
|
|
149
|
+
const apiClientFactory = deps.apiClientFactory ?? defaultApiClientFactory;
|
|
150
|
+
const prompts = deps.prompts ?? defaultPrompts;
|
|
151
|
+
const env = deps.env ?? process.env;
|
|
152
|
+
const nonInteractive = deps.nonInteractive ?? false;
|
|
153
|
+
const seed = resolveCredentialInputs({ endpoint: deps.endpoint, apiKey: deps.apiKey }, env);
|
|
154
|
+
const fileArg = deps.file?.trim();
|
|
155
|
+
const stagingArg = deps.stagingId?.trim();
|
|
156
|
+
p.intro(getMessage("deploy.intro", locale));
|
|
157
|
+
const spin = p.spinner();
|
|
158
|
+
const initialCreds = nonInteractive
|
|
159
|
+
? await resolveOrThrow(projectDir, locale, seed)
|
|
160
|
+
: await ensureCreds(projectDir, locale, seed);
|
|
161
|
+
const { creds, api } = await verifyCredentialsLoop(projectDir, locale, initialCreds, { dirty: false, interactive: !nonInteractive }, {
|
|
162
|
+
apiClientFactory,
|
|
163
|
+
repromptCredentials: reprompt,
|
|
164
|
+
persistCredentials: persist,
|
|
165
|
+
});
|
|
166
|
+
let stagingId;
|
|
167
|
+
if (stagingArg && stagingArg.length > 0) {
|
|
168
|
+
stagingId = stagingArg;
|
|
169
|
+
}
|
|
170
|
+
else if (nonInteractive) {
|
|
171
|
+
p.log.error(getMessage("deploy.error.missingStagingId", locale));
|
|
172
|
+
throw new Error("missing staging id");
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
let stagings;
|
|
176
|
+
spin.start(getMessage("deploy.progress.fetchingStagings", locale));
|
|
177
|
+
try {
|
|
178
|
+
stagings = await api.listStagings();
|
|
179
|
+
spin.stop(getMessage("deploy.progress.fetchingStagings", locale));
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
spin.stop(getMessage("deploy.progress.fetchingStagings", locale));
|
|
183
|
+
throw logAndRethrow(err, locale);
|
|
184
|
+
}
|
|
185
|
+
if (stagings.length === 0) {
|
|
186
|
+
p.log.error(getMessage("deploy.error.noStagings", locale));
|
|
187
|
+
throw new Error("no stagings");
|
|
188
|
+
}
|
|
189
|
+
stagingId = await prompts.selectStaging(stagings, locale);
|
|
190
|
+
}
|
|
191
|
+
const zipPath = await resolveZipPath({
|
|
192
|
+
projectDir,
|
|
193
|
+
locale,
|
|
194
|
+
nonInteractive,
|
|
195
|
+
fileArg,
|
|
196
|
+
scan,
|
|
197
|
+
selectZip: prompts.selectZip,
|
|
198
|
+
});
|
|
199
|
+
const description = (deps.description !== undefined
|
|
200
|
+
? deps.description
|
|
201
|
+
: nonInteractive
|
|
202
|
+
? ""
|
|
203
|
+
: await prompts.description(locale)).trim();
|
|
204
|
+
const immName = toImmFileName(zipPath);
|
|
205
|
+
if (!nonInteractive) {
|
|
206
|
+
const confirmed = await prompts.confirm({
|
|
207
|
+
endpoint: creds.endpoint,
|
|
208
|
+
stagingId,
|
|
209
|
+
sourceFile: basename(zipPath),
|
|
210
|
+
sentAs: immName,
|
|
211
|
+
}, locale);
|
|
212
|
+
if (!confirmed) {
|
|
213
|
+
p.log.info(getMessage("deploy.cancelled", locale));
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const bytes = await readFile(zipPath);
|
|
218
|
+
spin.start(getMessage("deploy.progress.deploying", locale));
|
|
219
|
+
let result;
|
|
220
|
+
try {
|
|
221
|
+
result = await api.createDeployment(stagingId, bytes, immName, description.length > 0 ? description : undefined);
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
spin.stop(getMessage("deploy.progress.deploying", locale));
|
|
225
|
+
throw logAndRethrow(err, locale);
|
|
226
|
+
}
|
|
227
|
+
spin.stop(getMessage("deploy.progress.deploying", locale));
|
|
228
|
+
p.note([
|
|
229
|
+
`${getMessage("deploy.result.deployId", locale)}: ${result.deployId}`,
|
|
230
|
+
`${getMessage("deploy.result.stagingId", locale)}: ${result.stagingId}`,
|
|
231
|
+
`${getMessage("deploy.result.status", locale)}: ${result.status}`,
|
|
232
|
+
`${getMessage("deploy.result.createDate", locale)}: ${formatEpochMillis(result.createDate, locale)}`,
|
|
233
|
+
].join("\n"));
|
|
234
|
+
p.outro(getMessage("deploy.success", locale));
|
|
235
|
+
};
|
|
236
|
+
const logAndRethrow = (err, locale) => {
|
|
237
|
+
if (isDeployError(err)) {
|
|
238
|
+
p.log.error(formatDeployError(err, locale));
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
p.log.error(err instanceof Error ? err.message : String(err));
|
|
242
|
+
}
|
|
243
|
+
return err;
|
|
244
|
+
};
|
|
245
|
+
export const deployCommand = defineCommand({
|
|
246
|
+
meta: {
|
|
247
|
+
name: "deploy",
|
|
248
|
+
description: "Deploy build artifacts to an iAP staging environment",
|
|
249
|
+
},
|
|
250
|
+
args: {
|
|
251
|
+
endpoint: {
|
|
252
|
+
type: "string",
|
|
253
|
+
description: "iAP base URL (or set ACCEL_ENDPOINT)",
|
|
254
|
+
},
|
|
255
|
+
"api-key": {
|
|
256
|
+
type: "string",
|
|
257
|
+
description: "OAuth Bearer token. Prefer the ACCEL_API_KEY env var (argv leaks to process listings / CI logs)",
|
|
258
|
+
},
|
|
259
|
+
"staging-id": {
|
|
260
|
+
type: "string",
|
|
261
|
+
description: "Target staging ID (required in non-interactive mode)",
|
|
262
|
+
},
|
|
263
|
+
file: {
|
|
264
|
+
type: "string",
|
|
265
|
+
description: "Path to the zip to deploy (not restricted to ./target/)",
|
|
266
|
+
},
|
|
267
|
+
description: {
|
|
268
|
+
type: "string",
|
|
269
|
+
description: "Deployment description",
|
|
270
|
+
},
|
|
271
|
+
"non-interactive": {
|
|
272
|
+
type: "boolean",
|
|
273
|
+
description: "Non-interactive mode (no prompts; exits non-zero on failure)",
|
|
274
|
+
default: false,
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
run: async ({ args }) => {
|
|
278
|
+
try {
|
|
279
|
+
await runDeploy({
|
|
280
|
+
projectDir: process.cwd(),
|
|
281
|
+
nonInteractive: args["non-interactive"],
|
|
282
|
+
endpoint: lastFlagValue(args.endpoint),
|
|
283
|
+
apiKey: lastFlagValue(args["api-key"]),
|
|
284
|
+
stagingId: lastFlagValue(args["staging-id"]),
|
|
285
|
+
file: lastFlagValue(args.file),
|
|
286
|
+
description: lastFlagValue(args.description),
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
process.exit(1);
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
});
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -16,6 +16,10 @@ export declare const initCommand: import("citty").CommandDef<{
|
|
|
16
16
|
type: "string";
|
|
17
17
|
description: string;
|
|
18
18
|
};
|
|
19
|
+
feature: {
|
|
20
|
+
type: "string";
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
19
23
|
group: {
|
|
20
24
|
type: "string";
|
|
21
25
|
description: string;
|
|
@@ -67,11 +71,19 @@ export declare const initCommand: import("citty").CommandDef<{
|
|
|
67
71
|
description: string;
|
|
68
72
|
default: false;
|
|
69
73
|
};
|
|
74
|
+
"asset-server-url": {
|
|
75
|
+
type: "string";
|
|
76
|
+
description: string;
|
|
77
|
+
};
|
|
78
|
+
"asset-ref": {
|
|
79
|
+
type: "string";
|
|
80
|
+
description: string;
|
|
81
|
+
};
|
|
70
82
|
"asset-source": {
|
|
71
83
|
type: "string";
|
|
72
84
|
description: string;
|
|
73
85
|
};
|
|
74
|
-
"
|
|
86
|
+
"debug-server-url": {
|
|
75
87
|
type: "string";
|
|
76
88
|
description: string;
|
|
77
89
|
};
|
package/dist/commands/init.js
CHANGED
|
@@ -3,12 +3,12 @@ import * as p from "@clack/prompts";
|
|
|
3
3
|
import { mkdir, stat } from "node:fs/promises";
|
|
4
4
|
import { execSync } from "node:child_process";
|
|
5
5
|
import { resolve } from "node:path";
|
|
6
|
-
import { CLI_VERSION } from "../core/constants.js";
|
|
6
|
+
import { CLI_VERSION, DEFAULT_ASSET_REPO_URL, DEFAULT_ASSET_REF, } from "../core/constants.js";
|
|
7
7
|
import { runPrompts } from "../interactive/prompts.js";
|
|
8
8
|
import { deployAssets } from "../asset/deployer.js";
|
|
9
9
|
import { createLocalAssetProvider } from "../asset/local-provider.js";
|
|
10
10
|
import { createFileAssetProvider } from "../asset/file-provider.js";
|
|
11
|
-
import {
|
|
11
|
+
import { createGitHubAssetProvider } from "../asset/github-provider.js";
|
|
12
12
|
import { getMessage } from "../i18n/index.js";
|
|
13
13
|
import { detectLocale } from "../utils/locale-detect.js";
|
|
14
14
|
import { commandExists } from "../utils/command-exists.js";
|
|
@@ -32,11 +32,15 @@ export const initCommand = defineCommand({
|
|
|
32
32
|
},
|
|
33
33
|
"accelplatform-version": {
|
|
34
34
|
type: "string",
|
|
35
|
-
description: "iAP version (e.g., 2026-
|
|
35
|
+
description: "iAP version (e.g., 2026-spring)",
|
|
36
36
|
},
|
|
37
37
|
module: {
|
|
38
38
|
type: "string",
|
|
39
|
-
description: "Modules to use (comma-separated)",
|
|
39
|
+
description: "Modules to use (comma-separated artifactIds, e.g., im_workflow)",
|
|
40
|
+
},
|
|
41
|
+
feature: {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "Features to use (comma-separated function ids, e.g., jssp)",
|
|
40
44
|
},
|
|
41
45
|
group: {
|
|
42
46
|
type: "string",
|
|
@@ -89,13 +93,21 @@ export const initCommand = defineCommand({
|
|
|
89
93
|
description: "Non-interactive mode",
|
|
90
94
|
default: false,
|
|
91
95
|
},
|
|
96
|
+
"asset-server-url": {
|
|
97
|
+
type: "string",
|
|
98
|
+
description: "GitHub repository URL to fetch assets from (overrides the default repository)",
|
|
99
|
+
},
|
|
100
|
+
"asset-ref": {
|
|
101
|
+
type: "string",
|
|
102
|
+
description: "Git ref (branch/tag/commit) to fetch from the GitHub asset repository. Default: master",
|
|
103
|
+
},
|
|
92
104
|
"asset-source": {
|
|
93
105
|
type: "string",
|
|
94
|
-
description: "Local asset source path (tar archive or extracted directory)
|
|
106
|
+
description: "(debug) Local asset source path (tar archive or extracted directory)",
|
|
95
107
|
},
|
|
96
|
-
"
|
|
108
|
+
"debug-server-url": {
|
|
97
109
|
type: "string",
|
|
98
|
-
description: "
|
|
110
|
+
description: "(debug) Local asset server URL serving GET /archive",
|
|
99
111
|
},
|
|
100
112
|
},
|
|
101
113
|
run: async ({ args }) => {
|
|
@@ -105,6 +117,10 @@ export const initCommand = defineCommand({
|
|
|
105
117
|
const modules = moduleArg
|
|
106
118
|
? moduleArg.split(",").map((m) => m.trim())
|
|
107
119
|
: undefined;
|
|
120
|
+
const featureArg = args.feature;
|
|
121
|
+
const features = featureArg
|
|
122
|
+
? featureArg.split(",").map((f) => f.trim())
|
|
123
|
+
: undefined;
|
|
108
124
|
const agentArg = args.agent;
|
|
109
125
|
const promptOpts = {
|
|
110
126
|
name: projectName,
|
|
@@ -112,6 +128,7 @@ export const initCommand = defineCommand({
|
|
|
112
128
|
jugglingProject: args["juggling-project"],
|
|
113
129
|
accelplatformVersion: args["accelplatform-version"],
|
|
114
130
|
module: modules,
|
|
131
|
+
feature: features,
|
|
115
132
|
group: args.group,
|
|
116
133
|
projectVersion: args["project-version"],
|
|
117
134
|
description: args.description,
|
|
@@ -153,6 +170,7 @@ export const initCommand = defineCommand({
|
|
|
153
170
|
description: resolved.description,
|
|
154
171
|
accelplatformVersion: resolved.accelplatformVersion,
|
|
155
172
|
modules: resolved.modules,
|
|
173
|
+
features: resolved.features,
|
|
156
174
|
database: resolved.database,
|
|
157
175
|
agents: resolved.agents,
|
|
158
176
|
javascript: resolved.javascript,
|
|
@@ -165,11 +183,14 @@ export const initCommand = defineCommand({
|
|
|
165
183
|
if (isInteractive) {
|
|
166
184
|
printSummary(settings, projectDir, locale);
|
|
167
185
|
}
|
|
168
|
-
const
|
|
169
|
-
const
|
|
170
|
-
const provider =
|
|
171
|
-
?
|
|
172
|
-
:
|
|
186
|
+
const assetSource = args["asset-source"];
|
|
187
|
+
const debugServerUrl = args["debug-server-url"];
|
|
188
|
+
const provider = assetSource
|
|
189
|
+
? createFileAssetProvider(assetSource)
|
|
190
|
+
: debugServerUrl
|
|
191
|
+
? createLocalAssetProvider(debugServerUrl)
|
|
192
|
+
: createGitHubAssetProvider(args["asset-server-url"] ??
|
|
193
|
+
DEFAULT_ASSET_REPO_URL, args["asset-ref"] ?? DEFAULT_ASSET_REF);
|
|
173
194
|
await deployAssets({
|
|
174
195
|
projectDir,
|
|
175
196
|
settings,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AccelCredentials } from "../core/types.js";
|
|
2
|
+
import { type ApiClient } from "../deploy/api-client.js";
|
|
3
|
+
export type RunLoginDeps = {
|
|
4
|
+
projectDir: string;
|
|
5
|
+
locale?: string;
|
|
6
|
+
nonInteractive?: boolean;
|
|
7
|
+
endpoint?: string;
|
|
8
|
+
apiKey?: string;
|
|
9
|
+
env?: Record<string, string | undefined>;
|
|
10
|
+
readCredentials?: (projectDir: string) => Promise<Partial<AccelCredentials>>;
|
|
11
|
+
repromptCredentials?: (current: AccelCredentials, locale: string, seed?: Partial<AccelCredentials>) => Promise<AccelCredentials>;
|
|
12
|
+
resolveCredentialsOrThrow?: (projectDir: string, locale: string, seed: Partial<AccelCredentials>) => Promise<AccelCredentials>;
|
|
13
|
+
persistCredentials?: (projectDir: string, creds: AccelCredentials) => Promise<void>;
|
|
14
|
+
apiClientFactory?: (endpoint: string, apiKey: string) => ApiClient;
|
|
15
|
+
};
|
|
16
|
+
export declare const runLogin: (deps: RunLoginDeps) => Promise<void>;
|
|
17
|
+
export declare const loginCommand: import("citty").CommandDef<{
|
|
18
|
+
endpoint: {
|
|
19
|
+
type: "string";
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
"api-key": {
|
|
23
|
+
type: "string";
|
|
24
|
+
description: string;
|
|
25
|
+
};
|
|
26
|
+
"non-interactive": {
|
|
27
|
+
type: "boolean";
|
|
28
|
+
description: string;
|
|
29
|
+
default: false;
|
|
30
|
+
};
|
|
31
|
+
}>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import * as p from "@clack/prompts";
|
|
3
|
+
import { detectLocale } from "../utils/locale-detect.js";
|
|
4
|
+
import { readSettingsSafe } from "../utils/settings-io.js";
|
|
5
|
+
import { readCredentials as defaultReadCredentials, persistCredentials as defaultPersistCredentials, resolveCredentialInputs, } from "../utils/credentials.js";
|
|
6
|
+
import { repromptCredentials as defaultRepromptCredentials, resolveCredentialsOrThrow as defaultResolveCredentialsOrThrow, } from "../interactive/credentials-prompts.js";
|
|
7
|
+
import { verifyCredentialsLoop } from "../interactive/credential-auth.js";
|
|
8
|
+
import { createApiClient as defaultApiClientFactory, } from "../deploy/api-client.js";
|
|
9
|
+
import { getMessage } from "../i18n/index.js";
|
|
10
|
+
import { lastFlagValue } from "../utils/args.js";
|
|
11
|
+
const resolveLocale = async (projectDir) => {
|
|
12
|
+
const settings = await readSettingsSafe(projectDir);
|
|
13
|
+
return settings?.locale ?? detectLocale();
|
|
14
|
+
};
|
|
15
|
+
export const runLogin = async (deps) => {
|
|
16
|
+
const { projectDir } = deps;
|
|
17
|
+
const locale = deps.locale ?? (await resolveLocale(projectDir));
|
|
18
|
+
const read = deps.readCredentials ?? defaultReadCredentials;
|
|
19
|
+
const reprompt = deps.repromptCredentials ?? defaultRepromptCredentials;
|
|
20
|
+
const resolveOrThrow = deps.resolveCredentialsOrThrow ?? defaultResolveCredentialsOrThrow;
|
|
21
|
+
const persist = deps.persistCredentials ?? defaultPersistCredentials;
|
|
22
|
+
const apiClientFactory = deps.apiClientFactory ?? defaultApiClientFactory;
|
|
23
|
+
const env = deps.env ?? process.env;
|
|
24
|
+
const seed = resolveCredentialInputs({ endpoint: deps.endpoint, apiKey: deps.apiKey }, env);
|
|
25
|
+
p.intro(getMessage("login.intro", locale));
|
|
26
|
+
let initial;
|
|
27
|
+
if (deps.nonInteractive) {
|
|
28
|
+
initial = await resolveOrThrow(projectDir, locale, seed);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const existing = await read(projectDir);
|
|
32
|
+
initial = await reprompt({ endpoint: existing.endpoint ?? "", apiKey: existing.apiKey ?? "" }, locale, seed);
|
|
33
|
+
}
|
|
34
|
+
const { creds } = await verifyCredentialsLoop(projectDir, locale, initial, { dirty: true, interactive: !deps.nonInteractive }, {
|
|
35
|
+
apiClientFactory,
|
|
36
|
+
repromptCredentials: reprompt,
|
|
37
|
+
persistCredentials: persist,
|
|
38
|
+
});
|
|
39
|
+
p.log.success(`endpoint: ${creds.endpoint}`);
|
|
40
|
+
p.outro(getMessage("login.complete", locale));
|
|
41
|
+
};
|
|
42
|
+
export const loginCommand = defineCommand({
|
|
43
|
+
meta: {
|
|
44
|
+
name: "login",
|
|
45
|
+
description: "Configure and verify iAP connection credentials",
|
|
46
|
+
},
|
|
47
|
+
args: {
|
|
48
|
+
endpoint: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "iAP base URL (or set ACCEL_ENDPOINT)",
|
|
51
|
+
},
|
|
52
|
+
"api-key": {
|
|
53
|
+
type: "string",
|
|
54
|
+
description: "OAuth Bearer token. Prefer the ACCEL_API_KEY env var (argv leaks to process listings / CI logs)",
|
|
55
|
+
},
|
|
56
|
+
"non-interactive": {
|
|
57
|
+
type: "boolean",
|
|
58
|
+
description: "Non-interactive mode (no prompts; exits non-zero on failure)",
|
|
59
|
+
default: false,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
run: async ({ args }) => {
|
|
63
|
+
try {
|
|
64
|
+
await runLogin({
|
|
65
|
+
projectDir: process.cwd(),
|
|
66
|
+
nonInteractive: args["non-interactive"],
|
|
67
|
+
endpoint: lastFlagValue(args.endpoint),
|
|
68
|
+
apiKey: lastFlagValue(args["api-key"]),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Release, ModuleEntry, FunctionEntry, Labels } from "@intra-mart/catalog";
|
|
2
|
+
import type { AccelplatformVersion, ModuleContextItem, FeatureContextItem } from "./types.js";
|
|
3
|
+
export type { Release, ModuleEntry, FunctionEntry, Labels };
|
|
4
|
+
export declare const getReleases: () => readonly Release[];
|
|
5
|
+
export declare const findReleaseById: (id: string) => Release | undefined;
|
|
6
|
+
export declare const findReleaseBySemver: (semver: string) => Release | undefined;
|
|
7
|
+
export declare const resolveAccelplatformVersion: (id: string) => AccelplatformVersion;
|
|
8
|
+
export declare const resolveLabel: (labels: Labels, locale: string) => string;
|
|
9
|
+
export declare const findModuleByCatalogId: (release: Release, id: string) => ModuleEntry | undefined;
|
|
10
|
+
export declare const toModuleContextItems: (release: Release, artifactIds: string[], locale: string) => ModuleContextItem[];
|
|
11
|
+
export declare const toFeatureContextItems: (release: Release, functionIds: string[], locale: string) => FeatureContextItem[];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { catalog } from "@intra-mart/catalog";
|
|
2
|
+
export const getReleases = () => catalog;
|
|
3
|
+
export const findReleaseById = (id) => catalog.find((r) => r.id === id);
|
|
4
|
+
export const findReleaseBySemver = (semver) => catalog.find((r) => r.version === semver);
|
|
5
|
+
export const resolveAccelplatformVersion = (id) => {
|
|
6
|
+
const release = findReleaseById(id);
|
|
7
|
+
if (!release) {
|
|
8
|
+
throw new Error(`Unknown iAP release id: ${id}`);
|
|
9
|
+
}
|
|
10
|
+
return { label: release.id, semver: release.version };
|
|
11
|
+
};
|
|
12
|
+
export const resolveLabel = (labels, locale) => labels[locale] ?? labels.en;
|
|
13
|
+
export const findModuleByCatalogId = (release, id) => release.modules.find((m) => m.id === id);
|
|
14
|
+
export const toModuleContextItems = (release, artifactIds, locale) => artifactIds.flatMap((artifactId) => {
|
|
15
|
+
const entry = release.modules.find((m) => m.artifactId === artifactId);
|
|
16
|
+
if (!entry)
|
|
17
|
+
return [];
|
|
18
|
+
return [
|
|
19
|
+
{
|
|
20
|
+
id: entry.id,
|
|
21
|
+
groupId: entry.groupId,
|
|
22
|
+
artifactId: entry.artifactId,
|
|
23
|
+
version: entry.version,
|
|
24
|
+
name: entry.name,
|
|
25
|
+
label: resolveLabel(entry.labels, locale),
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
});
|
|
29
|
+
export const toFeatureContextItems = (release, functionIds, locale) => functionIds.flatMap((functionId) => {
|
|
30
|
+
const entry = release.functions.find((f) => f.id === functionId);
|
|
31
|
+
if (!entry)
|
|
32
|
+
return [];
|
|
33
|
+
return [
|
|
34
|
+
{
|
|
35
|
+
id: entry.id,
|
|
36
|
+
name: entry.name,
|
|
37
|
+
label: resolveLabel(entry.labels, locale),
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { satisfies } from "semver";
|
|
2
|
-
import { isAndCondition, isOrCondition,
|
|
2
|
+
import { isAndCondition, isOrCondition, isAccelplatformVersionCondition, isModuleCondition, isFeatureCondition, isLocaleCondition, isAgentCondition, isPackageManagerCondition, isJavascriptCondition, } from "./types.js";
|
|
3
3
|
export const evaluateCondition = (condition, context) => {
|
|
4
4
|
if (condition === undefined) {
|
|
5
5
|
return true;
|
|
@@ -10,12 +10,15 @@ export const evaluateCondition = (condition, context) => {
|
|
|
10
10
|
if (isOrCondition(condition)) {
|
|
11
11
|
return condition.or.some((c) => evaluateCondition(c, context));
|
|
12
12
|
}
|
|
13
|
-
if (
|
|
14
|
-
return satisfies(context.
|
|
13
|
+
if (isAccelplatformVersionCondition(condition)) {
|
|
14
|
+
return satisfies(context.accelplatformVersion.semver, condition.accelplatformVersion);
|
|
15
15
|
}
|
|
16
16
|
if (isModuleCondition(condition)) {
|
|
17
17
|
return context.modules.includes(condition.module);
|
|
18
18
|
}
|
|
19
|
+
if (isFeatureCondition(condition)) {
|
|
20
|
+
return context.features.includes(condition.feature);
|
|
21
|
+
}
|
|
19
22
|
if (isLocaleCondition(condition)) {
|
|
20
23
|
return context.locale === condition.locale;
|
|
21
24
|
}
|
package/dist/core/constants.d.ts
CHANGED
|
@@ -4,10 +4,10 @@ export declare const DATABASE_OPTIONS: readonly ["postgresql", "oracle", "sqlser
|
|
|
4
4
|
export type DatabaseOption = (typeof DATABASE_OPTIONS)[number];
|
|
5
5
|
export declare const AGENT_OPTIONS: readonly ["claude-code", "github-copilot"];
|
|
6
6
|
export type AgentOption = (typeof AGENT_OPTIONS)[number];
|
|
7
|
-
export declare const MODULE_OPTIONS: readonly ["workflow", "bpm", "copilot", "imbox", "pdfd", "kaiden"];
|
|
8
|
-
export type ModuleOption = (typeof MODULE_OPTIONS)[number];
|
|
9
7
|
export declare const LOCALE_OPTIONS: readonly ["ja", "en", "zh_CN"];
|
|
10
8
|
export type LocaleOption = (typeof LOCALE_OPTIONS)[number];
|
|
11
9
|
export declare const PACKAGE_MANAGER_OPTIONS: readonly ["bun", "npm", "yarn", "pnpm"];
|
|
12
10
|
export type PackageManagerOption = (typeof PACKAGE_MANAGER_OPTIONS)[number];
|
|
11
|
+
export declare const DEFAULT_ASSET_REPO_URL = "https://github.com/accelplatform/skills";
|
|
12
|
+
export declare const DEFAULT_ASSET_REF = "experiment";
|
|
13
13
|
export declare const DEFAULT_SETTINGS: Omit<AccelSettings, "cliVersion" | "createdAt" | "deployedAssets">;
|
package/dist/core/constants.js
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
export const CLI_VERSION = "0.1.0";
|
|
2
2
|
export const DATABASE_OPTIONS = ["postgresql", "oracle", "sqlserver"];
|
|
3
3
|
export const AGENT_OPTIONS = ["claude-code", "github-copilot"];
|
|
4
|
-
export const MODULE_OPTIONS = [
|
|
5
|
-
"workflow",
|
|
6
|
-
"bpm",
|
|
7
|
-
"copilot",
|
|
8
|
-
"imbox",
|
|
9
|
-
"pdfd",
|
|
10
|
-
"kaiden",
|
|
11
|
-
];
|
|
12
4
|
export const LOCALE_OPTIONS = ["ja", "en", "zh_CN"];
|
|
13
5
|
export const PACKAGE_MANAGER_OPTIONS = [
|
|
14
6
|
"bun",
|
|
@@ -16,14 +8,17 @@ export const PACKAGE_MANAGER_OPTIONS = [
|
|
|
16
8
|
"yarn",
|
|
17
9
|
"pnpm",
|
|
18
10
|
];
|
|
11
|
+
export const DEFAULT_ASSET_REPO_URL = "https://github.com/accelplatform/skills";
|
|
12
|
+
export const DEFAULT_ASSET_REF = "experiment";
|
|
19
13
|
export const DEFAULT_SETTINGS = {
|
|
20
14
|
name: "my-accel-project",
|
|
21
15
|
artifactId: "",
|
|
22
16
|
group: "com.example",
|
|
23
17
|
projectVersion: "0.1.0",
|
|
24
18
|
description: "",
|
|
25
|
-
accelplatformVersion: "
|
|
19
|
+
accelplatformVersion: { label: "2026-spring", semver: "8.0.39" },
|
|
26
20
|
modules: [],
|
|
21
|
+
features: [],
|
|
27
22
|
database: "postgresql",
|
|
28
23
|
agents: ["claude-code", "github-copilot"],
|
|
29
24
|
javascript: false,
|