@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
package/README.md
CHANGED
|
@@ -6,7 +6,11 @@ intra-mart Accel Platform (iAP) 開発プロジェクトの作成・管理を行
|
|
|
6
6
|
|
|
7
7
|
## 必要環境
|
|
8
8
|
|
|
9
|
-
-
|
|
9
|
+
- 以下のいずれかのパッケージマネージャ(`--package-manager` で選択、デフォルト: Bun)
|
|
10
|
+
- [Bun](https://bun.sh/) v1.0+
|
|
11
|
+
- [npm](https://www.npmjs.com/)
|
|
12
|
+
- [Yarn](https://classic.yarnpkg.com/) (classic v1)
|
|
13
|
+
- [pnpm](https://pnpm.io/)
|
|
10
14
|
- Git(`--no-git-init` を指定しない場合)
|
|
11
15
|
|
|
12
16
|
## インストール
|
|
@@ -40,6 +44,8 @@ accel init my-project
|
|
|
40
44
|
```bash
|
|
41
45
|
accel init my-project \
|
|
42
46
|
--non-interactive \
|
|
47
|
+
--accelplatform-version 2026-Spring \
|
|
48
|
+
--module workflow \
|
|
43
49
|
--agent claude-code \
|
|
44
50
|
--locale ja
|
|
45
51
|
```
|
|
@@ -49,6 +55,8 @@ accel init my-project \
|
|
|
49
55
|
| オプション | 型 | 説明 | デフォルト |
|
|
50
56
|
|---|---|---|---|
|
|
51
57
|
| `[project-name]` (位置引数) | string | プロジェクト名(ディレクトリ名と一致) | `my-accel-project`(対話で変更可) |
|
|
58
|
+
| `--accelplatform-version` | string | iAPバージョン(例: `2026-Spring`) | 対話で選択 |
|
|
59
|
+
| `--module` | string | 使用モジュール(カンマ区切り) | 対話で選択 |
|
|
52
60
|
| `--agent` | string | エージェント種別(`claude-code`, `github-copilot`、カンマ区切り) | 自動検出 |
|
|
53
61
|
| `--locale` | string | ロケール(`ja`, `en`, `zh_CN`) | OS設定から自動検出 |
|
|
54
62
|
| `--artifact-id` | string | アーティファクトID(pomの `artifactId` に相当) | プロジェクト名と同値 |
|
|
@@ -58,9 +66,12 @@ accel init my-project \
|
|
|
58
66
|
| `--database` | string | データベース種別(`postgresql`, `oracle`, `sqlserver`) | `postgresql` |
|
|
59
67
|
| `--javascript` | boolean | TypeScriptの代わりにJavaScriptを使用 | `false` |
|
|
60
68
|
| `--juggling-project` | string | IM-Jugglingプロジェクトパス | - |
|
|
69
|
+
| `--package-manager` | string | パッケージマネージャ(`bun`, `npm`, `yarn`, `pnpm`)。対話には現れず、CLIオプションでのみ指定可能 | `bun` |
|
|
61
70
|
| `--non-interactive` | boolean | 非対話モード(このモードでは `project-name` が必須) | `false` |
|
|
62
71
|
| `--no-git-init` | boolean | git initをスキップ | `false`(git initする) |
|
|
63
72
|
| `--skip-install` | boolean | 依存インストールをスキップ | `false` |
|
|
73
|
+
| `--asset-source` | string | ローカル資材のパス(tarアーカイブまたは展開済みディレクトリ) | パッケージ同梱の `assets/assets.tar.gz` |
|
|
74
|
+
| `--asset-server-url` | string | 資材サーバーURL。明示指定時は `--asset-source` より優先される | - |
|
|
64
75
|
|
|
65
76
|
### `accel attach`
|
|
66
77
|
|
|
@@ -68,20 +79,24 @@ accel init my-project \
|
|
|
68
79
|
|
|
69
80
|
```bash
|
|
70
81
|
cd my-existing-project
|
|
71
|
-
accel attach --non-interactive
|
|
82
|
+
accel attach --non-interactive --accelplatform-version 2026-Spring --module workflow
|
|
72
83
|
```
|
|
73
84
|
|
|
74
85
|
`init` との違い:
|
|
75
86
|
- ディレクトリを新規作成せず、カレントディレクトリを使用
|
|
76
87
|
- git initは行わない
|
|
77
88
|
- プロジェクト名のデフォルトはカレントディレクトリ名
|
|
78
|
-
-
|
|
89
|
+
- **既存ファイルがある配備先はファイル単位で上書き確認**を行う。対話モードでは1ファイルごとに「Yes / No / All (以降全て上書き) / Skip-all (以降全てスキップ)」を選択。`--overwrite` 指定時は確認なしで全て上書き。非対話モードかつ `--overwrite` 未指定の場合は全てスキップ
|
|
90
|
+
- 上書きされたファイルは `hashsum.txt` および `deployedAssets` に記録される(`detach` の対象になる)
|
|
91
|
+
- スキップされたファイルは記録されない(`detach` の対象外)
|
|
79
92
|
|
|
80
93
|
#### オプション一覧
|
|
81
94
|
|
|
82
95
|
| オプション | 型 | 説明 | デフォルト |
|
|
83
96
|
|---|---|---|---|
|
|
84
97
|
| `--name` | string | プロジェクト名 | カレントディレクトリ名 |
|
|
98
|
+
| `--accelplatform-version` | string | iAPバージョン(例: `2026-Spring`) | 対話で選択 |
|
|
99
|
+
| `--module` | string | 使用モジュール(カンマ区切り) | 対話で選択 |
|
|
85
100
|
| `--agent` | string | エージェント種別(`claude-code`, `github-copilot`、カンマ区切り) | 自動検出 |
|
|
86
101
|
| `--locale` | string | ロケール(`ja`, `en`, `zh_CN`) | OS設定から自動検出 |
|
|
87
102
|
| `--artifact-id` | string | アーティファクトID(pomの `artifactId` に相当) | プロジェクト名と同値 |
|
|
@@ -91,8 +106,12 @@ accel attach --non-interactive
|
|
|
91
106
|
| `--database` | string | データベース種別(`postgresql`, `oracle`, `sqlserver`) | `postgresql` |
|
|
92
107
|
| `--javascript` | boolean | TypeScriptの代わりにJavaScriptを使用 | `false` |
|
|
93
108
|
| `--juggling-project` | string | IM-Jugglingプロジェクトパス | - |
|
|
109
|
+
| `--package-manager` | string | パッケージマネージャ(`bun`, `npm`, `yarn`, `pnpm`)。対話には現れず、CLIオプションでのみ指定可能 | `bun` |
|
|
110
|
+
| `--overwrite` | boolean | 既存ファイルの上書き確認を行わず、全て上書きする | `false`(対話で確認 / 非対話ではスキップ) |
|
|
94
111
|
| `--non-interactive` | boolean | 非対話モード | `false` |
|
|
95
112
|
| `--skip-install` | boolean | 依存インストールをスキップ | `false` |
|
|
113
|
+
| `--asset-source` | string | ローカル資材のパス(tarアーカイブまたは展開済みディレクトリ) | パッケージ同梱の `assets/assets.tar.gz` |
|
|
114
|
+
| `--asset-server-url` | string | 資材サーバーURL。明示指定時は `--asset-source` より優先される | - |
|
|
96
115
|
|
|
97
116
|
### `accel detach`
|
|
98
117
|
|
|
@@ -107,6 +126,33 @@ accel detach
|
|
|
107
126
|
- ユーザーが編集したファイルはスキップ(警告表示)
|
|
108
127
|
- `.accel/` ディレクトリを削除
|
|
109
128
|
|
|
129
|
+
### `accel deploy`
|
|
130
|
+
|
|
131
|
+
ビルド成果物(`./target/` 配下の zip)を iAP のステージング環境へデプロイします。**対話モードのみ**対応です。
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
cd my-project
|
|
135
|
+
accel deploy
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
- プロジェクトのルートで実行します。ビルド成果物は `./target/` 配下に出力されている前提です(`mvn package` で生成される `<artifactId>-<version>.zip`)。
|
|
139
|
+
- 初回実行時に iAP の接続情報(エンドポイントURL・APIキー)の入力を求めます。入力値は `.accel/credentials.json` に保存され、次回以降は再入力不要です。
|
|
140
|
+
- **APIキーは秘匿情報のため、`.accel/credentials.json` は自動的に `.gitignore` に追加されます**(コミット対象外)。
|
|
141
|
+
- 既存のステージング環境を一覧から選択します(ステージングは iAP 側で事前に作成しておく必要があります)。
|
|
142
|
+
- `./target/` 配下の zip が複数ある場合は選択し、単一の場合は自動選択します。いずれの場合もデプロイ実行前に最終確認を行います。
|
|
143
|
+
- 送信時、zip は imm 形式としてアップロードされます(送信時のファイル名のみ `.imm` に変更され、ディスク上のファイルはそのままです)。
|
|
144
|
+
|
|
145
|
+
#### 接続情報ファイル `.accel/credentials.json`
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"endpoint": "https://example.com/imart",
|
|
150
|
+
"apiKey": "<OAuth Bearer トークン>"
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`endpoint` には iAP のベースURL を指定します。API パス(`/api/bearer/development/...`)は CLI が組み立てます。
|
|
155
|
+
|
|
110
156
|
## IM-Juggling連携
|
|
111
157
|
|
|
112
158
|
`--juggling-project` オプションでIM-Jugglingプロジェクトのパスを指定すると、`juggling.im` からiAPバージョンと使用モジュールを自動検出します。
|
|
@@ -135,8 +181,24 @@ my-project/
|
|
|
135
181
|
|
|
136
182
|
- `.accel/settings.json` — プロジェクト設定。git管理対象、手動編集可
|
|
137
183
|
- `.accel/hashsum.txt` — 配備ファイルのSHA-1。`detach` 時の変更検出に使用
|
|
184
|
+
- `.accel/credentials.json` — iAP接続情報(endpoint / APIキー)。`accel deploy` 初回実行時に生成。APIキーを含むため `.gitignore` 対象(git管理対象外)
|
|
138
185
|
|
|
139
186
|
## 対応iAPバージョン
|
|
140
187
|
|
|
141
|
-
|
|
142
|
-
|
|
188
|
+
2024-Spring (8.0.35) 以降の iAP バージョンを選択可能です。
|
|
189
|
+
|
|
190
|
+
## 入力値のバリデーション
|
|
191
|
+
|
|
192
|
+
CLIに渡された値および対話で入力された値は、以下のルールでバリデーションされます。違反する値は対話モードでは再入力を促し、非対話モードではエラーメッセージを表示して終了します。
|
|
193
|
+
|
|
194
|
+
| オプション | ルール |
|
|
195
|
+
|-----------|------|
|
|
196
|
+
| `[project-name]` / `--name` | 空文字不可。ディレクトリ名として不正な文字を含まない(`/ \ : * ? " < > \|`、制御文字、先頭末尾の空白/ドット) |
|
|
197
|
+
| `--artifact-id` | Maven artifactId 規約: `^[A-Za-z0-9][A-Za-z0-9._-]*$` |
|
|
198
|
+
| `--group` | Maven groupId 規約: ドット区切りの識別子 `^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*)*$` |
|
|
199
|
+
| `--project-version` | Maven version 規約: `^[A-Za-z0-9][A-Za-z0-9._-]*$` |
|
|
200
|
+
| `--accelplatform-version` | 対応iAPバージョン一覧(`2024-Spring` 以降)に含まれる値 |
|
|
201
|
+
| `--module` | `workflow`, `bpm`, `copilot`, `imbox`, `pdfd`, `kaiden` のいずれか(各要素) |
|
|
202
|
+
| `--database` | `postgresql`, `oracle`, `sqlserver` のいずれか |
|
|
203
|
+
| `--agent` | `claude-code`, `github-copilot` のいずれか(各要素) |
|
|
204
|
+
| `--package-manager` | `bun`, `npm`, `yarn`, `pnpm` のいずれか |
|
package/assets/assets.tar.gz
CHANGED
|
Binary file
|
package/dist/asset/deployer.d.ts
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import type { AssetProvider, AccelSettings, HashsumEntry } from "../core/types.js";
|
|
2
|
+
export type OverwriteDecision = "overwrite" | "skip";
|
|
3
|
+
export type ExistingFileHandler = (relativePath: string) => Promise<OverwriteDecision>;
|
|
4
|
+
export type ProgressCallbacks = {
|
|
5
|
+
onFetchStart?: () => void;
|
|
6
|
+
onSectionDeploy?: (section: string, files: string[]) => void;
|
|
7
|
+
onInstallStart?: (command: string) => void;
|
|
8
|
+
onBuildStart?: (command: string) => void;
|
|
9
|
+
};
|
|
2
10
|
export type DeployOptions = {
|
|
3
11
|
projectDir: string;
|
|
4
12
|
settings: AccelSettings;
|
|
5
13
|
provider: AssetProvider;
|
|
6
14
|
noInstall: boolean;
|
|
7
15
|
skipExistingFiles?: boolean;
|
|
16
|
+
onExistingFile?: ExistingFileHandler;
|
|
17
|
+
progress?: ProgressCallbacks;
|
|
8
18
|
};
|
|
9
19
|
export type DeployResult = {
|
|
10
20
|
deployedFiles: string[];
|
|
11
21
|
hashEntries: HashsumEntry[];
|
|
12
22
|
skippedFiles: string[];
|
|
23
|
+
overwrittenFiles: string[];
|
|
13
24
|
};
|
|
25
|
+
export declare const getInstallCmds: (packageManager: string) => string[];
|
|
26
|
+
export declare const ROOT_SECTION = "(root)";
|
|
14
27
|
export declare const deployAssets: (options: DeployOptions) => Promise<DeployResult>;
|
package/dist/asset/deployer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFile, writeFile, mkdir, stat } from "node:fs/promises";
|
|
2
|
-
import { join, dirname } from "node:path";
|
|
2
|
+
import { join, dirname, resolve, sep } from "node:path";
|
|
3
3
|
import { labelToSemver } from "../core/version-map.js";
|
|
4
4
|
import { walkAssetRepo } from "./walker.js";
|
|
5
5
|
import { processMarkdown } from "../markdown/processor.js";
|
|
@@ -16,14 +16,46 @@ const fileExists = async (path) => {
|
|
|
16
16
|
return false;
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
|
+
const isWithinDir = (parentDir, candidate) => {
|
|
20
|
+
const parent = resolve(parentDir);
|
|
21
|
+
const target = resolve(candidate);
|
|
22
|
+
if (target === parent)
|
|
23
|
+
return true;
|
|
24
|
+
const prefix = parent.endsWith(sep) ? parent : parent + sep;
|
|
25
|
+
return target.startsWith(prefix);
|
|
26
|
+
};
|
|
27
|
+
export const getInstallCmds = (packageManager) => {
|
|
28
|
+
switch (packageManager) {
|
|
29
|
+
case "npm":
|
|
30
|
+
return ["npm ci", "npm run build"];
|
|
31
|
+
case "yarn":
|
|
32
|
+
return ["yarn install --frozen-lockfile", "yarn run build"];
|
|
33
|
+
case "pnpm":
|
|
34
|
+
return ["pnpm install --frozen-lockfile", "pnpm run build"];
|
|
35
|
+
case "bun":
|
|
36
|
+
default:
|
|
37
|
+
return ["bun ci", "bun run build"];
|
|
38
|
+
}
|
|
39
|
+
};
|
|
19
40
|
const collectReplacements = (entry) => {
|
|
20
41
|
if (!entry.meta?.replacements)
|
|
21
42
|
return [];
|
|
22
43
|
return entry.meta.replacements;
|
|
23
44
|
};
|
|
45
|
+
export const ROOT_SECTION = "(root)";
|
|
46
|
+
const sectionOf = (relativePath) => {
|
|
47
|
+
const idx = relativePath.indexOf("/");
|
|
48
|
+
return idx === -1 ? ROOT_SECTION : relativePath.slice(0, idx) + "/";
|
|
49
|
+
};
|
|
50
|
+
const fileLabelOf = (relativePath, section) => {
|
|
51
|
+
if (section === ROOT_SECTION)
|
|
52
|
+
return relativePath;
|
|
53
|
+
return relativePath.slice(section.length);
|
|
54
|
+
};
|
|
24
55
|
export const deployAssets = async (options) => {
|
|
25
|
-
const { projectDir, settings, provider, noInstall, skipExistingFiles } = options;
|
|
56
|
+
const { projectDir, settings, provider, noInstall, skipExistingFiles, onExistingFile, progress, } = options;
|
|
26
57
|
try {
|
|
58
|
+
progress?.onFetchStart?.();
|
|
27
59
|
const repoDir = await provider.fetch();
|
|
28
60
|
const semver = labelToSemver(settings.accelplatformVersion);
|
|
29
61
|
const context = {
|
|
@@ -38,19 +70,52 @@ export const deployAssets = async (options) => {
|
|
|
38
70
|
accelplatformVersion: settings.accelplatformVersion,
|
|
39
71
|
database: settings.database,
|
|
40
72
|
projectVersion: settings.projectVersion,
|
|
73
|
+
packageManager: settings.packageManager,
|
|
74
|
+
javascript: settings.javascript,
|
|
41
75
|
};
|
|
42
76
|
const entries = await walkAssetRepo(repoDir, semver, context);
|
|
43
77
|
const deployedFiles = [];
|
|
44
78
|
const hashEntries = [];
|
|
45
79
|
const deployedAssets = {};
|
|
46
80
|
const skippedFiles = [];
|
|
81
|
+
const overwrittenFiles = [];
|
|
82
|
+
let currentSection = null;
|
|
47
83
|
for (const entry of entries) {
|
|
48
84
|
const targetPath = entry.relativePath;
|
|
49
85
|
const destPath = join(projectDir, targetPath);
|
|
50
|
-
|
|
51
|
-
|
|
86
|
+
const section = sectionOf(targetPath);
|
|
87
|
+
if (section !== currentSection) {
|
|
88
|
+
currentSection = section;
|
|
89
|
+
if (progress?.onSectionDeploy) {
|
|
90
|
+
const sectionFiles = entries
|
|
91
|
+
.filter((e) => sectionOf(e.relativePath) === section)
|
|
92
|
+
.map((e) => fileLabelOf(e.relativePath, section));
|
|
93
|
+
progress.onSectionDeploy(section, sectionFiles);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (!isWithinDir(projectDir, destPath)) {
|
|
97
|
+
console.warn(`Warning: skipping asset with path escaping project directory: ${targetPath}`);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (!isWithinDir(repoDir, entry.sourcePath)) {
|
|
101
|
+
console.warn(`Warning: skipping asset with source path escaping asset repo: ${entry.sourcePath}`);
|
|
52
102
|
continue;
|
|
53
103
|
}
|
|
104
|
+
const exists = await fileExists(destPath);
|
|
105
|
+
if (exists) {
|
|
106
|
+
let decision = "overwrite";
|
|
107
|
+
if (skipExistingFiles) {
|
|
108
|
+
decision = "skip";
|
|
109
|
+
}
|
|
110
|
+
else if (onExistingFile) {
|
|
111
|
+
decision = await onExistingFile(targetPath);
|
|
112
|
+
}
|
|
113
|
+
if (decision === "skip") {
|
|
114
|
+
skippedFiles.push(targetPath);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
overwrittenFiles.push(targetPath);
|
|
118
|
+
}
|
|
54
119
|
let content = await readFile(entry.sourcePath, "utf-8");
|
|
55
120
|
const replacements = collectReplacements(entry);
|
|
56
121
|
if (replacements.length > 0) {
|
|
@@ -79,17 +144,23 @@ export const deployAssets = async (options) => {
|
|
|
79
144
|
await writeSettings(projectDir, updatedSettings);
|
|
80
145
|
await writeHashsum(projectDir, hashEntries);
|
|
81
146
|
if (!noInstall) {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
147
|
+
const [installCmd, buildCmd] = getInstallCmds(settings.packageManager);
|
|
148
|
+
progress?.onInstallStart?.(installCmd);
|
|
149
|
+
try {
|
|
150
|
+
execSync(installCmd, { cwd: projectDir, stdio: "pipe" });
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
console.warn(`Warning: install command failed: ${installCmd} in ${projectDir}`);
|
|
154
|
+
}
|
|
155
|
+
progress?.onBuildStart?.(buildCmd);
|
|
156
|
+
try {
|
|
157
|
+
execSync(buildCmd, { cwd: projectDir, stdio: "pipe" });
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
console.warn(`Warning: build command failed: ${buildCmd} in ${projectDir}`);
|
|
90
161
|
}
|
|
91
162
|
}
|
|
92
|
-
return { deployedFiles, hashEntries, skippedFiles };
|
|
163
|
+
return { deployedFiles, hashEntries, skippedFiles, overwrittenFiles };
|
|
93
164
|
}
|
|
94
165
|
finally {
|
|
95
166
|
await provider.cleanup().catch(() => { });
|
package/dist/asset/walker.js
CHANGED
|
@@ -53,6 +53,8 @@ const findMatchingVersionDirs = async (repoDir, targetSemver) => {
|
|
|
53
53
|
accelplatformVersion: "",
|
|
54
54
|
database: "",
|
|
55
55
|
projectVersion: "",
|
|
56
|
+
packageManager: "",
|
|
57
|
+
javascript: false,
|
|
56
58
|
};
|
|
57
59
|
if (evaluateCondition(meta.conditions, context)) {
|
|
58
60
|
matched.push(dirPath);
|
|
@@ -47,6 +47,15 @@ export declare const attachCommand: import("citty").CommandDef<{
|
|
|
47
47
|
type: "string";
|
|
48
48
|
description: string;
|
|
49
49
|
};
|
|
50
|
+
"package-manager": {
|
|
51
|
+
type: "string";
|
|
52
|
+
description: string;
|
|
53
|
+
};
|
|
54
|
+
overwrite: {
|
|
55
|
+
type: "boolean";
|
|
56
|
+
description: string;
|
|
57
|
+
default: false;
|
|
58
|
+
};
|
|
50
59
|
"skip-install": {
|
|
51
60
|
type: "boolean";
|
|
52
61
|
description: string;
|
package/dist/commands/attach.js
CHANGED
|
@@ -4,12 +4,15 @@ import { stat } from "node:fs/promises";
|
|
|
4
4
|
import { basename, join } from "node:path";
|
|
5
5
|
import { CLI_VERSION } from "../core/constants.js";
|
|
6
6
|
import { runPrompts } from "../interactive/prompts.js";
|
|
7
|
-
import { deployAssets } from "../asset/deployer.js";
|
|
7
|
+
import { deployAssets, } from "../asset/deployer.js";
|
|
8
8
|
import { createLocalAssetProvider } from "../asset/local-provider.js";
|
|
9
9
|
import { createFileAssetProvider } from "../asset/file-provider.js";
|
|
10
10
|
import { defaultAssetSourcePath } from "../asset/default-source.js";
|
|
11
11
|
import { getMessage } from "../i18n/index.js";
|
|
12
12
|
import { detectLocale } from "../utils/locale-detect.js";
|
|
13
|
+
import { printSummary } from "../interactive/summary.js";
|
|
14
|
+
import { printNextSteps } from "../interactive/next-steps.js";
|
|
15
|
+
import { buildProgressCallbacks } from "../interactive/progress.js";
|
|
13
16
|
export const attachCommand = defineCommand({
|
|
14
17
|
meta: {
|
|
15
18
|
name: "attach",
|
|
@@ -64,6 +67,15 @@ export const attachCommand = defineCommand({
|
|
|
64
67
|
type: "string",
|
|
65
68
|
description: "Maven artifactId (defaults to project name)",
|
|
66
69
|
},
|
|
70
|
+
"package-manager": {
|
|
71
|
+
type: "string",
|
|
72
|
+
description: "Package manager (bun, npm, yarn, pnpm). Default: bun",
|
|
73
|
+
},
|
|
74
|
+
overwrite: {
|
|
75
|
+
type: "boolean",
|
|
76
|
+
description: "Overwrite existing files without per-file confirmation",
|
|
77
|
+
default: false,
|
|
78
|
+
},
|
|
67
79
|
"skip-install": {
|
|
68
80
|
type: "boolean",
|
|
69
81
|
description: "Skip dependency installation",
|
|
@@ -112,6 +124,7 @@ export const attachCommand = defineCommand({
|
|
|
112
124
|
agent: agentArg
|
|
113
125
|
? agentArg.split(",").map((a) => a.trim())
|
|
114
126
|
: undefined,
|
|
127
|
+
packageManager: args["package-manager"],
|
|
115
128
|
locale,
|
|
116
129
|
noInteraction: args["non-interactive"],
|
|
117
130
|
isInit: false,
|
|
@@ -138,6 +151,7 @@ export const attachCommand = defineCommand({
|
|
|
138
151
|
agents: resolved.agents,
|
|
139
152
|
javascript: resolved.javascript,
|
|
140
153
|
locale: resolved.locale,
|
|
154
|
+
packageManager: resolved.packageManager,
|
|
141
155
|
jugglingProject: resolved.jugglingProject,
|
|
142
156
|
deployedAssets: {},
|
|
143
157
|
};
|
|
@@ -146,22 +160,89 @@ export const attachCommand = defineCommand({
|
|
|
146
160
|
const provider = serverUrl
|
|
147
161
|
? createLocalAssetProvider(serverUrl)
|
|
148
162
|
: createFileAssetProvider(assetSource);
|
|
149
|
-
|
|
163
|
+
const isInteractive = !args["non-interactive"];
|
|
164
|
+
const overwriteFlag = args.overwrite;
|
|
165
|
+
if (isInteractive) {
|
|
166
|
+
printSummary(settings, projectDir, locale);
|
|
167
|
+
}
|
|
168
|
+
let skipAll = false;
|
|
169
|
+
let onExistingFile;
|
|
170
|
+
if (!isInteractive) {
|
|
171
|
+
if (!overwriteFlag)
|
|
172
|
+
skipAll = true;
|
|
173
|
+
}
|
|
174
|
+
else if (!overwriteFlag) {
|
|
175
|
+
let sticky;
|
|
176
|
+
onExistingFile = async (path) => {
|
|
177
|
+
if (sticky === "all")
|
|
178
|
+
return "overwrite";
|
|
179
|
+
if (sticky === "skipAll")
|
|
180
|
+
return "skip";
|
|
181
|
+
const choice = await p.select({
|
|
182
|
+
message: getMessage("attach.overwritePrompt", locale, { path }),
|
|
183
|
+
options: [
|
|
184
|
+
{
|
|
185
|
+
value: "yes",
|
|
186
|
+
label: getMessage("attach.overwritePrompt.yes", locale),
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
value: "no",
|
|
190
|
+
label: getMessage("attach.overwritePrompt.no", locale),
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
value: "all",
|
|
194
|
+
label: getMessage("attach.overwritePrompt.all", locale),
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
value: "skipAll",
|
|
198
|
+
label: getMessage("attach.overwritePrompt.skipAll", locale),
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
});
|
|
202
|
+
if (p.isCancel(choice))
|
|
203
|
+
process.exit(0);
|
|
204
|
+
if (choice === "all") {
|
|
205
|
+
sticky = "all";
|
|
206
|
+
return "overwrite";
|
|
207
|
+
}
|
|
208
|
+
if (choice === "skipAll") {
|
|
209
|
+
sticky = "skipAll";
|
|
210
|
+
return "skip";
|
|
211
|
+
}
|
|
212
|
+
return choice === "yes" ? "overwrite" : "skip";
|
|
213
|
+
};
|
|
214
|
+
}
|
|
150
215
|
const result = await deployAssets({
|
|
151
216
|
projectDir,
|
|
152
217
|
settings,
|
|
153
218
|
provider,
|
|
154
219
|
noInstall: args["skip-install"],
|
|
155
|
-
skipExistingFiles:
|
|
220
|
+
skipExistingFiles: skipAll || undefined,
|
|
221
|
+
onExistingFile,
|
|
222
|
+
progress: buildProgressCallbacks(locale),
|
|
156
223
|
});
|
|
224
|
+
for (const path of result.overwrittenFiles) {
|
|
225
|
+
p.log.info(getMessage("attach.overwritten", locale, { path }));
|
|
226
|
+
}
|
|
157
227
|
for (const path of result.skippedFiles) {
|
|
158
228
|
p.log.warn(getMessage("warning.fileExists", locale, { path }));
|
|
159
229
|
}
|
|
230
|
+
if (result.overwrittenFiles.length > 0) {
|
|
231
|
+
p.log.info(getMessage("attach.overwriteSummary", locale, {
|
|
232
|
+
count: String(result.overwrittenFiles.length),
|
|
233
|
+
}));
|
|
234
|
+
}
|
|
160
235
|
if (result.skippedFiles.length > 0) {
|
|
161
236
|
p.log.info(getMessage("attach.skipSummary", locale, {
|
|
162
237
|
count: String(result.skippedFiles.length),
|
|
163
238
|
}));
|
|
164
239
|
}
|
|
165
240
|
p.log.success(getMessage("progress.complete", locale));
|
|
241
|
+
printNextSteps({
|
|
242
|
+
projectDir,
|
|
243
|
+
agents: resolved.agents,
|
|
244
|
+
isInit: false,
|
|
245
|
+
locale,
|
|
246
|
+
});
|
|
166
247
|
},
|
|
167
248
|
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AccelCredentials, StagingResponse } from "../core/types.js";
|
|
2
|
+
import { type ApiClient } from "../deploy/api-client.js";
|
|
3
|
+
export declare const toImmFileName: (zipPath: string) => string;
|
|
4
|
+
type ConfirmInfo = {
|
|
5
|
+
endpoint: string;
|
|
6
|
+
stagingId: string;
|
|
7
|
+
sourceFile: string;
|
|
8
|
+
sentAs: string;
|
|
9
|
+
};
|
|
10
|
+
export type DeployPrompts = {
|
|
11
|
+
selectStaging: (stagings: StagingResponse[], locale: string) => Promise<string>;
|
|
12
|
+
selectZip: (zips: string[], locale: string) => Promise<string>;
|
|
13
|
+
description: (locale: string) => Promise<string>;
|
|
14
|
+
confirm: (info: ConfirmInfo, locale: string) => Promise<boolean>;
|
|
15
|
+
};
|
|
16
|
+
export type RunDeployDeps = {
|
|
17
|
+
projectDir: string;
|
|
18
|
+
locale?: string;
|
|
19
|
+
ensureCredentials?: (projectDir: string, locale: string) => Promise<AccelCredentials>;
|
|
20
|
+
scanTargets?: (projectDir: string) => Promise<string[]>;
|
|
21
|
+
apiClientFactory?: (endpoint: string, apiKey: string) => ApiClient;
|
|
22
|
+
prompts?: DeployPrompts;
|
|
23
|
+
};
|
|
24
|
+
export declare const runDeploy: (deps: RunDeployDeps) => Promise<void>;
|
|
25
|
+
export declare const deployCommand: import("citty").CommandDef<{}>;
|
|
26
|
+
export {};
|