@powerhousedao/switchboard 6.1.0-dev.9 → 6.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.
Files changed (36) hide show
  1. package/.tsbuild/test/attachments/auth.test.d.ts +2 -0
  2. package/.tsbuild/test/attachments/auth.test.d.ts.map +1 -0
  3. package/.tsbuild/test/attachments/index.test.d.ts +2 -0
  4. package/.tsbuild/test/attachments/index.test.d.ts.map +1 -0
  5. package/.tsbuild/test/attachments/routes-integration.test.d.ts +2 -0
  6. package/.tsbuild/test/attachments/routes-integration.test.d.ts.map +1 -0
  7. package/.tsbuild/test/attachments/routes.test.d.ts +2 -0
  8. package/.tsbuild/test/attachments/routes.test.d.ts.map +1 -0
  9. package/.tsbuild/test/attachments/service-config.test.d.ts +2 -0
  10. package/.tsbuild/test/attachments/service-config.test.d.ts.map +1 -0
  11. package/.tsbuild/test/metrics.test.d.ts +2 -0
  12. package/.tsbuild/test/metrics.test.d.ts.map +1 -0
  13. package/.tsbuild/test/pglite-dialect.test.d.ts +2 -0
  14. package/.tsbuild/test/pglite-dialect.test.d.ts.map +1 -0
  15. package/.tsbuild/test/pglite-version.test.d.ts +2 -0
  16. package/.tsbuild/test/pglite-version.test.d.ts.map +1 -0
  17. package/.tsbuild/tsconfig.tsbuildinfo +1 -0
  18. package/.tsbuild/tsdown.config.d.ts +3 -0
  19. package/.tsbuild/tsdown.config.d.ts.map +1 -0
  20. package/.tsbuild/vitest.config.d.ts +3 -0
  21. package/.tsbuild/vitest.config.d.ts.map +1 -0
  22. package/CHANGELOG.md +51 -0
  23. package/dist/index.mjs +2 -2
  24. package/dist/{server-DcQv9aK4.mjs → server-CdgQ8Mhi.mjs} +4 -4
  25. package/dist/{server-DcQv9aK4.mjs.map → server-CdgQ8Mhi.mjs.map} +1 -1
  26. package/dist/server.d.mts +1 -1
  27. package/dist/server.mjs +4 -4
  28. package/dist/{utils-BVNg1DRI.mjs → utils-Baw7rThP.mjs} +3 -4
  29. package/dist/utils-Baw7rThP.mjs.map +1 -0
  30. package/dist/utils.d.mts.map +1 -1
  31. package/dist/utils.mjs +3 -3
  32. package/package.json +12 -12
  33. package/test/attachments/auth.test.ts +36 -25
  34. package/test/attachments/index.test.ts +14 -10
  35. package/test/attachments/service-config.test.ts +3 -3
  36. package/dist/utils-BVNg1DRI.mjs.map +0 -1
@@ -60,7 +60,7 @@ function makeAuthService(
60
60
  }
61
61
 
