@mondaydotcomorg/z2h-cli 0.34.1 → 0.34.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2969 -0
- package/dist/backend/__tests__/ast.test.d.ts +2 -0
- package/dist/backend/__tests__/ast.test.d.ts.map +1 -0
- package/dist/backend/__tests__/parse.test.d.ts +2 -0
- package/dist/backend/__tests__/parse.test.d.ts.map +1 -0
- package/dist/backend/ast.d.ts +41 -0
- package/dist/backend/ast.d.ts.map +1 -0
- package/dist/backend/ast.js +152 -0
- package/dist/backend/handler-declaration.d.ts +17 -0
- package/dist/backend/handler-declaration.d.ts.map +1 -0
- package/dist/backend/handler-declaration.js +83 -0
- package/dist/backend/messages.d.ts +10 -0
- package/dist/backend/messages.d.ts.map +1 -0
- package/dist/backend/messages.js +14 -0
- package/dist/backend/parse.d.ts +11 -0
- package/dist/backend/parse.d.ts.map +1 -0
- package/dist/backend/parse.js +66 -0
- package/dist/backend/rules/__tests__/snowflake-static-sql.test.d.ts +2 -0
- package/dist/backend/rules/__tests__/snowflake-static-sql.test.d.ts.map +1 -0
- package/dist/backend/rules/index.d.ts +5 -0
- package/dist/backend/rules/index.d.ts.map +1 -0
- package/dist/backend/rules/index.js +8 -0
- package/dist/backend/rules/snowflake-static-sql.d.ts +15 -0
- package/dist/backend/rules/snowflake-static-sql.d.ts.map +1 -0
- package/dist/backend/rules/snowflake-static-sql.js +75 -0
- package/dist/backend/rules/types.d.ts +29 -0
- package/dist/backend/rules/types.d.ts.map +1 -0
- package/dist/backend/rules/types.js +1 -0
- package/dist/commands/__tests__/delete.test.d.ts +2 -0
- package/dist/commands/__tests__/delete.test.d.ts.map +1 -0
- package/dist/commands/backend.d.ts +0 -1
- package/dist/commands/backend.d.ts.map +1 -1
- package/dist/commands/backend.js +4 -4
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +7 -5
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +12 -0
- package/dist/esm/backend/__tests__/ast.test.d.ts +2 -0
- package/dist/esm/backend/__tests__/ast.test.d.ts.map +1 -0
- package/dist/esm/backend/__tests__/parse.test.d.ts +2 -0
- package/dist/esm/backend/__tests__/parse.test.d.ts.map +1 -0
- package/dist/esm/backend/ast.d.ts +41 -0
- package/dist/esm/backend/ast.d.ts.map +1 -0
- package/dist/esm/backend/ast.mjs +146 -0
- package/dist/esm/backend/handler-declaration.d.ts +17 -0
- package/dist/esm/backend/handler-declaration.d.ts.map +1 -0
- package/dist/esm/backend/handler-declaration.mjs +78 -0
- package/dist/esm/backend/messages.d.ts +10 -0
- package/dist/esm/backend/messages.d.ts.map +1 -0
- package/dist/esm/backend/messages.mjs +12 -0
- package/dist/esm/backend/parse.d.ts +11 -0
- package/dist/esm/backend/parse.d.ts.map +1 -0
- package/dist/esm/backend/parse.mjs +64 -0
- package/dist/esm/backend/rules/__tests__/snowflake-static-sql.test.d.ts +2 -0
- package/dist/esm/backend/rules/__tests__/snowflake-static-sql.test.d.ts.map +1 -0
- package/dist/esm/backend/rules/index.d.ts +5 -0
- package/dist/esm/backend/rules/index.d.ts.map +1 -0
- package/dist/esm/backend/rules/index.mjs +6 -0
- package/dist/esm/backend/rules/snowflake-static-sql.d.ts +15 -0
- package/dist/esm/backend/rules/snowflake-static-sql.d.ts.map +1 -0
- package/dist/esm/backend/rules/snowflake-static-sql.mjs +73 -0
- package/dist/esm/backend/rules/types.d.ts +29 -0
- package/dist/esm/backend/rules/types.d.ts.map +1 -0
- package/dist/esm/backend/rules/types.mjs +1 -0
- package/dist/esm/commands/__tests__/delete.test.d.ts +2 -0
- package/dist/esm/commands/__tests__/delete.test.d.ts.map +1 -0
- package/dist/esm/commands/backend.d.ts +0 -1
- package/dist/esm/commands/backend.d.ts.map +1 -1
- package/dist/esm/commands/backend.mjs +4 -4
- package/dist/esm/commands/deploy.d.ts.map +1 -1
- package/dist/esm/commands/deploy.mjs +7 -5
- package/dist/esm/constants.d.ts +2 -1
- package/dist/esm/constants.d.ts.map +1 -1
- package/dist/esm/constants.mjs +5 -2
- package/dist/esm/util/__tests__/usage-upload.test.d.ts +2 -0
- package/dist/esm/util/__tests__/usage-upload.test.d.ts.map +1 -0
- package/dist/esm/util/auth/__tests__/index.test.d.ts +2 -0
- package/dist/esm/util/auth/__tests__/index.test.d.ts.map +1 -0
- package/dist/esm/util/auth/broker-credential-provider.d.ts +6 -1
- package/dist/esm/util/auth/broker-credential-provider.d.ts.map +1 -1
- package/dist/esm/util/auth/broker-credential-provider.mjs +2 -2
- package/dist/esm/util/auth/index.d.ts +3 -0
- package/dist/esm/util/auth/index.d.ts.map +1 -0
- package/dist/esm/util/auth/index.mjs +2 -0
- package/dist/esm/util/broker/app.d.ts +0 -1
- package/dist/esm/util/broker/app.d.ts.map +1 -1
- package/dist/esm/util/broker/app.mjs +3 -4
- package/dist/esm/util/usage-json.d.ts +2 -2
- package/dist/esm/util/usage-json.d.ts.map +1 -1
- package/dist/esm/util/usage-json.mjs +5 -2
- package/dist/esm/util/usage-upload.d.ts +3 -0
- package/dist/esm/util/usage-upload.d.ts.map +1 -0
- package/dist/esm/util/usage-upload.mjs +29 -0
- package/dist/util/__tests__/usage-upload.test.d.ts +2 -0
- package/dist/util/__tests__/usage-upload.test.d.ts.map +1 -0
- package/dist/util/auth/__tests__/index.test.d.ts +2 -0
- package/dist/util/auth/__tests__/index.test.d.ts.map +1 -0
- package/dist/util/auth/broker-credential-provider.d.ts +6 -1
- package/dist/util/auth/broker-credential-provider.d.ts.map +1 -1
- package/dist/util/auth/broker-credential-provider.js +2 -2
- package/dist/util/auth/index.d.ts +3 -0
- package/dist/util/auth/index.d.ts.map +1 -0
- package/dist/util/auth/index.js +11 -0
- package/dist/util/broker/app.d.ts +0 -1
- package/dist/util/broker/app.d.ts.map +1 -1
- package/dist/util/broker/app.js +3 -4
- package/dist/util/usage-json.d.ts +2 -2
- package/dist/util/usage-json.d.ts.map +1 -1
- package/dist/util/usage-json.js +5 -2
- package/dist/util/usage-upload.d.ts +3 -0
- package/dist/util/usage-upload.d.ts.map +1 -0
- package/dist/util/usage-upload.js +31 -0
- package/package.json +3 -3
- package/src/commands/__tests__/backend-deploy.test.ts +2 -4
- package/src/commands/__tests__/deploy.test.ts +43 -11
- package/src/commands/backend.ts +4 -5
- package/src/commands/deploy.ts +9 -5
- package/src/constants.ts +6 -0
- package/src/util/__tests__/usage-upload.test.ts +58 -0
- package/src/util/auth/__tests__/broker-credential-provider.test.ts +4 -4
- package/src/util/auth/broker-credential-provider.ts +4 -4
- package/src/util/broker/app.ts +2 -15
- package/src/util/usage-json.ts +11 -4
- package/src/util/usage-upload.ts +38 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { simple } from 'acorn-walk';
|
|
2
|
+
import { lineOf } from '../ast.mjs';
|
|
3
|
+
|
|
4
|
+
const SNOWFLAKE_QUERY = 'ctx.api.v1.snowflake.query';
|
|
5
|
+
const message = (file, line) => `${file}${line ? `:${line}` : ''}: ${SNOWFLAKE_QUERY} must receive SQL written in the handler — a string literal, ` +
|
|
6
|
+
`or a variable bound to one. Client-supplied values go through params (\`:name\` bindings) and options, never into the SQL text.`;
|
|
7
|
+
/**
|
|
8
|
+
* True when every possible value of `node` is text authored in this file:
|
|
9
|
+
* string literals, templates whose holes are themselves static, `+`
|
|
10
|
+
* concatenation, either branch of a conditional, and identifiers that resolve
|
|
11
|
+
* (within the file) to such values. Anything reaching outside the file —
|
|
12
|
+
* `ctx.input`, calls, member reads, destructuring — is not static.
|
|
13
|
+
*/
|
|
14
|
+
function isStaticSql(node, bindings, resolving) {
|
|
15
|
+
if (!node) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
const staticChild = (child) => isStaticSql(child, bindings, resolving);
|
|
19
|
+
switch (node.type) {
|
|
20
|
+
case 'Literal':
|
|
21
|
+
return typeof node.value === 'string';
|
|
22
|
+
case 'TemplateLiteral':
|
|
23
|
+
return node.expressions.every(staticChild);
|
|
24
|
+
case 'BinaryExpression':
|
|
25
|
+
return node.operator === '+' && staticChild(node.left) && staticChild(node.right);
|
|
26
|
+
case 'ConditionalExpression':
|
|
27
|
+
return staticChild(node.consequent) && staticChild(node.alternate);
|
|
28
|
+
case 'LogicalExpression':
|
|
29
|
+
return staticChild(node.left) && staticChild(node.right);
|
|
30
|
+
case 'Identifier': {
|
|
31
|
+
const { name } = node;
|
|
32
|
+
if (bindings.unpinnable.has(name) || resolving.has(name)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const decls = bindings.declarations.get(name);
|
|
36
|
+
if (!decls || decls.length === 0) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
const next = new Set(resolving).add(name);
|
|
40
|
+
return decls.every(d => d.path?.length === 0 && isStaticSql(d.init, bindings, next));
|
|
41
|
+
}
|
|
42
|
+
default:
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* `ctx.api.v1.snowflake.query(sql, params?, options?)` — the SQL text must live
|
|
48
|
+
* in the handler. The frontend chooses *which* handler to call and supplies
|
|
49
|
+
* `params` / `options`; it never ships SQL. Binding placeholders (`:name`) are
|
|
50
|
+
* how client values reach the query.
|
|
51
|
+
*
|
|
52
|
+
* The call is matched through `const` aliases of the channel
|
|
53
|
+
* (`const sf = ctx.api.v1.snowflake; sf.query(…)`), see `PathResolver`.
|
|
54
|
+
*/
|
|
55
|
+
class SnowflakeStaticSqlRule {
|
|
56
|
+
name = 'snowflake/static-sql';
|
|
57
|
+
check({ file, program, bindings, paths }) {
|
|
58
|
+
const violations = [];
|
|
59
|
+
simple(program, {
|
|
60
|
+
CallExpression(node) {
|
|
61
|
+
if (paths.pathOf(node.callee) !== SNOWFLAKE_QUERY) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (!isStaticSql(node.arguments[0], bindings, new Set())) {
|
|
65
|
+
violations.push(message(file, lineOf(node)));
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
return violations;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { SnowflakeStaticSqlRule };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Program } from 'acorn';
|
|
2
|
+
import type { Bindings, PathResolver } from '../ast';
|
|
3
|
+
export interface RuleContext {
|
|
4
|
+
/** Handler file name, used to prefix messages. */
|
|
5
|
+
file: string;
|
|
6
|
+
/** Parsed with `locations: true`, so rules can point at a line. */
|
|
7
|
+
program: Program;
|
|
8
|
+
/** Every variable binding in the file — see `collectBindings`. */
|
|
9
|
+
bindings: Bindings;
|
|
10
|
+
/** Resolves member chains through `const` aliases — see `createPathResolver`. */
|
|
11
|
+
paths: PathResolver;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A capability-specific check that runs once the handler is structurally valid
|
|
15
|
+
* (parses as a script, defines `handler`, imports nothing).
|
|
16
|
+
*
|
|
17
|
+
* Rules return human-readable violations rather than throwing so the validator
|
|
18
|
+
* can report every problem in one pass — agent-generated handlers are fixed in
|
|
19
|
+
* a loop, and one round-trip per violation is slow.
|
|
20
|
+
*
|
|
21
|
+
* Implement as a class (see `SnowflakeStaticSqlRule`) and add an instance to
|
|
22
|
+
* `HANDLER_RULES` in `./index.ts` — keeps every rule the same shape to read.
|
|
23
|
+
*/
|
|
24
|
+
export interface HandlerRule {
|
|
25
|
+
/** Stable identifier, e.g. `snowflake/static-sql`. */
|
|
26
|
+
name: string;
|
|
27
|
+
check(ctx: RuleContext): string[];
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/backend/rules/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,OAAO,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,QAAQ,EAAE,QAAQ,CAAC;IACnB,iFAAiF;IACjF,KAAK,EAAE,YAAY,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,EAAE,CAAC;CACnC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.test.d.ts","sourceRoot":"","sources":["../../../../src/commands/__tests__/delete.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../../src/commands/backend.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../../src/commands/backend.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AA+BD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CASrC;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,MAAM,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAe1F;AAsBD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,EAC5C,MAAM,GAAE,MAAsB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -24,14 +24,14 @@ function currentAppName() {
|
|
|
24
24
|
}
|
|
25
25
|
async function readDetectAndUpload(appDir, prefix, appName, version, deployedBy, logLabel) {
|
|
26
26
|
if (!hasHandlers(appDir)) {
|
|
27
|
-
return { integrations: [], handlerNames: []
|
|
27
|
+
return { integrations: [], handlerNames: [] };
|
|
28
28
|
}
|
|
29
29
|
info(`reading backend handlers ${logLabel}`);
|
|
30
|
-
const { handlers, apiDomains
|
|
30
|
+
const { handlers, apiDomains } = await readHandlers(appDir);
|
|
31
31
|
const integrations = detectIntegrations(apiDomains);
|
|
32
32
|
const handlerNames = Object.keys(handlers);
|
|
33
33
|
if (Object.keys(handlers).length === 0) {
|
|
34
|
-
return { integrations, handlerNames
|
|
34
|
+
return { integrations, handlerNames };
|
|
35
35
|
}
|
|
36
36
|
const s3 = getS3Client();
|
|
37
37
|
const meta = JSON.stringify({ version, deployedBy, handlers: Object.keys(handlers) });
|
|
@@ -40,7 +40,7 @@ async function readDetectAndUpload(appDir, prefix, appName, version, deployedBy,
|
|
|
40
40
|
...Object.entries(handlers).map(([name, code]) => put(`${prefix}/${name}.js`, code, 'application/javascript')),
|
|
41
41
|
put(`${prefix}/meta.json`, meta, 'application/json'),
|
|
42
42
|
]);
|
|
43
|
-
return { integrations, handlerNames
|
|
43
|
+
return { integrations, handlerNames };
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
46
|
* Integration sync note: the returned set is re-derived from the CURRENT backend
|
|
@@ -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":"AAoBA,OAAO,EAAE,KAAK,UAAU,EAA2C,MAAM,4BAA4B,CAAC;AAatG,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IAIrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAWD,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB3E"}
|
|
@@ -10,6 +10,7 @@ import { readZthAuth } from '../util/auth/auth-store.mjs';
|
|
|
10
10
|
import { validateAppName, cleanAppName, mfAppName, buildPreviewSlug } from '../util/app-name.mjs';
|
|
11
11
|
import { getRemoteUrl, initRepo, guardCleanTree, pullAndResolve, pushToRemote } from '../util/git/repo.mjs';
|
|
12
12
|
import { updateOrCreateUsageJson } from '../util/usage-json.mjs';
|
|
13
|
+
import { putAppUsage } from '../util/usage-upload.mjs';
|
|
13
14
|
import { resolveGitEnv } from '../util/git/git-env.mjs';
|
|
14
15
|
import { validateRemoteOptions, resolveRemoteUrl } from '../util/git/remote-options.mjs';
|
|
15
16
|
import { setupS3Client } from '../util/s3/client.mjs';
|
|
@@ -83,7 +84,7 @@ async function uploadAndRegister(opts) {
|
|
|
83
84
|
const { paths, keyPrefix, appName, token, nextVersion, entry, gitRemote, isPreview, description, masterAppName } = opts;
|
|
84
85
|
// Runs before the frontend upload so a `deployBackend` failure can't leave a
|
|
85
86
|
// preview's unversioned `MF` dir overwritten with no rollback.
|
|
86
|
-
const { integrations, handlerNames
|
|
87
|
+
const { integrations, handlerNames } = await deployBackend({
|
|
87
88
|
appDir: process.cwd(),
|
|
88
89
|
appName,
|
|
89
90
|
mfKeyPrefix: keyPrefix,
|
|
@@ -102,7 +103,6 @@ async function uploadAndRegister(opts) {
|
|
|
102
103
|
gitRemote,
|
|
103
104
|
integrations,
|
|
104
105
|
handlerNames,
|
|
105
|
-
apiUsages,
|
|
106
106
|
description,
|
|
107
107
|
masterAppName,
|
|
108
108
|
});
|
|
@@ -136,7 +136,7 @@ async function deployPreview({ paths, consumerName, appName, token, opts }) {
|
|
|
136
136
|
const url = `${BUCKET_READ_DNS_URL}/${keyPrefix}`;
|
|
137
137
|
// No catch-all: every stage below tags its own DeployError reason at the throw site,
|
|
138
138
|
// and anything unclassified reports as `unknown` via reasonOf() in runCommand.
|
|
139
|
-
const nextVersion = (await fetchDeployVersion(previewAppName)) + 1;
|
|
139
|
+
const nextVersion = (await fetchDeployVersion(previewAppName)).version + 1;
|
|
140
140
|
info('building');
|
|
141
141
|
const entry = await buildAndStamp({
|
|
142
142
|
paths,
|
|
@@ -201,9 +201,10 @@ async function deployLive({ paths, consumerName, appName, token, opts }) {
|
|
|
201
201
|
await initRepo(process.cwd(), remote);
|
|
202
202
|
gitRemote = remote;
|
|
203
203
|
}
|
|
204
|
-
const version = await fetchDeployVersion(appName);
|
|
204
|
+
const { version, id: appId } = await fetchDeployVersion(appName);
|
|
205
205
|
const nextVersion = version + 1;
|
|
206
206
|
const gitEnv = await resolveGitEnv(appName, gitRemote);
|
|
207
|
+
let usage = {};
|
|
207
208
|
// Sync git first so a divergence (GitConflictError) stops us.
|
|
208
209
|
// The skill commits the working tree (with an LLM-authored message) before
|
|
209
210
|
// invoking deploy, so the tree should be clean here.
|
|
@@ -212,7 +213,7 @@ async function deployLive({ paths, consumerName, appName, token, opts }) {
|
|
|
212
213
|
await guardCleanTree(process.cwd());
|
|
213
214
|
info('syncing with git remote');
|
|
214
215
|
await pullAndResolve(process.cwd(), gitEnv);
|
|
215
|
-
await updateOrCreateUsageJson(process.cwd(), appName, whoAmI());
|
|
216
|
+
usage = await updateOrCreateUsageJson(process.cwd(), appName, whoAmI());
|
|
216
217
|
}
|
|
217
218
|
catch (err) {
|
|
218
219
|
throw tagDeployError('git_error', err);
|
|
@@ -269,6 +270,7 @@ async function deployLive({ paths, consumerName, appName, token, opts }) {
|
|
|
269
270
|
info('releasing deploy lock');
|
|
270
271
|
await releaseLockBestEffort(appName, token);
|
|
271
272
|
}
|
|
273
|
+
await putAppUsage(appName, appId, usage, nextVersion);
|
|
272
274
|
// Tags are a post-deploy concern: the S3 upload has already succeeded, so a
|
|
273
275
|
// tag failure never fails the deploy (handled inside).
|
|
274
276
|
await handleDeployTags(appName);
|
package/dist/esm/constants.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare const SHADOW_DEV_DEPS: Record<string, string>;
|
|
|
8
8
|
export declare const MIN_PORT = 13000;
|
|
9
9
|
export declare const MAX_PORT = 19999;
|
|
10
10
|
export declare const GITIGNORE_ENTRIES: string[];
|
|
11
|
-
export { ALWAYS_ON_CHANNELS, APP_NAME_PATTERN, BUCKET_READ_DNS_NAME, BUCKET_READ_DNS_URL, BUCKET_WRITE_NAME, BUCKET_WRITE_URL, DATAVIZ_SKILLS_PREFIX, DECLARED_INTEGRATIONS, MANIFEST_KEY, MANIFEST_READ_URL, PREVIEW_APP_NAME_PREFIX, REGION, S3_PREVIEWS_FOLDER, S3_SKILLS_BUCKET_NAME, type DeclaredIntegration, } from '@mondaydotcomorg/z2h-shared-utils';
|
|
11
|
+
export { ALWAYS_ON_CHANNELS, APP_USAGE_BUCKET_NAME, appUsageFolder, APP_NAME_PATTERN, BUCKET_READ_DNS_NAME, BUCKET_READ_DNS_URL, BUCKET_WRITE_NAME, BUCKET_WRITE_URL, DATAVIZ_SKILLS_PREFIX, DECLARED_INTEGRATIONS, MANIFEST_KEY, MANIFEST_READ_URL, PREVIEW_APP_NAME_PREFIX, REGION, S3_PREVIEWS_FOLDER, S3_SKILLS_BUCKET_NAME, type DeclaredIntegration, } from '@mondaydotcomorg/z2h-shared-utils';
|
|
12
12
|
export declare const DEFAULT_BROKER_BASE_URL = "https://bigbrain-zth.bigbrain.me";
|
|
13
13
|
/**
|
|
14
14
|
* Resolves the broker origin (no trailing slash). Honors
|
|
@@ -16,6 +16,7 @@ export declare const DEFAULT_BROKER_BASE_URL = "https://bigbrain-zth.bigbrain.me
|
|
|
16
16
|
* STS credential provider and the npm-broker registry URL.
|
|
17
17
|
*/
|
|
18
18
|
export declare function brokerBaseUrl(): string;
|
|
19
|
+
export declare function isProdBroker(): boolean;
|
|
19
20
|
export declare function routingHeaders(): Record<string, string>;
|
|
20
21
|
export declare const NPM_BROKER_PATH = "/z2h-cli/npm";
|
|
21
22
|
export declare const BROKER_NPM_SCOPE = "@mondaydotcomorg";
|
|
@@ -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,CAEjD,CAAC;AAKF,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;AAI3C,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,uBAAuB,EACvB,MAAM,EACN,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,mBAAmB,GACzB,MAAM,mCAAmC,CAAC;AAK3C,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"}
|
|
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,CAEjD,CAAC;AAKF,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;AAI3C,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,uBAAuB,EACvB,MAAM,EACN,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,mBAAmB,GACzB,MAAM,mCAAmC,CAAC;AAK3C,eAAO,MAAM,uBAAuB,qCAAqC,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,YAAY,IAAI,OAAO,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/esm/constants.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ALWAYS_ON_CHANNELS, APP_NAME_PATTERN, BUCKET_READ_DNS_NAME, BUCKET_READ_DNS_URL, BUCKET_WRITE_NAME, BUCKET_WRITE_URL, DATAVIZ_SKILLS_PREFIX, DECLARED_INTEGRATIONS, MANIFEST_KEY, MANIFEST_READ_URL, PREVIEW_APP_NAME_PREFIX, REGION, S3_PREVIEWS_FOLDER, S3_SKILLS_BUCKET_NAME } from '@mondaydotcomorg/z2h-shared-utils';
|
|
1
|
+
export { ALWAYS_ON_CHANNELS, APP_NAME_PATTERN, APP_USAGE_BUCKET_NAME, BUCKET_READ_DNS_NAME, BUCKET_READ_DNS_URL, BUCKET_WRITE_NAME, BUCKET_WRITE_URL, DATAVIZ_SKILLS_PREFIX, DECLARED_INTEGRATIONS, MANIFEST_KEY, MANIFEST_READ_URL, PREVIEW_APP_NAME_PREFIX, REGION, S3_PREVIEWS_FOLDER, S3_SKILLS_BUCKET_NAME, appUsageFolder } from '@mondaydotcomorg/z2h-shared-utils';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Cross-file constants. Narrowly-used literals (templates, prefixes used in
|
|
@@ -36,6 +36,9 @@ const DEFAULT_BROKER_BASE_URL = 'https://bigbrain-zth.bigbrain.me';
|
|
|
36
36
|
function brokerBaseUrl() {
|
|
37
37
|
return process.env.Z2H_BROKER_BASE_URL || DEFAULT_BROKER_BASE_URL;
|
|
38
38
|
}
|
|
39
|
+
function isProdBroker() {
|
|
40
|
+
return brokerBaseUrl() === DEFAULT_BROKER_BASE_URL;
|
|
41
|
+
}
|
|
39
42
|
// Returns Baggage header for monday-mirror routing when Z2H_ROUTING_KEY is set.
|
|
40
43
|
// No-op in production (returns {}) — only activates when the env var is set.
|
|
41
44
|
function routingHeaders() {
|
|
@@ -65,4 +68,4 @@ function brokerNpmRegistryUrl() {
|
|
|
65
68
|
return `${brokerBaseUrl()}${NPM_BROKER_PATH}`;
|
|
66
69
|
}
|
|
67
70
|
|
|
68
|
-
export { BROKER_NPM_SCOPE, DEFAULT_BROKER_BASE_URL, GITIGNORE_ENTRIES, MAX_PORT, MIN_PORT, NPM_BROKER_PATH, PUBLIC_NPM_REGISTRY_URL, SHADOW_DEV_DEPS, SHADOW_DIR_NAME, SHADOW_SCRIPTS, Z2H_NPM_TOKEN_ENV, brokerBaseUrl, brokerNpmRegistryUrl, routingHeaders };
|
|
71
|
+
export { BROKER_NPM_SCOPE, DEFAULT_BROKER_BASE_URL, GITIGNORE_ENTRIES, MAX_PORT, MIN_PORT, NPM_BROKER_PATH, PUBLIC_NPM_REGISTRY_URL, SHADOW_DEV_DEPS, SHADOW_DIR_NAME, SHADOW_SCRIPTS, Z2H_NPM_TOKEN_ENV, brokerBaseUrl, brokerNpmRegistryUrl, isProdBroker, routingHeaders };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-upload.test.d.ts","sourceRoot":"","sources":["../../../../src/util/__tests__/usage-upload.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../../../src/util/auth/__tests__/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type { AwsCredentialIdentityProvider } from '@aws-sdk/types';
|
|
2
2
|
export declare const STS_BROKER_PATH = "/z2h-cli/sts/credentials";
|
|
3
3
|
export declare const DEPLOY_VERSION_PATH = "/z2h-cli/apps/version";
|
|
4
|
+
interface VersionResponse {
|
|
5
|
+
version?: number;
|
|
6
|
+
id?: number | null;
|
|
7
|
+
}
|
|
4
8
|
/**
|
|
5
9
|
* Reserve the version this deploy will write to. Split out of the STS
|
|
6
10
|
* credentials call so version derivation lives on its own endpoint — the CLI
|
|
7
11
|
* asks for the version first, then requests credentials scoped to it.
|
|
8
12
|
*/
|
|
9
|
-
export declare function fetchDeployVersion(appName: string): Promise<
|
|
13
|
+
export declare function fetchDeployVersion(appName: string): Promise<Required<VersionResponse>>;
|
|
10
14
|
/**
|
|
11
15
|
* AWS SDK credential provider that fetches short-lived credentials from the
|
|
12
16
|
* bigbrain-zth STS broker, scoped to `appName` — or, when `previewId` is
|
|
@@ -19,4 +23,5 @@ export declare function brokerCredentialProvider({ appName, previewId, }: {
|
|
|
19
23
|
appName: string;
|
|
20
24
|
previewId?: string;
|
|
21
25
|
}): AwsCredentialIdentityProvider;
|
|
26
|
+
export {};
|
|
22
27
|
//# sourceMappingURL=broker-credential-provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broker-credential-provider.d.ts","sourceRoot":"","sources":["../../../../src/util/auth/broker-credential-provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAyB,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAE3F,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAC1D,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"broker-credential-provider.d.ts","sourceRoot":"","sources":["../../../../src/util/auth/broker-credential-provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAyB,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAE3F,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAC1D,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAa3D,UAAU,eAAe;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AA2CD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAK5F;AAwDD;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,SAAS,GACV,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,6BAA6B,CAIhC"}
|
|
@@ -49,8 +49,8 @@ async function assertBrokerOk(res, errorLabel) {
|
|
|
49
49
|
async function fetchDeployVersion(appName) {
|
|
50
50
|
const res = await postToBroker(DEPLOY_VERSION_PATH, { appName });
|
|
51
51
|
await assertBrokerOk(res, 'deploy');
|
|
52
|
-
const
|
|
53
|
-
return
|
|
52
|
+
const { version = 0, id = null } = (await res.json());
|
|
53
|
+
return { version, id };
|
|
54
54
|
}
|
|
55
55
|
async function requestSts(path, body, errorLabel) {
|
|
56
56
|
const res = await postToBroker(path, body);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/util/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -30,7 +30,6 @@ export interface RegisterOrUpdateOptions {
|
|
|
30
30
|
gitRemote: string;
|
|
31
31
|
integrations?: string[];
|
|
32
32
|
handlerNames?: string[];
|
|
33
|
-
apiUsages?: Record<string, unknown>;
|
|
34
33
|
description?: string;
|
|
35
34
|
/**
|
|
36
35
|
* The base app a preview is for, sent only on first registration — the link
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../../src/util/broker/app.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACtC,uGAAuG;IACvG,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAsBvE;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhF;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../../src/util/broker/app.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACtC,uGAAuG;IACvG,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAsBvE;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhF;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAkDD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBtF"}
|
|
@@ -48,7 +48,7 @@ async function claimApp(appName, gitRemote) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
async function registerApp(params) {
|
|
51
|
-
const { appName, token, nextVersion: version, entry, visibility, gitRemote, integrations, handlerNames,
|
|
51
|
+
const { appName, token, nextVersion: version, entry, visibility, gitRemote, integrations, handlerNames, description, masterAppName, } = params;
|
|
52
52
|
const res = await fetch(`${brokerBaseUrl()}/z2h-cli/apps/register`, {
|
|
53
53
|
method: 'POST',
|
|
54
54
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', ...routingHeaders() },
|
|
@@ -60,7 +60,6 @@ async function registerApp(params) {
|
|
|
60
60
|
gitRemote,
|
|
61
61
|
integrations,
|
|
62
62
|
handlerNames,
|
|
63
|
-
apiUsages,
|
|
64
63
|
description,
|
|
65
64
|
masterAppName,
|
|
66
65
|
}),
|
|
@@ -72,11 +71,11 @@ async function registerApp(params) {
|
|
|
72
71
|
}
|
|
73
72
|
/** Releases a new version onto an app that already exists. */
|
|
74
73
|
async function updateApp(params) {
|
|
75
|
-
const { appName, token, nextVersion: version, entry, gitRemote, integrations, handlerNames,
|
|
74
|
+
const { appName, token, nextVersion: version, entry, gitRemote, integrations, handlerNames, description } = params;
|
|
76
75
|
const res = await fetch(`${brokerBaseUrl()}/z2h-cli/apps/update`, {
|
|
77
76
|
method: 'POST',
|
|
78
77
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', ...routingHeaders() },
|
|
79
|
-
body: JSON.stringify({ appName, version, entry, gitRemote, integrations, handlerNames,
|
|
78
|
+
body: JSON.stringify({ appName, version, entry, gitRemote, integrations, handlerNames, description }),
|
|
80
79
|
});
|
|
81
80
|
if (!res.ok) {
|
|
82
81
|
const text = await res.text();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare function hasHandlers(appDir: string): boolean;
|
|
2
2
|
/** Other features may add top-level fields, so writes merge into the existing file instead of replacing it. */
|
|
3
|
-
export declare function writeUsageJson(appDir: string, patch: Record<string, unknown>): Promise<
|
|
3
|
+
export declare function writeUsageJson(appDir: string, patch: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
4
4
|
/** Refreshes the git-tracked `usage.json` and commits it if it changed, so a deploy's push carries it. */
|
|
5
|
-
export declare function updateOrCreateUsageJson(appDir: string, appName: string, deployedBy: string): Promise<
|
|
5
|
+
export declare function updateOrCreateUsageJson(appDir: string, appName: string, deployedBy: string): Promise<Record<string, unknown>>;
|
|
6
6
|
//# sourceMappingURL=usage-json.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-json.d.ts","sourceRoot":"","sources":["../../../src/util/usage-json.ts"],"names":[],"mappings":"AAOA,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,+GAA+G;AAC/G,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"usage-json.d.ts","sourceRoot":"","sources":["../../../src/util/usage-json.ts"],"names":[],"mappings":"AAOA,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,+GAA+G;AAC/G,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAarH;AAED,0GAA0G;AAC1G,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CASlC"}
|
|
@@ -20,17 +20,20 @@ async function writeUsageJson(appDir, patch) {
|
|
|
20
20
|
throw err;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
const merged = { ...existing, ...patch };
|
|
24
|
+
await writeJson(file, merged, { spaces: 2 });
|
|
25
|
+
return merged;
|
|
24
26
|
}
|
|
25
27
|
/** Refreshes the git-tracked `usage.json` and commits it if it changed, so a deploy's push carries it. */
|
|
26
28
|
async function updateOrCreateUsageJson(appDir, appName, deployedBy) {
|
|
27
29
|
const apiUsages = hasHandlers(appDir) ? (await readHandlers(appDir)).apiUsages : {};
|
|
28
|
-
await writeUsageJson(appDir, { appName, deployedBy, apiUsages });
|
|
30
|
+
const usage = await writeUsageJson(appDir, { appName, deployedBy, apiUsages });
|
|
29
31
|
await execGit(['add', 'usage.json'], appDir);
|
|
30
32
|
const { exitCode } = await execa('git', ['diff', '--cached', '--quiet'], { cwd: appDir, reject: false });
|
|
31
33
|
if (exitCode !== 0) {
|
|
32
34
|
await execGit(['commit', '-m', 'Update usage.json'], appDir);
|
|
33
35
|
}
|
|
36
|
+
return usage;
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
export { hasHandlers, updateOrCreateUsageJson, writeUsageJson };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Snowpipe ignores re-uploads of an existing key, so the key is unique per app row id and deploy version. */
|
|
2
|
+
export declare function putAppUsage(appName: string, appId: number | null, usage: Record<string, unknown>, uploadVersion: number): Promise<void>;
|
|
3
|
+
//# sourceMappingURL=usage-upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-upload.d.ts","sourceRoot":"","sources":["../../../src/util/usage-upload.ts"],"names":[],"mappings":"AAKA,8GAA8G;AAC9G,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CA0Bf"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { PutObjectCommand } from '@aws-sdk/client-s3';
|
|
2
|
+
import { isProdBroker, brokerBaseUrl } from '../constants.mjs';
|
|
3
|
+
import { warn } from './logger.mjs';
|
|
4
|
+
import { getS3Client } from './s3/client.mjs';
|
|
5
|
+
import { APP_USAGE_BUCKET_NAME, appUsageFolder } from '@mondaydotcomorg/z2h-shared-utils';
|
|
6
|
+
|
|
7
|
+
/** Snowpipe ignores re-uploads of an existing key, so the key is unique per app row id and deploy version. */
|
|
8
|
+
async function putAppUsage(appName, appId, usage, uploadVersion) {
|
|
9
|
+
if (!isProdBroker()) {
|
|
10
|
+
warn(`skipping app usage upload to Snowflake: ${brokerBaseUrl()} is not the production broker, and only production deploys are recorded.`);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (appId === null) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
await getS3Client().send(new PutObjectCommand({
|
|
18
|
+
Bucket: APP_USAGE_BUCKET_NAME,
|
|
19
|
+
Key: `${appUsageFolder(appName, appId)}/${uploadVersion}/usage.json`,
|
|
20
|
+
Body: JSON.stringify({ ...usage, appName, appId, uploadVersion }),
|
|
21
|
+
ContentType: 'application/json',
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
warn(`could not record app usage for Snowflake: ${err.message}. Your app is live. To record it, run \`z2h-cli deploy\` again (no changes or commit needed).`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { putAppUsage };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-upload.test.d.ts","sourceRoot":"","sources":["../../../src/util/__tests__/usage-upload.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../../src/util/auth/__tests__/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type { AwsCredentialIdentityProvider } from '@aws-sdk/types';
|
|
2
2
|
export declare const STS_BROKER_PATH = "/z2h-cli/sts/credentials";
|
|
3
3
|
export declare const DEPLOY_VERSION_PATH = "/z2h-cli/apps/version";
|
|
4
|
+
interface VersionResponse {
|
|
5
|
+
version?: number;
|
|
6
|
+
id?: number | null;
|
|
7
|
+
}
|
|
4
8
|
/**
|
|
5
9
|
* Reserve the version this deploy will write to. Split out of the STS
|
|
6
10
|
* credentials call so version derivation lives on its own endpoint — the CLI
|
|
7
11
|
* asks for the version first, then requests credentials scoped to it.
|
|
8
12
|
*/
|
|
9
|
-
export declare function fetchDeployVersion(appName: string): Promise<
|
|
13
|
+
export declare function fetchDeployVersion(appName: string): Promise<Required<VersionResponse>>;
|
|
10
14
|
/**
|
|
11
15
|
* AWS SDK credential provider that fetches short-lived credentials from the
|
|
12
16
|
* bigbrain-zth STS broker, scoped to `appName` — or, when `previewId` is
|
|
@@ -19,4 +23,5 @@ export declare function brokerCredentialProvider({ appName, previewId, }: {
|
|
|
19
23
|
appName: string;
|
|
20
24
|
previewId?: string;
|
|
21
25
|
}): AwsCredentialIdentityProvider;
|
|
26
|
+
export {};
|
|
22
27
|
//# sourceMappingURL=broker-credential-provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broker-credential-provider.d.ts","sourceRoot":"","sources":["../../../src/util/auth/broker-credential-provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAyB,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAE3F,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAC1D,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"broker-credential-provider.d.ts","sourceRoot":"","sources":["../../../src/util/auth/broker-credential-provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAyB,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAE3F,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAC1D,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAa3D,UAAU,eAAe;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AA2CD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAK5F;AAwDD;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,SAAS,GACV,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,6BAA6B,CAIhC"}
|
|
@@ -51,8 +51,8 @@ async function assertBrokerOk(res, errorLabel) {
|
|
|
51
51
|
async function fetchDeployVersion(appName) {
|
|
52
52
|
const res = await postToBroker(DEPLOY_VERSION_PATH, { appName });
|
|
53
53
|
await assertBrokerOk(res, 'deploy');
|
|
54
|
-
const
|
|
55
|
-
return
|
|
54
|
+
const { version = 0, id = null } = (await res.json());
|
|
55
|
+
return { version, id };
|
|
56
56
|
}
|
|
57
57
|
async function requestSts(path, body, errorLabel) {
|
|
58
58
|
const res = await postToBroker(path, body);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/util/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const util_npm_ensureToken = require('../npm/ensure-token.js');
|
|
4
|
+
const util_auth_authStore = require('./auth-store.js');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
exports.ensureZ2hToken = util_npm_ensureToken.ensureZ2hToken;
|
|
9
|
+
exports.Z2hAuthMissingError = util_auth_authStore.Z2hAuthMissingError;
|
|
10
|
+
exports.readZthAuth = util_auth_authStore.readZthAuth;
|
|
11
|
+
exports.tryReadAuthTokenSync = util_auth_authStore.tryReadAuthTokenSync;
|
|
@@ -30,7 +30,6 @@ export interface RegisterOrUpdateOptions {
|
|
|
30
30
|
gitRemote: string;
|
|
31
31
|
integrations?: string[];
|
|
32
32
|
handlerNames?: string[];
|
|
33
|
-
apiUsages?: Record<string, unknown>;
|
|
34
33
|
description?: string;
|
|
35
34
|
/**
|
|
36
35
|
* The base app a preview is for, sent only on first registration — the link
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../src/util/broker/app.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACtC,uGAAuG;IACvG,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAsBvE;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhF;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../src/util/broker/app.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACtC,uGAAuG;IACvG,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAsBvE;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhF;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAkDD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBtF"}
|
package/dist/util/broker/app.js
CHANGED
|
@@ -50,7 +50,7 @@ async function claimApp(appName, gitRemote) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
async function registerApp(params) {
|
|
53
|
-
const { appName, token, nextVersion: version, entry, visibility, gitRemote, integrations, handlerNames,
|
|
53
|
+
const { appName, token, nextVersion: version, entry, visibility, gitRemote, integrations, handlerNames, description, masterAppName, } = params;
|
|
54
54
|
const res = await fetch(`${constants.brokerBaseUrl()}/z2h-cli/apps/register`, {
|
|
55
55
|
method: 'POST',
|
|
56
56
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', ...constants.routingHeaders() },
|
|
@@ -62,7 +62,6 @@ async function registerApp(params) {
|
|
|
62
62
|
gitRemote,
|
|
63
63
|
integrations,
|
|
64
64
|
handlerNames,
|
|
65
|
-
apiUsages,
|
|
66
65
|
description,
|
|
67
66
|
masterAppName,
|
|
68
67
|
}),
|
|
@@ -74,11 +73,11 @@ async function registerApp(params) {
|
|
|
74
73
|
}
|
|
75
74
|
/** Releases a new version onto an app that already exists. */
|
|
76
75
|
async function updateApp(params) {
|
|
77
|
-
const { appName, token, nextVersion: version, entry, gitRemote, integrations, handlerNames,
|
|
76
|
+
const { appName, token, nextVersion: version, entry, gitRemote, integrations, handlerNames, description } = params;
|
|
78
77
|
const res = await fetch(`${constants.brokerBaseUrl()}/z2h-cli/apps/update`, {
|
|
79
78
|
method: 'POST',
|
|
80
79
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', ...constants.routingHeaders() },
|
|
81
|
-
body: JSON.stringify({ appName, version, entry, gitRemote, integrations, handlerNames,
|
|
80
|
+
body: JSON.stringify({ appName, version, entry, gitRemote, integrations, handlerNames, description }),
|
|
82
81
|
});
|
|
83
82
|
if (!res.ok) {
|
|
84
83
|
const text = await res.text();
|