@intra-mart/accel 0.1.0 → 0.3.0-next.202605250439
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 +67 -5
- package/assets/assets.tar.gz +0 -0
- package/dist/asset/deployer.d.ts +13 -0
- package/dist/asset/deployer.js +84 -13
- package/dist/asset/walker.js +2 -0
- package/dist/commands/attach.d.ts +9 -0
- package/dist/commands/attach.js +84 -3
- package/dist/commands/deploy.d.ts +26 -0
- package/dist/commands/deploy.js +188 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +20 -1
- package/dist/core/condition-evaluator.js +7 -1
- package/dist/core/constants.d.ts +2 -0
- package/dist/core/constants.js +8 -1
- package/dist/core/types.d.ts +51 -1
- package/dist/core/types.js +2 -0
- package/dist/core/validators.d.ts +2 -1
- package/dist/core/validators.js +58 -25
- package/dist/core/variable-interpolator.js +1 -0
- package/dist/deploy/api-client.d.ts +15 -0
- package/dist/deploy/api-client.js +81 -0
- package/dist/deploy/target-scanner.d.ts +5 -0
- package/dist/deploy/target-scanner.js +20 -0
- package/dist/i18n/en.js +80 -4
- package/dist/i18n/ja.js +83 -7
- package/dist/i18n/zh_CN.js +83 -7
- package/dist/index.js +2 -0
- package/dist/interactive/credentials-prompts.d.ts +2 -0
- package/dist/interactive/credentials-prompts.js +43 -0
- package/dist/interactive/format.d.ts +2 -0
- package/dist/interactive/format.js +33 -0
- package/dist/interactive/next-steps.d.ts +8 -0
- package/dist/interactive/next-steps.js +22 -0
- package/dist/interactive/progress.d.ts +2 -0
- package/dist/interactive/progress.js +21 -0
- package/dist/interactive/prompts.d.ts +1 -0
- package/dist/interactive/prompts.js +74 -15
- package/dist/interactive/summary.d.ts +3 -0
- package/dist/interactive/summary.js +58 -0
- package/dist/utils/credentials.d.ts +5 -0
- package/dist/utils/credentials.js +25 -0
- package/dist/utils/gitignore.d.ts +1 -0
- package/dist/utils/gitignore.js +23 -0
- package/package.json +2 -2
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import * as p from "@clack/prompts";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { basename } from "node:path";
|
|
5
|
+
import { detectLocale } from "../utils/locale-detect.js";
|
|
6
|
+
import { readSettings } from "../utils/settings-io.js";
|
|
7
|
+
import { getMessage } from "../i18n/index.js";
|
|
8
|
+
import { ensureCredentials as defaultEnsureCredentials } from "../interactive/credentials-prompts.js";
|
|
9
|
+
import { scanTargets as defaultScanTargets } from "../deploy/target-scanner.js";
|
|
10
|
+
import { createApiClient as defaultApiClientFactory, isDeployError, } from "../deploy/api-client.js";
|
|
11
|
+
export const toImmFileName = (zipPath) => {
|
|
12
|
+
const base = basename(zipPath);
|
|
13
|
+
return base.replace(/\.zip$/i, "") + ".imm";
|
|
14
|
+
};
|
|
15
|
+
const defaultPrompts = {
|
|
16
|
+
selectStaging: async (stagings, locale) => {
|
|
17
|
+
const res = await p.select({
|
|
18
|
+
message: getMessage("deploy.selectStaging", locale),
|
|
19
|
+
options: stagings.map((s) => ({
|
|
20
|
+
value: s.stagingId,
|
|
21
|
+
label: s.description
|
|
22
|
+
? `${s.stagingId} (${s.description})`
|
|
23
|
+
: s.stagingId,
|
|
24
|
+
})),
|
|
25
|
+
});
|
|
26
|
+
if (p.isCancel(res))
|
|
27
|
+
process.exit(0);
|
|
28
|
+
return res;
|
|
29
|
+
},
|
|
30
|
+
selectZip: async (zips, locale) => {
|
|
31
|
+
const res = await p.select({
|
|
32
|
+
message: getMessage("deploy.selectZip", locale),
|
|
33
|
+
options: zips.map((z) => ({ value: z, label: basename(z) })),
|
|
34
|
+
});
|
|
35
|
+
if (p.isCancel(res))
|
|
36
|
+
process.exit(0);
|
|
37
|
+
return res;
|
|
38
|
+
},
|
|
39
|
+
description: async (locale) => {
|
|
40
|
+
const res = await p.text({
|
|
41
|
+
message: getMessage("deploy.descriptionPrompt", locale),
|
|
42
|
+
defaultValue: "",
|
|
43
|
+
initialValue: "",
|
|
44
|
+
});
|
|
45
|
+
if (p.isCancel(res))
|
|
46
|
+
process.exit(0);
|
|
47
|
+
return res;
|
|
48
|
+
},
|
|
49
|
+
confirm: async (info, locale) => {
|
|
50
|
+
p.note([
|
|
51
|
+
`${getMessage("deploy.confirm.endpoint", locale)}: ${info.endpoint}`,
|
|
52
|
+
`${getMessage("deploy.confirm.stagingId", locale)}: ${info.stagingId}`,
|
|
53
|
+
`${getMessage("deploy.confirm.sourceFile", locale)}: ${info.sourceFile}`,
|
|
54
|
+
`${getMessage("deploy.confirm.sentAs", locale)}: ${info.sentAs}`,
|
|
55
|
+
].join("\n"));
|
|
56
|
+
const res = await p.confirm({
|
|
57
|
+
message: getMessage("deploy.confirm", locale),
|
|
58
|
+
initialValue: true,
|
|
59
|
+
});
|
|
60
|
+
if (p.isCancel(res))
|
|
61
|
+
process.exit(0);
|
|
62
|
+
return res;
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
const resolveLocale = async (projectDir) => {
|
|
66
|
+
try {
|
|
67
|
+
const settings = await readSettings(projectDir);
|
|
68
|
+
return settings.locale ?? detectLocale();
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return detectLocale();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const formatDeployError = (err, locale) => {
|
|
75
|
+
if (err.kind === "network") {
|
|
76
|
+
return getMessage("deploy.error.network", locale, {
|
|
77
|
+
message: err.serverMessage ?? "",
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (err.serverMessage) {
|
|
81
|
+
return getMessage("deploy.error.server", locale, {
|
|
82
|
+
message: err.serverMessage,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
switch (err.status) {
|
|
86
|
+
case 401:
|
|
87
|
+
return getMessage("deploy.error.unauthorized", locale);
|
|
88
|
+
case 403:
|
|
89
|
+
return getMessage("deploy.error.forbidden", locale);
|
|
90
|
+
case 404:
|
|
91
|
+
return getMessage("deploy.error.notFound", locale);
|
|
92
|
+
case 400:
|
|
93
|
+
return getMessage("deploy.error.badRequest", locale);
|
|
94
|
+
case 500:
|
|
95
|
+
return getMessage("deploy.error.serverError", locale);
|
|
96
|
+
default:
|
|
97
|
+
return getMessage("deploy.error.unexpectedResponse", locale, {
|
|
98
|
+
status: String(err.status ?? "?"),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
export const runDeploy = async (deps) => {
|
|
103
|
+
const { projectDir } = deps;
|
|
104
|
+
const locale = deps.locale ?? (await resolveLocale(projectDir));
|
|
105
|
+
const ensureCreds = deps.ensureCredentials ?? defaultEnsureCredentials;
|
|
106
|
+
const scan = deps.scanTargets ?? defaultScanTargets;
|
|
107
|
+
const apiClientFactory = deps.apiClientFactory ?? defaultApiClientFactory;
|
|
108
|
+
const prompts = deps.prompts ?? defaultPrompts;
|
|
109
|
+
p.intro(getMessage("deploy.intro", locale));
|
|
110
|
+
const creds = await ensureCreds(projectDir, locale);
|
|
111
|
+
const api = apiClientFactory(creds.endpoint, creds.apiKey);
|
|
112
|
+
const spin = p.spinner();
|
|
113
|
+
spin.start(getMessage("deploy.progress.fetchingStagings", locale));
|
|
114
|
+
let stagings;
|
|
115
|
+
try {
|
|
116
|
+
stagings = await api.listStagings();
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
spin.stop(getMessage("deploy.progress.fetchingStagings", locale));
|
|
120
|
+
throw logAndRethrow(err, locale);
|
|
121
|
+
}
|
|
122
|
+
spin.stop(getMessage("deploy.progress.fetchingStagings", locale));
|
|
123
|
+
if (stagings.length === 0) {
|
|
124
|
+
p.log.error(getMessage("deploy.error.noStagings", locale));
|
|
125
|
+
throw new Error("no stagings");
|
|
126
|
+
}
|
|
127
|
+
const stagingId = await prompts.selectStaging(stagings, locale);
|
|
128
|
+
const zips = await scan(projectDir);
|
|
129
|
+
if (zips.length === 0) {
|
|
130
|
+
p.log.error(getMessage("deploy.error.noTargetZip", locale));
|
|
131
|
+
throw new Error("no target zip");
|
|
132
|
+
}
|
|
133
|
+
const zipPath = zips.length === 1 ? zips[0] : await prompts.selectZip(zips, locale);
|
|
134
|
+
const description = (await prompts.description(locale)).trim();
|
|
135
|
+
const immName = toImmFileName(zipPath);
|
|
136
|
+
const confirmed = await prompts.confirm({
|
|
137
|
+
endpoint: creds.endpoint,
|
|
138
|
+
stagingId,
|
|
139
|
+
sourceFile: basename(zipPath),
|
|
140
|
+
sentAs: immName,
|
|
141
|
+
}, locale);
|
|
142
|
+
if (!confirmed) {
|
|
143
|
+
p.log.info(getMessage("deploy.cancelled", locale));
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const bytes = await readFile(zipPath);
|
|
147
|
+
spin.start(getMessage("deploy.progress.deploying", locale));
|
|
148
|
+
let result;
|
|
149
|
+
try {
|
|
150
|
+
result = await api.createDeployment(stagingId, bytes, immName, description.length > 0 ? description : undefined);
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
spin.stop(getMessage("deploy.progress.deploying", locale));
|
|
154
|
+
throw logAndRethrow(err, locale);
|
|
155
|
+
}
|
|
156
|
+
spin.stop(getMessage("deploy.progress.deploying", locale));
|
|
157
|
+
p.note([
|
|
158
|
+
`${getMessage("deploy.result.deployId", locale)}: ${result.deployId}`,
|
|
159
|
+
`${getMessage("deploy.result.stagingId", locale)}: ${result.stagingId}`,
|
|
160
|
+
`${getMessage("deploy.result.status", locale)}: ${result.status}`,
|
|
161
|
+
`${getMessage("deploy.result.createDate", locale)}: ${result.createDate}`,
|
|
162
|
+
].join("\n"));
|
|
163
|
+
p.outro(getMessage("deploy.success", locale));
|
|
164
|
+
};
|
|
165
|
+
const logAndRethrow = (err, locale) => {
|
|
166
|
+
if (isDeployError(err)) {
|
|
167
|
+
p.log.error(formatDeployError(err, locale));
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
p.log.error(err instanceof Error ? err.message : String(err));
|
|
171
|
+
}
|
|
172
|
+
return err;
|
|
173
|
+
};
|
|
174
|
+
export const deployCommand = defineCommand({
|
|
175
|
+
meta: {
|
|
176
|
+
name: "deploy",
|
|
177
|
+
description: "Deploy build artifacts to an iAP staging environment",
|
|
178
|
+
},
|
|
179
|
+
args: {},
|
|
180
|
+
run: async () => {
|
|
181
|
+
try {
|
|
182
|
+
await runDeploy({ projectDir: process.cwd() });
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
});
|
package/dist/commands/init.d.ts
CHANGED
package/dist/commands/init.js
CHANGED
|
@@ -12,6 +12,9 @@ import { defaultAssetSourcePath } from "../asset/default-source.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";
|
|
15
|
+
import { printSummary } from "../interactive/summary.js";
|
|
16
|
+
import { printNextSteps } from "../interactive/next-steps.js";
|
|
17
|
+
import { buildProgressCallbacks } from "../interactive/progress.js";
|
|
15
18
|
export const initCommand = defineCommand({
|
|
16
19
|
meta: {
|
|
17
20
|
name: "init",
|
|
@@ -67,6 +70,10 @@ export const initCommand = defineCommand({
|
|
|
67
70
|
type: "string",
|
|
68
71
|
description: "Maven artifactId (defaults to project name)",
|
|
69
72
|
},
|
|
73
|
+
"package-manager": {
|
|
74
|
+
type: "string",
|
|
75
|
+
description: "Package manager (bun, npm, yarn, pnpm). Default: bun",
|
|
76
|
+
},
|
|
70
77
|
"git-init": {
|
|
71
78
|
type: "boolean",
|
|
72
79
|
description: "Initialize git repository (use --no-git-init to disable)",
|
|
@@ -113,6 +120,7 @@ export const initCommand = defineCommand({
|
|
|
113
120
|
agent: agentArg
|
|
114
121
|
? agentArg.split(",").map((a) => a.trim())
|
|
115
122
|
: undefined,
|
|
123
|
+
packageManager: args["package-manager"],
|
|
116
124
|
locale,
|
|
117
125
|
withGit: args["git-init"],
|
|
118
126
|
noInteraction: args["non-interactive"],
|
|
@@ -149,20 +157,25 @@ export const initCommand = defineCommand({
|
|
|
149
157
|
agents: resolved.agents,
|
|
150
158
|
javascript: resolved.javascript,
|
|
151
159
|
locale: resolved.locale,
|
|
160
|
+
packageManager: resolved.packageManager,
|
|
152
161
|
jugglingProject: resolved.jugglingProject,
|
|
153
162
|
deployedAssets: {},
|
|
154
163
|
};
|
|
164
|
+
const isInteractive = !args["non-interactive"];
|
|
165
|
+
if (isInteractive) {
|
|
166
|
+
printSummary(settings, projectDir, locale);
|
|
167
|
+
}
|
|
155
168
|
const serverUrl = args["asset-server-url"];
|
|
156
169
|
const assetSource = args["asset-source"] ?? defaultAssetSourcePath();
|
|
157
170
|
const provider = serverUrl
|
|
158
171
|
? createLocalAssetProvider(serverUrl)
|
|
159
172
|
: createFileAssetProvider(assetSource);
|
|
160
|
-
p.log.info(getMessage("progress.deploying", locale));
|
|
161
173
|
await deployAssets({
|
|
162
174
|
projectDir,
|
|
163
175
|
settings,
|
|
164
176
|
provider,
|
|
165
177
|
noInstall: args["skip-install"],
|
|
178
|
+
progress: buildProgressCallbacks(locale),
|
|
166
179
|
});
|
|
167
180
|
if (resolved.withGit) {
|
|
168
181
|
if (commandExists("git")) {
|
|
@@ -179,5 +192,11 @@ export const initCommand = defineCommand({
|
|
|
179
192
|
}
|
|
180
193
|
}
|
|
181
194
|
p.log.success(getMessage("progress.complete", locale));
|
|
195
|
+
printNextSteps({
|
|
196
|
+
projectDir,
|
|
197
|
+
agents: resolved.agents,
|
|
198
|
+
isInit: true,
|
|
199
|
+
locale,
|
|
200
|
+
});
|
|
182
201
|
},
|
|
183
202
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { satisfies } from "semver";
|
|
2
|
-
import { isAndCondition, isOrCondition, isVersionCondition, isModuleCondition, isLocaleCondition, isAgentCondition, } from "./types.js";
|
|
2
|
+
import { isAndCondition, isOrCondition, isVersionCondition, isModuleCondition, isLocaleCondition, isAgentCondition, isPackageManagerCondition, isJavascriptCondition, } from "./types.js";
|
|
3
3
|
export const evaluateCondition = (condition, context) => {
|
|
4
4
|
if (condition === undefined) {
|
|
5
5
|
return true;
|
|
@@ -22,5 +22,11 @@ export const evaluateCondition = (condition, context) => {
|
|
|
22
22
|
if (isAgentCondition(condition)) {
|
|
23
23
|
return context.agents.includes(condition.agent);
|
|
24
24
|
}
|
|
25
|
+
if (isPackageManagerCondition(condition)) {
|
|
26
|
+
return context.packageManager === condition.packageManager;
|
|
27
|
+
}
|
|
28
|
+
if (isJavascriptCondition(condition)) {
|
|
29
|
+
return context.javascript === condition.javascript;
|
|
30
|
+
}
|
|
25
31
|
return false;
|
|
26
32
|
};
|
package/dist/core/constants.d.ts
CHANGED
|
@@ -8,4 +8,6 @@ export declare const MODULE_OPTIONS: readonly ["workflow", "bpm", "copilot", "im
|
|
|
8
8
|
export type ModuleOption = (typeof MODULE_OPTIONS)[number];
|
|
9
9
|
export declare const LOCALE_OPTIONS: readonly ["ja", "en", "zh_CN"];
|
|
10
10
|
export type LocaleOption = (typeof LOCALE_OPTIONS)[number];
|
|
11
|
+
export declare const PACKAGE_MANAGER_OPTIONS: readonly ["bun", "npm", "yarn", "pnpm"];
|
|
12
|
+
export type PackageManagerOption = (typeof PACKAGE_MANAGER_OPTIONS)[number];
|
|
11
13
|
export declare const DEFAULT_SETTINGS: Omit<AccelSettings, "cliVersion" | "createdAt" | "deployedAssets">;
|
package/dist/core/constants.js
CHANGED
|
@@ -10,17 +10,24 @@ export const MODULE_OPTIONS = [
|
|
|
10
10
|
"kaiden",
|
|
11
11
|
];
|
|
12
12
|
export const LOCALE_OPTIONS = ["ja", "en", "zh_CN"];
|
|
13
|
+
export const PACKAGE_MANAGER_OPTIONS = [
|
|
14
|
+
"bun",
|
|
15
|
+
"npm",
|
|
16
|
+
"yarn",
|
|
17
|
+
"pnpm",
|
|
18
|
+
];
|
|
13
19
|
export const DEFAULT_SETTINGS = {
|
|
14
20
|
name: "my-accel-project",
|
|
15
21
|
artifactId: "",
|
|
16
22
|
group: "com.example",
|
|
17
23
|
projectVersion: "0.1.0",
|
|
18
24
|
description: "",
|
|
19
|
-
accelplatformVersion: "
|
|
25
|
+
accelplatformVersion: "2026-Spring",
|
|
20
26
|
modules: [],
|
|
21
27
|
database: "postgresql",
|
|
22
28
|
agents: ["claude-code", "github-copilot"],
|
|
23
29
|
javascript: false,
|
|
24
30
|
locale: "ja",
|
|
31
|
+
packageManager: "bun",
|
|
25
32
|
jugglingProject: null,
|
|
26
33
|
};
|
package/dist/core/types.d.ts
CHANGED
|
@@ -16,7 +16,13 @@ export type LocaleCondition = {
|
|
|
16
16
|
export type AgentCondition = {
|
|
17
17
|
agent: string;
|
|
18
18
|
};
|
|
19
|
-
export type
|
|
19
|
+
export type PackageManagerCondition = {
|
|
20
|
+
packageManager: string;
|
|
21
|
+
};
|
|
22
|
+
export type JavascriptCondition = {
|
|
23
|
+
javascript: boolean;
|
|
24
|
+
};
|
|
25
|
+
export type LeafCondition = VersionCondition | ModuleCondition | LocaleCondition | AgentCondition | PackageManagerCondition | JavascriptCondition;
|
|
20
26
|
export type Condition = AndCondition | OrCondition | LeafCondition;
|
|
21
27
|
export type TextReplacement = {
|
|
22
28
|
type: "text";
|
|
@@ -69,6 +75,7 @@ export type AccelSettings = {
|
|
|
69
75
|
agents: string[];
|
|
70
76
|
javascript: boolean;
|
|
71
77
|
locale: string;
|
|
78
|
+
packageManager: string;
|
|
72
79
|
jugglingProject: string | null;
|
|
73
80
|
deployedAssets: Record<string, string>;
|
|
74
81
|
};
|
|
@@ -93,6 +100,8 @@ export type EvalContext = {
|
|
|
93
100
|
accelplatformVersion: string;
|
|
94
101
|
database: string;
|
|
95
102
|
projectVersion: string;
|
|
103
|
+
packageManager: string;
|
|
104
|
+
javascript: boolean;
|
|
96
105
|
};
|
|
97
106
|
export declare const isAndCondition: (c: Condition) => c is AndCondition;
|
|
98
107
|
export declare const isOrCondition: (c: Condition) => c is OrCondition;
|
|
@@ -100,3 +109,44 @@ export declare const isVersionCondition: (c: Condition) => c is VersionCondition
|
|
|
100
109
|
export declare const isModuleCondition: (c: Condition) => c is ModuleCondition;
|
|
101
110
|
export declare const isLocaleCondition: (c: Condition) => c is LocaleCondition;
|
|
102
111
|
export declare const isAgentCondition: (c: Condition) => c is AgentCondition;
|
|
112
|
+
export declare const isPackageManagerCondition: (c: Condition) => c is PackageManagerCondition;
|
|
113
|
+
export declare const isJavascriptCondition: (c: Condition) => c is JavascriptCondition;
|
|
114
|
+
export type AccelCredentials = {
|
|
115
|
+
endpoint: string;
|
|
116
|
+
apiKey: string;
|
|
117
|
+
};
|
|
118
|
+
export type StagingResponse = {
|
|
119
|
+
stagingId: string;
|
|
120
|
+
description?: string | null;
|
|
121
|
+
currentDeployId?: string | null;
|
|
122
|
+
createUserCd: string;
|
|
123
|
+
createDate: string;
|
|
124
|
+
};
|
|
125
|
+
export type StagingListResponse = {
|
|
126
|
+
totalCount: number;
|
|
127
|
+
offset: number;
|
|
128
|
+
limit: number;
|
|
129
|
+
records: StagingResponse[];
|
|
130
|
+
};
|
|
131
|
+
export type DeploymentResponse = {
|
|
132
|
+
deployId: string;
|
|
133
|
+
stagingId: string;
|
|
134
|
+
status: "STAGED" | "UNDEPLOYED";
|
|
135
|
+
description?: string | null;
|
|
136
|
+
createUserCd: string;
|
|
137
|
+
createDate: string;
|
|
138
|
+
};
|
|
139
|
+
export type ApiSuccess<T> = {
|
|
140
|
+
error: false;
|
|
141
|
+
data: T;
|
|
142
|
+
};
|
|
143
|
+
export type ApiErrorBody = {
|
|
144
|
+
error: true;
|
|
145
|
+
errorMessage: string;
|
|
146
|
+
};
|
|
147
|
+
export type DeployError = {
|
|
148
|
+
_tag: "DeployError";
|
|
149
|
+
kind: "network" | "http";
|
|
150
|
+
status?: number;
|
|
151
|
+
serverMessage?: string;
|
|
152
|
+
};
|
package/dist/core/types.js
CHANGED
|
@@ -4,3 +4,5 @@ export const isVersionCondition = (c) => "version" in c && !("and" in c) && !("o
|
|
|
4
4
|
export const isModuleCondition = (c) => "module" in c;
|
|
5
5
|
export const isLocaleCondition = (c) => "locale" in c;
|
|
6
6
|
export const isAgentCondition = (c) => "agent" in c;
|
|
7
|
+
export const isPackageManagerCondition = (c) => "packageManager" in c;
|
|
8
|
+
export const isJavascriptCondition = (c) => "javascript" in c;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type Validator = (value: string) => string | undefined;
|
|
1
|
+
export type Validator = (value: string | undefined) => string | undefined;
|
|
2
2
|
export type Validators = {
|
|
3
3
|
name: Validator;
|
|
4
4
|
artifactId: Validator;
|
|
@@ -8,5 +8,6 @@ export type Validators = {
|
|
|
8
8
|
module: Validator;
|
|
9
9
|
database: Validator;
|
|
10
10
|
agent: Validator;
|
|
11
|
+
packageManager: Validator;
|
|
11
12
|
};
|
|
12
13
|
export declare const createValidators: (locale: string) => Validators;
|
package/dist/core/validators.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getMessage } from "../i18n/index.js";
|
|
2
|
-
import { AGENT_OPTIONS, DATABASE_OPTIONS, MODULE_OPTIONS, } from "./constants.js";
|
|
2
|
+
import { AGENT_OPTIONS, DATABASE_OPTIONS, MODULE_OPTIONS, PACKAGE_MANAGER_OPTIONS, } from "./constants.js";
|
|
3
3
|
import { SELECTABLE_VERSIONS } from "./version-map.js";
|
|
4
4
|
const ARTIFACT_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
5
5
|
const GROUP_PATTERN = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*)*$/;
|
|
@@ -23,29 +23,62 @@ const isValidVersionLabel = (value) => SELECTABLE_VERSIONS.some((v) => v.label =
|
|
|
23
23
|
const isValidModule = (value) => MODULE_OPTIONS.includes(value);
|
|
24
24
|
const isValidDatabase = (value) => DATABASE_OPTIONS.includes(value);
|
|
25
25
|
const isValidAgent = (value) => AGENT_OPTIONS.includes(value);
|
|
26
|
+
const isValidPackageManager = (value) => PACKAGE_MANAGER_OPTIONS.includes(value);
|
|
26
27
|
export const createValidators = (locale) => ({
|
|
27
|
-
name: (value) =>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
28
|
+
name: (value) => {
|
|
29
|
+
const v = value ?? "";
|
|
30
|
+
return isValidName(v)
|
|
31
|
+
? undefined
|
|
32
|
+
: getMessage("error.invalidName", locale, { value: v });
|
|
33
|
+
},
|
|
34
|
+
artifactId: (value) => {
|
|
35
|
+
const v = value ?? "";
|
|
36
|
+
return isValidArtifactId(v)
|
|
37
|
+
? undefined
|
|
38
|
+
: getMessage("error.invalidArtifactId", locale, { value: v });
|
|
39
|
+
},
|
|
40
|
+
group: (value) => {
|
|
41
|
+
const v = value ?? "";
|
|
42
|
+
return isValidGroup(v)
|
|
43
|
+
? undefined
|
|
44
|
+
: getMessage("error.invalidGroup", locale, { value: v });
|
|
45
|
+
},
|
|
46
|
+
projectVersion: (value) => {
|
|
47
|
+
const v = value ?? "";
|
|
48
|
+
return isValidProjectVersion(v)
|
|
49
|
+
? undefined
|
|
50
|
+
: getMessage("error.invalidProjectVersion", locale, { value: v });
|
|
51
|
+
},
|
|
52
|
+
versionLabel: (value) => {
|
|
53
|
+
const v = value ?? "";
|
|
54
|
+
return isValidVersionLabel(v)
|
|
55
|
+
? undefined
|
|
56
|
+
: getMessage("error.invalidVersion", locale, { version: v });
|
|
57
|
+
},
|
|
58
|
+
module: (value) => {
|
|
59
|
+
const v = value ?? "";
|
|
60
|
+
return isValidModule(v)
|
|
61
|
+
? undefined
|
|
62
|
+
: getMessage("error.invalidModule", locale, { module: v });
|
|
63
|
+
},
|
|
64
|
+
database: (value) => {
|
|
65
|
+
const v = value ?? "";
|
|
66
|
+
return isValidDatabase(v)
|
|
67
|
+
? undefined
|
|
68
|
+
: getMessage("error.invalidDatabase", locale, { database: v });
|
|
69
|
+
},
|
|
70
|
+
agent: (value) => {
|
|
71
|
+
const v = value ?? "";
|
|
72
|
+
return isValidAgent(v)
|
|
73
|
+
? undefined
|
|
74
|
+
: getMessage("error.invalidAgent", locale, { agent: v });
|
|
75
|
+
},
|
|
76
|
+
packageManager: (value) => {
|
|
77
|
+
const v = value ?? "";
|
|
78
|
+
return isValidPackageManager(v)
|
|
79
|
+
? undefined
|
|
80
|
+
: getMessage("error.invalidPackageManager", locale, {
|
|
81
|
+
packageManager: v,
|
|
82
|
+
});
|
|
83
|
+
},
|
|
51
84
|
});
|
|
@@ -8,6 +8,7 @@ const VARIABLE_MAP = new Map([
|
|
|
8
8
|
["locale", "locale"],
|
|
9
9
|
["database", "database"],
|
|
10
10
|
["projectVersion", "projectVersion"],
|
|
11
|
+
["packageManager", "packageManager"],
|
|
11
12
|
]);
|
|
12
13
|
const INTERPOLATION_PATTERN = /\{\{\$(\w+)\}\}/g;
|
|
13
14
|
export const interpolateVariables = (template, context) => {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { StagingResponse, DeploymentResponse, DeployError } from "../core/types.js";
|
|
2
|
+
type FetchFn = typeof globalThis.fetch;
|
|
3
|
+
export declare const makeDeployError: (kind: DeployError["kind"], extra?: {
|
|
4
|
+
status?: number;
|
|
5
|
+
serverMessage?: string;
|
|
6
|
+
}) => DeployError;
|
|
7
|
+
export declare const isDeployError: (e: unknown) => e is DeployError;
|
|
8
|
+
export type ApiClient = {
|
|
9
|
+
listStagings: () => Promise<StagingResponse[]>;
|
|
10
|
+
createDeployment: (stagingId: string, bytes: Uint8Array, immFileName: string, description?: string) => Promise<DeploymentResponse>;
|
|
11
|
+
};
|
|
12
|
+
export declare const createApiClient: (endpoint: string, apiKey: string, deps?: {
|
|
13
|
+
fetch?: FetchFn;
|
|
14
|
+
}) => ApiClient;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const STAGING_PATH = "/api/bearer/development/staging";
|
|
2
|
+
const PAGE_LIMIT = 100;
|
|
3
|
+
const MAX_PAGES = 1000;
|
|
4
|
+
export const makeDeployError = (kind, extra = {}) => ({ _tag: "DeployError", kind, ...extra });
|
|
5
|
+
export const isDeployError = (e) => typeof e === "object" &&
|
|
6
|
+
e !== null &&
|
|
7
|
+
e._tag === "DeployError";
|
|
8
|
+
export const createApiClient = (endpoint, apiKey, deps = {}) => {
|
|
9
|
+
const doFetch = deps.fetch ?? globalThis.fetch;
|
|
10
|
+
const baseHeaders = {
|
|
11
|
+
"X-Intramart-Session": "never",
|
|
12
|
+
Authorization: `Bearer ${apiKey}`,
|
|
13
|
+
};
|
|
14
|
+
const request = async (url, init) => {
|
|
15
|
+
let res;
|
|
16
|
+
try {
|
|
17
|
+
res = await doFetch(url, init);
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
throw makeDeployError("network", {
|
|
21
|
+
serverMessage: err instanceof Error ? err.message : String(err),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const text = await res.text();
|
|
25
|
+
let body;
|
|
26
|
+
try {
|
|
27
|
+
body = text.length > 0 ? JSON.parse(text) : undefined;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
throw makeDeployError("http", { status: res.status });
|
|
31
|
+
}
|
|
32
|
+
if (body !== null &&
|
|
33
|
+
typeof body === "object" &&
|
|
34
|
+
body.error === true) {
|
|
35
|
+
throw makeDeployError("http", {
|
|
36
|
+
status: res.status,
|
|
37
|
+
serverMessage: body.errorMessage,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (!res.ok) {
|
|
41
|
+
throw makeDeployError("http", { status: res.status });
|
|
42
|
+
}
|
|
43
|
+
if (body !== null &&
|
|
44
|
+
typeof body === "object" &&
|
|
45
|
+
"data" in body) {
|
|
46
|
+
return body.data;
|
|
47
|
+
}
|
|
48
|
+
throw makeDeployError("http", { status: res.status });
|
|
49
|
+
};
|
|
50
|
+
const listStagings = async () => {
|
|
51
|
+
const records = [];
|
|
52
|
+
let offset = 0;
|
|
53
|
+
for (let page = 0; page < MAX_PAGES; page++) {
|
|
54
|
+
const url = `${endpoint}${STAGING_PATH}?offset=${offset}&limit=${PAGE_LIMIT}`;
|
|
55
|
+
const data = await request(url, {
|
|
56
|
+
method: "GET",
|
|
57
|
+
headers: baseHeaders,
|
|
58
|
+
});
|
|
59
|
+
records.push(...data.records);
|
|
60
|
+
if (records.length >= data.totalCount || data.records.length === 0) {
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
offset += PAGE_LIMIT;
|
|
64
|
+
}
|
|
65
|
+
return records;
|
|
66
|
+
};
|
|
67
|
+
const createDeployment = async (stagingId, bytes, immFileName, description) => {
|
|
68
|
+
const form = new FormData();
|
|
69
|
+
form.append("archiveFile", new File([bytes], immFileName, { type: "application/zip" }));
|
|
70
|
+
if (description && description.length > 0) {
|
|
71
|
+
form.append("description", description);
|
|
72
|
+
}
|
|
73
|
+
const url = `${endpoint}${STAGING_PATH}/${encodeURIComponent(stagingId)}/deploy`;
|
|
74
|
+
return request(url, {
|
|
75
|
+
method: "POST",
|
|
76
|
+
headers: baseHeaders,
|
|
77
|
+
body: form,
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
return { listStagings, createDeployment };
|
|
81
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { readdir } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
const DEFAULT_DIR = "target";
|
|
4
|
+
const DEFAULT_PATTERN = /\.zip$/i;
|
|
5
|
+
export const scanTargets = async (projectDir, opts = {}) => {
|
|
6
|
+
const dir = opts.dir ?? DEFAULT_DIR;
|
|
7
|
+
const pattern = opts.pattern ?? DEFAULT_PATTERN;
|
|
8
|
+
const targetDir = join(projectDir, dir);
|
|
9
|
+
let entries;
|
|
10
|
+
try {
|
|
11
|
+
entries = await readdir(targetDir, { withFileTypes: true });
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
return entries
|
|
17
|
+
.filter((e) => e.isFile() && pattern.test(e.name))
|
|
18
|
+
.map((e) => join(targetDir, e.name))
|
|
19
|
+
.sort();
|
|
20
|
+
};
|