@mondaydotcomorg/z2h-cli 0.7.2 → 0.9.1

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.
Files changed (90) hide show
  1. package/dist/commands/build.d.ts +1 -1
  2. package/dist/commands/build.d.ts.map +1 -1
  3. package/dist/commands/build.js +4 -3
  4. package/dist/commands/clean.d.ts +1 -1
  5. package/dist/commands/clean.d.ts.map +1 -1
  6. package/dist/commands/clean.js +5 -4
  7. package/dist/commands/create-workspace.d.ts +1 -1
  8. package/dist/commands/create-workspace.d.ts.map +1 -1
  9. package/dist/commands/create-workspace.js +14 -14
  10. package/dist/commands/create.d.ts +1 -1
  11. package/dist/commands/create.d.ts.map +1 -1
  12. package/dist/commands/create.js +27 -13
  13. package/dist/commands/deploy.d.ts +1 -1
  14. package/dist/commands/deploy.d.ts.map +1 -1
  15. package/dist/commands/deploy.js +45 -11
  16. package/dist/commands/dev.d.ts +1 -1
  17. package/dist/commands/dev.d.ts.map +1 -1
  18. package/dist/commands/dev.js +10 -6
  19. package/dist/commands/migrate.d.ts +1 -1
  20. package/dist/commands/migrate.d.ts.map +1 -1
  21. package/dist/commands/migrate.js +1 -1
  22. package/dist/esm/commands/build.d.ts +1 -1
  23. package/dist/esm/commands/build.d.ts.map +1 -1
  24. package/dist/esm/commands/build.mjs +2 -1
  25. package/dist/esm/commands/clean.d.ts +1 -1
  26. package/dist/esm/commands/clean.d.ts.map +1 -1
  27. package/dist/esm/commands/clean.mjs +2 -1
  28. package/dist/esm/commands/create-workspace.d.ts +1 -1
  29. package/dist/esm/commands/create-workspace.d.ts.map +1 -1
  30. package/dist/esm/commands/create-workspace.mjs +1 -1
  31. package/dist/esm/commands/create.d.ts +1 -1
  32. package/dist/esm/commands/create.d.ts.map +1 -1
  33. package/dist/esm/commands/create.mjs +16 -2
  34. package/dist/esm/commands/deploy.d.ts +1 -1
  35. package/dist/esm/commands/deploy.d.ts.map +1 -1
  36. package/dist/esm/commands/deploy.mjs +42 -8
  37. package/dist/esm/commands/dev.d.ts +1 -1
  38. package/dist/esm/commands/dev.d.ts.map +1 -1
  39. package/dist/esm/commands/dev.mjs +5 -1
  40. package/dist/esm/commands/migrate.d.ts +1 -1
  41. package/dist/esm/commands/migrate.d.ts.map +1 -1
  42. package/dist/esm/commands/migrate.mjs +1 -1
  43. package/dist/esm/index.mjs +4 -1
  44. package/dist/esm/migrations/auto-migrate.mjs +1 -1
  45. package/dist/esm/templates/app/claude-settings.mjs +1 -1
  46. package/dist/esm/util/git/__tests__/repo.test.d.ts +2 -0
  47. package/dist/esm/util/git/__tests__/repo.test.d.ts.map +1 -0
  48. package/dist/esm/util/git/repo.d.ts +12 -0
  49. package/dist/esm/util/git/repo.d.ts.map +1 -0
  50. package/dist/esm/util/git/repo.mjs +105 -0
  51. package/dist/esm/util/manifest.d.ts +1 -0
  52. package/dist/esm/util/manifest.d.ts.map +1 -1
  53. package/dist/index.js +4 -1
  54. package/dist/migrations/auto-migrate.js +11 -11
  55. package/dist/shadow/consumer-pkg.js +2 -2
  56. package/dist/shadow/gitignore.js +4 -4
  57. package/dist/shadow/merge-package-json.js +2 -2
  58. package/dist/shadow/metadata.js +4 -4
  59. package/dist/shadow/prepare.js +5 -5
  60. package/dist/shadow/scaffold.js +8 -8
  61. package/dist/shadow/sync.js +3 -3
  62. package/dist/templates/app/claude-settings.js +1 -1
  63. package/dist/util/auth/auth-store.js +4 -4
  64. package/dist/util/auth/write-auth.js +3 -3
  65. package/dist/util/git/__tests__/repo.test.d.ts +2 -0
  66. package/dist/util/git/__tests__/repo.test.d.ts.map +1 -0
  67. package/dist/util/git/repo.d.ts +12 -0
  68. package/dist/util/git/repo.d.ts.map +1 -0
  69. package/dist/util/git/repo.js +120 -0
  70. package/dist/util/manifest.d.ts +1 -0
  71. package/dist/util/manifest.d.ts.map +1 -1
  72. package/dist/util/s3/upload.js +2 -2
  73. package/dist/util/workspace.js +3 -3
  74. package/package.json +1 -1
  75. package/src/commands/__tests__/create-workspace.test.ts +4 -4
  76. package/src/commands/__tests__/create.test.ts +12 -5
  77. package/src/commands/build.ts +2 -1
  78. package/src/commands/clean.ts +2 -1
  79. package/src/commands/create-workspace.ts +1 -1
  80. package/src/commands/create.ts +15 -2
  81. package/src/commands/deploy.ts +43 -8
  82. package/src/commands/dev.ts +5 -1
  83. package/src/commands/migrate.ts +1 -1
  84. package/src/index.ts +4 -1
  85. package/src/migrations/auto-migrate.ts +3 -3
  86. package/src/templates/app/CLAUDE.md +3 -1
  87. package/src/templates/app/claude-settings.json +1 -1
  88. package/src/util/git/__tests__/repo.test.ts +208 -0
  89. package/src/util/git/repo.ts +112 -0
  90. package/src/util/manifest.ts +1 -0
