@mondaydotcomorg/z2h-cli 0.34.0 → 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.
Files changed (133) hide show
  1. package/CHANGELOG.md +2969 -0
  2. package/dist/backend/__tests__/ast.test.d.ts +2 -0
  3. package/dist/backend/__tests__/ast.test.d.ts.map +1 -0
  4. package/dist/backend/__tests__/parse.test.d.ts +2 -0
  5. package/dist/backend/__tests__/parse.test.d.ts.map +1 -0
  6. package/dist/backend/ast.d.ts +41 -0
  7. package/dist/backend/ast.d.ts.map +1 -0
  8. package/dist/backend/ast.js +152 -0
  9. package/dist/backend/handler-declaration.d.ts +17 -0
  10. package/dist/backend/handler-declaration.d.ts.map +1 -0
  11. package/dist/backend/handler-declaration.js +83 -0
  12. package/dist/backend/messages.d.ts +10 -0
  13. package/dist/backend/messages.d.ts.map +1 -0
  14. package/dist/backend/messages.js +14 -0
  15. package/dist/backend/parse.d.ts +11 -0
  16. package/dist/backend/parse.d.ts.map +1 -0
  17. package/dist/backend/parse.js +66 -0
  18. package/dist/backend/rules/__tests__/snowflake-static-sql.test.d.ts +2 -0
  19. package/dist/backend/rules/__tests__/snowflake-static-sql.test.d.ts.map +1 -0
  20. package/dist/backend/rules/index.d.ts +5 -0
  21. package/dist/backend/rules/index.d.ts.map +1 -0
  22. package/dist/backend/rules/index.js +8 -0
  23. package/dist/backend/rules/snowflake-static-sql.d.ts +15 -0
  24. package/dist/backend/rules/snowflake-static-sql.d.ts.map +1 -0
  25. package/dist/backend/rules/snowflake-static-sql.js +75 -0
  26. package/dist/backend/rules/types.d.ts +29 -0
  27. package/dist/backend/rules/types.d.ts.map +1 -0
  28. package/dist/backend/rules/types.js +1 -0
  29. package/dist/commands/__tests__/delete.test.d.ts +2 -0
  30. package/dist/commands/__tests__/delete.test.d.ts.map +1 -0
  31. package/dist/commands/backend.d.ts +0 -1
  32. package/dist/commands/backend.d.ts.map +1 -1
  33. package/dist/commands/backend.js +6 -6
  34. package/dist/commands/deploy.d.ts.map +1 -1
  35. package/dist/commands/deploy.js +16 -13
  36. package/dist/constants.d.ts +2 -13
  37. package/dist/constants.d.ts.map +1 -1
  38. package/dist/constants.js +60 -45
  39. package/dist/esm/backend/__tests__/ast.test.d.ts +2 -0
  40. package/dist/esm/backend/__tests__/ast.test.d.ts.map +1 -0
  41. package/dist/esm/backend/__tests__/parse.test.d.ts +2 -0
  42. package/dist/esm/backend/__tests__/parse.test.d.ts.map +1 -0
  43. package/dist/esm/backend/ast.d.ts +41 -0
  44. package/dist/esm/backend/ast.d.ts.map +1 -0
  45. package/dist/esm/backend/ast.mjs +146 -0
  46. package/dist/esm/backend/handler-declaration.d.ts +17 -0
  47. package/dist/esm/backend/handler-declaration.d.ts.map +1 -0
  48. package/dist/esm/backend/handler-declaration.mjs +78 -0
  49. package/dist/esm/backend/messages.d.ts +10 -0
  50. package/dist/esm/backend/messages.d.ts.map +1 -0
  51. package/dist/esm/backend/messages.mjs +12 -0
  52. package/dist/esm/backend/parse.d.ts +11 -0
  53. package/dist/esm/backend/parse.d.ts.map +1 -0
  54. package/dist/esm/backend/parse.mjs +64 -0
  55. package/dist/esm/backend/rules/__tests__/snowflake-static-sql.test.d.ts +2 -0
  56. package/dist/esm/backend/rules/__tests__/snowflake-static-sql.test.d.ts.map +1 -0
  57. package/dist/esm/backend/rules/index.d.ts +5 -0
  58. package/dist/esm/backend/rules/index.d.ts.map +1 -0
  59. package/dist/esm/backend/rules/index.mjs +6 -0
  60. package/dist/esm/backend/rules/snowflake-static-sql.d.ts +15 -0
  61. package/dist/esm/backend/rules/snowflake-static-sql.d.ts.map +1 -0
  62. package/dist/esm/backend/rules/snowflake-static-sql.mjs +73 -0
  63. package/dist/esm/backend/rules/types.d.ts +29 -0
  64. package/dist/esm/backend/rules/types.d.ts.map +1 -0
  65. package/dist/esm/backend/rules/types.mjs +1 -0
  66. package/dist/esm/commands/__tests__/delete.test.d.ts +2 -0
  67. package/dist/esm/commands/__tests__/delete.test.d.ts.map +1 -0
  68. package/dist/esm/commands/backend.d.ts +0 -1
  69. package/dist/esm/commands/backend.d.ts.map +1 -1
  70. package/dist/esm/commands/backend.mjs +5 -5
  71. package/dist/esm/commands/deploy.d.ts.map +1 -1
  72. package/dist/esm/commands/deploy.mjs +9 -6
  73. package/dist/esm/constants.d.ts +2 -13
  74. package/dist/esm/constants.d.ts.map +1 -1
  75. package/dist/esm/constants.mjs +5 -35
  76. package/dist/esm/util/__tests__/usage-upload.test.d.ts +2 -0
  77. package/dist/esm/util/__tests__/usage-upload.test.d.ts.map +1 -0
  78. package/dist/esm/util/app-name.mjs +1 -1
  79. package/dist/esm/util/auth/__tests__/index.test.d.ts +2 -0
  80. package/dist/esm/util/auth/__tests__/index.test.d.ts.map +1 -0
  81. package/dist/esm/util/auth/broker-credential-provider.d.ts +6 -1
  82. package/dist/esm/util/auth/broker-credential-provider.d.ts.map +1 -1
  83. package/dist/esm/util/auth/broker-credential-provider.mjs +2 -2
  84. package/dist/esm/util/auth/index.d.ts +3 -0
  85. package/dist/esm/util/auth/index.d.ts.map +1 -0
  86. package/dist/esm/util/auth/index.mjs +2 -0
  87. package/dist/esm/util/broker/app.d.ts +0 -1
  88. package/dist/esm/util/broker/app.d.ts.map +1 -1
  89. package/dist/esm/util/broker/app.mjs +3 -4
  90. package/dist/esm/util/git/repo.mjs +1 -1
  91. package/dist/esm/util/s3/client.mjs +1 -1
  92. package/dist/esm/util/s3/upload.mjs +1 -1
  93. package/dist/esm/util/usage-json.d.ts +2 -2
  94. package/dist/esm/util/usage-json.d.ts.map +1 -1
  95. package/dist/esm/util/usage-json.mjs +5 -2
  96. package/dist/esm/util/usage-upload.d.ts +3 -0
  97. package/dist/esm/util/usage-upload.d.ts.map +1 -0
  98. package/dist/esm/util/usage-upload.mjs +29 -0
  99. package/dist/util/__tests__/usage-upload.test.d.ts +2 -0
  100. package/dist/util/__tests__/usage-upload.test.d.ts.map +1 -0
  101. package/dist/util/app-name.js +6 -6
  102. package/dist/util/auth/__tests__/index.test.d.ts +2 -0
  103. package/dist/util/auth/__tests__/index.test.d.ts.map +1 -0
  104. package/dist/util/auth/broker-credential-provider.d.ts +6 -1
  105. package/dist/util/auth/broker-credential-provider.d.ts.map +1 -1
  106. package/dist/util/auth/broker-credential-provider.js +2 -2
  107. package/dist/util/auth/index.d.ts +3 -0
  108. package/dist/util/auth/index.d.ts.map +1 -0
  109. package/dist/util/auth/index.js +11 -0
  110. package/dist/util/broker/app.d.ts +0 -1
  111. package/dist/util/broker/app.d.ts.map +1 -1
  112. package/dist/util/broker/app.js +3 -4
  113. package/dist/util/git/repo.js +2 -2
  114. package/dist/util/s3/client.js +2 -2
  115. package/dist/util/s3/upload.js +2 -2
  116. package/dist/util/usage-json.d.ts +2 -2
  117. package/dist/util/usage-json.d.ts.map +1 -1
  118. package/dist/util/usage-json.js +5 -2
  119. package/dist/util/usage-upload.d.ts +3 -0
  120. package/dist/util/usage-upload.d.ts.map +1 -0
  121. package/dist/util/usage-upload.js +31 -0
  122. package/package.json +3 -3
  123. package/src/commands/__tests__/backend-deploy.test.ts +2 -4
  124. package/src/commands/__tests__/deploy.test.ts +43 -11
  125. package/src/commands/backend.ts +4 -5
  126. package/src/commands/deploy.ts +9 -5
  127. package/src/constants.ts +25 -47
  128. package/src/util/__tests__/usage-upload.test.ts +58 -0
  129. package/src/util/auth/__tests__/broker-credential-provider.test.ts +4 -4
  130. package/src/util/auth/broker-credential-provider.ts +4 -4
  131. package/src/util/broker/app.ts +2 -15
  132. package/src/util/usage-json.ts +11 -4
  133. package/src/util/usage-upload.ts +38 -0
