@shipfox/api-definitions 13.1.0 → 14.0.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 +11 -11
- package/CHANGELOG.md +35 -0
- package/dist/core/entities/index.d.ts +1 -1
- package/dist/core/entities/index.d.ts.map +1 -1
- package/dist/core/entities/index.js +1 -1
- package/dist/core/entities/index.js.map +1 -1
- package/dist/core/entities/integration-context.d.ts +4 -0
- package/dist/core/entities/integration-context.d.ts.map +1 -1
- package/dist/core/entities/integration-context.js.map +1 -1
- package/dist/core/entities/sync-state.d.ts +10 -4
- package/dist/core/entities/sync-state.d.ts.map +1 -1
- package/dist/core/entities/sync-state.js +26 -7
- package/dist/core/entities/sync-state.js.map +1 -1
- package/dist/core/entities/validation-diagnostic.d.ts +8 -0
- package/dist/core/entities/validation-diagnostic.d.ts.map +1 -0
- package/dist/core/entities/validation-diagnostic.js +3 -0
- package/dist/core/entities/validation-diagnostic.js.map +1 -0
- package/dist/core/entities/workflow-definition.d.ts +2 -0
- package/dist/core/entities/workflow-definition.d.ts.map +1 -1
- package/dist/core/entities/workflow-definition.js.map +1 -1
- package/dist/core/errors.d.ts +10 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +9 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/integrations.d.ts +3 -1
- package/dist/core/integrations.d.ts.map +1 -1
- package/dist/core/integrations.js +10 -2
- package/dist/core/integrations.js.map +1 -1
- package/dist/core/parse-definition.d.ts +4 -4
- package/dist/core/parse-definition.d.ts.map +1 -1
- package/dist/core/parse-definition.js +5 -5
- package/dist/core/parse-definition.js.map +1 -1
- package/dist/core/resolve-definition-at-ref.d.ts +66 -0
- package/dist/core/resolve-definition-at-ref.d.ts.map +1 -0
- package/dist/core/resolve-definition-at-ref.js +374 -0
- package/dist/core/resolve-definition-at-ref.js.map +1 -0
- package/dist/core/sync-definitions.d.ts +2 -2
- package/dist/core/sync-definitions.d.ts.map +1 -1
- package/dist/core/sync-definitions.js +5 -5
- package/dist/core/sync-definitions.js.map +1 -1
- package/dist/core/validate-definition.d.ts +3 -3
- package/dist/core/validate-definition.d.ts.map +1 -1
- package/dist/core/validate-definition.js +17 -12
- package/dist/core/validate-definition.js.map +1 -1
- package/dist/core/workflow-model/cron-trigger.d.ts +1 -1
- package/dist/core/workflow-model/cron-trigger.d.ts.map +1 -1
- package/dist/core/workflow-model/cron-trigger.js +9 -5
- package/dist/core/workflow-model/cron-trigger.js.map +1 -1
- package/dist/core/workflow-model/index.d.ts +1 -1
- package/dist/core/workflow-model/index.d.ts.map +1 -1
- package/dist/core/workflow-model/index.js.map +1 -1
- package/dist/core/workflow-model/invalid-workflow-model-error.d.ts +4 -2
- package/dist/core/workflow-model/invalid-workflow-model-error.d.ts.map +1 -1
- package/dist/core/workflow-model/invalid-workflow-model-error.js.map +1 -1
- package/dist/core/workflow-model/normalize-job-listening.d.ts.map +1 -1
- package/dist/core/workflow-model/normalize-job-listening.js +51 -30
- package/dist/core/workflow-model/normalize-job-listening.js.map +1 -1
- package/dist/core/workflow-model/normalize-triggers.d.ts +1 -1
- package/dist/core/workflow-model/normalize-triggers.d.ts.map +1 -1
- package/dist/core/workflow-model/normalize-triggers.js +48 -18
- package/dist/core/workflow-model/normalize-triggers.js.map +1 -1
- package/dist/core/workflow-model/normalize-workflow-document.d.ts +1 -1
- package/dist/core/workflow-model/normalize-workflow-document.d.ts.map +1 -1
- package/dist/core/workflow-model/normalize-workflow-document.js +3 -3
- package/dist/core/workflow-model/normalize-workflow-document.js.map +1 -1
- package/dist/core/workflow-model/parse-interpolation-field.d.ts.map +1 -1
- package/dist/core/workflow-model/parse-interpolation-field.js +1 -15
- package/dist/core/workflow-model/parse-interpolation-field.js.map +1 -1
- package/dist/core/workflow-model/validate-predicate-expression.d.ts +3 -1
- package/dist/core/workflow-model/validate-predicate-expression.d.ts.map +1 -1
- package/dist/core/workflow-model/validate-predicate-expression.js +3 -0
- package/dist/core/workflow-model/validate-predicate-expression.js.map +1 -1
- package/dist/core/workflow-model/validation-issue.d.ts +2 -1
- package/dist/core/workflow-model/validation-issue.d.ts.map +1 -1
- package/dist/core/workflow-model/validation-issue.js +12 -15
- package/dist/core/workflow-model/validation-issue.js.map +1 -1
- package/dist/db/db.d.ts +196 -4
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +3 -1
- package/dist/db/db.js.map +1 -1
- package/dist/db/definition-triggers.js +3 -1
- package/dist/db/definition-triggers.js.map +1 -1
- package/dist/db/definitions.d.ts +17 -0
- package/dist/db/definitions.d.ts.map +1 -1
- package/dist/db/definitions.js +190 -23
- package/dist/db/definitions.js.map +1 -1
- package/dist/db/index.d.ts +2 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +2 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/schema/definitions.d.ts +17 -0
- package/dist/db/schema/definitions.d.ts.map +1 -1
- package/dist/db/schema/definitions.js +8 -0
- package/dist/db/schema/definitions.js.map +1 -1
- package/dist/db/schema/sync-states.d.ts +7 -3
- package/dist/db/schema/sync-states.d.ts.map +1 -1
- package/dist/db/schema/sync-states.js +5 -1
- package/dist/db/schema/sync-states.js.map +1 -1
- package/dist/db/schema/workflows.d.ts +78 -0
- package/dist/db/schema/workflows.d.ts.map +1 -0
- package/dist/db/schema/workflows.js +17 -0
- package/dist/db/schema/workflows.js.map +1 -0
- package/dist/db/sync-states.d.ts +2 -2
- package/dist/db/sync-states.d.ts.map +1 -1
- package/dist/db/sync-states.js +4 -4
- package/dist/db/sync-states.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics/index.d.ts +2 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +3 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/instance.d.ts +4 -0
- package/dist/metrics/instance.d.ts.map +1 -0
- package/dist/metrics/instance.js +19 -0
- package/dist/metrics/instance.js.map +1 -0
- package/dist/presentation/dto/definition.d.ts.map +1 -1
- package/dist/presentation/dto/definition.js +11 -4
- package/dist/presentation/dto/definition.js.map +1 -1
- package/dist/presentation/inter-module.d.ts +9 -1
- package/dist/presentation/inter-module.d.ts.map +1 -1
- package/dist/presentation/inter-module.js +66 -2
- package/dist/presentation/inter-module.js.map +1 -1
- package/dist/presentation/routes/create-definition.d.ts.map +1 -1
- package/dist/presentation/routes/create-definition.js +16 -3
- package/dist/presentation/routes/create-definition.js.map +1 -1
- package/dist/presentation/routes/get-definition.d.ts.map +1 -1
- package/dist/presentation/routes/get-definition.js +18 -4
- package/dist/presentation/routes/get-definition.js.map +1 -1
- package/dist/presentation/routes/project-access.d.ts +1 -0
- package/dist/presentation/routes/project-access.d.ts.map +1 -1
- package/dist/presentation/routes/validate-definition.js +3 -3
- package/dist/presentation/routes/validate-definition.js.map +1 -1
- package/dist/temporal/activities/sync-activities.d.ts +3 -3
- package/dist/temporal/activities/sync-activities.d.ts.map +1 -1
- package/dist/temporal/activities/sync-activities.js +7 -4
- package/dist/temporal/activities/sync-activities.js.map +1 -1
- package/dist/temporal/workflows/definition-sync.js +1 -1
- package/dist/temporal/workflows/definition-sync.js.map +1 -1
- package/dist/temporal/workflows/index.bundle.js +50 -22
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0003_nebulous_nemesis.sql +11 -0
- package/drizzle/0004_workflow_ref_lookup.sql +1 -0
- package/drizzle/meta/0003_snapshot.json +627 -0
- package/drizzle/meta/0004_snapshot.json +649 -0
- package/drizzle/meta/_journal.json +14 -0
- package/drizzle.config.ts +1 -0
- package/package.json +7 -7
- package/src/core/entities/index.ts +1 -1
- package/src/core/entities/integration-context.ts +4 -0
- package/src/core/entities/sync-state.test.ts +49 -0
- package/src/core/entities/sync-state.ts +35 -12
- package/src/core/entities/validation-diagnostic.ts +8 -0
- package/src/core/entities/workflow-definition.ts +2 -0
- package/src/core/errors.ts +26 -0
- package/src/core/index.ts +12 -0
- package/src/core/integrations.test.ts +38 -0
- package/src/core/integrations.ts +10 -1
- package/src/core/parse-definition-diagnostics.test.ts +47 -0
- package/src/core/parse-definition.test.ts +29 -5
- package/src/core/parse-definition.ts +7 -7
- package/src/core/resolve-definition-at-ref.test.ts +792 -0
- package/src/core/resolve-definition-at-ref.ts +551 -0
- package/src/core/sync-definitions.test.ts +61 -2
- package/src/core/sync-definitions.ts +7 -7
- package/src/core/validate-definition.test.ts +31 -22
- package/src/core/validate-definition.ts +21 -13
- package/src/core/workflow-model/cron-trigger.ts +6 -2
- package/src/core/workflow-model/index.ts +1 -0
- package/src/core/workflow-model/invalid-workflow-model-error.ts +5 -1
- package/src/core/workflow-model/normalize-job-listening.ts +55 -23
- package/src/core/workflow-model/normalize-triggers.ts +44 -15
- package/src/core/workflow-model/normalize-workflow-document.test.ts +444 -36
- package/src/core/workflow-model/normalize-workflow-document.ts +8 -4
- package/src/core/workflow-model/parse-interpolation-field.ts +1 -23
- package/src/core/workflow-model/validate-predicate-expression.ts +6 -0
- package/src/core/workflow-model/validation-issue.ts +8 -13
- package/src/db/db.ts +7 -1
- package/src/db/definition-triggers.test.ts +44 -0
- package/src/db/definition-triggers.ts +1 -1
- package/src/db/definitions.test.ts +300 -1
- package/src/db/definitions.ts +282 -28
- package/src/db/index.ts +2 -0
- package/src/db/schema/definitions.test.ts +1 -0
- package/src/db/schema/definitions.ts +11 -0
- package/src/db/schema/sync-states.ts +12 -3
- package/src/db/schema/workflows.ts +23 -0
- package/src/db/sync-states.test.ts +87 -18
- package/src/db/sync-states.ts +6 -6
- package/src/db/workflow-lineage-migration.test.ts +158 -0
- package/src/index.ts +3 -1
- package/src/metrics/index.ts +1 -0
- package/src/metrics/instance.test.ts +50 -0
- package/src/metrics/instance.ts +23 -0
- package/src/presentation/dto/definition.test.ts +89 -1
- package/src/presentation/dto/definition.ts +8 -5
- package/src/presentation/inter-module.test.ts +177 -0
- package/src/presentation/inter-module.ts +77 -4
- package/src/presentation/routes/create-definition.test.ts +38 -0
- package/src/presentation/routes/create-definition.ts +20 -3
- package/src/presentation/routes/get-definition.test.ts +125 -11
- package/src/presentation/routes/get-definition.ts +21 -4
- package/src/presentation/routes/list-definitions.test.ts +1 -1
- package/src/presentation/routes/validate-definition.test.ts +1 -1
- package/src/presentation/routes/validate-definition.ts +3 -3
- package/src/presentation/subscribers/on-integration-connection-available.test.ts +3 -0
- package/src/temporal/activities/sync-activities.test.ts +46 -2
- package/src/temporal/activities/sync-activities.ts +9 -7
- package/src/temporal/workflows/definition-sync.ts +1 -1
- package/test/factories/definition.ts +1 -0
- package/test/globalSetup.ts +2 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/core/entities/validation-warning.d.ts +0 -6
- package/dist/core/entities/validation-warning.d.ts.map +0 -1
- package/dist/core/entities/validation-warning.js +0 -3
- package/dist/core/entities/validation-warning.js.map +0 -1
- package/src/core/entities/validation-warning.ts +0 -5
- package/src/core/parse-definition-warnings.test.ts +0 -33
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipfox/api-definitions",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "14.0.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
"js-yaml": "^4.1.0",
|
|
27
27
|
"yaml": "^2.8.3",
|
|
28
28
|
"zod": "^4.4.3",
|
|
29
|
-
"@shipfox/api-agent-dto": "
|
|
29
|
+
"@shipfox/api-agent-dto": "14.0.0",
|
|
30
30
|
"@shipfox/api-auth-context": "12.2.0",
|
|
31
|
-
"@shipfox/api-definitions-dto": "
|
|
32
|
-
"@shipfox/api-integration-core-dto": "
|
|
33
|
-
"@shipfox/api-projects-dto": "
|
|
31
|
+
"@shipfox/api-definitions-dto": "14.0.0",
|
|
32
|
+
"@shipfox/api-integration-core-dto": "14.0.0",
|
|
33
|
+
"@shipfox/api-projects-dto": "14.0.0",
|
|
34
34
|
"@shipfox/api-secrets-dto": "12.0.0",
|
|
35
35
|
"@shipfox/config": "1.2.4",
|
|
36
|
-
"@shipfox/expression": "2.2.
|
|
36
|
+
"@shipfox/expression": "2.2.1",
|
|
37
37
|
"@shipfox/inter-module": "0.2.3",
|
|
38
38
|
"@shipfox/node-drizzle": "0.3.5",
|
|
39
39
|
"@shipfox/node-fastify": "0.4.2",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@shipfox/node-postgres": "0.5.0",
|
|
45
45
|
"@shipfox/node-temporal": "0.4.5",
|
|
46
46
|
"@shipfox/runner-labels": "0.2.0",
|
|
47
|
-
"@shipfox/workflow-document": "3.0
|
|
47
|
+
"@shipfox/workflow-document": "3.1.0"
|
|
48
48
|
},
|
|
49
49
|
"imports": {
|
|
50
50
|
"#*": "./dist/*"
|
|
@@ -25,5 +25,9 @@ export interface IntegrationValidationContext {
|
|
|
25
25
|
readonly capabilities: readonly IntegrationCapability[];
|
|
26
26
|
}
|
|
27
27
|
>;
|
|
28
|
+
/** Documented event names per provider; provider-minted names are never a closed set. */
|
|
29
|
+
readonly eventCatalogs: ReadonlyMap<IntegrationProviderKind, ReadonlySet<string>>;
|
|
30
|
+
/** Providers whose single event name is Shipfox-minted (`webhook` today). */
|
|
31
|
+
readonly fixedEventProviders: ReadonlySet<IntegrationProviderKind>;
|
|
28
32
|
readonly defaultConnectionSlug?: string | undefined;
|
|
29
33
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {DEFINITION_SYNC_DIAGNOSTICS_MAX_COUNT} from '@shipfox/api-definitions-dto';
|
|
2
|
+
import {type DefinitionSyncDiagnostic, limitDefinitionSyncDiagnostics} from './sync-state.js';
|
|
3
|
+
|
|
4
|
+
describe('limitDefinitionSyncDiagnostics', () => {
|
|
5
|
+
it('orders errors before warnings while keeping the order within each severity', () => {
|
|
6
|
+
const diagnostics: DefinitionSyncDiagnostic[] = [
|
|
7
|
+
{code: 'warning-a', message: 'first warning', severity: 'warning'},
|
|
8
|
+
{code: 'error-a', message: 'first error', severity: 'error'},
|
|
9
|
+
{code: 'warning-b', message: 'second warning', severity: 'warning'},
|
|
10
|
+
{code: 'error-b', message: 'second error', severity: 'error'},
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
expect(limitDefinitionSyncDiagnostics(diagnostics).map((entry) => entry.code)).toEqual([
|
|
14
|
+
'error-a',
|
|
15
|
+
'error-b',
|
|
16
|
+
'warning-a',
|
|
17
|
+
'warning-b',
|
|
18
|
+
]);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('drops warnings first when the list exceeds the maximum count', () => {
|
|
22
|
+
const diagnostics: DefinitionSyncDiagnostic[] = [
|
|
23
|
+
...Array.from({length: DEFINITION_SYNC_DIAGNOSTICS_MAX_COUNT}, (_, index) => ({
|
|
24
|
+
code: `warning-${index}`,
|
|
25
|
+
message: `warning ${index}`,
|
|
26
|
+
severity: 'warning' as const,
|
|
27
|
+
})),
|
|
28
|
+
{code: 'error-last', message: 'error persisted', severity: 'error'},
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
const limited = limitDefinitionSyncDiagnostics(diagnostics);
|
|
32
|
+
|
|
33
|
+
expect(limited).toHaveLength(DEFINITION_SYNC_DIAGNOSTICS_MAX_COUNT);
|
|
34
|
+
expect(limited[0]?.code).toBe('error-last');
|
|
35
|
+
expect(limited.filter((entry) => entry.severity === 'error')).toHaveLength(1);
|
|
36
|
+
expect(limited.some((entry) => entry.code === 'warning-0')).toBe(true);
|
|
37
|
+
expect(
|
|
38
|
+
limited.some(
|
|
39
|
+
(entry) => entry.code === `warning-${DEFINITION_SYNC_DIAGNOSTICS_MAX_COUNT - 1}`,
|
|
40
|
+
),
|
|
41
|
+
).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('preserves severity and an absent path', () => {
|
|
45
|
+
expect(
|
|
46
|
+
limitDefinitionSyncDiagnostics([{code: 'code', message: 'message', severity: 'warning'}]),
|
|
47
|
+
).toEqual([{code: 'code', message: 'message', severity: 'warning'}]);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -1,24 +1,47 @@
|
|
|
1
1
|
import {
|
|
2
|
+
DEFINITION_SYNC_DIAGNOSTIC_FILE_PATH_MAX_LENGTH,
|
|
3
|
+
DEFINITION_SYNC_DIAGNOSTICS_MAX_COUNT,
|
|
2
4
|
DEFINITION_SYNC_WARNING_CODE_MAX_LENGTH,
|
|
3
5
|
DEFINITION_SYNC_WARNING_MESSAGE_MAX_LENGTH,
|
|
4
6
|
DEFINITION_SYNC_WARNING_PATH_MAX_LENGTH,
|
|
5
|
-
DEFINITION_SYNC_WARNINGS_MAX_COUNT,
|
|
6
7
|
} from '@shipfox/api-definitions-dto';
|
|
7
|
-
import type {
|
|
8
|
+
import type {ValidationDiagnostic} from './validation-diagnostic.js';
|
|
8
9
|
|
|
9
10
|
export type DefinitionSyncStatus = 'pending' | 'syncing' | 'succeeded' | 'failed';
|
|
10
11
|
|
|
11
|
-
export
|
|
12
|
+
export interface DefinitionSyncDiagnostic extends ValidationDiagnostic {
|
|
13
|
+
filePath?: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Orders errors before warnings and bounds the list so truncation at
|
|
18
|
+
* `DEFINITION_SYNC_DIAGNOSTICS_MAX_COUNT` drops warnings first.
|
|
19
|
+
*/
|
|
20
|
+
export function limitDefinitionSyncDiagnostics(
|
|
21
|
+
diagnostics: readonly DefinitionSyncDiagnostic[],
|
|
22
|
+
): DefinitionSyncDiagnostic[] {
|
|
23
|
+
const ordered: DefinitionSyncDiagnostic[] = [];
|
|
24
|
+
for (const severity of ['error', 'warning'] as const) {
|
|
25
|
+
for (const diagnostic of diagnostics) {
|
|
26
|
+
if (diagnostic.severity !== severity) continue;
|
|
27
|
+
ordered.push(diagnostic);
|
|
28
|
+
if (ordered.length === DEFINITION_SYNC_DIAGNOSTICS_MAX_COUNT) break;
|
|
29
|
+
}
|
|
30
|
+
if (ordered.length === DEFINITION_SYNC_DIAGNOSTICS_MAX_COUNT) break;
|
|
31
|
+
}
|
|
12
32
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
33
|
+
return ordered.map((diagnostic) => ({
|
|
34
|
+
code: diagnostic.code.slice(0, DEFINITION_SYNC_WARNING_CODE_MAX_LENGTH),
|
|
35
|
+
message: diagnostic.message.slice(0, DEFINITION_SYNC_WARNING_MESSAGE_MAX_LENGTH),
|
|
36
|
+
severity: diagnostic.severity,
|
|
37
|
+
...(diagnostic.path === undefined
|
|
38
|
+
? {}
|
|
39
|
+
: {path: diagnostic.path.slice(0, DEFINITION_SYNC_WARNING_PATH_MAX_LENGTH)}),
|
|
40
|
+
...(diagnostic.filePath === undefined
|
|
20
41
|
? {}
|
|
21
|
-
: {
|
|
42
|
+
: {
|
|
43
|
+
filePath: diagnostic.filePath.slice(0, DEFINITION_SYNC_DIAGNOSTIC_FILE_PATH_MAX_LENGTH),
|
|
44
|
+
}),
|
|
22
45
|
}));
|
|
23
46
|
}
|
|
24
47
|
|
|
@@ -55,7 +78,7 @@ export interface DefinitionSyncState {
|
|
|
55
78
|
status: DefinitionSyncStatus;
|
|
56
79
|
lastErrorCode: DefinitionSyncErrorCode | null;
|
|
57
80
|
lastErrorMessage: string | null;
|
|
58
|
-
|
|
81
|
+
diagnostics: DefinitionSyncDiagnostic[];
|
|
59
82
|
startedAt: Date | null;
|
|
60
83
|
finishedAt: Date | null;
|
|
61
84
|
createdAt: Date;
|
|
@@ -13,6 +13,8 @@ export interface WorkflowDefinitionPayload {
|
|
|
13
13
|
|
|
14
14
|
export interface WorkflowDefinition {
|
|
15
15
|
id: string;
|
|
16
|
+
/** Stable identity per project and config path; pathless manual rows share a project lineage. */
|
|
17
|
+
workflowId: string;
|
|
16
18
|
projectId: string;
|
|
17
19
|
configPath: string | null;
|
|
18
20
|
source: 'manual' | 'vcs';
|
package/src/core/errors.ts
CHANGED
|
@@ -19,3 +19,29 @@ export class DefinitionSyncPermanentError extends Error {
|
|
|
19
19
|
this.name = 'DefinitionSyncPermanentError';
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
export type DefinitionAtRefErrorCode =
|
|
24
|
+
| 'project-not-found'
|
|
25
|
+
| 'ref-not-found'
|
|
26
|
+
| 'ref-invalid'
|
|
27
|
+
| 'ref-moved'
|
|
28
|
+
| 'file-not-found'
|
|
29
|
+
| 'content-too-large'
|
|
30
|
+
| 'invalid-definition'
|
|
31
|
+
| 'too-many-files'
|
|
32
|
+
| 'source-unavailable';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Rejects a definition resolution or listing at a git ref. `details` carries
|
|
36
|
+
* the bounded context the presentation translates into known-error details.
|
|
37
|
+
*/
|
|
38
|
+
export class DefinitionAtRefError extends Error {
|
|
39
|
+
constructor(
|
|
40
|
+
public readonly code: DefinitionAtRefErrorCode,
|
|
41
|
+
message: string,
|
|
42
|
+
public readonly details: Record<string, unknown> = {},
|
|
43
|
+
) {
|
|
44
|
+
super(message);
|
|
45
|
+
this.name = 'DefinitionAtRefError';
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/core/index.ts
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
export type * from './entities/index.js';
|
|
2
2
|
export {
|
|
3
|
+
DefinitionAtRefError,
|
|
4
|
+
type DefinitionAtRefErrorCode,
|
|
3
5
|
DefinitionParseError,
|
|
4
6
|
DefinitionSyncPermanentError,
|
|
5
7
|
} from './errors.js';
|
|
6
8
|
export {parseDefinition} from './parse-definition.js';
|
|
9
|
+
export {
|
|
10
|
+
type DefinitionAtRefFile,
|
|
11
|
+
type DefinitionsAtRefListing,
|
|
12
|
+
type ListDefinitionsAtRefParams,
|
|
13
|
+
listDefinitionsAtRef,
|
|
14
|
+
type ResolveDefinitionAtRefParams,
|
|
15
|
+
type ResolvedDefinitionAtRef,
|
|
16
|
+
resolveDefinitionAtRef,
|
|
17
|
+
type ValidationWarning,
|
|
18
|
+
} from './resolve-definition-at-ref.js';
|
|
7
19
|
export {
|
|
8
20
|
classifySyncFailure,
|
|
9
21
|
DEFAULT_WORKFLOW_PATH,
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';
|
|
2
|
+
import {loadIntegrationValidationContext} from './integrations.js';
|
|
3
|
+
|
|
4
|
+
describe('loadIntegrationValidationContext', () => {
|
|
5
|
+
it('materializes provider event catalogs and fixed-provider metadata', async () => {
|
|
6
|
+
const getAgentToolsContext = vi.fn<IntegrationsModuleClient['getAgentToolsContext']>(
|
|
7
|
+
async () => ({
|
|
8
|
+
selectionCatalogs: [],
|
|
9
|
+
catalogs: [],
|
|
10
|
+
workspaceConnections: [],
|
|
11
|
+
eventCatalogs: [
|
|
12
|
+
{provider: 'github', events: ['push', 'pull_request.opened']},
|
|
13
|
+
{provider: 'gitea', events: ['push']},
|
|
14
|
+
],
|
|
15
|
+
fixedEventProviders: ['webhook'],
|
|
16
|
+
defaultConnection: null,
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
const integrations = {getAgentToolsContext} as unknown as IntegrationsModuleClient;
|
|
20
|
+
const workspaceId = crypto.randomUUID();
|
|
21
|
+
const defaultConnectionId = crypto.randomUUID();
|
|
22
|
+
|
|
23
|
+
const context = await loadIntegrationValidationContext(
|
|
24
|
+
integrations,
|
|
25
|
+
workspaceId,
|
|
26
|
+
defaultConnectionId,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
expect(getAgentToolsContext).toHaveBeenCalledWith({workspaceId, defaultConnectionId});
|
|
30
|
+
expect(context.eventCatalogs).toEqual(
|
|
31
|
+
new Map([
|
|
32
|
+
['github', new Set(['push', 'pull_request.opened'])],
|
|
33
|
+
['gitea', new Set(['push'])],
|
|
34
|
+
]),
|
|
35
|
+
);
|
|
36
|
+
expect(context.fixedEventProviders).toEqual(new Set(['webhook']));
|
|
37
|
+
});
|
|
38
|
+
});
|
package/src/core/integrations.ts
CHANGED
|
@@ -23,8 +23,13 @@ export async function loadIntegrationValidationContext(
|
|
|
23
23
|
integrations: IntegrationsModuleClient,
|
|
24
24
|
workspaceId: string,
|
|
25
25
|
defaultConnectionId: string,
|
|
26
|
+
signal?: AbortSignal,
|
|
26
27
|
) {
|
|
27
|
-
const
|
|
28
|
+
const input = {workspaceId, defaultConnectionId};
|
|
29
|
+
const context =
|
|
30
|
+
signal === undefined
|
|
31
|
+
? await integrations.getAgentToolsContext(input)
|
|
32
|
+
: await integrations.getAgentToolsContext(input, {signal});
|
|
28
33
|
return {
|
|
29
34
|
agentToolSelectionCatalogs: new Map(
|
|
30
35
|
context.selectionCatalogs.map(({provider, selectors}) => [provider, {selectors}]),
|
|
@@ -32,6 +37,10 @@ export async function loadIntegrationValidationContext(
|
|
|
32
37
|
workspaceConnectionSnapshot: new Map(
|
|
33
38
|
context.workspaceConnections.map(({slug, ...connection}) => [slug, connection]),
|
|
34
39
|
),
|
|
40
|
+
eventCatalogs: new Map(
|
|
41
|
+
context.eventCatalogs.map(({provider, events}) => [provider, new Set(events)]),
|
|
42
|
+
),
|
|
43
|
+
fixedEventProviders: new Set(context.fixedEventProviders),
|
|
35
44
|
defaultConnectionSlug: context.defaultConnection?.slug,
|
|
36
45
|
};
|
|
37
46
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
2
|
+
import {parseDefinitionWithDiagnostics} from './parse-definition.js';
|
|
3
|
+
import {validateDefinition} from './validate-definition.js';
|
|
4
|
+
|
|
5
|
+
vi.mock('./validate-definition.js', () => ({
|
|
6
|
+
validateDefinition: vi.fn(),
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
describe('parseDefinitionWithDiagnostics', () => {
|
|
10
|
+
it('returns diagnostics from successful validation', () => {
|
|
11
|
+
vi.mocked(validateDefinition).mockReturnValue({
|
|
12
|
+
valid: true,
|
|
13
|
+
definition: {document: {}, model: {}} as never,
|
|
14
|
+
diagnostics: [
|
|
15
|
+
{
|
|
16
|
+
code: 'synthetic-warning',
|
|
17
|
+
message: 'A non-fatal validation warning',
|
|
18
|
+
path: 'jobs.build.steps.0.run',
|
|
19
|
+
severity: 'warning',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
code: 'synthetic-error',
|
|
23
|
+
message: 'A trigger-scoped validation error',
|
|
24
|
+
path: 'triggers.on_demand',
|
|
25
|
+
severity: 'error',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const parsed = parseDefinitionWithDiagnostics('name: Workflow', {agentValidationCatalog});
|
|
31
|
+
|
|
32
|
+
expect(parsed.diagnostics).toEqual([
|
|
33
|
+
{
|
|
34
|
+
code: 'synthetic-warning',
|
|
35
|
+
message: 'A non-fatal validation warning',
|
|
36
|
+
path: 'jobs.build.steps.0.run',
|
|
37
|
+
severity: 'warning',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
code: 'synthetic-error',
|
|
41
|
+
message: 'A trigger-scoped validation error',
|
|
42
|
+
path: 'triggers.on_demand',
|
|
43
|
+
severity: 'error',
|
|
44
|
+
},
|
|
45
|
+
]);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -3,7 +3,10 @@ import {dirname, resolve} from 'node:path';
|
|
|
3
3
|
import {fileURLToPath} from 'node:url';
|
|
4
4
|
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
5
5
|
import {DefinitionParseError} from './errors.js';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
parseDefinition as parseDefinitionBase,
|
|
8
|
+
parseDefinitionWithDiagnostics as parseDefinitionWithDiagnosticsBase,
|
|
9
|
+
} from './parse-definition.js';
|
|
7
10
|
|
|
8
11
|
const fixturesDir = resolve(dirname(fileURLToPath(import.meta.url)), '../../test/fixtures');
|
|
9
12
|
|
|
@@ -11,6 +14,10 @@ function parseDefinition(yaml: string, options = {}) {
|
|
|
11
14
|
return parseDefinitionBase(yaml, {agentValidationCatalog, ...options});
|
|
12
15
|
}
|
|
13
16
|
|
|
17
|
+
function parseDefinitionWithDiagnostics(yaml: string, options = {}) {
|
|
18
|
+
return parseDefinitionWithDiagnosticsBase(yaml, {agentValidationCatalog, ...options});
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
function readFixture(name: string): string {
|
|
15
22
|
return readFileSync(resolve(fixturesDir, name), 'utf-8');
|
|
16
23
|
}
|
|
@@ -177,7 +184,7 @@ jobs:
|
|
|
177
184
|
expect(() => parseDefinition(yaml)).toThrow(DefinitionParseError);
|
|
178
185
|
});
|
|
179
186
|
|
|
180
|
-
test('manual trigger
|
|
187
|
+
test('manual trigger without an explicit event parses and materializes fire', () => {
|
|
181
188
|
const yaml = `name: Manual only
|
|
182
189
|
runner: ubuntu-latest
|
|
183
190
|
triggers:
|
|
@@ -189,10 +196,19 @@ jobs:
|
|
|
189
196
|
- run: echo hello
|
|
190
197
|
`;
|
|
191
198
|
|
|
192
|
-
|
|
199
|
+
const definition = parseDefinition(yaml);
|
|
200
|
+
|
|
201
|
+
expect(definition.model.triggers).toEqual([
|
|
202
|
+
{
|
|
203
|
+
id: 'on-demand',
|
|
204
|
+
key: 'on_demand',
|
|
205
|
+
source: 'manual',
|
|
206
|
+
event: 'fire',
|
|
207
|
+
},
|
|
208
|
+
]);
|
|
193
209
|
});
|
|
194
210
|
|
|
195
|
-
test('
|
|
211
|
+
test('keeps the first manual trigger active and makes later ones inert', () => {
|
|
196
212
|
const yaml = `name: Multi manual
|
|
197
213
|
runner: ubuntu-latest
|
|
198
214
|
triggers:
|
|
@@ -206,6 +222,14 @@ jobs:
|
|
|
206
222
|
- run: echo hello
|
|
207
223
|
`;
|
|
208
224
|
|
|
209
|
-
|
|
225
|
+
const definition = parseDefinitionWithDiagnostics(yaml);
|
|
226
|
+
|
|
227
|
+
expect(definition.diagnostics).toEqual([
|
|
228
|
+
expect.objectContaining({
|
|
229
|
+
code: 'multiple-manual-triggers',
|
|
230
|
+
path: 'triggers.rollback',
|
|
231
|
+
}),
|
|
232
|
+
]);
|
|
233
|
+
expect(definition.model.triggers.map((trigger) => trigger.key)).toEqual(['deploy']);
|
|
210
234
|
});
|
|
211
235
|
});
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {ValidationDiagnostic} from './entities/validation-diagnostic.js';
|
|
2
2
|
import type {WorkflowDefinitionPayload} from './entities/workflow-definition.js';
|
|
3
3
|
import {DefinitionParseError} from './errors.js';
|
|
4
4
|
import {type DefinitionValidationOptions, validateDefinition} from './validate-definition.js';
|
|
5
5
|
|
|
6
6
|
export interface ParsedDefinition extends WorkflowDefinitionPayload {
|
|
7
|
-
|
|
7
|
+
diagnostics: ValidationDiagnostic[];
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export type ParseDefinitionOptions = DefinitionValidationOptions;
|
|
11
11
|
|
|
12
|
-
export function
|
|
12
|
+
export function parseDefinitionWithDiagnostics(
|
|
13
13
|
yamlString: string,
|
|
14
14
|
options: ParseDefinitionOptions,
|
|
15
15
|
): ParsedDefinition {
|
|
@@ -25,7 +25,7 @@ export function parseDefinitionWithWarnings(
|
|
|
25
25
|
return {
|
|
26
26
|
...result.definition,
|
|
27
27
|
sourceSnapshot: {content: yamlString, format: 'yaml'},
|
|
28
|
-
|
|
28
|
+
diagnostics: result.diagnostics,
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -33,11 +33,11 @@ export function parseDefinition(
|
|
|
33
33
|
yamlString: string,
|
|
34
34
|
options: ParseDefinitionOptions,
|
|
35
35
|
): WorkflowDefinitionPayload {
|
|
36
|
-
const parsed =
|
|
37
|
-
return
|
|
36
|
+
const parsed = parseDefinitionWithDiagnostics(yamlString, options);
|
|
37
|
+
return stripDefinitionDiagnostics(parsed);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
export function
|
|
40
|
+
export function stripDefinitionDiagnostics(parsed: ParsedDefinition): WorkflowDefinitionPayload {
|
|
41
41
|
return {
|
|
42
42
|
document: parsed.document,
|
|
43
43
|
model: parsed.model,
|