62
62
  describe("requireAuth", () => {
63
- it("returns the original handler unchanged when authService is undefined", async () => {
63
+ it("returns the original handler unchanged when authService is undefined", () => {
64
64
  const handler: NodeHandler = vi.fn();
65
65
  const wrapped = requireAuth(undefined, handler);
66
66
  expect(wrapped).toBe(handler);
@@ -77,11 +77,13 @@ describe("requireAuth", () => {
77
77
  });
78
78
 
79
79
  it("returns 401 with { error: 'Authentication required' } when Authorization header is missing", async () => {
80
- const { service, spy } = makeAuthService(async () => ({
81
- user: undefined,
82
- admins: [],
83
- auth_enabled: true,
84
- }));
80
+ const { service, spy } = makeAuthService(() =>
81
+ Promise.resolve({
82
+ user: undefined,
83
+ admins: [],
84
+ auth_enabled: true,
85
+ }),
86
+ );
85
87
  const handler = vi.fn<NodeHandler>();
86
88
  const wrapped = requireAuth(service, handler);
87
89
 
@@ -96,12 +98,13 @@ describe("requireAuth", () => {
96
98
  });
97
99
 
98
100
  it("forwards a Response from AuthService (status, content-type, body) for an invalid bearer token", async () => {
99
- const { service } = makeAuthService(
100
- async () =>
101
+ const { service } = makeAuthService(() =>
102
+ Promise.resolve(
101
103
  new Response(JSON.stringify({ error: "Verification failed" }), {
102
104
  status: 401,
103
105
  headers: { "content-type": "application/json" },
104
106
  }),
107
+ ),
105
108
  );
106
109
  const handler = vi.fn<NodeHandler>();
107
110
  const wrapped = requireAuth(service, handler);
@@ -119,12 +122,13 @@ describe("requireAuth", () => {
119
122
  });
120
123
 
121
124
  it("forwards a Response with a non-JSON content-type verbatim", async () => {
122
- const { service } = makeAuthService(
123
- async () =>
125
+ const { service } = makeAuthService(() =>
126
+ Promise.resolve(
124
127
  new Response("nope", {
125
128
  status: 403,
126
129
  headers: { "content-type": "text/plain" },
127
130
  }),
131
+ ),
128
132
  );
129
133
  const handler = vi.fn<NodeHandler>();
130
134
  const wrapped = requireAuth(service, handler);
@@ -142,11 +146,13 @@ describe("requireAuth", () => {
142
146
  });
143
147
 
144
148
  it("invokes the handler and leaves the response untouched on a valid bearer token", async () => {
145
- const { service } = makeAuthService(async () => ({
146
- user: { address: "0x123", chainId: 1, networkId: "mainnet" },
147
- admins: [],
148
- auth_enabled: true,
149
- }));
149
+ const { service } = makeAuthService(() =>
150
+ Promise.resolve({
151
+ user: { address: "0x123", chainId: 1, networkId: "mainnet" },
152
+ admins: [],
153
+ auth_enabled: true,
154
+ }),
155
+ );
150
156
  const handler = vi.fn<NodeHandler>();
151
157
  const wrapped = requireAuth(service, handler);
152
158
 
@@ -166,6 +172,7 @@ describe("requireAuth", () => {
166
172
 
167
173
  it("returns 500 with a sanitized body when AuthService throws", async () => {
168
174
  const { service } = makeAuthService(async () => {
175
+ await Promise.resolve();
169
176
  throw new Error("transient Renown failure: secret-internal-detail");
170
177
  });
171
178
  const handler = vi.fn<NodeHandler>();
@@ -187,11 +194,13 @@ describe("requireAuth", () => {
187
194
  });
188
195
 
189
196
  it("calls authService.verifyBearer with the incoming authorization header", async () => {
190
- const { service, spy } = makeAuthService(async () => ({
191
- user: { address: "0x1", chainId: 1, networkId: "mainnet" },
192
- admins: [],
193
- auth_enabled: true,
194
- }));
197
+ const { service, spy } = makeAuthService(() =>
198
+ Promise.resolve({
199
+ user: { address: "0x1", chainId: 1, networkId: "mainnet" },
200
+ admins: [],
201
+ auth_enabled: true,
202
+ }),
203
+ );
195
204
  const wrapped = requireAuth(service, vi.fn());
196
205
 
197
206
  await wrapped(
@@ -204,11 +213,13 @@ describe("requireAuth", () => {
204
213
  });
205
214
 
206
215
  it("calls verifyBearer with undefined when no authorization header is present", async () => {
207
- const { service, spy } = makeAuthService(async () => ({
208
- user: undefined,
209
- admins: [],
210
- auth_enabled: true,
211
- }));
216
+ const { service, spy } = makeAuthService(() =>
217
+ Promise.resolve({
218
+ user: undefined,
219
+ admins: [],
220
+ auth_enabled: true,
221
+ }),
222
+ );
212
223
  const wrapped = requireAuth(service, vi.fn());
213
224
 
214
225
  await wrapped(makeReq({ headers: {} }), makeRes());
@@ -61,11 +61,13 @@ function makeRes() {
61
61
 
62
62
  describe("mountAuthenticatedNodeRoute", () => {
63
63
  it("wraps the handler with auth enforcement when authService is defined", async () => {
64
- const verifyBearer = vi.fn(async () => ({
65
- user: undefined,
66
- admins: [],
67
- auth_enabled: true,
68
- }));
64
+ const verifyBearer = vi.fn(() =>
65
+ Promise.resolve({
66
+ user: undefined,
67
+ admins: [],
68
+ auth_enabled: true,
69
+ }),
70
+ );
69
71
  const authService = { verifyBearer } as unknown as AuthService;
70
72
  const { api, captured } = makeFakeApi(authService);
71
73
  const inner = vi.fn();
@@ -88,11 +90,13 @@ describe("mountAuthenticatedNodeRoute", () => {
88
90
  });
89
91
 
90
92
  it("invokes the inner handler when verifyBearer returns a valid user", async () => {
91
- const verifyBearer = vi.fn(async () => ({
92
- user: { address: "0x1", chainId: 1, networkId: "mainnet" },
93
- admins: [],
94
- auth_enabled: true,
95
- }));
93
+ const verifyBearer = vi.fn(() =>
94
+ Promise.resolve({
95
+ user: { address: "0x1", chainId: 1, networkId: "mainnet" },
96
+ admins: [],
97
+ auth_enabled: true,
98
+ }),
99
+ );
96
100
  const authService = { verifyBearer } as unknown as AuthService;
97
101
  const { api, captured } = makeFakeApi(authService);
98
102
  const inner = vi.fn();
@@ -61,9 +61,9 @@ describe("deriveAttachmentServiceConfig", () => {
61
61
  const calls: Array<{ expiresIn: number; aud: string }> = [];
62
62
  const renown = {
63
63
  user: { address: "0xabc" },
64
- getBearerToken: async (opts: { expiresIn: number; aud: string }) => {
64
+ getBearerToken: (opts: { expiresIn: number; aud: string }) => {
65
65
  calls.push(opts);
66
- return "tok-for-" + opts.aud;
66
+ return Promise.resolve("tok-for-" + opts.aud);
67
67
  },
68
68
  } as unknown as IRenown;
69
69
 
@@ -80,7 +80,7 @@ describe("deriveAttachmentServiceConfig", () => {
80
80
  it("returns undefined token when renown has no user identity", async () => {
81
81
  const renown = {
82
82
  user: null,
83
- getBearerToken: async () => "should-not-be-called",
83
+ getBearerToken: () => Promise.resolve("should-not-be-called"),
84
84
  } as unknown as IRenown;
85
85
 
86
86
  const { jwtHandler } = deriveAttachmentServiceConfig({}, 4001, renown);
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-BVNg1DRI.mjs","sources":["../src/utils.mts"],"sourcesContent":["import type { IReactorClient } from \"@powerhousedao/reactor\";\nimport {\n reactorDriveCreateDocument,\n reactorDriveCreateState,\n} from \"@powerhousedao/reactor-drive\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport {\n driveCreateDocument,\n driveCreateState,\n} from \"@powerhousedao/shared/document-drive\";\nimport type { DriveInput } from \"@powerhousedao/shared/document-drive\";\nimport { generateId } from \"@powerhousedao/shared/document-model\";\n\nexport async function addDefaultDrive(\n client: IReactorClient,\n drive: DriveInput,\n serverPort: number,\n) {\n let driveId = drive.id;\n if (!driveId || driveId.length === 0) {\n driveId = drive.slug;\n }\n\n if (!driveId || driveId.length === 0) {\n throw new Error(\"Invalid Drive Id\");\n }\n\n // check if the drive already exists\n let existingDrive;\n try {\n existingDrive = await client.get(driveId);\n } catch {\n //\n }\n\n // already exists, return the existing drive url\n if (existingDrive) {\n return `http://localhost:${serverPort}/d/${driveId}`;\n }\n\n const { global } = driveCreateState();\n const document = driveCreateDocument({\n global: {\n ...global,\n name: drive.global.name,\n icon: drive.global.icon ?? global.icon,\n },\n local: {\n availableOffline: drive.local?.availableOffline ?? false,\n sharingType: drive.local?.sharingType ?? \"public\",\n listeners: drive.local?.listeners ?? [],\n triggers: drive.local?.triggers ?? [],\n },\n });\n\n if (drive.id && drive.id.length > 0) {\n document.header.id = drive.id;\n }\n if (drive.slug && drive.slug.length > 0) {\n document.header.slug = drive.slug;\n }\n if (drive.global.name) {\n document.header.name = drive.global.name;\n }\n if (drive.preferredEditor) {\n document.header.meta = { preferredEditor: drive.preferredEditor };\n }\n\n try {\n await client.create(document);\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n if (!errorMessage.includes(\"already exists\")) {\n throw e;\n }\n }\n\n return `http://localhost:${serverPort}/d/${driveId}`;\n}\n\nexport async function addDefaultReactorDrive(\n client: IReactorClient,\n drive: DriveInput,\n serverPort: number,\n) {\n let driveId = drive.id;\n if (!driveId || driveId.length === 0) {\n driveId = drive.slug;\n }\n\n if (!driveId || driveId.length === 0) {\n throw new Error(\"Invalid Drive Id\");\n }\n\n let existingDrive;\n try {\n existingDrive = await client.get(driveId);\n } catch {\n //\n }\n\n if (existingDrive) {\n return `http://localhost:${serverPort}/d/${driveId}`;\n }\n\n const { global, local } = reactorDriveCreateState();\n const document = reactorDriveCreateDocument({\n global: {\n ...global,\n name: drive.global.name,\n icon: drive.global.icon ?? global.icon,\n },\n local: {\n ...local,\n availableOffline: drive.local?.availableOffline ?? local.availableOffline,\n sharingType: drive.local?.sharingType ?? local.sharingType,\n },\n });\n\n if (drive.id && drive.id.length > 0) {\n document.header.id = drive.id;\n }\n if (drive.slug && drive.slug.length > 0) {\n document.header.slug = drive.slug;\n }\n if (drive.global.name) {\n document.header.name = drive.global.name;\n }\n if (drive.preferredEditor) {\n document.header.meta = { preferredEditor: drive.preferredEditor };\n }\n\n try {\n await client.create(document);\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n if (!errorMessage.includes(\"already exists\")) {\n throw e;\n }\n }\n\n return `http://localhost:${serverPort}/d/${driveId}`;\n}\n\nexport function isPostgresUrl(url: string) {\n return url.startsWith(\"postgresql\") || url.startsWith(\"postgres\");\n}\n"],"names":[],"mappings":";;;;;;AAaA,eAAsB,gBACpB,QACA,OACA,YACA;CACA,IAAI,UAAU,MAAM;AACpB,KAAI,CAAC,WAAW,QAAQ,WAAW,EACjC,WAAU,MAAM;AAGlB,KAAI,CAAC,WAAW,QAAQ,WAAW,EACjC,OAAM,IAAI,MAAM,mBAAmB;CAIrC,IAAI;AACJ,KAAI;AACF,kBAAgB,MAAM,OAAO,IAAI,QAAQ;SACnC;AAKR,KAAI,cACF,QAAO,oBAAoB,WAAW,KAAK;CAG7C,MAAM,EAAE,WAAW,kBAAkB;CACrC,MAAM,WAAW,oBAAoB;EACnC,QAAQ;GACN,GAAG;GACH,MAAM,MAAM,OAAO;GACnB,MAAM,MAAM,OAAO,QAAQ,OAAO;GACnC;EACD,OAAO;GACL,kBAAkB,MAAM,OAAO,oBAAoB;GACnD,aAAa,MAAM,OAAO,eAAe;GACzC,WAAW,MAAM,OAAO,aAAa,EAAE;GACvC,UAAU,MAAM,OAAO,YAAY,EAAE;GACtC;EACF,CAAC;AAEF,KAAI,MAAM,MAAM,MAAM,GAAG,SAAS,EAChC,UAAS,OAAO,KAAK,MAAM;AAE7B,KAAI,MAAM,QAAQ,MAAM,KAAK,SAAS,EACpC,UAAS,OAAO,OAAO,MAAM;AAE/B,KAAI,MAAM,OAAO,KACf,UAAS,OAAO,OAAO,MAAM,OAAO;AAEtC,KAAI,MAAM,gBACR,UAAS,OAAO,OAAO,EAAE,iBAAiB,MAAM,iBAAiB;AAGnE,KAAI;AACF,QAAM,OAAO,OAAO,SAAS;UACtB,GAAG;AAEV,MAAI,EADiB,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE,EAC7C,SAAS,iBAAiB,CAC1C,OAAM;;AAIV,QAAO,oBAAoB,WAAW,KAAK;;AAG7C,eAAsB,uBACpB,QACA,OACA,YACA;CACA,IAAI,UAAU,MAAM;AACpB,KAAI,CAAC,WAAW,QAAQ,WAAW,EACjC,WAAU,MAAM;AAGlB,KAAI,CAAC,WAAW,QAAQ,WAAW,EACjC,OAAM,IAAI,MAAM,mBAAmB;CAGrC,IAAI;AACJ,KAAI;AACF,kBAAgB,MAAM,OAAO,IAAI,QAAQ;SACnC;AAIR,KAAI,cACF,QAAO,oBAAoB,WAAW,KAAK;CAG7C,MAAM,EAAE,QAAQ,UAAU,yBAAyB;CACnD,MAAM,WAAW,2BAA2B;EAC1C,QAAQ;GACN,GAAG;GACH,MAAM,MAAM,OAAO;GACnB,MAAM,MAAM,OAAO,QAAQ,OAAO;GACnC;EACD,OAAO;GACL,GAAG;GACH,kBAAkB,MAAM,OAAO,oBAAoB,MAAM;GACzD,aAAa,MAAM,OAAO,eAAe,MAAM;GAChD;EACF,CAAC;AAEF,KAAI,MAAM,MAAM,MAAM,GAAG,SAAS,EAChC,UAAS,OAAO,KAAK,MAAM;AAE7B,KAAI,MAAM,QAAQ,MAAM,KAAK,SAAS,EACpC,UAAS,OAAO,OAAO,MAAM;AAE/B,KAAI,MAAM,OAAO,KACf,UAAS,OAAO,OAAO,MAAM,OAAO;AAEtC,KAAI,MAAM,gBACR,UAAS,OAAO,OAAO,EAAE,iBAAiB,MAAM,iBAAiB;AAGnE,KAAI;AACF,QAAM,OAAO,OAAO,SAAS;UACtB,GAAG;AAEV,MAAI,EADiB,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE,EAC7C,SAAS,iBAAiB,CAC1C,OAAM;;AAIV,QAAO,oBAAoB,WAAW,KAAK;;AAG7C,SAAgB,cAAc,KAAa;AACzC,QAAO,IAAI,WAAW,aAAa,IAAI,IAAI,WAAW,WAAW","debug_id":"62094c88-5d64-5b09-a31f-23862e9c8977"}