@shipfox/api-projects-dto 10.1.0 → 12.2.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 +1 -1
- package/CHANGELOG.md +27 -0
- package/dist/e2e/project.d.ts +2 -0
- package/dist/e2e/project.d.ts.map +1 -1
- package/dist/e2e/project.js +2 -1
- package/dist/e2e/project.js.map +1 -1
- package/dist/events.d.ts +46 -6
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +17 -1
- package/dist/events.js.map +1 -1
- package/dist/inter-module.d.ts +78 -12
- package/dist/inter-module.d.ts.map +1 -1
- package/dist/inter-module.js +54 -0
- package/dist/inter-module.js.map +1 -1
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/project.d.ts +9 -0
- package/dist/schemas/project.d.ts.map +1 -1
- package/dist/schemas/project.js +7 -1
- package/dist/schemas/project.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/e2e/project.ts +2 -1
- package/src/events.test.ts +23 -0
- package/src/events.ts +23 -2
- package/src/inter-module.test.ts +48 -0
- package/src/inter-module.ts +47 -0
- package/src/schemas/index.ts +2 -0
- package/src/schemas/project.ts +12 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipfox/api-projects-dto",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "12.2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"zod": "^4.4.3",
|
|
26
|
-
"@shipfox/api-common-dto": "
|
|
27
|
-
"@shipfox/inter-module": "0.2.
|
|
26
|
+
"@shipfox/api-common-dto": "12.0.0",
|
|
27
|
+
"@shipfox/inter-module": "0.2.3"
|
|
28
28
|
},
|
|
29
29
|
"imports": {
|
|
30
30
|
"#*": "./dist/*"
|
package/src/e2e/project.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {displayNameSchema} from '@shipfox/api-common-dto';
|
|
1
|
+
import {displayNameSchema, slugSchema} from '@shipfox/api-common-dto';
|
|
2
2
|
import {z} from 'zod';
|
|
3
3
|
import {projectResponseSchema} from '../schemas/project.js';
|
|
4
4
|
|
|
5
5
|
export const e2eCreateProjectBodySchema = z.object({
|
|
6
6
|
workspace_id: z.string().uuid(),
|
|
7
7
|
name: displayNameSchema,
|
|
8
|
+
slug: slugSchema.optional(),
|
|
8
9
|
source_connection_id: z.string().uuid().optional(),
|
|
9
10
|
source_external_repository_id: z.string().min(1).max(255).optional(),
|
|
10
11
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {projectCreatedEventSchema} from './events.js';
|
|
2
|
+
|
|
3
|
+
const legacyProjectCreatedEvent = {
|
|
4
|
+
actorId: 'actor-1',
|
|
5
|
+
workspaceId: 'workspace-1',
|
|
6
|
+
projectId: 'project-1',
|
|
7
|
+
sourceConnectionId: 'connection-1',
|
|
8
|
+
sourceExternalRepositoryId: 'repository-1',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
describe('project created event schema', () => {
|
|
12
|
+
test('accepts legacy in-flight payloads without a slug', () => {
|
|
13
|
+
expect(projectCreatedEventSchema.parse(legacyProjectCreatedEvent)).toEqual(
|
|
14
|
+
legacyProjectCreatedEvent,
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('preserves slugs on new payloads', () => {
|
|
19
|
+
expect(
|
|
20
|
+
projectCreatedEventSchema.parse({...legacyProjectCreatedEvent, slug: 'project'}),
|
|
21
|
+
).toMatchObject({slug: 'project'});
|
|
22
|
+
});
|
|
23
|
+
});
|
package/src/events.ts
CHANGED
|
@@ -3,17 +3,36 @@ import {z} from 'zod';
|
|
|
3
3
|
const nonEmptyStringSchema = z.string().nonempty();
|
|
4
4
|
|
|
5
5
|
export const PROJECT_CREATED = 'projects.project.created' as const;
|
|
6
|
+
export const PROJECT_UPDATED = 'projects.project.updated' as const;
|
|
6
7
|
export const PROJECT_SOURCE_BOUND = 'projects.project.source_bound' as const;
|
|
7
8
|
export const PROJECT_SOURCE_COMMIT_OBSERVED = 'projects.project.source_commit_observed' as const;
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
const projectCreatedEventWithoutSlugSchema = z.object({
|
|
10
11
|
actorId: nonEmptyStringSchema,
|
|
11
12
|
workspaceId: nonEmptyStringSchema,
|
|
12
13
|
projectId: nonEmptyStringSchema,
|
|
13
14
|
sourceConnectionId: nonEmptyStringSchema,
|
|
14
15
|
sourceExternalRepositoryId: nonEmptyStringSchema,
|
|
15
16
|
});
|
|
16
|
-
|
|
17
|
+
|
|
18
|
+
const projectCreatedEventWithSlugSchema = projectCreatedEventWithoutSlugSchema.extend({
|
|
19
|
+
slug: nonEmptyStringSchema,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const projectCreatedEventSchema = z.union([
|
|
23
|
+
projectCreatedEventWithSlugSchema,
|
|
24
|
+
projectCreatedEventWithoutSlugSchema,
|
|
25
|
+
]);
|
|
26
|
+
export type ProjectCreatedEvent = z.infer<typeof projectCreatedEventWithSlugSchema>;
|
|
27
|
+
|
|
28
|
+
export const projectUpdatedEventSchema = z.object({
|
|
29
|
+
actorId: nonEmptyStringSchema,
|
|
30
|
+
workspaceId: nonEmptyStringSchema,
|
|
31
|
+
projectId: nonEmptyStringSchema,
|
|
32
|
+
name: nonEmptyStringSchema,
|
|
33
|
+
slug: nonEmptyStringSchema,
|
|
34
|
+
});
|
|
35
|
+
export type ProjectUpdatedEvent = z.infer<typeof projectUpdatedEventSchema>;
|
|
17
36
|
|
|
18
37
|
export const projectSourceBoundEventSchema = z.object({
|
|
19
38
|
actorId: nonEmptyStringSchema,
|
|
@@ -40,12 +59,14 @@ export type ProjectSourceCommitObservedEvent = z.infer<
|
|
|
40
59
|
|
|
41
60
|
export interface ProjectsEventMap {
|
|
42
61
|
[PROJECT_CREATED]: ProjectCreatedEvent;
|
|
62
|
+
[PROJECT_UPDATED]: ProjectUpdatedEvent;
|
|
43
63
|
[PROJECT_SOURCE_BOUND]: ProjectSourceBoundEvent;
|
|
44
64
|
[PROJECT_SOURCE_COMMIT_OBSERVED]: ProjectSourceCommitObservedEvent;
|
|
45
65
|
}
|
|
46
66
|
|
|
47
67
|
export const projectsEventSchemas = {
|
|
48
68
|
[PROJECT_CREATED]: projectCreatedEventSchema,
|
|
69
|
+
[PROJECT_UPDATED]: projectUpdatedEventSchema,
|
|
49
70
|
[PROJECT_SOURCE_BOUND]: projectSourceBoundEventSchema,
|
|
50
71
|
[PROJECT_SOURCE_COMMIT_OBSERVED]: projectSourceCommitObservedEventSchema,
|
|
51
72
|
} satisfies Record<keyof ProjectsEventMap, z.ZodType>;
|
package/src/inter-module.test.ts
CHANGED
|
@@ -9,11 +9,59 @@ describe('projectsInterModuleContract', () => {
|
|
|
9
9
|
workspaceId: '00000000-0000-4000-8000-000000000002',
|
|
10
10
|
sourceConnectionId: '00000000-0000-4000-8000-000000000003',
|
|
11
11
|
sourceExternalRepositoryId: 'shipfox/project',
|
|
12
|
+
sourceRepositoryOwner: 'shipfox',
|
|
12
13
|
name: 'Project',
|
|
13
14
|
},
|
|
14
15
|
});
|
|
15
16
|
|
|
16
17
|
expect(result.project?.id).toBe(projectId);
|
|
18
|
+
expect(result.project?.sourceRepositoryOwner).toBe('shipfox');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('accepts checkout targets addressed by project or repository', () => {
|
|
22
|
+
const workspaceId = '00000000-0000-4000-8000-000000000001';
|
|
23
|
+
const connectionId = '00000000-0000-4000-8000-000000000002';
|
|
24
|
+
|
|
25
|
+
expect(
|
|
26
|
+
projectsInterModuleContract.methods.resolveCheckoutTarget.input.parse({
|
|
27
|
+
workspaceId,
|
|
28
|
+
defaults: {connectionId, owner: 'acme'},
|
|
29
|
+
target: {project: '00000000-0000-4000-8000-000000000003'},
|
|
30
|
+
}).target,
|
|
31
|
+
).toEqual({project: '00000000-0000-4000-8000-000000000003'});
|
|
32
|
+
expect(
|
|
33
|
+
projectsInterModuleContract.methods.resolveCheckoutTarget.input.parse({
|
|
34
|
+
workspaceId,
|
|
35
|
+
defaults: {connectionId, owner: 'acme'},
|
|
36
|
+
target: {connection: connectionId, repository: 'acme/api'},
|
|
37
|
+
}).target,
|
|
38
|
+
).toEqual({connection: connectionId, repository: 'acme/api'});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('accepts paginated workspace project source listings', () => {
|
|
42
|
+
const workspaceId = '00000000-0000-4000-8000-000000000001';
|
|
43
|
+
const cursor = {
|
|
44
|
+
createdAt: '2026-08-05T12:00:00.000Z',
|
|
45
|
+
id: '00000000-0000-4000-8000-000000000002',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
expect(
|
|
49
|
+
projectsInterModuleContract.methods.listProjectsByWorkspace.input.parse({
|
|
50
|
+
workspaceId,
|
|
51
|
+
limit: 100,
|
|
52
|
+
cursor,
|
|
53
|
+
}),
|
|
54
|
+
).toEqual({workspaceId, limit: 100, cursor});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('defines the checkout authorization failure', () => {
|
|
58
|
+
const details = {};
|
|
59
|
+
|
|
60
|
+
expect(
|
|
61
|
+
projectsInterModuleContract.methods.resolveCheckoutTarget.errors[
|
|
62
|
+
'checkout-repository-not-authorized'
|
|
63
|
+
].parse(details),
|
|
64
|
+
).toEqual(details);
|
|
17
65
|
});
|
|
18
66
|
|
|
19
67
|
test.each([
|
package/src/inter-module.ts
CHANGED
|
@@ -7,12 +7,29 @@ const projectSchema = z.object({
|
|
|
7
7
|
workspaceId: idSchema,
|
|
8
8
|
sourceConnectionId: idSchema,
|
|
9
9
|
sourceExternalRepositoryId: z.string(),
|
|
10
|
+
sourceRepositoryOwner: z.string().min(1).nullable().optional(),
|
|
10
11
|
name: z.string(),
|
|
11
12
|
});
|
|
12
13
|
const workspaceProjectCountSchema = z.object({
|
|
13
14
|
workspaceId: idSchema,
|
|
14
15
|
count: z.number().int().nonnegative(),
|
|
15
16
|
});
|
|
17
|
+
const projectCursorSchema = z.object({
|
|
18
|
+
createdAt: z.string().datetime(),
|
|
19
|
+
id: idSchema,
|
|
20
|
+
});
|
|
21
|
+
const checkoutTargetSchema = z.union([
|
|
22
|
+
z.strictObject({project: idSchema}),
|
|
23
|
+
z.strictObject({
|
|
24
|
+
connection: idSchema.optional(),
|
|
25
|
+
repository: z.string().min(1),
|
|
26
|
+
}),
|
|
27
|
+
]);
|
|
28
|
+
const resolvedCheckoutTargetSchema = z.object({
|
|
29
|
+
projectId: idSchema,
|
|
30
|
+
connectionId: idSchema,
|
|
31
|
+
externalRepositoryId: z.string(),
|
|
32
|
+
});
|
|
16
33
|
|
|
17
34
|
/** Producer-owned project lookup and workspace ownership operations. */
|
|
18
35
|
export const projectsInterModuleContract = defineInterModuleContract({
|
|
@@ -22,6 +39,25 @@ export const projectsInterModuleContract = defineInterModuleContract({
|
|
|
22
39
|
input: z.object({projectId: idSchema}),
|
|
23
40
|
output: z.object({project: projectSchema.nullable()}),
|
|
24
41
|
},
|
|
42
|
+
getProjectBySource: {
|
|
43
|
+
input: z.object({
|
|
44
|
+
workspaceId: idSchema,
|
|
45
|
+
sourceConnectionId: idSchema,
|
|
46
|
+
sourceExternalRepositoryId: z.string(),
|
|
47
|
+
}),
|
|
48
|
+
output: z.object({project: projectSchema.nullable()}),
|
|
49
|
+
},
|
|
50
|
+
listProjectsByWorkspace: {
|
|
51
|
+
input: z.object({
|
|
52
|
+
workspaceId: idSchema,
|
|
53
|
+
limit: z.number().int().min(1).max(100),
|
|
54
|
+
cursor: projectCursorSchema.optional(),
|
|
55
|
+
}),
|
|
56
|
+
output: z.object({
|
|
57
|
+
projects: z.array(projectSchema),
|
|
58
|
+
nextCursor: projectCursorSchema.nullable(),
|
|
59
|
+
}),
|
|
60
|
+
},
|
|
25
61
|
requireProjectForWorkspace: {
|
|
26
62
|
input: z.object({projectId: idSchema, workspaceId: idSchema}),
|
|
27
63
|
output: z.object({project: projectSchema}),
|
|
@@ -34,6 +70,17 @@ export const projectsInterModuleContract = defineInterModuleContract({
|
|
|
34
70
|
input: z.object({workspaceIds: z.array(idSchema).min(1).max(100)}),
|
|
35
71
|
output: z.object({counts: z.array(workspaceProjectCountSchema)}),
|
|
36
72
|
},
|
|
73
|
+
resolveCheckoutTarget: {
|
|
74
|
+
input: z.object({
|
|
75
|
+
workspaceId: idSchema,
|
|
76
|
+
defaults: z.object({connectionId: idSchema, owner: z.string().min(1)}),
|
|
77
|
+
target: checkoutTargetSchema,
|
|
78
|
+
}),
|
|
79
|
+
output: resolvedCheckoutTargetSchema,
|
|
80
|
+
errors: {
|
|
81
|
+
'checkout-repository-not-authorized': z.object({}),
|
|
82
|
+
},
|
|
83
|
+
},
|
|
37
84
|
},
|
|
38
85
|
});
|
|
39
86
|
|
package/src/schemas/index.ts
CHANGED
package/src/schemas/project.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {displayNameSchema} from '@shipfox/api-common-dto';
|
|
1
|
+
import {displayNameSchema, slugSchema} from '@shipfox/api-common-dto';
|
|
2
2
|
import {z} from 'zod';
|
|
3
3
|
|
|
4
4
|
export const projectSourceDtoSchema = z.object({
|
|
@@ -10,6 +10,7 @@ export type ProjectSourceDto = z.infer<typeof projectSourceDtoSchema>;
|
|
|
10
10
|
export const createProjectBodySchema = z.object({
|
|
11
11
|
workspace_id: z.string().uuid(),
|
|
12
12
|
name: displayNameSchema,
|
|
13
|
+
slug: slugSchema,
|
|
13
14
|
source: z.object({
|
|
14
15
|
connection_id: z.string().uuid(),
|
|
15
16
|
external_repository_id: z.string().min(1).max(255),
|
|
@@ -18,10 +19,20 @@ export const createProjectBodySchema = z.object({
|
|
|
18
19
|
|
|
19
20
|
export type CreateProjectBodyDto = z.infer<typeof createProjectBodySchema>;
|
|
20
21
|
|
|
22
|
+
export const updateProjectBodySchema = z
|
|
23
|
+
.object({
|
|
24
|
+
name: displayNameSchema.optional(),
|
|
25
|
+
slug: slugSchema.optional(),
|
|
26
|
+
})
|
|
27
|
+
.partial();
|
|
28
|
+
|
|
29
|
+
export type UpdateProjectBodyDto = z.infer<typeof updateProjectBodySchema>;
|
|
30
|
+
|
|
21
31
|
export const projectDtoSchema = z.object({
|
|
22
32
|
id: z.string().uuid(),
|
|
23
33
|
workspace_id: z.string().uuid(),
|
|
24
34
|
name: z.string(),
|
|
35
|
+
slug: slugSchema,
|
|
25
36
|
source: projectSourceDtoSchema,
|
|
26
37
|
created_at: z.string(),
|
|
27
38
|
updated_at: z.string(),
|