@shipfox/api-server 7.0.1 → 7.1.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.
@@ -1,2 +1,2 @@
1
1
  $ shipfox-swc
2
- Successfully compiled: 6 files with swc (360.44ms)
2
+ Successfully compiled: 7 files with swc (415.93ms)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,52 @@
1
1
  # @shipfox/api-server
2
2
 
3
+ ## 7.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 769d919: Adds an anonymous login-method catalog with a published bounded DTO contract.
8
+ - 2e05e0e: Adds a host factory for replacing only the default Runners module with the composed Auth client.
9
+
10
+ ### Patch Changes
11
+
12
+ - ac42c96: Adds boundary-owned reporting for unexpected API runtime failures while preserving expected client and provider outcomes.
13
+ - 6ce08c0: Adds provider-neutral OpenTelemetry traces and Prometheus metrics across the API, Fastify, module workers, and Temporal workers.
14
+ - Updated dependencies [ac42c96]
15
+ - Updated dependencies [769d919]
16
+ - Updated dependencies [2a7d951]
17
+ - Updated dependencies [6ce08c0]
18
+ - Updated dependencies [8bb32b2]
19
+ - @shipfox/node-error-monitoring@0.2.0
20
+ - @shipfox/node-fastify@0.3.0
21
+ - @shipfox/node-module@0.5.0
22
+ - @shipfox/api-dispatcher@7.1.0
23
+ - @shipfox/api-logs@7.1.0
24
+ - @shipfox/api-triggers@7.1.0
25
+ - @shipfox/api-runners@7.1.0
26
+ - @shipfox/api-agent@7.1.0
27
+ - @shipfox/api-integration-core@7.1.0
28
+ - @shipfox/api-auth-dto@7.1.0
29
+ - @shipfox/api-auth@7.1.0
30
+ - @shipfox/node-opentelemetry@0.6.0
31
+ - @shipfox/api-email-challenges@0.3.0
32
+ - @shipfox/api-definitions@7.1.0
33
+ - @shipfox/api-workflows@7.1.0
34
+ - @shipfox/annotations@7.1.0
35
+ - @shipfox/api-projects@7.1.0
36
+ - @shipfox/api-secrets@7.1.0
37
+ - @shipfox/api-workspaces@7.1.0
38
+
39
+ ## 7.0.2
40
+
41
+ ### Patch Changes
42
+
43
+ - @shipfox/annotations@6.0.0
44
+ - @shipfox/api-auth@7.0.2
45
+ - @shipfox/api-email-challenges@0.2.3
46
+ - @shipfox/api-logs@6.0.0
47
+ - @shipfox/api-runners@7.0.2
48
+ - @shipfox/api-workflows@7.0.2
49
+
3
50
  ## 7.0.1
4
51
 
5
52
  ### Patch Changes
package/README.md CHANGED
@@ -7,6 +7,7 @@ Runs a Shipfox API server.
7
7
  - **`defaultModules()`**: Returns the standard module list.
8
8
  - **`createServer()`**: Builds an API server. The caller owns process signals.
9
9
  - **`runServer()`**: Starts the server. It listens for SIGTERM and SIGINT.
10
+ - **`createLoginMethodsRoute()`**: Builds the public login-method catalog route. `createServer` mounts it automatically.
10
11
  - **Instrumentation preload**: Starts metrics early. Load it before feature modules.
11
12
 
12
13
  ## Installation
@@ -41,6 +42,7 @@ node --import @shipfox/api-server/instrumentation ./dist/index.js
41
42
  ## Behavior Notes
42
43
 
43
44
  - **Custom composition**: Pass a module list to make a custom server. A module must declare a unique `loginMethods` entry. `createServer` throws before startup side effects when no login method is available.
45
+ - **Login-method catalog**: Every server composition exposes a public, unauthenticated `GET /auth/login-methods`, listing the bounded IDs of every module-contributed login method.
44
46
  - **Signal handling**: `createServer` does not install signal handlers.
45
47
  - **Lifecycle**: `start` starts workers and module services before the HTTP listener. `stop` is safe to call again. It stops services before workers and shared clients.
46
48
  - **Process scope**: Run one server at a time.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export { type DefaultModulesOptions, defaultModules } from './modules.js';
1
+ export { type DefaultModulesOptions, type DefaultRunnersModuleFactory, defaultModules, } from './modules.js';
2
+ export { createLoginMethodsRoute } from './routes/login-methods.js';
2
3
  export type { CreateServerOptions, RunServerOptions, ServerHandle } from './server.js';
3
4
  export { createServer, runServer } from './server.js';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,qBAAqB,EAAE,cAAc,EAAC,MAAM,cAAc,CAAC;AACxE,YAAY,EAAC,mBAAmB,EAAE,gBAAgB,EAAE,YAAY,EAAC,MAAM,aAAa,CAAC;AACrF,OAAO,EAAC,YAAY,EAAE,SAAS,EAAC,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAC,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AAClE,YAAY,EAAC,mBAAmB,EAAE,gBAAgB,EAAE,YAAY,EAAC,MAAM,aAAa,CAAC;AACrF,OAAO,EAAC,YAAY,EAAE,SAAS,EAAC,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { defaultModules } from './modules.js';
2
+ export { createLoginMethodsRoute } from './routes/login-methods.js';
2
3
  export { createServer, runServer } from './server.js';
3
4
 
4
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {type DefaultModulesOptions, defaultModules} from './modules.js';\nexport type {CreateServerOptions, RunServerOptions, ServerHandle} from './server.js';\nexport {createServer, runServer} from './server.js';\n"],"names":["defaultModules","createServer","runServer"],"mappings":"AAAA,SAAoCA,cAAc,QAAO,eAAe;AAExE,SAAQC,YAAY,EAAEC,SAAS,QAAO,cAAc"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {\n type DefaultModulesOptions,\n type DefaultRunnersModuleFactory,\n defaultModules,\n} from './modules.js';\nexport {createLoginMethodsRoute} from './routes/login-methods.js';\nexport type {CreateServerOptions, RunServerOptions, ServerHandle} from './server.js';\nexport {createServer, runServer} from './server.js';\n"],"names":["defaultModules","createLoginMethodsRoute","createServer","runServer"],"mappings":"AAAA,SAGEA,cAAc,QACT,eAAe;AACtB,SAAQC,uBAAuB,QAAO,4BAA4B;AAElE,SAAQC,YAAY,EAAEC,SAAS,QAAO,cAAc"}
@@ -1,12 +1,16 @@
1
+ import { createRequire } from 'node:module';
1
2
  import { startInstanceInstrumentation } from '@shipfox/node-opentelemetry';
3
+ const { version } = createRequire(import.meta.url)('../package.json');
2
4
  // The metrics API has no proxy meter: instruments created before this preload
3
5
  // completes bind to a no-op provider for the process lifetime.
4
6
  await startInstanceInstrumentation({
5
7
  serviceName: 'api',
8
+ serviceVersion: version,
6
9
  instrumentations: {
7
10
  fastify: true,
8
11
  http: true,
9
- pg: true
12
+ pg: true,
13
+ awsSdk: true
10
14
  }
11
15
  });