@@ -2,5 +2,5 @@ export interface BuildOptions {
2
2
  json?: boolean;
3
3
  publicUrl?: string;
4
4
  }
5
- export declare function buildCommand(opts: BuildOptions): Promise<void>;
5
+ export declare function buildCommand(opts?: BuildOptions): Promise<void>;
6
6
  //# sourceMappingURL=build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCpE"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,wBAAsB,YAAY,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCzE"}
@@ -1,11 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
- const fsExtra = require('fs-extra');
3
+ const fs = require('fs-extra');
4
4
  const execa = require('execa');
5
5
  const util_logger = require('../util/logger.js');
6
6
  const shadow_prepare = require('../shadow/prepare.js');
7
7
 
8
- async function buildCommand(opts) {
8
+ // Should be run from the consumer app directory — uses process.cwd() to locate it.
9
+ async function buildCommand(opts = {}) {
9
10
  if (opts.json) {
10
11
  util_logger.setOutputMode('json');
11
12
  }
@@ -27,7 +28,7 @@ async function buildCommand(opts) {
27
28
  stdio: 'inherit',
28
29
  env: { ...process.env, ...(opts.publicUrl ? { PUBLIC_URL: opts.publicUrl } : {}) },
29
30
  });
30
- if (!(await fsExtra.pathExists(ctx.paths.shadowBuild))) {
31
+ if (!(await fs.pathExists(ctx.paths.shadowBuild))) {
31
32
  throw new Error(`Expected build output at ${ctx.paths.shadowBuild} — not found.`);
32
33
  }
33
34
  util_logger.output(`[z2h-cli] build complete — artifacts at ${ctx.paths.shadowBuild}`, {
@@ -1,5 +1,5 @@
1
1
  export interface CleanOptions {
2
2
  json?: boolean;
3
3
  }
4
- export declare function cleanCommand(opts: CleanOptions): Promise<void>;
4
+ export declare function cleanCommand(opts?: CleanOptions): Promise<void>;
5
5
  //# sourceMappingURL=clean.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBpE"}
1
+ {"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAGD,wBAAsB,YAAY,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBzE"}
@@ -1,18 +1,19 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
- const fsExtra = require('fs-extra');
3
+ const fs = require('fs-extra');
4
4
  const util_logger = require('../util/logger.js');
5
5
  const shadow_paths = require('../shadow/paths.js');
6
6
 
7
- async function cleanCommand(opts) {
7
+ // Should be run from the consumer app directory — uses process.cwd() to locate it.
8
+ async function cleanCommand(opts = {}) {
8
9
  if (opts.json) {
9
10
  util_logger.setOutputMode('json');
10
11
  }
11
12
  const paths = shadow_paths.resolveConsumerPaths(process.cwd());
12
- const existed = await fsExtra.pathExists(paths.shadowDir);
13
+ const existed = await fs.pathExists(paths.shadowDir);
13
14
  if (existed) {
14
15
  util_logger.info(`removing ${paths.shadowDir}`);
15
- await fsExtra.remove(paths.shadowDir);
16
+ await fs.remove(paths.shadowDir);
16
17
  }
17
18
  util_logger.output(existed ? `[z2h-cli] cleaned shadow at ${paths.shadowDir}` : '[z2h-cli] nothing to clean', {
18
19
  ok: true,
@@ -1,5 +1,5 @@
1
1
  export interface CreateWorkspaceOptions {
2
2
  json?: boolean;
3
3
  }
4
- export declare function createWorkspaceCommand(opts: CreateWorkspaceOptions): Promise<void>;
4
+ export declare function createWorkspaceCommand(opts?: CreateWorkspaceOptions): Promise<void>;
5
5
  //# sourceMappingURL=create-workspace.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-workspace.d.ts","sourceRoot":"","sources":["../../src/commands/create-workspace.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CxF"}
1
+ {"version":3,"file":"create-workspace.d.ts","sourceRoot":"","sources":["../../src/commands/create-workspace.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,sBAAsB,CAAC,IAAI,GAAE,sBAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C7F"}
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const path = require('node:path');
4
4
  const promises = require('node:fs/promises');
5
- const fsExtra = require('fs-extra');
5
+ const fs = require('fs-extra');
6
6
  const util_logger = require('../util/logger.js');
7
7
  const util_workspace = require('../util/workspace.js');
8
8
  const util_templates = require('../util/templates.js');
@@ -12,33 +12,33 @@ const _interopDefault = e => e && e.__esModule ? e : { default: e };
12
12
 
13
13
  const path__default = /*#__PURE__*/_interopDefault(path);
14
14
 
15
- async function createWorkspaceCommand(opts) {
15
+ async function createWorkspaceCommand(opts = {}) {
16
16
  if (opts.json) {
17
17
  util_logger.setOutputMode('json');
18
18
  }
19
19
  const home = util_workspace.getWorkspaceHome();
20
20
  const templatesDir = util_templates.getTemplatesDir();
21
21
  const wsTemplatesDir = path__default.default.join(templatesDir, 'workspace');
22
- if (await fsExtra.pathExists(home)) {
23
- const entries = await fsExtra.readdir(home);
22
+ if (await fs.pathExists(home)) {
23
+ const entries = await fs.readdir(home);
24
24
  if (entries.length > 0) {
25
25
  throw new Error(`Workspace already exists at ${home}. Remove it and try again.`);
26
26
  }
27
27
  }
28
28
  else {
29
- await fsExtra.ensureDir(home);
29
+ await fs.ensureDir(home);
30
30
  }
31
31
  const pkgRaw = await promises.readFile(path__default.default.join(wsTemplatesDir, 'package.json.tmpl'), 'utf8');
32
32
  await Promise.all([
33
- fsExtra.writeFile(path__default.default.join(home, 'package.json'), pkgRaw),
34
- fsExtra.copy(path__default.default.join(wsTemplatesDir, 'gitignore'), path__default.default.join(home, '.gitignore')),
35
- fsExtra.copy(path__default.default.join(wsTemplatesDir, 'yarnrc.yml'), path__default.default.join(home, '.yarnrc.yml')),
36
- fsExtra.copy(path__default.default.join(wsTemplatesDir, 'nx.json'), path__default.default.join(home, 'nx.json')),
37
- fsExtra.copy(path__default.default.join(wsTemplatesDir, 'yarnlock'), path__default.default.join(home, 'yarn.lock')),
38
- fsExtra.copy(path__default.default.join(wsTemplatesDir, 'nvmrc'), path__default.default.join(home, '.nvmrc')),
39
- fsExtra.copy(path__default.default.join(wsTemplatesDir, 'npmrc'), path__default.default.join(home, '.npmrc')),
40
- fsExtra.copy(path__default.default.join(wsTemplatesDir, 'README.md'), path__default.default.join(home, 'README.md')),
41
- fsExtra.copy(path__default.default.join(wsTemplatesDir, 'yarn-releases', 'yarn-4.5.1.cjs'), path__default.default.join(home, '.yarn', 'releases', 'yarn-4.5.1.cjs')),
33
+ fs.writeFile(path__default.default.join(home, 'package.json'), pkgRaw),
34
+ fs.copy(path__default.default.join(wsTemplatesDir, 'gitignore'), path__default.default.join(home, '.gitignore')),
35
+ fs.copy(path__default.default.join(wsTemplatesDir, 'yarnrc.yml'), path__default.default.join(home, '.yarnrc.yml')),
36
+ fs.copy(path__default.default.join(wsTemplatesDir, 'nx.json'), path__default.default.join(home, 'nx.json')),
37
+ fs.copy(path__default.default.join(wsTemplatesDir, 'yarnlock'), path__default.default.join(home, 'yarn.lock')),
38
+ fs.copy(path__default.default.join(wsTemplatesDir, 'nvmrc'), path__default.default.join(home, '.nvmrc')),
39
+ fs.copy(path__default.default.join(wsTemplatesDir, 'npmrc'), path__default.default.join(home, '.npmrc')),
40
+ fs.copy(path__default.default.join(wsTemplatesDir, 'README.md'), path__default.default.join(home, 'README.md')),
41
+ fs.copy(path__default.default.join(wsTemplatesDir, 'yarn-releases', 'yarn-4.5.1.cjs'), path__default.default.join(home, '.yarn', 'releases', 'yarn-4.5.1.cjs')),
42
42
  ]);
43
43
  util_logger.info(`setting up your Z2H workspace — this may take a minute...`);
44
44
  await util_npm_install.runYarnInstall({ cwd: home });
@@ -3,5 +3,5 @@ export interface CreateOptions {
3
3
  htmlFile?: string;
4
4
  json?: boolean;
5
5
  }
6
- export declare function createCommand(appName: string, opts: CreateOptions): Promise<void>;
6
+ export declare function createCommand(appName: string, opts?: CreateOptions): Promise<void>;
7
7
  //# sourceMappingURL=create.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA6BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFvF"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA6BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8F5F"}
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const path = require('node:path');
4
4
  const promises = require('node:fs/promises');
5
- const fsExtra = require('fs-extra');
5
+ const fs = require('fs-extra');
6
6
  const util_logger = require('../util/logger.js');
7
7
  const util_workspace = require('../util/workspace.js');
8
8
  const util_templates = require('../util/templates.js');
@@ -10,6 +10,7 @@ const util_manifest = require('../util/manifest.js');
10
10
  const util_appName = require('../util/app-name.js');
11
11
  const constants = require('../constants.js');
12
12
  const util_npm_install = require('../util/npm/install.js');
13
+ const commands_build = require('./build.js');
13
14
 
14
15
  const _interopDefault = e => e && e.__esModule ? e : { default: e };
15
16
 
@@ -33,13 +34,13 @@ function pascalCase(input) {
33
34
  * Returns true iff `dir` either does not exist or is an empty directory.
34
35
  */
35
36
  async function isDirEmpty(dir) {
36
- if (!(await fsExtra.pathExists(dir))) {
37
+ if (!(await fs.pathExists(dir))) {
37
38
  return true;
38
39
  }
39
- const entries = await fsExtra.readdir(dir);
40
+ const entries = await fs.readdir(dir);
40
41
  return entries.length === 0;
41
42
  }
42
- async function createCommand(appName, opts) {
43
+ async function createCommand(appName, opts = {}) {
43
44
  if (opts.json) {
44
45
  util_logger.setOutputMode('json');
45
46
  }
@@ -59,7 +60,7 @@ async function createCommand(appName, opts) {
59
60
  if (!util_templates.APP_TEMPLATES.includes(template)) {
60
61
  throw new Error(`Unknown template "${template}". Available: ${util_templates.APP_TEMPLATES.join(', ')}.`);
61
62
  }
62
- if (opts.htmlFile && !(await fsExtra.pathExists(opts.htmlFile))) {
63
+ if (opts.htmlFile && !(await fs.pathExists(opts.htmlFile))) {
63
64
  throw new Error(`HTML file does not exist: ${opts.htmlFile}`);
64
65
  }
65
66
  // Validate target dir.
@@ -78,25 +79,38 @@ async function createCommand(appName, opts) {
78
79
  __APP_COMPONENT__: pascalCase(appName),
79
80
  };
80
81
  const appTemplatesDir = path__default.default.join(util_templates.getTemplatesDir(), 'app');
81
- await fsExtra.ensureDir(path__default.default.join(appDir, 'src'));
82
- await fsExtra.ensureDir(path__default.default.join(appDir, '.claude'));
82
+ await fs.ensureDir(path__default.default.join(appDir, 'src'));
83
+ await fs.ensureDir(path__default.default.join(appDir, '.claude'));
83
84
  // package.json (templated).
84
85
  const pkgRaw = await promises.readFile(path__default.default.join(appTemplatesDir, 'package.json.tmpl'), 'utf8');
85
- await fsExtra.writeFile(path__default.default.join(appDir, 'package.json'), util_templates.renderTemplate(pkgRaw, vars));
86
+ await fs.writeFile(path__default.default.join(appDir, 'package.json'), util_templates.renderTemplate(pkgRaw, vars));
86
87
  // src/index.tsx (templated; choice driven by template).
87
88
  const indexTemplate = template === 'html-embed' ? 'html-index.tsx.tmpl' : 'default-index.tsx.tmpl';
88
89
  const indexRaw = await promises.readFile(path__default.default.join(appTemplatesDir, indexTemplate), 'utf8');
89
- await fsExtra.writeFile(path__default.default.join(appDir, 'src', 'index.tsx'), util_templates.renderTemplate(indexRaw, vars));
90
+ await fs.writeFile(path__default.default.join(appDir, 'src', 'index.tsx'), util_templates.renderTemplate(indexRaw, vars));
90
91
  // Copy verbatim files.
91
- await fsExtra.copy(path__default.default.join(appTemplatesDir, 'gitignore'), path__default.default.join(appDir, '.gitignore'));
92
- await fsExtra.copy(path__default.default.join(appTemplatesDir, 'claude-settings.json'), path__default.default.join(appDir, '.claude', 'settings.json'));
93
- await fsExtra.copy(path__default.default.join(appTemplatesDir, 'CLAUDE.md'), path__default.default.join(appDir, 'CLAUDE.md'));
92
+ await fs.copy(path__default.default.join(appTemplatesDir, 'gitignore'), path__default.default.join(appDir, '.gitignore'));
93
+ await fs.copy(path__default.default.join(appTemplatesDir, 'claude-settings.json'), path__default.default.join(appDir, '.claude', 'settings.json'));
94
+ await fs.copy(path__default.default.join(appTemplatesDir, 'CLAUDE.md'), path__default.default.join(appDir, 'CLAUDE.md'));
94
95
  // html-embed: also copy the source HTML.
95
96
  if (template === 'html-embed' && opts.htmlFile) {
96
- await fsExtra.copy(opts.htmlFile, path__default.default.join(appDir, 'src', 'page.html'));
97
+ await fs.copy(opts.htmlFile, path__default.default.join(appDir, 'src', 'page.html'));
97
98
  }
98
99
  util_logger.info(`installing dependencies for ${appName}...`);
99
100
  await util_npm_install.runYarnInstall({ cwd: workspace });
101
+ // build/dev/deploy all locate the consumer via process.cwd() — chdir before calling them.
102
+ const prevCwd = process.cwd();
103
+ try {
104
+ util_logger.info(`pre-building ${appName}`);
105
+ process.chdir(appDir);
106
+ await commands_build.buildCommand();
107
+ }
108
+ catch {
109
+ util_logger.warn(`pre-build failed. No worries — it will run again when needed.`);
110
+ }
111
+ finally {
112
+ process.chdir(prevCwd);
113
+ }
100
114
  util_logger.output(`[z2h-cli] app ready at ${appDir}`, {
101
115
  ok: true,
102
116
  appDir,
@@ -2,5 +2,5 @@ export interface DeployOptions {
2
2
  dryRun?: boolean;
3
3
  json?: boolean;
4
4
  }
5
- export declare function deployCommand(opts: DeployOptions): Promise<void>;
5
+ export declare function deployCommand(opts?: DeployOptions): Promise<void>;
6
6
  //# sourceMappingURL=deploy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA+EtE"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAGD,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuF3E"}
@@ -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 fsExtra = require('fs-extra');
5
+ const fs = require('fs-extra');
6
6
  const util_logger = require('../util/logger.js');
7
7
  const shadow_paths = require('../shadow/paths.js');
8
8
  const util_manifest = require('../util/manifest.js');
@@ -18,19 +18,20 @@ const _interopDefault = e => e && e.__esModule ? e : { default: e };
18
18
  const path__default = /*#__PURE__*/_interopDefault(path);
19
19
  const os__default = /*#__PURE__*/_interopDefault(os);
20
20
 
21
- async function deployCommand(opts) {
21
+ // Should be run from the consumer app directory — uses process.cwd() to locate it.
22
+ async function deployCommand(opts = {}) {
22
23
  if (opts.json) {
23
24
  util_logger.setOutputMode('json');
24
25
  }
25
26
  const paths = shadow_paths.resolveConsumerPaths(process.cwd());
26
- const consumerPkg = (await fsExtra.readJson(paths.consumerPkg));
27
+ const consumerPkg = (await fs.readJson(paths.consumerPkg));
27
28
  if (!consumerPkg.name) {
28
29
  throw new Error('Consumer package.json must have a "name" field');
29
30
  }
30
31
  const appName = util_appName.mfAppName(consumerPkg.name);
31
32
  // Validate the user's deploy token is on disk before doing any expensive
32
33
  // work. Throws Z2hAuthMissingError with a remediation hint if not.
33
- await util_auth_authStore.readZthAuth();
34
+ const { token } = await util_auth_authStore.readZthAuth();
34
35
  util_s3_client.setupS3Client({ appName });
35
36
  util_logger.info('reading current Z2H manifest');
36
37
  const manifest = await util_manifest.readManifest();
@@ -39,15 +40,15 @@ async function deployCommand(opts) {
39
40
  const url = `${constants.BUCKET_READ_DNS_URL}/${keyPrefix}`;
40
41
  util_logger.info('building');
41
42
  await commands_build.buildCommand({ json: opts.json, publicUrl: url });
42
- if (!(await fsExtra.pathExists(paths.shadowBuild))) {
43
+ if (!(await fs.pathExists(paths.shadowBuild))) {
43
44
  throw new Error(`No build output at ${paths.shadowBuild} after build step.`);
44
45
  }
45
46
  // Trident emits the canonical per-MF manifest at build/asset-manifest.json.
46
47
  const assetManifestPath = path__default.default.join(paths.shadowBuild, 'asset-manifest.json');
47
- if (!(await fsExtra.pathExists(assetManifestPath))) {
48
+ if (!(await fs.pathExists(assetManifestPath))) {
48
49
  throw new Error(`Missing asset-manifest.json at ${assetManifestPath}.`);
49
50
  }
50
- const assetManifest = (await fsExtra.readJson(assetManifestPath));
51
+ const assetManifest = (await fs.readJson(assetManifestPath));
51
52
  const deployedBy = os__default.default.userInfo().username;
52
53
  const entry = {
53
54
  ...assetManifest,
@@ -68,10 +69,18 @@ async function deployCommand(opts) {
68
69
  });
69
70
  return;
70
71
  }
71
- util_logger.info(`uploading build → s3://${constants.BUCKET_WRITE_NAME}/${keyPrefix}/`);
72
- await util_s3_upload.uploadDir(paths.shadowBuild, keyPrefix);
73
- util_logger.info(`updating manifest entry "${appName}" → v${version}`);
74
- await util_manifest.writeManifest(util_manifest.upsertEntry(manifest, appName, entry));
72
+ try {
73
+ // Lock is acquired here — uploadDir triggers the STS credential provider on first S3 call
74
+ util_logger.info(`uploading build → s3://${constants.BUCKET_WRITE_NAME}/${keyPrefix}/`);
75
+ await util_s3_upload.uploadDir(paths.shadowBuild, keyPrefix);
76
+ util_logger.info(`updating manifest entry "${appName}" → v${version}`);
77
+ await util_manifest.writeManifest(util_manifest.upsertEntry(manifest, appName, entry));
78
+ util_logger.info(`registering app "${appName}" → v${version}`);
79
+ await registerApp(appName, token, version, entry);
80
+ }
81
+ finally {
82
+ await releaseLockBestEffort(appName, token);
83
+ }
75
84
  // The host MF parses the app name from the URL and prepends `mf-` itself
76
85
  // before looking it up in the manifest. So the user-facing URL must use
77
86
  // the consumer's de-scoped package name (no `mf-` prefix, no `@scope/`).
@@ -87,5 +96,30 @@ async function deployCommand(opts) {
87
96
  entry,
88
97
  });
89
98
  }
99
+ async function registerApp(appName, token, version, entry) {
100
+ const res = await fetch(`${constants.brokerBaseUrl()}/z2h-cli/apps/register`, {
101
+ method: 'POST',
102
+ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
103
+ body: JSON.stringify({ appName, version, entry }),
104
+ });
105
+ if (!res.ok) {
106
+ const text = await res.text();
107
+ throw new Error(`App registration failed (${res.status}): ${text.slice(0, 1024)}`);
108
+ }
109
+ }
110
+ // best-effort — the 5-min TTL backstop handles failures
111
+ async function releaseLockBestEffort(appName, token) {
112
+ try {
113
+ await fetch(`${constants.brokerBaseUrl()}/z2h-cli/lock/release`, {
114
+ method: 'POST',
115
+ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
116
+ body: JSON.stringify({ appName }),
117
+ });
118
+ util_logger.info(`lock released for ${appName}`);
119
+ }
120
+ catch {
121
+ util_logger.warn(`failed to release lock for ${appName}`);
122
+ }
123
+ }
90
124
 
91
125
  exports.deployCommand = deployCommand;
@@ -1,5 +1,5 @@
1
1
  export interface DevOptions {
2
2
  json?: boolean;
3
3
  }
4
- export declare function devCommand(opts: DevOptions): Promise<void>;
4
+ export declare function devCommand(opts?: DevOptions): Promise<void>;
5
5
  //# sourceMappingURL=dev.d.ts.map
@@ -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;AAID,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAuEhE"}
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"}
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const path = require('node:path');
4
- const fs = require('node:fs');
5
- const fsExtra = require('fs-extra');
4
+ const fs$1 = require('node:fs');
5
+ const fs = require('fs-extra');
6
6
  const chokidar = require('chokidar');
7
7
  const execa = require('execa');
8
8
  const util_logger = require('../util/logger.js');
@@ -13,10 +13,11 @@ const shadow_sync = require('../shadow/sync.js');
13
13
  const _interopDefault = e => e && e.__esModule ? e : { default: e };
14
14
 
15
15
  const path__default = /*#__PURE__*/_interopDefault(path);
16
- const fs__default = /*#__PURE__*/_interopDefault(fs);
16
+ const fs__default = /*#__PURE__*/_interopDefault(fs$1);
17
17
 
18
18
  const TRIDENT_READY_PATTERN = /Server started at/i;
19
- async function devCommand(opts) {
19
+ // Should be run from the consumer app directory — uses process.cwd() to locate it.
20
+ async function devCommand(opts = {}) {
20
21
  if (opts.json) {
21
22
  util_logger.setOutputMode('json');
22
23
  }
@@ -30,10 +31,13 @@ async function devCommand(opts) {
30
31
  const server = execa.execa('yarn', ['start'], {
31
32
  cwd: ctx.paths.shadowDir,
32
33
  stdio: ['inherit', 'pipe', 'inherit'],
34
+ // Trident requires NPM_TOKEN to be set or it refuses to start; 'FAKE_TOKEN' satisfies the check without real credentials.
35
+ // we always pass a fake token for same behavior for all users (no matter if they have a token or not)
36
+ env: { ...process.env, NPM_TOKEN: 'FAKE_TOKEN' },
33
37
  });
34
38
  const pidFile = path__default.default.join(ctx.paths.shadowDir, 'dev.pid');
35
39
  if (server.pid) {
36
- await fsExtra.writeFile(pidFile, String(server.pid));
40
+ await fs.writeFile(pidFile, String(server.pid));
37
41
  }
38
42
  const cleanupPid = () => {
39
43
  try {
@@ -73,7 +77,7 @@ async function devCommand(opts) {
73
77
  pkgWatcher.on('change', async () => {
74
78
  util_logger.warn('consumer package.json changed — re-checking deps');
75
79
  try {
76
- const raw = (await fsExtra.readJson(ctx.paths.consumerPkg));
80
+ const raw = (await fs.readJson(ctx.paths.consumerPkg));
77
81
  const { pkg } = await shadow_consumerPkg.ensureConsumerPkg(ctx.paths.consumerPkg, raw);
78
82
  await shadow_sync.syncShadow(ctx.paths, pkg);
79
83
  }
@@ -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: MigrateOptions): Promise<void>;
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,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAM5F"}
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"}
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3
3
  const util_logger = require('../util/logger.js');
4
4
  const migrations_autoMigrate = require('../migrations/auto-migrate.js');
5
5
 
6
- async function migrateCommand(cliVersion, opts) {
6
+ async function migrateCommand(cliVersion, opts = {}) {
7
7
  if (opts.json) {
8
8
  util_logger.setOutputMode('json');
9
9
  }
@@ -2,5 +2,5 @@ export interface BuildOptions {
2
2
  json?: boolean;
3
3
  publicUrl?: string;
4
4
  }
5
- export declare function buildCommand(opts: BuildOptions): Promise<void>;
5
+ export declare function buildCommand(opts?: BuildOptions): Promise<void>;
6
6
  //# sourceMappingURL=build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/commands/build.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCpE"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/commands/build.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,wBAAsB,YAAY,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCzE"}
@@ -3,7 +3,8 @@ import { execa } from 'execa';
3
3
  import { setOutputMode, info, output } from '../util/logger.mjs';
4
4
  import { prepareShadow } from '../shadow/prepare.mjs';
5
5
 
6
- async function buildCommand(opts) {
6
+ // Should be run from the consumer app directory — uses process.cwd() to locate it.
7
+ async function buildCommand(opts = {}) {
7
8
  if (opts.json) {
8
9
  setOutputMode('json');
9
10
  }
@@ -1,5 +1,5 @@
1
1
  export interface CleanOptions {
2
2
  json?: boolean;
3
3
  }
4
- export declare function cleanCommand(opts: CleanOptions): Promise<void>;
4
+ export declare function cleanCommand(opts?: CleanOptions): Promise<void>;
5
5
  //# sourceMappingURL=clean.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../../src/commands/clean.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBpE"}
1
+ {"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../../src/commands/clean.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAGD,wBAAsB,YAAY,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBzE"}
@@ -2,7 +2,8 @@ import { pathExists, remove } from 'fs-extra';
2
2
  import { setOutputMode, info, output } from '../util/logger.mjs';
3
3
  import { resolveConsumerPaths } from '../shadow/paths.mjs';
4
4
 
5
- async function cleanCommand(opts) {
5
+ // Should be run from the consumer app directory — uses process.cwd() to locate it.
6
+ async function cleanCommand(opts = {}) {
6
7
  if (opts.json) {
7
8
  setOutputMode('json');
8
9
  }
@@ -1,5 +1,5 @@
1
1
  export interface CreateWorkspaceOptions {
2
2
  json?: boolean;
3
3
  }
4
- export declare function createWorkspaceCommand(opts: CreateWorkspaceOptions): Promise<void>;
4
+ export declare function createWorkspaceCommand(opts?: CreateWorkspaceOptions): Promise<void>;
5
5
  //# sourceMappingURL=create-workspace.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-workspace.d.ts","sourceRoot":"","sources":["../../../src/commands/create-workspace.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CxF"}
1
+ {"version":3,"file":"create-workspace.d.ts","sourceRoot":"","sources":["../../../src/commands/create-workspace.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,sBAAsB,CAAC,IAAI,GAAE,sBAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C7F"}
@@ -6,7 +6,7 @@ import { getWorkspaceHome } from '../util/workspace.mjs';
6
6
  import { getTemplatesDir } from '../util/templates.mjs';
7
7
  import { runYarnInstall } from '../util/npm/install.mjs';
8
8
 
9
- async function createWorkspaceCommand(opts) {
9
+ async function createWorkspaceCommand(opts = {}) {
10
10
  if (opts.json) {
11
11
  setOutputMode('json');
12
12
  }
@@ -3,5 +3,5 @@ export interface CreateOptions {
3
3
  htmlFile?: string;
4
4
  json?: boolean;
5
5
  }
6
- export declare function createCommand(appName: string, opts: CreateOptions): Promise<void>;
6
+ export declare function createCommand(appName: string, opts?: CreateOptions): Promise<void>;
7
7
  //# sourceMappingURL=create.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/create.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA6BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFvF"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/create.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA6BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8F5F"}
@@ -1,13 +1,14 @@
1
1
  import path from 'node:path';
2
2
  import { readFile } from 'node:fs/promises';
3
3
  import { pathExists, ensureDir, writeFile, copy, readdir } from 'fs-extra';
4
- import { setOutputMode, info, output } from '../util/logger.mjs';
4
+ import { setOutputMode, info, warn, output } from '../util/logger.mjs';
5
5
  import { assertWorkspace } from '../util/workspace.mjs';
6
6
  import { APP_TEMPLATES, getTemplatesDir, renderTemplate } from '../util/templates.mjs';
7
7
  import { readManifest } from '../util/manifest.mjs';
8
8
  import { mfAppName } from '../util/app-name.mjs';
9
9
  import { APP_NAME_PATTERN } from '../constants.mjs';
10
10
  import { runYarnInstall } from '../util/npm/install.mjs';
11
+ import { buildCommand } from './build.mjs';
11
12
 
12
13
  // Names reserved by the host MF (mf-bigbrain-zth) for platform pages under
13
14
  // /bigbrain-vibe/<name>. Creating an app with one of these would shadow the
@@ -33,7 +34,7 @@ async function isDirEmpty(dir) {
33
34
  const entries = await readdir(dir);
34
35
  return entries.length === 0;
35
36
  }
36
- async function createCommand(appName, opts) {
37
+ async function createCommand(appName, opts = {}) {
37
38
  if (opts.json) {
38
39
  setOutputMode('json');
39
40
  }
@@ -91,6 +92,19 @@ async function createCommand(appName, opts) {
91
92
  }
92
93
  info(`installing dependencies for ${appName}...`);
93
94
  await runYarnInstall({ cwd: workspace });
95
+ // build/dev/deploy all locate the consumer via process.cwd() — chdir before calling them.
96
+ const prevCwd = process.cwd();
97
+ try {
98
+ info(`pre-building ${appName}`);
99
+ process.chdir(appDir);
100
+ await buildCommand();
101
+ }
102
+ catch {
103
+ warn(`pre-build failed. No worries — it will run again when needed.`);
104
+ }
105
+ finally {
106
+ process.chdir(prevCwd);
107
+ }
94
108
  output(`[z2h-cli] app ready at ${appDir}`, {
95
109
  ok: true,
96
110
  appDir,
@@ -2,5 +2,5 @@ export interface DeployOptions {
2
2
  dryRun?: boolean;
3
3
  json?: boolean;
4
4
  }
5
- export declare function deployCommand(opts: DeployOptions): Promise<void>;
5
+ export declare function deployCommand(opts?: DeployOptions): Promise<void>;
6
6
  //# sourceMappingURL=deploy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/commands/deploy.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA+EtE"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/commands/deploy.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAGD,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuF3E"}