@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.
@@ -1,2 +1,2 @@
1
1
  $ shipfox-swc
2
- Successfully compiled: 6 files with swc (77.53ms)
2
+ Successfully compiled: 6 files with swc (57.66ms)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
1
1
  # @shipfox/api-server
2
2
 
3
+ ## 4.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [5d129d6]
8
+ - Updated dependencies [67176d4]
9
+ - Updated dependencies [0b0a9c2]
10
+ - Updated dependencies [bbba3b7]
11
+ - Updated dependencies [1951293]
12
+ - @shipfox/api-integration-core@4.0.0
13
+ - @shipfox/api-auth@4.0.0
14
+ - @shipfox/api-definitions@4.0.0
15
+ - @shipfox/api-projects@4.0.0
16
+ - @shipfox/api-workflows@4.0.0
17
+ - @shipfox/annotations@4.0.0
18
+ - @shipfox/api-logs@4.0.0
19
+ - @shipfox/api-runners@4.0.0
20
+ - @shipfox/api-agent@4.0.0
21
+ - @shipfox/api-secrets@4.0.0
22
+ - @shipfox/api-triggers@4.0.0
23
+ - @shipfox/api-workspaces@4.0.0
24
+ - @shipfox/node-module@0.3.1
25
+ - @shipfox/api-dispatcher@4.0.0
26
+
27
+ ## 3.0.0
28
+
29
+ ### Minor Changes
30
+
31
+ - 3976f8c: Adds module login-method declarations, validates server compositions before startup, and adds password-login route configuration.
32
+
33
+ ### Patch Changes
34
+
35
+ - Updated dependencies [3976f8c]
36
+ - Updated dependencies [7a71e7d]
37
+ - Updated dependencies [08fc93b]
38
+ - @shipfox/node-module@0.3.0
39
+ - @shipfox/api-auth@3.0.0
40
+ - @shipfox/api-agent@3.0.0
41
+ - @shipfox/api-definitions@3.0.0
42
+ - @shipfox/api-dispatcher@3.0.0
43
+ - @shipfox/api-integration-core@3.0.0
44
+ - @shipfox/api-logs@3.0.0
45
+ - @shipfox/api-projects@3.0.0
46
+ - @shipfox/api-runners@3.0.0
47
+ - @shipfox/api-triggers@3.0.0
48
+ - @shipfox/api-workflows@3.0.0
49
+ - @shipfox/node-opentelemetry@0.5.1
50
+ - @shipfox/annotations@3.0.0
51
+ - @shipfox/api-secrets@3.0.0
52
+ - @shipfox/api-workspaces@3.0.0
53
+ - @shipfox/node-fastify@0.2.2
54
+
3
55
  ## 2.0.0
4
56
 
5
57
  ### Minor Changes
package/README.md CHANGED
@@ -40,7 +40,7 @@ node --import @shipfox/api-server/instrumentation ./dist/index.js
40
40
 
41
41
  ## Behavior Notes
42
42
 
43
- - **Custom composition**: Pass a module list to make a custom server.
43
+ - **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.
44
44
  - **Signal handling**: `createServer` does not install signal handlers.
45
45
  - **Lifecycle**: `start` starts workers before the HTTP listener. `stop` is safe to call again.
46
46
  - **Process scope**: Run one server at a time.
@@ -1 +1 @@
1
- {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AAExD,wBAAsB,cAAc,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CA+D/D"}
1
+ {"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AAExD,wBAAsB,cAAc,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAgF/D"}
package/dist/modules.js CHANGED
@@ -28,6 +28,20 @@ export async function defaultModules() {
28
28
  ...params,
29
29
  namespace: `system/integrations/linear/${params.namespace}`
30
30
  })
