@zalkera/cli 0.28.1 → 0.30.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/README.md +5 -3
- package/dist/main.js +100 -67
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -85,6 +85,8 @@ zalkera logout
|
|
|
85
85
|
|
|
86
86
|
- **`publish` 는 편집을 새 버전으로 만든다.** 올린 것만으로는 손님에게 안 보인다 — 이 동사가
|
|
87
87
|
그 자리다. 정적 사이트는 바로 보이고, Next 사이트는 다시 지은 뒤에 보인다.
|
|
88
|
+
⚠ 사이트 주인이 **서빙을 중단해 둔 사이트**에 위임 계정으로 발행하면 새 버전은 만들어지지만 **손님 화면은 그대로**다 —
|
|
89
|
+
켜는 것은 사이트 주인만 할 수 있고, 무엇을 해야 하는지는 서버 안내가 말한다. 그때는 「손님 화면은 그대로입니다」와 그 안내를 찍는다.
|
|
88
90
|
- **`rollback <판번호>` 는 라이브만 옮긴다.** 이 폴더의 파일은 **안 건드린다** — 맞추려면 `pull`.
|
|
89
91
|
되돌린 판과 폴더가 다르면 그 사실을 말한다(그 상태로 올리면 전부 나가기 때문이다).
|
|
90
92
|
- **되돌릴 대상이 지금 켜진 버전이면 받지 않는다.** 그것은 되돌리기가 아니라 **버리기**다 —
|
|
@@ -103,9 +105,9 @@ zalkera logout
|
|
|
103
105
|
`y`/`버립니다` 를 그대로 이어 붙인다 — 크레딧이 안 걸렸으니 다시 묻지 않는다.
|
|
104
106
|
- 다만 확인하시는 사이 사이트 쪽 편집이 달라졌으면 **아무것도 안 버리고** 멈춘다.
|
|
105
107
|
보여 드린 것과 버리는 것이 갈리면 안 되기 때문이다.
|
|
106
|
-
- ⚠ **되돌리기는
|
|
107
|
-
**새 버전을 세워** 켠다 — 그래서
|
|
108
|
-
그 사실을 함께 말한다.
|
|
108
|
+
- ⚠ **되돌리기는 버전 목록을 되감지 않는다.** 되돌릴 대상이 마지막 버전이 아니면 사이트는 그
|
|
109
|
+
내용으로 **새 버전을 세워** 켠다 — 그래서 「버전 5로 되돌렸습니다」 뒤에 켜진 번호가 10일 수
|
|
110
|
+
있다. 그때 그 사실을 함께 말한다.
|
|
109
111
|
- ⚠ **편집이 걸려 있으면 되돌리기가 막힌다.** 사이트가 그것을 거절한다 — 먼저 `zalkera publish`
|
|
110
112
|
로 새 버전을 만들거나 `zalkera discard` 로 버려야 한다.
|
|
111
113
|
- 그 편집이 **옛 버전 위**에 있으면(그 사이 라이브가 옮겨진 경우) `publish` 쪽도 막힌다.
|
package/dist/main.js
CHANGED
|
@@ -25,7 +25,7 @@ function plainNotice(text, limit = 300) {
|
|
|
25
25
|
return "";
|
|
26
26
|
const cap = Math.min(limit, MAX_CAP);
|
|
27
27
|
const head = text.length > cap * 4 ? text.slice(0, cap * 4) : text;
|
|
28
|
-
const stripped = head.replace(
|
|
28
|
+
const stripped = head.replace(new RegExp("[\\u0000-\\u001f\\u007f-\\u009f\\u2028\\u2029]|\\p{Cf}", "gu"), " ");
|
|
29
29
|
const tidy = defang(stripped).replace(/\s+/g, " ").trim();
|
|
30
30
|
return tidy.length > cap ? `${tidy.slice(0, cap)}\u2026` : tidy;
|
|
31
31
|
}
|
|
@@ -1131,7 +1131,7 @@ async function ensureEnvIgnored(dir) {
|
|
|
1131
1131
|
return "created";
|
|
1132
1132
|
}
|
|
1133
1133
|
const content = await readFile2(path, "utf8");
|
|
1134
|
-
const ignored = content.split("\n").map((line) => line.trim()).some((line) => line === ".env.local" || line === ".env*" || line === ".env*.local");
|
|
1134
|
+
const ignored = content.split("\n").map((line) => line.trim()).some((line) => line === ".env.local" || line === ".env*" || line === ".env.*" || line === ".env*.local");
|
|
1135
1135
|
if (ignored)
|
|
1136
1136
|
return "already";
|
|
1137
1137
|
const suffix = content.endsWith("\n") || content.length === 0 ? "" : "\n";
|
|
@@ -1363,8 +1363,12 @@ async function createSink(targetDir, options) {
|
|
|
1363
1363
|
if (options.rejectVendored === true)
|
|
1364
1364
|
assertNotVendored(segments, name);
|
|
1365
1365
|
if (entry.type === "5") {
|
|
1366
|
-
if (options.decide)
|
|
1367
|
-
|
|
1366
|
+
if (options.decide) {
|
|
1367
|
+
if (options.emptyDirs !== true)
|
|
1368
|
+
return;
|
|
1369
|
+
if (options.decide(`${segments.join("/")}/`) === "skip")
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1368
1372
|
await descend(root, segments, verified);
|
|
1369
1373
|
return;
|
|
1370
1374
|
}
|
|
@@ -1940,7 +1944,39 @@ function serializeSyncLedger(ledger) {
|
|
|
1940
1944
|
}
|
|
1941
1945
|
|
|
1942
1946
|
// ../core/dist/localMark.js
|
|
1947
|
+
import { join as join10 } from "node:path";
|
|
1948
|
+
|
|
1949
|
+
// ../core/dist/gitExclude.js
|
|
1950
|
+
import { chmod as chmod3, lstat as lstat3, readFile as readFile5 } from "node:fs/promises";
|
|
1943
1951
|
import { join as join9 } from "node:path";
|
|
1952
|
+
async function excludeFromGit(root, path) {
|
|
1953
|
+
try {
|
|
1954
|
+
const info = await lstat3(join9(root, ".git")).catch(() => null);
|
|
1955
|
+
if (!info || !info.isDirectory())
|
|
1956
|
+
return "no-git";
|
|
1957
|
+
const dir = await ensureOwnDir(root, ".git", "info");
|
|
1958
|
+
const file = join9(dir, "exclude");
|
|
1959
|
+
const leaf = await lstat3(file).catch((error) => {
|
|
1960
|
+
if (error?.code === "ENOENT")
|
|
1961
|
+
return null;
|
|
1962
|
+
throw error;
|
|
1963
|
+
});
|
|
1964
|
+
if (leaf !== null && !leaf.isFile())
|
|
1965
|
+
return "failed";
|
|
1966
|
+
const current = leaf === null ? "" : await readFile5(file, "utf8");
|
|
1967
|
+
if (current.split(/\r?\n/).some((line) => line.trim() === path))
|
|
1968
|
+
return "already";
|
|
1969
|
+
const prefix = current === "" || current.endsWith("\n") ? "" : "\n";
|
|
1970
|
+
const mode = leaf === null ? 420 : leaf.mode & 511;
|
|
1971
|
+
await writeOwnFile(file, `${current}${prefix}${path}
|
|
1972
|
+
`, mode);
|
|
1973
|
+
if (leaf !== null)
|
|
1974
|
+
await chmod3(file, mode);
|
|
1975
|
+
return "written";
|
|
1976
|
+
} catch {
|
|
1977
|
+
return "failed";
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1944
1980
|
|
|
1945
1981
|
// ../core/dist/sourceVersion.js
|
|
1946
1982
|
var VERSION_DIGEST_PATTERN = /^[0-9a-f]{64}$/;
|
|
@@ -2027,11 +2063,12 @@ async function writeSourceMarkTo(root, mark) {
|
|
|
2027
2063
|
async function writeMarkText(root, text) {
|
|
2028
2064
|
try {
|
|
2029
2065
|
await ensureOwnDir(root, ".zalkera");
|
|
2030
|
-
await writeOwnFile(
|
|
2031
|
-
return { ok: true, text: "" };
|
|
2066
|
+
await writeOwnFile(join10(root, SOURCE_MARK_PATH), text);
|
|
2032
2067
|
} catch (error) {
|
|
2033
2068
|
return { ok: false, reason: error instanceof Error ? error.message : String(error) };
|
|
2034
2069
|
}
|
|
2070
|
+
await excludeFromGit(root, SOURCE_MARK_PATH);
|
|
2071
|
+
return { ok: true, text: "" };
|
|
2035
2072
|
}
|
|
2036
2073
|
|
|
2037
2074
|
// ../core/dist/provenance.js
|
|
@@ -2039,7 +2076,7 @@ var PROVENANCE_PATH = ".zalkera/provenance.json";
|
|
|
2039
2076
|
|
|
2040
2077
|
// ../core/dist/zip.js
|
|
2041
2078
|
init_errors();
|
|
2042
|
-
import { join as
|
|
2079
|
+
import { join as join11, relative as relative3, sep as sep3 } from "node:path";
|
|
2043
2080
|
import { deflateRaw } from "node:zlib";
|
|
2044
2081
|
import { promisify } from "node:util";
|
|
2045
2082
|
var deflate = promisify(deflateRaw);
|
|
@@ -2184,8 +2221,9 @@ var SECRET_NAMES = /* @__PURE__ */ new Set([
|
|
|
2184
2221
|
var SECRET_SUFFIXES = [".pem", ".key", ".p12", ".pfx", ".p8"];
|
|
2185
2222
|
var EXCLUDED_PATHS = /* @__PURE__ */ new Set([".zalkera/source.json", SYNC_LEDGER_PATH, PROVENANCE_PATH]);
|
|
2186
2223
|
var EXCLUDED_PREFIXES = [".zalkera/saved/"];
|
|
2224
|
+
var OWN_TMP = /\.zalkera-[0-9a-f]{12}\.tmp$/;
|
|
2187
2225
|
function isExcludedPath(path) {
|
|
2188
|
-
return EXCLUDED_PATHS.has(path) || EXCLUDED_PREFIXES.some((prefix) => path.startsWith(prefix));
|
|
2226
|
+
return EXCLUDED_PATHS.has(path) || EXCLUDED_PREFIXES.some((prefix) => path.startsWith(prefix)) || OWN_TMP.test(path);
|
|
2189
2227
|
}
|
|
2190
2228
|
function isExcludedEntry(entryPath) {
|
|
2191
2229
|
const path = entryPath.split(sep3).join("/").toLowerCase();
|
|
@@ -2268,8 +2306,8 @@ var SERVER_NORMALIZATION_SETS = {
|
|
|
2268
2306
|
init_errors();
|
|
2269
2307
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
2270
2308
|
import { createHash as createHash5 } from "node:crypto";
|
|
2271
|
-
import { lstat as
|
|
2272
|
-
import { join as
|
|
2309
|
+
import { lstat as lstat4, readdir as readdir3 } from "node:fs/promises";
|
|
2310
|
+
import { join as join12, sep as sep4 } from "node:path";
|
|
2273
2311
|
async function hashWorkdir(root, options = {}) {
|
|
2274
2312
|
const manifest = {};
|
|
2275
2313
|
const cap = Math.min(options.maxEntries ?? MAX_ENTRIES, MAX_ENTRIES);
|
|
@@ -2287,7 +2325,7 @@ async function hashWorkdir(root, options = {}) {
|
|
|
2287
2325
|
if (item.isSymbolicLink())
|
|
2288
2326
|
continue;
|
|
2289
2327
|
if (item.isDirectory()) {
|
|
2290
|
-
await walk(
|
|
2328
|
+
await walk(join12(dir, item.name), relative5);
|
|
2291
2329
|
continue;
|
|
2292
2330
|
}
|
|
2293
2331
|
if (!item.isFile())
|
|
@@ -2296,7 +2334,7 @@ async function hashWorkdir(root, options = {}) {
|
|
|
2296
2334
|
if (seen > cap) {
|
|
2297
2335
|
throw new DevtoolsError("LOCAL_TOO_LARGE", `\uC774 \uD3F4\uB354\uC758 \uD30C\uC77C\uC774 \uB108\uBB34 \uB9CE\uC2B5\uB2C8\uB2E4(${cap}\uAC1C \uCD08\uACFC).`, "\uC0AC\uC774\uD2B8 \uD3F4\uB354\uAC00 \uC544\uB2CC \uACF3\uC744 \uAC00\uB9AC\uD0A4\uACE0 \uC788\uC9C0 \uC54A\uC740\uC9C0 \uD655\uC778\uD574 \uC8FC\uC138\uC694.");
|
|
2298
2336
|
}
|
|
2299
|
-
manifest[relative5] = { sha256: await hashFile(
|
|
2337
|
+
manifest[relative5] = { sha256: await hashFile(join12(dir, item.name)) };
|
|
2300
2338
|
}
|
|
2301
2339
|
}
|
|
2302
2340
|
await walk(root, "");
|
|
@@ -2318,8 +2356,8 @@ async function resolveExisting(root, path) {
|
|
|
2318
2356
|
return null;
|
|
2319
2357
|
let current = root;
|
|
2320
2358
|
for (const part of segments) {
|
|
2321
|
-
const next =
|
|
2322
|
-
const info = await
|
|
2359
|
+
const next = join12(current, part);
|
|
2360
|
+
const info = await lstat4(next).catch(() => null);
|
|
2323
2361
|
if (!info || info.isSymbolicLink())
|
|
2324
2362
|
return null;
|
|
2325
2363
|
current = next;
|
|
@@ -2496,10 +2534,13 @@ var DEFAULT_TIMEOUT_MS2 = 10 * 60 * 1e3;
|
|
|
2496
2534
|
// ../core/dist/tenantScope.js
|
|
2497
2535
|
init_notice();
|
|
2498
2536
|
|
|
2537
|
+
// ../core/dist/git.js
|
|
2538
|
+
init_notice();
|
|
2539
|
+
|
|
2499
2540
|
// ../core/dist/npmChoice.js
|
|
2500
2541
|
import { execFileSync } from "node:child_process";
|
|
2501
2542
|
import { existsSync as existsSync7, realpathSync } from "node:fs";
|
|
2502
|
-
import { delimiter as delimiter2, isAbsolute as isAbsolute2, join as
|
|
2543
|
+
import { delimiter as delimiter2, isAbsolute as isAbsolute2, join as join13, normalize as normalize3, sep as sep5 } from "node:path";
|
|
2503
2544
|
var MIN_SYSTEM_NPM_MAJOR = 9;
|
|
2504
2545
|
function majorOf(version2) {
|
|
2505
2546
|
const m = /^(\d+)\./.exec((version2 ?? "").trim());
|
|
@@ -2562,7 +2603,7 @@ function npmArgvOf(choice, nodePath) {
|
|
|
2562
2603
|
return null;
|
|
2563
2604
|
}
|
|
2564
2605
|
}
|
|
2565
|
-
var PATH_OPS = { join:
|
|
2606
|
+
var PATH_OPS = { join: join13, isAbsolute: isAbsolute2, normalize: normalize3, sep: sep5 };
|
|
2566
2607
|
function probeSystemNpm(nodePath, excludeUnder = [], env = process.env) {
|
|
2567
2608
|
const entries = (env.PATH ?? "").split(delimiter2);
|
|
2568
2609
|
for (const step of systemNpmSearchSteps(entries, PATH_OPS, excludeUnder)) {
|
|
@@ -2641,12 +2682,12 @@ var UPGRADE_NOTICE_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
|
2641
2682
|
|
|
2642
2683
|
// ../core/dist/tokenPath.js
|
|
2643
2684
|
import { homedir as homedir2 } from "node:os";
|
|
2644
|
-
import { isAbsolute as isAbsolute3, join as
|
|
2685
|
+
import { isAbsolute as isAbsolute3, join as join14, resolve as resolve5, sep as sep6 } from "node:path";
|
|
2645
2686
|
function tokenPath(env = process.env, home = homedir2()) {
|
|
2646
|
-
const fallback =
|
|
2687
|
+
const fallback = join14(home, ".config");
|
|
2647
2688
|
const base = env.XDG_CONFIG_HOME;
|
|
2648
2689
|
const inside = base !== void 0 && isAbsolute3(base) && (resolve5(base) === resolve5(home) || resolve5(base).startsWith(resolve5(home) + sep6));
|
|
2649
|
-
return
|
|
2690
|
+
return join14(inside ? resolve5(base) : fallback, "zalkera", "auth.json");
|
|
2650
2691
|
}
|
|
2651
2692
|
|
|
2652
2693
|
// ../core/dist/index.js
|
|
@@ -2766,9 +2807,9 @@ function trimPaths(paths, cap = PATH_LIST_CAP, all = false) {
|
|
|
2766
2807
|
}
|
|
2767
2808
|
|
|
2768
2809
|
// ../core/dist/pull.js
|
|
2769
|
-
import { lstat as
|
|
2810
|
+
import { lstat as lstat5, mkdir as mkdir5, readFile as readFile6, realpath as realpath2, rename as rename2, rmdir, unlink } from "node:fs/promises";
|
|
2770
2811
|
init_errors();
|
|
2771
|
-
import { basename as basename2, dirname as dirname2, join as
|
|
2812
|
+
import { basename as basename2, dirname as dirname2, join as join15, relative as relative4, resolve as resolve6, sep as sep7 } from "node:path";
|
|
2772
2813
|
var SAVED_SUFFIX = ".zalkera-saved";
|
|
2773
2814
|
async function pullSiteSource(options) {
|
|
2774
2815
|
const report = options.onProgress ?? (() => {
|
|
@@ -2867,11 +2908,11 @@ async function requireNoLinkedTargets(root, paths) {
|
|
|
2867
2908
|
const segments = path.split("/").filter((s) => s !== "");
|
|
2868
2909
|
let current = root;
|
|
2869
2910
|
for (const part of segments) {
|
|
2870
|
-
current =
|
|
2911
|
+
current = join15(current, part);
|
|
2871
2912
|
if (checked.has(current))
|
|
2872
2913
|
continue;
|
|
2873
2914
|
checked.add(current);
|
|
2874
|
-
const info = await
|
|
2915
|
+
const info = await lstat5(current).catch(() => null);
|
|
2875
2916
|
if (!info?.isSymbolicLink())
|
|
2876
2917
|
continue;
|
|
2877
2918
|
throw new DevtoolsError("PULL_WOULD_OVERWRITE", `\uC774 \uD3F4\uB354\uC758 ${relative4(root, current).split(sep7).join("/")} \uAC00 \uB2E4\uB978 \uACF3\uC744 \uAC00\uB9AC\uD0A4\uB294 \uBC14\uB85C\uAC00\uAE30\uC785\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uBC1B\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`, "\uADF8 \uBC14\uB85C\uAC00\uAE30\uB97C \uC9C0\uC6B0\uACE0 \uB2E4\uC2DC \uC2E4\uD589\uD574 \uC8FC\uC138\uC694. \uADF8\uB300\uB85C \uB450\uBA74 \uC774 \uD3F4\uB354 \uBC16\uC758 \uAC83\uC744 \uB36E\uC5B4\uC4F0\uAC8C \uB429\uB2C8\uB2E4.");
|
|
@@ -2890,13 +2931,13 @@ function withoutExcluded(declared) {
|
|
|
2890
2931
|
return { incoming, dropped: dropped.sort() };
|
|
2891
2932
|
}
|
|
2892
2933
|
async function readLedger(root) {
|
|
2893
|
-
const text = await
|
|
2934
|
+
const text = await readFile6(join15(root, SYNC_LEDGER_PATH), "utf8").catch(() => null);
|
|
2894
2935
|
return text === null ? null : parseSyncLedger(text);
|
|
2895
2936
|
}
|
|
2896
2937
|
async function writeLedger(root, ledger) {
|
|
2897
2938
|
try {
|
|
2898
2939
|
const dir = await ensureOwnDir(root, ...SYNC_LEDGER_PATH.split("/").slice(0, -1));
|
|
2899
|
-
await writeOwnFile(
|
|
2940
|
+
await writeOwnFile(join15(dir, basename2(SYNC_LEDGER_PATH)), serializeSyncLedger(ledger));
|
|
2900
2941
|
} catch {
|
|
2901
2942
|
return false;
|
|
2902
2943
|
}
|
|
@@ -2905,18 +2946,7 @@ async function writeLedger(root, ledger) {
|
|
|
2905
2946
|
return true;
|
|
2906
2947
|
}
|
|
2907
2948
|
async function ignoreLedger(root) {
|
|
2908
|
-
|
|
2909
|
-
const exists = await stat3(join14(root, ".git")).then((s) => s.isDirectory()).catch(() => false);
|
|
2910
|
-
if (!exists)
|
|
2911
|
-
return;
|
|
2912
|
-
const path = join14(info, "exclude");
|
|
2913
|
-
const current = await readFile5(path, "utf8").catch(() => "");
|
|
2914
|
-
if (current.split(/\r?\n/).some((line) => line.trim() === SYNC_LEDGER_PATH))
|
|
2915
|
-
return;
|
|
2916
|
-
await mkdir5(info, { recursive: true });
|
|
2917
|
-
const prefix = current === "" || current.endsWith("\n") ? "" : "\n";
|
|
2918
|
-
await writeFile7(path, `${current}${prefix}${SYNC_LEDGER_PATH}
|
|
2919
|
-
`);
|
|
2949
|
+
await excludeFromGit(root, SYNC_LEDGER_PATH);
|
|
2920
2950
|
}
|
|
2921
2951
|
async function currentGeneration(api) {
|
|
2922
2952
|
return await api.draftFiles().then((state) => state.generation ?? null).catch(() => null);
|
|
@@ -2946,13 +2976,13 @@ async function applyDeletes(root, paths) {
|
|
|
2946
2976
|
async function setAside(root, plan) {
|
|
2947
2977
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2948
2978
|
const real = await realpath2(root).catch(() => root);
|
|
2949
|
-
const saved =
|
|
2979
|
+
const saved = join15(dirname2(real), `${basename2(real)}${SAVED_SUFFIX}`, stamp);
|
|
2950
2980
|
const moved = [];
|
|
2951
2981
|
for (const conflict of plan.conflicts) {
|
|
2952
2982
|
const from = await resolveExisting(root, conflict.path);
|
|
2953
2983
|
if (!from)
|
|
2954
2984
|
continue;
|
|
2955
|
-
const to =
|
|
2985
|
+
const to = join15(saved, conflict.path);
|
|
2956
2986
|
await mkdir5(dirname2(to), { recursive: true });
|
|
2957
2987
|
await rename2(from, to);
|
|
2958
2988
|
moved.push(conflict.path);
|
|
@@ -2974,13 +3004,13 @@ ${list}`,
|
|
|
2974
3004
|
|
|
2975
3005
|
// ../core/dist/baseline.js
|
|
2976
3006
|
init_errors();
|
|
2977
|
-
import { readFile as
|
|
2978
|
-
import { join as
|
|
3007
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
3008
|
+
import { join as join16, resolve as resolve7 } from "node:path";
|
|
2979
3009
|
async function rebuildBaseline(options) {
|
|
2980
3010
|
const report = options.onProgress ?? (() => {
|
|
2981
3011
|
});
|
|
2982
3012
|
const root = resolve7(options.folder);
|
|
2983
|
-
const previousText = await
|
|
3013
|
+
const previousText = await readFile7(join16(root, SYNC_LEDGER_PATH), "utf8").catch(() => null);
|
|
2984
3014
|
const previous = previousText === null ? null : parseSyncLedger(previousText);
|
|
2985
3015
|
report("\uD310\uC758 \uD30C\uC77C \uBAA9\uB85D\uC744 \uB2E4\uC2DC \uC77D\uB294 \uC911\uC785\uB2C8\uB2E4\u2026");
|
|
2986
3016
|
const tar = await fetchVerifiedSourceTar({
|
|
@@ -3080,8 +3110,8 @@ function ledgerCorrection(ledger, draft) {
|
|
|
3080
3110
|
// ../core/dist/push.js
|
|
3081
3111
|
init_errors();
|
|
3082
3112
|
init_notice();
|
|
3083
|
-
import { readFile as
|
|
3084
|
-
import { basename as basename3, join as
|
|
3113
|
+
import { readFile as readFile8, stat as stat3 } from "node:fs/promises";
|
|
3114
|
+
import { basename as basename3, join as join17, resolve as resolve8 } from "node:path";
|
|
3085
3115
|
|
|
3086
3116
|
// ../core/dist/pushPlan.js
|
|
3087
3117
|
function effectiveSha(base, draft, path) {
|
|
@@ -3358,13 +3388,13 @@ async function bodyOf(root, edits) {
|
|
|
3358
3388
|
body.push({ path: edit.path, remove: true, ...edit.baseSha256 === null ? {} : { baseSha256: edit.baseSha256 } });
|
|
3359
3389
|
continue;
|
|
3360
3390
|
}
|
|
3361
|
-
const size = (await
|
|
3391
|
+
const size = (await stat3(join17(root, edit.path))).size;
|
|
3362
3392
|
if (size > MAX_PUSH_FILE_BYTES) {
|
|
3363
3393
|
throw new DevtoolsError("PUSH_TOO_LARGE", `\uD30C\uC77C \uD558\uB098\uAC00 \uB108\uBB34 \uD07D\uB2C8\uB2E4: ${edit.path} (${Math.round(size / 1024)}KB \xB7 \uC0C1\uD55C ${MAX_PUSH_FILE_BYTES / 1024}KB).`, "\uB3D9\uC601\uC0C1\xB7\uC6D0\uBCF8 \uC774\uBBF8\uC9C0\xB7\uBE4C\uB4DC \uC0B0\uCD9C\uBB3C\uC774 \uC18C\uC2A4 \uD3F4\uB354\uC5D0 \uB4E4\uC5B4 \uC788\uC9C0 \uC54A\uC740\uC9C0 \uD655\uC778\uD574 \uC8FC\uC138\uC694.");
|
|
3364
3394
|
}
|
|
3365
3395
|
if (total + size > MAX_PUSH_BYTES)
|
|
3366
3396
|
throw tooLarge();
|
|
3367
|
-
const raw = await
|
|
3397
|
+
const raw = await readFile8(join17(root, edit.path));
|
|
3368
3398
|
const breach = templateBreach(basename3(edit.path), raw);
|
|
3369
3399
|
if (breach !== null) {
|
|
3370
3400
|
throw new DevtoolsError("PUSH_SECRET_TEMPLATE", `${edit.path} \uC5D0 \uC2E4\uC81C \uAC12\uC774 \uB4E4\uC5B4 \uC788\uC5B4 \uC62C\uB9AC\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(${breach}).`, "`.env.example` \uAC19\uC740 \uC11C\uC2DD \uD30C\uC77C\uC740 \uAC12\uC744 \uBE44\uC6CC \uB450\uC5B4\uC57C \uC62C\uB77C\uAC11\uB2C8\uB2E4. \uC2E4\uC81C \uAC12\uC740 \uCF58\uC194\uC758 \uD658\uACBD\uBCC0\uC218 \uD654\uBA74\uC5D0\uC11C \uAD00\uB9AC\uD574 \uC8FC\uC138\uC694.");
|
|
@@ -3631,12 +3661,12 @@ function flagValue(flags, name) {
|
|
|
3631
3661
|
|
|
3632
3662
|
// src/context.ts
|
|
3633
3663
|
import { readFileSync } from "node:fs";
|
|
3634
|
-
import { readFile as
|
|
3664
|
+
import { readFile as readFile10 } from "node:fs/promises";
|
|
3635
3665
|
import { fileURLToPath } from "node:url";
|
|
3636
|
-
import { join as
|
|
3666
|
+
import { join as join19, resolve as resolve11 } from "node:path";
|
|
3637
3667
|
|
|
3638
3668
|
// src/tokenStore.ts
|
|
3639
|
-
import { chmod as
|
|
3669
|
+
import { chmod as chmod4, readFile as readFile9, rm as rm6 } from "node:fs/promises";
|
|
3640
3670
|
import { basename as basename4, dirname as dirname3 } from "node:path";
|
|
3641
3671
|
var FileTokenStore = class {
|
|
3642
3672
|
// ⚠ 매개변수 프로퍼티(`constructor(private path)`)를 안 쓴다 — Node 의 타입 제거 실행기가
|
|
@@ -3646,7 +3676,7 @@ var FileTokenStore = class {
|
|
|
3646
3676
|
this.path = path;
|
|
3647
3677
|
}
|
|
3648
3678
|
async read() {
|
|
3649
|
-
const text = await
|
|
3679
|
+
const text = await readFile9(this.path, "utf8").catch(() => null);
|
|
3650
3680
|
if (text === null) return null;
|
|
3651
3681
|
try {
|
|
3652
3682
|
const raw = JSON.parse(text);
|
|
@@ -3667,10 +3697,10 @@ var FileTokenStore = class {
|
|
|
3667
3697
|
}
|
|
3668
3698
|
async write(tokens) {
|
|
3669
3699
|
const dir = await ensureOwnDir(dirname3(dirname3(this.path)), basename4(dirname3(this.path)));
|
|
3670
|
-
await
|
|
3700
|
+
await chmod4(dir, 448).catch(() => {
|
|
3671
3701
|
});
|
|
3672
3702
|
await writeOwnFile(this.path, JSON.stringify(tokens), 384);
|
|
3673
|
-
await
|
|
3703
|
+
await chmod4(this.path, 384);
|
|
3674
3704
|
}
|
|
3675
3705
|
async clear() {
|
|
3676
3706
|
await rm6(this.path, { force: true });
|
|
@@ -3693,9 +3723,9 @@ function serverUrlOf(env = process.env) {
|
|
|
3693
3723
|
}
|
|
3694
3724
|
async function tenantOf(folder, explicit) {
|
|
3695
3725
|
if (explicit) return TENANT_CODE.test(explicit) ? explicit : null;
|
|
3696
|
-
const mark = parseSourceMark(await
|
|
3726
|
+
const mark = parseSourceMark(await readFile10(join19(folder, SOURCE_MARK_PATH), "utf8").catch(() => null));
|
|
3697
3727
|
if (mark) return mark.tenant;
|
|
3698
|
-
const text = await
|
|
3728
|
+
const text = await readFile10(join19(folder, SYNC_LEDGER_PATH), "utf8").catch(() => null);
|
|
3699
3729
|
return text === null ? null : parseSyncLedger(text)?.tenant ?? null;
|
|
3700
3730
|
}
|
|
3701
3731
|
async function openAuth(options = {}) {
|
|
@@ -3847,6 +3877,21 @@ var BLOCKER_TEXT = {
|
|
|
3847
3877
|
// 「모르는 명령입니다」로 끝난다. `discard` 는 T3 에서 실제로 생겼다.
|
|
3848
3878
|
STRANDED: "\uC0AC\uC774\uD2B8 \uCABD\uC5D0\uC11C \uD3B8\uC9D1 \uC911\uC774\uB358 \uAC83\uC774 \uC9C0\uAE08 \uBC84\uC804 \uC704\uAC00 \uC544\uB2D9\uB2C8\uB2E4. \uADF8\uB300\uB85C\uB294 \uCF24 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.\n`zalkera discard` \uB85C \uADF8 \uD3B8\uC9D1\uC744 \uBC84\uB9B4 \uC218 \uC788\uC2B5\uB2C8\uB2E4 \u2014 \uBC84\uB9AC\uAE30 \uC804\uC5D0 \uBB34\uC5C7\uC774 \uAC78\uB824 \uC788\uB294\uC9C0 \uBCF4\uC5EC \uC90D\uB2C8\uB2E4."
|
|
3849
3879
|
};
|
|
3880
|
+
function describePublish(result) {
|
|
3881
|
+
const lines = [
|
|
3882
|
+
`\uBC84\uC804 ${countJosa(result.revisionNo, "\uC73C\uB85C/\uB85C")} \uC62C\uB838\uC2B5\uB2C8\uB2E4.`,
|
|
3883
|
+
result.servingPaused === true ? "\uC11C\uBE59\uC774 \uC911\uB2E8\uB3FC \uC788\uC5B4 \uC190\uB2D8 \uD654\uBA74\uC740 \uADF8\uB300\uB85C\uC785\uB2C8\uB2E4." : result.siteType === "STATIC" ? "\uC9C0\uAE08 \uBC14\uB85C \uC190\uB2D8\uC5D0\uAC8C \uBCF4\uC785\uB2C8\uB2E4." : "\uC0AC\uC774\uD2B8\uB97C \uB2E4\uC2DC \uC9D3\uB294 \uC911\uC785\uB2C8\uB2E4 \u2014 \uB2E4 \uC9C0\uC5B4\uC9C0\uBA74 \uC790\uB3D9\uC73C\uB85C \uC190\uB2D8\uC5D0\uAC8C \uBCF4\uC785\uB2C8\uB2E4."
|
|
3884
|
+
];
|
|
3885
|
+
if (result.capabilityNote) lines.push(plainNotice(result.capabilityNote, 300));
|
|
3886
|
+
if (!result.ledgerRebuilt) {
|
|
3887
|
+
lines.push(
|
|
3888
|
+
"",
|
|
3889
|
+
"\uB2E4\uB9CC \uC0C8 \uBC84\uC804\uC758 \uD30C\uC77C \uBAA9\uB85D\uC744 \uC77D\uC9C0 \uBABB\uD574 \uC774 \uD3F4\uB354\uC758 \uAE30\uC900 \uAE30\uB85D\uC744 \uC9C0\uC6E0\uC2B5\uB2C8\uB2E4.",
|
|
3890
|
+
"`zalkera baseline` \uC744 \uD55C \uBC88 \uC2E4\uD589\uD574 \uC8FC\uC138\uC694 \u2014 \uD3F4\uB354\uC758 \uD30C\uC77C\uC740 \uAC74\uB4DC\uB9AC\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
|
3891
|
+
);
|
|
3892
|
+
}
|
|
3893
|
+
return lines;
|
|
3894
|
+
}
|
|
3850
3895
|
function describePush(result, verbose = false) {
|
|
3851
3896
|
const lines = [];
|
|
3852
3897
|
if (result.reconciled === "applied") {
|
|
@@ -4044,19 +4089,7 @@ async function main(argv) {
|
|
|
4044
4089
|
onProgress: (message) => process.stderr.write(`${message}
|
|
4045
4090
|
`)
|
|
4046
4091
|
});
|
|
4047
|
-
|
|
4048
|
-
`\uBC84\uC804 ${countJosa(result.revisionNo, "\uC73C\uB85C/\uB85C")} \uC62C\uB838\uC2B5\uB2C8\uB2E4.`,
|
|
4049
|
-
result.siteType === "STATIC" ? "\uC9C0\uAE08 \uBC14\uB85C \uC190\uB2D8\uC5D0\uAC8C \uBCF4\uC785\uB2C8\uB2E4." : "\uC0AC\uC774\uD2B8\uB97C \uB2E4\uC2DC \uC9D3\uB294 \uC911\uC785\uB2C8\uB2E4 \u2014 \uB2E4 \uC9C0\uC5B4\uC9C0\uBA74 \uC790\uB3D9\uC73C\uB85C \uC190\uB2D8\uC5D0\uAC8C \uBCF4\uC785\uB2C8\uB2E4."
|
|
4050
|
-
];
|
|
4051
|
-
if (result.capabilityNote) lines.push(result.capabilityNote);
|
|
4052
|
-
if (!result.ledgerRebuilt) {
|
|
4053
|
-
lines.push(
|
|
4054
|
-
"",
|
|
4055
|
-
"\uB2E4\uB9CC \uC0C8 \uBC84\uC804\uC758 \uD30C\uC77C \uBAA9\uB85D\uC744 \uC77D\uC9C0 \uBABB\uD574 \uC774 \uD3F4\uB354\uC758 \uAE30\uC900 \uAE30\uB85D\uC744 \uC9C0\uC6E0\uC2B5\uB2C8\uB2E4.",
|
|
4056
|
-
"`zalkera baseline` \uC744 \uD55C \uBC88 \uC2E4\uD589\uD574 \uC8FC\uC138\uC694 \u2014 \uD3F4\uB354\uC758 \uD30C\uC77C\uC740 \uAC74\uB4DC\uB9AC\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
|
4057
|
-
);
|
|
4058
|
-
}
|
|
4059
|
-
process.stdout.write(`${lines.join("\n")}
|
|
4092
|
+
process.stdout.write(`${describePublish(result).join("\n")}
|
|
4060
4093
|
`);
|
|
4061
4094
|
return 0;
|
|
4062
4095
|
}
|