12
16
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/instrumentation.ts"],"sourcesContent":["import {startInstanceInstrumentation} from '@shipfox/node-opentelemetry';\n\n// The metrics API has no proxy meter: instruments created before this preload\n// completes bind to a no-op provider for the process lifetime.\nawait startInstanceInstrumentation({\n serviceName: 'api',\n instrumentations: {fastify: true, http: true, pg: true},\n});\n"],"names":["startInstanceInstrumentation","serviceName","instrumentations","fastify","http","pg"],"mappings":"AAAA,SAAQA,4BAA4B,QAAO,8BAA8B;AAEzE,8EAA8E;AAC9E,+DAA+D;AAC/D,MAAMA,6BAA6B;IACjCC,aAAa;IACbC,kBAAkB;QAACC,SAAS;QAAMC,MAAM;QAAMC,IAAI;IAAI;AACxD"}
1
+ {"version":3,"sources":["../src/instrumentation.ts"],"sourcesContent":["import {createRequire} from 'node:module';\nimport {startInstanceInstrumentation} from '@shipfox/node-opentelemetry';\n\nconst {version} = createRequire(import.meta.url)('../package.json') as {version: string};\n\n// The metrics API has no proxy meter: instruments created before this preload\n// completes bind to a no-op provider for the process lifetime.\nawait startInstanceInstrumentation({\n serviceName: 'api',\n serviceVersion: version,\n instrumentations: {fastify: true, http: true, pg: true, awsSdk: true},\n});\n"],"names":["createRequire","startInstanceInstrumentation","version","url","serviceName","serviceVersion","instrumentations","fastify","http","pg","awsSdk"],"mappings":"AAAA,SAAQA,aAAa,QAAO,cAAc;AAC1C,SAAQC,4BAA4B,QAAO,8BAA8B;AAEzE,MAAM,EAACC,OAAO,EAAC,GAAGF,cAAc,YAAYG,GAAG,EAAE;AAEjD,8EAA8E;AAC9E,+DAA+D;AAC/D,MAAMF,6BAA6B;IACjCG,aAAa;IACbC,gBAAgBH;IAChBI,kBAAkB;QAACC,SAAS;QAAMC,MAAM;QAAMC,IAAI;QAAMC,QAAQ;IAAI;AACtE"}
package/dist/modules.d.ts CHANGED
@@ -1,7 +1,12 @@
1
+ import { type AuthInterModuleClient } from '@shipfox/api-auth-dto/inter-module';
1
2
  import { type WebhookDeliverySource } from '@shipfox/api-integration-core';
2
3
  import type { ShipfoxModule } from '@shipfox/node-module';
3
4
  export interface DefaultModulesOptions {
4
5
  webhookDeliverySource?: WebhookDeliverySource | undefined;
6
+ runnersModule?: DefaultRunnersModuleFactory | undefined;
5
7
  }
8
+ export type DefaultRunnersModuleFactory = (options: {
9
+ auth: AuthInterModuleClient;
10
+ }) => ShipfoxModule;
6
11
  export declare function defaultModules(options?: DefaultModulesOptions): Promise<ShipfoxModule[]>;
7
12
  //# sourceMappingURL=modules.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAWA,OAAO,EAA4B,KAAK,qBAAqB,EAAC,MAAM,+BAA+B,CAAC;AAepG,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AAMxD,MAAM,WAAW,qBAAqB;IACpC,qBAAqB,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;CAC3D;AAED,wBAAsB,cAAc,CAClC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,aAAa,EAAE,CAAC,CAiI1B"}
