@mondaydotcomorg/z2h-cli 0.7.2 → 0.9.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/dist/commands/build.d.ts +1 -1
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +4 -3
- package/dist/commands/clean.d.ts +1 -1
- package/dist/commands/clean.d.ts.map +1 -1
- package/dist/commands/clean.js +5 -4
- package/dist/commands/create-workspace.d.ts +1 -1
- package/dist/commands/create-workspace.d.ts.map +1 -1
- package/dist/commands/create-workspace.js +14 -14
- package/dist/commands/create.d.ts +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +27 -13
- package/dist/commands/deploy.d.ts +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +32 -11
- package/dist/commands/dev.d.ts +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +10 -6
- package/dist/commands/migrate.d.ts +1 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +1 -1
- package/dist/esm/commands/build.d.ts +1 -1
- package/dist/esm/commands/build.d.ts.map +1 -1
- package/dist/esm/commands/build.mjs +2 -1
- package/dist/esm/commands/clean.d.ts +1 -1
- package/dist/esm/commands/clean.d.ts.map +1 -1
- package/dist/esm/commands/clean.mjs +2 -1
- package/dist/esm/commands/create-workspace.d.ts +1 -1
- package/dist/esm/commands/create-workspace.d.ts.map +1 -1
- package/dist/esm/commands/create-workspace.mjs +1 -1
- package/dist/esm/commands/create.d.ts +1 -1
- package/dist/esm/commands/create.d.ts.map +1 -1
- package/dist/esm/commands/create.mjs +16 -2
- package/dist/esm/commands/deploy.d.ts +1 -1
- package/dist/esm/commands/deploy.d.ts.map +1 -1
- package/dist/esm/commands/deploy.mjs +29 -8
- package/dist/esm/commands/dev.d.ts +1 -1
- package/dist/esm/commands/dev.d.ts.map +1 -1
- package/dist/esm/commands/dev.mjs +5 -1
- package/dist/esm/commands/migrate.d.ts +1 -1
- package/dist/esm/commands/migrate.d.ts.map +1 -1
- package/dist/esm/commands/migrate.mjs +1 -1
- package/dist/esm/index.mjs +4 -1
- package/dist/esm/migrations/auto-migrate.mjs +1 -1
- package/dist/esm/templates/app/claude-settings.mjs +1 -1
- package/dist/esm/util/git/__tests__/repo.test.d.ts +2 -0
- package/dist/esm/util/git/__tests__/repo.test.d.ts.map +1 -0
- package/dist/esm/util/git/repo.d.ts +12 -0
- package/dist/esm/util/git/repo.d.ts.map +1 -0
- package/dist/esm/util/git/repo.mjs +105 -0
- package/dist/esm/util/manifest.d.ts +1 -0
- package/dist/esm/util/manifest.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/migrations/auto-migrate.js +11 -11
- package/dist/shadow/consumer-pkg.js +2 -2
- package/dist/shadow/gitignore.js +4 -4
- package/dist/shadow/merge-package-json.js +2 -2
- package/dist/shadow/metadata.js +4 -4
- package/dist/shadow/prepare.js +5 -5
- package/dist/shadow/scaffold.js +8 -8
- package/dist/shadow/sync.js +3 -3
- package/dist/templates/app/claude-settings.js +1 -1
- package/dist/util/auth/auth-store.js +4 -4
- package/dist/util/auth/write-auth.js +3 -3
- package/dist/util/git/__tests__/repo.test.d.ts +2 -0
- package/dist/util/git/__tests__/repo.test.d.ts.map +1 -0
- package/dist/util/git/repo.d.ts +12 -0
- package/dist/util/git/repo.d.ts.map +1 -0
- package/dist/util/git/repo.js +120 -0
- package/dist/util/manifest.d.ts +1 -0
- package/dist/util/manifest.d.ts.map +1 -1
- package/dist/util/s3/upload.js +2 -2
- package/dist/util/workspace.js +3 -3
- package/package.json +1 -1
- package/src/commands/__tests__/create-workspace.test.ts +4 -4
- package/src/commands/__tests__/create.test.ts +12 -5
- package/src/commands/build.ts +2 -1
- package/src/commands/clean.ts +2 -1
- package/src/commands/create-workspace.ts +1 -1
- package/src/commands/create.ts +15 -2
- package/src/commands/deploy.ts +28 -8
- package/src/commands/dev.ts +5 -1
- package/src/commands/migrate.ts +1 -1
- package/src/index.ts +4 -1
- package/src/migrations/auto-migrate.ts +3 -3
- package/src/templates/app/CLAUDE.md +3 -1
- package/src/templates/app/claude-settings.json +1 -1
- package/src/util/git/__tests__/repo.test.ts +208 -0
- package/src/util/git/repo.ts +112 -0
- package/src/util/manifest.ts +1 -0
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import { readJson, pathExists } from 'fs-extra';
|
|
4
|
-
import { setOutputMode, info, output } from '../util/logger.mjs';
|
|
4
|
+
import { setOutputMode, info, output, warn } from '../util/logger.mjs';
|
|
5
5
|
import { resolveConsumerPaths } from '../shadow/paths.mjs';
|
|
6
6
|
import { readManifest, nextVersion, writeManifest, upsertEntry } from '../util/manifest.mjs';
|
|
7
7
|
import { uploadDir } from '../util/s3/upload.mjs';
|
|
8
|
-
import { BUCKET_WRITE_NAME, BUCKET_READ_DNS_URL } from '../constants.mjs';
|
|
8
|
+
import { BUCKET_WRITE_NAME, brokerBaseUrl, BUCKET_READ_DNS_URL } from '../constants.mjs';
|
|
9
9
|
import { setupS3Client } from '../util/s3/client.mjs';
|
|
10
10
|
import { readZthAuth } from '../util/auth/auth-store.mjs';
|
|
11
11
|
import { mfAppName, cleanAppName } from '../util/app-name.mjs';
|
|
12
12
|
import { buildCommand } from './build.mjs';
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
// Should be run from the consumer app directory — uses process.cwd() to locate it.
|
|
15
|
+
async function deployCommand(opts = {}) {
|
|
15
16
|
if (opts.json) {
|
|
16
17
|
setOutputMode('json');
|
|
17
18
|
}
|
|
@@ -23,7 +24,7 @@ async function deployCommand(opts) {
|
|
|
23
24
|
const appName = mfAppName(consumerPkg.name);
|
|
24
25
|
// Validate the user's deploy token is on disk before doing any expensive
|
|
25
26
|
// work. Throws Z2hAuthMissingError with a remediation hint if not.
|
|
26
|
-
await readZthAuth();
|
|
27
|
+
const { token } = await readZthAuth();
|
|
27
28
|
setupS3Client({ appName });
|
|
28
29
|
info('reading current Z2H manifest');
|
|
29
30
|
const manifest = await readManifest();
|
|
@@ -61,10 +62,16 @@ async function deployCommand(opts) {
|
|
|
61
62
|
});
|
|
62
63
|
return;
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
try {
|
|
66
|
+
// Lock is acquired here — uploadDir triggers the STS credential provider on first S3 call
|
|
67
|
+
info(`uploading build → s3://${BUCKET_WRITE_NAME}/${keyPrefix}/`);
|
|
68
|
+
await uploadDir(paths.shadowBuild, keyPrefix);
|
|
69
|
+
info(`updating manifest entry "${appName}" → v${version}`);
|
|
70
|
+
await writeManifest(upsertEntry(manifest, appName, entry));
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
await releaseLockBestEffort(appName, token);
|
|
74
|
+
}
|
|
68
75
|
// The host MF parses the app name from the URL and prepends `mf-` itself
|
|
69
76
|
// before looking it up in the manifest. So the user-facing URL must use
|
|
70
77
|
// the consumer's de-scoped package name (no `mf-` prefix, no `@scope/`).
|
|
@@ -80,5 +87,19 @@ async function deployCommand(opts) {
|
|
|
80
87
|
entry,
|
|
81
88
|
});
|
|
82
89
|
}
|
|
90
|
+
// best-effort — the 5-min TTL backstop handles failures
|
|
91
|
+
async function releaseLockBestEffort(appName, token) {
|
|
92
|
+
try {
|
|
93
|
+
await fetch(`${brokerBaseUrl()}/z2h-cli/lock/release`, {
|
|
94
|
+
method: 'POST',
|
|
95
|
+
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
96
|
+
body: JSON.stringify({ appName }),
|
|
97
|
+
});
|
|
98
|
+
info(`lock released for ${appName}`);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
warn(`failed to release lock for ${appName}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
83
104
|
|
|
84
105
|
export { deployCommand };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/commands/dev.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/commands/dev.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAKD,wBAAsB,UAAU,CAAC,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA0ErE"}
|
|
@@ -9,7 +9,8 @@ import { ensureConsumerPkg } from '../shadow/consumer-pkg.mjs';
|
|
|
9
9
|
import { syncShadow } from '../shadow/sync.mjs';
|
|
10
10
|
|
|
11
11
|
const TRIDENT_READY_PATTERN = /Server started at/i;
|
|
12
|
-
|
|
12
|
+
// Should be run from the consumer app directory — uses process.cwd() to locate it.
|
|
13
|
+
async function devCommand(opts = {}) {
|
|
13
14
|
if (opts.json) {
|
|
14
15
|
setOutputMode('json');
|
|
15
16
|
}
|
|
@@ -23,6 +24,9 @@ async function devCommand(opts) {
|
|
|
23
24
|
const server = execa('yarn', ['start'], {
|
|
24
25
|
cwd: ctx.paths.shadowDir,
|
|
25
26
|
stdio: ['inherit', 'pipe', 'inherit'],
|
|
27
|
+
// Trident requires NPM_TOKEN to be set or it refuses to start; 'FAKE_TOKEN' satisfies the check without real credentials.
|
|
28
|
+
// we always pass a fake token for same behavior for all users (no matter if they have a token or not)
|
|
29
|
+
env: { ...process.env, NPM_TOKEN: 'FAKE_TOKEN' },
|
|
26
30
|
});
|
|
27
31
|
const pidFile = path.join(ctx.paths.shadowDir, 'dev.pid');
|
|
28
32
|
if (server.pid) {
|
|
@@ -2,5 +2,5 @@ export interface MigrateOptions {
|
|
|
2
2
|
dryRun?: boolean;
|
|
3
3
|
json?: boolean;
|
|
4
4
|
}
|
|
5
|
-
export declare function migrateCommand(cliVersion: string, opts
|
|
5
|
+
export declare function migrateCommand(cliVersion: string, opts?: MigrateOptions): Promise<void>;
|
|
6
6
|
//# sourceMappingURL=migrate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMjG"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { setOutputMode } from '../util/logger.mjs';
|
|
2
2
|
import { autoMigrate } from '../migrations/auto-migrate.mjs';
|
|
3
3
|
|
|
4
|
-
async function migrateCommand(cliVersion, opts) {
|
|
4
|
+
async function migrateCommand(cliVersion, opts = {}) {
|
|
5
5
|
if (opts.json) {
|
|
6
6
|
setOutputMode('json');
|
|
7
7
|
}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -19,7 +19,10 @@ const { version } = createRequire(import.meta.url)('../package.json');
|
|
|
19
19
|
const UPDATE_SCRIPT = path.join(os.homedir(), 'Development', 'bigbrain-z2h', 'z2h', 'setup', 'update.sh');
|
|
20
20
|
function selfUpdate() {
|
|
21
21
|
try {
|
|
22
|
-
execa('bash', [UPDATE_SCRIPT], {
|
|
22
|
+
execa('bash', [UPDATE_SCRIPT], {
|
|
23
|
+
detached: true,
|
|
24
|
+
stdio: 'ignore',
|
|
25
|
+
}).unref();
|
|
23
26
|
}
|
|
24
27
|
catch (err) {
|
|
25
28
|
errorLog(`Z2H auto-update failed to start: ${err.message}`);
|
|
@@ -9,7 +9,7 @@ var hooks = {
|
|
|
9
9
|
hooks: [
|
|
10
10
|
{
|
|
11
11
|
type: "command",
|
|
12
|
-
command: "if [ -f .zth/dev.pid ]; then
|
|
12
|
+
command: "if [ -f .zth/dev.pid ]; then PGID=$(ps -o pgid= -p $(cat .zth/dev.pid) 2>/dev/null | tr -d ' '); [ -n \"$PGID\" ] && kill -- -$PGID 2>/dev/null; rm -f .zth/dev.pid; fi"
|
|
13
13
|
}
|
|
14
14
|
]
|
|
15
15
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo.test.d.ts","sourceRoot":"","sources":["../../../../../src/util/git/__tests__/repo.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class GitConflictError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
export declare function defaultS3Remote(app: string): string;
|
|
5
|
+
export declare function initAndPush(dir: string, remote: string): Promise<void>;
|
|
6
|
+
export declare function cloneRepo(remote: string, dir: string): Promise<void>;
|
|
7
|
+
export declare function safeBackupIfDirty(dir: string): Promise<void>;
|
|
8
|
+
export declare function pullAndResolve(dir: string): Promise<void>;
|
|
9
|
+
export declare function remoteHead(dir: string): Promise<string>;
|
|
10
|
+
export declare function localHead(dir: string): Promise<string>;
|
|
11
|
+
export declare function commitDetailedAndPush(dir: string, version: number): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=repo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../../../src/util/git/repo.ts"],"names":[],"mappings":"AAKA,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAID,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO5E;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAclE;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS/D;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7D;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG5D;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASvF"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
|
+
import { BUCKET_WRITE_NAME } from '../../constants.mjs';
|
|
5
|
+
|
|
6
|
+
class GitConflictError extends Error {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = 'GitConflictError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const REQUIRED_GITIGNORE_ENTRIES = ['node_modules/', '.zth/', 'build/'];
|
|
13
|
+
function defaultS3Remote(app) {
|
|
14
|
+
return `s3://${BUCKET_WRITE_NAME}/${app}/git`;
|
|
15
|
+
}
|
|
16
|
+
async function initAndPush(dir, remote) {
|
|
17
|
+
await ensureGitignore(dir);
|
|
18
|
+
await execa('git', ['init', '-b', 'master'], { cwd: dir });
|
|
19
|
+
await execa('git', ['add', '.'], { cwd: dir });
|
|
20
|
+
await execa('git', ['commit', '-m', 'Initial commit'], { cwd: dir });
|
|
21
|
+
await execa('git', ['remote', 'add', 'origin', remote], { cwd: dir });
|
|
22
|
+
await execa('git', ['push', '-u', 'origin', 'master'], { cwd: dir });
|
|
23
|
+
}
|
|
24
|
+
async function cloneRepo(remote, dir) {
|
|
25
|
+
await execa('git', ['clone', remote, dir]);
|
|
26
|
+
}
|
|
27
|
+
async function safeBackupIfDirty(dir) {
|
|
28
|
+
let status;
|
|
29
|
+
try {
|
|
30
|
+
({ stdout: status } = await execa('git', ['status', '--porcelain'], { cwd: dir }));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (!status.trim()) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const sha = await localHead(dir).catch(() => 'unknown');
|
|
39
|
+
const appName = path.basename(dir);
|
|
40
|
+
const backupDir = path.join(path.dirname(dir), `${appName}.backup-${sha}`);
|
|
41
|
+
await fs.copy(dir, backupDir, { overwrite: false });
|
|
42
|
+
}
|
|
43
|
+
async function pullAndResolve(dir) {
|
|
44
|
+
try {
|
|
45
|
+
await execa('git', ['pull', '--ff-only'], { cwd: dir });
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// TODO(Phase 7): safeBackupIfDirty(dir) → resolveDivergence(dir) instead of throwing
|
|
49
|
+
throw new GitConflictError('This app changed while you were working — please re-open it to get the latest version.');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function remoteHead(dir) {
|
|
53
|
+
const { stdout } = await execa('git', ['ls-remote', 'origin', 'refs/heads/master'], { cwd: dir });
|
|
54
|
+
const sha = stdout.split('\t')[0]?.trim();
|
|
55
|
+
if (!sha) {
|
|
56
|
+
throw new Error('could not read remote head — is the remote reachable?');
|
|
57
|
+
}
|
|
58
|
+
return sha;
|
|
59
|
+
}
|
|
60
|
+
async function localHead(dir) {
|
|
61
|
+
const { stdout } = await execa('git', ['rev-parse', 'HEAD'], { cwd: dir });
|
|
62
|
+
return stdout.trim();
|
|
63
|
+
}
|
|
64
|
+
async function commitDetailedAndPush(dir, version) {
|
|
65
|
+
const message = await buildCommitMessage(dir, version);
|
|
66
|
+
await execa('git', ['add', '.'], { cwd: dir });
|
|
67
|
+
await execa('git', ['commit', '-m', message], { cwd: dir });
|
|
68
|
+
try {
|
|
69
|
+
await execa('git', ['push'], { cwd: dir });
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
throw new GitConflictError('push rejected — remote has new commits');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function buildCommitMessage(dir, version) {
|
|
76
|
+
// TODO(Phase 7): replace with LLM-generated summary using git diff + commit messages
|
|
77
|
+
const { stdout } = await execa('git', ['status', '--short'], { cwd: dir });
|
|
78
|
+
const files = stdout
|
|
79
|
+
.split('\n')
|
|
80
|
+
.map(line => line.slice(3).trim())
|
|
81
|
+
.filter(Boolean);
|
|
82
|
+
const fileList = files.length
|
|
83
|
+
? files.slice(0, 5).join(', ') + (files.length > 5 ? ` (+${files.length - 5} more)` : '')
|
|
84
|
+
: 'no changes';
|
|
85
|
+
return `v${version}: deploy — ${fileList}`;
|
|
86
|
+
}
|
|
87
|
+
async function ensureGitignore(dir) {
|
|
88
|
+
const gitignorePath = path.join(dir, '.gitignore');
|
|
89
|
+
let content = '';
|
|
90
|
+
try {
|
|
91
|
+
content = await fs.readFile(gitignorePath, 'utf8');
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// file doesn't exist yet
|
|
95
|
+
}
|
|
96
|
+
const lines = content.split('\n').map(l => l.trim());
|
|
97
|
+
const missing = REQUIRED_GITIGNORE_ENTRIES.filter(entry => !lines.includes(entry));
|
|
98
|
+
if (missing.length === 0) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const separator = content && !content.endsWith('\n') ? '\n' : '';
|
|
102
|
+
await fs.outputFile(gitignorePath, content + separator + missing.join('\n') + '\n');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export { GitConflictError, cloneRepo, commitDetailedAndPush, defaultS3Remote, initAndPush, localHead, pullAndResolve, remoteHead, safeBackupIfDirty };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/util/manifest.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAClC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/util/manifest.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAClC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAErD,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,CAQtD;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,UAI1D;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,QAAQ,CAE3F;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAWrE"}
|
package/dist/index.js
CHANGED
|
@@ -25,7 +25,10 @@ const { version } = node_module.createRequire((typeof document === 'undefined' ?
|
|
|
25
25
|
const UPDATE_SCRIPT = path__default.default.join(os__default.default.homedir(), 'Development', 'bigbrain-z2h', 'z2h', 'setup', 'update.sh');
|
|
26
26
|
function selfUpdate() {
|
|
27
27
|
try {
|
|
28
|
-
execa.execa('bash', [UPDATE_SCRIPT], {
|
|
28
|
+
execa.execa('bash', [UPDATE_SCRIPT], {
|
|
29
|
+
detached: true,
|
|
30
|
+
stdio: 'ignore',
|
|
31
|
+
}).unref();
|
|
29
32
|
}
|
|
30
33
|
catch (err) {
|
|
31
34
|
util_logger.errorLog(`Z2H auto-update failed to start: ${err.message}`);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
|
-
const path = require('node:path');
|
|
4
3
|
const node_module = require('node:module');
|
|
4
|
+
const path = require('node:path');
|
|
5
5
|
const node_url = require('node:url');
|
|
6
|
-
const
|
|
6
|
+
const fs = require('fs-extra');
|
|
7
7
|
const execa = require('execa');
|
|
8
8
|
const semver = require('semver');
|
|
9
9
|
const util_logger = require('../util/logger.js');
|
|
@@ -20,11 +20,11 @@ const NX_JSON_CONTENT = '{\n "extends": "@mondaydotcomorg/trident-monorepo/pres
|
|
|
20
20
|
// ─── Helpers ───
|
|
21
21
|
async function readState(workspaceHome) {
|
|
22
22
|
const statePath = path__default.default.join(workspaceHome, STATE_FILE);
|
|
23
|
-
if (!(await
|
|
23
|
+
if (!(await fs.pathExists(statePath))) {
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
26
|
try {
|
|
27
|
-
return (await
|
|
27
|
+
return (await fs.readJson(statePath));
|
|
28
28
|
}
|
|
29
29
|
catch {
|
|
30
30
|
return null;
|
|
@@ -32,7 +32,7 @@ async function readState(workspaceHome) {
|
|
|
32
32
|
}
|
|
33
33
|
async function writeState(workspaceHome, state) {
|
|
34
34
|
const statePath = path__default.default.join(workspaceHome, STATE_FILE);
|
|
35
|
-
await
|
|
35
|
+
await fs.writeJson(statePath, state, { spaces: 2 });
|
|
36
36
|
}
|
|
37
37
|
async function yarnInstall(workspaceHome, context) {
|
|
38
38
|
util_logger.info(`${context} — running yarn install...`);
|
|
@@ -69,11 +69,11 @@ function isNxAvailable(workspaceHome) {
|
|
|
69
69
|
async function ensureWorkspaceNx(workspaceHome) {
|
|
70
70
|
const nxJsonPath = path__default.default.join(workspaceHome, 'nx.json');
|
|
71
71
|
const pkgPath = path__default.default.join(workspaceHome, 'package.json');
|
|
72
|
-
if (!(await
|
|
73
|
-
await
|
|
72
|
+
if (!(await fs.pathExists(nxJsonPath))) {
|
|
73
|
+
await fs.writeFile(nxJsonPath, NX_JSON_CONTENT);
|
|
74
74
|
util_logger.info('added nx.json to workspace');
|
|
75
75
|
}
|
|
76
|
-
const pkg = (await
|
|
76
|
+
const pkg = (await fs.readJson(pkgPath));
|
|
77
77
|
if (!pkg.devDependencies?.['@mondaydotcomorg/trident-monorepo']) {
|
|
78
78
|
pkg.devDependencies = pkg.devDependencies ?? {};
|
|
79
79
|
pkg.devDependencies['@mondaydotcomorg/trident-monorepo'] = await getLatestTrientMonorepoVersion();
|
|
@@ -82,7 +82,7 @@ async function ensureWorkspaceNx(workspaceHome) {
|
|
|
82
82
|
pkg.scripts = pkg.scripts ?? {};
|
|
83
83
|
pkg.scripts.nx = 'nx';
|
|
84
84
|
}
|
|
85
|
-
await
|
|
85
|
+
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
86
86
|
// Only install if NX isn't already importable from the workspace
|
|
87
87
|
if (!isNxAvailable(workspaceHome)) {
|
|
88
88
|
const ok = await yarnInstall(workspaceHome, 'NX not found, installing');
|
|
@@ -110,11 +110,11 @@ async function autoMigrate(cliVersion, dryRun = false) {
|
|
|
110
110
|
// migrations.json is at the package root — two dirs up from dist/migrations/
|
|
111
111
|
const thisDir = path__default.default.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('migrations/auto-migrate.js', document.baseURI).href))));
|
|
112
112
|
const migrationsJsonPath = path__default.default.resolve(thisDir, '..', '..', 'migrations.json');
|
|
113
|
-
if (!(await
|
|
113
|
+
if (!(await fs.pathExists(migrationsJsonPath))) {
|
|
114
114
|
util_logger.warn('migrations.json not found — skipping migrations');
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
|
-
const migrationsJson = (await
|
|
117
|
+
const migrationsJson = (await fs.readJson(migrationsJsonPath));
|
|
118
118
|
// Filter to pending migrations (version > lastVersion AND <= cliVersion).
|
|
119
119
|
// CONVENTION: a migration's `version` field must equal the CLI release it
|
|
120
120
|
// ships with (not the feature branch version). This ensures the `gt` check
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* The consumer pkg is a thin manifest. Z2H apps live inside a yarn
|
|
@@ -15,7 +15,7 @@ async function ensureConsumerPkg(pkgPath, pkg) {
|
|
|
15
15
|
return { changed: false, pkg };
|
|
16
16
|
}
|
|
17
17
|
const next = { ...pkg, private: true };
|
|
18
|
-
await
|
|
18
|
+
await fs.writeJson(pkgPath, next, { spaces: 2 });
|
|
19
19
|
return { changed: true, pkg: next };
|
|
20
20
|
}
|
|
21
21
|
|
package/dist/shadow/gitignore.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
3
|
const path = require('node:path');
|
|
4
|
-
const
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
5
|
const constants = require('../constants.js');
|
|
6
6
|
|
|
7
7
|
const _interopDefault = e => e && e.__esModule ? e : { default: e };
|
|
@@ -16,8 +16,8 @@ const path__default = /*#__PURE__*/_interopDefault(path);
|
|
|
16
16
|
async function ensureGitignore(consumerDir) {
|
|
17
17
|
const gitignorePath = path__default.default.join(consumerDir, '.gitignore');
|
|
18
18
|
let body = '';
|
|
19
|
-
if (await
|
|
20
|
-
body = await
|
|
19
|
+
if (await fs.pathExists(gitignorePath)) {
|
|
20
|
+
body = await fs.readFile(gitignorePath, 'utf8');
|
|
21
21
|
}
|
|
22
22
|
const existing = new Set(body
|
|
23
23
|
.split('\n')
|
|
@@ -29,7 +29,7 @@ async function ensureGitignore(consumerDir) {
|
|
|
29
29
|
}
|
|
30
30
|
const prefix = body.length && !body.endsWith('\n') ? '\n' : '';
|
|
31
31
|
const block = `${prefix}\n# z2h-cli\n${missing.join('\n')}\n`;
|
|
32
|
-
await
|
|
32
|
+
await fs.writeFile(gitignorePath, body + block);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
exports.ensureGitignore = ensureGitignore;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
3
|
const crypto = require('node:crypto');
|
|
4
|
-
const
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
5
|
const constants = require('../constants.js');
|
|
6
6
|
const util_appName = require('../util/app-name.js');
|
|
7
7
|
|
|
@@ -59,7 +59,7 @@ function hashConsumerDeps(consumer) {
|
|
|
59
59
|
.digest('hex');
|
|
60
60
|
}
|
|
61
61
|
async function writeShadowPkg(shadowPkgPath, shadow) {
|
|
62
|
-
await
|
|
62
|
+
await fs.writeJson(shadowPkgPath, shadow, { spaces: 2 });
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
exports.buildShadowPkg = buildShadowPkg;
|
package/dist/shadow/metadata.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
4
|
|
|
5
5
|
async function readMetadata(paths) {
|
|
6
|
-
if (!(await
|
|
6
|
+
if (!(await fs.pathExists(paths.shadowMetadata))) {
|
|
7
7
|
return null;
|
|
8
8
|
}
|
|
9
9
|
try {
|
|
10
|
-
return (await
|
|
10
|
+
return (await fs.readJson(paths.shadowMetadata));
|
|
11
11
|
}
|
|
12
12
|
catch {
|
|
13
13
|
return null;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
async function writeMetadata(paths, meta) {
|
|
17
|
-
await
|
|
17
|
+
await fs.writeJson(paths.shadowMetadata, meta, { spaces: 2 });
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
exports.readMetadata = readMetadata;
|
package/dist/shadow/prepare.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
4
|
const util_logger = require('../util/logger.js');
|
|
5
5
|
const util_appName = require('../util/app-name.js');
|
|
6
6
|
const shadow_paths = require('./paths.js');
|
|
@@ -13,13 +13,13 @@ const shadow_sync = require('./sync.js');
|
|
|
13
13
|
|
|
14
14
|
async function prepareShadow() {
|
|
15
15
|
const paths = shadow_paths.resolveConsumerPaths(process.cwd());
|
|
16
|
-
if (!(await
|
|
16
|
+
if (!(await fs.pathExists(paths.consumerPkg))) {
|
|
17
17
|
throw new Error(`No package.json found in ${paths.consumerDir}`);
|
|
18
18
|
}
|
|
19
|
-
if (!(await
|
|
19
|
+
if (!(await fs.pathExists(paths.consumerSrcEntry))) {
|
|
20
20
|
throw new Error(`Consumer must have src/index.tsx (in ${paths.consumerDir})`);
|
|
21
21
|
}
|
|
22
|
-
const rawConsumerPkg = (await
|
|
22
|
+
const rawConsumerPkg = (await fs.readJson(paths.consumerPkg));
|
|
23
23
|
if (!rawConsumerPkg.name) {
|
|
24
24
|
throw new Error('Consumer package.json must have a "name" field');
|
|
25
25
|
}
|
|
@@ -29,7 +29,7 @@ async function prepareShadow() {
|
|
|
29
29
|
util_logger.info(`ensured consumer pkg shape at ${paths.consumerPkg}`);
|
|
30
30
|
}
|
|
31
31
|
await shadow_gitignore.ensureGitignore(paths.consumerDir);
|
|
32
|
-
await
|
|
32
|
+
await fs.ensureDir(paths.shadowDir);
|
|
33
33
|
const metadata = await resolvePortAndMetadata(paths, appName);
|
|
34
34
|
const port = metadata.port;
|
|
35
35
|
util_logger.info(`preparing shadow at ${paths.shadowDir} (port ${port})`);
|
package/dist/shadow/scaffold.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
3
|
const path = require('node:path');
|
|
4
|
-
const
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
5
|
|
|
6
6
|
const _interopDefault = e => e && e.__esModule ? e : { default: e };
|
|
7
7
|
|
|
@@ -110,14 +110,14 @@ const TSCONFIG_TEMPLATE = {
|
|
|
110
110
|
* shadow dir is a deterministic function of the CLI version — no drift.
|
|
111
111
|
*/
|
|
112
112
|
async function scaffoldShadow(paths, appName, port) {
|
|
113
|
-
await
|
|
114
|
-
await
|
|
115
|
-
await
|
|
116
|
-
await
|
|
117
|
-
await
|
|
118
|
-
await
|
|
113
|
+
await fs.ensureDir(paths.shadowSrc);
|
|
114
|
+
await fs.writeFile(paths.shadowWrapper, WRAPPER_TEMPLATE);
|
|
115
|
+
await fs.writeFile(paths.shadowTridentrc, tridentrcTemplate(appName, port));
|
|
116
|
+
await fs.writeFile(paths.shadowNvmrc, `${process.version}\n`);
|
|
117
|
+
await fs.writeFile(paths.shadowDts, dtsFileTemplate());
|
|
118
|
+
await fs.writeJson(paths.shadowTsconfig, TSCONFIG_TEMPLATE, { spaces: 2 });
|
|
119
119
|
// Drop a stub README so contributors who open .zth/ know what they're looking at.
|
|
120
|
-
await
|
|
120
|
+
await fs.writeFile(path__default.default.join(paths.shadowDir, 'README.md'), '# .zth/\nGenerated by z2h-cli. Do not edit — run `z2h-cli build` or `z2h-cli dev` to refresh.\n');
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
exports.scaffoldShadow = scaffoldShadow;
|
package/dist/shadow/sync.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
4
|
const util_logger = require('../util/logger.js');
|
|
5
5
|
const util_npm_install = require('../util/npm/install.js');
|
|
6
6
|
const shadow_mergePackageJson = require('./merge-package-json.js');
|
|
@@ -15,14 +15,14 @@ async function syncShadow(paths, consumerPkg) {
|
|
|
15
15
|
const shadow = shadow_mergePackageJson.buildShadowPkg(consumerPkg);
|
|
16
16
|
await shadow_mergePackageJson.writeShadowPkg(paths.shadowPkg, shadow);
|
|
17
17
|
const newHash = shadow_mergePackageJson.hashConsumerDeps(consumerPkg);
|
|
18
|
-
const oldHash = (await
|
|
18
|
+
const oldHash = (await fs.pathExists(paths.shadowDepsHash)) ? await fs.readFile(paths.shadowDepsHash, 'utf8') : null;
|
|
19
19
|
if (oldHash !== newHash) {
|
|
20
20
|
util_logger.info(oldHash ? 'consumer deps changed — yarn install' : 'first run — yarn install');
|
|
21
21
|
// Yarn 4 is cache-first and non-interactive by default in non-TTY
|
|
22
22
|
// contexts, so plain `yarn install` is all we need. runYarnInstall injects
|
|
23
23
|
// the npm-broker token, preflights auth, and re-auths on a broker 401.
|
|
24
24
|
await util_npm_install.runYarnInstall({ cwd: paths.consumerDir });
|
|
25
|
-
await
|
|
25
|
+
await fs.writeFile(paths.shadowDepsHash, newHash);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -11,7 +11,7 @@ var hooks = {
|
|
|
11
11
|
hooks: [
|
|
12
12
|
{
|
|
13
13
|
type: "command",
|
|
14
|
-
command: "if [ -f .zth/dev.pid ]; then
|
|
14
|
+
command: "if [ -f .zth/dev.pid ]; then PGID=$(ps -o pgid= -p $(cat .zth/dev.pid) 2>/dev/null | tr -d ' '); [ -n \"$PGID\" ] && kill -- -$PGID 2>/dev/null; rm -f .zth/dev.pid; fi"
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
const os = require('node:os');
|
|
5
|
-
const
|
|
5
|
+
const fs = require('fs-extra');
|
|
6
6
|
|
|
7
7
|
const _interopDefault = e => e && e.__esModule ? e : { default: e };
|
|
8
8
|
|
|
@@ -23,10 +23,10 @@ class Z2hAuthMissingError extends Error {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
async function readZthAuth() {
|
|
26
|
-
if (!(await
|
|
26
|
+
if (!(await fs.pathExists(Z2H_AUTH_FILE))) {
|
|
27
27
|
throw new Z2hAuthMissingError(Z2H_AUTH_FILE);
|
|
28
28
|
}
|
|
29
|
-
const parsed = (await
|
|
29
|
+
const parsed = (await fs.readJson(Z2H_AUTH_FILE));
|
|
30
30
|
if (!parsed.token) {
|
|
31
31
|
throw new Error(`${Z2H_AUTH_FILE} is missing a "token" string field.`);
|
|
32
32
|
}
|
|
@@ -43,7 +43,7 @@ async function readZthAuth() {
|
|
|
43
43
|
*/
|
|
44
44
|
function tryReadAuthTokenSync() {
|
|
45
45
|
try {
|
|
46
|
-
const parsed =
|
|
46
|
+
const parsed = fs.readJsonSync(Z2H_AUTH_FILE);
|
|
47
47
|
return parsed?.token ?? null;
|
|
48
48
|
}
|
|
49
49
|
catch {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
3
|
const promises = require('node:fs/promises');
|
|
4
|
-
const
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
5
|
const util_auth_authStore = require('./auth-store.js');
|
|
6
6
|
|
|
7
7
|
// 0o600 — owner read/write only. The file holds a long-lived bearer token,
|
|
8
8
|
// so other local users on the machine must not be able to read it.
|
|
9
9
|
const OWNER_READ_WRITE_FILE_MODE = 0o600;
|
|
10
10
|
async function writeZthAuth(auth) {
|
|
11
|
-
await
|
|
12
|
-
await
|
|
11
|
+
await fs.ensureDir(util_auth_authStore.Z2H_AUTH_DIR);
|
|
12
|
+
await fs.writeFile(util_auth_authStore.Z2H_AUTH_FILE, `${JSON.stringify(auth, null, 2)}\n`);
|
|
13
13
|
await promises.chmod(util_auth_authStore.Z2H_AUTH_FILE, OWNER_READ_WRITE_FILE_MODE);
|
|
14
14
|
return { filePath: util_auth_authStore.Z2H_AUTH_FILE };
|
|
15
15
|
}
|