31
+ },
32
+ slack: {
33
+ getSecret: (params)=>getSecret({
34
+ ...params,
35
+ namespace: `system/integrations/slack/${params.namespace}`
36
+ }),
37
+ setSecrets: (params)=>setSecrets({
38
+ ...params,
39
+ namespace: `system/integrations/slack/${params.namespace}`
40
+ }),
41
+ deleteSecrets: (params)=>deleteSecrets({
42
+ ...params,
43
+ namespace: `system/integrations/slack/${params.namespace}`
44
+ })
31
45
  }
32
46
  },
33
47
  agentTools: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/modules.ts"],"sourcesContent":["import {annotationsModule} from '@shipfox/annotations';\nimport {agentModule} from '@shipfox/api-agent';\nimport {authModule} from '@shipfox/api-auth';\nimport {createDefinitionsModule} from '@shipfox/api-definitions';\nimport {dispatcherModule} from '@shipfox/api-dispatcher';\nimport {\n buildAgentToolCatalogs,\n buildAgentToolSelectionCatalogs,\n createIntegrationsContext,\n createWorkspaceConnectionSnapshotLoader,\n getIntegrationConnectionById,\n} from '@shipfox/api-integration-core';\nimport {logsModule} from '@shipfox/api-logs';\nimport {createProjectsModule} from '@shipfox/api-projects';\nimport {runnersModule} from '@shipfox/api-runners';\nimport {deleteSecrets, getSecret, secretsModule, setSecrets} from '@shipfox/api-secrets';\nimport {triggersModule} from '@shipfox/api-triggers';\nimport {\n loadRunningLeasedStep,\n setAgentToolMaterializationServices,\n setSourceControl,\n workflowsModule,\n} from '@shipfox/api-workflows';\nimport {workspacesModule} from '@shipfox/api-workspaces';\nimport type {ShipfoxModule} from '@shipfox/node-module';\n\nexport async function defaultModules(): Promise<ShipfoxModule[]> {\n const integrations = await createIntegrationsContext({\n secrets: {\n deleteSecrets,\n linear: {\n getSecret: (params) =>\n getSecret({\n ...params,\n namespace: `system/integrations/linear/${params.namespace}`,\n }),\n setSecrets: (params) =>\n setSecrets({\n ...params,\n namespace: `system/integrations/linear/${params.namespace}`,\n }),\n deleteSecrets: (params) =>\n deleteSecrets({\n ...params,\n namespace: `system/integrations/linear/${params.namespace}`,\n }),\n },\n },\n agentTools: {loadLeasedAgentStep: loadRunningLeasedStep},\n });\n const [agentToolSelectionCatalogs, agentToolCatalogs] = await Promise.all([\n buildAgentToolSelectionCatalogs(integrations.registry),\n buildAgentToolCatalogs(integrations.registry),\n ]);\n const loadWorkspaceConnectionSnapshot = createWorkspaceConnectionSnapshotLoader(\n integrations.registry,\n );\n\n // The checkout-token route resolves intents and mints credentials through the\n // source-control service; wire it into the workflows module before serving.\n setSourceControl(integrations.sourceControl);\n setAgentToolMaterializationServices({\n catalogs: agentToolCatalogs,\n loadWorkspaceConnectionSnapshot,\n getIntegrationConnectionById,\n });\n const projectsModule = createProjectsModule({sourceControl: integrations.sourceControl});\n const definitionsModule = createDefinitionsModule({\n sourceControl: integrations.sourceControl,\n agentToolSelectionCatalogs,\n loadWorkspaceConnectionSnapshot,\n getIntegrationConnectionById,\n });\n\n return [\n authModule,\n workspacesModule,\n secretsModule,\n agentModule,\n integrations.module,\n projectsModule,\n definitionsModule,\n workflowsModule,\n annotationsModule,\n runnersModule,\n logsModule,\n triggersModule,\n dispatcherModule,\n ];\n}\n"],"names":["annotationsModule","agentModule","authModule","createDefinitionsModule","dispatcherModule","buildAgentToolCatalogs","buildAgentToolSelectionCatalogs","createIntegrationsContext","createWorkspaceConnectionSnapshotLoader","getIntegrationConnectionById","logsModule","createProjectsModule","runnersModule","deleteSecrets","getSecret","secretsModule","setSecrets","triggersModule","loadRunningLeasedStep","setAgentToolMaterializationServices","setSourceControl","workflowsModule","workspacesModule","defaultModules","integrations","secrets","linear","params","namespace","agentTools","loadLeasedAgentStep","agentToolSelectionCatalogs","agentToolCatalogs","Promise","all","registry","loadWorkspaceConnectionSnapshot","sourceControl","catalogs","projectsModule","definitionsModule","module"],"mappings":"AAAA,SAAQA,iBAAiB,QAAO,uBAAuB;AACvD,SAAQC,WAAW,QAAO,qBAAqB;AAC/C,SAAQC,UAAU,QAAO,oBAAoB;AAC7C,SAAQC,uBAAuB,QAAO,2BAA2B;AACjE,SAAQC,gBAAgB,QAAO,0BAA0B;AACzD,SACEC,sBAAsB,EACtBC,+BAA+B,EAC/BC,yBAAyB,EACzBC,uCAAuC,EACvCC,4BAA4B,QACvB,gCAAgC;AACvC,SAAQC,UAAU,QAAO,oBAAoB;AAC7C,SAAQC,oBAAoB,QAAO,wBAAwB;AAC3D,SAAQC,aAAa,QAAO,uBAAuB;AACnD,SAAQC,aAAa,EAAEC,SAAS,EAAEC,aAAa,EAAEC,UAAU,QAAO,uBAAuB;AACzF,SAAQC,cAAc,QAAO,wBAAwB;AACrD,SACEC,qBAAqB,EACrBC,mCAAmC,EACnCC,gBAAgB,EAChBC,eAAe,QACV,yBAAyB;AAChC,SAAQC,gBAAgB,QAAO,0BAA0B;AAGzD,OAAO,eAAeC;IACpB,MAAMC,eAAe,MAAMjB,0BAA0B;QACnDkB,SAAS;YACPZ;YACAa,QAAQ;gBACNZ,WAAW,CAACa,SACVb,UAAU;wBACR,GAAGa,MAAM;wBACTC,WAAW,CAAC,2BAA2B,EAAED,OAAOC,SAAS,EAAE;oBAC7D;gBACFZ,YAAY,CAACW,SACXX,WAAW;wBACT,GAAGW,MAAM;wBACTC,WAAW,CAAC,2BAA2B,EAAED,OAAOC,SAAS,EAAE;oBAC7D;gBACFf,eAAe,CAACc,SACdd,cAAc;wBACZ,GAAGc,MAAM;wBACTC,WAAW,CAAC,2BAA2B,EAAED,OAAOC,SAAS,EAAE;oBAC7D;YACJ;QACF;QACAC,YAAY;YAACC,qBAAqBZ;QAAqB;IACzD;IACA,MAAM,CAACa,4BAA4BC,kBAAkB,GAAG,MAAMC,QAAQC,GAAG,CAAC;QACxE5B,gCAAgCkB,aAAaW,QAAQ;QACrD9B,uBAAuBmB,aAAaW,QAAQ;KAC7C;IACD,MAAMC,kCAAkC5B,wCACtCgB,aAAaW,QAAQ;IAGvB,8EAA8E;IAC9E,4EAA4E;IAC5Ef,iBAAiBI,aAAaa,aAAa;IAC3ClB,oCAAoC;QAClCmB,UAAUN;QACVI;QACA3B;IACF;IACA,MAAM8B,iBAAiB5B,qBAAqB;QAAC0B,eAAeb,aAAaa,aAAa;IAAA;IACtF,MAAMG,oBAAoBrC,wBAAwB;QAChDkC,eAAeb,aAAaa,aAAa;QACzCN;QACAK;QACA3B;IACF;IAEA,OAAO;QACLP;QACAoB;QACAP;QACAd;QACAuB,aAAaiB,MAAM;QACnBF;QACAC;QACAnB;QACArB;QACAY;QACAF;QACAO;QACAb;KACD;AACH"}
1
+ {"version":3,"sources":["../src/modules.ts"],"sourcesContent":["import {annotationsModule} from '@shipfox/annotations';\nimport {agentModule} from '@shipfox/api-agent';\nimport {authModule} from '@shipfox/api-auth';\nimport {createDefinitionsModule} from '@shipfox/api-definitions';\nimport {dispatcherModule} from '@shipfox/api-dispatcher';\nimport {\n buildAgentToolCatalogs,\n buildAgentToolSelectionCatalogs,\n createIntegrationsContext,\n createWorkspaceConnectionSnapshotLoader,\n getIntegrationConnectionById,\n} from '@shipfox/api-integration-core';\nimport {logsModule} from '@shipfox/api-logs';\nimport {createProjectsModule} from '@shipfox/api-projects';\nimport {runnersModule} from '@shipfox/api-runners';\nimport {deleteSecrets, getSecret, secretsModule, setSecrets} from '@shipfox/api-secrets';\nimport {triggersModule} from '@shipfox/api-triggers';\nimport {\n loadRunningLeasedStep,\n setAgentToolMaterializationServices,\n setSourceControl,\n workflowsModule,\n} from '@shipfox/api-workflows';\nimport {workspacesModule} from '@shipfox/api-workspaces';\nimport type {ShipfoxModule} from '@shipfox/node-module';\n\nexport async function defaultModules(): Promise<ShipfoxModule[]> {\n const integrations = await createIntegrationsContext({\n secrets: {\n deleteSecrets,\n linear: {\n getSecret: (params) =>\n getSecret({\n ...params,\n namespace: `system/integrations/linear/${params.namespace}`,\n }),\n setSecrets: (params) =>\n setSecrets({\n ...params,\n namespace: `system/integrations/linear/${params.namespace}`,\n }),\n deleteSecrets: (params) =>\n deleteSecrets({\n ...params,\n namespace: `system/integrations/linear/${params.namespace}`,\n }),\n },\n slack: {\n getSecret: (params) =>\n getSecret({\n ...params,\n namespace: `system/integrations/slack/${params.namespace}`,\n }),\n setSecrets: (params) =>\n setSecrets({\n ...params,\n namespace: `system/integrations/slack/${params.namespace}`,\n }),\n deleteSecrets: (params) =>\n deleteSecrets({\n ...params,\n namespace: `system/integrations/slack/${params.namespace}`,\n }),\n },\n },\n agentTools: {loadLeasedAgentStep: loadRunningLeasedStep},\n });\n const [agentToolSelectionCatalogs, agentToolCatalogs] = await Promise.all([\n buildAgentToolSelectionCatalogs(integrations.registry),\n buildAgentToolCatalogs(integrations.registry),\n ]);\n const loadWorkspaceConnectionSnapshot = createWorkspaceConnectionSnapshotLoader(\n integrations.registry,\n );\n\n // The checkout-token route resolves intents and mints credentials through the\n // source-control service; wire it into the workflows module before serving.\n setSourceControl(integrations.sourceControl);\n setAgentToolMaterializationServices({\n catalogs: agentToolCatalogs,\n loadWorkspaceConnectionSnapshot,\n getIntegrationConnectionById,\n });\n const projectsModule = createProjectsModule({sourceControl: integrations.sourceControl});\n const definitionsModule = createDefinitionsModule({\n sourceControl: integrations.sourceControl,\n agentToolSelectionCatalogs,\n loadWorkspaceConnectionSnapshot,\n getIntegrationConnectionById,\n });\n\n return [\n authModule,\n workspacesModule,\n secretsModule,\n agentModule,\n integrations.module,\n projectsModule,\n definitionsModule,\n workflowsModule,\n annotationsModule,\n runnersModule,\n logsModule,\n triggersModule,\n dispatcherModule,\n ];\n}\n"],"names":["annotationsModule","agentModule","authModule","createDefinitionsModule","dispatcherModule","buildAgentToolCatalogs","buildAgentToolSelectionCatalogs","createIntegrationsContext","createWorkspaceConnectionSnapshotLoader","getIntegrationConnectionById","logsModule","createProjectsModule","runnersModule","deleteSecrets","getSecret","secretsModule","setSecrets","triggersModule","loadRunningLeasedStep","setAgentToolMaterializationServices","setSourceControl","workflowsModule","workspacesModule","defaultModules","integrations","secrets","linear","params","namespace","slack","agentTools","loadLeasedAgentStep","agentToolSelectionCatalogs","agentToolCatalogs","Promise","all","registry","loadWorkspaceConnectionSnapshot","sourceControl","catalogs","projectsModule","definitionsModule","module"],"mappings":"AAAA,SAAQA,iBAAiB,QAAO,uBAAuB;AACvD,SAAQC,WAAW,QAAO,qBAAqB;AAC/C,SAAQC,UAAU,QAAO,oBAAoB;AAC7C,SAAQC,uBAAuB,QAAO,2BAA2B;AACjE,SAAQC,gBAAgB,QAAO,0BAA0B;AACzD,SACEC,sBAAsB,EACtBC,+BAA+B,EAC/BC,yBAAyB,EACzBC,uCAAuC,EACvCC,4BAA4B,QACvB,gCAAgC;AACvC,SAAQC,UAAU,QAAO,oBAAoB;AAC7C,SAAQC,oBAAoB,QAAO,wBAAwB;AAC3D,SAAQC,aAAa,QAAO,uBAAuB;AACnD,SAAQC,aAAa,EAAEC,SAAS,EAAEC,aAAa,EAAEC,UAAU,QAAO,uBAAuB;AACzF,SAAQC,cAAc,QAAO,wBAAwB;AACrD,SACEC,qBAAqB,EACrBC,mCAAmC,EACnCC,gBAAgB,EAChBC,eAAe,QACV,yBAAyB;AAChC,SAAQC,gBAAgB,QAAO,0BAA0B;AAGzD,OAAO,eAAeC;IACpB,MAAMC,eAAe,MAAMjB,0BAA0B;QACnDkB,SAAS;YACPZ;YACAa,QAAQ;gBACNZ,WAAW,CAACa,SACVb,UAAU;wBACR,GAAGa,MAAM;wBACTC,WAAW,CAAC,2BAA2B,EAAED,OAAOC,SAAS,EAAE;oBAC7D;gBACFZ,YAAY,CAACW,SACXX,WAAW;wBACT,GAAGW,MAAM;wBACTC,WAAW,CAAC,2BAA2B,EAAED,OAAOC,SAAS,EAAE;oBAC7D;gBACFf,eAAe,CAACc,SACdd,cAAc;wBACZ,GAAGc,MAAM;wBACTC,WAAW,CAAC,2BAA2B,EAAED,OAAOC,SAAS,EAAE;oBAC7D;YACJ;YACAC,OAAO;gBACLf,WAAW,CAACa,SACVb,UAAU;wBACR,GAAGa,MAAM;wBACTC,WAAW,CAAC,0BAA0B,EAAED,OAAOC,SAAS,EAAE;oBAC5D;gBACFZ,YAAY,CAACW,SACXX,WAAW;wBACT,GAAGW,MAAM;wBACTC,WAAW,CAAC,0BAA0B,EAAED,OAAOC,SAAS,EAAE;oBAC5D;gBACFf,eAAe,CAACc,SACdd,cAAc;wBACZ,GAAGc,MAAM;wBACTC,WAAW,CAAC,0BAA0B,EAAED,OAAOC,SAAS,EAAE;oBAC5D;YACJ;QACF;QACAE,YAAY;YAACC,qBAAqBb;QAAqB;IACzD;IACA,MAAM,CAACc,4BAA4BC,kBAAkB,GAAG,MAAMC,QAAQC,GAAG,CAAC;QACxE7B,gCAAgCkB,aAAaY,QAAQ;QACrD/B,uBAAuBmB,aAAaY,QAAQ;KAC7C;IACD,MAAMC,kCAAkC7B,wCACtCgB,aAAaY,QAAQ;IAGvB,8EAA8E;IAC9E,4EAA4E;IAC5EhB,iBAAiBI,aAAac,aAAa;IAC3CnB,oCAAoC;QAClCoB,UAAUN;QACVI;QACA5B;IACF;IACA,MAAM+B,iBAAiB7B,qBAAqB;QAAC2B,eAAed,aAAac,aAAa;IAAA;IACtF,MAAMG,oBAAoBtC,wBAAwB;QAChDmC,eAAed,aAAac,aAAa;QACzCN;QACAK;QACA5B;IACF;IAEA,OAAO;QACLP;QACAoB;QACAP;QACAd;QACAuB,aAAakB,MAAM;QACnBF;QACAC;QACApB;QACArB;QACAY;QACAF;QACAO;QACAb;KACD;AACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,YAAY,EAMjB,KAAK,aAAa,EAEnB,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;CAClF;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,CA2FtF;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAgChF"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,YAAY,EAMjB,KAAK,aAAa,EAEnB,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;CAClF;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,CA4FtF;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAgChF"}
package/dist/server.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { captureException, closeErrorMonitoring } from '@shipfox/node-error-monitoring';
2
2
  import { closeApp, createApp, listen } from '@shipfox/node-fastify';
3
- import { initializeModules, registerModuleMetrics, resetPublishers, resetSubscribers, runModuleStartupTasks, startModuleWorkers } from '@shipfox/node-module';
3
+ import { aggregateLoginMethods, initializeModules, registerModuleMetrics, resetPublishers, resetSubscribers, runModuleStartupTasks, 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';
@@ -14,6 +14,9 @@ export async function createServer(options) {
14
14
  }
15
15
  hasActiveServer = true;
16
16
  try {
17
+ aggregateLoginMethods({
18
+ modules: options.modules
19
+ });
17
20
  startServiceMetrics({
18
21
  serviceName: 'api'
19
22
  });
@@ -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 initializeModules,\n type ModuleWorker,\n type ModuleWorkersHandle,\n registerModuleMetrics,\n resetPublishers,\n resetSubscribers,\n runModuleStartupTasks,\n type ShipfoxModule,\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 WORKER_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}\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 startServiceMetrics({serviceName: 'api'});\n createPostgresClient();\n\n const {auth, routes, e2eRoutes, workers} = await initializeModules({modules: options.modules});\n registerModuleMetrics({modules: options.modules});\n await runModuleStartupTasks({modules: options.modules});\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 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 onWorkerFailure: (error, worker) =>\n handleModuleWorkerFailure(error, worker, options.onWorkerFailure),\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 () => workersHandle?.stop(),\n () => shutdownServiceMetrics(),\n () => closePostgresClient(),\n () => resetPublishers(),\n () => resetSubscribers(),\n () => closeErrorMonitoring(ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS),\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 () => resetPublishers(),\n () => resetSubscribers(),\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 });\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 logger().error({err: error, taskQueue: worker.taskQueue}, 'Module worker stopped unexpectedly');\n captureException(error);\n\n try {\n await closeHttpServerAfterWorkerFailure();\n await closeErrorMonitoring(ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS);\n } finally {\n await onWorkerFailure?.(error, worker);\n }\n}\n\nasync function closeHttpServerAfterWorkerFailure(): Promise<void> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<'timeout'>((resolve) => {\n timeoutId = setTimeout(() => resolve('timeout'), WORKER_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: WORKER_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS},\n 'Timed out closing HTTP server after worker failure',\n );\n }\n } catch (error) {\n logger().error({err: error}, 'Failed to close HTTP server after worker failure');\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n}\n"],"names":["captureException","closeErrorMonitoring","closeApp","createApp","listen","initializeModules","registerModuleMetrics","resetPublishers","resetSubscribers","runModuleStartupTasks","startModuleWorkers","logger","shutdownServiceMetrics","startServiceMetrics","closePostgresClient","createPostgresClient","config","parseApiTrustProxy","createE2eAdminAuthMethod","createE2eRouteGroup","WORKER_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS","ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS","hasActiveServer","createServer","options","Error","serviceName","auth","routes","e2eRoutes","workers","modules","e2eAuth","E2E_ENABLED","mountedE2eRoutes","info","fastifyOptions","trustProxy","API_TRUST_PROXY","workersHandle","startPromise","stopPromise","stopped","start","Promise","reject","onWorkerFailure","error","worker","handleModuleWorkerFailure","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","taskQueue","closeHttpServerAfterWorkerFailure","timeoutId","timeout","setTimeout","result","race","then","clearTimeout","timeoutMs"],"mappings":"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"}
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 ModuleWorker,\n type ModuleWorkersHandle,\n registerModuleMetrics,\n resetPublishers,\n resetSubscribers,\n runModuleStartupTasks,\n type ShipfoxModule,\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 WORKER_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}\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} = await initializeModules({modules: options.modules});\n registerModuleMetrics({modules: options.modules});\n await runModuleStartupTasks({modules: options.modules});\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 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 onWorkerFailure: (error, worker) =>\n handleModuleWorkerFailure(error, worker, options.onWorkerFailure),\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 () => workersHandle?.stop(),\n () => shutdownServiceMetrics(),\n () => closePostgresClient(),\n () => resetPublishers(),\n () => resetSubscribers(),\n () => closeErrorMonitoring(ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS),\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 () => resetPublishers(),\n () => resetSubscribers(),\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 });\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 logger().error({err: error, taskQueue: worker.taskQueue}, 'Module worker stopped unexpectedly');\n captureException(error);\n\n try {\n await closeHttpServerAfterWorkerFailure();\n await closeErrorMonitoring(ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS);\n } finally {\n await onWorkerFailure?.(error, worker);\n }\n}\n\nasync function closeHttpServerAfterWorkerFailure(): Promise<void> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<'timeout'>((resolve) => {\n timeoutId = setTimeout(() => resolve('timeout'), WORKER_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: WORKER_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS},\n 'Timed out closing HTTP server after worker failure',\n );\n }\n } catch (error) {\n logger().error({err: error}, 'Failed to close HTTP server after worker failure');\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n}\n"],"names":["captureException","closeErrorMonitoring","closeApp","createApp","listen","aggregateLoginMethods","initializeModules","registerModuleMetrics","resetPublishers","resetSubscribers","runModuleStartupTasks","startModuleWorkers","logger","shutdownServiceMetrics","startServiceMetrics","closePostgresClient","createPostgresClient","config","parseApiTrustProxy","createE2eAdminAuthMethod","createE2eRouteGroup","WORKER_FAILURE_HTTP_SHUTDOWN_TIMEOUT_MS","ERROR_MONITORING_SHUTDOWN_TIMEOUT_MS","hasActiveServer","createServer","options","Error","modules","serviceName","auth","routes","e2eRoutes","workers","e2eAuth","E2E_ENABLED","mountedE2eRoutes","info","fastifyOptions","trustProxy","API_TRUST_PROXY","workersHandle","startPromise","stopPromise","stopped","start","Promise","reject","onWorkerFailure","error","worker","handleModuleWorkerFailure","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","taskQueue","closeHttpServerAfterWorkerFailure","timeoutId","timeout","setTimeout","result","race","then","clearTimeout","timeoutMs"],"mappings":"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"}