@shipfox/api-server 2.0.0 → 4.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 +52 -0
- package/README.md +1 -1
- package/dist/modules.d.ts.map +1 -1
- package/dist/modules.js +14 -0
- package/dist/modules.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +4 -1
- package/dist/server.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +21 -21
- package/src/modules.test.ts +23 -1
- package/src/modules.ts +17 -0
- package/src/server.test.ts +28 -1
- package/src/server.ts +2 -0
- 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": "4.0.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
@@ -41,32 +41,32 @@
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@shipfox/
|
|
45
|
-
"@shipfox/api-agent": "
|
|
46
|
-
"@shipfox/api-
|
|
47
|
-
"@shipfox/
|
|
48
|
-
"@shipfox/api-
|
|
49
|
-
"@shipfox/api-
|
|
50
|
-
"@shipfox/api-logs": "
|
|
51
|
-
"@shipfox/api-projects": "
|
|
52
|
-
"@shipfox/api-
|
|
53
|
-
"@shipfox/api-
|
|
44
|
+
"@shipfox/annotations": "4.0.0",
|
|
45
|
+
"@shipfox/api-agent": "4.0.0",
|
|
46
|
+
"@shipfox/api-auth": "4.0.0",
|
|
47
|
+
"@shipfox/api-definitions": "4.0.0",
|
|
48
|
+
"@shipfox/api-dispatcher": "4.0.0",
|
|
49
|
+
"@shipfox/api-integration-core": "4.0.0",
|
|
50
|
+
"@shipfox/api-logs": "4.0.0",
|
|
51
|
+
"@shipfox/api-projects": "4.0.0",
|
|
52
|
+
"@shipfox/api-runners": "4.0.0",
|
|
53
|
+
"@shipfox/api-secrets": "4.0.0",
|
|
54
|
+
"@shipfox/api-triggers": "4.0.0",
|
|
55
|
+
"@shipfox/api-workflows": "4.0.0",
|
|
56
|
+
"@shipfox/api-workspaces": "4.0.0",
|
|
54
57
|
"@shipfox/config": "1.2.1",
|
|
55
|
-
"@shipfox/node-fastify": "0.2.1",
|
|
56
58
|
"@shipfox/node-error-monitoring": "0.1.2",
|
|
57
|
-
"@shipfox/
|
|
58
|
-
"@shipfox/node-module": "0.
|
|
59
|
-
"@shipfox/
|
|
60
|
-
"@shipfox/node-postgres": "0.4.1"
|
|
61
|
-
"@shipfox/api-runners": "2.0.0",
|
|
62
|
-
"@shipfox/node-opentelemetry": "0.5.0"
|
|
59
|
+
"@shipfox/node-fastify": "0.2.2",
|
|
60
|
+
"@shipfox/node-module": "0.3.1",
|
|
61
|
+
"@shipfox/node-opentelemetry": "0.5.1",
|
|
62
|
+
"@shipfox/node-postgres": "0.4.1"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@shipfox/ts-config": "1.3.8",
|
|
66
65
|
"@shipfox/biome": "1.8.1",
|
|
67
66
|
"@shipfox/swc": "1.2.5",
|
|
68
|
-
"@shipfox/
|
|
69
|
-
"@shipfox/typescript": "1.1.6"
|
|
67
|
+
"@shipfox/ts-config": "1.3.8",
|
|
68
|
+
"@shipfox/typescript": "1.1.6",
|
|
69
|
+
"@shipfox/vitest": "1.2.2"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "shipfox-swc",
|
package/src/modules.test.ts
CHANGED
|
@@ -96,7 +96,7 @@ describe('defaultModules', () => {
|
|
|
96
96
|
]);
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
it('uses the leased-step loader and namespaced
|
|
99
|
+
it('uses the leased-step loader and namespaced provider secrets', async () => {
|
|
100
100
|
await defaultModules();
|
|
101
101
|
|
|
102
102
|
expect(mocks.createIntegrationsContext).toHaveBeenCalledWith({
|
|
@@ -107,6 +107,11 @@ describe('defaultModules', () => {
|
|
|
107
107
|
getSecret: expect.any(Function),
|
|
108
108
|
setSecrets: expect.any(Function),
|
|
109
109
|
},
|
|
110
|
+
slack: {
|
|
111
|
+
deleteSecrets: expect.any(Function),
|
|
112
|
+
getSecret: expect.any(Function),
|
|
113
|
+
setSecrets: expect.any(Function),
|
|
114
|
+
},
|
|
110
115
|
},
|
|
111
116
|
agentTools: {loadLeasedAgentStep: mocks.loadRunningLeasedStep},
|
|
112
117
|
});
|
|
@@ -118,11 +123,19 @@ describe('defaultModules', () => {
|
|
|
118
123
|
getSecret: (params: {namespace: string}) => unknown;
|
|
119
124
|
setSecrets: (params: {namespace: string}) => unknown;
|
|
120
125
|
};
|
|
126
|
+
slack: {
|
|
127
|
+
deleteSecrets: (params: {namespace: string}) => unknown;
|
|
128
|
+
getSecret: (params: {namespace: string}) => unknown;
|
|
129
|
+
setSecrets: (params: {namespace: string}) => unknown;
|
|
130
|
+
};
|
|
121
131
|
};
|
|
122
132
|
};
|
|
123
133
|
integrationsOptions.secrets.linear.getSecret({namespace: 'workspace'});
|
|
124
134
|
integrationsOptions.secrets.linear.setSecrets({namespace: 'workspace'});
|
|
125
135
|
integrationsOptions.secrets.linear.deleteSecrets({namespace: 'workspace'});
|
|
136
|
+
integrationsOptions.secrets.slack.getSecret({namespace: 'workspace'});
|
|
137
|
+
integrationsOptions.secrets.slack.setSecrets({namespace: 'workspace'});
|
|
138
|
+
integrationsOptions.secrets.slack.deleteSecrets({namespace: 'workspace'});
|
|
126
139
|
|
|
127
140
|
expect(mocks.getSecret).toHaveBeenCalledWith({
|
|
128
141
|
namespace: 'system/integrations/linear/workspace',
|
|
@@ -133,5 +146,14 @@ describe('defaultModules', () => {
|
|
|
133
146
|
expect(mocks.deleteSecrets).toHaveBeenCalledWith({
|
|
134
147
|
namespace: 'system/integrations/linear/workspace',
|
|
135
148
|
});
|
|
149
|
+
expect(mocks.getSecret).toHaveBeenCalledWith({
|
|
150
|
+
namespace: 'system/integrations/slack/workspace',
|
|
151
|
+
});
|
|
152
|
+
expect(mocks.setSecrets).toHaveBeenCalledWith({
|
|
153
|
+
namespace: 'system/integrations/slack/workspace',
|
|
154
|
+
});
|
|
155
|
+
expect(mocks.deleteSecrets).toHaveBeenCalledWith({
|
|
156
|
+
namespace: 'system/integrations/slack/workspace',
|
|
157
|
+
});
|
|
136
158
|
});
|
|
137
159
|
});
|
package/src/modules.ts
CHANGED
|
@@ -45,6 +45,23 @@ export async function defaultModules(): Promise<ShipfoxModule[]> {
|
|
|
45
45
|
namespace: `system/integrations/linear/${params.namespace}`,
|
|
46
46
|
}),
|
|
47
47
|
},
|
|
48
|
+
slack: {
|
|
49
|
+
getSecret: (params) =>
|
|
50
|
+
getSecret({
|
|
51
|
+
...params,
|
|
52
|
+
namespace: `system/integrations/slack/${params.namespace}`,
|
|
53
|
+
}),
|
|
54
|
+
setSecrets: (params) =>
|
|
55
|
+
setSecrets({
|
|
56
|
+
...params,
|
|
57
|
+
namespace: `system/integrations/slack/${params.namespace}`,
|
|
58
|
+
}),
|
|
59
|
+
deleteSecrets: (params) =>
|
|
60
|
+
deleteSecrets({
|
|
61
|
+
...params,
|
|
62
|
+
namespace: `system/integrations/slack/${params.namespace}`,
|
|
63
|
+
}),
|
|
64
|
+
},
|
|
48
65
|
},
|
|
49
66
|
agentTools: {loadLeasedAgentStep: loadRunningLeasedStep},
|
|
50
67
|
});
|
package/src/server.test.ts
CHANGED
|
@@ -17,6 +17,7 @@ const mocks = vi.hoisted(() => {
|
|
|
17
17
|
createE2eAdminAuthMethod: vi.fn(),
|
|
18
18
|
createE2eRouteGroup: vi.fn(),
|
|
19
19
|
createPostgresClient: vi.fn(),
|
|
20
|
+
aggregateLoginMethods: vi.fn(),
|
|
20
21
|
initializeModules: vi.fn(),
|
|
21
22
|
listen: vi.fn(),
|
|
22
23
|
logger: {error: vi.fn(), info: vi.fn()},
|
|
@@ -47,6 +48,7 @@ vi.mock('@shipfox/node-fastify', () => ({
|
|
|
47
48
|
listen: mocks.listen,
|
|
48
49
|
}));
|
|
49
50
|
vi.mock('@shipfox/node-module', () => ({
|
|
51
|
+
aggregateLoginMethods: mocks.aggregateLoginMethods,
|
|
50
52
|
initializeModules: mocks.initializeModules,
|
|
51
53
|
registerModuleMetrics: mocks.registerModuleMetrics,
|
|
52
54
|
resetPublishers: mocks.resetPublishers,
|
|
@@ -73,7 +75,7 @@ vi.mock('./e2e.js', () => ({
|
|
|
73
75
|
}));
|
|
74
76
|
|
|
75
77
|
function module(): ShipfoxModule {
|
|
76
|
-
return {name: 'test'};
|
|
78
|
+
return {name: 'test', loginMethods: [{id: 'test-login'}]};
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
function worker(taskQueue = 'runtime-queue'): ModuleWorker {
|
|
@@ -101,6 +103,7 @@ function resetMocks(): void {
|
|
|
101
103
|
mocks.createE2eAdminAuthMethod.mockReset();
|
|
102
104
|
mocks.createE2eRouteGroup.mockReset();
|
|
103
105
|
mocks.createPostgresClient.mockReset();
|
|
106
|
+
mocks.aggregateLoginMethods.mockReset();
|
|
104
107
|
mocks.initializeModules.mockReset();
|
|
105
108
|
mocks.listen.mockReset();
|
|
106
109
|
mocks.logger.error.mockReset();
|
|
@@ -122,6 +125,7 @@ function resetMocks(): void {
|
|
|
122
125
|
mocks.closeErrorMonitoring.mockResolvedValue(true);
|
|
123
126
|
mocks.closePostgresClient.mockResolvedValue(undefined);
|
|
124
127
|
mocks.createApp.mockResolvedValue({});
|
|
128
|
+
mocks.aggregateLoginMethods.mockReturnValue([{id: 'test-login'}]);
|
|
125
129
|
mocks.createE2eRouteGroup.mockReturnValue([]);
|
|
126
130
|
mocks.initializeModules.mockResolvedValue({
|
|
127
131
|
auth: [],
|
|
@@ -166,6 +170,7 @@ describe('createServer', () => {
|
|
|
166
170
|
await createTestServer({modules});
|
|
167
171
|
|
|
168
172
|
expect(mocks.startServiceMetrics).toHaveBeenCalledWith({serviceName: 'api'});
|
|
173
|
+
expect(mocks.aggregateLoginMethods).toHaveBeenCalledWith({modules});
|
|
169
174
|
expect(mocks.createPostgresClient).toHaveBeenCalledOnce();
|
|
170
175
|
expect(mocks.initializeModules).toHaveBeenCalledWith({modules});
|
|
171
176
|
expect(mocks.registerModuleMetrics).toHaveBeenCalledWith({modules});
|
|
@@ -177,6 +182,28 @@ describe('createServer', () => {
|
|
|
177
182
|
});
|
|
178
183
|
});
|
|
179
184
|
|
|
185
|
+
it('fails before startup side effects when no login method is configured', async () => {
|
|
186
|
+
const failure = new Error('No login methods are configured');
|
|
187
|
+
mocks.aggregateLoginMethods.mockImplementationOnce(() => {
|
|
188
|
+
throw failure;
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const result = createTestServer({modules: [module()]});
|
|
192
|
+
|
|
193
|
+
await expect(result).rejects.toBe(failure);
|
|
194
|
+
expect(mocks.startServiceMetrics).not.toHaveBeenCalled();
|
|
195
|
+
expect(mocks.createPostgresClient).not.toHaveBeenCalled();
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('constructs and starts when a module contributes a login method', async () => {
|
|
199
|
+
const server = await createTestServer({modules: [module()]});
|
|
200
|
+
|
|
201
|
+
await server.start();
|
|
202
|
+
|
|
203
|
+
expect(mocks.startModuleWorkers).toHaveBeenCalledOnce();
|
|
204
|
+
expect(mocks.listen).toHaveBeenCalledOnce();
|
|
205
|
+
});
|
|
206
|
+
|
|
180
207
|
it('starts module workers before listening for HTTP requests', async () => {
|
|
181
208
|
const server = await createTestServer({modules: [module()]});
|
|
182
209
|
let resolveWorkers: ((handle: ModuleWorkersHandle) => void) | undefined;
|
package/src/server.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {captureException, closeErrorMonitoring} from '@shipfox/node-error-monitoring';
|
|
2
2
|
import {closeApp, createApp, listen} from '@shipfox/node-fastify';
|
|
3
3
|
import {
|
|
4
|
+
aggregateLoginMethods,
|
|
4
5
|
initializeModules,
|
|
5
6
|
type ModuleWorker,
|
|
6
7
|
type ModuleWorkersHandle,
|
|
@@ -43,6 +44,7 @@ export async function createServer(options: CreateServerOptions): Promise<Server
|
|
|
43
44
|
hasActiveServer = true;
|
|
44
45
|
|
|
45
46
|
try {
|
|
47
|
+
aggregateLoginMethods({modules: options.modules});
|
|
46
48
|
startServiceMetrics({serviceName: 'api'});
|
|
47
49
|
createPostgresClient();
|
|
48
50
|
|