1
+ {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,qBAAqB,EAE3B,MAAM,oCAAoC,CAAC;AAK5C,OAAO,EAA4B,KAAK,qBAAqB,EAAC,MAAM,+BAA+B,CAAC;AAgBpG,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AAOxD,MAAM,WAAW,qBAAqB;IACpC,qBAAqB,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAC1D,aAAa,CAAC,EAAE,2BAA2B,GAAG,SAAS,CAAC;CACzD;AAED,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,EAAE;IAAC,IAAI,EAAE,qBAAqB,CAAA;CAAC,KAAK,aAAa,CAAC;AAEpG,wBAAsB,cAAc,CAClC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,aAAa,EAAE,CAAC,CA6I1B"}
package/dist/modules.js CHANGED
@@ -23,10 +23,30 @@ import { createWorkflowsModule } from '@shipfox/api-workflows';
23
23
  import { workflowsInterModuleContract } from '@shipfox/api-workflows-dto/inter-module';
24
24
  import { workspacesModule } from '@shipfox/api-workspaces';
25
25
  import { workspacesInterModuleContract } from '@shipfox/api-workspaces-dto/inter-module';
26
+ import { reportError } from '@shipfox/node-error-monitoring';
26
27
  import { durationToSeconds } from '@shipfox/node-jwt';
27
28
  import { createInMemoryInterModuleTransport, registerInterModulePresentations } from '@shipfox/node-module/inter-module';
29
+ import { logger } from '@shipfox/node-opentelemetry';
28
30
  export async function defaultModules(options = {}) {
29
- const interModuleTransport = createInMemoryInterModuleTransport();
31
+ const interModuleTransport = createInMemoryInterModuleTransport({
32
+ reportInternalError: (error, context)=>{
33
+ logger().error({
34
+ err: error,
35
+ module: context.module,
36
+ method: context.method,
37
+ phase: context.phase
38
+ }, 'Inter-module call failed unexpectedly');
39
+ reportError(error, {
40
+ boundary: 'inter-module',
41
+ operation: `${context.module}.${context.method}`,
42
+ tags: {
43
+ module: context.module,
44
+ method: context.method,
45
+ phase: context.phase
46
+ }
47
+ });
48
+ }
49
+ });
30
50
  const workflowsClient = interModuleTransport.createClient(workflowsInterModuleContract);
31
51
  const authClient = interModuleTransport.createClient(authInterModuleContract);
32
52
  const agentClient = interModuleTransport.createClient(agentInterModuleContract);
@@ -138,7 +158,7 @@ export async function defaultModules(options = {}) {
138
158
  integrations: integrationsClient
139
159
  }),
140
160
  annotationsModule,
141
- createRunnersModule({
161
+ (options.runnersModule ?? createRunnersModule)({
142
162
  auth: authClient
143
163
  }),
144
164
  createLogsModule({
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/modules.ts"],"sourcesContent":["import {annotationsModule} from '@shipfox/annotations';\nimport {annotationsInterModuleContract} from '@shipfox/annotations-dto/inter-module';\nimport {createAgentModule} from '@shipfox/api-agent';\nimport {agentInterModuleContract} from '@shipfox/api-agent-dto/inter-module';\nimport {createAuthModule} from '@shipfox/api-auth';\nimport {config as authConfig} from '@shipfox/api-auth/config';\nimport {authInterModuleContract} from '@shipfox/api-auth-dto/inter-module';\nimport {createDefinitionsModule} from '@shipfox/api-definitions';\nimport {definitionsInterModuleContract} from '@shipfox/api-definitions-dto/inter-module';\nimport {dispatcherModule} from '@shipfox/api-dispatcher';\nimport {emailChallengesModule} from '@shipfox/api-email-challenges';\nimport {createIntegrationsContext, type WebhookDeliverySource} from '@shipfox/api-integration-core';\nimport {integrationsInterModuleContract} from '@shipfox/api-integration-core-dto';\nimport {createLogsModule} from '@shipfox/api-logs';\nimport {createProjectsModule} from '@shipfox/api-projects';\nimport {projectsInterModuleContract} from '@shipfox/api-projects-dto';\nimport {createRunnersModule} from '@shipfox/api-runners';\nimport {runnersInterModuleContract} from '@shipfox/api-runners-dto/inter-module';\nimport {createSecretsModule} from '@shipfox/api-secrets';\nimport {secretsInterModuleContract} from '@shipfox/api-secrets-dto/inter-module';\nimport {createTriggersModule} from '@shipfox/api-triggers';\nimport {createWorkflowsModule} from '@shipfox/api-workflows';\nimport {workflowsInterModuleContract} from '@shipfox/api-workflows-dto/inter-module';\nimport {workspacesModule} from '@shipfox/api-workspaces';\nimport {workspacesInterModuleContract} from '@shipfox/api-workspaces-dto/inter-module';\nimport {durationToSeconds} from '@shipfox/node-jwt';\nimport type {ShipfoxModule} from '@shipfox/node-module';\nimport {\n createInMemoryInterModuleTransport,\n registerInterModulePresentations,\n} from '@shipfox/node-module/inter-module';\n\nexport interface DefaultModulesOptions {\n webhookDeliverySource?: WebhookDeliverySource | undefined;\n}\n\nexport async function defaultModules(\n options: DefaultModulesOptions = {},\n): Promise<ShipfoxModule[]> {\n const interModuleTransport = createInMemoryInterModuleTransport();\n const workflowsClient = interModuleTransport.createClient(workflowsInterModuleContract);\n const authClient = interModuleTransport.createClient(authInterModuleContract);\n const agentClient = interModuleTransport.createClient(agentInterModuleContract);\n const runnersClient = interModuleTransport.createClient(runnersInterModuleContract);\n const projectsClient = interModuleTransport.createClient(projectsInterModuleContract);\n const definitionsClient = interModuleTransport.createClient(definitionsInterModuleContract);\n const annotationsClient = interModuleTransport.createClient(annotationsInterModuleContract);\n const secretsClient = interModuleTransport.createClient(secretsInterModuleContract);\n const workspacesClient = interModuleTransport.createClient(workspacesInterModuleContract);\n const integrationsClient = interModuleTransport.createClient(integrationsInterModuleContract);\n const integrations = await createIntegrationsContext({\n workspaces: workspacesClient,\n secrets: {\n deleteSecrets: async (params) => (await secretsClient.deleteSecrets(params)).deleted,\n linear: {\n getSecret: async (params) =>\n (\n await secretsClient.getSecret({\n ...params,\n namespace: `system/integrations/linear/${params.namespace}`,\n })\n ).value,\n setSecrets: async (params) => {\n const {editedBy, ...secretParams} = params;\n await secretsClient.setSecrets({\n ...secretParams,\n namespace: `system/integrations/linear/${secretParams.namespace}`,\n ...(editedBy === undefined ? {} : {editedBy}),\n });\n },\n deleteSecrets: async (params) =>\n (\n await secretsClient.deleteSecrets({\n ...params,\n namespace: `system/integrations/linear/${params.namespace}`,\n })\n ).deleted,\n },\n jira: {\n getSecret: async (params) =>\n (\n await secretsClient.getSecret({\n ...params,\n namespace: `system/integrations/jira/${params.namespace}`,\n })\n ).value,\n setSecrets: async (params) => {\n const {editedBy, ...secretParams} = params;\n await secretsClient.setSecrets({\n ...secretParams,\n namespace: `system/integrations/jira/${secretParams.namespace}`,\n ...(editedBy === undefined ? {} : {editedBy}),\n });\n },\n deleteSecrets: async (params) =>\n (\n await secretsClient.deleteSecrets({\n ...params,\n namespace: `system/integrations/jira/${params.namespace}`,\n })\n ).deleted,\n },\n slack: {\n getSecret: async (params) =>\n (\n await secretsClient.getSecret({\n ...params,\n namespace: `system/integrations/slack/${params.namespace}`,\n })\n ).value,\n setSecrets: async (params) => {\n const {editedBy, ...secretParams} = params;\n await secretsClient.setSecrets({\n ...secretParams,\n namespace: `system/integrations/slack/${secretParams.namespace}`,\n ...(editedBy === undefined ? {} : {editedBy}),\n });\n },\n deleteSecrets: async (params) =>\n (\n await secretsClient.deleteSecrets({\n ...params,\n namespace: `system/integrations/slack/${params.namespace}`,\n })\n ).deleted,\n },\n },\n agentTools: {workflows: workflowsClient},\n webhookDeliverySource: options.webhookDeliverySource,\n });\n const projectsModule = createProjectsModule({integrations: integrationsClient});\n const definitionsModule = createDefinitionsModule({\n projects: projectsClient,\n integrations: integrationsClient,\n });\n\n const modules = [\n emailChallengesModule,\n createAuthModule({workspaces: workspacesClient}),\n workspacesModule,\n createSecretsModule(projectsClient),\n createAgentModule({secrets: secretsClient}),\n integrations.module,\n projectsModule,\n definitionsModule,\n createWorkflowsModule({\n annotations: annotationsClient,\n agent: agentClient,\n definitions: definitionsClient,\n auth: authClient,\n projects: projectsClient,\n runners: runnersClient,\n secrets: secretsClient,\n integrations: integrationsClient,\n }),\n annotationsModule,\n createRunnersModule({auth: authClient}),\n createLogsModule({\n workflows: workflowsClient,\n jobLeaseTokenTtlSeconds: durationToSeconds(authConfig.AUTH_JOB_LEASE_TOKEN_EXPIRES_IN),\n }),\n createTriggersModule({workflows: workflowsClient}),\n dispatcherModule,\n ];\n registerInterModulePresentations({transport: interModuleTransport, modules});\n interModuleTransport.seal();\n return modules;\n}\n"],"names":["annotationsModule","annotationsInterModuleContract","createAgentModule","agentInterModuleContract","createAuthModule","config","authConfig","authInterModuleContract","createDefinitionsModule","definitionsInterModuleContract","dispatcherModule","emailChallengesModule","createIntegrationsContext","integrationsInterModuleContract","createLogsModule","createProjectsModule","projectsInterModuleContract","createRunnersModule","runnersInterModuleContract","createSecretsModule","secretsInterModuleContract","createTriggersModule","createWorkflowsModule","workflowsInterModuleContract","workspacesModule","workspacesInterModuleContract","durationToSeconds","createInMemoryInterModuleTransport","registerInterModulePresentations","defaultModules","options","interModuleTransport","workflowsClient","createClient","authClient","agentClient","runnersClient","projectsClient","definitionsClient","annotationsClient","secretsClient","workspacesClient","integrationsClient","integrations","workspaces","secrets","deleteSecrets","params","deleted","linear","getSecret","namespace","value","setSecrets","editedBy","secretParams","undefined","jira","slack","agentTools","workflows","webhookDeliverySource","projectsModule","definitionsModule","projects","modules","module","annotations","agent","definitions","auth","runners","jobLeaseTokenTtlSeconds","AUTH_JOB_LEASE_TOKEN_EXPIRES_IN","transport","seal"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/modules.ts"],"sourcesContent":["import {annotationsModule} from '@shipfox/annotations';\nimport {annotationsInterModuleContract} from '@shipfox/annotations-dto/inter-module';\nimport {createAgentModule} from '@shipfox/api-agent';\nimport {agentInterModuleContract} from '@shipfox/api-agent-dto/inter-module';\nimport {createAuthModule} from '@shipfox/api-auth';\nimport {config as authConfig} from '@shipfox/api-auth/config';\nimport {\n type AuthInterModuleClient,\n authInterModuleContract,\n} from '@shipfox/api-auth-dto/inter-module';\nimport {createDefinitionsModule} from '@shipfox/api-definitions';\nimport {definitionsInterModuleContract} from '@shipfox/api-definitions-dto/inter-module';\nimport {dispatcherModule} from '@shipfox/api-dispatcher';\nimport {emailChallengesModule} from '@shipfox/api-email-challenges';\nimport {createIntegrationsContext, type WebhookDeliverySource} from '@shipfox/api-integration-core';\nimport {integrationsInterModuleContract} from '@shipfox/api-integration-core-dto';\nimport {createLogsModule} from '@shipfox/api-logs';\nimport {createProjectsModule} from '@shipfox/api-projects';\nimport {projectsInterModuleContract} from '@shipfox/api-projects-dto';\nimport {createRunnersModule} from '@shipfox/api-runners';\nimport {runnersInterModuleContract} from '@shipfox/api-runners-dto/inter-module';\nimport {createSecretsModule} from '@shipfox/api-secrets';\nimport {secretsInterModuleContract} from '@shipfox/api-secrets-dto/inter-module';\nimport {createTriggersModule} from '@shipfox/api-triggers';\nimport {createWorkflowsModule} from '@shipfox/api-workflows';\nimport {workflowsInterModuleContract} from '@shipfox/api-workflows-dto/inter-module';\nimport {workspacesModule} from '@shipfox/api-workspaces';\nimport {workspacesInterModuleContract} from '@shipfox/api-workspaces-dto/inter-module';\nimport {reportError} from '@shipfox/node-error-monitoring';\nimport {durationToSeconds} from '@shipfox/node-jwt';\nimport type {ShipfoxModule} from '@shipfox/node-module';\nimport {\n createInMemoryInterModuleTransport,\n registerInterModulePresentations,\n} from '@shipfox/node-module/inter-module';\nimport {logger} from '@shipfox/node-opentelemetry';\n\nexport interface DefaultModulesOptions {\n webhookDeliverySource?: WebhookDeliverySource | undefined;\n runnersModule?: DefaultRunnersModuleFactory | undefined;\n}\n\nexport type DefaultRunnersModuleFactory = (options: {auth: AuthInterModuleClient}) => ShipfoxModule;\n\nexport async function defaultModules(\n options: DefaultModulesOptions = {},\n): Promise<ShipfoxModule[]> {\n const interModuleTransport = createInMemoryInterModuleTransport({\n reportInternalError: (error, context) => {\n logger().error(\n {err: error, module: context.module, method: context.method, phase: context.phase},\n 'Inter-module call failed unexpectedly',\n );\n reportError(error, {\n boundary: 'inter-module',\n operation: `${context.module}.${context.method}`,\n tags: {module: context.module, method: context.method, phase: context.phase},\n });\n },\n });\n const workflowsClient = interModuleTransport.createClient(workflowsInterModuleContract);\n const authClient = interModuleTransport.createClient(authInterModuleContract);\n const agentClient = interModuleTransport.createClient(agentInterModuleContract);\n const runnersClient = interModuleTransport.createClient(runnersInterModuleContract);\n const projectsClient = interModuleTransport.createClient(projectsInterModuleContract);\n const definitionsClient = interModuleTransport.createClient(definitionsInterModuleContract);\n const annotationsClient = interModuleTransport.createClient(annotationsInterModuleContract);\n const secretsClient = interModuleTransport.createClient(secretsInterModuleContract);\n const workspacesClient = interModuleTransport.createClient(workspacesInterModuleContract);\n const integrationsClient = interModuleTransport.createClient(integrationsInterModuleContract);\n const integrations = await createIntegrationsContext({\n workspaces: workspacesClient,\n secrets: {\n deleteSecrets: async (params) => (await secretsClient.deleteSecrets(params)).deleted,\n linear: {\n getSecret: async (params) =>\n (\n await secretsClient.getSecret({\n ...params,\n namespace: `system/integrations/linear/${params.namespace}`,\n })\n ).value,\n setSecrets: async (params) => {\n const {editedBy, ...secretParams} = params;\n await secretsClient.setSecrets({\n ...secretParams,\n namespace: `system/integrations/linear/${secretParams.namespace}`,\n ...(editedBy === undefined ? {} : {editedBy}),\n });\n },\n deleteSecrets: async (params) =>\n (\n await secretsClient.deleteSecrets({\n ...params,\n namespace: `system/integrations/linear/${params.namespace}`,\n })\n ).deleted,\n },\n jira: {\n getSecret: async (params) =>\n (\n await secretsClient.getSecret({\n ...params,\n namespace: `system/integrations/jira/${params.namespace}`,\n })\n ).value,\n setSecrets: async (params) => {\n const {editedBy, ...secretParams} = params;\n await secretsClient.setSecrets({\n ...secretParams,\n namespace: `system/integrations/jira/${secretParams.namespace}`,\n ...(editedBy === undefined ? {} : {editedBy}),\n });\n },\n deleteSecrets: async (params) =>\n (\n await secretsClient.deleteSecrets({\n ...params,\n namespace: `system/integrations/jira/${params.namespace}`,\n })\n ).deleted,\n },\n slack: {\n getSecret: async (params) =>\n (\n await secretsClient.getSecret({\n ...params,\n namespace: `system/integrations/slack/${params.namespace}`,\n })\n ).value,\n setSecrets: async (params) => {\n const {editedBy, ...secretParams} = params;\n await secretsClient.setSecrets({\n ...secretParams,\n namespace: `system/integrations/slack/${secretParams.namespace}`,\n ...(editedBy === undefined ? {} : {editedBy}),\n });\n },\n deleteSecrets: async (params) =>\n (\n await secretsClient.deleteSecrets({\n ...params,\n namespace: `system/integrations/slack/${params.namespace}`,\n })\n ).deleted,\n },\n },\n agentTools: {workflows: workflowsClient},\n webhookDeliverySource: options.webhookDeliverySource,\n });\n const projectsModule = createProjectsModule({integrations: integrationsClient});\n const definitionsModule = createDefinitionsModule({\n projects: projectsClient,\n integrations: integrationsClient,\n });\n\n const modules = [\n emailChallengesModule,\n createAuthModule({workspaces: workspacesClient}),\n workspacesModule,\n createSecretsModule(projectsClient),\n createAgentModule({secrets: secretsClient}),\n integrations.module,\n projectsModule,\n definitionsModule,\n createWorkflowsModule({\n annotations: annotationsClient,\n agent: agentClient,\n definitions: definitionsClient,\n auth: authClient,\n projects: projectsClient,\n runners: runnersClient,\n secrets: secretsClient,\n integrations: integrationsClient,\n }),\n annotationsModule,\n (options.runnersModule ?? createRunnersModule)({auth: authClient}),\n createLogsModule({\n workflows: workflowsClient,\n jobLeaseTokenTtlSeconds: durationToSeconds(authConfig.AUTH_JOB_LEASE_TOKEN_EXPIRES_IN),\n }),\n createTriggersModule({workflows: workflowsClient}),\n dispatcherModule,\n ];\n registerInterModulePresentations({transport: interModuleTransport, modules});\n interModuleTransport.seal();\n return modules;\n}\n"],"names":["annotationsModule","annotationsInterModuleContract","createAgentModule","agentInterModuleContract","createAuthModule","config","authConfig","authInterModuleContract","createDefinitionsModule","definitionsInterModuleContract","dispatcherModule","emailChallengesModule","createIntegrationsContext","integrationsInterModuleContract","createLogsModule","createProjectsModule","projectsInterModuleContract","createRunnersModule","runnersInterModuleContract","createSecretsModule","secretsInterModuleContract","createTriggersModule","createWorkflowsModule","workflowsInterModuleContract","workspacesModule","workspacesInterModuleContract","reportError","durationToSeconds","createInMemoryInterModuleTransport","registerInterModulePresentations","logger","defaultModules","options","interModuleTransport","reportInternalError","error","context","err","module","method","phase","boundary","operation","tags","workflowsClient","createClient","authClient","agentClient","runnersClient","projectsClient","definitionsClient","annotationsClient","secretsClient","workspacesClient","integrationsClient","integrations","workspaces","secrets","deleteSecrets","params","deleted","linear","getSecret","namespace","value","setSecrets","editedBy","secretParams","undefined","jira","slack","agentTools","workflows","webhookDeliverySource","projectsModule","definitionsModule","projects","modules","annotations","agent","definitions","auth","runners","runnersModule","jobLeaseTokenTtlSeconds","AUTH_JOB_LEASE_TOKEN_EXPIRES_IN","transport","seal"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { LoginMethod } from '@shipfox/node-module';
2
+ export declare function createLoginMethodsRoute({ loginMethods }: {
3
+ loginMethods: readonly LoginMethod[];
4
+ }): import("@shipfox/node-fastify").RouteDefinition;
5
+ //# sourceMappingURL=login-methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login-methods.d.ts","sourceRoot":"","sources":["../../src/routes/login-methods.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,sBAAsB,CAAC;AAEtD,wBAAgB,uBAAuB,CAAC,EAAC,YAAY,EAAC,EAAE;IAAC,YAAY,EAAE,SAAS,WAAW,EAAE,CAAA;CAAC,mDAgB7F"}
@@ -0,0 +1,22 @@
1
+ import { loginMethodsResponseSchema } from '@shipfox/api-auth-dto';
2
+ import { defineRoute } from '@shipfox/node-fastify';
3
+ export function createLoginMethodsRoute({ loginMethods }) {
4
+ const response = loginMethodsResponseSchema.parse({
5
+ login_methods: loginMethods.map(({ id })=>({
6
+ id
7
+ }))
8
+ });
9
+ return defineRoute({
10
+ method: 'GET',
11
+ path: '/auth/login-methods',
12
+ description: 'List the login methods available in this server composition.',
13
+ schema: {
14
+ response: {
15
+ 200: loginMethodsResponseSchema
16
+ }
17
+ },
18
+ handler: ()=>response
19
+ });
20
+ }
21
+
22
+ //# sourceMappingURL=login-methods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/routes/login-methods.ts"],"sourcesContent":["import {loginMethodsResponseSchema} from '@shipfox/api-auth-dto';\nimport {defineRoute} from '@shipfox/node-fastify';\nimport type {LoginMethod} from '@shipfox/node-module';\n\nexport function createLoginMethodsRoute({loginMethods}: {loginMethods: readonly LoginMethod[]}) {\n const response = loginMethodsResponseSchema.parse({\n login_methods: loginMethods.map(({id}) => ({id})),\n });\n\n return defineRoute({\n method: 'GET',\n path: '/auth/login-methods',\n description: 'List the login methods available in this server composition.',\n schema: {\n response: {\n 200: loginMethodsResponseSchema,\n },\n },\n handler: () => response,\n });\n}\n"],"names":["loginMethodsResponseSchema","defineRoute","createLoginMethodsRoute","loginMethods","response","parse","login_methods","map","id","method","path","description","schema","handler"],"mappings":"AAAA,SAAQA,0BAA0B,QAAO,wBAAwB;AACjE,SAAQC,WAAW,QAAO,wBAAwB;AAGlD,OAAO,SAASC,wBAAwB,EAACC,YAAY,EAAyC;IAC5F,MAAMC,WAAWJ,2BAA2BK,KAAK,CAAC;QAChDC,eAAeH,aAAaI,GAAG,CAAC,CAAC,EAACC,EAAE,EAAC,GAAM,CAAA;gBAACA;YAAE,CAAA;IAChD;IAEA,OAAOP,YAAY;QACjBQ,QAAQ;QACRC,MAAM;QACNC,aAAa;QACbC,QAAQ;YACNR,UAAU;gBACR,KAAKJ;YACP;QACF;QACAa,SAAS,IAAMT;IACjB;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,aAAa,EAElB,KAAK,YAAY,EAIjB,KAAK,aAAa,EAGnB,MAAM,sBAAsB,CAAC;AAW9B,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrF;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAuGtF;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiChF"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,aAAa,EAElB,KAAK,YAAY,EAIjB,KAAK,aAAa,EAGnB,MAAM,sBAAsB,CAAC;AAY9B,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrF;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAsHtF;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CA6ChF"}
package/dist/server.js CHANGED
@@ -1,10 +1,11 @@
1
- import { captureException, closeErrorMonitoring } from '@shipfox/node-error-monitoring';
1
+ import { closeErrorMonitoring, markErrorReported, reportError } from '@shipfox/node-error-monitoring';
2
2
  import { closeApp, createApp, listen } from '@shipfox/node-fastify';
3
3
  import { aggregateLoginMethods, initializeModules, registerModuleMetrics, runModuleStartupTasks, startModuleServices, startModuleWorkers } from '@shipfox/node-module';
4
4
  import { logger, shutdownServiceMetrics, startServiceMetrics } from '@shipfox/node-opentelemetry';
5
5
  import { closePostgresClient, createPostgresClient } from '@shipfox/node-postgres';
6
6
  import { config, parseApiTrustProxy } from './config.js';
7
7
  import { createE2eAdminAuthMethod, createE2eRouteGroup } from './e2e.js';
8
+ import { createLoginMethodsRoute } from './routes/login-methods.js';
8
9
  const RUNTIME_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS = 10_000;
9
10
  const ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS = 2_000;
10
11
  let hasActiveServer = false;
@@ -14,7 +15,7 @@ export async function createServer(options) {
14
15
  }
15
16
  hasActiveServer = true;
16
17
  try {
17
- aggregateLoginMethods({
18
+ const loginMethods = aggregateLoginMethods({
18
19
  modules: options.modules
19
20
  });
20
21
  startServiceMetrics({
@@ -47,6 +48,9 @@ export async function createServer(options) {
47
48
  ...e2eAuth
48
49
  ],
49
50
  routes: [
51
+ createLoginMethodsRoute({
52
+ loginMethods
53
+ }),
50
54
  ...routes,
51
55
  ...mountedE2eRoutes
52
56
  ],
@@ -100,11 +104,26 @@ export async function createServer(options) {
100
104
  ()=>servicesHandle?.stop(),
101
105
  ()=>workersHandle?.stop(),
102
106
  ()=>shutdownServiceMetrics(),
103
- ()=>closePostgresClient(),
104
- async ()=>{
105
- await closeErrorMonitoring(ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS);
106
- }
107
+ ()=>closePostgresClient()
107
108
  ]);
109
+ for (const cleanupError of cleanupErrors){
110
+ logger().error({
111
+ err: cleanupError
112
+ }, 'Failed to clean up API server during shutdown');
113
+ reportError(cleanupError, {
114
+ boundary: 'api.shutdown',
115
+ operation: 'cleanup'
116
+ });
117
+ }
118
+ try {
119
+ const errorMonitoringClosed = await closeErrorMonitoring(ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS);
120
+ if (!errorMonitoringClosed) {
121
+ logger().error('Timed out closing error monitoring during API shutdown');
122
+ cleanupErrors.push(new Error('Timed out closing error monitoring during API shutdown'));
123
+ }
124
+ } catch (error) {
125
+ cleanupErrors.push(error);
126
+ }
108
127
  throwCleanupErrors(cleanupErrors, 'Failed to stop API server');
109
128
  stopped = true;
110
129
  hasActiveServer = false;
@@ -128,6 +147,10 @@ export async function createServer(options) {
128
147
  err: cleanupError,
129
148
  bootError: error
130
149
  }, 'Failed to clean up API server boot');
150
+ reportError(cleanupError, {
151
+ boundary: 'api.startup',
152
+ operation: 'cleanup'
153
+ });
131
154
  }
132
155
  hasActiveServer = false;
133
156
  throw error;
@@ -156,10 +179,23 @@ export async function runServer(options) {
156
179
  err: cleanupError,
157
180
  startError: error
158
181
  }, 'Failed to clean up API server startup');
182
+ reportError(cleanupError, {
183
+ boundary: 'api.startup',
184
+ operation: 'cleanup-after-failed-start'
185
+ });
159
186
  }
160
187
  throw error;
161
188
  }
162
- const stopAndExit = ()=>void handle.stop().finally(()=>process.exit(0));
189
+ const stopAndExit = ()=>void handle.stop().then(()=>process.exit(0), (error)=>{
190
+ logger().error({
191
+ err: error
192
+ }, 'Failed to stop API server after shutdown signal');
193
+ reportError(error, {
194
+ boundary: 'api.shutdown',
195
+ operation: 'signal-stop'
196
+ });
197
+ process.exit(1);
198
+ });
163
199
  process.once('SIGTERM', stopAndExit);
164
200
  process.once('SIGINT', stopAndExit);
165
201
  return handle;
@@ -188,7 +224,9 @@ async function runCleanupSteps(steps) {
188
224
  function throwCleanupErrors(cleanupErrors, message) {
189
225
  if (cleanupErrors.length === 0) return;
190
226
  if (cleanupErrors.length === 1) throw cleanupErrors[0];
191
- throw new AggregateError(cleanupErrors, message);
227
+ const aggregate = new AggregateError(cleanupErrors, message);
228
+ markErrorReported(aggregate);
229
+ throw aggregate;
192
230
  }
193
231
  async function handleModuleWorkerFailure(error, worker, onWorkerFailure) {
194
232
  await handleModuleRuntimeFailure({
@@ -215,10 +253,20 @@ async function handleModuleRuntimeFailure(options) {
215
253
  err: options.error,
216
254
  ...options.fields
217
255
  }, options.message);
218
- captureException(options.error);
256
+ reportError(options.error, {
257
+ boundary: 'api.runtime',
258
+ tags: options.fields
259
+ });
219
260
  try {
220
261
  await closeHttpServerAfterRuntimeFailure();
221
- await closeErrorMonitoring(ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS);
262
+ const errorMonitoringClosed = await closeErrorMonitoring(ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS);
263
+ if (!errorMonitoringClosed) {
264
+ logger().error('Timed out closing error monitoring after module runtime failure');
265
+ }
266
+ } catch (error) {
267
+ logger().error({
268
+ err: error
269
+ }, 'Failed to close error monitoring after module runtime failure');
222
270
  } finally{
223
271
  await options.onFailure();
224
272
  }
@@ -238,14 +286,23 @@ async function closeHttpServerAfterRuntimeFailure() {
238
286
  }
239
287
  });
240
288
  if (result === 'timeout') {
289
+ const error = new Error('Timed out closing HTTP server after module runtime failure');
241
290
  logger().error({
242
291
  timeoutMs: RUNTIME_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS
243
- }, 'Timed out closing HTTP server after module runtime failure');
292
+ }, error.message);
293
+ reportError(error, {
294
+ boundary: 'api.runtime',
295
+ operation: 'close-http-timeout'
296
+ });
244
297
  }
245
298
  } catch (error) {
246
299
  logger().error({
247
300
  err: error
248
301
  }, 'Failed to close HTTP server after module runtime failure');
302
+ reportError(error, {
303
+ boundary: 'api.runtime',
304
+ operation: 'close-http'
305
+ });
249
306
  } finally{
250
307
  if (timeoutId) {
251
308
  clearTimeout(timeoutId);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import {captureException, closeErrorMonitoring} from '@shipfox/node-error-monitoring';\nimport {closeApp, createApp, listen} from '@shipfox/node-fastify';\nimport {\n aggregateLoginMethods,\n initializeModules,\n type ModuleService,\n type ModuleServicesHandle,\n type ModuleWorker,\n type ModuleWorkersHandle,\n registerModuleMetrics,\n runModuleStartupTasks,\n type ShipfoxModule,\n startModuleServices,\n startModuleWorkers,\n} from '@shipfox/node-module';\nimport {logger, shutdownServiceMetrics, startServiceMetrics} from '@shipfox/node-opentelemetry';\nimport {closePostgresClient, createPostgresClient} from '@shipfox/node-postgres';\nimport {config, parseApiTrustProxy} from './config.js';\nimport {createE2eAdminAuthMethod, createE2eRouteGroup} from './e2e.js';\n\nconst RUNTIME_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS = 10_000;\nconst ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS = 2_000;\n\nlet hasActiveServer = false;\n\nexport interface CreateServerOptions {\n modules: ShipfoxModule[];\n onWorkerFailure?: (error: unknown, worker: ModuleWorker) => void | Promise<void>;\n onServiceFailure?: (error: unknown, service: ModuleService) => void | Promise<void>;\n}\n\nexport interface ServerHandle {\n start(): Promise<string>;\n stop(): Promise<void>;\n}\n\nexport interface RunServerOptions {\n modules: ShipfoxModule[];\n onStartupFailure?: (error: unknown) => void | Promise<void>;\n}\n\nexport async function createServer(options: CreateServerOptions): Promise<ServerHandle> {\n if (hasActiveServer) {\n throw new Error('Cannot create a second API server before the existing server stops');\n }\n hasActiveServer = true;\n\n try {\n aggregateLoginMethods({modules: options.modules});\n startServiceMetrics({serviceName: 'api'});\n createPostgresClient();\n\n const {auth, routes, e2eRoutes, workers, services, outboxRegistry} = await initializeModules({\n modules: options.modules,\n });\n registerModuleMetrics({modules: options.modules, context: {outboxRegistry}});\n await runModuleStartupTasks({modules: options.modules, context: {outboxRegistry}});\n\n const e2eAuth = config.E2E_ENABLED ? [createE2eAdminAuthMethod(config)] : [];\n const mountedE2eRoutes = createE2eRouteGroup(e2eRoutes, config);\n\n logger().info('Creating HTTP server');\n await createApp({\n auth: [...auth, ...e2eAuth],\n routes: [...routes, ...mountedE2eRoutes],\n fastifyOptions: {trustProxy: parseApiTrustProxy(config.API_TRUST_PROXY)},\n });\n\n let workersHandle: ModuleWorkersHandle | undefined;\n let servicesHandle: ModuleServicesHandle | undefined;\n let startPromise: Promise<string> | undefined;\n let stopPromise: Promise<void> | undefined;\n let stopped = false;\n\n const start = (): Promise<string> => {\n if (stopPromise || stopped)\n return Promise.reject(new Error('Cannot start a stopped API server'));\n\n startPromise ??= (async () => {\n logger().info('Starting module workers');\n workersHandle = await startModuleWorkers({\n workers,\n context: {outboxRegistry},\n onWorkerFailure: (error, worker) =>\n handleModuleWorkerFailure(error, worker, options.onWorkerFailure),\n });\n\n logger().info('Starting module services');\n servicesHandle = await startModuleServices({\n services,\n context: {outboxRegistry},\n onServiceFailure: (error, service) =>\n handleModuleServiceFailure(error, service, options.onServiceFailure),\n });\n\n if (stopPromise) throw new Error('API server stopped during startup');\n\n logger().info('Starting HTTP server');\n const address =\n config.API_PORT === undefined ? await listen() : await listen({port: config.API_PORT});\n logger().info({address}, 'HTTP server listening');\n return address;\n })();\n return startPromise;\n };\n\n const stop = (): Promise<void> => {\n if (stopped) return Promise.resolve();\n\n stopPromise ??= (async () => {\n try {\n await startPromise?.catch(() => undefined);\n const cleanupErrors = await runCleanupSteps([\n () => closeApp(),\n () => servicesHandle?.stop(),\n () => workersHandle?.stop(),\n () => shutdownServiceMetrics(),\n () => closePostgresClient(),\n async () => {\n await closeErrorMonitoring(ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS);\n },\n ]);\n throwCleanupErrors(cleanupErrors, 'Failed to stop API server');\n stopped = true;\n hasActiveServer = false;\n } finally {\n stopPromise = undefined;\n }\n })();\n return stopPromise;\n };\n\n return {start, stop};\n } catch (error) {\n const cleanupErrors = await runCleanupSteps([\n () => shutdownServiceMetrics(),\n () => closePostgresClient(),\n ]);\n for (const cleanupError of cleanupErrors) {\n logger().error({err: cleanupError, bootError: error}, 'Failed to clean up API server boot');\n }\n hasActiveServer = false;\n throw error;\n }\n}\n\nexport async function runServer(options: RunServerOptions): Promise<ServerHandle> {\n let handle: ServerHandle;\n try {\n handle = await createServer({\n modules: options.modules,\n onWorkerFailure: () => process.exit(1),\n onServiceFailure: () => process.exit(1),\n });\n } catch (error) {\n await reportStartupFailure(error, options.onStartupFailure);\n throw error;\n }\n\n try {\n await handle.start();\n } catch (error) {\n await reportStartupFailure(error, options.onStartupFailure);\n try {\n await handle.stop();\n } catch (cleanupError) {\n logger().error(\n {err: cleanupError, startError: error},\n 'Failed to clean up API server startup',\n );\n }\n throw error;\n }\n\n const stopAndExit = () => void handle.stop().finally(() => process.exit(0));\n process.once('SIGTERM', stopAndExit);\n process.once('SIGINT', stopAndExit);\n\n return handle;\n}\n\nasync function reportStartupFailure(\n error: unknown,\n onStartupFailure: RunServerOptions['onStartupFailure'],\n): Promise<void> {\n try {\n await onStartupFailure?.(error);\n } catch (reportingError) {\n logger().error(\n {err: reportingError, startError: error},\n 'Failed to report API server startup error',\n );\n }\n}\n\ntype CleanupStep = () => void | Promise<void>;\n\nasync function runCleanupSteps(steps: CleanupStep[]): Promise<unknown[]> {\n const cleanupErrors: unknown[] = [];\n for (const step of steps) {\n try {\n await step();\n } catch (error) {\n cleanupErrors.push(error);\n }\n }\n return cleanupErrors;\n}\n\nfunction throwCleanupErrors(cleanupErrors: unknown[], message: string): void {\n if (cleanupErrors.length === 0) return;\n if (cleanupErrors.length === 1) throw cleanupErrors[0];\n throw new AggregateError(cleanupErrors, message);\n}\n\nasync function handleModuleWorkerFailure(\n error: unknown,\n worker: ModuleWorker,\n onWorkerFailure: CreateServerOptions['onWorkerFailure'],\n): Promise<void> {\n await handleModuleRuntimeFailure({\n error,\n fields: {taskQueue: worker.taskQueue},\n message: 'Module worker stopped unexpectedly',\n onFailure: () => onWorkerFailure?.(error, worker),\n });\n}\n\nasync function handleModuleServiceFailure(\n error: unknown,\n service: ModuleService,\n onServiceFailure: CreateServerOptions['onServiceFailure'],\n): Promise<void> {\n await handleModuleRuntimeFailure({\n error,\n fields: {service: service.name},\n message: 'Module service stopped unexpectedly',\n onFailure: () => onServiceFailure?.(error, service),\n });\n}\n\nasync function handleModuleRuntimeFailure(options: {\n error: unknown;\n fields: Record<string, string>;\n message: string;\n onFailure(): void | Promise<void>;\n}): Promise<void> {\n logger().error({err: options.error, ...options.fields}, options.message);\n captureException(options.error);\n\n try {\n await closeHttpServerAfterRuntimeFailure();\n await closeErrorMonitoring(ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS);\n } finally {\n await options.onFailure();\n }\n}\n\nasync function closeHttpServerAfterRuntimeFailure(): Promise<void> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<'timeout'>((resolve) => {\n timeoutId = setTimeout(() => resolve('timeout'), RUNTIME_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS);\n });\n try {\n const result = await Promise.race([closeApp().then(() => 'closed' as const), timeout]).finally(\n () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n },\n );\n if (result === 'timeout') {\n logger().error(\n {timeoutMs: RUNTIME_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS},\n 'Timed out closing HTTP server after module runtime failure',\n );\n }\n } catch (error) {\n logger().error({err: error}, 'Failed to close HTTP server after module runtime failure');\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n}\n"],"names":["captureException","closeErrorMonitoring","closeApp","createApp","listen","aggregateLoginMethods","initializeModules","registerModuleMetrics","runModuleStartupTasks","startModuleServices","startModuleWorkers","logger","shutdownServiceMetrics","startServiceMetrics","closePostgresClient","createPostgresClient","config","parseApiTrustProxy","createE2eAdminAuthMethod","createE2eRouteGroup","RUNTIME_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS","ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS","hasActiveServer","createServer","options","Error","modules","serviceName","auth","routes","e2eRoutes","workers","services","outboxRegistry","context","e2eAuth","E2E_ENABLED","mountedE2eRoutes","info","fastifyOptions","trustProxy","API_TRUST_PROXY","workersHandle","servicesHandle","startPromise","stopPromise","stopped","start","Promise","reject","onWorkerFailure","error","worker","handleModuleWorkerFailure","onServiceFailure","service","handleModuleServiceFailure","address","API_PORT","undefined","port","stop","resolve","catch","cleanupErrors","runCleanupSteps","throwCleanupErrors","cleanupError","err","bootError","runServer","handle","process","exit","reportStartupFailure","onStartupFailure","startError","stopAndExit","finally","once","reportingError","steps","step","push","message","length","AggregateError","handleModuleRuntimeFailure","fields","taskQueue","onFailure","name","closeHttpServerAfterRuntimeFailure","timeoutId","timeout","setTimeout","result","race","then","clearTimeout","timeoutMs"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import {closeErrorMonitoring, markErrorReported, reportError} from '@shipfox/node-error-monitoring';\nimport {closeApp, createApp, listen} from '@shipfox/node-fastify';\nimport {\n aggregateLoginMethods,\n initializeModules,\n type ModuleService,\n type ModuleServicesHandle,\n type ModuleWorker,\n type ModuleWorkersHandle,\n registerModuleMetrics,\n runModuleStartupTasks,\n type ShipfoxModule,\n startModuleServices,\n startModuleWorkers,\n} from '@shipfox/node-module';\nimport {logger, shutdownServiceMetrics, startServiceMetrics} from '@shipfox/node-opentelemetry';\nimport {closePostgresClient, createPostgresClient} from '@shipfox/node-postgres';\nimport {config, parseApiTrustProxy} from './config.js';\nimport {createE2eAdminAuthMethod, createE2eRouteGroup} from './e2e.js';\nimport {createLoginMethodsRoute} from './routes/login-methods.js';\n\nconst RUNTIME_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS = 10_000;\nconst ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS = 2_000;\n\nlet hasActiveServer = false;\n\nexport interface CreateServerOptions {\n modules: ShipfoxModule[];\n onWorkerFailure?: (error: unknown, worker: ModuleWorker) => void | Promise<void>;\n onServiceFailure?: (error: unknown, service: ModuleService) => void | Promise<void>;\n}\n\nexport interface ServerHandle {\n start(): Promise<string>;\n stop(): Promise<void>;\n}\n\nexport interface RunServerOptions {\n modules: ShipfoxModule[];\n onStartupFailure?: (error: unknown) => void | Promise<void>;\n}\n\nexport async function createServer(options: CreateServerOptions): Promise<ServerHandle> {\n if (hasActiveServer) {\n throw new Error('Cannot create a second API server before the existing server stops');\n }\n hasActiveServer = true;\n\n try {\n const loginMethods = aggregateLoginMethods({modules: options.modules});\n startServiceMetrics({serviceName: 'api'});\n createPostgresClient();\n\n const {auth, routes, e2eRoutes, workers, services, outboxRegistry} = await initializeModules({\n modules: options.modules,\n });\n registerModuleMetrics({modules: options.modules, context: {outboxRegistry}});\n await runModuleStartupTasks({modules: options.modules, context: {outboxRegistry}});\n\n const e2eAuth = config.E2E_ENABLED ? [createE2eAdminAuthMethod(config)] : [];\n const mountedE2eRoutes = createE2eRouteGroup(e2eRoutes, config);\n\n logger().info('Creating HTTP server');\n await createApp({\n auth: [...auth, ...e2eAuth],\n routes: [createLoginMethodsRoute({loginMethods}), ...routes, ...mountedE2eRoutes],\n fastifyOptions: {trustProxy: parseApiTrustProxy(config.API_TRUST_PROXY)},\n });\n\n let workersHandle: ModuleWorkersHandle | undefined;\n let servicesHandle: ModuleServicesHandle | undefined;\n let startPromise: Promise<string> | undefined;\n let stopPromise: Promise<void> | undefined;\n let stopped = false;\n\n const start = (): Promise<string> => {\n if (stopPromise || stopped)\n return Promise.reject(new Error('Cannot start a stopped API server'));\n\n startPromise ??= (async () => {\n logger().info('Starting module workers');\n workersHandle = await startModuleWorkers({\n workers,\n context: {outboxRegistry},\n onWorkerFailure: (error, worker) =>\n handleModuleWorkerFailure(error, worker, options.onWorkerFailure),\n });\n\n logger().info('Starting module services');\n servicesHandle = await startModuleServices({\n services,\n context: {outboxRegistry},\n onServiceFailure: (error, service) =>\n handleModuleServiceFailure(error, service, options.onServiceFailure),\n });\n\n if (stopPromise) throw new Error('API server stopped during startup');\n\n logger().info('Starting HTTP server');\n const address =\n config.API_PORT === undefined ? await listen() : await listen({port: config.API_PORT});\n logger().info({address}, 'HTTP server listening');\n return address;\n })();\n return startPromise;\n };\n\n const stop = (): Promise<void> => {\n if (stopped) return Promise.resolve();\n\n stopPromise ??= (async () => {\n try {\n await startPromise?.catch(() => undefined);\n const cleanupErrors = await runCleanupSteps([\n () => closeApp(),\n () => servicesHandle?.stop(),\n () => workersHandle?.stop(),\n () => shutdownServiceMetrics(),\n () => closePostgresClient(),\n ]);\n for (const cleanupError of cleanupErrors) {\n logger().error({err: cleanupError}, 'Failed to clean up API server during shutdown');\n reportError(cleanupError, {boundary: 'api.shutdown', operation: 'cleanup'});\n }\n try {\n const errorMonitoringClosed = await closeErrorMonitoring(\n ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS,\n );\n if (!errorMonitoringClosed) {\n logger().error('Timed out closing error monitoring during API shutdown');\n cleanupErrors.push(\n new Error('Timed out closing error monitoring during API shutdown'),\n );\n }\n } catch (error) {\n cleanupErrors.push(error);\n }\n throwCleanupErrors(cleanupErrors, 'Failed to stop API server');\n stopped = true;\n hasActiveServer = false;\n } finally {\n stopPromise = undefined;\n }\n })();\n return stopPromise;\n };\n\n return {start, stop};\n } catch (error) {\n const cleanupErrors = await runCleanupSteps([\n () => shutdownServiceMetrics(),\n () => closePostgresClient(),\n ]);\n for (const cleanupError of cleanupErrors) {\n logger().error({err: cleanupError, bootError: error}, 'Failed to clean up API server boot');\n reportError(cleanupError, {boundary: 'api.startup', operation: 'cleanup'});\n }\n hasActiveServer = false;\n throw error;\n }\n}\n\nexport async function runServer(options: RunServerOptions): Promise<ServerHandle> {\n let handle: ServerHandle;\n try {\n handle = await createServer({\n modules: options.modules,\n onWorkerFailure: () => process.exit(1),\n onServiceFailure: () => process.exit(1),\n });\n } catch (error) {\n await reportStartupFailure(error, options.onStartupFailure);\n throw error;\n }\n\n try {\n await handle.start();\n } catch (error) {\n await reportStartupFailure(error, options.onStartupFailure);\n try {\n await handle.stop();\n } catch (cleanupError) {\n logger().error(\n {err: cleanupError, startError: error},\n 'Failed to clean up API server startup',\n );\n reportError(cleanupError, {\n boundary: 'api.startup',\n operation: 'cleanup-after-failed-start',\n });\n }\n throw error;\n }\n\n const stopAndExit = () =>\n void handle.stop().then(\n () => process.exit(0),\n (error) => {\n logger().error({err: error}, 'Failed to stop API server after shutdown signal');\n reportError(error, {boundary: 'api.shutdown', operation: 'signal-stop'});\n process.exit(1);\n },\n );\n process.once('SIGTERM', stopAndExit);\n process.once('SIGINT', stopAndExit);\n\n return handle;\n}\n\nasync function reportStartupFailure(\n error: unknown,\n onStartupFailure: RunServerOptions['onStartupFailure'],\n): Promise<void> {\n try {\n await onStartupFailure?.(error);\n } catch (reportingError) {\n logger().error(\n {err: reportingError, startError: error},\n 'Failed to report API server startup error',\n );\n }\n}\n\ntype CleanupStep = () => void | Promise<void>;\n\nasync function runCleanupSteps(steps: CleanupStep[]): Promise<unknown[]> {\n const cleanupErrors: unknown[] = [];\n for (const step of steps) {\n try {\n await step();\n } catch (error) {\n cleanupErrors.push(error);\n }\n }\n return cleanupErrors;\n}\n\nfunction throwCleanupErrors(cleanupErrors: unknown[], message: string): void {\n if (cleanupErrors.length === 0) return;\n if (cleanupErrors.length === 1) throw cleanupErrors[0];\n const aggregate = new AggregateError(cleanupErrors, message);\n markErrorReported(aggregate);\n throw aggregate;\n}\n\nasync function handleModuleWorkerFailure(\n error: unknown,\n worker: ModuleWorker,\n onWorkerFailure: CreateServerOptions['onWorkerFailure'],\n): Promise<void> {\n await handleModuleRuntimeFailure({\n error,\n fields: {taskQueue: worker.taskQueue},\n message: 'Module worker stopped unexpectedly',\n onFailure: () => onWorkerFailure?.(error, worker),\n });\n}\n\nasync function handleModuleServiceFailure(\n error: unknown,\n service: ModuleService,\n onServiceFailure: CreateServerOptions['onServiceFailure'],\n): Promise<void> {\n await handleModuleRuntimeFailure({\n error,\n fields: {service: service.name},\n message: 'Module service stopped unexpectedly',\n onFailure: () => onServiceFailure?.(error, service),\n });\n}\n\nasync function handleModuleRuntimeFailure(options: {\n error: unknown;\n fields: Record<string, string>;\n message: string;\n onFailure(): void | Promise<void>;\n}): Promise<void> {\n logger().error({err: options.error, ...options.fields}, options.message);\n reportError(options.error, {\n boundary: 'api.runtime',\n tags: options.fields,\n });\n\n try {\n await closeHttpServerAfterRuntimeFailure();\n const errorMonitoringClosed = await closeErrorMonitoring(ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS);\n if (!errorMonitoringClosed) {\n logger().error('Timed out closing error monitoring after module runtime failure');\n }\n } catch (error) {\n logger().error({err: error}, 'Failed to close error monitoring after module runtime failure');\n } finally {\n await options.onFailure();\n }\n}\n\nasync function closeHttpServerAfterRuntimeFailure(): Promise<void> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<'timeout'>((resolve) => {\n timeoutId = setTimeout(() => resolve('timeout'), RUNTIME_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS);\n });\n try {\n const result = await Promise.race([closeApp().then(() => 'closed' as const), timeout]).finally(\n () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n },\n );\n if (result === 'timeout') {\n const error = new Error('Timed out closing HTTP server after module runtime failure');\n logger().error({timeoutMs: RUNTIME_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS}, error.message);\n reportError(error, {boundary: 'api.runtime', operation: 'close-http-timeout'});\n }\n } catch (error) {\n logger().error({err: error}, 'Failed to close HTTP server after module runtime failure');\n reportError(error, {boundary: 'api.runtime', operation: 'close-http'});\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n}\n"],"names":["closeErrorMonitoring","markErrorReported","reportError","closeApp","createApp","listen","aggregateLoginMethods","initializeModules","registerModuleMetrics","runModuleStartupTasks","startModuleServices","startModuleWorkers","logger","shutdownServiceMetrics","startServiceMetrics","closePostgresClient","createPostgresClient","config","parseApiTrustProxy","createE2eAdminAuthMethod","createE2eRouteGroup","createLoginMethodsRoute","RUNTIME_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS","ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS","hasActiveServer","createServer","options","Error","loginMethods","modules","serviceName","auth","routes","e2eRoutes","workers","services","outboxRegistry","context","e2eAuth","E2E_ENABLED","mountedE2eRoutes","info","fastifyOptions","trustProxy","API_TRUST_PROXY","workersHandle","servicesHandle","startPromise","stopPromise","stopped","start","Promise","reject","onWorkerFailure","error","worker","handleModuleWorkerFailure","onServiceFailure","service","handleModuleServiceFailure","address","API_PORT","undefined","port","stop","resolve","catch","cleanupErrors","runCleanupSteps","cleanupError","err","boundary","operation","errorMonitoringClosed","push","throwCleanupErrors","bootError","runServer","handle","process","exit","reportStartupFailure","onStartupFailure","startError","stopAndExit","then","once","reportingError","steps","step","message","length","aggregate","AggregateError","handleModuleRuntimeFailure","fields","taskQueue","onFailure","name","tags","closeHttpServerAfterRuntimeFailure","timeoutId","timeout","setTimeout","result","race","finally","clearTimeout","timeoutMs"],"mappings":"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"}