@shipfox/api-definitions 9.0.2 → 9.1.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/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +17 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -0
- package/dist/config.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/sync-definitions.d.ts +2 -1
- package/dist/core/sync-definitions.d.ts.map +1 -1
- package/dist/core/sync-definitions.js +4 -3
- package/dist/core/sync-definitions.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/temporal/activities/sync-activities.d.ts +4 -1
- package/dist/temporal/activities/sync-activities.d.ts.map +1 -1
- package/dist/temporal/activities/sync-activities.js +5 -4
- package/dist/temporal/activities/sync-activities.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/src/config.ts +6 -0
- package/src/core/index.ts +1 -1
- package/src/core/sync-definitions.test.ts +36 -0
- package/src/core/sync-definitions.ts +5 -3
- package/src/index.ts +5 -1
- package/src/temporal/activities/sync-activities.test.ts +29 -0
- package/src/temporal/activities/sync-activities.ts +14 -2
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
$ shipfox-swc && shipfox-temporal-bundle dist/temporal/workflows/index.js
|
|
2
|
-
Successfully compiled: 72 files with swc (
|
|
3
|
-
2026-07-
|
|
2
|
+
Successfully compiled: 72 files with swc (612.23ms)
|
|
3
|
+
2026-07-26T09:59:21.648Z [INFO] asset workflow-bundle-2e2f2f4d6c035dc8e198.js 3.18 MiB [emitted] [immutable] (name: main)
|
|
4
4
|
orphan modules 33.5 KiB [orphan] 21 modules
|
|
5
5
|
runtime modules 1.13 KiB 5 modules
|
|
6
6
|
modules by path ../../../node_modules/.pnpm/ 970 KiB 196 modules
|
|
@@ -14,6 +14,6 @@ optional modules 30 bytes [optional]
|
|
|
14
14
|
__temporal_custom_payload_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
15
15
|
__temporal_custom_failure_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
16
16
|
../../shared/node/temporal/dist/workflow-error-interceptor.js 1.21 KiB [built] [code generated]
|
|
17
|
-
webpack 5.107.2 compiled successfully in
|
|
18
|
-
2026-07-
|
|
17
|
+
webpack 5.107.2 compiled successfully in 7664 ms
|
|
18
|
+
2026-07-26T09:59:21.657Z [INFO] Workflow bundle created { size: '3.18MB' }
|
|
19
19
|
/home/runner/work/shipfox/shipfox/libs/api/definitions/dist/temporal/workflows/index.js: 3332889 bytes
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @shipfox/api-definitions
|
|
2
2
|
|
|
3
|
+
## 9.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 2e9d82d: Adds a configurable repository path for workflow definition sync.
|
|
8
|
+
|
|
9
|
+
## 9.0.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [a831b32]
|
|
14
|
+
- @shipfox/node-error-monitoring@0.3.0
|
|
15
|
+
- @shipfox/node-fastify@0.3.3
|
|
16
|
+
- @shipfox/node-module@1.0.2
|
|
17
|
+
- @shipfox/node-temporal@0.4.3
|
|
18
|
+
- @shipfox/api-auth-context@9.0.3
|
|
19
|
+
|
|
3
20
|
## 9.0.2
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/dist/config.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const config: Readonly<{
|
|
2
2
|
DEFINITION_DEFAULT_RUNNER_LABEL: string;
|
|
3
|
+
DEFINITION_WORKFLOW_PATH: string;
|
|
3
4
|
} & import("@shipfox/config").CleanedEnvAccessors>;
|
|
4
5
|
export declare function parseDefinitionDefaultRunnerLabels(value: string): readonly string[];
|
|
5
6
|
export declare const definitionDefaultRunnerLabels: readonly string[];
|
|
7
|
+
export declare const definitionWorkflowPath: string;
|
|
6
8
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM;;;kDASjB,CAAC;AAEH,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAiBnF;AAED,eAAO,MAAM,6BAA6B,mBAEzC,CAAC;AAEF,eAAO,MAAM,sBAAsB,QAAkC,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -4,6 +4,10 @@ export const config = createConfig({
|
|
|
4
4
|
DEFINITION_DEFAULT_RUNNER_LABEL: str({
|
|
5
5
|
desc: 'Default runner label(s) applied to workflow jobs that do not declare a "runner" at the job or workflow level. Set it to a comma-separated list, for example ubuntu-latest or ubuntu-latest,node-22. Leave it empty to require every workflow job to declare runner labels explicitly; with no value set, a job without a runner fails definition validation.',
|
|
6
6
|
default: ''
|
|
7
|
+
}),
|
|
8
|
+
DEFINITION_WORKFLOW_PATH: str({
|
|
9
|
+
desc: 'Repository-relative path that contains workflow YAML files. Set a different path for each Shipfox instance when staging and production share a repository.',
|
|
10
|
+
default: '.shipfox/workflows/'
|
|
7
11
|
})
|
|
8
12
|
});
|
|
9
13
|
export function parseDefinitionDefaultRunnerLabels(value) {
|
|
@@ -18,5 +22,6 @@ export function parseDefinitionDefaultRunnerLabels(value) {
|
|
|
18
22
|
return labels;
|
|
19
23
|
}
|
|
20
24
|
export const definitionDefaultRunnerLabels = parseDefinitionDefaultRunnerLabels(config.DEFINITION_DEFAULT_RUNNER_LABEL);
|
|
25
|
+
export const definitionWorkflowPath = config.DEFINITION_WORKFLOW_PATH;
|
|
21
26
|
|
|
22
27
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["import {createConfig, str} from '@shipfox/config';\nimport {findInvalidLabels, MAX_RUNNER_LABELS, parseLabelList} from '@shipfox/runner-labels';\n\nexport const config = createConfig({\n DEFINITION_DEFAULT_RUNNER_LABEL: str({\n desc: 'Default runner label(s) applied to workflow jobs that do not declare a \"runner\" at the job or workflow level. Set it to a comma-separated list, for example ubuntu-latest or ubuntu-latest,node-22. Leave it empty to require every workflow job to declare runner labels explicitly; with no value set, a job without a runner fails definition validation.',\n default: '',\n }),\n});\n\nexport function parseDefinitionDefaultRunnerLabels(value: string): readonly string[] {\n const labels = parseLabelList(value);\n const invalid = findInvalidLabels(labels);\n\n if (invalid.length > 0) {\n throw new Error(\n `DEFINITION_DEFAULT_RUNNER_LABEL contains invalid runner label(s): ${invalid.join(', ')}`,\n );\n }\n\n if (labels.length > MAX_RUNNER_LABELS) {\n throw new Error(\n `DEFINITION_DEFAULT_RUNNER_LABEL contains ${labels.length} runner labels; the maximum is ${MAX_RUNNER_LABELS}`,\n );\n }\n\n return labels;\n}\n\nexport const definitionDefaultRunnerLabels = parseDefinitionDefaultRunnerLabels(\n config.DEFINITION_DEFAULT_RUNNER_LABEL,\n);\n"],"names":["createConfig","str","findInvalidLabels","MAX_RUNNER_LABELS","parseLabelList","config","DEFINITION_DEFAULT_RUNNER_LABEL","desc","default","parseDefinitionDefaultRunnerLabels","value","labels","invalid","length","Error","join","definitionDefaultRunnerLabels"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,GAAG,QAAO,kBAAkB;AAClD,SAAQC,iBAAiB,EAAEC,iBAAiB,EAAEC,cAAc,QAAO,yBAAyB;AAE5F,OAAO,MAAMC,SAASL,aAAa;IACjCM,iCAAiCL,IAAI;QACnCM,MAAM;QACNC,SAAS;IACX;AACF,GAAG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["import {createConfig, str} from '@shipfox/config';\nimport {findInvalidLabels, MAX_RUNNER_LABELS, parseLabelList} from '@shipfox/runner-labels';\n\nexport const config = createConfig({\n DEFINITION_DEFAULT_RUNNER_LABEL: str({\n desc: 'Default runner label(s) applied to workflow jobs that do not declare a \"runner\" at the job or workflow level. Set it to a comma-separated list, for example ubuntu-latest or ubuntu-latest,node-22. Leave it empty to require every workflow job to declare runner labels explicitly; with no value set, a job without a runner fails definition validation.',\n default: '',\n }),\n DEFINITION_WORKFLOW_PATH: str({\n desc: 'Repository-relative path that contains workflow YAML files. Set a different path for each Shipfox instance when staging and production share a repository.',\n default: '.shipfox/workflows/',\n }),\n});\n\nexport function parseDefinitionDefaultRunnerLabels(value: string): readonly string[] {\n const labels = parseLabelList(value);\n const invalid = findInvalidLabels(labels);\n\n if (invalid.length > 0) {\n throw new Error(\n `DEFINITION_DEFAULT_RUNNER_LABEL contains invalid runner label(s): ${invalid.join(', ')}`,\n );\n }\n\n if (labels.length > MAX_RUNNER_LABELS) {\n throw new Error(\n `DEFINITION_DEFAULT_RUNNER_LABEL contains ${labels.length} runner labels; the maximum is ${MAX_RUNNER_LABELS}`,\n );\n }\n\n return labels;\n}\n\nexport const definitionDefaultRunnerLabels = parseDefinitionDefaultRunnerLabels(\n config.DEFINITION_DEFAULT_RUNNER_LABEL,\n);\n\nexport const definitionWorkflowPath = config.DEFINITION_WORKFLOW_PATH;\n"],"names":["createConfig","str","findInvalidLabels","MAX_RUNNER_LABELS","parseLabelList","config","DEFINITION_DEFAULT_RUNNER_LABEL","desc","default","DEFINITION_WORKFLOW_PATH","parseDefinitionDefaultRunnerLabels","value","labels","invalid","length","Error","join","definitionDefaultRunnerLabels","definitionWorkflowPath"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,GAAG,QAAO,kBAAkB;AAClD,SAAQC,iBAAiB,EAAEC,iBAAiB,EAAEC,cAAc,QAAO,yBAAyB;AAE5F,OAAO,MAAMC,SAASL,aAAa;IACjCM,iCAAiCL,IAAI;QACnCM,MAAM;QACNC,SAAS;IACX;IACAC,0BAA0BR,IAAI;QAC5BM,MAAM;QACNC,SAAS;IACX;AACF,GAAG;AAEH,OAAO,SAASE,mCAAmCC,KAAa;IAC9D,MAAMC,SAASR,eAAeO;IAC9B,MAAME,UAAUX,kBAAkBU;IAElC,IAAIC,QAAQC,MAAM,GAAG,GAAG;QACtB,MAAM,IAAIC,MACR,CAAC,kEAAkE,EAAEF,QAAQG,IAAI,CAAC,OAAO;IAE7F;IAEA,IAAIJ,OAAOE,MAAM,GAAGX,mBAAmB;QACrC,MAAM,IAAIY,MACR,CAAC,yCAAyC,EAAEH,OAAOE,MAAM,CAAC,+BAA+B,EAAEX,mBAAmB;IAElH;IAEA,OAAOS;AACT;AAEA,OAAO,MAAMK,gCAAgCP,mCAC3CL,OAAOC,+BAA+B,EACtC;AAEF,OAAO,MAAMY,yBAAyBb,OAAOI,wBAAwB,CAAC"}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type * from './entities/index.js';
|
|
2
2
|
export { DefinitionParseError, DefinitionSyncPermanentError, } from './errors.js';
|
|
3
3
|
export { parseDefinition } from './parse-definition.js';
|
|
4
|
-
export { classifySyncFailure, type DiscoverWorkflowFilesParams, discoverWorkflowFiles, type FetchAndParseWorkflowsParams, FILE_FETCH_CONCURRENCY, fetchAndParseWorkflows, MAX_WORKFLOW_FILES, type ParsedWorkflow, type ResolvedSyncSource, resolveSyncSource, type SyncFailureClassification, type SyncSourceContext, UNRESOLVED_SYNC_REF,
|
|
4
|
+
export { classifySyncFailure, DEFAULT_WORKFLOW_PATH, type DiscoverWorkflowFilesParams, discoverWorkflowFiles, type FetchAndParseWorkflowsParams, FILE_FETCH_CONCURRENCY, fetchAndParseWorkflows, MAX_WORKFLOW_FILES, type ParsedWorkflow, type ResolvedSyncSource, resolveSyncSource, type SyncFailureClassification, type SyncSourceContext, UNRESOLVED_SYNC_REF, } from './sync-definitions.js';
|
|
5
5
|
export { DEFAULT_RUN_TIMEOUT_MS } from './workflow-model/constants.js';
|
|
6
6
|
export { normalizeWorkflowDocument } from './workflow-model/index.js';
|
|
7
7
|
export { DEFAULT_JOB_CHECKOUT } from './workflow-model/normalize-job-checkout.js';
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,qBAAqB,CAAC;AACzC,OAAO,EACL,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,KAAK,2BAA2B,EAChC,qBAAqB,EACrB,KAAK,4BAA4B,EACjC,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,iBAAiB,EACjB,KAAK,yBAAyB,EAC9B,KAAK,iBAAiB,EACtB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,qBAAqB,CAAC;AACzC,OAAO,EACL,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,2BAA2B,EAChC,qBAAqB,EACrB,KAAK,4BAA4B,EACjC,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,iBAAiB,EACjB,KAAK,yBAAyB,EAC9B,KAAK,iBAAiB,EACtB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAC,sBAAsB,EAAC,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAC,yBAAyB,EAAC,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAC,oBAAoB,EAAC,MAAM,4CAA4C,CAAC;AAChF,OAAO,EAAC,mBAAmB,EAAC,MAAM,2CAA2C,CAAC"}
|
package/dist/core/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { DefinitionParseError, DefinitionSyncPermanentError } from './errors.js';
|
|
2
2
|
export { parseDefinition } from './parse-definition.js';
|
|
3
|
-
export { classifySyncFailure, discoverWorkflowFiles, FILE_FETCH_CONCURRENCY, fetchAndParseWorkflows, MAX_WORKFLOW_FILES, resolveSyncSource, UNRESOLVED_SYNC_REF
|
|
3
|
+
export { classifySyncFailure, DEFAULT_WORKFLOW_PATH, discoverWorkflowFiles, FILE_FETCH_CONCURRENCY, fetchAndParseWorkflows, MAX_WORKFLOW_FILES, resolveSyncSource, UNRESOLVED_SYNC_REF } from './sync-definitions.js';
|
|
4
4
|
export { DEFAULT_RUN_TIMEOUT_MS } from './workflow-model/constants.js';
|
|
5
5
|
export { normalizeWorkflowDocument } from './workflow-model/index.js';
|
|
6
6
|
export { DEFAULT_JOB_CHECKOUT } from './workflow-model/normalize-job-checkout.js';
|
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/index.ts"],"sourcesContent":["export type * from './entities/index.js';\nexport {\n DefinitionParseError,\n DefinitionSyncPermanentError,\n} from './errors.js';\nexport {parseDefinition} from './parse-definition.js';\nexport {\n classifySyncFailure,\n type DiscoverWorkflowFilesParams,\n discoverWorkflowFiles,\n type FetchAndParseWorkflowsParams,\n FILE_FETCH_CONCURRENCY,\n fetchAndParseWorkflows,\n MAX_WORKFLOW_FILES,\n type ParsedWorkflow,\n type ResolvedSyncSource,\n resolveSyncSource,\n type SyncFailureClassification,\n type SyncSourceContext,\n UNRESOLVED_SYNC_REF,\n
|
|
1
|
+
{"version":3,"sources":["../../src/core/index.ts"],"sourcesContent":["export type * from './entities/index.js';\nexport {\n DefinitionParseError,\n DefinitionSyncPermanentError,\n} from './errors.js';\nexport {parseDefinition} from './parse-definition.js';\nexport {\n classifySyncFailure,\n DEFAULT_WORKFLOW_PATH,\n type DiscoverWorkflowFilesParams,\n discoverWorkflowFiles,\n type FetchAndParseWorkflowsParams,\n FILE_FETCH_CONCURRENCY,\n fetchAndParseWorkflows,\n MAX_WORKFLOW_FILES,\n type ParsedWorkflow,\n type ResolvedSyncSource,\n resolveSyncSource,\n type SyncFailureClassification,\n type SyncSourceContext,\n UNRESOLVED_SYNC_REF,\n} from './sync-definitions.js';\nexport {DEFAULT_RUN_TIMEOUT_MS} from './workflow-model/constants.js';\nexport {normalizeWorkflowDocument} from './workflow-model/index.js';\nexport {DEFAULT_JOB_CHECKOUT} from './workflow-model/normalize-job-checkout.js';\nexport {DEFAULT_JOB_SUCCESS} from './workflow-model/normalize-job-success.js';\n"],"names":["DefinitionParseError","DefinitionSyncPermanentError","parseDefinition","classifySyncFailure","DEFAULT_WORKFLOW_PATH","discoverWorkflowFiles","FILE_FETCH_CONCURRENCY","fetchAndParseWorkflows","MAX_WORKFLOW_FILES","resolveSyncSource","UNRESOLVED_SYNC_REF","DEFAULT_RUN_TIMEOUT_MS","normalizeWorkflowDocument","DEFAULT_JOB_CHECKOUT","DEFAULT_JOB_SUCCESS"],"mappings":"AACA,SACEA,oBAAoB,EACpBC,4BAA4B,QACvB,cAAc;AACrB,SAAQC,eAAe,QAAO,wBAAwB;AACtD,SACEC,mBAAmB,EACnBC,qBAAqB,EAErBC,qBAAqB,EAErBC,sBAAsB,EACtBC,sBAAsB,EACtBC,kBAAkB,EAGlBC,iBAAiB,EAGjBC,mBAAmB,QACd,wBAAwB;AAC/B,SAAQC,sBAAsB,QAAO,gCAAgC;AACrE,SAAQC,yBAAyB,QAAO,4BAA4B;AACpE,SAAQC,oBAAoB,QAAO,6CAA6C;AAChF,SAAQC,mBAAmB,QAAO,4CAA4C"}
|
|
@@ -3,7 +3,7 @@ import type { IntegrationValidationContext } from './entities/integration-contex
|
|
|
3
3
|
import type { DefinitionSyncErrorCode } from './entities/sync-state.js';
|
|
4
4
|
import type { WorkflowDefinitionPayload } from './entities/workflow-definition.js';
|
|
5
5
|
import type { DefinitionsSourceControl } from './integrations.js';
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const DEFAULT_WORKFLOW_PATH = ".shipfox/workflows/";
|
|
7
7
|
export declare const MAX_WORKFLOW_FILES = 100;
|
|
8
8
|
export declare const MAX_WORKFLOW_FILE_BYTES = 1000000;
|
|
9
9
|
export declare const FILE_FETCH_CONCURRENCY = 4;
|
|
@@ -20,6 +20,7 @@ export interface ResolvedSyncSource {
|
|
|
20
20
|
export declare function resolveSyncSource(params: SyncSourceContext): Promise<ResolvedSyncSource>;
|
|
21
21
|
export interface DiscoverWorkflowFilesParams extends SyncSourceContext {
|
|
22
22
|
ref: string;
|
|
23
|
+
workflowPath?: string | undefined;
|
|
23
24
|
}
|
|
24
25
|
export declare function discoverWorkflowFiles(params: DiscoverWorkflowFilesParams): Promise<{
|
|
25
26
|
paths: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-definitions.d.ts","sourceRoot":"","sources":["../../src/core/sync-definitions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,qCAAqC,CAAC;AAIhF,OAAO,KAAK,EAAC,4BAA4B,EAAC,MAAM,mCAAmC,CAAC;AACpF,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,0BAA0B,CAAC;AACtE,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,mCAAmC,CAAC;AAGjF,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,mBAAmB,CAAC;AAGhE,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"sync-definitions.d.ts","sourceRoot":"","sources":["../../src/core/sync-definitions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,qCAAqC,CAAC;AAIhF,OAAO,KAAK,EAAC,4BAA4B,EAAC,MAAM,mCAAmC,CAAC;AACpF,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,0BAA0B,CAAC;AACtE,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,mCAAmC,CAAC;AAGjF,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,mBAAmB,CAAC;AAGhE,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAC3D,eAAO,MAAM,kBAAkB,MAAM,CAAC;AACtC,eAAO,MAAM,uBAAuB,UAAY,CAAC;AACjD,eAAO,MAAM,sBAAsB,IAAI,CAAC;AACxC,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0BAA0B,EAAE,MAAM,CAAC;IACnC,aAAa,EAAE,wBAAwB,CAAC;CACzC;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAO9F;AAED,MAAM,WAAW,2BAA4B,SAAQ,iBAAiB;IACpE,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAC,CAAC,CA4B5B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,yBAAyB,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,4BAA6B,SAAQ,iBAAiB;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAClD,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,gCAAgC,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,4BAA4B,CAAC,CAAC,GAAG,SAAS,CAAC;CAC9F;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC,cAAc,EAAE,CAAC,CAkD3B;AA6BD,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,uBAAuB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,yBAAyB,CA+B7E"}
|
|
@@ -5,7 +5,7 @@ import { boundedMap } from '@shipfox/node-module';
|
|
|
5
5
|
import { DefinitionParseError, DefinitionSyncPermanentError } from './errors.js';
|
|
6
6
|
import { hasAgentStepIntegrations } from './has-agent-step-integrations.js';
|
|
7
7
|
import { parseDefinition } from './parse-definition.js';
|
|
8
|
-
export const
|
|
8
|
+
export const DEFAULT_WORKFLOW_PATH = '.shipfox/workflows/';
|
|
9
9
|
export const MAX_WORKFLOW_FILES = 100;
|
|
10
10
|
export const MAX_WORKFLOW_FILE_BYTES = 1_000_000;
|
|
11
11
|
export const FILE_FETCH_CONCURRENCY = 4;
|
|
@@ -21,12 +21,13 @@ export async function resolveSyncSource(params) {
|
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
export async function discoverWorkflowFiles(params) {
|
|
24
|
+
const workflowPath = params.workflowPath ?? DEFAULT_WORKFLOW_PATH;
|
|
24
25
|
const page = await params.sourceControl.listFiles({
|
|
25
26
|
workspaceId: params.workspaceId,
|
|
26
27
|
connectionId: params.sourceConnectionId,
|
|
27
28
|
externalRepositoryId: params.sourceExternalRepositoryId,
|
|
28
29
|
ref: params.ref,
|
|
29
|
-
prefix:
|
|
30
|
+
prefix: workflowPath,
|
|
30
31
|
limit: MAX_WORKFLOW_FILES
|
|
31
32
|
});
|
|
32
33
|
if (page.nextCursor) {
|
|
@@ -34,7 +35,7 @@ export async function discoverWorkflowFiles(params) {
|
|
|
34
35
|
}
|
|
35
36
|
const paths = page.files.filter((file)=>file.path.endsWith('.yml') || file.path.endsWith('.yaml')).map((file)=>file.path);
|
|
36
37
|
if (paths.length === 0) {
|
|
37
|
-
throw new DefinitionSyncPermanentError('no-workflow-files', `No workflow files were found under ${
|
|
38
|
+
throw new DefinitionSyncPermanentError('no-workflow-files', `No workflow files were found under ${workflowPath}`);
|
|
38
39
|
}
|
|
39
40
|
return {
|
|
40
41
|
paths
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/sync-definitions.ts"],"sourcesContent":["import {createHash} from 'node:crypto';\nimport type {AgentValidationCatalog} from '@shipfox/api-agent-dto/inter-module';\nimport {integrationsInterModuleContract} from '@shipfox/api-integration-core-dto/inter-module';\nimport {isInterModuleKnownError} from '@shipfox/inter-module';\nimport {boundedMap} from '@shipfox/node-module';\nimport type {IntegrationValidationContext} from './entities/integration-context.js';\nimport type {DefinitionSyncErrorCode} from './entities/sync-state.js';\nimport type {WorkflowDefinitionPayload} from './entities/workflow-definition.js';\nimport {DefinitionParseError, DefinitionSyncPermanentError} from './errors.js';\nimport {hasAgentStepIntegrations} from './has-agent-step-integrations.js';\nimport type {DefinitionsSourceControl} from './integrations.js';\nimport {parseDefinition} from './parse-definition.js';\n\nexport const WORKFLOW_PREFIX = '.shipfox/workflows/';\nexport const MAX_WORKFLOW_FILES = 100;\nexport const MAX_WORKFLOW_FILE_BYTES = 1_000_000;\nexport const FILE_FETCH_CONCURRENCY = 4;\nexport const UNRESOLVED_SYNC_REF = '__unresolved__';\n\nexport interface SyncSourceContext {\n workspaceId: string;\n sourceConnectionId: string;\n sourceExternalRepositoryId: string;\n sourceControl: DefinitionsSourceControl;\n}\n\nexport interface ResolvedSyncSource {\n ref: string;\n}\n\nexport async function resolveSyncSource(params: SyncSourceContext): Promise<ResolvedSyncSource> {\n const source = await params.sourceControl.resolveRepository({\n workspaceId: params.workspaceId,\n connectionId: params.sourceConnectionId,\n externalRepositoryId: params.sourceExternalRepositoryId,\n });\n return {ref: source.repository.defaultBranch};\n}\n\nexport interface DiscoverWorkflowFilesParams extends SyncSourceContext {\n ref: string;\n}\n\nexport async function discoverWorkflowFiles(\n params: DiscoverWorkflowFilesParams,\n): Promise<{paths: string[]}> {\n const page = await params.sourceControl.listFiles({\n workspaceId: params.workspaceId,\n connectionId: params.sourceConnectionId,\n externalRepositoryId: params.sourceExternalRepositoryId,\n ref: params.ref,\n prefix: WORKFLOW_PREFIX,\n limit: MAX_WORKFLOW_FILES,\n });\n if (page.nextCursor) {\n throw new DefinitionSyncPermanentError(\n 'too-many-files',\n `More than ${MAX_WORKFLOW_FILES} workflow files were found`,\n );\n }\n\n const paths = page.files\n .filter((file) => file.path.endsWith('.yml') || file.path.endsWith('.yaml'))\n .map((file) => file.path);\n if (paths.length === 0) {\n throw new DefinitionSyncPermanentError(\n 'no-workflow-files',\n `No workflow files were found under ${WORKFLOW_PREFIX}`,\n );\n }\n\n return {paths};\n}\n\nexport interface ParsedWorkflow {\n path: string;\n name: string;\n definition: WorkflowDefinitionPayload;\n contentHash: string;\n}\n\nexport interface FetchAndParseWorkflowsParams extends SyncSourceContext {\n ref: string;\n paths: string[];\n onProgress?: ((path: string) => void) | undefined;\n agentValidationCatalog: AgentValidationCatalog;\n loadIntegrationValidationContext?: (() => Promise<IntegrationValidationContext>) | undefined;\n}\n\nexport async function fetchAndParseWorkflows(\n params: FetchAndParseWorkflowsParams,\n): Promise<ParsedWorkflow[]> {\n const parsed = await boundedMap(\n params.paths,\n FILE_FETCH_CONCURRENCY,\n async (path) => {\n params.onProgress?.(path);\n\n const snapshot = await params.sourceControl.fetchFile({\n workspaceId: params.workspaceId,\n connectionId: params.sourceConnectionId,\n externalRepositoryId: params.sourceExternalRepositoryId,\n ref: params.ref,\n path,\n });\n\n if (Buffer.byteLength(snapshot.content, 'utf8') > MAX_WORKFLOW_FILE_BYTES) {\n throw new DefinitionSyncPermanentError(\n 'content-too-large',\n `Workflow file is larger than ${MAX_WORKFLOW_FILE_BYTES} bytes: ${snapshot.path}`,\n );\n }\n\n return {\n ...parseWorkflowSnapshot({\n path: snapshot.path,\n content: snapshot.content,\n agentValidationCatalog: params.agentValidationCatalog,\n }),\n rawContent: snapshot.content,\n };\n },\n {stopOnError: true},\n );\n\n if (\n !params.loadIntegrationValidationContext ||\n !parsed.some((entry) => hasAgentStepIntegrations(entry.definition.document))\n ) {\n return parsed.map(({rawContent: _rawContent, ...entry}) => entry);\n }\n\n const integrationValidationContext = await params.loadIntegrationValidationContext();\n return parsed.map((entry) =>\n parseWorkflowSnapshot({\n path: entry.path,\n content: entry.rawContent,\n agentValidationCatalog: params.agentValidationCatalog,\n integrationValidationContext,\n }),\n );\n}\n\nfunction parseWorkflowSnapshot(params: {\n path: string;\n content: string;\n integrationValidationContext?: IntegrationValidationContext | undefined;\n agentValidationCatalog: AgentValidationCatalog;\n}): ParsedWorkflow {\n try {\n const definition =\n params.integrationValidationContext === undefined\n ? parseDefinition(params.content, {agentValidationCatalog: params.agentValidationCatalog})\n : parseDefinition(params.content, {\n agentValidationCatalog: params.agentValidationCatalog,\n integrationValidationContext: params.integrationValidationContext,\n });\n const contentHash = sha256Hex(params.content);\n return {path: params.path, name: definition.document.name, definition, contentHash};\n } catch (error) {\n if (error instanceof DefinitionParseError) {\n throw new DefinitionSyncPermanentError(\n 'invalid-definition',\n `Invalid workflow definition at ${params.path}: ${error.message}`,\n );\n }\n throw error;\n }\n}\n\nexport interface SyncFailureClassification {\n code: DefinitionSyncErrorCode;\n message: string;\n retryable: boolean;\n}\n\nexport function classifySyncFailure(error: unknown): SyncFailureClassification {\n if (error instanceof DefinitionSyncPermanentError) {\n return {code: error.code, message: error.message, retryable: false};\n }\n const methods = [\n integrationsInterModuleContract.methods.resolveSourceRepository,\n integrationsInterModuleContract.methods.listSourceFiles,\n integrationsInterModuleContract.methods.fetchSourceFile,\n ] as const;\n for (const method of methods) {\n if (!isInterModuleKnownError(method, error)) continue;\n if (\n error.code === 'connection-not-found' ||\n error.code === 'connection-inactive' ||\n error.code === 'connection-workspace-mismatch'\n ) {\n return {code: 'connection-unavailable', message: error.message, retryable: false};\n }\n if (error.code === 'provider-failure') {\n return {\n code: providerErrorCode(error.details.reason),\n message: error.message,\n retryable: isProviderReasonRetryable(error.details.reason),\n };\n }\n }\n return {\n code: 'unknown',\n message: error instanceof Error ? error.message : String(error),\n retryable: true,\n };\n}\n\nfunction isProviderReasonRetryable(reason: string): boolean {\n return reason === 'rate-limited' || reason === 'timeout' || reason === 'provider-unavailable';\n}\n\nfunction providerErrorCode(reason: string): DefinitionSyncErrorCode {\n if (reason === 'repository-not-found') return 'provider-repository-not-found';\n if (reason === 'file-not-found') return 'provider-file-not-found';\n if (reason === 'access-denied') return 'provider-access-denied';\n if (reason === 'rate-limited') return 'provider-rate-limited';\n if (reason === 'timeout') return 'provider-timeout';\n if (reason === 'provider-unavailable') return 'provider-unavailable';\n if (reason === 'malformed-provider-response') return 'provider-malformed-response';\n if (reason === 'content-too-large') return 'content-too-large';\n if (reason === 'too-many-files') return 'too-many-files';\n return 'unknown';\n}\n\nfunction sha256Hex(content: string): string {\n return createHash('sha256').update(content, 'utf8').digest('hex');\n}\n"],"names":["createHash","integrationsInterModuleContract","isInterModuleKnownError","boundedMap","DefinitionParseError","DefinitionSyncPermanentError","hasAgentStepIntegrations","parseDefinition","WORKFLOW_PREFIX","MAX_WORKFLOW_FILES","MAX_WORKFLOW_FILE_BYTES","FILE_FETCH_CONCURRENCY","UNRESOLVED_SYNC_REF","resolveSyncSource","params","source","sourceControl","resolveRepository","workspaceId","connectionId","sourceConnectionId","externalRepositoryId","sourceExternalRepositoryId","ref","repository","defaultBranch","discoverWorkflowFiles","page","listFiles","prefix","limit","nextCursor","paths","files","filter","file","path","endsWith","map","length","fetchAndParseWorkflows","parsed","onProgress","snapshot","fetchFile","Buffer","byteLength","content","parseWorkflowSnapshot","agentValidationCatalog","rawContent","stopOnError","loadIntegrationValidationContext","some","entry","definition","document","_rawContent","integrationValidationContext","undefined","contentHash","sha256Hex","name","error","message","classifySyncFailure","code","retryable","methods","resolveSourceRepository","listSourceFiles","fetchSourceFile","method","providerErrorCode","details","reason","isProviderReasonRetryable","Error","String","update","digest"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/sync-definitions.ts"],"sourcesContent":["import {createHash} from 'node:crypto';\nimport type {AgentValidationCatalog} from '@shipfox/api-agent-dto/inter-module';\nimport {integrationsInterModuleContract} from '@shipfox/api-integration-core-dto/inter-module';\nimport {isInterModuleKnownError} from '@shipfox/inter-module';\nimport {boundedMap} from '@shipfox/node-module';\nimport type {IntegrationValidationContext} from './entities/integration-context.js';\nimport type {DefinitionSyncErrorCode} from './entities/sync-state.js';\nimport type {WorkflowDefinitionPayload} from './entities/workflow-definition.js';\nimport {DefinitionParseError, DefinitionSyncPermanentError} from './errors.js';\nimport {hasAgentStepIntegrations} from './has-agent-step-integrations.js';\nimport type {DefinitionsSourceControl} from './integrations.js';\nimport {parseDefinition} from './parse-definition.js';\n\nexport const DEFAULT_WORKFLOW_PATH = '.shipfox/workflows/';\nexport const MAX_WORKFLOW_FILES = 100;\nexport const MAX_WORKFLOW_FILE_BYTES = 1_000_000;\nexport const FILE_FETCH_CONCURRENCY = 4;\nexport const UNRESOLVED_SYNC_REF = '__unresolved__';\n\nexport interface SyncSourceContext {\n workspaceId: string;\n sourceConnectionId: string;\n sourceExternalRepositoryId: string;\n sourceControl: DefinitionsSourceControl;\n}\n\nexport interface ResolvedSyncSource {\n ref: string;\n}\n\nexport async function resolveSyncSource(params: SyncSourceContext): Promise<ResolvedSyncSource> {\n const source = await params.sourceControl.resolveRepository({\n workspaceId: params.workspaceId,\n connectionId: params.sourceConnectionId,\n externalRepositoryId: params.sourceExternalRepositoryId,\n });\n return {ref: source.repository.defaultBranch};\n}\n\nexport interface DiscoverWorkflowFilesParams extends SyncSourceContext {\n ref: string;\n workflowPath?: string | undefined;\n}\n\nexport async function discoverWorkflowFiles(\n params: DiscoverWorkflowFilesParams,\n): Promise<{paths: string[]}> {\n const workflowPath = params.workflowPath ?? DEFAULT_WORKFLOW_PATH;\n const page = await params.sourceControl.listFiles({\n workspaceId: params.workspaceId,\n connectionId: params.sourceConnectionId,\n externalRepositoryId: params.sourceExternalRepositoryId,\n ref: params.ref,\n prefix: workflowPath,\n limit: MAX_WORKFLOW_FILES,\n });\n if (page.nextCursor) {\n throw new DefinitionSyncPermanentError(\n 'too-many-files',\n `More than ${MAX_WORKFLOW_FILES} workflow files were found`,\n );\n }\n\n const paths = page.files\n .filter((file) => file.path.endsWith('.yml') || file.path.endsWith('.yaml'))\n .map((file) => file.path);\n if (paths.length === 0) {\n throw new DefinitionSyncPermanentError(\n 'no-workflow-files',\n `No workflow files were found under ${workflowPath}`,\n );\n }\n\n return {paths};\n}\n\nexport interface ParsedWorkflow {\n path: string;\n name: string;\n definition: WorkflowDefinitionPayload;\n contentHash: string;\n}\n\nexport interface FetchAndParseWorkflowsParams extends SyncSourceContext {\n ref: string;\n paths: string[];\n onProgress?: ((path: string) => void) | undefined;\n agentValidationCatalog: AgentValidationCatalog;\n loadIntegrationValidationContext?: (() => Promise<IntegrationValidationContext>) | undefined;\n}\n\nexport async function fetchAndParseWorkflows(\n params: FetchAndParseWorkflowsParams,\n): Promise<ParsedWorkflow[]> {\n const parsed = await boundedMap(\n params.paths,\n FILE_FETCH_CONCURRENCY,\n async (path) => {\n params.onProgress?.(path);\n\n const snapshot = await params.sourceControl.fetchFile({\n workspaceId: params.workspaceId,\n connectionId: params.sourceConnectionId,\n externalRepositoryId: params.sourceExternalRepositoryId,\n ref: params.ref,\n path,\n });\n\n if (Buffer.byteLength(snapshot.content, 'utf8') > MAX_WORKFLOW_FILE_BYTES) {\n throw new DefinitionSyncPermanentError(\n 'content-too-large',\n `Workflow file is larger than ${MAX_WORKFLOW_FILE_BYTES} bytes: ${snapshot.path}`,\n );\n }\n\n return {\n ...parseWorkflowSnapshot({\n path: snapshot.path,\n content: snapshot.content,\n agentValidationCatalog: params.agentValidationCatalog,\n }),\n rawContent: snapshot.content,\n };\n },\n {stopOnError: true},\n );\n\n if (\n !params.loadIntegrationValidationContext ||\n !parsed.some((entry) => hasAgentStepIntegrations(entry.definition.document))\n ) {\n return parsed.map(({rawContent: _rawContent, ...entry}) => entry);\n }\n\n const integrationValidationContext = await params.loadIntegrationValidationContext();\n return parsed.map((entry) =>\n parseWorkflowSnapshot({\n path: entry.path,\n content: entry.rawContent,\n agentValidationCatalog: params.agentValidationCatalog,\n integrationValidationContext,\n }),\n );\n}\n\nfunction parseWorkflowSnapshot(params: {\n path: string;\n content: string;\n integrationValidationContext?: IntegrationValidationContext | undefined;\n agentValidationCatalog: AgentValidationCatalog;\n}): ParsedWorkflow {\n try {\n const definition =\n params.integrationValidationContext === undefined\n ? parseDefinition(params.content, {agentValidationCatalog: params.agentValidationCatalog})\n : parseDefinition(params.content, {\n agentValidationCatalog: params.agentValidationCatalog,\n integrationValidationContext: params.integrationValidationContext,\n });\n const contentHash = sha256Hex(params.content);\n return {path: params.path, name: definition.document.name, definition, contentHash};\n } catch (error) {\n if (error instanceof DefinitionParseError) {\n throw new DefinitionSyncPermanentError(\n 'invalid-definition',\n `Invalid workflow definition at ${params.path}: ${error.message}`,\n );\n }\n throw error;\n }\n}\n\nexport interface SyncFailureClassification {\n code: DefinitionSyncErrorCode;\n message: string;\n retryable: boolean;\n}\n\nexport function classifySyncFailure(error: unknown): SyncFailureClassification {\n if (error instanceof DefinitionSyncPermanentError) {\n return {code: error.code, message: error.message, retryable: false};\n }\n const methods = [\n integrationsInterModuleContract.methods.resolveSourceRepository,\n integrationsInterModuleContract.methods.listSourceFiles,\n integrationsInterModuleContract.methods.fetchSourceFile,\n ] as const;\n for (const method of methods) {\n if (!isInterModuleKnownError(method, error)) continue;\n if (\n error.code === 'connection-not-found' ||\n error.code === 'connection-inactive' ||\n error.code === 'connection-workspace-mismatch'\n ) {\n return {code: 'connection-unavailable', message: error.message, retryable: false};\n }\n if (error.code === 'provider-failure') {\n return {\n code: providerErrorCode(error.details.reason),\n message: error.message,\n retryable: isProviderReasonRetryable(error.details.reason),\n };\n }\n }\n return {\n code: 'unknown',\n message: error instanceof Error ? error.message : String(error),\n retryable: true,\n };\n}\n\nfunction isProviderReasonRetryable(reason: string): boolean {\n return reason === 'rate-limited' || reason === 'timeout' || reason === 'provider-unavailable';\n}\n\nfunction providerErrorCode(reason: string): DefinitionSyncErrorCode {\n if (reason === 'repository-not-found') return 'provider-repository-not-found';\n if (reason === 'file-not-found') return 'provider-file-not-found';\n if (reason === 'access-denied') return 'provider-access-denied';\n if (reason === 'rate-limited') return 'provider-rate-limited';\n if (reason === 'timeout') return 'provider-timeout';\n if (reason === 'provider-unavailable') return 'provider-unavailable';\n if (reason === 'malformed-provider-response') return 'provider-malformed-response';\n if (reason === 'content-too-large') return 'content-too-large';\n if (reason === 'too-many-files') return 'too-many-files';\n return 'unknown';\n}\n\nfunction sha256Hex(content: string): string {\n return createHash('sha256').update(content, 'utf8').digest('hex');\n}\n"],"names":["createHash","integrationsInterModuleContract","isInterModuleKnownError","boundedMap","DefinitionParseError","DefinitionSyncPermanentError","hasAgentStepIntegrations","parseDefinition","DEFAULT_WORKFLOW_PATH","MAX_WORKFLOW_FILES","MAX_WORKFLOW_FILE_BYTES","FILE_FETCH_CONCURRENCY","UNRESOLVED_SYNC_REF","resolveSyncSource","params","source","sourceControl","resolveRepository","workspaceId","connectionId","sourceConnectionId","externalRepositoryId","sourceExternalRepositoryId","ref","repository","defaultBranch","discoverWorkflowFiles","workflowPath","page","listFiles","prefix","limit","nextCursor","paths","files","filter","file","path","endsWith","map","length","fetchAndParseWorkflows","parsed","onProgress","snapshot","fetchFile","Buffer","byteLength","content","parseWorkflowSnapshot","agentValidationCatalog","rawContent","stopOnError","loadIntegrationValidationContext","some","entry","definition","document","_rawContent","integrationValidationContext","undefined","contentHash","sha256Hex","name","error","message","classifySyncFailure","code","retryable","methods","resolveSourceRepository","listSourceFiles","fetchSourceFile","method","providerErrorCode","details","reason","isProviderReasonRetryable","Error","String","update","digest"],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,qCAAqC,CAAC;AAMhF,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,gDAAgD,CAAC;AAM7F,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAC,KAAK,aAAa,EAAoB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,qCAAqC,CAAC;AAMhF,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,gDAAgD,CAAC;AAM7F,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAC,KAAK,aAAa,EAAoB,MAAM,sBAAsB,CAAC;AAa3E,YAAY,EACV,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,aAAa,EACb,wBAAwB,EACxB,sBAAsB,EACtB,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAC,EAAE,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAC,MAAM,cAAc,CAAC;AAOtF,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,KAAK,EAAE,sBAAsB,CAAC;IAC9B,YAAY,EAAE,wBAAwB,CAAC;CACxC;AAED,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,KAAK,EACL,YAAY,GACb,EAAE,8BAA8B,GAAG,aAAa,CA+BhD"}
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { createDefinitionRoutes } from '#presentation/index.js';
|
|
|
10
10
|
import { createDefinitionsInterModulePresentation } from '#presentation/inter-module.js';
|
|
11
11
|
import { onProjectSourceBound, onProjectSourceCommitObserved } from '#presentation/subscribers/index.js';
|
|
12
12
|
import { createDefinitionSyncActivities, DEFINITIONS_TASK_QUEUE } from '#temporal/index.js';
|
|
13
|
+
import { definitionWorkflowPath } from './config.js';
|
|
13
14
|
export { DEFAULT_JOB_CHECKOUT, DEFAULT_JOB_SUCCESS, DEFAULT_RUN_TIMEOUT_MS, normalizeWorkflowDocument } from '#core/index.js';
|
|
14
15
|
export { db, definitionsOutbox, getDefinitionById, migrationsPath } from '#db/index.js';
|
|
15
16
|
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
@@ -51,7 +52,9 @@ export function createDefinitionsModule({ projects, agent, integrations }) {
|
|
|
51
52
|
{
|
|
52
53
|
taskQueue: DEFINITIONS_TASK_QUEUE,
|
|
53
54
|
workflowsPath,
|
|
54
|
-
activities: ()=>createDefinitionSyncActivities(sourceControl, agent, integrations
|
|
55
|
+
activities: ()=>createDefinitionSyncActivities(sourceControl, agent, integrations, {
|
|
56
|
+
workflowPath: definitionWorkflowPath
|
|
57
|
+
}),
|
|
55
58
|
workflows: []
|
|
56
59
|
}
|
|
57
60
|
],
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';\nimport {\n DEFINITION_RESOLVED,\n type DefinitionsEventMap,\n definitionsEventSchemas,\n} from '@shipfox/api-definitions-dto';\nimport type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport {\n PROJECT_SOURCE_BOUND,\n PROJECT_SOURCE_COMMIT_OBSERVED,\n type ProjectsEventMap,\n} from '@shipfox/api-projects-dto';\nimport type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';\nimport {type ShipfoxModule, subscriberFactory} from '@shipfox/node-module';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport {createDefinitionsSourceControl} from '#core/integrations.js';\nimport {db, definitionsOutbox, migrationsPath} from '#db/index.js';\nimport {createDefinitionRoutes} from '#presentation/index.js';\nimport {createDefinitionsInterModulePresentation} from '#presentation/inter-module.js';\nimport {\n onProjectSourceBound,\n onProjectSourceCommitObserved,\n} from '#presentation/subscribers/index.js';\nimport {createDefinitionSyncActivities, DEFINITIONS_TASK_QUEUE} from '#temporal/index.js';\n\nexport type {\n WorkflowDefinition,\n WorkflowDefinitionPayload,\n WorkflowEnvTemplates,\n WorkflowModel,\n WorkflowModelJobCheckout,\n WorkflowSourceSnapshot,\n WorkflowSpec,\n} from '#core/index.js';\nexport {\n DEFAULT_JOB_CHECKOUT,\n DEFAULT_JOB_SUCCESS,\n DEFAULT_RUN_TIMEOUT_MS,\n normalizeWorkflowDocument,\n} from '#core/index.js';\nexport {db, definitionsOutbox, getDefinitionById, migrationsPath} from '#db/index.js';\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\nconst workflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');\n\nconst subscriber = subscriberFactory<DefinitionsEventMap & ProjectsEventMap>();\n\nexport interface CreateDefinitionsModuleOptions {\n projects: ProjectsModuleClient;\n agent: AgentInterModuleClient;\n integrations: IntegrationsModuleClient;\n}\n\nexport function createDefinitionsModule({\n projects,\n agent,\n integrations,\n}: CreateDefinitionsModuleOptions): ShipfoxModule {\n const sourceControl = createDefinitionsSourceControl(integrations);\n\n return {\n name: 'definitions',\n database: {db, migrationsPath, databaseNamespace: 'definitions'},\n routes: createDefinitionRoutes({projects, agent, integrations}),\n publishers: [\n {name: 'definitions', table: definitionsOutbox, db, eventSchemas: definitionsEventSchemas},\n ],\n subscribers: [\n subscriber(DEFINITION_RESOLVED, (_payload, event) => {\n logger().info({event}, 'Definition resolved');\n return Promise.resolve();\n }),\n subscriber(PROJECT_SOURCE_BOUND, onProjectSourceBound),\n subscriber(PROJECT_SOURCE_COMMIT_OBSERVED, onProjectSourceCommitObserved),\n ],\n workers: [\n {\n taskQueue: DEFINITIONS_TASK_QUEUE,\n workflowsPath,\n activities: ()
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';\nimport {\n DEFINITION_RESOLVED,\n type DefinitionsEventMap,\n definitionsEventSchemas,\n} from '@shipfox/api-definitions-dto';\nimport type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport {\n PROJECT_SOURCE_BOUND,\n PROJECT_SOURCE_COMMIT_OBSERVED,\n type ProjectsEventMap,\n} from '@shipfox/api-projects-dto';\nimport type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';\nimport {type ShipfoxModule, subscriberFactory} from '@shipfox/node-module';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport {createDefinitionsSourceControl} from '#core/integrations.js';\nimport {db, definitionsOutbox, migrationsPath} from '#db/index.js';\nimport {createDefinitionRoutes} from '#presentation/index.js';\nimport {createDefinitionsInterModulePresentation} from '#presentation/inter-module.js';\nimport {\n onProjectSourceBound,\n onProjectSourceCommitObserved,\n} from '#presentation/subscribers/index.js';\nimport {createDefinitionSyncActivities, DEFINITIONS_TASK_QUEUE} from '#temporal/index.js';\nimport {definitionWorkflowPath} from './config.js';\n\nexport type {\n WorkflowDefinition,\n WorkflowDefinitionPayload,\n WorkflowEnvTemplates,\n WorkflowModel,\n WorkflowModelJobCheckout,\n WorkflowSourceSnapshot,\n WorkflowSpec,\n} from '#core/index.js';\nexport {\n DEFAULT_JOB_CHECKOUT,\n DEFAULT_JOB_SUCCESS,\n DEFAULT_RUN_TIMEOUT_MS,\n normalizeWorkflowDocument,\n} from '#core/index.js';\nexport {db, definitionsOutbox, getDefinitionById, migrationsPath} from '#db/index.js';\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\nconst workflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');\n\nconst subscriber = subscriberFactory<DefinitionsEventMap & ProjectsEventMap>();\n\nexport interface CreateDefinitionsModuleOptions {\n projects: ProjectsModuleClient;\n agent: AgentInterModuleClient;\n integrations: IntegrationsModuleClient;\n}\n\nexport function createDefinitionsModule({\n projects,\n agent,\n integrations,\n}: CreateDefinitionsModuleOptions): ShipfoxModule {\n const sourceControl = createDefinitionsSourceControl(integrations);\n\n return {\n name: 'definitions',\n database: {db, migrationsPath, databaseNamespace: 'definitions'},\n routes: createDefinitionRoutes({projects, agent, integrations}),\n publishers: [\n {name: 'definitions', table: definitionsOutbox, db, eventSchemas: definitionsEventSchemas},\n ],\n subscribers: [\n subscriber(DEFINITION_RESOLVED, (_payload, event) => {\n logger().info({event}, 'Definition resolved');\n return Promise.resolve();\n }),\n subscriber(PROJECT_SOURCE_BOUND, onProjectSourceBound),\n subscriber(PROJECT_SOURCE_COMMIT_OBSERVED, onProjectSourceCommitObserved),\n ],\n workers: [\n {\n taskQueue: DEFINITIONS_TASK_QUEUE,\n workflowsPath,\n activities: () =>\n createDefinitionSyncActivities(sourceControl, agent, integrations, {\n workflowPath: definitionWorkflowPath,\n }),\n workflows: [],\n },\n ],\n interModulePresentations: [createDefinitionsInterModulePresentation()],\n };\n}\n"],"names":["dirname","resolve","fileURLToPath","DEFINITION_RESOLVED","definitionsEventSchemas","PROJECT_SOURCE_BOUND","PROJECT_SOURCE_COMMIT_OBSERVED","subscriberFactory","logger","createDefinitionsSourceControl","db","definitionsOutbox","migrationsPath","createDefinitionRoutes","createDefinitionsInterModulePresentation","onProjectSourceBound","onProjectSourceCommitObserved","createDefinitionSyncActivities","DEFINITIONS_TASK_QUEUE","definitionWorkflowPath","DEFAULT_JOB_CHECKOUT","DEFAULT_JOB_SUCCESS","DEFAULT_RUN_TIMEOUT_MS","normalizeWorkflowDocument","getDefinitionById","packageRoot","url","workflowsPath","subscriber","createDefinitionsModule","projects","agent","integrations","sourceControl","name","database","databaseNamespace","routes","publishers","table","eventSchemas","subscribers","_payload","event","info","Promise","workers","taskQueue","activities","workflowPath","workflows","interModulePresentations"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAEvC,SACEC,mBAAmB,EAEnBC,uBAAuB,QAClB,+BAA+B;AAEtC,SACEC,oBAAoB,EACpBC,8BAA8B,QAEzB,4BAA4B;AAEnC,SAA4BC,iBAAiB,QAAO,uBAAuB;AAC3E,SAAQC,MAAM,QAAO,8BAA8B;AACnD,SAAQC,8BAA8B,QAAO,wBAAwB;AACrE,SAAQC,EAAE,EAAEC,iBAAiB,EAAEC,cAAc,QAAO,eAAe;AACnE,SAAQC,sBAAsB,QAAO,yBAAyB;AAC9D,SAAQC,wCAAwC,QAAO,gCAAgC;AACvF,SACEC,oBAAoB,EACpBC,6BAA6B,QACxB,qCAAqC;AAC5C,SAAQC,8BAA8B,EAAEC,sBAAsB,QAAO,qBAAqB;AAC1F,SAAQC,sBAAsB,QAAO,cAAc;AAWnD,SACEC,oBAAoB,EACpBC,mBAAmB,EACnBC,sBAAsB,EACtBC,yBAAyB,QACpB,iBAAiB;AACxB,SAAQb,EAAE,EAAEC,iBAAiB,EAAEa,iBAAiB,EAAEZ,cAAc,QAAO,eAAe;AAEtF,MAAMa,cAAcxB,QAAQD,QAAQE,cAAc,YAAYwB,GAAG,IAAI;AACrE,MAAMC,gBAAgB1B,QAAQwB,aAAa;AAE3C,MAAMG,aAAarB;AAQnB,OAAO,SAASsB,wBAAwB,EACtCC,QAAQ,EACRC,KAAK,EACLC,YAAY,EACmB;IAC/B,MAAMC,gBAAgBxB,+BAA+BuB;IAErD,OAAO;QACLE,MAAM;QACNC,UAAU;YAACzB;YAAIE;YAAgBwB,mBAAmB;QAAa;QAC/DC,QAAQxB,uBAAuB;YAACiB;YAAUC;YAAOC;QAAY;QAC7DM,YAAY;YACV;gBAACJ,MAAM;gBAAeK,OAAO5B;gBAAmBD;gBAAI8B,cAAcpC;YAAuB;SAC1F;QACDqC,aAAa;YACXb,WAAWzB,qBAAqB,CAACuC,UAAUC;gBACzCnC,SAASoC,IAAI,CAAC;oBAACD;gBAAK,GAAG;gBACvB,OAAOE,QAAQ5C,OAAO;YACxB;YACA2B,WAAWvB,sBAAsBU;YACjCa,WAAWtB,gCAAgCU;SAC5C;QACD8B,SAAS;YACP;gBACEC,WAAW7B;gBACXS;gBACAqB,YAAY,IACV/B,+BAA+BgB,eAAeF,OAAOC,cAAc;wBACjEiB,cAAc9B;oBAChB;gBACF+B,WAAW,EAAE;YACf;SACD;QACDC,0BAA0B;YAACrC;SAA2C;IACxE;AACF"}
|
|
@@ -32,7 +32,10 @@ export interface FetchAndApplyActivityResult {
|
|
|
32
32
|
appliedCount: number;
|
|
33
33
|
deletedCount: number;
|
|
34
34
|
}
|
|
35
|
-
export
|
|
35
|
+
export interface DefinitionSyncActivityOptions {
|
|
36
|
+
workflowPath: string;
|
|
37
|
+
}
|
|
38
|
+
export declare function createDefinitionSyncActivities(sourceControl: DefinitionsSourceControl, agent: AgentInterModuleClient, integrations?: IntegrationsModuleClient | undefined, options?: DefinitionSyncActivityOptions | undefined): {
|
|
36
39
|
prepareDefinitionSync: (input: SyncWorkflowInput) => Promise<PrepareSyncResult>;
|
|
37
40
|
discoverDefinitionWorkflows: (input: SyncRefScopedInput) => Promise<DiscoverWorkflowsActivityResult>;
|
|
38
41
|
fetchAndApplyDefinitionWorkflows: (input: FetchAndApplyActivityInput) => Promise<FetchAndApplyActivityResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-activities.d.ts","sourceRoot":"","sources":["../../../src/temporal/activities/sync-activities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,gDAAgD,CAAC;AAI7F,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,8BAA8B,CAAC;AAQ1E,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,uBAAuB,CAAC;AAIpE,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0BAA0B,EAAE,MAAM,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,0BAA2B,SAAQ,kBAAkB;IACpE,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,2BAA4B,SAAQ,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC;IACvF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,uBAAuB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,2BAA2B;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,8BAA8B,CAC5C,aAAa,EAAE,wBAAwB,EACvC,KAAK,EAAE,sBAAsB,EAC7B,YAAY,CAAC,EAAE,wBAAwB,GAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"sync-activities.d.ts","sourceRoot":"","sources":["../../../src/temporal/activities/sync-activities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,gDAAgD,CAAC;AAI7F,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,8BAA8B,CAAC;AAQ1E,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,uBAAuB,CAAC;AAIpE,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0BAA0B,EAAE,MAAM,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,0BAA2B,SAAQ,kBAAkB;IACpE,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,2BAA4B,SAAQ,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC;IACvF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,uBAAuB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,2BAA2B;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,6BAA6B;IAC5C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,8BAA8B,CAC5C,aAAa,EAAE,wBAAwB,EACvC,KAAK,EAAE,sBAAsB,EAC7B,YAAY,CAAC,EAAE,wBAAwB,GAAG,SAAS,EACnD,OAAO,CAAC,EAAE,6BAA6B,GAAG,SAAS;mCAoB1C,iBAAiB,KACvB,OAAO,CAAC,iBAAiB,CAAC;yCA0BpB,kBAAkB,KACxB,OAAO,CAAC,+BAA+B,CAAC;8CAkBlC,0BAA0B,KAChC,OAAO,CAAC,2BAA2B,CAAC;yCAsCkB,kBAAkB,KAAG,OAAO,CAAC,IAAI,CAAC;sCAgBlF,2BAA2B,KACjC,OAAO,CAAC,IAAI,CAAC;EA1GjB"}
|
|
@@ -4,10 +4,10 @@ import { ApplicationFailure } from '@temporalio/common';
|
|
|
4
4
|
import { classifySyncFailure, discoverWorkflowFiles, fetchAndParseWorkflows, resolveSyncSource, UNRESOLVED_SYNC_REF } from '#core/index.js';
|
|
5
5
|
import { loadIntegrationValidationContext } from '#core/integrations.js';
|
|
6
6
|
import { applyVcsDefinitionsBatch, markDefinitionSyncState } from '#db/index.js';
|
|
7
|
-
export function createDefinitionSyncActivities(sourceControl, agent, integrations) {
|
|
7
|
+
export function createDefinitionSyncActivities(sourceControl, agent, integrations, options) {
|
|
8
8
|
return {
|
|
9
9
|
prepareDefinitionSync: createPrepareDefinitionSyncActivity(sourceControl),
|
|
10
|
-
discoverDefinitionWorkflows: createDiscoverDefinitionWorkflowsActivity(sourceControl),
|
|
10
|
+
discoverDefinitionWorkflows: createDiscoverDefinitionWorkflowsActivity(sourceControl, options?.workflowPath),
|
|
11
11
|
fetchAndApplyDefinitionWorkflows: createFetchAndApplyActivity(sourceControl, agent, integrations),
|
|
12
12
|
markDefinitionSyncSucceeded: createMarkSyncSucceededActivity(),
|
|
13
13
|
markDefinitionSyncFailed: createMarkSyncFailedActivity()
|
|
@@ -38,13 +38,14 @@ function createPrepareDefinitionSyncActivity(sourceControl) {
|
|
|
38
38
|
});
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
function createDiscoverDefinitionWorkflowsActivity(sourceControl) {
|
|
41
|
+
function createDiscoverDefinitionWorkflowsActivity(sourceControl, workflowPath) {
|
|
42
42
|
return async function discoverDefinitionWorkflows(input) {
|
|
43
43
|
return await runWithPermanentTranslation(async ()=>{
|
|
44
44
|
return await discoverWorkflowFiles({
|
|
45
45
|
...input,
|
|
46
46
|
ref: input.sourceCommitSha ?? input.sourceRef,
|
|
47
|
-
sourceControl
|
|
47
|
+
sourceControl,
|
|
48
|
+
workflowPath
|
|
48
49
|
});
|
|
49
50
|
});
|
|
50
51
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/temporal/activities/sync-activities.ts"],"sourcesContent":["import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';\nimport type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport {markErrorReported} from '@shipfox/node-error-monitoring';\nimport {Context} from '@temporalio/activity';\nimport {ApplicationFailure} from '@temporalio/common';\nimport type {DefinitionSyncErrorCode} from '#core/entities/sync-state.js';\nimport {\n classifySyncFailure,\n discoverWorkflowFiles,\n fetchAndParseWorkflows,\n resolveSyncSource,\n UNRESOLVED_SYNC_REF,\n} from '#core/index.js';\nimport type {DefinitionsSourceControl} from '#core/integrations.js';\nimport {loadIntegrationValidationContext} from '#core/integrations.js';\nimport {applyVcsDefinitionsBatch, markDefinitionSyncState} from '#db/index.js';\n\nexport interface SyncWorkflowInput {\n projectId: string;\n workspaceId: string;\n sourceConnectionId: string;\n sourceExternalRepositoryId: string;\n sourceRef?: string | undefined;\n sourceCommitSha?: string | undefined;\n}\n\nexport interface SyncRefScopedInput extends SyncWorkflowInput {\n sourceRef: string;\n}\n\nexport interface FetchAndApplyActivityInput extends SyncRefScopedInput {\n paths: string[];\n}\n\nexport interface MarkSyncFailedActivityInput extends Omit<SyncWorkflowInput, 'sourceRef'> {\n sourceRef: string | null;\n code: DefinitionSyncErrorCode;\n message: string;\n}\n\nexport interface PrepareSyncResult {\n sourceRef: string;\n sourceCommitSha?: string | undefined;\n}\n\nexport interface DiscoverWorkflowsActivityResult {\n paths: string[];\n}\n\nexport interface FetchAndApplyActivityResult {\n appliedCount: number;\n deletedCount: number;\n}\n\nexport function createDefinitionSyncActivities(\n sourceControl: DefinitionsSourceControl,\n agent: AgentInterModuleClient,\n integrations?: IntegrationsModuleClient | undefined,\n) {\n return {\n prepareDefinitionSync: createPrepareDefinitionSyncActivity(sourceControl),\n discoverDefinitionWorkflows: createDiscoverDefinitionWorkflowsActivity(sourceControl),\n fetchAndApplyDefinitionWorkflows: createFetchAndApplyActivity(\n sourceControl,\n agent,\n integrations,\n ),\n markDefinitionSyncSucceeded: createMarkSyncSucceededActivity(),\n markDefinitionSyncFailed: createMarkSyncFailedActivity(),\n };\n}\n\nfunction createPrepareDefinitionSyncActivity(sourceControl: DefinitionsSourceControl) {\n return async function prepareDefinitionSync(\n input: SyncWorkflowInput,\n ): Promise<PrepareSyncResult> {\n return await runWithPermanentTranslation(async () => {\n const sourceRef = input.sourceRef ?? (await resolveSyncSource({...input, sourceControl})).ref;\n\n await markDefinitionSyncState({\n projectId: input.projectId,\n sourceConnectionId: input.sourceConnectionId,\n sourceExternalRepositoryId: input.sourceExternalRepositoryId,\n ref: sourceRef,\n status: 'syncing',\n lastErrorCode: null,\n lastErrorMessage: null,\n startedAt: new Date(),\n finishedAt: null,\n });\n\n return {sourceRef, sourceCommitSha: input.sourceCommitSha};\n });\n };\n}\n\nfunction createDiscoverDefinitionWorkflowsActivity(sourceControl: DefinitionsSourceControl) {\n return async function discoverDefinitionWorkflows(\n input: SyncRefScopedInput,\n ): Promise<DiscoverWorkflowsActivityResult> {\n return await runWithPermanentTranslation(async () => {\n return await discoverWorkflowFiles({\n ...input,\n ref: input.sourceCommitSha ?? input.sourceRef,\n sourceControl,\n });\n });\n };\n}\n\nfunction createFetchAndApplyActivity(\n sourceControl: DefinitionsSourceControl,\n agent: AgentInterModuleClient,\n integrations?: IntegrationsModuleClient | undefined,\n) {\n return async function fetchAndApplyDefinitionWorkflows(\n input: FetchAndApplyActivityInput,\n ): Promise<FetchAndApplyActivityResult> {\n return await runWithPermanentTranslation(async () => {\n const definitions = await fetchAndParseWorkflows({\n ...input,\n ref: input.sourceCommitSha ?? input.sourceRef,\n sourceControl,\n agentValidationCatalog: await agent.getValidationCatalog({}),\n onProgress: (path) => Context.current().heartbeat({path}),\n loadIntegrationValidationContext:\n integrations === undefined\n ? undefined\n : async () => {\n return await loadIntegrationValidationContext(\n integrations,\n input.workspaceId,\n input.sourceConnectionId,\n );\n },\n });\n\n return await applyVcsDefinitionsBatch({\n projectId: input.projectId,\n workspaceId: input.workspaceId,\n ref: input.sourceRef,\n upserts: definitions.map((entry) => ({\n configPath: entry.path,\n name: entry.name,\n document: entry.definition.document,\n model: entry.definition.model,\n sourceSnapshot: entry.definition.sourceSnapshot,\n contentHash: entry.contentHash,\n })),\n });\n });\n };\n}\n\nfunction createMarkSyncSucceededActivity() {\n return async function markDefinitionSyncSucceeded(input: SyncRefScopedInput): Promise<void> {\n await markDefinitionSyncState({\n projectId: input.projectId,\n sourceConnectionId: input.sourceConnectionId,\n sourceExternalRepositoryId: input.sourceExternalRepositoryId,\n ref: input.sourceRef,\n status: 'succeeded',\n lastErrorCode: null,\n lastErrorMessage: null,\n finishedAt: new Date(),\n });\n };\n}\n\nfunction createMarkSyncFailedActivity() {\n return async function markDefinitionSyncFailed(\n input: MarkSyncFailedActivityInput,\n ): Promise<void> {\n await markDefinitionSyncState({\n projectId: input.projectId,\n sourceConnectionId: input.sourceConnectionId,\n sourceExternalRepositoryId: input.sourceExternalRepositoryId,\n ref: input.sourceRef ?? UNRESOLVED_SYNC_REF,\n status: 'failed',\n lastErrorCode: input.code,\n lastErrorMessage: input.message,\n finishedAt: new Date(),\n });\n };\n}\n\nasync function runWithPermanentTranslation<T>(operation: () => Promise<T>): Promise<T> {\n try {\n return await operation();\n } catch (error) {\n if (error instanceof ApplicationFailure) {\n throw error;\n }\n const failure = classifySyncFailure(error);\n const translatedError = failure.retryable\n ? ApplicationFailure.retryable(failure.message, failure.code)\n : ApplicationFailure.nonRetryable(failure.message, failure.code);\n if (failure.code !== 'unknown') markErrorReported(translatedError);\n throw translatedError;\n }\n}\n"],"names":["markErrorReported","Context","ApplicationFailure","classifySyncFailure","discoverWorkflowFiles","fetchAndParseWorkflows","resolveSyncSource","UNRESOLVED_SYNC_REF","loadIntegrationValidationContext","applyVcsDefinitionsBatch","markDefinitionSyncState","createDefinitionSyncActivities","sourceControl","agent","integrations","prepareDefinitionSync","createPrepareDefinitionSyncActivity","discoverDefinitionWorkflows","createDiscoverDefinitionWorkflowsActivity","fetchAndApplyDefinitionWorkflows","createFetchAndApplyActivity","markDefinitionSyncSucceeded","createMarkSyncSucceededActivity","markDefinitionSyncFailed","createMarkSyncFailedActivity","input","runWithPermanentTranslation","sourceRef","ref","projectId","sourceConnectionId","sourceExternalRepositoryId","status","lastErrorCode","lastErrorMessage","startedAt","Date","finishedAt","sourceCommitSha","definitions","agentValidationCatalog","getValidationCatalog","onProgress","path","current","heartbeat","undefined","workspaceId","upserts","map","entry","configPath","name","document","definition","model","sourceSnapshot","contentHash","code","message","operation","error","failure","translatedError","retryable","nonRetryable"],"mappings":"AAEA,SAAQA,iBAAiB,QAAO,iCAAiC;AACjE,SAAQC,OAAO,QAAO,uBAAuB;AAC7C,SAAQC,kBAAkB,QAAO,qBAAqB;AAEtD,SACEC,mBAAmB,EACnBC,qBAAqB,EACrBC,sBAAsB,EACtBC,iBAAiB,EACjBC,mBAAmB,QACd,iBAAiB;AAExB,SAAQC,gCAAgC,QAAO,wBAAwB;AACvE,SAAQC,wBAAwB,EAAEC,uBAAuB,QAAO,eAAe;AAuC/E,OAAO,SAASC,+BACdC,aAAuC,EACvCC,KAA6B,EAC7BC,YAAmD;IAEnD,OAAO;QACLC,uBAAuBC,oCAAoCJ;QAC3DK,6BAA6BC,0CAA0CN;QACvEO,kCAAkCC,4BAChCR,eACAC,OACAC;QAEFO,6BAA6BC;QAC7BC,0BAA0BC;IAC5B;AACF;AAEA,SAASR,oCAAoCJ,aAAuC;IAClF,OAAO,eAAeG,sBACpBU,KAAwB;QAExB,OAAO,MAAMC,4BAA4B;YACvC,MAAMC,YAAYF,MAAME,SAAS,IAAI,AAAC,CAAA,MAAMrB,kBAAkB;gBAAC,GAAGmB,KAAK;gBAAEb;YAAa,EAAC,EAAGgB,GAAG;YAE7F,MAAMlB,wBAAwB;gBAC5BmB,WAAWJ,MAAMI,SAAS;gBAC1BC,oBAAoBL,MAAMK,kBAAkB;gBAC5CC,4BAA4BN,MAAMM,0BAA0B;gBAC5DH,KAAKD;gBACLK,QAAQ;gBACRC,eAAe;gBACfC,kBAAkB;gBAClBC,WAAW,IAAIC;gBACfC,YAAY;YACd;YAEA,OAAO;gBAACV;gBAAWW,iBAAiBb,MAAMa,eAAe;YAAA;QAC3D;IACF;AACF;AAEA,SAASpB,0CAA0CN,aAAuC;IACxF,OAAO,eAAeK,4BACpBQ,KAAyB;QAEzB,OAAO,MAAMC,4BAA4B;YACvC,OAAO,MAAMtB,sBAAsB;gBACjC,GAAGqB,KAAK;gBACRG,KAAKH,MAAMa,eAAe,IAAIb,MAAME,SAAS;gBAC7Cf;YACF;QACF;IACF;AACF;AAEA,SAASQ,4BACPR,aAAuC,EACvCC,KAA6B,EAC7BC,YAAmD;IAEnD,OAAO,eAAeK,iCACpBM,KAAiC;QAEjC,OAAO,MAAMC,4BAA4B;YACvC,MAAMa,cAAc,MAAMlC,uBAAuB;gBAC/C,GAAGoB,KAAK;gBACRG,KAAKH,MAAMa,eAAe,IAAIb,MAAME,SAAS;gBAC7Cf;gBACA4B,wBAAwB,MAAM3B,MAAM4B,oBAAoB,CAAC,CAAC;gBAC1DC,YAAY,CAACC,OAAS1C,QAAQ2C,OAAO,GAAGC,SAAS,CAAC;wBAACF;oBAAI;gBACvDnC,kCACEM,iBAAiBgC,YACbA,YACA;oBACE,OAAO,MAAMtC,iCACXM,cACAW,MAAMsB,WAAW,EACjBtB,MAAMK,kBAAkB;gBAE5B;YACR;YAEA,OAAO,MAAMrB,yBAAyB;gBACpCoB,WAAWJ,MAAMI,SAAS;gBAC1BkB,aAAatB,MAAMsB,WAAW;gBAC9BnB,KAAKH,MAAME,SAAS;gBACpBqB,SAAST,YAAYU,GAAG,CAAC,CAACC,QAAW,CAAA;wBACnCC,YAAYD,MAAMP,IAAI;wBACtBS,MAAMF,MAAME,IAAI;wBAChBC,UAAUH,MAAMI,UAAU,CAACD,QAAQ;wBACnCE,OAAOL,MAAMI,UAAU,CAACC,KAAK;wBAC7BC,gBAAgBN,MAAMI,UAAU,CAACE,cAAc;wBAC/CC,aAAaP,MAAMO,WAAW;oBAChC,CAAA;YACF;QACF;IACF;AACF;AAEA,SAASnC;IACP,OAAO,eAAeD,4BAA4BI,KAAyB;QACzE,MAAMf,wBAAwB;YAC5BmB,WAAWJ,MAAMI,SAAS;YAC1BC,oBAAoBL,MAAMK,kBAAkB;YAC5CC,4BAA4BN,MAAMM,0BAA0B;YAC5DH,KAAKH,MAAME,SAAS;YACpBK,QAAQ;YACRC,eAAe;YACfC,kBAAkB;YAClBG,YAAY,IAAID;QAClB;IACF;AACF;AAEA,SAASZ;IACP,OAAO,eAAeD,yBACpBE,KAAkC;QAElC,MAAMf,wBAAwB;YAC5BmB,WAAWJ,MAAMI,SAAS;YAC1BC,oBAAoBL,MAAMK,kBAAkB;YAC5CC,4BAA4BN,MAAMM,0BAA0B;YAC5DH,KAAKH,MAAME,SAAS,IAAIpB;YACxByB,QAAQ;YACRC,eAAeR,MAAMiC,IAAI;YACzBxB,kBAAkBT,MAAMkC,OAAO;YAC/BtB,YAAY,IAAID;QAClB;IACF;AACF;AAEA,eAAeV,4BAA+BkC,SAA2B;IACvE,IAAI;QACF,OAAO,MAAMA;IACf,EAAE,OAAOC,OAAO;QACd,IAAIA,iBAAiB3D,oBAAoB;YACvC,MAAM2D;QACR;QACA,MAAMC,UAAU3D,oBAAoB0D;QACpC,MAAME,kBAAkBD,QAAQE,SAAS,GACrC9D,mBAAmB8D,SAAS,CAACF,QAAQH,OAAO,EAAEG,QAAQJ,IAAI,IAC1DxD,mBAAmB+D,YAAY,CAACH,QAAQH,OAAO,EAAEG,QAAQJ,IAAI;QACjE,IAAII,QAAQJ,IAAI,KAAK,WAAW1D,kBAAkB+D;QAClD,MAAMA;IACR;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../src/temporal/activities/sync-activities.ts"],"sourcesContent":["import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';\nimport type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport {markErrorReported} from '@shipfox/node-error-monitoring';\nimport {Context} from '@temporalio/activity';\nimport {ApplicationFailure} from '@temporalio/common';\nimport type {DefinitionSyncErrorCode} from '#core/entities/sync-state.js';\nimport {\n classifySyncFailure,\n discoverWorkflowFiles,\n fetchAndParseWorkflows,\n resolveSyncSource,\n UNRESOLVED_SYNC_REF,\n} from '#core/index.js';\nimport type {DefinitionsSourceControl} from '#core/integrations.js';\nimport {loadIntegrationValidationContext} from '#core/integrations.js';\nimport {applyVcsDefinitionsBatch, markDefinitionSyncState} from '#db/index.js';\n\nexport interface SyncWorkflowInput {\n projectId: string;\n workspaceId: string;\n sourceConnectionId: string;\n sourceExternalRepositoryId: string;\n sourceRef?: string | undefined;\n sourceCommitSha?: string | undefined;\n}\n\nexport interface SyncRefScopedInput extends SyncWorkflowInput {\n sourceRef: string;\n}\n\nexport interface FetchAndApplyActivityInput extends SyncRefScopedInput {\n paths: string[];\n}\n\nexport interface MarkSyncFailedActivityInput extends Omit<SyncWorkflowInput, 'sourceRef'> {\n sourceRef: string | null;\n code: DefinitionSyncErrorCode;\n message: string;\n}\n\nexport interface PrepareSyncResult {\n sourceRef: string;\n sourceCommitSha?: string | undefined;\n}\n\nexport interface DiscoverWorkflowsActivityResult {\n paths: string[];\n}\n\nexport interface FetchAndApplyActivityResult {\n appliedCount: number;\n deletedCount: number;\n}\n\nexport interface DefinitionSyncActivityOptions {\n workflowPath: string;\n}\n\nexport function createDefinitionSyncActivities(\n sourceControl: DefinitionsSourceControl,\n agent: AgentInterModuleClient,\n integrations?: IntegrationsModuleClient | undefined,\n options?: DefinitionSyncActivityOptions | undefined,\n) {\n return {\n prepareDefinitionSync: createPrepareDefinitionSyncActivity(sourceControl),\n discoverDefinitionWorkflows: createDiscoverDefinitionWorkflowsActivity(\n sourceControl,\n options?.workflowPath,\n ),\n fetchAndApplyDefinitionWorkflows: createFetchAndApplyActivity(\n sourceControl,\n agent,\n integrations,\n ),\n markDefinitionSyncSucceeded: createMarkSyncSucceededActivity(),\n markDefinitionSyncFailed: createMarkSyncFailedActivity(),\n };\n}\n\nfunction createPrepareDefinitionSyncActivity(sourceControl: DefinitionsSourceControl) {\n return async function prepareDefinitionSync(\n input: SyncWorkflowInput,\n ): Promise<PrepareSyncResult> {\n return await runWithPermanentTranslation(async () => {\n const sourceRef = input.sourceRef ?? (await resolveSyncSource({...input, sourceControl})).ref;\n\n await markDefinitionSyncState({\n projectId: input.projectId,\n sourceConnectionId: input.sourceConnectionId,\n sourceExternalRepositoryId: input.sourceExternalRepositoryId,\n ref: sourceRef,\n status: 'syncing',\n lastErrorCode: null,\n lastErrorMessage: null,\n startedAt: new Date(),\n finishedAt: null,\n });\n\n return {sourceRef, sourceCommitSha: input.sourceCommitSha};\n });\n };\n}\n\nfunction createDiscoverDefinitionWorkflowsActivity(\n sourceControl: DefinitionsSourceControl,\n workflowPath?: string | undefined,\n) {\n return async function discoverDefinitionWorkflows(\n input: SyncRefScopedInput,\n ): Promise<DiscoverWorkflowsActivityResult> {\n return await runWithPermanentTranslation(async () => {\n return await discoverWorkflowFiles({\n ...input,\n ref: input.sourceCommitSha ?? input.sourceRef,\n sourceControl,\n workflowPath,\n });\n });\n };\n}\n\nfunction createFetchAndApplyActivity(\n sourceControl: DefinitionsSourceControl,\n agent: AgentInterModuleClient,\n integrations?: IntegrationsModuleClient | undefined,\n) {\n return async function fetchAndApplyDefinitionWorkflows(\n input: FetchAndApplyActivityInput,\n ): Promise<FetchAndApplyActivityResult> {\n return await runWithPermanentTranslation(async () => {\n const definitions = await fetchAndParseWorkflows({\n ...input,\n ref: input.sourceCommitSha ?? input.sourceRef,\n sourceControl,\n agentValidationCatalog: await agent.getValidationCatalog({}),\n onProgress: (path) => Context.current().heartbeat({path}),\n loadIntegrationValidationContext:\n integrations === undefined\n ? undefined\n : async () => {\n return await loadIntegrationValidationContext(\n integrations,\n input.workspaceId,\n input.sourceConnectionId,\n );\n },\n });\n\n return await applyVcsDefinitionsBatch({\n projectId: input.projectId,\n workspaceId: input.workspaceId,\n ref: input.sourceRef,\n upserts: definitions.map((entry) => ({\n configPath: entry.path,\n name: entry.name,\n document: entry.definition.document,\n model: entry.definition.model,\n sourceSnapshot: entry.definition.sourceSnapshot,\n contentHash: entry.contentHash,\n })),\n });\n });\n };\n}\n\nfunction createMarkSyncSucceededActivity() {\n return async function markDefinitionSyncSucceeded(input: SyncRefScopedInput): Promise<void> {\n await markDefinitionSyncState({\n projectId: input.projectId,\n sourceConnectionId: input.sourceConnectionId,\n sourceExternalRepositoryId: input.sourceExternalRepositoryId,\n ref: input.sourceRef,\n status: 'succeeded',\n lastErrorCode: null,\n lastErrorMessage: null,\n finishedAt: new Date(),\n });\n };\n}\n\nfunction createMarkSyncFailedActivity() {\n return async function markDefinitionSyncFailed(\n input: MarkSyncFailedActivityInput,\n ): Promise<void> {\n await markDefinitionSyncState({\n projectId: input.projectId,\n sourceConnectionId: input.sourceConnectionId,\n sourceExternalRepositoryId: input.sourceExternalRepositoryId,\n ref: input.sourceRef ?? UNRESOLVED_SYNC_REF,\n status: 'failed',\n lastErrorCode: input.code,\n lastErrorMessage: input.message,\n finishedAt: new Date(),\n });\n };\n}\n\nasync function runWithPermanentTranslation<T>(operation: () => Promise<T>): Promise<T> {\n try {\n return await operation();\n } catch (error) {\n if (error instanceof ApplicationFailure) {\n throw error;\n }\n const failure = classifySyncFailure(error);\n const translatedError = failure.retryable\n ? ApplicationFailure.retryable(failure.message, failure.code)\n : ApplicationFailure.nonRetryable(failure.message, failure.code);\n if (failure.code !== 'unknown') markErrorReported(translatedError);\n throw translatedError;\n }\n}\n"],"names":["markErrorReported","Context","ApplicationFailure","classifySyncFailure","discoverWorkflowFiles","fetchAndParseWorkflows","resolveSyncSource","UNRESOLVED_SYNC_REF","loadIntegrationValidationContext","applyVcsDefinitionsBatch","markDefinitionSyncState","createDefinitionSyncActivities","sourceControl","agent","integrations","options","prepareDefinitionSync","createPrepareDefinitionSyncActivity","discoverDefinitionWorkflows","createDiscoverDefinitionWorkflowsActivity","workflowPath","fetchAndApplyDefinitionWorkflows","createFetchAndApplyActivity","markDefinitionSyncSucceeded","createMarkSyncSucceededActivity","markDefinitionSyncFailed","createMarkSyncFailedActivity","input","runWithPermanentTranslation","sourceRef","ref","projectId","sourceConnectionId","sourceExternalRepositoryId","status","lastErrorCode","lastErrorMessage","startedAt","Date","finishedAt","sourceCommitSha","definitions","agentValidationCatalog","getValidationCatalog","onProgress","path","current","heartbeat","undefined","workspaceId","upserts","map","entry","configPath","name","document","definition","model","sourceSnapshot","contentHash","code","message","operation","error","failure","translatedError","retryable","nonRetryable"],"mappings":"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"}
|