@@ -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, apiUsages, description, masterAppName, } = params;
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, apiUsages, description, } = params;
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, apiUsages, description }),
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,7 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import fs from 'fs-extra';
3
3
  import { execa } from 'execa';
4
- import { BUCKET_WRITE_NAME } from '../../constants.mjs';
4
+ import { BUCKET_WRITE_NAME } from '@mondaydotcomorg/z2h-shared-utils';
5
5
  import { mfAppName } from '../app-name.mjs';
6
6
  import { GitConflictError, DeployError, messageOf } from '../errors.mjs';
7
7
 
@@ -1,5 +1,5 @@
1
1
  import { S3Client } from '@aws-sdk/client-s3';
2
- import { REGION } from '../../constants.mjs';
2
+ import { REGION } from '@mondaydotcomorg/z2h-shared-utils';
3
3
 
4
4
  let client = null;
5
5
  function setupS3Client(credentials) {
@@ -4,7 +4,7 @@ import { readFile } from 'fs-extra';
4
4
  import { lookup } from 'mime-types';
5
5
  import pMap from 'p-map';
6
6
  import { PutObjectCommand } from '@aws-sdk/client-s3';
7
- import { BUCKET_WRITE_NAME } from '../../constants.mjs';
7
+ import { BUCKET_WRITE_NAME } from '@mondaydotcomorg/z2h-shared-utils';
8
8
  import { tagDeployError } from '../errors.mjs';
9
9
  import { getS3Client } from './client.mjs';
10
10
 
@@ -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<void>;
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<void>;
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,IAAI,CAAC,CAWlG;AAED,0GAA0G;AAC1G,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhH"}
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
- await writeJson(file, { ...existing, ...patch }, { spaces: 2 });
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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=usage-upload.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-upload.test.d.ts","sourceRoot":"","sources":["../../../src/util/__tests__/usage-upload.test.ts"],"names":[],"mappings":""}
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const fs = require('node:fs');
4
- const constants = require('../constants.js');
4
+ const z2hSharedUtils = require('@mondaydotcomorg/z2h-shared-utils');
5
5
 
6
6
  /**
7
7
  * Strip any npm scope (`@scope/`) from a package name.
@@ -40,12 +40,12 @@ function validateAppName(appName) {
40
40
  if (RESERVED_APP_NAMES.has(appName)) {
41
41
  throw new Error(`App name "${appName}" is reserved by the Z2H host for a platform page under /bigbrain-vibe/${appName}. Pick a different name.`);
42
42
  }
43
- if (!constants.APP_NAME_PATTERN.test(appName)) {
43
+ if (!z2hSharedUtils.APP_NAME_PATTERN.test(appName)) {
44
44
  throw new Error(`App name "${appName}" is invalid. Use lowercase kebab-case (a-z, 0-9, -), ` +
45
45
  `2-50 chars, starting with a letter.`);
46
46
  }
47
- if (appName.startsWith(constants.PREVIEW_APP_NAME_PREFIX)) {
48
- throw new Error(`App names starting with "${constants.PREVIEW_APP_NAME_PREFIX}" are reserved for the ephemeral preview mechanism. Pick a different name.`);
47
+ if (appName.startsWith(z2hSharedUtils.PREVIEW_APP_NAME_PREFIX)) {
48
+ throw new Error(`App names starting with "${z2hSharedUtils.PREVIEW_APP_NAME_PREFIX}" are reserved for the ephemeral preview mechanism. Pick a different name.`);
49
49
  }
50
50
  }
51
51
  // Preview slugs are capped here so the mf-prefixed name (`mf-` + slug) stays
@@ -61,13 +61,13 @@ const PREVIEW_SLUG_MAX_LEN = 47;
61
61
  */
62
62
  function buildPreviewSlug(appName, previewId) {
63
63
  const shortId = previewId.replace(/-/g, '').slice(0, 8);
64
- const base = `${constants.PREVIEW_APP_NAME_PREFIX}${shortId}-${cleanAppName(appName)}`;
64
+ const base = `${z2hSharedUtils.PREVIEW_APP_NAME_PREFIX}${shortId}-${cleanAppName(appName)}`;
65
65
  // Trailing hyphens are stripped post-slice — a cut that lands right after a
66
66
  // hyphen in appName would otherwise leave one dangling.
67
67
  return base.slice(0, PREVIEW_SLUG_MAX_LEN).replace(/-+$/, '');
68
68
  }
69
69
  function isPreviewAppName(appName) {
70
- return appName.startsWith(`mf-${constants.PREVIEW_APP_NAME_PREFIX}`);
70
+ return appName.startsWith(`mf-${z2hSharedUtils.PREVIEW_APP_NAME_PREFIX}`);
71
71
  }
72
72
 
73
73
  exports.buildPreviewSlug = buildPreviewSlug;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -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<number>;
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;AA0D3D;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMzE;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"}
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 body = (await res.json());
55
- return body.version ?? 0;
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,3 @@
1
+ export { ensureZ2hToken, type EnsureZ2hTokenOptions } from '../npm/ensure-token';
2
+ export { readZthAuth, tryReadAuthTokenSync, Z2hAuthMissingError, type ZthAuth } from './auth-store';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA8DD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBtF"}
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"}
@@ -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, apiUsages, description, masterAppName, } = params;
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, apiUsages, description, } = params;
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, apiUsages, description }),
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();
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3
3
  const path = require('node:path');
