connectbase-client 6.3.3 → 6.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +3 -1
- package/dist/cli.js +147 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,38 @@
|
|
|
3
3
|
본 SDK 의 모든 주요 변경사항을 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/) 형식으로 기록합니다.
|
|
4
4
|
버전은 [Semantic Versioning](https://semver.org/lang/ko/) 을 따릅니다.
|
|
5
5
|
|
|
6
|
+
## [6.4.0] - 2026-10-01
|
|
7
|
+
|
|
8
|
+
### Added — 웹 배포에 브라우저 ML 모델 확장자 허용 (`.onnx` `.tflite` `.task` `.safetensors`)
|
|
9
|
+
|
|
10
|
+
onnxruntime-web / TensorFlow Lite / MediaPipe Tasks / transformers.js 가 fetch 로 읽는 모델 파일을
|
|
11
|
+
`deploy` 가 허용목록에 없다는 이유로 빠뜨렸습니다. 배포는 성공으로 끝나는데 사이트에서는 404 였습니다.
|
|
12
|
+
이제 네 확장자 모두 바이너리로 수집되며, 웹 스토리지 파일당 한도(약 6 MB)를 넘는 모델은 다른 대용량
|
|
13
|
+
바이너리와 똑같이 presigned URL 로 오브젝트 스토리지에 직접 올라갑니다. `.bin` 으로 이름을 바꾸는
|
|
14
|
+
우회는 더 이상 필요 없습니다.
|
|
15
|
+
|
|
16
|
+
### Changed — 허용되지 않는 파일이 있으면 배포 때 알려줍니다
|
|
17
|
+
|
|
18
|
+
허용되지 않는 확장자의 파일은 여전히 배포에서 제외되지만, 이제 조용히 넘어가지 않습니다. 파일 수집
|
|
19
|
+
직후 제외된 파일 목록(앞 10개 + 외 N개), 확장자별 개수, 허용 확장자 목록을 경고로 보여주고, 배포 성공
|
|
20
|
+
메시지 뒤에도 "N개는 포함되지 않았습니다" 를 한 번 더 찍습니다. 숨김 파일/폴더(`.env`, `.git/` 등)는
|
|
21
|
+
의도적 제외라 목록에 넣지 않습니다. 배포 결과(종료 코드)는 바뀌지 않습니다.
|
|
22
|
+
|
|
23
|
+
## [6.3.4] - 2026-09-08
|
|
24
|
+
|
|
25
|
+
### Fixed — deploy 스크립트가 `npx` 로 CLI 를 부르면 6.3.3 의 "스크립트 안" 판정이 빠지던 문제
|
|
26
|
+
|
|
27
|
+
6.3.3 은 `npm_lifecycle_event` 가 package.json scripts 의 이름이면 스크립트 안으로 봤습니다. 그런데
|
|
28
|
+
`"deploy": "vite build && npx -y -p connectbase-client@latest connectbase deploy ./dist"` 처럼 npx 로
|
|
29
|
+
CLI 를 부르는 스크립트(예전 init 이 만들던 형태)에서는 npx 가 `npm_lifecycle_event` 를 "npx" 로,
|
|
30
|
+
`npm_lifecycle_script` 도 덮어써 `npm run deploy → npx` 와 직접 `npx` 의 환경변수가 완전히 같아집니다.
|
|
31
|
+
그래서 여전히 "deploy 스크립트를 쓰세요" 안내가 그 스크립트 안에서 찍혔습니다.
|
|
32
|
+
|
|
33
|
+
이제 (1) pnpm 은 npx 가 덮어쓰지 않는 `PNPM_SCRIPT_SRC_DIR` 로, (2) npm / yarn / bun 은 부모 프로세스
|
|
34
|
+
명령줄(Linux `/proc`, macOS `ps`)에서 `<pm> run <스크립트>` 를 찾아 스크립트 안임을 판정합니다.
|
|
35
|
+
`npm-cli.js exec …` 나 스크립트 본문 자체에는 맞지 않는 패턴이라 직접 `npx connectbase-client deploy`
|
|
36
|
+
를 친 경우엔 종전대로 안내합니다. 판정에 실패해도 안내 한 줄이 더 나올 뿐 배포에는 영향이 없습니다.
|
|
37
|
+
|
|
6
38
|
## [6.3.3] - 2026-09-08
|
|
7
39
|
|
|
8
40
|
### Fixed — `deploy` 가 방금 빌드한 직후에도 "배포 전 빌드를 먼저 실행하세요" 를 찍던 문제
|
package/README.md
CHANGED
|
@@ -294,7 +294,9 @@ In CI, read the Secret Key from a repository secret:
|
|
|
294
294
|
### Requirements
|
|
295
295
|
|
|
296
296
|
- `index.html` must exist in the root of the deploy directory
|
|
297
|
-
- Supported file types: `.html`, `.css`, `.js`, `.json`, `.svg`, `.png`, `.jpg`, `.gif`, `.webp`, `.woff`, `.woff2`, `.ttf`, `.mp3`, `.mp4`, `.pdf`, `.wasm`, etc.
|
|
297
|
+
- Supported file types: `.html`, `.css`, `.js`, `.json`, `.svg`, `.png`, `.jpg`, `.gif`, `.webp`, `.woff`, `.woff2`, `.ttf`, `.mp3`, `.mp4`, `.pdf`, `.wasm`, 3D assets (`.glb`, `.gltf`, `.bin`), browser ML models (`.onnx`, `.tflite`, `.task`, `.safetensors`), etc.
|
|
298
|
+
- Files with other extensions are skipped, and `deploy` prints the skipped list as a warning. Hidden files and folders (`.env`, `.git/`) are skipped silently.
|
|
299
|
+
- Binary files over the per-file limit (~6 MB) are uploaded directly to object storage via presigned URLs.
|
|
298
300
|
|
|
299
301
|
### SPA Mode
|
|
300
302
|
|
package/dist/cli.js
CHANGED
|
@@ -32,10 +32,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
32
32
|
var cli_exports = {};
|
|
33
33
|
__export(cli_exports, {
|
|
34
34
|
TunnelConnectSelector: () => TunnelConnectSelector,
|
|
35
|
+
ancestorCommandLines: () => ancestorCommandLines,
|
|
35
36
|
apiErrorMessage: () => apiErrorMessage,
|
|
36
37
|
buildFirstHint: () => buildFirstHint,
|
|
38
|
+
collectDeployFiles: () => collectDeployFiles,
|
|
37
39
|
computeDeployDiff: () => computeDeployDiff,
|
|
38
40
|
detectPackageManager: () => detectPackageManager,
|
|
41
|
+
formatSkippedFilesReport: () => formatSkippedFilesReport,
|
|
39
42
|
getTunnelConnectCandidates: () => getTunnelConnectCandidates,
|
|
40
43
|
guessMimeType: () => guessMimeType,
|
|
41
44
|
isAllowedDeployExt: () => isAllowedDeployExt,
|
|
@@ -43,8 +46,10 @@ __export(cli_exports, {
|
|
|
43
46
|
makeRequest: () => makeRequest,
|
|
44
47
|
normalizeRelativePath: () => normalizeRelativePath,
|
|
45
48
|
packageManagerCommands: () => packageManagerCommands,
|
|
49
|
+
packageScriptInvocationPattern: () => packageScriptInvocationPattern,
|
|
46
50
|
parseArgs: () => parseArgs,
|
|
47
51
|
registerEndpointBinding: () => registerEndpointBinding,
|
|
52
|
+
runningInsidePackageScript: () => runningInsidePackageScript,
|
|
48
53
|
sha256Hex: () => sha256Hex,
|
|
49
54
|
storageAdminHeaders: () => storageAdminHeaders
|
|
50
55
|
});
|
|
@@ -151,7 +156,7 @@ function handleTunnelError(msg, appId, localPort) {
|
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
// src/cli.ts
|
|
154
|
-
var VERSION = "6.
|
|
159
|
+
var VERSION = "6.4.0" ? "6.4.0" : getPackageVersion();
|
|
155
160
|
var DEFAULT_BASE_URL = "https://api.connectbase.world";
|
|
156
161
|
var colors = {
|
|
157
162
|
reset: "\x1B[0m",
|
|
@@ -212,7 +217,17 @@ var ALLOWED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
212
217
|
// 3D 에셋: .glb/.bin 은 바이너리, .gltf 는 JSON(텍스트)
|
|
213
218
|
".glb",
|
|
214
219
|
".gltf",
|
|
215
|
-
".bin"
|
|
220
|
+
".bin",
|
|
221
|
+
// 브라우저 추론용 ML 모델 (platform-issue 01a0f660). 전부 바이너리다.
|
|
222
|
+
// .onnx — onnxruntime-web
|
|
223
|
+
// .tflite — TensorFlow Lite (tfjs-tflite 등)
|
|
224
|
+
// .task — MediaPipe Tasks 번들
|
|
225
|
+
// .safetensors — transformers.js 등의 가중치
|
|
226
|
+
// 수 MB~수십 MB 가 흔하므로 BINARY_EXTENSIONS 에도 넣어 대용량 오프로드(presign) 대상으로 만든다.
|
|
227
|
+
".onnx",
|
|
228
|
+
".tflite",
|
|
229
|
+
".task",
|
|
230
|
+
".safetensors"
|
|
216
231
|
]);
|
|
217
232
|
var ALLOWED_EXTENSIONLESS_FILES = /* @__PURE__ */ new Set(["_redirects", "_headers"]);
|
|
218
233
|
var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
@@ -237,7 +252,11 @@ var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
237
252
|
".zip",
|
|
238
253
|
".wasm",
|
|
239
254
|
".glb",
|
|
240
|
-
".bin"
|
|
255
|
+
".bin",
|
|
256
|
+
".onnx",
|
|
257
|
+
".tflite",
|
|
258
|
+
".task",
|
|
259
|
+
".safetensors"
|
|
241
260
|
]);
|
|
242
261
|
var MIME_BY_EXT = {
|
|
243
262
|
".png": "image/png",
|
|
@@ -263,7 +282,13 @@ var MIME_BY_EXT = {
|
|
|
263
282
|
".wasm": "application/wasm",
|
|
264
283
|
".glb": "model/gltf-binary",
|
|
265
284
|
".gltf": "model/gltf+json",
|
|
266
|
-
".bin": "application/octet-stream"
|
|
285
|
+
".bin": "application/octet-stream",
|
|
286
|
+
// ML 모델은 등록된 표준 MIME 이 없다. 로더(onnxruntime-web/MediaPipe/transformers.js)는
|
|
287
|
+
// fetch → ArrayBuffer 로 읽으므로 octet-stream 이면 충분하다.
|
|
288
|
+
".onnx": "application/octet-stream",
|
|
289
|
+
".tflite": "application/octet-stream",
|
|
290
|
+
".task": "application/octet-stream",
|
|
291
|
+
".safetensors": "application/octet-stream"
|
|
267
292
|
};
|
|
268
293
|
function guessMimeType(filePath) {
|
|
269
294
|
if (ALLOWED_EXTENSIONLESS_FILES.has(path2.basename(filePath))) {
|
|
@@ -346,7 +371,13 @@ function loadConfig() {
|
|
|
346
371
|
}
|
|
347
372
|
return config;
|
|
348
373
|
}
|
|
349
|
-
function
|
|
374
|
+
function collectDeployFiles(dir) {
|
|
375
|
+
const skipped = [];
|
|
376
|
+
const files = collectFiles(dir, dir, skipped);
|
|
377
|
+
skipped.sort();
|
|
378
|
+
return { files, skipped };
|
|
379
|
+
}
|
|
380
|
+
function collectFiles(dir, baseDir, skipped) {
|
|
350
381
|
const files = [];
|
|
351
382
|
const entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
352
383
|
for (const entry of entries) {
|
|
@@ -354,14 +385,15 @@ function collectFiles(dir, baseDir = dir) {
|
|
|
354
385
|
const relativePath = path2.relative(baseDir, fullPath);
|
|
355
386
|
if (entry.isDirectory()) {
|
|
356
387
|
if (!entry.name.startsWith(".")) {
|
|
357
|
-
files.push(...collectFiles(fullPath, baseDir));
|
|
388
|
+
files.push(...collectFiles(fullPath, baseDir, skipped));
|
|
358
389
|
}
|
|
359
390
|
} else if (entry.isFile()) {
|
|
360
391
|
const ext = path2.extname(entry.name).toLowerCase();
|
|
361
|
-
if (
|
|
392
|
+
if (entry.name.startsWith(".")) {
|
|
362
393
|
continue;
|
|
363
394
|
}
|
|
364
|
-
if (entry.name
|
|
395
|
+
if (!isAllowedDeployExt(entry.name)) {
|
|
396
|
+
skipped.push(normalizeRelativePath(relativePath));
|
|
365
397
|
continue;
|
|
366
398
|
}
|
|
367
399
|
const isBinary = BINARY_EXTENSIONS.has(ext);
|
|
@@ -382,6 +414,44 @@ function collectFiles(dir, baseDir = dir) {
|
|
|
382
414
|
}
|
|
383
415
|
return files;
|
|
384
416
|
}
|
|
417
|
+
var SKIPPED_FILES_LIST_LIMIT = 10;
|
|
418
|
+
function formatSkippedFilesReport(skipped, limit = SKIPPED_FILES_LIST_LIMIT) {
|
|
419
|
+
if (skipped.length === 0) return [];
|
|
420
|
+
const lines = [];
|
|
421
|
+
lines.push(
|
|
422
|
+
`\uD5C8\uC6A9\uB418\uC9C0 \uC54A\uB294 \uD655\uC7A5\uC790\uB77C \uBC30\uD3EC\uC5D0\uC11C \uC81C\uC678\uB41C \uD30C\uC77C ${skipped.length}\uAC1C \u2014 \uC0AC\uC774\uD2B8\uC5D0\uC11C 404 \uAC00 \uB429\uB2C8\uB2E4:`
|
|
423
|
+
);
|
|
424
|
+
for (const p of skipped.slice(0, limit)) lines.push(` \u2022 ${p}`);
|
|
425
|
+
if (skipped.length > limit) {
|
|
426
|
+
lines.push(` \u2026 \uC678 ${skipped.length - limit}\uAC1C`);
|
|
427
|
+
}
|
|
428
|
+
const byExt = /* @__PURE__ */ new Map();
|
|
429
|
+
for (const p of skipped) {
|
|
430
|
+
const ext = path2.extname(p).toLowerCase() || "(\uD655\uC7A5\uC790 \uC5C6\uC74C)";
|
|
431
|
+
byExt.set(ext, (byExt.get(ext) ?? 0) + 1);
|
|
432
|
+
}
|
|
433
|
+
const extSummary = [...byExt.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).map(([ext, n]) => `${ext} ${n}\uAC1C`).join(", ");
|
|
434
|
+
lines.push(` \uD655\uC7A5\uC790\uBCC4: ${extSummary}`);
|
|
435
|
+
lines.push(
|
|
436
|
+
` \uD5C8\uC6A9 \uD655\uC7A5\uC790: ${[...ALLOWED_EXTENSIONS].join(" ")} (+ \uD655\uC7A5\uC790 \uC5C6\uB294 ${[...ALLOWED_EXTENSIONLESS_FILES].join(", ")})`
|
|
437
|
+
);
|
|
438
|
+
lines.push(
|
|
439
|
+
" \uD544\uC694\uD55C \uD30C\uC77C\uC774\uBA74 \uD5C8\uC6A9 \uD655\uC7A5\uC790\uB85C \uBC14\uAFB8\uAC70\uB098, \uD30C\uC77C \uC2A4\uD1A0\uB9AC\uC9C0(cb.storage)\uC5D0 \uC62C\uB824 URL \uB85C \uCC38\uC870\uD558\uC138\uC694."
|
|
440
|
+
);
|
|
441
|
+
return lines;
|
|
442
|
+
}
|
|
443
|
+
function reportSkippedFiles(skipped) {
|
|
444
|
+
const lines = formatSkippedFilesReport(skipped);
|
|
445
|
+
if (lines.length === 0) return;
|
|
446
|
+
warn(`${colors.yellow}${lines[0]}${colors.reset}`);
|
|
447
|
+
for (const line of lines.slice(1)) log(line);
|
|
448
|
+
}
|
|
449
|
+
function remindSkippedFiles(skipped) {
|
|
450
|
+
if (skipped.length === 0) return;
|
|
451
|
+
warn(
|
|
452
|
+
`\uB2E8, \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uB294 \uD655\uC7A5\uC790 \uD30C\uC77C ${skipped.length}\uAC1C\uB294 \uBC30\uD3EC\uC5D0 \uD3EC\uD568\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4 (\uC704 \uBAA9\uB85D \uCC38\uACE0).`
|
|
453
|
+
);
|
|
454
|
+
}
|
|
385
455
|
function formatSize(bytes) {
|
|
386
456
|
if (bytes >= 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
387
457
|
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
@@ -680,7 +750,8 @@ async function deploy(directory, config, isDev = false, deployOpts = {}) {
|
|
|
680
750
|
try {
|
|
681
751
|
const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
|
|
682
752
|
const pm = packageManagerCommands(detectPackageManager(process.cwd()));
|
|
683
|
-
|
|
753
|
+
const inside = runningInsidePackageScript(pkg.scripts ?? {});
|
|
754
|
+
for (const line of buildFirstHint(pkg, pm, inside)) warn(line);
|
|
684
755
|
} catch {
|
|
685
756
|
}
|
|
686
757
|
}
|
|
@@ -695,17 +766,19 @@ async function deploy(directory, config, isDev = false, deployOpts = {}) {
|
|
|
695
766
|
}
|
|
696
767
|
info(`\uBC30\uD3EC \uC900\uBE44 \uC911... ${dir}`);
|
|
697
768
|
process.stdout.write(`${colors.dim}\uD30C\uC77C \uC218\uC9D1 \uC911...${colors.reset}`);
|
|
698
|
-
const files =
|
|
769
|
+
const { files, skipped } = collectDeployFiles(dir);
|
|
699
770
|
process.stdout.write(`\r${colors.dim} \r${colors.reset}`);
|
|
700
771
|
if (files.length === 0) {
|
|
772
|
+
reportSkippedFiles(skipped);
|
|
701
773
|
error("\uBC30\uD3EC\uD560 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
702
774
|
process.exit(1);
|
|
703
775
|
}
|
|
704
776
|
const totalSize = files.reduce((sum, f) => sum + f.content.length, 0);
|
|
705
777
|
const sizeKB = (totalSize / 1024).toFixed(1);
|
|
706
778
|
log(
|
|
707
|
-
`${colors.green}\u2713${colors.reset} ${files.length}\uAC1C \uD30C\uC77C \uBC1C\uACAC (${sizeKB} KB)`
|
|
779
|
+
`${colors.green}\u2713${colors.reset} ${files.length}\uAC1C \uD30C\uC77C \uBC1C\uACAC (${sizeKB} KB)${skipped.length > 0 ? ` ${colors.yellow}\u2014 ${skipped.length}\uAC1C \uC81C\uC678${colors.reset}` : ""}`
|
|
708
780
|
);
|
|
781
|
+
reportSkippedFiles(skipped);
|
|
709
782
|
const target = isDev ? "qa" : void 0;
|
|
710
783
|
const envLabel = isDev ? "QA" : "Prod";
|
|
711
784
|
if (isDev) {
|
|
@@ -732,6 +805,7 @@ async function deploy(directory, config, isDev = false, deployOpts = {}) {
|
|
|
732
805
|
timeoutMs,
|
|
733
806
|
target
|
|
734
807
|
);
|
|
808
|
+
remindSkippedFiles(skipped);
|
|
735
809
|
return;
|
|
736
810
|
}
|
|
737
811
|
const diff = computeDeployDiff(files, manifest);
|
|
@@ -750,6 +824,7 @@ ${colors.cyan}URL: https://${config.storageId}.web.connectbase.world${colors.res
|
|
|
750
824
|
`
|
|
751
825
|
);
|
|
752
826
|
}
|
|
827
|
+
remindSkippedFiles(skipped);
|
|
753
828
|
return;
|
|
754
829
|
}
|
|
755
830
|
await offloadLargeBinaries(
|
|
@@ -773,6 +848,7 @@ ${colors.cyan}URL: https://${config.storageId}.web.connectbase.world${colors.res
|
|
|
773
848
|
timeoutMs,
|
|
774
849
|
target
|
|
775
850
|
);
|
|
851
|
+
remindSkippedFiles(skipped);
|
|
776
852
|
} catch (err) {
|
|
777
853
|
process.stdout.write("\r \r");
|
|
778
854
|
error(`\uB124\uD2B8\uC6CC\uD06C \uC624\uB958: ${err instanceof Error ? err.message : err}`);
|
|
@@ -1642,12 +1718,63 @@ ${entry}
|
|
|
1642
1718
|
success(".gitignore \uC0DD\uC131 \uC644\uB8CC");
|
|
1643
1719
|
}
|
|
1644
1720
|
}
|
|
1645
|
-
function
|
|
1721
|
+
function runningInsidePackageScript(scripts, env = process.env, ancestors = ancestorCommandLines) {
|
|
1722
|
+
const names = Object.keys(scripts);
|
|
1723
|
+
if (names.length === 0) return false;
|
|
1724
|
+
if (env.npm_lifecycle_event && names.includes(env.npm_lifecycle_event)) {
|
|
1725
|
+
return true;
|
|
1726
|
+
}
|
|
1727
|
+
if (env.PNPM_SCRIPT_SRC_DIR) return true;
|
|
1728
|
+
if (env.npm_lifecycle_event !== "npx") return false;
|
|
1729
|
+
const pattern = packageScriptInvocationPattern(names);
|
|
1730
|
+
return ancestors().some((cmd) => pattern.test(cmd));
|
|
1731
|
+
}
|
|
1732
|
+
function packageScriptInvocationPattern(names) {
|
|
1733
|
+
const alt = names.map((n) => n.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
|
|
1734
|
+
return new RegExp(
|
|
1735
|
+
`^(?:\\S*node(?:\\.exe)?\\s+)?\\S*(?:npm(?:-cli)?|pnpm|yarn|bun)(?:\\.c?js)?\\s+(?:run(?:-script)?\\s+)?(?:-\\S+\\s+)*(?:${alt})(?:\\s|$)`
|
|
1736
|
+
);
|
|
1737
|
+
}
|
|
1738
|
+
function ancestorCommandLines(maxDepth = 8) {
|
|
1739
|
+
const lines = [];
|
|
1740
|
+
let pid = process.ppid;
|
|
1741
|
+
for (let i = 0; i < maxDepth && pid > 1; i++) {
|
|
1742
|
+
let cmd = "";
|
|
1743
|
+
let ppid = 0;
|
|
1744
|
+
try {
|
|
1745
|
+
if (process.platform === "linux") {
|
|
1746
|
+
cmd = fs2.readFileSync(`/proc/${pid}/cmdline`).toString("utf8").replace(/\0/g, " ").trim();
|
|
1747
|
+
const stat = fs2.readFileSync(`/proc/${pid}/stat`, "utf8");
|
|
1748
|
+
ppid = parseInt(
|
|
1749
|
+
stat.slice(stat.lastIndexOf(")") + 2).split(" ")[1],
|
|
1750
|
+
10
|
|
1751
|
+
);
|
|
1752
|
+
} else if (process.platform === "darwin") {
|
|
1753
|
+
const { execSync } = require("child_process");
|
|
1754
|
+
const out = execSync(`ps -o ppid=,args= -p ${pid}`, {
|
|
1755
|
+
encoding: "utf-8",
|
|
1756
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1757
|
+
}).trim();
|
|
1758
|
+
const m = out.match(/^\s*(\d+)\s+(.*)$/);
|
|
1759
|
+
if (!m) break;
|
|
1760
|
+
ppid = parseInt(m[1], 10);
|
|
1761
|
+
cmd = m[2];
|
|
1762
|
+
} else {
|
|
1763
|
+
break;
|
|
1764
|
+
}
|
|
1765
|
+
} catch {
|
|
1766
|
+
break;
|
|
1767
|
+
}
|
|
1768
|
+
lines.push(cmd);
|
|
1769
|
+
if (!Number.isFinite(ppid)) break;
|
|
1770
|
+
pid = ppid;
|
|
1771
|
+
}
|
|
1772
|
+
return lines;
|
|
1773
|
+
}
|
|
1774
|
+
function buildFirstHint(pkg, pm, insideScript) {
|
|
1646
1775
|
const scripts = pkg?.scripts ?? {};
|
|
1647
1776
|
if (!scripts.build) return [];
|
|
1648
|
-
if (
|
|
1649
|
-
return [];
|
|
1650
|
-
}
|
|
1777
|
+
if (insideScript) return [];
|
|
1651
1778
|
if (typeof scripts.deploy === "string" && scripts.deploy.includes("build")) {
|
|
1652
1779
|
return [
|
|
1653
1780
|
`\uBE4C\uB4DC\uAE4C\uC9C0 \uD55C \uBC88\uC5D0 \uD558\uB824\uBA74 deploy \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uC4F0\uC138\uC694: ${pm.run("deploy")}`
|
|
@@ -3822,10 +3949,13 @@ main().catch((err) => {
|
|
|
3822
3949
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3823
3950
|
0 && (module.exports = {
|
|
3824
3951
|
TunnelConnectSelector,
|
|
3952
|
+
ancestorCommandLines,
|
|
3825
3953
|
apiErrorMessage,
|
|
3826
3954
|
buildFirstHint,
|
|
3955
|
+
collectDeployFiles,
|
|
3827
3956
|
computeDeployDiff,
|
|
3828
3957
|
detectPackageManager,
|
|
3958
|
+
formatSkippedFilesReport,
|
|
3829
3959
|
getTunnelConnectCandidates,
|
|
3830
3960
|
guessMimeType,
|
|
3831
3961
|
isAllowedDeployExt,
|
|
@@ -3833,8 +3963,10 @@ main().catch((err) => {
|
|
|
3833
3963
|
makeRequest,
|
|
3834
3964
|
normalizeRelativePath,
|
|
3835
3965
|
packageManagerCommands,
|
|
3966
|
+
packageScriptInvocationPattern,
|
|
3836
3967
|
parseArgs,
|
|
3837
3968
|
registerEndpointBinding,
|
|
3969
|
+
runningInsidePackageScript,
|
|
3838
3970
|
sha256Hex,
|
|
3839
3971
|
storageAdminHeaders
|
|
3840
3972
|
});
|