@mondaydotcomorg/z2h-cli 0.10.0 → 0.11.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/__tests__/edit.test.d.ts +2 -0
- package/dist/commands/__tests__/edit.test.d.ts.map +1 -0
- package/dist/commands/create.d.ts +2 -2
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +14 -34
- package/dist/commands/deploy.d.ts +3 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +123 -23
- package/dist/commands/edit.d.ts +5 -0
- package/dist/commands/edit.d.ts.map +1 -0
- package/dist/commands/edit.js +61 -0
- package/dist/commands/grant.d.ts +12 -0
- package/dist/commands/grant.d.ts.map +1 -0
- package/dist/commands/grant.js +94 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +7 -0
- package/dist/esm/commands/__tests__/edit.test.d.ts +2 -0
- package/dist/esm/commands/__tests__/edit.test.d.ts.map +1 -0
- package/dist/esm/commands/create.d.ts +2 -2
- package/dist/esm/commands/create.d.ts.map +1 -1
- package/dist/esm/commands/create.mjs +16 -35
- package/dist/esm/commands/deploy.d.ts +3 -0
- package/dist/esm/commands/deploy.d.ts.map +1 -1
- package/dist/esm/commands/deploy.mjs +124 -24
- package/dist/esm/commands/edit.d.ts +5 -0
- package/dist/esm/commands/edit.d.ts.map +1 -0
- package/dist/esm/commands/edit.mjs +55 -0
- package/dist/esm/commands/grant.d.ts +12 -0
- package/dist/esm/commands/grant.d.ts.map +1 -0
- package/dist/esm/commands/grant.mjs +90 -0
- package/dist/esm/constants.d.ts +1 -0
- package/dist/esm/constants.d.ts.map +1 -1
- package/dist/esm/constants.mjs +7 -1
- package/dist/esm/index.mjs +67 -10
- package/dist/esm/shadow/prepare.d.ts +1 -1
- package/dist/esm/shadow/prepare.d.ts.map +1 -1
- package/dist/esm/shadow/prepare.mjs +2 -2
- package/dist/esm/util/app-name.d.ts +1 -0
- package/dist/esm/util/app-name.d.ts.map +1 -1
- package/dist/esm/util/app-name.mjs +11 -1
- package/dist/esm/util/auth/auth-store.d.ts.map +1 -1
- package/dist/esm/util/auth/auth-store.mjs +10 -0
- package/dist/esm/util/auth/broker-credential-provider.d.ts +10 -2
- package/dist/esm/util/auth/broker-credential-provider.d.ts.map +1 -1
- package/dist/esm/util/auth/broker-credential-provider.mjs +35 -13
- package/dist/esm/util/broker/app.d.ts +14 -0
- package/dist/esm/util/broker/app.d.ts.map +1 -0
- package/dist/esm/util/broker/app.mjs +27 -0
- package/dist/esm/util/git/git-env.d.ts +9 -0
- package/dist/esm/util/git/git-env.d.ts.map +1 -0
- package/dist/esm/util/git/git-env.mjs +22 -0
- package/dist/esm/util/git/remote-options.d.ts +17 -0
- package/dist/esm/util/git/remote-options.d.ts.map +1 -0
- package/dist/esm/util/git/remote-options.mjs +30 -0
- package/dist/esm/util/git/repo.d.ts +21 -3
- package/dist/esm/util/git/repo.d.ts.map +1 -1
- package/dist/esm/util/git/repo.mjs +103 -47
- package/dist/esm/util/machine-identity.d.ts +9 -0
- package/dist/esm/util/machine-identity.d.ts.map +1 -0
- package/dist/esm/util/machine-identity.mjs +12 -0
- package/dist/esm/util/s3/client.d.ts +2 -7
- package/dist/esm/util/s3/client.d.ts.map +1 -1
- package/dist/esm/util/s3/client.mjs +3 -11
- package/dist/index.js +69 -12
- package/dist/shadow/prepare.d.ts +1 -1
- package/dist/shadow/prepare.d.ts.map +1 -1
- package/dist/shadow/prepare.js +2 -2
- package/dist/util/app-name.d.ts +1 -0
- package/dist/util/app-name.d.ts.map +1 -1
- package/dist/util/app-name.js +11 -0
- package/dist/util/auth/auth-store.d.ts.map +1 -1
- package/dist/util/auth/auth-store.js +10 -0
- package/dist/util/auth/broker-credential-provider.d.ts +10 -2
- package/dist/util/auth/broker-credential-provider.d.ts.map +1 -1
- package/dist/util/auth/broker-credential-provider.js +35 -11
- package/dist/util/broker/app.d.ts +14 -0
- package/dist/util/broker/app.d.ts.map +1 -0
- package/dist/util/broker/app.js +29 -0
- package/dist/util/git/git-env.d.ts +9 -0
- package/dist/util/git/git-env.d.ts.map +1 -0
- package/dist/util/git/git-env.js +24 -0
- package/dist/util/git/remote-options.d.ts +17 -0
- package/dist/util/git/remote-options.d.ts.map +1 -0
- package/dist/util/git/remote-options.js +34 -0
- package/dist/util/git/repo.d.ts +21 -3
- package/dist/util/git/repo.d.ts.map +1 -1
- package/dist/util/git/repo.js +104 -47
- package/dist/util/machine-identity.d.ts +9 -0
- package/dist/util/machine-identity.d.ts.map +1 -0
- package/dist/util/machine-identity.js +14 -0
- package/dist/util/s3/client.d.ts +2 -7
- package/dist/util/s3/client.d.ts.map +1 -1
- package/dist/util/s3/client.js +3 -11
- package/package.json +1 -1
- package/src/commands/__tests__/create.test.ts +9 -7
- package/src/commands/__tests__/edit.test.ts +184 -0
- package/src/commands/create.ts +15 -33
- package/src/commands/deploy.ts +147 -33
- package/src/commands/edit.ts +63 -0
- package/src/commands/grant.ts +115 -0
- package/src/constants.ts +7 -0
- package/src/index.ts +83 -13
- package/src/shadow/prepare.ts +2 -2
- package/src/templates/app/CLAUDE.md +15 -0
- package/src/util/app-name.ts +10 -0
- package/src/util/auth/__tests__/broker-credential-provider.test.ts +34 -2
- package/src/util/auth/auth-store.ts +12 -0
- package/src/util/auth/broker-credential-provider.ts +43 -15
- package/src/util/broker/app.ts +34 -0
- package/src/util/git/__tests__/repo.test.ts +108 -90
- package/src/util/git/git-env.ts +23 -0
- package/src/util/git/remote-options.ts +37 -0
- package/src/util/git/repo.ts +121 -47
- package/src/util/machine-identity.ts +10 -0
- package/src/util/s3/client.ts +4 -11
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/edit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export type RemoteType
|
|
1
|
+
import { REMOTE_TYPES, type RemoteType } from '../util/git/remote-options';
|
|
2
|
+
export { REMOTE_TYPES, type RemoteType };
|
|
3
3
|
export interface CreateOptions {
|
|
4
4
|
template?: string;
|
|
5
5
|
htmlFile?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAA2C,MAAM,4BAA4B,CAAC;AAKpH,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA6BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkG5F"}
|
package/dist/commands/create.js
CHANGED
|
@@ -6,18 +6,18 @@ 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');
|
|
9
|
-
const util_manifest = require('../util/manifest.js');
|
|
10
|
-
const util_appName = require('../util/app-name.js');
|
|
11
9
|
const constants = require('../constants.js');
|
|
12
10
|
const util_npm_install = require('../util/npm/install.js');
|
|
13
11
|
const util_git_repo = require('../util/git/repo.js');
|
|
14
|
-
const
|
|
12
|
+
const util_git_remoteOptions = require('../util/git/remote-options.js');
|
|
13
|
+
const util_broker_app = require('../util/broker/app.js');
|
|
14
|
+
const util_appName = require('../util/app-name.js');
|
|
15
|
+
const shadow_prepare = require('../shadow/prepare.js');
|
|
15
16
|
|
|
16
17
|
const _interopDefault = e => e && e.__esModule ? e : { default: e };
|
|
17
18
|
|
|
18
19
|
const path__default = /*#__PURE__*/_interopDefault(path);
|
|
19
20
|
|
|
20
|
-
const REMOTE_TYPES = ['s3', 'github'];
|
|
21
21
|
// Names reserved by the host MF (mf-bigbrain-zth) for platform pages under
|
|
22
22
|
// /bigbrain-vibe/<name>. Creating an app with one of these would shadow the
|
|
23
23
|
// platform page in the URL, so we refuse upfront.
|
|
@@ -57,15 +57,7 @@ async function createCommand(appName, opts = {}) {
|
|
|
57
57
|
`2-50 chars, starting with a letter.`);
|
|
58
58
|
}
|
|
59
59
|
// Validate --remote up front before any file I/O.
|
|
60
|
-
|
|
61
|
-
throw new Error('--remote is required. Use --remote=s3 (shared storage) or --remote=github (your GitHub repo).');
|
|
62
|
-
}
|
|
63
|
-
if (!REMOTE_TYPES.includes(opts.remote)) {
|
|
64
|
-
throw new Error(`Unknown remote "${opts.remote}". Use ${REMOTE_TYPES.join(' or ')}.`);
|
|
65
|
-
}
|
|
66
|
-
if (opts.remote === 'github' && !opts.repoUrl) {
|
|
67
|
-
throw new Error('--repo-url is required when using --remote=github.');
|
|
68
|
-
}
|
|
60
|
+
util_git_remoteOptions.validateRemoteOptions(opts, true);
|
|
69
61
|
// Resolve template.
|
|
70
62
|
// `--html-file` implies `--template html-embed` unless the user already picked one.
|
|
71
63
|
const template = (opts.template ?? (opts.htmlFile ? 'html-embed' : 'default'));
|
|
@@ -80,9 +72,9 @@ async function createCommand(appName, opts = {}) {
|
|
|
80
72
|
if (!(await isDirEmpty(appDir))) {
|
|
81
73
|
throw new Error(`${appDir} is non-empty. Pick a different name or wipe it first.`);
|
|
82
74
|
}
|
|
83
|
-
// Check
|
|
84
|
-
const
|
|
85
|
-
if (
|
|
75
|
+
// Check the broker — fail fast if the app is already registered.
|
|
76
|
+
const existing = await util_broker_app.fetchApp(util_appName.mfAppName(appName));
|
|
77
|
+
if (existing) {
|
|
86
78
|
throw new Error(`An app named "${appName}" already exists in the Z2H registry. Pick a different name.`);
|
|
87
79
|
}
|
|
88
80
|
// Compute substitutions.
|
|
@@ -109,28 +101,16 @@ async function createCommand(appName, opts = {}) {
|
|
|
109
101
|
await fs.copy(opts.htmlFile, path__default.default.join(appDir, 'src', 'page.html'));
|
|
110
102
|
}
|
|
111
103
|
util_logger.info(`initializing git repo for ${appName}...`);
|
|
112
|
-
|
|
113
|
-
if (opts.remote === 's3') {
|
|
114
|
-
gitRemote = util_git_repo.defaultS3Remote(appName);
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
gitRemote = opts.repoUrl;
|
|
118
|
-
}
|
|
104
|
+
const gitRemote = util_git_remoteOptions.resolveRemoteUrl(opts.remote, appName, opts.repoUrl);
|
|
119
105
|
await util_git_repo.initRepo(appDir, gitRemote);
|
|
120
106
|
util_logger.info(`installing dependencies for ${appName}...`);
|
|
121
107
|
await util_npm_install.runYarnInstall({ cwd: workspace });
|
|
122
|
-
//
|
|
123
|
-
const prevCwd = process.cwd();
|
|
108
|
+
// Best-effort workspace wiring (.zth shadow). Non-fatal — dev/deploy re-run it.
|
|
124
109
|
try {
|
|
125
|
-
|
|
126
|
-
process.chdir(appDir);
|
|
127
|
-
await commands_build.buildCommand();
|
|
128
|
-
}
|
|
129
|
-
catch {
|
|
130
|
-
util_logger.warn(`pre-build failed. No worries — it will run again when needed.`);
|
|
110
|
+
await shadow_prepare.prepareShadow(appDir);
|
|
131
111
|
}
|
|
132
|
-
|
|
133
|
-
|
|
112
|
+
catch (err) {
|
|
113
|
+
util_logger.warn(`prepare shadow failed: ${err.message} — it will run again when needed.`);
|
|
134
114
|
}
|
|
135
115
|
util_logger.output(`[z2h-cli] app ready at ${appDir}`, {
|
|
136
116
|
ok: true,
|
|
@@ -142,5 +122,5 @@ async function createCommand(appName, opts = {}) {
|
|
|
142
122
|
});
|
|
143
123
|
}
|
|
144
124
|
|
|
145
|
-
exports.REMOTE_TYPES = REMOTE_TYPES;
|
|
125
|
+
exports.REMOTE_TYPES = util_git_remoteOptions.REMOTE_TYPES;
|
|
146
126
|
exports.createCommand = createCommand;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { type RemoteType } from '../util/git/remote-options';
|
|
1
2
|
export interface DeployOptions {
|
|
2
3
|
dryRun?: boolean;
|
|
3
4
|
json?: boolean;
|
|
5
|
+
remote?: RemoteType;
|
|
6
|
+
repoUrl?: string;
|
|
4
7
|
}
|
|
5
8
|
export declare function deployCommand(opts?: DeployOptions): Promise<void>;
|
|
6
9
|
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,UAAU,EAA2C,MAAM,4BAA4B,CAAC;AAItG,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAGD,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmJ3E"}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -2,17 +2,21 @@ 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 node_readline = require('node:readline');
|
|
5
6
|
const fs = require('fs-extra');
|
|
6
7
|
const util_logger = require('../util/logger.js');
|
|
7
8
|
const shadow_paths = require('../shadow/paths.js');
|
|
8
|
-
const util_manifest = require('../util/manifest.js');
|
|
9
9
|
const util_s3_upload = require('../util/s3/upload.js');
|
|
10
10
|
const constants = require('../constants.js');
|
|
11
|
-
const
|
|
11
|
+
const util_auth_brokerCredentialProvider = require('../util/auth/broker-credential-provider.js');
|
|
12
12
|
const util_auth_authStore = require('../util/auth/auth-store.js');
|
|
13
13
|
const util_appName = require('../util/app-name.js');
|
|
14
|
-
const
|
|
14
|
+
const util_machineIdentity = require('../util/machine-identity.js');
|
|
15
15
|
const util_git_repo = require('../util/git/repo.js');
|
|
16
|
+
const util_git_gitEnv = require('../util/git/git-env.js');
|
|
17
|
+
const util_git_remoteOptions = require('../util/git/remote-options.js');
|
|
18
|
+
const util_s3_client = require('../util/s3/client.js');
|
|
19
|
+
const commands_build = require('./build.js');
|
|
16
20
|
|
|
17
21
|
const _interopDefault = e => e && e.__esModule ? e : { default: e };
|
|
18
22
|
|
|
@@ -33,11 +37,42 @@ async function deployCommand(opts = {}) {
|
|
|
33
37
|
// Validate the user's deploy token is on disk before doing any expensive
|
|
34
38
|
// work. Throws Z2hAuthMissingError with a remediation hint if not.
|
|
35
39
|
const { token } = await util_auth_authStore.readZthAuth();
|
|
36
|
-
|
|
40
|
+
let gitRemote = await util_git_repo.getRemoteUrl(process.cwd());
|
|
41
|
+
if (gitRemote) {
|
|
42
|
+
if (opts.remote || opts.repoUrl) {
|
|
43
|
+
throw new Error(`--remote and --repo-url only apply on the first deploy of an app with no git remote.\n` +
|
|
44
|
+
`This app already tracks source at: ${gitRemote}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
if (!opts.remote) {
|
|
49
|
+
throw new Error(`This app has no git remote. On first deploy, tell Z2H how to track source:\n\n` +
|
|
50
|
+
` z2h-cli deploy --remote s3 (default)\n` +
|
|
51
|
+
` Stores source history in S3 alongside your app. No extra setup.\n\n` +
|
|
52
|
+
` z2h-cli deploy --remote github --repo-url https://github.com/org/repo.git\n` +
|
|
53
|
+
` Uses an existing GitHub repo (must exist before deploying).`);
|
|
54
|
+
}
|
|
55
|
+
util_git_remoteOptions.validateRemoteOptions(opts);
|
|
56
|
+
// Pass the raw consumer name (not the mf-prefixed appName) so defaultS3Remote
|
|
57
|
+
// produces the correct s3://bucket/mf-<name>/git path without double prefix.
|
|
58
|
+
const remote = util_git_remoteOptions.resolveRemoteUrl(opts.remote, consumerPkg.name, opts.repoUrl);
|
|
59
|
+
util_logger.info(`initializing git repo with ${opts.remote} remote...`);
|
|
60
|
+
await util_git_repo.initRepo(process.cwd(), remote);
|
|
61
|
+
gitRemote = remote;
|
|
62
|
+
}
|
|
63
|
+
const version = await util_auth_brokerCredentialProvider.fetchDeployVersion(appName);
|
|
64
|
+
const nextVersion = version + 1;
|
|
65
|
+
const gitEnv = await util_git_gitEnv.resolveGitEnv(appName, gitRemote);
|
|
66
|
+
// Sync git first so a divergence (GitConflictError) stops us.
|
|
67
|
+
// The skill commits the working tree (with an LLM-authored message) before
|
|
68
|
+
// invoking deploy, so the tree should be clean here.
|
|
69
|
+
if (gitRemote) {
|
|
70
|
+
await util_git_repo.guardCleanTree(process.cwd());
|
|
71
|
+
util_logger.info('syncing with git remote');
|
|
72
|
+
await util_git_repo.pullAndResolve(process.cwd(), gitEnv);
|
|
73
|
+
}
|
|
37
74
|
util_logger.info('reading current Z2H manifest');
|
|
38
|
-
const
|
|
39
|
-
const version = util_manifest.nextVersion(manifest, appName);
|
|
40
|
-
const keyPrefix = `${appName}/${version}`;
|
|
75
|
+
const keyPrefix = `${appName}/${nextVersion}`;
|
|
41
76
|
const url = `${constants.BUCKET_READ_DNS_URL}/${keyPrefix}`;
|
|
42
77
|
util_logger.info('building');
|
|
43
78
|
await commands_build.buildCommand({ json: opts.json, publicUrl: url });
|
|
@@ -50,11 +85,10 @@ async function deployCommand(opts = {}) {
|
|
|
50
85
|
throw new Error(`Missing asset-manifest.json at ${assetManifestPath}.`);
|
|
51
86
|
}
|
|
52
87
|
const assetManifest = (await fs.readJson(assetManifestPath));
|
|
53
|
-
const deployedBy = os__default.default.userInfo().username;
|
|
54
|
-
const gitRemote = await util_git_repo.getRemoteUrl(process.cwd());
|
|
88
|
+
const deployedBy = util_machineIdentity.getMachineAppName() ?? os__default.default.userInfo().username;
|
|
55
89
|
const entry = {
|
|
56
90
|
...assetManifest,
|
|
57
|
-
version,
|
|
91
|
+
version: nextVersion,
|
|
58
92
|
url,
|
|
59
93
|
deployedBy,
|
|
60
94
|
gitRemote,
|
|
@@ -72,14 +106,34 @@ async function deployCommand(opts = {}) {
|
|
|
72
106
|
});
|
|
73
107
|
return;
|
|
74
108
|
}
|
|
109
|
+
// lock → git push → bundle upload → manifest PUT (the manifest write is the single commit point).
|
|
75
110
|
try {
|
|
76
|
-
//
|
|
111
|
+
// Acquire the deploy lock explicitly. Done after the build
|
|
112
|
+
// so the lock hold stays tiny — it wraps only push → upload → manifest.
|
|
113
|
+
// A 409 here means someone else is mid-deploy;
|
|
114
|
+
const creds = await util_auth_brokerCredentialProvider.brokerCredentialProvider({ appName })();
|
|
115
|
+
util_s3_client.setupS3Client(creds);
|
|
116
|
+
await acquireDeployLock(appName, token);
|
|
117
|
+
// Push before any S3 write so a rejected push (someone deployed during our
|
|
118
|
+
// build) stops the deploy before the bundle/manifest go live
|
|
119
|
+
if (gitRemote) {
|
|
120
|
+
util_logger.info('pushing to git remote');
|
|
121
|
+
await util_git_repo.pushToRemote(process.cwd(), gitEnv);
|
|
122
|
+
}
|
|
77
123
|
util_logger.info(`uploading build → s3://${constants.BUCKET_WRITE_NAME}/${keyPrefix}/`);
|
|
78
124
|
await util_s3_upload.uploadDir(paths.shadowBuild, keyPrefix);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
125
|
+
// v1 creates the app row (+ owner grant); later versions release onto it.
|
|
126
|
+
// The two are separate endpoints, so the CLI picks based on the version it
|
|
127
|
+
// was handed.
|
|
128
|
+
if (nextVersion === 1) {
|
|
129
|
+
const visibility = await resolveFirstDeployVisibility(appName, opts.json);
|
|
130
|
+
util_logger.info(`registering app "${appName}" → v${nextVersion} (${visibility})`);
|
|
131
|
+
await registerApp(appName, token, nextVersion, entry, visibility, gitRemote);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
util_logger.info(`releasing "${appName}" → v${nextVersion}`);
|
|
135
|
+
await updateApp(appName, token, nextVersion, entry);
|
|
136
|
+
}
|
|
83
137
|
}
|
|
84
138
|
finally {
|
|
85
139
|
await releaseLockBestEffort(appName, token);
|
|
@@ -88,10 +142,10 @@ async function deployCommand(opts = {}) {
|
|
|
88
142
|
// before looking it up in the manifest. So the user-facing URL must use
|
|
89
143
|
// the consumer's de-scoped package name (no `mf-` prefix, no `@scope/`).
|
|
90
144
|
const liveUrl = `https://bigbrain.me/bigbrain-vibe/${util_appName.cleanAppName(consumerPkg.name)}`;
|
|
91
|
-
util_logger.output(`[z2h-cli] deployed ✅\n app: ${appName}\n version: ${
|
|
145
|
+
util_logger.output(`[z2h-cli] deployed ✅\n app: ${appName}\n version: ${nextVersion}\n open: ${liveUrl}`, {
|
|
92
146
|
ok: true,
|
|
93
147
|
appName,
|
|
94
|
-
version,
|
|
148
|
+
version: nextVersion,
|
|
95
149
|
bucket: constants.BUCKET_WRITE_NAME,
|
|
96
150
|
keyPrefix,
|
|
97
151
|
url,
|
|
@@ -99,25 +153,71 @@ async function deployCommand(opts = {}) {
|
|
|
99
153
|
entry,
|
|
100
154
|
});
|
|
101
155
|
}
|
|
102
|
-
async function registerApp(appName, token, version, entry) {
|
|
156
|
+
async function registerApp(appName, token, version, entry, visibility, gitRemote) {
|
|
103
157
|
const res = await fetch(`${constants.brokerBaseUrl()}/z2h-cli/apps/register`, {
|
|
104
158
|
method: 'POST',
|
|
105
|
-
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
106
|
-
body: JSON.stringify({ appName, version, entry }),
|
|
159
|
+
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', ...constants.routingHeaders() },
|
|
160
|
+
body: JSON.stringify({ appName, version, entry, visibility, gitRemote }),
|
|
107
161
|
});
|
|
108
162
|
if (!res.ok) {
|
|
109
163
|
const text = await res.text();
|
|
110
164
|
throw new Error(`App registration failed (${res.status}): ${text.slice(0, 1024)}`);
|
|
111
165
|
}
|
|
112
166
|
}
|
|
113
|
-
//
|
|
167
|
+
// Acquire the per-app deploy lock. Throws a friendly error on 409 (someone else is deploying)
|
|
168
|
+
// so the deploy stops and the caller can retry; the backend TTL backstops a crashed holder.
|
|
169
|
+
async function acquireDeployLock(appName, token) {
|
|
170
|
+
const res = await fetch(`${constants.brokerBaseUrl()}/z2h-cli/lock/acquire`, {
|
|
171
|
+
method: 'POST',
|
|
172
|
+
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', ...constants.routingHeaders() },
|
|
173
|
+
body: JSON.stringify({ appName }),
|
|
174
|
+
});
|
|
175
|
+
if (res.status === 409) {
|
|
176
|
+
throw new Error(`Someone is deploying "${appName}" right now — try again in a moment.`);
|
|
177
|
+
}
|
|
178
|
+
if (!res.ok) {
|
|
179
|
+
const text = await res.text();
|
|
180
|
+
throw new Error(`Failed to acquire deploy lock (${res.status}): ${text.slice(0, 512)}`);
|
|
181
|
+
}
|
|
182
|
+
util_logger.info(`deploy lock acquired for ${appName}`);
|
|
183
|
+
}
|
|
184
|
+
async function updateApp(appName, token, version, entry) {
|
|
185
|
+
const res = await fetch(`${constants.brokerBaseUrl()}/z2h-cli/apps/update`, {
|
|
186
|
+
method: 'POST',
|
|
187
|
+
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', ...constants.routingHeaders() },
|
|
188
|
+
body: JSON.stringify({ appName, version, entry }),
|
|
189
|
+
});
|
|
190
|
+
if (!res.ok) {
|
|
191
|
+
const text = await res.text();
|
|
192
|
+
throw new Error(`App update failed (${res.status}): ${text.slice(0, 1024)}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// First deploy only: decide whether the app is born public or private. The
|
|
196
|
+
// choice is passed to the register endpoint (default private). Non-interactive
|
|
197
|
+
// runs (--json or no TTY) always default to private.
|
|
198
|
+
async function resolveFirstDeployVisibility(appName, json) {
|
|
199
|
+
if (json || !process.stdout.isTTY) {
|
|
200
|
+
return 'private';
|
|
201
|
+
}
|
|
202
|
+
const rl = node_readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
203
|
+
const answer = await new Promise(resolve => {
|
|
204
|
+
rl.question(`Make "${appName}" public to all monday.com employees? (y/N) `, resolve);
|
|
205
|
+
});
|
|
206
|
+
rl.close();
|
|
207
|
+
return answer.trim().toLowerCase() === 'y' ? 'public' : 'private';
|
|
208
|
+
}
|
|
209
|
+
// best-effort — the 2-min TTL backstop handles failures
|
|
114
210
|
async function releaseLockBestEffort(appName, token) {
|
|
115
211
|
try {
|
|
116
|
-
await fetch(`${constants.brokerBaseUrl()}/z2h-cli/lock/release`, {
|
|
212
|
+
const res = await fetch(`${constants.brokerBaseUrl()}/z2h-cli/lock/release`, {
|
|
117
213
|
method: 'POST',
|
|
118
|
-
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
214
|
+
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', ...constants.routingHeaders() },
|
|
119
215
|
body: JSON.stringify({ appName }),
|
|
120
216
|
});
|
|
217
|
+
if (!res.ok) {
|
|
218
|
+
util_logger.warn(`failed to release lock for ${appName} (${res.status})`);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
121
221
|
util_logger.info(`lock released for ${appName}`);
|
|
122
222
|
}
|
|
123
223
|
catch {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/commands/edit.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+CxF"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
|
+
const util_logger = require('../util/logger.js');
|
|
6
|
+
const util_workspace = require('../util/workspace.js');
|
|
7
|
+
const util_appName = require('../util/app-name.js');
|
|
8
|
+
const util_broker_app = require('../util/broker/app.js');
|
|
9
|
+
const util_git_gitEnv = require('../util/git/git-env.js');
|
|
10
|
+
const util_git_repo = require('../util/git/repo.js');
|
|
11
|
+
const util_npm_install = require('../util/npm/install.js');
|
|
12
|
+
const shadow_prepare = require('../shadow/prepare.js');
|
|
13
|
+
|
|
14
|
+
const _interopDefault = e => e && e.__esModule ? e : { default: e };
|
|
15
|
+
|
|
16
|
+
const path__default = /*#__PURE__*/_interopDefault(path);
|
|
17
|
+
|
|
18
|
+
async function editCommand(appName, opts = {}) {
|
|
19
|
+
if (opts.json) {
|
|
20
|
+
util_logger.setOutputMode('json');
|
|
21
|
+
}
|
|
22
|
+
const workspace = await util_workspace.assertWorkspace();
|
|
23
|
+
const mfName = util_appName.mfAppName(appName);
|
|
24
|
+
const app = await util_broker_app.fetchApp(mfName);
|
|
25
|
+
if (!app?.gitRemote) {
|
|
26
|
+
util_logger.output(`[z2h-cli] ${appName} was deployed without git tracking — run "z2h-cli deploy" to set up a git remote`, {
|
|
27
|
+
ok: true,
|
|
28
|
+
appName,
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const { gitRemote } = app;
|
|
33
|
+
const gitEnv = await util_git_gitEnv.resolveGitEnv(mfName, gitRemote);
|
|
34
|
+
const appDir = path__default.default.join(workspace, appName);
|
|
35
|
+
const hasLocal = await fs.pathExists(appDir);
|
|
36
|
+
if (!hasLocal) {
|
|
37
|
+
util_logger.info(`cloning ${appName}...`);
|
|
38
|
+
await util_git_repo.cloneRepo(gitRemote, appDir, gitEnv);
|
|
39
|
+
util_logger.info(`installing dependencies for ${appName}...`);
|
|
40
|
+
await util_npm_install.runYarnInstall({ cwd: workspace });
|
|
41
|
+
// Best-effort workspace wiring (.zth shadow). Non-fatal — dev/deploy re-run it.
|
|
42
|
+
try {
|
|
43
|
+
await shadow_prepare.prepareShadow(appDir);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
util_logger.warn(`prepare shadow failed: ${err.message} — it will run again when needed.`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
util_logger.info(`pulling latest ${appName}...`);
|
|
51
|
+
await util_git_repo.pullAndResolve(appDir, gitEnv);
|
|
52
|
+
}
|
|
53
|
+
util_logger.output(`[z2h-cli] ${appName} is ready at ${appDir}`, {
|
|
54
|
+
ok: true,
|
|
55
|
+
appDir,
|
|
56
|
+
appName,
|
|
57
|
+
gitRemote,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
exports.editCommand = editCommand;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface GrantOptions {
|
|
2
|
+
public?: boolean;
|
|
3
|
+
level?: 'owner' | 'editor' | 'viewer';
|
|
4
|
+
json?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function grantCommand(email: string | undefined, opts: GrantOptions): Promise<void>;
|
|
7
|
+
export declare function revokeCommand(email: string | undefined, opts: GrantOptions): Promise<void>;
|
|
8
|
+
export interface TransferOwnerOptions {
|
|
9
|
+
json?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function transferOwnerCommand(email: string | undefined, opts: TransferOwnerOptions): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=grant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../src/commands/grant.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACtC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAkBD,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B/F;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BhG;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB/G"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const util_logger = require('../util/logger.js');
|
|
4
|
+
const util_appName = require('../util/app-name.js');
|
|
5
|
+
const constants = require('../constants.js');
|
|
6
|
+
const util_auth_authStore = require('../util/auth/auth-store.js');
|
|
7
|
+
|
|
8
|
+
async function postGrant(appName, token, body) {
|
|
9
|
+
const res = await fetch(`${constants.brokerBaseUrl()}/z2h-apps/${appName}/grants`, {
|
|
10
|
+
method: 'POST',
|
|
11
|
+
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', ...constants.routingHeaders() },
|
|
12
|
+
body: JSON.stringify(body),
|
|
13
|
+
});
|
|
14
|
+
if (!res.ok) {
|
|
15
|
+
const text = await res.text();
|
|
16
|
+
throw new Error(`Grant failed (${res.status}): ${text.slice(0, 1024)}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function grantCommand(email, opts) {
|
|
20
|
+
if (opts.json) {
|
|
21
|
+
util_logger.setOutputMode('json');
|
|
22
|
+
}
|
|
23
|
+
if (!opts.public && !email) {
|
|
24
|
+
throw new Error('Specify what to grant — e.g. --public or provide an email');
|
|
25
|
+
}
|
|
26
|
+
const level = opts.level ?? 'viewer';
|
|
27
|
+
if (!['owner', 'editor', 'viewer'].includes(level)) {
|
|
28
|
+
throw new Error(`Invalid --level "${level}". Must be owner, editor, or viewer`);
|
|
29
|
+
}
|
|
30
|
+
const appName = util_appName.mfAppName(util_appName.getCwdAppName());
|
|
31
|
+
const { token } = await util_auth_authStore.readZthAuth();
|
|
32
|
+
if (email) {
|
|
33
|
+
await postGrant(appName, token, { type: 'user', value: email, accessLevel: level });
|
|
34
|
+
}
|
|
35
|
+
if (opts.public) {
|
|
36
|
+
await postGrant(appName, token, { type: 'global', accessLevel: 'viewer' });
|
|
37
|
+
}
|
|
38
|
+
const parts = [];
|
|
39
|
+
if (email) {
|
|
40
|
+
parts.push(`${email} (${level})`);
|
|
41
|
+
}
|
|
42
|
+
if (opts.public) {
|
|
43
|
+
parts.push('public');
|
|
44
|
+
}
|
|
45
|
+
util_logger.output(`[z2h-cli] "${appName}" granted to: ${parts.join(', ')}`, { ok: true, appName, granted: parts });
|
|
46
|
+
}
|
|
47
|
+
async function revokeCommand(email, opts) {
|
|
48
|
+
if (opts.json) {
|
|
49
|
+
util_logger.setOutputMode('json');
|
|
50
|
+
}
|
|
51
|
+
if (!opts.public && !email) {
|
|
52
|
+
throw new Error('Specify what to revoke — e.g. --public or provide an email');
|
|
53
|
+
}
|
|
54
|
+
const appName = util_appName.mfAppName(util_appName.getCwdAppName());
|
|
55
|
+
const { token } = await util_auth_authStore.readZthAuth();
|
|
56
|
+
const target = email ? `user/${encodeURIComponent(email)}` : 'global';
|
|
57
|
+
const res = await fetch(`${constants.brokerBaseUrl()}/z2h-apps/${appName}/grants/${target}`, {
|
|
58
|
+
method: 'DELETE',
|
|
59
|
+
headers: { Authorization: `Bearer ${token}`, ...constants.routingHeaders() },
|
|
60
|
+
});
|
|
61
|
+
if (!res.ok) {
|
|
62
|
+
const text = await res.text();
|
|
63
|
+
throw new Error(`Revoke failed (${res.status}): ${text.slice(0, 1024)}`);
|
|
64
|
+
}
|
|
65
|
+
const revoked = email ?? 'public';
|
|
66
|
+
const msg = email
|
|
67
|
+
? `[z2h-cli] "${appName}" access revoked from ${email}`
|
|
68
|
+
: `[z2h-cli] "${appName}" is now private (owners/admins only)`;
|
|
69
|
+
util_logger.output(msg, { ok: true, appName, revoked });
|
|
70
|
+
}
|
|
71
|
+
async function transferOwnerCommand(email, opts) {
|
|
72
|
+
if (opts.json) {
|
|
73
|
+
util_logger.setOutputMode('json');
|
|
74
|
+
}
|
|
75
|
+
if (!email) {
|
|
76
|
+
throw new Error('Specify the new owner — e.g. z2h-cli transfer-owner someone@monday.com');
|
|
77
|
+
}
|
|
78
|
+
const appName = util_appName.mfAppName(util_appName.getCwdAppName());
|
|
79
|
+
const { token } = await util_auth_authStore.readZthAuth();
|
|
80
|
+
const res = await fetch(`${constants.brokerBaseUrl()}/z2h-apps/${appName}/transfer-owner`, {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', ...constants.routingHeaders() },
|
|
83
|
+
body: JSON.stringify({ email }),
|
|
84
|
+
});
|
|
85
|
+
if (!res.ok) {
|
|
86
|
+
const text = await res.text();
|
|
87
|
+
throw new Error(`Transfer owner failed (${res.status}): ${text.slice(0, 1024)}`);
|
|
88
|
+
}
|
|
89
|
+
util_logger.output(`[z2h-cli] "${appName}" ownership transferred to ${email}`, { ok: true, appName, newOwner: email });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
exports.grantCommand = grantCommand;
|
|
93
|
+
exports.revokeCommand = revokeCommand;
|
|
94
|
+
exports.transferOwnerCommand = transferOwnerCommand;
|
package/dist/constants.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export declare const DEFAULT_BROKER_BASE_URL = "https://bigbrain-zth.bigbrain.me
|
|
|
23
23
|
* STS credential provider and the npm-broker registry URL.
|
|
24
24
|
*/
|
|
25
25
|
export declare function brokerBaseUrl(): string;
|
|
26
|
+
export declare function routingHeaders(): Record<string, string>;
|
|
26
27
|
export declare const NPM_BROKER_PATH = "/z2h-cli/npm";
|
|
27
28
|
export declare const BROKER_NPM_SCOPE = "@mondaydotcomorg";
|
|
28
29
|
export declare const PUBLIC_NPM_REGISTRY_URL = "https://registry.npmjs.org/";
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,eAAe,SAAS,CAAC;AAGtC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGjD,CAAC;AAQF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAElD,CAAC;AAMF,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAC9B,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAG9B,eAAO,MAAM,iBAAiB,UAAY,CAAC;AAQ3C,eAAO,MAAM,iBAAiB,qCAAqC,CAAC;AACpE,eAAO,MAAM,MAAM,cAAc,CAAC;AAClC,eAAO,MAAM,gBAAgB,wEAA4D,CAAC;AAE1F,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAC7D,eAAO,MAAM,mBAAmB,+CAAgD,CAAC;AAKjF,eAAO,MAAM,YAAY,cAAc,CAAC;AACxC,eAAO,MAAM,iBAAiB,yDAA2C,CAAC;AAM1E,eAAO,MAAM,gBAAgB,QAA2B,CAAC;AAKzD,eAAO,MAAM,uBAAuB,qCAAqC,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAKD,eAAO,MAAM,eAAe,iBAAiB,CAAC;AAG9C,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAGnD,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AAMrE,eAAO,MAAM,iBAAiB,EAAG,eAAwB,CAAC;AAE1D;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,eAAe,SAAS,CAAC;AAGtC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGjD,CAAC;AAQF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAElD,CAAC;AAMF,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAC9B,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAG9B,eAAO,MAAM,iBAAiB,UAAY,CAAC;AAQ3C,eAAO,MAAM,iBAAiB,qCAAqC,CAAC;AACpE,eAAO,MAAM,MAAM,cAAc,CAAC;AAClC,eAAO,MAAM,gBAAgB,wEAA4D,CAAC;AAE1F,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAC7D,eAAO,MAAM,mBAAmB,+CAAgD,CAAC;AAKjF,eAAO,MAAM,YAAY,cAAc,CAAC;AACxC,eAAO,MAAM,iBAAiB,yDAA2C,CAAC;AAM1E,eAAO,MAAM,gBAAgB,QAA2B,CAAC;AAKzD,eAAO,MAAM,uBAAuB,qCAAqC,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAID,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGvD;AAKD,eAAO,MAAM,eAAe,iBAAiB,CAAC;AAG9C,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAGnD,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AAMrE,eAAO,MAAM,iBAAiB,EAAG,eAAwB,CAAC;AAE1D;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C"}
|
package/dist/constants.js
CHANGED
|
@@ -60,6 +60,12 @@ const DEFAULT_BROKER_BASE_URL = 'https://bigbrain-zth.bigbrain.me';
|
|
|
60
60
|
function brokerBaseUrl() {
|
|
61
61
|
return process.env.Z2H_BROKER_BASE_URL || DEFAULT_BROKER_BASE_URL;
|
|
62
62
|
}
|
|
63
|
+
// Returns Baggage header for monday-mirror routing when Z2H_ROUTING_KEY is set.
|
|
64
|
+
// No-op in production (returns {}) — only activates when the env var is set.
|
|
65
|
+
function routingHeaders() {
|
|
66
|
+
const key = process.env.Z2H_ROUTING_KEY;
|
|
67
|
+
return key ? { Baggage: `routingKey=${key}` } : {};
|
|
68
|
+
}
|
|
63
69
|
// The authenticated npm reverse-proxy is mounted here on the broker. Only the
|
|
64
70
|
// `@mondaydotcomorg` scope is served; everything else resolves from npmjs
|
|
65
71
|
// directly. See docs/superpowers/specs/2026-06-03-npm-brokering-design.md §3.
|
|
@@ -104,3 +110,4 @@ exports.SHADOW_SCRIPTS = SHADOW_SCRIPTS;
|
|
|
104
110
|
exports.Z2H_NPM_TOKEN_ENV = Z2H_NPM_TOKEN_ENV;
|
|
105
111
|
exports.brokerBaseUrl = brokerBaseUrl;
|
|
106
112
|
exports.brokerNpmRegistryUrl = brokerNpmRegistryUrl;
|
|
113
|
+
exports.routingHeaders = routingHeaders;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.test.d.ts","sourceRoot":"","sources":["../../../../src/commands/__tests__/edit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export type RemoteType
|
|
1
|
+
import { REMOTE_TYPES, type RemoteType } from '../util/git/remote-options';
|
|
2
|
+
export { REMOTE_TYPES, type RemoteType };
|
|
3
3
|
export interface CreateOptions {
|
|
4
4
|
template?: string;
|
|
5
5
|
htmlFile?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/create.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAA2C,MAAM,4BAA4B,CAAC;AAKpH,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA6BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkG5F"}
|