4
4
  const fs = require('fs-extra');
5
5
  const execa = require('execa');
6
- const constants = require('../../constants.js');
6
+ const z2hSharedUtils = require('@mondaydotcomorg/z2h-shared-utils');
7
7
  const util_appName = require('../app-name.js');
8
8
  const util_errors = require('../errors.js');
9
9
 
@@ -23,7 +23,7 @@ async function execGitLines(args, dir, env) {
23
23
  const REQUIRED_GITIGNORE_ENTRIES = ['node_modules/', '.zth/', 'build/'];
24
24
  const LOCAL_HOOKS_DIR = '.zth/hooks';
25
25
  function defaultS3Remote(app) {
26
- return `s3://${constants.BUCKET_WRITE_NAME}/${util_appName.mfAppName(app)}/git`;
26
+ return `s3://${z2hSharedUtils.BUCKET_WRITE_NAME}/${util_appName.mfAppName(app)}/git`;
27
27
  }
28
28
  async function initRepo(dir, remote) {
29
29
  await ensureGitignore(dir);
@@ -1,11 +1,11 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const clientS3 = require('@aws-sdk/client-s3');
4
- const constants = require('../../constants.js');
4
+ const z2hSharedUtils = require('@mondaydotcomorg/z2h-shared-utils');
5
5
 
6
6
  let client = null;
7
7
  function setupS3Client(credentials) {
8
- client = new clientS3.S3Client({ region: constants.REGION, credentials });
8
+ client = new clientS3.S3Client({ region: z2hSharedUtils.REGION, credentials });
9
9
  }
10
10
  function getS3Client() {
11
11
  if (!client) {
@@ -6,7 +6,7 @@ const fs = require('fs-extra');
6
6
  const mimeTypes = require('mime-types');
7
7
  const pMap = require('p-map');
8
8
  const clientS3 = require('@aws-sdk/client-s3');
9
- const constants = require('../../constants.js');
9
+ const z2hSharedUtils = require('@mondaydotcomorg/z2h-shared-utils');
10
10
  const util_errors = require('../errors.js');
11
11
  const util_s3_client = require('./client.js');
12
12
 
@@ -19,7 +19,7 @@ const pMap__default = /*#__PURE__*/_interopDefault(pMap);
19
19
  // the URL itself is the cache key. Assets never need to be revalidated.
20
20
  const FOREVER = 'public, immutable';
21
21
  const UPLOAD_CONCURRENCY = 5;
22
- async function uploadDir(localDir, keyPrefix, bucket = constants.BUCKET_WRITE_NAME) {
22
+ async function uploadDir(localDir, keyPrefix, bucket = z2hSharedUtils.BUCKET_WRITE_NAME) {
23
23
  try {
24
24
  const entries = await promises.readdir(localDir, { recursive: true, withFileTypes: true });
25
25
  const files = entries.filter(e => e.isFile()).map(e => path__default.default.relative(localDir, path__default.default.join(e.parentPath, e.name)));
@@ -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<void>;
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<void>;
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,IAAI,CAAC,CAWlG;AAED,0GAA0G;AAC1G,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhH"}
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"}
@@ -26,17 +26,20 @@ async function writeUsageJson(appDir, patch) {
26
26
  throw err;
27
27
  }
28
28
  }
29
- await fs$1.writeJson(file, { ...existing, ...patch }, { spaces: 2 });
29
+ const merged = { ...existing, ...patch };
30
+ await fs$1.writeJson(file, merged, { spaces: 2 });
31
+ return merged;
30
32
  }
31
33
  /** Refreshes the git-tracked `usage.json` and commits it if it changed, so a deploy's push carries it. */
32
34
  async function updateOrCreateUsageJson(appDir, appName, deployedBy) {
33
35
  const apiUsages = hasHandlers(appDir) ? (await backend_handlers.readHandlers(appDir)).apiUsages : {};
34
- await writeUsageJson(appDir, { appName, deployedBy, apiUsages });
36
+ const usage = await writeUsageJson(appDir, { appName, deployedBy, apiUsages });
35
37
  await util_git_repo.execGit(['add', 'usage.json'], appDir);
36
38
  const { exitCode } = await execa.execa('git', ['diff', '--cached', '--quiet'], { cwd: appDir, reject: false });
37
39
  if (exitCode !== 0) {
38
40
  await util_git_repo.execGit(['commit', '-m', 'Update usage.json'], appDir);
39
41
  }
42
+ return usage;
40
43
  }
41
44
 
42
45
  exports.hasHandlers = hasHandlers;
@@ -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,31 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const clientS3 = require('@aws-sdk/client-s3');
4
+ const constants = require('../constants.js');
5
+ const util_logger = require('./logger.js');
6
+ const util_s3_client = require('./s3/client.js');
7
+ const z2hSharedUtils = require('@mondaydotcomorg/z2h-shared-utils');
8
+
9
+ /** Snowpipe ignores re-uploads of an existing key, so the key is unique per app row id and deploy version. */
10
+ async function putAppUsage(appName, appId, usage, uploadVersion) {
11
+ if (!constants.isProdBroker()) {
12
+ util_logger.warn(`skipping app usage upload to Snowflake: ${constants.brokerBaseUrl()} is not the production broker, and only production deploys are recorded.`);
13
+ return;
14
+ }
15
+ if (appId === null) {
16
+ return;
17
+ }
18
+ try {
19
+ await util_s3_client.getS3Client().send(new clientS3.PutObjectCommand({
20
+ Bucket: z2hSharedUtils.APP_USAGE_BUCKET_NAME,
21
+ Key: `${z2hSharedUtils.appUsageFolder(appName, appId)}/${uploadVersion}/usage.json`,
22
+ Body: JSON.stringify({ ...usage, appName, appId, uploadVersion }),
23
+ ContentType: 'application/json',
24
+ }));
25
+ }
26
+ catch (err) {
27
+ util_logger.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).`);
28
+ }
29
+ }
30
+
31
+ exports.putAppUsage = putAppUsage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mondaydotcomorg/z2h-cli",
3
- "version": "0.34.0",
3
+ "version": "0.34.2",
4
4
  "bin": "./bin/z2h-cli.js",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -57,7 +57,7 @@
57
57
  "dependencies": {
58
58
  "@aws-sdk/client-s3": "^3.706.0",
59
59
  "@mondaydotcomorg/z2h-dashboard-templates": "^0.4.0",
60
- "@mondaydotcomorg/z2h-shared-utils": "^0.7.2",
60
+ "@mondaydotcomorg/z2h-shared-utils": "^0.7.4",
61
61
  "acorn": "^8.14.0",
62
62
  "acorn-walk": "^8.3.4",
63
63
  "chokidar": "^3.6.0",
@@ -94,4 +94,4 @@
94
94
  "url": "https://github.com/DaPulse/bigbrain-z2h.git",
95
95
  "directory": "packages/z2h-cli"
96
96
  }
97
- }
97
+ }
@@ -75,7 +75,7 @@ describe('deployBackend (live)', () => {
75
75
  deployedBy: 'test-user',
76
76
  isPreview: false,
77
77
  })
78
- ).resolves.toEqual({ integrations: [], handlerNames: [], apiUsages: {} });
78
+ ).resolves.toEqual({ integrations: [], handlerNames: [] });
79
79
  expect(mockSend).not.toHaveBeenCalled();
80
80
  });
81
81
 
@@ -92,7 +92,7 @@ describe('deployBackend (live)', () => {
92
92
  deployedBy: 'test-user',
93
93
  isPreview: false,
94
94
  })
95
- ).resolves.toEqual({ integrations: [], handlerNames: [], apiUsages: {} });
95
+ ).resolves.toEqual({ integrations: [], handlerNames: [] });
96
96
  expect(mockSend).not.toHaveBeenCalled();
97
97
  });
98
98
 
@@ -118,7 +118,6 @@ describe('deployBackend (live)', () => {
118
118
  ).resolves.toEqual({
119
119
  integrations: [],
120
120
  handlerNames: ['call_snowflake'],
121
- apiUsages: { call_snowflake: { snowflake: { query: [{ sql: 'x' }] } } },
122
121
  });
123
122
  expect(mockSend).toHaveBeenCalled();
124
123
  const keys: string[] = mockSend.mock.calls.map((c: unknown[]) => (c[0] as { input: { Key: string } }).input.Key);
@@ -186,7 +185,6 @@ describe('deployBackend (preview)', () => {
186
185
  ).resolves.toEqual({
187
186
  integrations: ['monday'],
188
187
  handlerNames: ['call_snowflake'],
189
- apiUsages: { call_snowflake: { monday: { query: [{ query: 'x' }] } } },
190
188
  });
191
189
  expect(mockSend).toHaveBeenCalled();
192
190
  const keys: string[] = mockSend.mock.calls.map((c: unknown[]) => (c[0] as { input: { Key: string } }).input.Key);