@shipfox/api-definitions 7.1.0 → 9.0.1
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 +71 -0
- package/dist/config.d.ts +0 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -14
- package/dist/config.js.map +1 -1
- package/dist/core/entities/integration-context.d.ts +12 -1
- package/dist/core/entities/integration-context.d.ts.map +1 -1
- package/dist/core/entities/integration-context.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.map +1 -1
- package/dist/core/integrations.d.ts +1 -1
- package/dist/core/integrations.d.ts.map +1 -1
- package/dist/core/integrations.js +1 -1
- package/dist/core/integrations.js.map +1 -1
- package/dist/core/parse-definition.d.ts +3 -3
- package/dist/core/parse-definition.d.ts.map +1 -1
- package/dist/core/parse-definition.js.map +1 -1
- package/dist/core/sync-definitions.d.ts +3 -0
- package/dist/core/sync-definitions.d.ts.map +1 -1
- package/dist/core/sync-definitions.js +11 -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 +3 -3
- package/dist/core/validate-definition.js.map +1 -1
- package/dist/core/workflow-model/normalize-agent-integrations.d.ts.map +1 -1
- package/dist/core/workflow-model/normalize-agent-integrations.js.map +1 -1
- package/dist/core/workflow-model/normalize-jobs.d.ts +2 -2
- package/dist/core/workflow-model/normalize-jobs.d.ts.map +1 -1
- package/dist/core/workflow-model/normalize-jobs.js +9 -11
- package/dist/core/workflow-model/normalize-jobs.js.map +1 -1
- package/dist/core/workflow-model/normalize-workflow-document.d.ts +3 -3
- package/dist/core/workflow-model/normalize-workflow-document.d.ts.map +1 -1
- package/dist/core/workflow-model/normalize-workflow-document.js +2 -4
- package/dist/core/workflow-model/normalize-workflow-document.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/presentation/routes/create-definition.d.ts +4 -2
- package/dist/presentation/routes/create-definition.d.ts.map +1 -1
- package/dist/presentation/routes/create-definition.js +5 -1
- package/dist/presentation/routes/create-definition.js.map +1 -1
- package/dist/presentation/routes/get-definition.d.ts +1 -1
- package/dist/presentation/routes/get-definition.d.ts.map +1 -1
- package/dist/presentation/routes/get-definition.js.map +1 -1
- package/dist/presentation/routes/index.js +2 -2
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/presentation/routes/list-definitions.d.ts +1 -1
- package/dist/presentation/routes/list-definitions.d.ts.map +1 -1
- package/dist/presentation/routes/list-definitions.js.map +1 -1
- package/dist/presentation/routes/project-access.d.ts +1 -1
- package/dist/presentation/routes/project-access.d.ts.map +1 -1
- package/dist/presentation/routes/project-access.js.map +1 -1
- package/dist/presentation/routes/validate-definition.d.ts +2 -1
- package/dist/presentation/routes/validate-definition.d.ts.map +1 -1
- package/dist/presentation/routes/validate-definition.js +26 -22
- package/dist/presentation/routes/validate-definition.js.map +1 -1
- package/dist/temporal/activities/sync-activities.d.ts +3 -2
- package/dist/temporal/activities/sync-activities.d.ts.map +1 -1
- package/dist/temporal/activities/sync-activities.js +4 -3
- package/dist/temporal/activities/sync-activities.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +23 -24
- package/src/config.ts +1 -19
- package/src/core/entities/integration-context.ts +13 -5
- package/src/core/index.ts +4 -1
- package/src/core/integrations.ts +1 -1
- package/src/core/parse-definition.test.ts +6 -1
- package/src/core/parse-definition.ts +3 -3
- package/src/core/sync-definitions.test.ts +12 -8
- package/src/core/sync-definitions.ts +15 -8
- package/src/core/validate-definition.test.ts +18 -4
- package/src/core/validate-definition.ts +5 -6
- package/src/core/workflow-model/normalize-agent-integrations.ts +7 -1
- package/src/core/workflow-model/normalize-jobs.ts +22 -23
- package/src/core/workflow-model/normalize-workflow-document.test.ts +37 -18
- package/src/core/workflow-model/normalize-workflow-document.ts +4 -9
- package/src/db/definitions.test.ts +2 -1
- package/src/db/schema/definitions.test.ts +2 -1
- package/src/index.ts +8 -5
- package/src/presentation/dto/definition.test.ts +2 -1
- package/src/presentation/routes/create-definition.test.ts +10 -3
- package/src/presentation/routes/create-definition.ts +7 -3
- package/src/presentation/routes/get-definition.test.ts +1 -1
- package/src/presentation/routes/get-definition.ts +1 -1
- package/src/presentation/routes/index.test.ts +6 -2
- package/src/presentation/routes/index.ts +2 -2
- package/src/presentation/routes/list-definitions.test.ts +1 -1
- package/src/presentation/routes/list-definitions.ts +1 -1
- package/src/presentation/routes/project-access.ts +1 -1
- package/src/presentation/routes/validate-definition.test.ts +8 -2
- package/src/presentation/routes/validate-definition.ts +27 -22
- package/src/temporal/activities/sync-activities.test.ts +17 -14
- package/src/temporal/activities/sync-activities.ts +10 -2
- package/test/agent-validation-catalog.ts +26 -0
- package/test/factories/definition.ts +2 -1
- package/test/published/workflow-source-bundle.mjs +17 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
import {sql} from 'drizzle-orm';
|
|
19
19
|
import type {WorkflowDefinitionPayload} from '#core/entities/workflow-definition.js';
|
|
20
20
|
import {normalizeWorkflowDocument} from '#core/workflow-model/index.js';
|
|
21
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
21
22
|
import {db} from './db.js';
|
|
22
23
|
import {
|
|
23
24
|
applyVcsDefinitionsBatch,
|
|
@@ -82,7 +83,7 @@ function definitionFields(name = 'Test Workflow'): WorkflowDefinitionPayload {
|
|
|
82
83
|
function definitionFieldsForDocument(
|
|
83
84
|
document: WorkflowDefinitionPayload['document'],
|
|
84
85
|
): WorkflowDefinitionPayload {
|
|
85
|
-
return {document, model: normalizeWorkflowDocument(document)};
|
|
86
|
+
return {document, model: normalizeWorkflowDocument(document, {agentValidationCatalog})};
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
async function listOutboxRowsForProject(projectId: string) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {normalizeWorkflowDocument} from '#core/workflow-model/index.js';
|
|
2
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
2
3
|
import type {DefinitionDb} from './definitions.js';
|
|
3
4
|
import {toDefinition} from './definitions.js';
|
|
4
5
|
|
|
@@ -21,7 +22,7 @@ describe('toDefinition', () => {
|
|
|
21
22
|
sha: null,
|
|
22
23
|
ref: null,
|
|
23
24
|
name: 'Manual workflow',
|
|
24
|
-
definition: {document, model: normalizeWorkflowDocument(document)},
|
|
25
|
+
definition: {document, model: normalizeWorkflowDocument(document, {agentValidationCatalog})},
|
|
25
26
|
contentHash: null,
|
|
26
27
|
fetchedAt: new Date('2026-06-09T10:00:00.000Z'),
|
|
27
28
|
createdAt: new Date('2026-06-09T10:00:01.000Z'),
|
package/src/index.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import {dirname, resolve} from 'node:path';
|
|
2
2
|
import {fileURLToPath} from 'node:url';
|
|
3
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
3
4
|
import {
|
|
4
5
|
DEFINITION_RESOLVED,
|
|
5
6
|
type DefinitionsEventMap,
|
|
6
7
|
definitionsEventSchemas,
|
|
7
8
|
} from '@shipfox/api-definitions-dto';
|
|
8
|
-
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto';
|
|
9
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
9
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';
|
|
10
10
|
import {
|
|
11
11
|
PROJECT_SOURCE_BOUND,
|
|
12
12
|
PROJECT_SOURCE_COMMIT_OBSERVED,
|
|
13
13
|
type ProjectsEventMap,
|
|
14
14
|
} from '@shipfox/api-projects-dto';
|
|
15
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
15
16
|
import {type ShipfoxModule, subscriberFactory} from '@shipfox/node-module';
|
|
16
17
|
import {logger} from '@shipfox/node-opentelemetry';
|
|
17
18
|
import {createDefinitionsSourceControl} from '#core/integrations.js';
|
|
@@ -48,19 +49,21 @@ const subscriber = subscriberFactory<DefinitionsEventMap & ProjectsEventMap>();
|
|
|
48
49
|
|
|
49
50
|
export interface CreateDefinitionsModuleOptions {
|
|
50
51
|
projects: ProjectsModuleClient;
|
|
52
|
+
agent: AgentInterModuleClient;
|
|
51
53
|
integrations: IntegrationsModuleClient;
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
export function createDefinitionsModule({
|
|
55
57
|
projects,
|
|
58
|
+
agent,
|
|
56
59
|
integrations,
|
|
57
60
|
}: CreateDefinitionsModuleOptions): ShipfoxModule {
|
|
58
61
|
const sourceControl = createDefinitionsSourceControl(integrations);
|
|
59
62
|
|
|
60
63
|
return {
|
|
61
64
|
name: 'definitions',
|
|
62
|
-
database: {db, migrationsPath},
|
|
63
|
-
routes: createDefinitionRoutes({projects, integrations}),
|
|
65
|
+
database: {db, migrationsPath, databaseNamespace: 'definitions'},
|
|
66
|
+
routes: createDefinitionRoutes({projects, agent, integrations}),
|
|
64
67
|
publishers: [
|
|
65
68
|
{name: 'definitions', table: definitionsOutbox, db, eventSchemas: definitionsEventSchemas},
|
|
66
69
|
],
|
|
@@ -76,7 +79,7 @@ export function createDefinitionsModule({
|
|
|
76
79
|
{
|
|
77
80
|
taskQueue: DEFINITIONS_TASK_QUEUE,
|
|
78
81
|
workflowsPath,
|
|
79
|
-
activities: () => createDefinitionSyncActivities(sourceControl, integrations),
|
|
82
|
+
activities: () => createDefinitionSyncActivities(sourceControl, agent, integrations),
|
|
80
83
|
workflows: [],
|
|
81
84
|
},
|
|
82
85
|
],
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {WorkflowDefinition} from '#core/entities/workflow-definition.js';
|
|
2
2
|
import {normalizeWorkflowDocument} from '#core/workflow-model/index.js';
|
|
3
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
3
4
|
import {toDefinitionDto} from './definition.js';
|
|
4
5
|
|
|
5
6
|
describe('toDefinitionDto', () => {
|
|
@@ -29,7 +30,7 @@ describe('toDefinitionDto', () => {
|
|
|
29
30
|
name: document.name,
|
|
30
31
|
definition: document,
|
|
31
32
|
document,
|
|
32
|
-
model: normalizeWorkflowDocument(document),
|
|
33
|
+
model: normalizeWorkflowDocument(document, {agentValidationCatalog}),
|
|
33
34
|
sourceSnapshot: null,
|
|
34
35
|
contentHash: null,
|
|
35
36
|
fetchedAt: new Date('2026-06-09T10:00:00.000Z'),
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import {buildUserContext, setUserContext} from '@shipfox/api-auth-context';
|
|
2
|
-
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto';
|
|
3
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';
|
|
3
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
4
4
|
import type {FastifyInstance} from 'fastify';
|
|
5
5
|
import Fastify from 'fastify';
|
|
6
6
|
import {serializerCompiler, validatorCompiler} from 'fastify-type-provider-zod';
|
|
7
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
7
8
|
import {buildCreateDefinitionRoute} from './create-definition.js';
|
|
8
9
|
|
|
9
10
|
const getProjectById = vi.fn();
|
|
10
11
|
const projects = {getProjectById} as Pick<ProjectsModuleClient, 'getProjectById'>;
|
|
12
|
+
const agent = {getValidationCatalog: vi.fn(() => agentValidationCatalog)};
|
|
11
13
|
|
|
12
14
|
describe('POST /api/definitions', () => {
|
|
13
15
|
let app: FastifyInstance;
|
|
@@ -32,7 +34,10 @@ describe('POST /api/definitions', () => {
|
|
|
32
34
|
});
|
|
33
35
|
app.post(
|
|
34
36
|
'/api/definitions',
|
|
35
|
-
buildCreateDefinitionRoute({
|
|
37
|
+
buildCreateDefinitionRoute({
|
|
38
|
+
projects: projects as ProjectsModuleClient,
|
|
39
|
+
agent: agent as never,
|
|
40
|
+
}),
|
|
36
41
|
);
|
|
37
42
|
await app.ready();
|
|
38
43
|
});
|
|
@@ -96,6 +101,7 @@ jobs:
|
|
|
96
101
|
'/api/definitions',
|
|
97
102
|
buildCreateDefinitionRoute({
|
|
98
103
|
projects: projects as ProjectsModuleClient,
|
|
104
|
+
agent: agent as never,
|
|
99
105
|
integrations: {getAgentToolsContext} as Pick<
|
|
100
106
|
IntegrationsModuleClient,
|
|
101
107
|
'getAgentToolsContext'
|
|
@@ -168,6 +174,7 @@ jobs:
|
|
|
168
174
|
'/api/definitions',
|
|
169
175
|
buildCreateDefinitionRoute({
|
|
170
176
|
projects: projects as ProjectsModuleClient,
|
|
177
|
+
agent: agent as never,
|
|
171
178
|
integrations: {getAgentToolsContext} as Pick<
|
|
172
179
|
IntegrationsModuleClient,
|
|
173
180
|
'getAgentToolsContext'
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
1
2
|
import {
|
|
2
3
|
createDefinitionBodySchema,
|
|
3
4
|
definitionResponseSchema,
|
|
4
5
|
definitionValidationErrorSchema,
|
|
5
6
|
} from '@shipfox/api-definitions-dto';
|
|
6
|
-
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto';
|
|
7
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
7
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';
|
|
8
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
8
9
|
import {ClientError, defineRoute} from '@shipfox/node-fastify';
|
|
9
10
|
import {z} from 'zod';
|
|
10
11
|
import {DefinitionParseError} from '#core/errors.js';
|
|
@@ -17,6 +18,7 @@ import {requireProjectAccess} from './project-access.js';
|
|
|
17
18
|
|
|
18
19
|
export interface CreateDefinitionRouteOptions {
|
|
19
20
|
projects: ProjectsModuleClient;
|
|
21
|
+
agent: AgentInterModuleClient;
|
|
20
22
|
integrations?: IntegrationsModuleClient;
|
|
21
23
|
}
|
|
22
24
|
|
|
@@ -50,11 +52,13 @@ export function buildCreateDefinitionRoute(options: CreateDefinitionRouteOptions
|
|
|
50
52
|
const {project_id: projectId, config_path, source, yaml: yamlString, sha, ref} = request.body;
|
|
51
53
|
const project = await requireProjectAccess(request, projectId, options.projects);
|
|
52
54
|
|
|
53
|
-
const
|
|
55
|
+
const agentValidationCatalog = await options.agent.getValidationCatalog({});
|
|
56
|
+
const structurallyParsed = parseDefinition(yamlString, {agentValidationCatalog});
|
|
54
57
|
const {integrations} = options;
|
|
55
58
|
const parsed =
|
|
56
59
|
integrations !== undefined && hasAgentStepIntegrations(structurallyParsed.document)
|
|
57
60
|
? parseDefinition(yamlString, {
|
|
61
|
+
agentValidationCatalog,
|
|
58
62
|
integrationValidationContext: await loadIntegrationValidationContext(
|
|
59
63
|
integrations,
|
|
60
64
|
project.workspaceId,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {buildUserContext, setUserContext} from '@shipfox/api-auth-context';
|
|
2
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
3
3
|
import type {FastifyInstance} from 'fastify';
|
|
4
4
|
import Fastify from 'fastify';
|
|
5
5
|
import {serializerCompiler, validatorCompiler} from 'fastify-type-provider-zod';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {definitionResponseSchema} from '@shipfox/api-definitions-dto';
|
|
2
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
3
3
|
import {ClientError, defineRoute} from '@shipfox/node-fastify';
|
|
4
4
|
import {z} from 'zod';
|
|
5
5
|
import {getDefinitionById} from '#db/definitions.js';
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import {AUTH_USER, buildUserContext, setUserContext} from '@shipfox/api-auth-context';
|
|
2
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
3
3
|
import {type AuthMethod, ClientError, closeApp, createApp} from '@shipfox/node-fastify';
|
|
4
4
|
import type {FastifyRequest} from 'fastify';
|
|
5
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
5
6
|
import {createDefinitionRoutes} from './index.js';
|
|
6
7
|
|
|
7
8
|
const projects = {
|
|
8
9
|
getProjectById: vi.fn(),
|
|
9
10
|
requireProjectForWorkspace: vi.fn(),
|
|
10
11
|
} as unknown as ProjectsModuleClient;
|
|
11
|
-
const definitionRoutes = createDefinitionRoutes({
|
|
12
|
+
const definitionRoutes = createDefinitionRoutes({
|
|
13
|
+
projects,
|
|
14
|
+
agent: {getValidationCatalog: vi.fn(() => agentValidationCatalog)} as never,
|
|
15
|
+
});
|
|
12
16
|
|
|
13
17
|
const fakeUserAuth: AuthMethod = {
|
|
14
18
|
name: AUTH_USER,
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from './create-definition.js';
|
|
7
7
|
import {buildGetDefinitionRoute} from './get-definition.js';
|
|
8
8
|
import {buildListDefinitionsRoute} from './list-definitions.js';
|
|
9
|
-
import {
|
|
9
|
+
import {buildValidateDefinitionRoute} from './validate-definition.js';
|
|
10
10
|
|
|
11
11
|
export interface DefinitionRouteOptions extends CreateDefinitionRouteOptions {}
|
|
12
12
|
|
|
@@ -19,7 +19,7 @@ export function createDefinitionRoutes(options: DefinitionRouteOptions): RouteGr
|
|
|
19
19
|
buildCreateDefinitionRoute(options),
|
|
20
20
|
buildListDefinitionsRoute(options.projects),
|
|
21
21
|
buildGetDefinitionRoute(options.projects),
|
|
22
|
-
|
|
22
|
+
buildValidateDefinitionRoute(options.agent),
|
|
23
23
|
],
|
|
24
24
|
},
|
|
25
25
|
];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {buildUserContext, setUserContext} from '@shipfox/api-auth-context';
|
|
2
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
3
3
|
import {encodeStringIdCursor} from '@shipfox/node-drizzle';
|
|
4
4
|
import type {FastifyInstance} from 'fastify';
|
|
5
5
|
import Fastify from 'fastify';
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
definitionListQuerySchema,
|
|
3
3
|
definitionListResponseSchema,
|
|
4
4
|
} from '@shipfox/api-definitions-dto';
|
|
5
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
5
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
6
6
|
import {decodeStringIdCursor, encodeStringIdCursor} from '@shipfox/node-drizzle';
|
|
7
7
|
import {ClientError, defineRoute} from '@shipfox/node-fastify';
|
|
8
8
|
import {listDefinitions} from '#db/definitions.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {requireWorkspaceAccess} from '@shipfox/api-auth-context';
|
|
2
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
3
3
|
import {ClientError} from '@shipfox/node-fastify';
|
|
4
4
|
import type {FastifyRequest} from 'fastify';
|
|
5
5
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type {FastifyInstance} from 'fastify';
|
|
2
2
|
import Fastify from 'fastify';
|
|
3
3
|
import {serializerCompiler, validatorCompiler} from 'fastify-type-provider-zod';
|
|
4
|
-
import {
|
|
4
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
5
|
+
import {buildValidateDefinitionRoute} from './validate-definition.js';
|
|
5
6
|
|
|
6
7
|
describe('POST /definitions/validate', () => {
|
|
7
8
|
let app: FastifyInstance;
|
|
@@ -10,7 +11,12 @@ describe('POST /definitions/validate', () => {
|
|
|
10
11
|
app = Fastify();
|
|
11
12
|
app.setValidatorCompiler(validatorCompiler);
|
|
12
13
|
app.setSerializerCompiler(serializerCompiler);
|
|
13
|
-
app.post(
|
|
14
|
+
app.post(
|
|
15
|
+
'/definitions/validate',
|
|
16
|
+
buildValidateDefinitionRoute({
|
|
17
|
+
getValidationCatalog: vi.fn(() => agentValidationCatalog),
|
|
18
|
+
} as never),
|
|
19
|
+
);
|
|
14
20
|
await app.ready();
|
|
15
21
|
});
|
|
16
22
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
1
2
|
import {definitionDtoSchema, definitionValidationErrorSchema} from '@shipfox/api-definitions-dto';
|
|
2
3
|
import {defineRoute} from '@shipfox/node-fastify';
|
|
3
4
|
import {z} from 'zod';
|
|
@@ -19,28 +20,32 @@ const validationResultSchema = z.union([
|
|
|
19
20
|
}),
|
|
20
21
|
]);
|
|
21
22
|
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
export function buildValidateDefinitionRoute(agent: AgentInterModuleClient) {
|
|
24
|
+
return defineRoute({
|
|
25
|
+
method: 'POST',
|
|
26
|
+
path: '/validate',
|
|
27
|
+
description: 'Validate a workflow definition without persisting',
|
|
28
|
+
schema: {
|
|
29
|
+
body: validateBodySchema,
|
|
30
|
+
response: {
|
|
31
|
+
200: validationResultSchema,
|
|
32
|
+
},
|
|
30
33
|
},
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
handler: async (request) => {
|
|
35
|
+
const {yaml} = request.body;
|
|
36
|
+
const result = validateDefinition(yaml, {
|
|
37
|
+
agentValidationCatalog: await agent.getValidationCatalog({}),
|
|
38
|
+
});
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
if (result.valid) {
|
|
41
|
+
return {
|
|
42
|
+
valid: true as const,
|
|
43
|
+
workflow_document: result.definition.document,
|
|
44
|
+
workflow_model: result.definition.model,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
});
|
|
48
|
+
return result;
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {integrationsInterModuleContract} from '@shipfox/api-integration-core-dto';
|
|
1
|
+
import {integrationsInterModuleContract} from '@shipfox/api-integration-core-dto/inter-module';
|
|
3
2
|
import {createInterModuleKnownError} from '@shipfox/inter-module';
|
|
4
3
|
import {isErrorReported} from '@shipfox/node-error-monitoring';
|
|
5
4
|
import {ApplicationFailure} from '@temporalio/common';
|
|
6
5
|
import {sql} from 'drizzle-orm';
|
|
6
|
+
import type {DefinitionsSourceControl} from '#core/integrations.js';
|
|
7
7
|
import {db, definitionSyncStates} from '#db/index.js';
|
|
8
8
|
import {workflowDefinitions} from '#db/schema/definitions.js';
|
|
9
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
9
10
|
import {createDefinitionSyncActivities} from './sync-activities.js';
|
|
10
11
|
|
|
12
|
+
const agent = {getValidationCatalog: vi.fn(() => agentValidationCatalog)} as never;
|
|
13
|
+
|
|
11
14
|
vi.mock('@temporalio/activity', () => ({
|
|
12
15
|
Context: {
|
|
13
16
|
current: () => ({heartbeat: vi.fn()}),
|
|
@@ -24,11 +27,9 @@ jobs:
|
|
|
24
27
|
`;
|
|
25
28
|
|
|
26
29
|
function sourceControl(
|
|
27
|
-
overrides: Partial<
|
|
28
|
-
):
|
|
30
|
+
overrides: Partial<DefinitionsSourceControl> = {},
|
|
31
|
+
): DefinitionsSourceControl {
|
|
29
32
|
return {
|
|
30
|
-
getConnection: vi.fn(),
|
|
31
|
-
listRepositories: vi.fn(),
|
|
32
33
|
resolveRepository: vi.fn(() =>
|
|
33
34
|
Promise.resolve({
|
|
34
35
|
connection: {
|
|
@@ -63,7 +64,6 @@ function sourceControl(
|
|
|
63
64
|
fetchFile: vi.fn(() =>
|
|
64
65
|
Promise.resolve({path: '.shipfox/workflows/ci.yml', ref: 'main', content: validYaml}),
|
|
65
66
|
),
|
|
66
|
-
createCheckoutSpec: vi.fn(),
|
|
67
67
|
...overrides,
|
|
68
68
|
};
|
|
69
69
|
}
|
|
@@ -79,7 +79,7 @@ describe('definition sync activities', () => {
|
|
|
79
79
|
|
|
80
80
|
describe('prepareDefinitionSync', () => {
|
|
81
81
|
it('marks the sync state as syncing and returns the resolved ref', async () => {
|
|
82
|
-
const activities = createDefinitionSyncActivities(sourceControl());
|
|
82
|
+
const activities = createDefinitionSyncActivities(sourceControl(), agent);
|
|
83
83
|
|
|
84
84
|
const result = await activities.prepareDefinitionSync({
|
|
85
85
|
projectId,
|
|
@@ -100,7 +100,7 @@ describe('definition sync activities', () => {
|
|
|
100
100
|
|
|
101
101
|
it('keeps source ref and source commit sha separate for commit-triggered sync', async () => {
|
|
102
102
|
const source = sourceControl();
|
|
103
|
-
const activities = createDefinitionSyncActivities(source);
|
|
103
|
+
const activities = createDefinitionSyncActivities(source, agent);
|
|
104
104
|
|
|
105
105
|
const result = await activities.prepareDefinitionSync({
|
|
106
106
|
projectId,
|
|
@@ -127,6 +127,7 @@ describe('definition sync activities', () => {
|
|
|
127
127
|
return Promise.reject(new Error('temporary outage'));
|
|
128
128
|
}),
|
|
129
129
|
}),
|
|
130
|
+
agent,
|
|
130
131
|
);
|
|
131
132
|
|
|
132
133
|
const result = activities.prepareDefinitionSync({
|
|
@@ -159,6 +160,7 @@ describe('definition sync activities', () => {
|
|
|
159
160
|
);
|
|
160
161
|
}),
|
|
161
162
|
}),
|
|
163
|
+
agent,
|
|
162
164
|
);
|
|
163
165
|
|
|
164
166
|
const result = activities.prepareDefinitionSync({
|
|
@@ -180,7 +182,7 @@ describe('definition sync activities', () => {
|
|
|
180
182
|
|
|
181
183
|
describe('fetchAndApplyDefinitionWorkflows', () => {
|
|
182
184
|
it('upserts workflow definitions and soft-deletes orphans', async () => {
|
|
183
|
-
const activities = createDefinitionSyncActivities(sourceControl());
|
|
185
|
+
const activities = createDefinitionSyncActivities(sourceControl(), agent);
|
|
184
186
|
|
|
185
187
|
const result = await activities.fetchAndApplyDefinitionWorkflows({
|
|
186
188
|
projectId,
|
|
@@ -206,6 +208,7 @@ describe('definition sync activities', () => {
|
|
|
206
208
|
}),
|
|
207
209
|
),
|
|
208
210
|
}),
|
|
211
|
+
agent,
|
|
209
212
|
);
|
|
210
213
|
|
|
211
214
|
const result = activities.fetchAndApplyDefinitionWorkflows({
|
|
@@ -224,7 +227,7 @@ describe('definition sync activities', () => {
|
|
|
224
227
|
|
|
225
228
|
it('fetches from source commit sha while persisting under source ref', async () => {
|
|
226
229
|
const source = sourceControl();
|
|
227
|
-
const activities = createDefinitionSyncActivities(source);
|
|
230
|
+
const activities = createDefinitionSyncActivities(source, agent);
|
|
228
231
|
|
|
229
232
|
const result = await activities.fetchAndApplyDefinitionWorkflows({
|
|
230
233
|
projectId,
|
|
@@ -250,7 +253,7 @@ describe('definition sync activities', () => {
|
|
|
250
253
|
|
|
251
254
|
describe('markDefinitionSyncFailed', () => {
|
|
252
255
|
it('persists last_error_code and last_error_message verbatim', async () => {
|
|
253
|
-
const activities = createDefinitionSyncActivities(sourceControl());
|
|
256
|
+
const activities = createDefinitionSyncActivities(sourceControl(), agent);
|
|
254
257
|
await activities.prepareDefinitionSync({
|
|
255
258
|
projectId,
|
|
256
259
|
workspaceId: crypto.randomUUID(),
|
|
@@ -280,7 +283,7 @@ describe('definition sync activities', () => {
|
|
|
280
283
|
});
|
|
281
284
|
|
|
282
285
|
it('persists failures with the unresolved sentinel ref when no ref was produced', async () => {
|
|
283
|
-
const activities = createDefinitionSyncActivities(sourceControl());
|
|
286
|
+
const activities = createDefinitionSyncActivities(sourceControl(), agent);
|
|
284
287
|
|
|
285
288
|
const result = activities.markDefinitionSyncFailed({
|
|
286
289
|
projectId,
|
|
@@ -307,7 +310,7 @@ describe('definition sync activities', () => {
|
|
|
307
310
|
|
|
308
311
|
describe('markDefinitionSyncSucceeded', () => {
|
|
309
312
|
it('clears stale error fields when transitioning to succeeded', async () => {
|
|
310
|
-
const activities = createDefinitionSyncActivities(sourceControl());
|
|
313
|
+
const activities = createDefinitionSyncActivities(sourceControl(), agent);
|
|
311
314
|
await activities.prepareDefinitionSync({
|
|
312
315
|
projectId,
|
|
313
316
|
workspaceId: crypto.randomUUID(),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
2
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';
|
|
2
3
|
import {markErrorReported} from '@shipfox/node-error-monitoring';
|
|
3
4
|
import {Context} from '@temporalio/activity';
|
|
4
5
|
import {ApplicationFailure} from '@temporalio/common';
|
|
@@ -53,12 +54,17 @@ export interface FetchAndApplyActivityResult {
|
|
|
53
54
|
|
|
54
55
|
export function createDefinitionSyncActivities(
|
|
55
56
|
sourceControl: DefinitionsSourceControl,
|
|
57
|
+
agent: AgentInterModuleClient,
|
|
56
58
|
integrations?: IntegrationsModuleClient | undefined,
|
|
57
59
|
) {
|
|
58
60
|
return {
|
|
59
61
|
prepareDefinitionSync: createPrepareDefinitionSyncActivity(sourceControl),
|
|
60
62
|
discoverDefinitionWorkflows: createDiscoverDefinitionWorkflowsActivity(sourceControl),
|
|
61
|
-
fetchAndApplyDefinitionWorkflows: createFetchAndApplyActivity(
|
|
63
|
+
fetchAndApplyDefinitionWorkflows: createFetchAndApplyActivity(
|
|
64
|
+
sourceControl,
|
|
65
|
+
agent,
|
|
66
|
+
integrations,
|
|
67
|
+
),
|
|
62
68
|
markDefinitionSyncSucceeded: createMarkSyncSucceededActivity(),
|
|
63
69
|
markDefinitionSyncFailed: createMarkSyncFailedActivity(),
|
|
64
70
|
};
|
|
@@ -104,6 +110,7 @@ function createDiscoverDefinitionWorkflowsActivity(sourceControl: DefinitionsSou
|
|
|
104
110
|
|
|
105
111
|
function createFetchAndApplyActivity(
|
|
106
112
|
sourceControl: DefinitionsSourceControl,
|
|
113
|
+
agent: AgentInterModuleClient,
|
|
107
114
|
integrations?: IntegrationsModuleClient | undefined,
|
|
108
115
|
) {
|
|
109
116
|
return async function fetchAndApplyDefinitionWorkflows(
|
|
@@ -114,6 +121,7 @@ function createFetchAndApplyActivity(
|
|
|
114
121
|
...input,
|
|
115
122
|
ref: input.sourceCommitSha ?? input.sourceRef,
|
|
116
123
|
sourceControl,
|
|
124
|
+
agentValidationCatalog: await agent.getValidationCatalog({}),
|
|
117
125
|
onProgress: (path) => Context.current().heartbeat({path}),
|
|
118
126
|
loadIntegrationValidationContext:
|
|
119
127
|
integrations === undefined
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_HARNESS_TOOL_DEPLOYMENT_CONFIG,
|
|
3
|
+
listEnabledHarnessTools,
|
|
4
|
+
listHarnessDescriptors,
|
|
5
|
+
MODEL_PROVIDER_CATALOG_SEED,
|
|
6
|
+
MODEL_PROVIDER_IDS,
|
|
7
|
+
} from '@shipfox/api-agent-dto';
|
|
8
|
+
import type {AgentValidationCatalog} from '@shipfox/api-agent-dto/inter-module';
|
|
9
|
+
|
|
10
|
+
export const agentValidationCatalog: AgentValidationCatalog = {
|
|
11
|
+
version: 1,
|
|
12
|
+
providers: MODEL_PROVIDER_IDS.map((id) => ({
|
|
13
|
+
id,
|
|
14
|
+
support_status:
|
|
15
|
+
MODEL_PROVIDER_CATALOG_SEED.find((entry) => entry.id === id)?.support_status ?? 'unsupported',
|
|
16
|
+
})),
|
|
17
|
+
harnesses: listHarnessDescriptors().map((harness) => ({
|
|
18
|
+
id: harness.id,
|
|
19
|
+
supported_provider_ids: [...harness.supportedProviderIds],
|
|
20
|
+
thinking_levels: [...harness.thinkingLevels],
|
|
21
|
+
effective_tools: listEnabledHarnessTools(
|
|
22
|
+
harness.id,
|
|
23
|
+
DEFAULT_HARNESS_TOOL_DEPLOYMENT_CONFIG,
|
|
24
|
+
).map((tool) => tool.name),
|
|
25
|
+
})),
|
|
26
|
+
};
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
} from '#core/entities/workflow-definition.js';
|
|
6
6
|
import {normalizeWorkflowDocument} from '#core/workflow-model/index.js';
|
|
7
7
|
import {upsertDefinition} from '#db/definitions.js';
|
|
8
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
8
9
|
|
|
9
10
|
function defaultDefinition(): WorkflowDefinitionPayload {
|
|
10
11
|
const document = {
|
|
@@ -16,7 +17,7 @@ function defaultDefinition(): WorkflowDefinitionPayload {
|
|
|
16
17
|
},
|
|
17
18
|
},
|
|
18
19
|
};
|
|
19
|
-
return {document, model: normalizeWorkflowDocument(document)};
|
|
20
|
+
return {document, model: normalizeWorkflowDocument(document, {agentValidationCatalog})};
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
interface DefinitionTransients {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
delete process.env.NODE_ENV;
|
|
2
|
+
|
|
3
|
+
const {createRequire} = await import('node:module');
|
|
4
|
+
const {fileURLToPath} = await import('node:url');
|
|
5
|
+
const {dirname, join} = await import('node:path');
|
|
6
|
+
const temporalRequire = createRequire(import.meta.resolve('@shipfox/node-temporal'));
|
|
7
|
+
const {bundleWorkflowCode} = await import(temporalRequire.resolve('@temporalio/worker'));
|
|
8
|
+
const packageEntryPoint = fileURLToPath(import.meta.resolve('@shipfox/api-definitions'));
|
|
9
|
+
const workflowsPath = join(
|
|
10
|
+
dirname(dirname(packageEntryPoint)),
|
|
11
|
+
'dist',
|
|
12
|
+
'temporal',
|
|
13
|
+
'workflows',
|
|
14
|
+
'index.js',
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
await bundleWorkflowCode({workflowsPath});
|