@shipfox/api-server 9.2.0 → 10.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 +1 -1
- package/CHANGELOG.md +89 -0
- package/README.md +14 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/instrumentation.js +2 -1
- package/dist/instrumentation.js.map +1 -1
- package/dist/modules.d.ts +4 -0
- package/dist/modules.d.ts.map +1 -1
- package/dist/modules.js +8 -3
- package/dist/modules.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +25 -25
- package/src/index.ts +1 -0
- package/src/instrumentation.ts +1 -1
- package/src/modules.test.ts +76 -29
- package/src/modules.ts +8 -3
- package/tsconfig.build.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@shipfox/api-server",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"private": false,
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "10.0.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
@@ -22,36 +22,36 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@shipfox/annotations": "
|
|
25
|
+
"@shipfox/annotations": "10.0.0",
|
|
26
26
|
"@shipfox/annotations-dto": "9.0.2",
|
|
27
|
-
"@shipfox/api-agent": "
|
|
28
|
-
"@shipfox/api-agent-dto": "
|
|
29
|
-
"@shipfox/api-auth": "
|
|
30
|
-
"@shipfox/api-auth-dto": "
|
|
31
|
-
"@shipfox/api-definitions": "
|
|
32
|
-
"@shipfox/api-definitions-dto": "
|
|
33
|
-
"@shipfox/api-dispatcher": "
|
|
34
|
-
"@shipfox/api-email-challenges": "1.1.
|
|
35
|
-
"@shipfox/api-integration-core": "
|
|
27
|
+
"@shipfox/api-agent": "10.0.0",
|
|
28
|
+
"@shipfox/api-agent-dto": "10.0.0",
|
|
29
|
+
"@shipfox/api-auth": "10.0.0",
|
|
30
|
+
"@shipfox/api-auth-dto": "10.0.0",
|
|
31
|
+
"@shipfox/api-definitions": "10.0.0",
|
|
32
|
+
"@shipfox/api-definitions-dto": "10.0.0",
|
|
33
|
+
"@shipfox/api-dispatcher": "10.0.0",
|
|
34
|
+
"@shipfox/api-email-challenges": "1.1.6",
|
|
35
|
+
"@shipfox/api-integration-core": "10.0.0",
|
|
36
36
|
"@shipfox/api-integration-core-dto": "9.0.2",
|
|
37
|
-
"@shipfox/api-logs": "
|
|
38
|
-
"@shipfox/api-projects": "
|
|
39
|
-
"@shipfox/api-projects-dto": "
|
|
40
|
-
"@shipfox/api-runners": "
|
|
41
|
-
"@shipfox/api-runners-dto": "
|
|
42
|
-
"@shipfox/api-secrets": "
|
|
37
|
+
"@shipfox/api-logs": "10.0.0",
|
|
38
|
+
"@shipfox/api-projects": "10.0.0",
|
|
39
|
+
"@shipfox/api-projects-dto": "10.0.0",
|
|
40
|
+
"@shipfox/api-runners": "10.0.0",
|
|
41
|
+
"@shipfox/api-runners-dto": "10.0.0",
|
|
42
|
+
"@shipfox/api-secrets": "10.0.0",
|
|
43
43
|
"@shipfox/api-secrets-dto": "9.0.2",
|
|
44
|
-
"@shipfox/api-triggers": "
|
|
45
|
-
"@shipfox/api-workflows": "
|
|
46
|
-
"@shipfox/api-workflows-dto": "
|
|
47
|
-
"@shipfox/api-workspaces-dto": "
|
|
48
|
-
"@shipfox/api-workspaces": "
|
|
44
|
+
"@shipfox/api-triggers": "10.0.0",
|
|
45
|
+
"@shipfox/api-workflows": "10.0.0",
|
|
46
|
+
"@shipfox/api-workflows-dto": "10.0.0",
|
|
47
|
+
"@shipfox/api-workspaces-dto": "10.0.0",
|
|
48
|
+
"@shipfox/api-workspaces": "10.0.0",
|
|
49
49
|
"@shipfox/config": "1.2.4",
|
|
50
50
|
"@shipfox/node-error-monitoring": "0.3.0",
|
|
51
|
-
"@shipfox/node-fastify": "0.
|
|
51
|
+
"@shipfox/node-fastify": "0.4.0",
|
|
52
52
|
"@shipfox/node-jwt": "0.3.2",
|
|
53
|
-
"@shipfox/node-module": "1.0.
|
|
54
|
-
"@shipfox/node-opentelemetry": "0.6.
|
|
53
|
+
"@shipfox/node-module": "1.0.4",
|
|
54
|
+
"@shipfox/node-opentelemetry": "0.6.3",
|
|
55
55
|
"@shipfox/node-postgres": "0.4.4"
|
|
56
56
|
},
|
|
57
57
|
"imports": {
|
package/src/index.ts
CHANGED
package/src/instrumentation.ts
CHANGED
|
@@ -8,5 +8,5 @@ const {version} = createRequire(import.meta.url)('../package.json') as {version:
|
|
|
8
8
|
await startInstanceInstrumentation({
|
|
9
9
|
serviceName: 'api',
|
|
10
10
|
serviceVersion: version,
|
|
11
|
-
instrumentations: {fastify: true, http: true, pg: true, awsSdk: true},
|
|
11
|
+
instrumentations: {fastify: true, http: true, pg: true, awsSdk: true, pino: true},
|
|
12
12
|
});
|
package/src/modules.test.ts
CHANGED
|
@@ -21,6 +21,7 @@ const mocks = vi.hoisted(() => ({
|
|
|
21
21
|
buildAgentToolCatalogs: vi.fn(),
|
|
22
22
|
buildAgentToolSelectionCatalogs: vi.fn(),
|
|
23
23
|
createAgentModule: vi.fn(),
|
|
24
|
+
createAuthModule: vi.fn(),
|
|
24
25
|
createDefinitionsModule: vi.fn(),
|
|
25
26
|
createIntegrationsContext: vi.fn(),
|
|
26
27
|
createLogsModule: vi.fn(),
|
|
@@ -29,11 +30,13 @@ const mocks = vi.hoisted(() => ({
|
|
|
29
30
|
createSecretsModule: vi.fn(),
|
|
30
31
|
createTriggersModule: vi.fn(),
|
|
31
32
|
createWorkflowsModule: vi.fn(),
|
|
33
|
+
createWorkspacesModule: vi.fn(),
|
|
32
34
|
createWorkspaceConnectionSnapshotLoader: vi.fn(),
|
|
33
35
|
deleteSecrets: vi.fn(),
|
|
34
36
|
getIntegrationConnectionById: vi.fn(),
|
|
35
37
|
getSecret: vi.fn(),
|
|
36
38
|
getWorkspaceCreator: vi.fn(),
|
|
39
|
+
getWorkspaceOperatingState: vi.fn(),
|
|
37
40
|
listMembershipsForTokenClaims: vi.fn(),
|
|
38
41
|
setSecrets: vi.fn(),
|
|
39
42
|
}));
|
|
@@ -50,20 +53,7 @@ vi.mock('@shipfox/annotations', () => ({
|
|
|
50
53
|
},
|
|
51
54
|
}));
|
|
52
55
|
vi.mock('@shipfox/api-auth', () => ({
|
|
53
|
-
createAuthModule:
|
|
54
|
-
name: 'auth',
|
|
55
|
-
interModulePresentations: [
|
|
56
|
-
{
|
|
57
|
-
contract: authInterModuleContract,
|
|
58
|
-
handlers: {
|
|
59
|
-
mintJobLeaseToken: vi.fn(),
|
|
60
|
-
mintRunnerSessionToken: vi.fn(),
|
|
61
|
-
getCurrentAdminRole: vi.fn(),
|
|
62
|
-
requireAdminRole: vi.fn(),
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
}),
|
|
56
|
+
createAuthModule: mocks.createAuthModule,
|
|
67
57
|
}));
|
|
68
58
|
vi.mock('@shipfox/api-agent', () => ({createAgentModule: mocks.createAgentModule}));
|
|
69
59
|
vi.mock('@shipfox/api-auth/config', () => ({
|
|
@@ -97,21 +87,7 @@ vi.mock('@shipfox/api-workflows', () => ({
|
|
|
97
87
|
createWorkflowsModule: mocks.createWorkflowsModule,
|
|
98
88
|
}));
|
|
99
89
|
vi.mock('@shipfox/api-workspaces', () => ({
|
|
100
|
-
|
|
101
|
-
name: 'workspaces',
|
|
102
|
-
interModulePresentations: [
|
|
103
|
-
{
|
|
104
|
-
contract: workspacesInterModuleContract,
|
|
105
|
-
handlers: {
|
|
106
|
-
listMembershipsForTokenClaims: mocks.listMembershipsForTokenClaims,
|
|
107
|
-
getWorkspaceCreator: mocks.getWorkspaceCreator,
|
|
108
|
-
preflightInvitationAcceptance: vi.fn(),
|
|
109
|
-
acceptInvitation: vi.fn(),
|
|
110
|
-
requireActiveMembership: vi.fn(),
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
],
|
|
114
|
-
},
|
|
90
|
+
createWorkspacesModule: mocks.createWorkspacesModule,
|
|
115
91
|
}));
|
|
116
92
|
|
|
117
93
|
describe('defaultModules', () => {
|
|
@@ -119,6 +95,7 @@ describe('defaultModules', () => {
|
|
|
119
95
|
mocks.buildAgentToolCatalogs.mockReset();
|
|
120
96
|
mocks.buildAgentToolSelectionCatalogs.mockReset();
|
|
121
97
|
mocks.createAgentModule.mockReset();
|
|
98
|
+
mocks.createAuthModule.mockReset();
|
|
122
99
|
mocks.createDefinitionsModule.mockReset();
|
|
123
100
|
mocks.createIntegrationsContext.mockReset();
|
|
124
101
|
mocks.createLogsModule.mockReset();
|
|
@@ -127,6 +104,7 @@ describe('defaultModules', () => {
|
|
|
127
104
|
mocks.createSecretsModule.mockReset();
|
|
128
105
|
mocks.createTriggersModule.mockReset();
|
|
129
106
|
mocks.createWorkflowsModule.mockReset();
|
|
107
|
+
mocks.createWorkspacesModule.mockReset();
|
|
130
108
|
mocks.createWorkspaceConnectionSnapshotLoader.mockReset();
|
|
131
109
|
mocks.deleteSecrets.mockReset();
|
|
132
110
|
mocks.getIntegrationConnectionById.mockReset();
|
|
@@ -155,6 +133,20 @@ describe('defaultModules', () => {
|
|
|
155
133
|
mocks.buildAgentToolCatalogs.mockResolvedValue(new Map());
|
|
156
134
|
mocks.buildAgentToolSelectionCatalogs.mockResolvedValue(new Map());
|
|
157
135
|
mocks.createWorkspaceConnectionSnapshotLoader.mockReturnValue(vi.fn());
|
|
136
|
+
mocks.createAuthModule.mockReturnValue({
|
|
137
|
+
name: 'auth',
|
|
138
|
+
interModulePresentations: [
|
|
139
|
+
{
|
|
140
|
+
contract: authInterModuleContract,
|
|
141
|
+
handlers: {
|
|
142
|
+
mintJobLeaseToken: vi.fn(),
|
|
143
|
+
mintRunnerSessionToken: vi.fn(),
|
|
144
|
+
getCurrentAdminRole: vi.fn(),
|
|
145
|
+
requireAdminRole: vi.fn(),
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
});
|
|
158
150
|
mocks.deleteSecrets.mockResolvedValue({deleted: 1});
|
|
159
151
|
mocks.getSecret.mockResolvedValue({value: 'secret'});
|
|
160
152
|
mocks.listMembershipsForTokenClaims.mockResolvedValue({memberships: []});
|
|
@@ -165,6 +157,7 @@ describe('defaultModules', () => {
|
|
|
165
157
|
interModulePresentations: [
|
|
166
158
|
defineInterModulePresentation(projectsInterModuleContract, {
|
|
167
159
|
getProjectById: () => ({project: null}),
|
|
160
|
+
getWorkspaceProjectCounts: () => ({counts: []}),
|
|
168
161
|
requireProjectForWorkspace: () => ({
|
|
169
162
|
project: {
|
|
170
163
|
id: crypto.randomUUID(),
|
|
@@ -211,6 +204,7 @@ describe('defaultModules', () => {
|
|
|
211
204
|
cancelJobs: vi.fn(),
|
|
212
205
|
enqueueJobExecution: vi.fn(),
|
|
213
206
|
getEffectiveRunnerToolCapabilities: vi.fn(),
|
|
207
|
+
getWorkspaceJobCounts: vi.fn(),
|
|
214
208
|
getLeaseState: vi.fn(),
|
|
215
209
|
releaseJobExecution: vi.fn(),
|
|
216
210
|
},
|
|
@@ -241,6 +235,22 @@ describe('defaultModules', () => {
|
|
|
241
235
|
],
|
|
242
236
|
});
|
|
243
237
|
mocks.createTriggersModule.mockReturnValue({name: 'triggers'});
|
|
238
|
+
mocks.createWorkspacesModule.mockReturnValue({
|
|
239
|
+
name: 'workspaces',
|
|
240
|
+
interModulePresentations: [
|
|
241
|
+
{
|
|
242
|
+
contract: workspacesInterModuleContract,
|
|
243
|
+
handlers: {
|
|
244
|
+
listMembershipsForTokenClaims: mocks.listMembershipsForTokenClaims,
|
|
245
|
+
getWorkspaceCreator: mocks.getWorkspaceCreator,
|
|
246
|
+
getWorkspaceOperatingState: mocks.getWorkspaceOperatingState,
|
|
247
|
+
preflightInvitationAcceptance: vi.fn(),
|
|
248
|
+
acceptInvitation: vi.fn(),
|
|
249
|
+
requireActiveMembership: vi.fn(),
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
});
|
|
244
254
|
});
|
|
245
255
|
|
|
246
256
|
it('returns the API modules in lifecycle order', async () => {
|
|
@@ -291,6 +301,43 @@ describe('defaultModules', () => {
|
|
|
291
301
|
expect(mocks.createRunnersModule).toHaveBeenCalledWith({auth: expect.any(Object)});
|
|
292
302
|
});
|
|
293
303
|
|
|
304
|
+
it('uses the default Auth module factory when none is supplied', async () => {
|
|
305
|
+
await defaultModules();
|
|
306
|
+
|
|
307
|
+
expect(mocks.createAuthModule).toHaveBeenCalledWith({workspaces: expect.any(Object)});
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('composes Auth with the shared Workspaces client and registers the supplied module', async () => {
|
|
311
|
+
const signupPolicy = {isSignupAllowed: vi.fn().mockResolvedValue({allowed: true})};
|
|
312
|
+
const customAuthModule = mocks.createAuthModule();
|
|
313
|
+
mocks.createAuthModule.mockClear();
|
|
314
|
+
let extensionWorkspaces: WorkspacesInterModuleClient | undefined;
|
|
315
|
+
const extension = vi.fn(({workspaces}: {workspaces: WorkspacesInterModuleClient}) => {
|
|
316
|
+
extensionWorkspaces = workspaces;
|
|
317
|
+
return [];
|
|
318
|
+
});
|
|
319
|
+
const authModule = vi.fn(({workspaces}: {workspaces: WorkspacesInterModuleClient}) =>
|
|
320
|
+
mocks.createAuthModule({workspaces, signupPolicy}),
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
const modules = await defaultModules({authModule, extension});
|
|
324
|
+
const authWorkspaces = authModule.mock.calls[0]?.[0].workspaces;
|
|
325
|
+
|
|
326
|
+
expect(authModule).toHaveBeenCalledWith({workspaces: expect.any(Object)});
|
|
327
|
+
expect(mocks.createAuthModule).toHaveBeenCalledWith({
|
|
328
|
+
workspaces: authWorkspaces,
|
|
329
|
+
signupPolicy,
|
|
330
|
+
});
|
|
331
|
+
expect(extension).toHaveBeenCalledWith({workspaces: authWorkspaces});
|
|
332
|
+
expect(extensionWorkspaces).toBe(authWorkspaces);
|
|
333
|
+
expect(modules).toContain(customAuthModule);
|
|
334
|
+
expect(
|
|
335
|
+
modules.flatMap((module) =>
|
|
336
|
+
(module.interModulePresentations ?? []).map(({contract}) => contract.module),
|
|
337
|
+
),
|
|
338
|
+
).toContain(authInterModuleContract.module);
|
|
339
|
+
});
|
|
340
|
+
|
|
294
341
|
it('lets a host replace only the Runners module with the composed Auth client', async () => {
|
|
295
342
|
const policy = {filterEligibleWorkspaceIds: vi.fn().mockResolvedValue(new Set<string>())};
|
|
296
343
|
const runnersModule = mocks.createRunnersModule({});
|
package/src/modules.ts
CHANGED
|
@@ -24,7 +24,7 @@ import {secretsInterModuleContract} from '@shipfox/api-secrets-dto/inter-module'
|
|
|
24
24
|
import {createTriggersModule} from '@shipfox/api-triggers';
|
|
25
25
|
import {createWorkflowsModule} from '@shipfox/api-workflows';
|
|
26
26
|
import {workflowsInterModuleContract} from '@shipfox/api-workflows-dto/inter-module';
|
|
27
|
-
import {
|
|
27
|
+
import {createWorkspacesModule} from '@shipfox/api-workspaces';
|
|
28
28
|
import {
|
|
29
29
|
type WorkspacesInterModuleClient,
|
|
30
30
|
workspacesInterModuleContract,
|
|
@@ -40,10 +40,14 @@ import {logger} from '@shipfox/node-opentelemetry';
|
|
|
40
40
|
|
|
41
41
|
export interface DefaultModulesOptions {
|
|
42
42
|
webhookDeliverySource?: WebhookDeliverySource | undefined;
|
|
43
|
+
authModule?: DefaultAuthModuleFactory | undefined;
|
|
43
44
|
runnersModule?: DefaultRunnersModuleFactory | undefined;
|
|
44
45
|
extension?: DefaultModulesExtension | undefined;
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
export type DefaultAuthModuleFactory = (options: {
|
|
49
|
+
workspaces: WorkspacesInterModuleClient;
|
|
50
|
+
}) => ShipfoxModule;
|
|
47
51
|
export type DefaultRunnersModuleFactory = (options: {auth: AuthInterModuleClient}) => ShipfoxModule;
|
|
48
52
|
export type DefaultModulesExtension = (options: {
|
|
49
53
|
workspaces: WorkspacesInterModuleClient;
|
|
@@ -165,8 +169,8 @@ export async function defaultModules(
|
|
|
165
169
|
|
|
166
170
|
const modules = [
|
|
167
171
|
emailChallengesModule,
|
|
168
|
-
createAuthModule({workspaces: workspacesClient}),
|
|
169
|
-
|
|
172
|
+
(options.authModule ?? createAuthModule)({workspaces: workspacesClient}),
|
|
173
|
+
createWorkspacesModule({auth: authClient, projects: projectsClient, runners: runnersClient}),
|
|
170
174
|
createSecretsModule(projectsClient),
|
|
171
175
|
createAgentModule({secrets: secretsClient}),
|
|
172
176
|
integrations.module,
|
|
@@ -180,6 +184,7 @@ export async function defaultModules(
|
|
|
180
184
|
projects: projectsClient,
|
|
181
185
|
runners: runnersClient,
|
|
182
186
|
secrets: secretsClient,
|
|
187
|
+
workspaces: workspacesClient,
|
|
183
188
|
integrations: integrationsClient,
|
|
184
189
|
}),
|
|
185
190
|
annotationsModule,
|