@classytic/arc 2.18.4 → 2.18.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BaseController-B-uXzf6I.mjs → BaseController-Dy6EQHjM.mjs} +7 -7
- package/dist/{QueryCache-Dsyv2mLS.d.mts → QueryCache-TRfXau3W.d.mts} +1 -1
- package/dist/{ResourceRegistry-CWmOggxS.mjs → ResourceRegistry-5fKZwhK_.mjs} +1 -1
- package/dist/{pipeline-D4sqiokR.mjs → actionPermissions-h7DYDNMg.mjs} +28 -5
- package/dist/audit/index.d.mts +1 -1
- package/dist/auth/index.d.mts +4 -4
- package/dist/auth/index.mjs +252 -5
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/betterAuthOpenApi-CV1lxpRX.mjs +2 -0
- package/dist/{buildHandler-Cvrc2p7r.mjs → buildHandler-B0qvAguf.mjs} +1 -1
- package/dist/cache/index.d.mts +3 -3
- package/dist/cache/index.mjs +3 -3
- package/dist/{caching-C0DdKiYB.mjs → caching-_NJeDd1_.mjs} +1 -1
- package/dist/cli/commands/describe.d.mts +1 -1
- package/dist/cli/commands/describe.mjs +2 -2
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.d.mts +2 -2
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.d.mts +2 -2
- package/dist/cli/commands/init.mjs +1 -1
- package/dist/cli/commands/introspect.mjs +1 -1
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.mjs +2 -2
- package/dist/context/index.mjs +1 -1
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +4 -4
- package/dist/{core-C88uIwd3.mjs → core-ZnQBa5rh.mjs} +55 -56
- package/dist/{createActionRouter-DGCCp-kP.mjs → createActionRouter-CagItpxI.mjs} +6 -7
- package/dist/{createAggregationRouter-Ca77b8iK.mjs → createAggregationRouter-DVKroXhC.mjs} +4 -4
- package/dist/{createApp-J1iPXY9p.mjs → createApp--703hQE1.mjs} +14 -14
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +2 -2
- package/dist/{elevation-BzhyVWfn.mjs → elevation-COpYKt2h.mjs} +2 -2
- package/dist/{errorHandler-Bua97SEt.mjs → errorHandler-Dxf6P_kV.mjs} +2 -2
- package/dist/{eventPlugin-Bw4bUDEO.mjs → eventPlugin-DJG2D7sy.mjs} +106 -5
- package/dist/{eventPlugin-C1W1CRbf.d.mts → eventPlugin-DbBFd3x_.d.mts} +1 -1
- package/dist/events/index.d.mts +3 -3
- package/dist/events/index.mjs +189 -5
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.mjs +3 -3
- package/dist/{fastify-augmentation-BdCl_eNo.d.mts → fastify-augmentation-Cxb0ROIw.d.mts} +2 -2
- package/dist/{fields-CKLrhyOb.d.mts → fields-C7ahdGYf.d.mts} +1 -1
- package/dist/{generate-BaxDdmJ8.mjs → generate-Brans3fW.mjs} +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/idempotency/index.d.mts +2 -2
- package/dist/idempotency/index.mjs +1 -1
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/{index-QYma8mdC.d.mts → index-CHNQIhcb.d.mts} +5 -6
- package/dist/{index-vcWUGkwf.d.mts → index-CRKiiP5o.d.mts} +3 -3
- package/dist/{index-Cvo1u9n6.d.mts → index-Dh0_RSTd.d.mts} +3 -3
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +7 -7
- package/dist/{init-DSsdRfk9.mjs → init-Bqpt1Hxf.mjs} +274 -130
- package/dist/integrations/event-gateway.d.mts +2 -2
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +3 -3
- package/dist/integrations/mcp/index.d.mts +4 -4
- package/dist/integrations/mcp/index.mjs +1 -1
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/integrations/streamline.mjs +7 -3
- package/dist/integrations/websocket-pushref-redis.d.mts +1 -1
- package/dist/integrations/websocket-redis.d.mts +1 -1
- package/dist/integrations/websocket.d.mts +3 -3
- package/dist/{loadResources-CwXt9MCh.mjs → loadResources-B8UmpITt.mjs} +1 -1
- package/dist/{loadResourcesFromEntry-XHNeUWpu.mjs → loadResourcesFromEntry-BTlFEx05.mjs} +1 -1
- package/dist/{mcpPlugin-CzKdt3B8.mjs → mcpPlugin-D1wuRD2c.mjs} +10 -11
- package/dist/{memory-TdTHCS9-.mjs → memory-CLXA2VeJ.mjs} +1 -1
- package/dist/{metrics-Da2EUPi9.mjs → metrics-fdxI5mn_.mjs} +1 -1
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +2 -2
- package/dist/{openapi-ButnRyOM.mjs → openapi-xVJibapr.mjs} +5 -5
- package/dist/permissions/index.d.mts +3 -3
- package/dist/permissions/index.mjs +2 -2
- package/dist/{permissions-3uzwkbQt.mjs → permissions-BPB1xqGf.mjs} +4 -4
- package/dist/{pipe-9Tl-OAus.mjs → pipe-BOLmGIxa.mjs} +1 -1
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/pipeline/index.mjs +1 -1
- package/dist/plugins/index.d.mts +6 -7
- package/dist/plugins/index.mjs +12 -12
- package/dist/plugins/response-cache.mjs +1 -1
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/presets/filesUpload.d.mts +4 -4
- package/dist/presets/filesUpload.mjs +4 -4
- package/dist/presets/index.d.mts +1 -1
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +2 -2
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +1 -1
- package/dist/{presets-CF79RHEo.mjs → presets-BtyFwTO4.mjs} +2 -2
- package/dist/{queryCachePlugin-CnAeFqju.mjs → queryCachePlugin-emHb0CuX.mjs} +4 -4
- package/dist/{queryCachePlugin-Bd2tYgh5.d.mts → queryCachePlugin-xzFyKAjT.d.mts} +2 -2
- package/dist/{redis-3hqH_Qk_.d.mts → redis-C3W0qbz8.d.mts} +1 -1
- package/dist/{redis-stream-BtEUtjxZ.d.mts → redis-stream-DsP1vqZB.d.mts} +1 -1
- package/dist/{rateLimit-yKvxWAky.mjs → registerRoute-CPmdkZGu.mjs} +109 -2
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{registry-Br15xdGM.mjs → registry-Bm9LjWKs.mjs} +1 -1
- package/dist/{replyHelpers-DXHVxrrj.mjs → replyHelpers-67tRawQZ.mjs} +1 -1
- package/dist/{schemaIR-CE6USIRi.mjs → schemaIR-D1MJwqmp.mjs} +1 -1
- package/dist/schemas/index.d.mts +64 -65
- package/dist/scope/index.d.mts +2 -2
- package/dist/scope/index.mjs +3 -3
- package/dist/{sse-BrY1W6U8.mjs → sse-CfUjwjDk.mjs} +7 -4
- package/dist/streaming-BQcW6_Kq.mjs +162 -0
- package/dist/testing/index.d.mts +7 -7
- package/dist/testing/index.mjs +3 -3
- package/dist/testing/storageContract.d.mts +1 -1
- package/dist/types/index.d.mts +5 -5
- package/dist/types/storage.d.mts +1 -1
- package/dist/{types-WVlAVp8T.d.mts → types-CmkknLzI.d.mts} +10 -10
- package/dist/{types-BWBcb88c.d.mts → types-D60PFwfG.d.mts} +1 -1
- package/dist/{types-Bi0r0vjG.mjs → types-bHblZ9YN.mjs} +1 -1
- package/dist/utils/index.d.mts +42 -4
- package/dist/utils/index.mjs +6 -5
- package/dist/{utils-xAQeDyU_.mjs → utils-C6QQ9-hd.mjs} +1415 -1524
- package/dist/{validate-0__MuUsK.mjs → validate-CRcaWzp2.mjs} +1 -1
- package/dist/{versioning-BSEDGXKC.d.mts → versioning-D_eBCfNr.d.mts} +8 -1
- package/dist/{versioning-C0K8KQLx.mjs → versioning-Dk-71iIz.mjs} +1 -1
- package/dist/{websocket-BFBT5rH-.d.mts → websocket-MlYlrYq0.d.mts} +1 -1
- package/package.json +36 -30
- package/dist/EventTransport-7LPXLEUX.mjs +0 -103
- package/dist/actionPermissions-CX9QIMTd.mjs +0 -24
- package/dist/betterAuthOpenApi-DAAhMZff.mjs +0 -251
- package/dist/defineEvent-DC981g-o.mjs +0 -188
- package/dist/registerRoute-BEYn0ylk.mjs +0 -108
- /package/dist/{EventTransport-CaaXM5Y1.d.mts → EventTransport-IEn7Tn-Q.d.mts} +0 -0
- /package/dist/{HookSystem-BfCpWbwM.mjs → HookSystem-C1vB_Gc9.mjs} +0 -0
- /package/dist/{constants-TrJVIJl0.mjs → constants-gaEeMlz-.mjs} +0 -0
- /package/dist/{elevation-DW90z5bT.d.mts → elevation-xGUBq6p_.d.mts} +0 -0
- /package/dist/{errorHandler-_Lp2k9M3.d.mts → errorHandler-BtUUDPEa.d.mts} +0 -0
- /package/dist/{errors-DZOemeGa.d.mts → errors-DOHkjQlD.d.mts} +0 -0
- /package/dist/{errors-j4aJm1Wg.mjs → errors-DkO8Nk6-.mjs} +0 -0
- /package/dist/{externalPaths-DLle0R07.d.mts → externalPaths-BE6wFpYv.d.mts} +0 -0
- /package/dist/{generate-Dmk8cfvX.d.mts → generate-BnsL9GBm.d.mts} +0 -0
- /package/dist/{init-BS4Daqnv.d.mts → init-BPEu8cs-.d.mts} +0 -0
- /package/dist/{interface-DL7LlWS5.d.mts → interface-C1_WLTMK.d.mts} +0 -0
- /package/dist/{interface-CsrGR8LF.d.mts → interface-Uk8ONJv7.d.mts} +0 -0
- /package/dist/{keys-B3yyBEyH.mjs → keys-Cd316u_y.mjs} +0 -0
- /package/dist/{multipartBody-709YcXi1.mjs → multipartBody-CHEQSZ6G.mjs} +0 -0
- /package/dist/{pluralize-BxdUl2P4.mjs → pluralize-DccFV9R7.mjs} +0 -0
- /package/dist/{preloadResources-B-j-iqo-.mjs → preloadResources-CHw3_oA_.mjs} +0 -0
- /package/dist/{pushref-registry-Dqclzjy7.d.mts → pushref-registry-DnCqL3aa.d.mts} +0 -0
- /package/dist/{requestContext-DDLS3NVU.mjs → requestContext-BZKOr13H.mjs} +0 -0
- /package/dist/{chunk-BpYLSNr0.mjs → rolldown-runtime-8H4AJuhK.mjs} +0 -0
- /package/dist/{schemaConverter-DatAaVNj.mjs → schemaConverter-U0MnO9vd.mjs} +0 -0
- /package/dist/{sessionManager-CyHpYXoB.d.mts → sessionManager-BXG-HGwG.d.mts} +0 -0
- /package/dist/{storage-C5q8fuEt.d.mts → storage-Co_PQpeQ.d.mts} +0 -0
- /package/dist/{store-helpers-DjSYI2uP.mjs → store-helpers-DY6xq4sM.mjs} +0 -0
- /package/dist/{tracing-Bnb1-YVd.d.mts → tracing-D8jlGXP7.d.mts} +0 -0
- /package/dist/{typeGuards-CcFZXgU7.mjs → typeGuards-C9KXUly6.mjs} +0 -0
- /package/dist/{types-BJwJN2Pg.d.mts → types-LNebCoJx.d.mts} +0 -0
- /package/dist/{types-D57iXYb8.mjs → types-XTApa8b6.mjs} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as DomainEvent } from "./EventTransport-
|
|
1
|
+
import { n as DomainEvent } from "./EventTransport-IEn7Tn-Q.mjs";
|
|
2
2
|
import { FastifyPluginAsync, FastifyRequest } from "fastify";
|
|
3
3
|
|
|
4
4
|
//#region src/plugins/health.d.ts
|
|
@@ -76,6 +76,13 @@ interface SSEOptions {
|
|
|
76
76
|
orgScoped?: boolean;
|
|
77
77
|
/** Custom event filter function */
|
|
78
78
|
filter?: (event: DomainEvent<unknown>, request: FastifyRequest) => boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Query parameter that carries the bearer token for browser `EventSource`
|
|
81
|
+
* clients (which cannot send an `Authorization` header). Promoted into the
|
|
82
|
+
* header before auth. Default `'token'` — matches arc-next's `buildStreamUrl`.
|
|
83
|
+
* Set `null` to disable promotion (e.g. cookie-only auth).
|
|
84
|
+
*/
|
|
85
|
+
tokenQueryParam?: string | null;
|
|
79
86
|
}
|
|
80
87
|
declare const ssePlugin: FastifyPluginAsync<SSEOptions>;
|
|
81
88
|
declare const _default$2: FastifyPluginAsync<SSEOptions>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as PushRefRegistry, l as EnvelopeWriter, s as PushRefStore } from "./pushref-registry-
|
|
1
|
+
import { a as PushRefRegistry, l as EnvelopeWriter, s as PushRefStore } from "./pushref-registry-DnCqL3aa.mjs";
|
|
2
2
|
import { FastifyBaseLogger, FastifyPluginAsync } from "fastify";
|
|
3
3
|
|
|
4
4
|
//#region src/integrations/websocket/adapter.d.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@classytic/arc",
|
|
3
|
-
"version": "2.18.
|
|
3
|
+
"version": "2.18.5",
|
|
4
4
|
"description": "Resource-oriented backend framework for Fastify - clean, minimal, powerful, tree-shakable",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -224,6 +224,7 @@
|
|
|
224
224
|
"lint:all": "biome check src/ tests/",
|
|
225
225
|
"test": "vitest run",
|
|
226
226
|
"test:main": "vitest run --no-file-parallelism",
|
|
227
|
+
"test:fast": "vitest run --exclude \"**/tests/integrations/websocket/**\" && vitest run tests/integrations/websocket/ --no-file-parallelism",
|
|
227
228
|
"test:perf": "node --expose-gc ./node_modules/vitest/vitest.mjs run --config vitest.perf.config.ts --no-file-parallelism",
|
|
228
229
|
"test:ci": "npm run test:main && npm run test:perf",
|
|
229
230
|
"test:watch": "vitest",
|
|
@@ -350,56 +351,61 @@
|
|
|
350
351
|
}
|
|
351
352
|
},
|
|
352
353
|
"dependencies": {
|
|
353
|
-
"fastify-plugin": "^
|
|
354
|
+
"fastify-plugin": "^6.0.0",
|
|
354
355
|
"qs": "^6.15.2",
|
|
355
356
|
"secure-json-parse": "^4.1.0"
|
|
356
357
|
},
|
|
357
358
|
"devDependencies": {
|
|
358
|
-
"@better-auth/drizzle-adapter": "^1.6.
|
|
359
|
-
"@better-auth/mongo-adapter": "^1.6.
|
|
360
|
-
"@biomejs/biome": "^2.
|
|
359
|
+
"@better-auth/drizzle-adapter": "^1.6.19",
|
|
360
|
+
"@better-auth/mongo-adapter": "^1.6.19",
|
|
361
|
+
"@biomejs/biome": "^2.5.0",
|
|
361
362
|
"@classytic/dev-tools": "^0.2.0",
|
|
362
|
-
"@classytic/mongokit": "^3.16.
|
|
363
|
-
"@classytic/primitives": "^0.
|
|
363
|
+
"@classytic/mongokit": "^3.16.1",
|
|
364
|
+
"@classytic/primitives": "^0.7.2",
|
|
364
365
|
"@classytic/repo-core": "^0.6.0",
|
|
365
366
|
"@classytic/sqlitekit": "^0.6.0",
|
|
366
|
-
"@classytic/streamline": "^2.
|
|
367
|
+
"@classytic/streamline": "^2.6.0",
|
|
367
368
|
"@fastify/cors": "^11.2.0",
|
|
368
369
|
"@fastify/helmet": "^13.0.2",
|
|
369
|
-
"@fastify/jwt": "^10.
|
|
370
|
+
"@fastify/jwt": "^10.1.0",
|
|
370
371
|
"@fastify/multipart": "^10.0.0",
|
|
371
|
-
"@fastify/rate-limit": "^
|
|
372
|
+
"@fastify/rate-limit": "^11.0.0",
|
|
372
373
|
"@fastify/sensible": "^6.0.4",
|
|
373
|
-
"@fastify/type-provider-typebox": "^6.
|
|
374
|
+
"@fastify/type-provider-typebox": "^6.1.0",
|
|
374
375
|
"@fastify/under-pressure": "^9.0.3",
|
|
375
|
-
"@fastify/websocket": "^11.
|
|
376
|
+
"@fastify/websocket": "^11.2.0",
|
|
376
377
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
377
378
|
"@opentelemetry/api": "^1.9.1",
|
|
378
|
-
"@sinclair/typebox": "^0.34.
|
|
379
|
-
"@types/node": "^22.19.
|
|
379
|
+
"@sinclair/typebox": "^0.34.49",
|
|
380
|
+
"@types/node": "^22.19.21",
|
|
380
381
|
"@types/qs": "^6.15.1",
|
|
381
|
-
"@vitest/coverage-v8": "^
|
|
382
|
-
"ajv": "^8.
|
|
383
|
-
"better-auth": "^1.6.
|
|
384
|
-
"better-sqlite3": "^12.
|
|
385
|
-
"bullmq": "^5.
|
|
382
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
383
|
+
"ajv": "^8.20.0",
|
|
384
|
+
"better-auth": "^1.6.19",
|
|
385
|
+
"better-sqlite3": "^12.11.1",
|
|
386
|
+
"bullmq": "^5.79.0",
|
|
386
387
|
"dotenv": "^17.4.2",
|
|
387
388
|
"drizzle-orm": "^0.45.2",
|
|
388
389
|
"fast-check": "^4.8.0",
|
|
389
390
|
"fastify": "^5.8.5",
|
|
390
391
|
"fastify-raw-body": "^5.0.0",
|
|
391
392
|
"h3-js": "^4.4.0",
|
|
392
|
-
"ioredis": "^5.
|
|
393
|
-
"jsonwebtoken": "^9.0.
|
|
394
|
-
"knip": "^6.
|
|
395
|
-
"mongodb": "^7.
|
|
396
|
-
"mongodb-memory-server": "^11.0
|
|
397
|
-
"mongoose": "^9.
|
|
398
|
-
"tsdown": "^0.
|
|
399
|
-
"typescript": "^6.0.
|
|
400
|
-
"vitest": "^
|
|
401
|
-
"ws": "^8.
|
|
402
|
-
"zod": "^4.3
|
|
393
|
+
"ioredis": "^5.11.1",
|
|
394
|
+
"jsonwebtoken": "^9.0.3",
|
|
395
|
+
"knip": "^6.17.1",
|
|
396
|
+
"mongodb": "^7.3.0",
|
|
397
|
+
"mongodb-memory-server": "^11.2.0",
|
|
398
|
+
"mongoose": "^9.7.1",
|
|
399
|
+
"tsdown": "^0.22.3",
|
|
400
|
+
"typescript": "^6.0.3",
|
|
401
|
+
"vitest": "^4.1.9",
|
|
402
|
+
"ws": "^8.21.0",
|
|
403
|
+
"zod": "^4.4.3"
|
|
404
|
+
},
|
|
405
|
+
"config": {
|
|
406
|
+
"mongodbMemoryServer": {
|
|
407
|
+
"disablePostinstall": "1"
|
|
408
|
+
}
|
|
403
409
|
},
|
|
404
410
|
"keywords": [
|
|
405
411
|
"fastify",
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { createEvent, matchEventPattern } from "@classytic/primitives/events";
|
|
2
|
-
//#region src/events/EventTransport.ts
|
|
3
|
-
/**
|
|
4
|
-
* Internal arc events module — concrete in-memory transport.
|
|
5
|
-
*
|
|
6
|
-
* **Public type contracts moved out (arc 2.12).** `EventMeta`, `DomainEvent`,
|
|
7
|
-
* `EventHandler`, `EventLogger`, `EventTransport`, `DeadLetteredEvent`,
|
|
8
|
-
* `PublishManyResult`, plus the `createEvent` / `createChildEvent` /
|
|
9
|
-
* `matchEventPattern` helpers, are now owned by `@classytic/primitives/events`.
|
|
10
|
-
* Two reasons:
|
|
11
|
-
*
|
|
12
|
-
* 1. The shapes ARE the cross-package contract. arc, arc-next, mongokit's
|
|
13
|
-
* audit-log plugin, future kits and downstream services all share them.
|
|
14
|
-
* Owning them in `primitives` (pure types, zero runtime, zero deps)
|
|
15
|
-
* eliminates the "manually mirror in two places" problem the previous
|
|
16
|
-
* `primitives/src/events.ts` header explicitly called out.
|
|
17
|
-
* 2. Inverting the dependency direction lets future packages (sqlitekit
|
|
18
|
-
* audit, billing services) consume the contract without depending on
|
|
19
|
-
* arc's HTTP-coupled stack.
|
|
20
|
-
*
|
|
21
|
-
* Hosts MUST import the types from primitives directly:
|
|
22
|
-
*
|
|
23
|
-
* ```typescript
|
|
24
|
-
* import type {
|
|
25
|
-
* EventMeta, DomainEvent, EventHandler, EventTransport,
|
|
26
|
-
* DeadLetteredEvent, PublishManyResult,
|
|
27
|
-
* } from '@classytic/primitives/events';
|
|
28
|
-
* import { createEvent, createChildEvent } from '@classytic/primitives/events';
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* arc's `events/index.ts` barrel does NOT re-export these — by design, so
|
|
32
|
-
* that consumer code is forced into the canonical import path and the org's
|
|
33
|
-
* "no re-exports" rule holds at every public surface.
|
|
34
|
-
*
|
|
35
|
-
* What stays here:
|
|
36
|
-
* - `MemoryEventTransport` — the in-memory `EventTransport` implementation
|
|
37
|
-
* used as arc's default transport. Its handler-set state is process-local;
|
|
38
|
-
* wrong layer for primitives.
|
|
39
|
-
* - `MemoryEventTransportOptions` — its options shape.
|
|
40
|
-
*
|
|
41
|
-
* Inside arc, files that previously imported types from `./EventTransport.js`
|
|
42
|
-
* keep working: this file re-exports them from primitives for arc's own
|
|
43
|
-
* call sites. That re-export is an internal refactor convenience — the
|
|
44
|
-
* public `events/index.ts` barrel stays clean.
|
|
45
|
-
*/
|
|
46
|
-
/**
|
|
47
|
-
* In-memory event transport (default).
|
|
48
|
-
*
|
|
49
|
-
* Events are delivered synchronously within the process. Not suitable for
|
|
50
|
-
* multi-instance deployments — pair with `RedisEventTransport` /
|
|
51
|
-
* `RedisStreamTransport` (subpath imports) for those.
|
|
52
|
-
*/
|
|
53
|
-
var MemoryEventTransport = class {
|
|
54
|
-
name = "memory";
|
|
55
|
-
handlers = /* @__PURE__ */ new Map();
|
|
56
|
-
logger;
|
|
57
|
-
constructor(options) {
|
|
58
|
-
this.logger = options?.logger ?? console;
|
|
59
|
-
}
|
|
60
|
-
async publish(event) {
|
|
61
|
-
const allHandlers = /* @__PURE__ */ new Set();
|
|
62
|
-
for (const [pattern, handlers] of this.handlers) if (matchEventPattern(pattern, event.type)) for (const h of handlers) allHandlers.add(h);
|
|
63
|
-
for (const handler of allHandlers) try {
|
|
64
|
-
await handler(event);
|
|
65
|
-
} catch (err) {
|
|
66
|
-
this.logger.error(`[EventTransport] Handler error for ${event.type}:`, err);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Reference `publishMany` implementation — delegates to `publish()` in order.
|
|
71
|
-
*
|
|
72
|
-
* Production transports (Kafka, Redis pipeline, SQS batch) should override
|
|
73
|
-
* this with a single batched network call. Memory transport has nothing to
|
|
74
|
-
* batch, so we just loop — the loop still returns a proper result map so
|
|
75
|
-
* `EventOutbox.relay` can exercise the batched code path in tests.
|
|
76
|
-
*/
|
|
77
|
-
async publishMany(events) {
|
|
78
|
-
const results = /* @__PURE__ */ new Map();
|
|
79
|
-
for (const event of events) try {
|
|
80
|
-
await this.publish(event);
|
|
81
|
-
results.set(event.meta.id, null);
|
|
82
|
-
} catch (err) {
|
|
83
|
-
results.set(event.meta.id, err instanceof Error ? err : new Error(String(err)));
|
|
84
|
-
}
|
|
85
|
-
return results;
|
|
86
|
-
}
|
|
87
|
-
async subscribe(pattern, handler) {
|
|
88
|
-
if (!this.handlers.has(pattern)) this.handlers.set(pattern, /* @__PURE__ */ new Set());
|
|
89
|
-
this.handlers.get(pattern)?.add(handler);
|
|
90
|
-
return () => {
|
|
91
|
-
const set = this.handlers.get(pattern);
|
|
92
|
-
if (set) {
|
|
93
|
-
set.delete(handler);
|
|
94
|
-
if (set.size === 0) this.handlers.delete(pattern);
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
async close() {
|
|
99
|
-
this.handlers.clear();
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
//#endregion
|
|
103
|
-
export { createEvent as n, MemoryEventTransport as t };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
//#region src/core/actionPermissions.ts
|
|
2
|
-
/**
|
|
3
|
-
* Return the effective `PermissionCheck` for a single action, or `undefined`
|
|
4
|
-
* when the resource declares no gate at any level.
|
|
5
|
-
*
|
|
6
|
-
* Callers decide what "no gate" means:
|
|
7
|
-
* - HTTP: boot-time throw in `normalizeActionsToRouterConfig`.
|
|
8
|
-
* - MCP: tool-generation throw in `resourceToTools` (mirrors HTTP — the
|
|
9
|
-
* two surfaces fail closed identically so MCP can't expose an
|
|
10
|
-
* unauthenticated mutating tool when the HTTP plugin lifecycle hasn't
|
|
11
|
-
* run).
|
|
12
|
-
* - OpenAPI: docs advertise the endpoint as unauthenticated.
|
|
13
|
-
*/
|
|
14
|
-
function resolveActionPermission(input) {
|
|
15
|
-
const { action, resourcePermissions, resourceActionPermissions, globalAuth } = input;
|
|
16
|
-
const explicit = typeof action !== "function" && action.permissions ? action.permissions : void 0;
|
|
17
|
-
if (explicit) return explicit;
|
|
18
|
-
if (resourceActionPermissions) return resourceActionPermissions;
|
|
19
|
-
if (globalAuth) return globalAuth;
|
|
20
|
-
const updateFallback = resourcePermissions?.update;
|
|
21
|
-
if (updateFallback) return updateFallback;
|
|
22
|
-
}
|
|
23
|
-
//#endregion
|
|
24
|
-
export { resolveActionPermission as t };
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
|
-
import { a as toJsonSchema } from "./schemaConverter-DatAaVNj.mjs";
|
|
3
|
-
//#region src/auth/betterAuthOpenApi.ts
|
|
4
|
-
var betterAuthOpenApi_exports = /* @__PURE__ */ __exportAll({ extractBetterAuthOpenApi: () => extractBetterAuthOpenApi });
|
|
5
|
-
/**
|
|
6
|
-
* Check if a value looks like a Better Auth endpoint (has .path and .options)
|
|
7
|
-
*/
|
|
8
|
-
function isBetterAuthEndpoint(value) {
|
|
9
|
-
if (typeof value !== "function" && typeof value !== "object") return false;
|
|
10
|
-
if (!value) return false;
|
|
11
|
-
const v = value;
|
|
12
|
-
return typeof v.path === "string" && typeof v.options === "object" && v.options !== null;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Convert Fastify-style path params (/:id) to OpenAPI-style (/{id})
|
|
16
|
-
*/
|
|
17
|
-
function toOpenApiPath(path) {
|
|
18
|
-
return path.replace(/:([^/]+)/g, "{$1}");
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Extract path parameters from a path string
|
|
22
|
-
*/
|
|
23
|
-
function extractPathParams(path) {
|
|
24
|
-
const params = [];
|
|
25
|
-
const matches = path.matchAll(/:(\w+)/g);
|
|
26
|
-
for (const match of matches) {
|
|
27
|
-
const name = match[1];
|
|
28
|
-
if (!name) continue;
|
|
29
|
-
params.push({
|
|
30
|
-
name,
|
|
31
|
-
in: "path",
|
|
32
|
-
required: true,
|
|
33
|
-
schema: { type: "string" }
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
return params;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Extract OpenAPI paths from a Better Auth instance's API object.
|
|
40
|
-
*
|
|
41
|
-
* Walks `authApi` (the `auth.api` object from Better Auth), discovers
|
|
42
|
-
* endpoints, converts their Zod schemas to JSON Schema via `z.toJSONSchema()`,
|
|
43
|
-
* and returns a complete `ExternalOpenApiPaths` object ready for Arc's spec builder.
|
|
44
|
-
*/
|
|
45
|
-
function extractBetterAuthOpenApi(authApi, options = {}) {
|
|
46
|
-
const { basePath = "/api/auth", tagName = "Authentication", tagDescription = "Better Auth authentication endpoints", excludePaths = [], excludeServerOnly = true, userFields } = options;
|
|
47
|
-
const normalizedBase = basePath.replace(/\/+$/, "");
|
|
48
|
-
const paths = {};
|
|
49
|
-
const detectedPlugins = detectActivePlugins(authApi);
|
|
50
|
-
const securityOptions = [{ cookieAuth: [] }, { bearerAuth: [] }];
|
|
51
|
-
if (detectedPlugins.apiKey) securityOptions.push({ apiKeyAuth: [] });
|
|
52
|
-
for (const [key, value] of Object.entries(authApi)) {
|
|
53
|
-
if (!isBetterAuthEndpoint(value)) continue;
|
|
54
|
-
const { path: endpointPath, options: endpointOpts } = value;
|
|
55
|
-
if (excludePaths.includes(endpointPath)) continue;
|
|
56
|
-
if (excludeServerOnly && endpointOpts.metadata?.SERVER_ONLY) continue;
|
|
57
|
-
const fullPath = toOpenApiPath(`${normalizedBase}${endpointPath}`);
|
|
58
|
-
const methods = [];
|
|
59
|
-
if (endpointOpts.method) if (Array.isArray(endpointOpts.method)) methods.push(...endpointOpts.method.map((m) => m.toLowerCase()));
|
|
60
|
-
else methods.push(endpointOpts.method.toLowerCase());
|
|
61
|
-
else methods.push(endpointOpts.body ? "post" : "get");
|
|
62
|
-
const openApiMeta = endpointOpts.metadata?.openapi;
|
|
63
|
-
for (const method of methods) {
|
|
64
|
-
const operation = {
|
|
65
|
-
tags: openApiMeta?.tags ?? [tagName],
|
|
66
|
-
operationId: openApiMeta?.operationId ?? key,
|
|
67
|
-
summary: openApiMeta?.summary ?? formatOperationSummary(key),
|
|
68
|
-
security: securityOptions
|
|
69
|
-
};
|
|
70
|
-
if (openApiMeta?.description) operation.description = openApiMeta.description;
|
|
71
|
-
const parameters = [...extractPathParams(endpointPath)];
|
|
72
|
-
if ((method === "get" || method === "delete") && endpointOpts.query) {
|
|
73
|
-
const querySchema = toJsonSchema(endpointOpts.query);
|
|
74
|
-
if (querySchema && querySchema.type === "object" && querySchema.properties) {
|
|
75
|
-
const props = querySchema.properties;
|
|
76
|
-
const required = querySchema.required ?? [];
|
|
77
|
-
for (const [name, prop] of Object.entries(props)) {
|
|
78
|
-
const paramEntry = {
|
|
79
|
-
name,
|
|
80
|
-
in: "query",
|
|
81
|
-
required: required.includes(name),
|
|
82
|
-
schema: prop
|
|
83
|
-
};
|
|
84
|
-
if (prop.description) paramEntry.description = prop.description;
|
|
85
|
-
parameters.push(paramEntry);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (parameters.length > 0) operation.parameters = parameters;
|
|
90
|
-
if (method === "post" || method === "put" || method === "patch") {
|
|
91
|
-
if (openApiMeta?.requestBody) operation.requestBody = structuredClone(openApiMeta.requestBody);
|
|
92
|
-
else if (endpointOpts.body) {
|
|
93
|
-
const bodySchema = toJsonSchema(endpointOpts.body);
|
|
94
|
-
if (bodySchema) operation.requestBody = {
|
|
95
|
-
required: true,
|
|
96
|
-
content: { "application/json": { schema: bodySchema } }
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
if (userFields && isUserFieldEndpoint(endpointPath) && operation.requestBody) mergeUserFieldsIntoRequestBody(operation.requestBody, userFields, endpointPath);
|
|
100
|
-
}
|
|
101
|
-
if (openApiMeta?.responses) operation.responses = openApiMeta.responses;
|
|
102
|
-
else operation.responses = {
|
|
103
|
-
"200": { description: "Success" },
|
|
104
|
-
"400": { description: "Bad request" },
|
|
105
|
-
"401": { description: "Unauthorized" }
|
|
106
|
-
};
|
|
107
|
-
if (!paths[fullPath]) paths[fullPath] = {};
|
|
108
|
-
paths[fullPath][method] = operation;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
const schemas = {
|
|
112
|
-
User: {
|
|
113
|
-
type: "object",
|
|
114
|
-
properties: {
|
|
115
|
-
id: { type: "string" },
|
|
116
|
-
name: { type: "string" },
|
|
117
|
-
email: {
|
|
118
|
-
type: "string",
|
|
119
|
-
format: "email"
|
|
120
|
-
},
|
|
121
|
-
emailVerified: { type: "boolean" },
|
|
122
|
-
image: {
|
|
123
|
-
type: "string",
|
|
124
|
-
nullable: true
|
|
125
|
-
},
|
|
126
|
-
createdAt: {
|
|
127
|
-
type: "string",
|
|
128
|
-
format: "date-time"
|
|
129
|
-
},
|
|
130
|
-
updatedAt: {
|
|
131
|
-
type: "string",
|
|
132
|
-
format: "date-time"
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
Session: {
|
|
137
|
-
type: "object",
|
|
138
|
-
properties: {
|
|
139
|
-
id: { type: "string" },
|
|
140
|
-
userId: { type: "string" },
|
|
141
|
-
token: { type: "string" },
|
|
142
|
-
expiresAt: {
|
|
143
|
-
type: "string",
|
|
144
|
-
format: "date-time"
|
|
145
|
-
},
|
|
146
|
-
ipAddress: {
|
|
147
|
-
type: "string",
|
|
148
|
-
nullable: true
|
|
149
|
-
},
|
|
150
|
-
userAgent: {
|
|
151
|
-
type: "string",
|
|
152
|
-
nullable: true
|
|
153
|
-
},
|
|
154
|
-
createdAt: {
|
|
155
|
-
type: "string",
|
|
156
|
-
format: "date-time"
|
|
157
|
-
},
|
|
158
|
-
updatedAt: {
|
|
159
|
-
type: "string",
|
|
160
|
-
format: "date-time"
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
if (userFields) {
|
|
166
|
-
const userProps = schemas.User?.properties;
|
|
167
|
-
for (const [name, field] of Object.entries(userFields)) {
|
|
168
|
-
const prop = { type: field.type };
|
|
169
|
-
if (field.description) prop.description = field.description;
|
|
170
|
-
userProps[name] = prop;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
const securitySchemes = { cookieAuth: {
|
|
174
|
-
type: "apiKey",
|
|
175
|
-
in: "cookie",
|
|
176
|
-
name: "better-auth.session_token",
|
|
177
|
-
description: "Session cookie set by Better Auth after sign-in"
|
|
178
|
-
} };
|
|
179
|
-
if (detectedPlugins.apiKey) securitySchemes.apiKeyAuth = {
|
|
180
|
-
type: "apiKey",
|
|
181
|
-
in: "header",
|
|
182
|
-
name: "x-api-key",
|
|
183
|
-
description: "API key for programmatic access. Pass org context via x-organization-id header."
|
|
184
|
-
};
|
|
185
|
-
const resourceSecurity = [];
|
|
186
|
-
if (detectedPlugins.apiKey) resourceSecurity.push({
|
|
187
|
-
apiKeyAuth: [],
|
|
188
|
-
orgHeader: []
|
|
189
|
-
});
|
|
190
|
-
return {
|
|
191
|
-
paths,
|
|
192
|
-
schemas,
|
|
193
|
-
securitySchemes,
|
|
194
|
-
tags: [{
|
|
195
|
-
name: tagName,
|
|
196
|
-
description: tagDescription
|
|
197
|
-
}],
|
|
198
|
-
resourceSecurity: resourceSecurity.length > 0 ? resourceSecurity : void 0
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Auto-detect active Better Auth plugins by inspecting the API object.
|
|
203
|
-
*
|
|
204
|
-
* Rather than hardcoding plugin-specific behavior, we check for known
|
|
205
|
-
* endpoint signatures that each plugin registers. This way the OpenAPI
|
|
206
|
-
* spec adapts automatically to whatever plugins the app has enabled —
|
|
207
|
-
* no Arc update needed when adding/removing plugins.
|
|
208
|
-
*/
|
|
209
|
-
function detectActivePlugins(authApi) {
|
|
210
|
-
const endpointPaths = /* @__PURE__ */ new Set();
|
|
211
|
-
for (const value of Object.values(authApi)) if (isBetterAuthEndpoint(value)) endpointPaths.add(value.path);
|
|
212
|
-
return {
|
|
213
|
-
apiKey: endpointPaths.has("/api-key/create"),
|
|
214
|
-
organization: endpointPaths.has("/organization/create")
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Convert a camelCase key like 'signInEmail' to a readable summary like 'Sign in email'
|
|
219
|
-
*/
|
|
220
|
-
function formatOperationSummary(key) {
|
|
221
|
-
return key.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Check if an endpoint path should have userFields merged into its request body.
|
|
225
|
-
*/
|
|
226
|
-
function isUserFieldEndpoint(path) {
|
|
227
|
-
return path === "/sign-up/email" || path === "/update-user";
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Merge user-defined fields into an existing requestBody schema.
|
|
231
|
-
* For updateUser, all fields are treated as optional regardless of their `required` setting.
|
|
232
|
-
*/
|
|
233
|
-
function mergeUserFieldsIntoRequestBody(requestBody, userFields, endpointPath) {
|
|
234
|
-
const content = requestBody?.content?.["application/json"];
|
|
235
|
-
if (!content?.schema) return;
|
|
236
|
-
const schema = content.schema;
|
|
237
|
-
if (!schema.properties) schema.properties = {};
|
|
238
|
-
if (!schema.required) schema.required = [];
|
|
239
|
-
const props = schema.properties;
|
|
240
|
-
const required = schema.required;
|
|
241
|
-
for (const [name, field] of Object.entries(userFields)) {
|
|
242
|
-
if (field.input === false) continue;
|
|
243
|
-
const isRequired = endpointPath === "/update-user" ? false : field.required ?? false;
|
|
244
|
-
const prop = { type: field.type };
|
|
245
|
-
if (field.description) prop.description = field.description;
|
|
246
|
-
props[name] = prop;
|
|
247
|
-
if (isRequired && !required.includes(name)) required.push(name);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
//#endregion
|
|
251
|
-
export { extractBetterAuthOpenApi as n, betterAuthOpenApi_exports as t };
|