@classytic/arc 2.1.2 → 2.1.7
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/README.md +6 -5
- package/bin/arc.js +1 -0
- package/dist/{EventTransport-BD2U0BTc.d.mts → EventTransport-BkUDYZEb.d.mts} +1 -2
- package/dist/HookSystem-BsGV-j2l.mjs +1 -2
- package/dist/{ResourceRegistry-DsN4KJjV.mjs → ResourceRegistry-7Ic20ZMw.mjs} +1 -2
- package/dist/adapters/index.d.mts +4 -4
- package/dist/audit/index.d.mts +5 -6
- package/dist/audit/index.mjs +2 -3
- package/dist/audit/mongodb.d.mts +4 -4
- package/dist/audit/mongodb.mjs +1 -1
- package/dist/{audited-C3T5DTUx.mjs → audited-CGdLiSlE.mjs} +1 -2
- package/dist/auth/index.d.mts +6 -7
- package/dist/auth/index.mjs +10 -16
- package/dist/auth/redis-session.d.mts +2 -3
- package/dist/auth/redis-session.mjs +1 -2
- package/dist/{betterAuthOpenApi-BrHKeSAx.mjs → betterAuthOpenApi-DjWDddNc.mjs} +2 -3
- package/dist/cache/index.d.mts +3 -4
- package/dist/cache/index.mjs +4 -5
- package/dist/{caching-Bl28lYsR.mjs → caching-GSDJcA6-.mjs} +1 -2
- package/dist/{circuitBreaker-DeY4FCjs.mjs → circuitBreaker-DYhWBW_D.mjs} +1 -2
- package/dist/cli/commands/describe.d.mts +1 -2
- package/dist/cli/commands/describe.mjs +1 -2
- package/dist/cli/commands/docs.d.mts +1 -2
- package/dist/cli/commands/docs.mjs +3 -4
- package/dist/cli/commands/generate.d.mts +6 -2
- package/dist/cli/commands/generate.mjs +89 -58
- package/dist/cli/commands/init.d.mts +1 -2
- package/dist/cli/commands/init.mjs +15 -19
- package/dist/cli/commands/introspect.d.mts +1 -2
- package/dist/cli/commands/introspect.mjs +2 -3
- package/dist/cli/index.d.mts +1 -2
- package/dist/cli/index.mjs +1 -2
- package/dist/constants-DdXFXQtN.mjs +1 -2
- package/dist/core/index.d.mts +4 -4
- package/dist/core/index.mjs +1 -1
- package/dist/{createApp-CUgNqegw.mjs → createApp-D2D5XXaV.mjs} +9 -10
- package/dist/{defineResource-k0_BDn8v.mjs → defineResource-DZVbwsFb.mjs} +17 -39
- package/dist/discovery/index.d.mts +1 -2
- package/dist/discovery/index.mjs +1 -2
- package/dist/docs/index.d.mts +5 -6
- package/dist/docs/index.mjs +5 -4
- package/dist/{elevation-B_2dRLVP.d.mts → elevation-DGo5shaX.d.mts} +1 -2
- package/dist/{elevation-BRy3yFWT.mjs → elevation-DSTbVvYj.mjs} +4 -4
- package/dist/{errorHandler-C1okiriz.mjs → errorHandler-C3GY3_ow.mjs} +2 -3
- package/dist/{errorHandler-BbcgBmIH.d.mts → errorHandler-CW3OOeYq.d.mts} +2 -3
- package/dist/{errors-ChKiFz62.d.mts → errors-DAWRdiYP.d.mts} +1 -2
- package/dist/{errors-B9bZok84.mjs → errors-DBANPbGr.mjs} +1 -2
- package/dist/{eventPlugin-DGR_B2on.mjs → eventPlugin-BEOvaDqo.mjs} +2 -3
- package/dist/{eventPlugin-CTrLH3mt.d.mts → eventPlugin-H6wDDjGO.d.mts} +2 -3
- package/dist/events/index.d.mts +4 -5
- package/dist/events/index.mjs +2 -3
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +1 -2
- package/dist/events/transports/redis.d.mts +2 -3
- package/dist/events/transports/redis.mjs +1 -2
- package/dist/{externalPaths-DlINfKbP.d.mts → externalPaths-SyPF2tgK.d.mts} +1 -2
- package/dist/factory/index.d.mts +8 -9
- package/dist/factory/index.mjs +1 -1
- package/dist/{fastifyAdapter-BkrGrlFi.d.mts → fastifyAdapter-sGkvUvf5.d.mts} +4 -5
- package/dist/{fields-DyaDVX4J.d.mts → fields-Bi_AVKSo.d.mts} +2 -3
- package/dist/{fields-iagOozy0.mjs → fields-CTd_CrKr.mjs} +2 -3
- package/dist/hooks/index.d.mts +3 -3
- package/dist/idempotency/index.d.mts +4 -5
- package/dist/idempotency/index.mjs +1 -2
- package/dist/idempotency/mongodb.d.mts +1 -1
- package/dist/idempotency/mongodb.mjs +1 -2
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/idempotency/redis.mjs +1 -2
- package/dist/index.d.mts +9 -10
- package/dist/index.mjs +7 -8
- package/dist/integrations/event-gateway.d.mts +2 -3
- package/dist/integrations/event-gateway.mjs +2 -3
- package/dist/integrations/jobs.d.mts +1 -2
- package/dist/integrations/jobs.mjs +1 -2
- package/dist/integrations/streamline.d.mts +1 -2
- package/dist/integrations/streamline.mjs +1 -2
- package/dist/integrations/websocket.d.mts +1 -2
- package/dist/integrations/websocket.mjs +1 -2
- package/dist/{interface-B01JvPVc.d.mts → interface-CSNjltAc.d.mts} +1 -2
- package/dist/{interface-Ch8HU9uM.d.mts → interface-Cb2klgid.d.mts} +10 -10
- package/dist/{interface-CZe8IkMf.d.mts → interface-DTbsvIWe.d.mts} +1 -2
- package/dist/{introspectionPlugin-rFdO8ZUa.mjs → introspectionPlugin-B3JkrjwU.mjs} +1 -2
- package/dist/{keys-BqNejWup.mjs → keys-DhqDRxv3.mjs} +1 -2
- package/dist/{logger-Df2O2WsW.mjs → logger-ByrvQWZO.mjs} +1 -2
- package/dist/{memory-cQgelFOj.mjs → memory-B2v7KrCB.mjs} +1 -2
- package/dist/migrations/index.d.mts +1 -2
- package/dist/migrations/index.mjs +1 -2
- package/dist/{mongodb-CGzRbfAK.d.mts → mongodb-ClykrfGo.d.mts} +2 -3
- package/dist/{mongodb-BfJVlUJH.mjs → mongodb-DNKEExbf.mjs} +1 -2
- package/dist/{mongodb-JN-9JA7K.d.mts → mongodb-Dg8O_gvd.d.mts} +2 -3
- package/dist/{openapi-G3Cw7XuM.mjs → openapi-9nB_kiuR.mjs} +5 -4
- package/dist/org/index.d.mts +4 -5
- package/dist/org/index.mjs +1 -2
- package/dist/org/types.d.mts +1 -2
- package/dist/permissions/index.d.mts +5 -6
- package/dist/permissions/index.mjs +7 -7
- package/dist/plugins/index.d.mts +7 -8
- package/dist/plugins/index.mjs +7 -8
- package/dist/plugins/response-cache.d.mts +1 -2
- package/dist/plugins/response-cache.mjs +2 -3
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -2
- package/dist/{pluralize-CEweyOEm.mjs → pluralize-CM-jZg7p.mjs} +1 -2
- package/dist/policies/index.d.mts +4 -5
- package/dist/policies/index.mjs +1 -2
- package/dist/presets/index.d.mts +4 -5
- package/dist/presets/index.mjs +2 -3
- package/dist/presets/multiTenant.d.mts +4 -5
- package/dist/presets/multiTenant.mjs +1 -2
- package/dist/{presets-DzSMwlKj.d.mts → presets-BTeYbw7h.d.mts} +2 -3
- package/dist/{presets-BITljm96.mjs → presets-CeFtfDR8.mjs} +1 -2
- package/dist/prisma-DJbMt3yf.mjs +1 -2
- package/dist/{prisma-Dg9GoVdj.d.mts → prisma-DQBSSHAB.d.mts} +2 -3
- package/dist/{queryCachePlugin-DMBnp2Q0.mjs → queryCachePlugin-B6R0d4av.mjs} +4 -5
- package/dist/{queryCachePlugin-7THaI5mt.d.mts → queryCachePlugin-Q6SYuHZ6.d.mts} +2 -3
- package/dist/{redis-D-JAeLtm.d.mts → redis-UwjEp8Ea.d.mts} +2 -3
- package/dist/{redis-stream-Bdh_vUU8.d.mts → redis-stream-CBg0upHI.d.mts} +2 -3
- package/dist/registry/index.d.mts +4 -5
- package/dist/registry/index.mjs +2 -2
- package/dist/{requestContext-QQD6ROJc.mjs → requestContext-xi6OKBL-.mjs} +1 -2
- package/dist/{schemaConverter-BwrmWroW.mjs → schemaConverter-Dtg0Kt9T.mjs} +1 -2
- package/dist/schemas/index.d.mts +1 -2
- package/dist/schemas/index.mjs +1 -2
- package/dist/scope/index.d.mts +2 -3
- package/dist/scope/index.mjs +2 -3
- package/dist/{sessionManager-jPKLbHE0.d.mts → sessionManager-D_iEHjQl.d.mts} +1 -2
- package/dist/{sse-B3c3_yZp.mjs → sse-DkqQ1uxb.mjs} +2 -3
- package/dist/testing/index.d.mts +8 -9
- package/dist/testing/index.mjs +3 -4
- package/dist/{tracing-Cc7vVQPp.d.mts → tracing-8CEbhF0w.d.mts} +1 -2
- package/dist/{typeGuards-DhMNLuvU.mjs → typeGuards-DwxA1t_L.mjs} +1 -2
- package/dist/types/index.d.mts +7 -8
- package/dist/types/index.mjs +1 -2
- package/dist/{types-CIgB7UUl.d.mts → types-B0dhNrnd.d.mts} +9 -10
- package/dist/types-Beqn1Un7.mjs +1 -2
- package/dist/types-DelU6kln.mjs +25 -0
- package/dist/{types-aYB4V7uN.d.mts → types-RLkFVgaw.d.mts} +18 -4
- package/dist/utils/index.d.mts +5 -6
- package/dist/utils/index.mjs +4 -4
- package/package.json +1 -1
- package/dist/EventTransport-BD2U0BTc.d.mts.map +0 -1
- package/dist/HookSystem-BsGV-j2l.mjs.map +0 -1
- package/dist/ResourceRegistry-DsN4KJjV.mjs.map +0 -1
- package/dist/audit/index.d.mts.map +0 -1
- package/dist/audit/index.mjs.map +0 -1
- package/dist/audited-C3T5DTUx.mjs.map +0 -1
- package/dist/auth/index.d.mts.map +0 -1
- package/dist/auth/index.mjs.map +0 -1
- package/dist/auth/redis-session.d.mts.map +0 -1
- package/dist/auth/redis-session.mjs.map +0 -1
- package/dist/betterAuthOpenApi-BrHKeSAx.mjs.map +0 -1
- package/dist/cache/index.d.mts.map +0 -1
- package/dist/cache/index.mjs.map +0 -1
- package/dist/caching-Bl28lYsR.mjs.map +0 -1
- package/dist/circuitBreaker-DeY4FCjs.mjs.map +0 -1
- package/dist/cli/commands/describe.d.mts.map +0 -1
- package/dist/cli/commands/describe.mjs.map +0 -1
- package/dist/cli/commands/docs.d.mts.map +0 -1
- package/dist/cli/commands/docs.mjs.map +0 -1
- package/dist/cli/commands/generate.d.mts.map +0 -1
- package/dist/cli/commands/generate.mjs.map +0 -1
- package/dist/cli/commands/init.d.mts.map +0 -1
- package/dist/cli/commands/init.mjs.map +0 -1
- package/dist/cli/commands/introspect.d.mts.map +0 -1
- package/dist/cli/commands/introspect.mjs.map +0 -1
- package/dist/cli/index.d.mts.map +0 -1
- package/dist/cli/index.mjs.map +0 -1
- package/dist/constants-DdXFXQtN.mjs.map +0 -1
- package/dist/createApp-CUgNqegw.mjs.map +0 -1
- package/dist/defineResource-k0_BDn8v.mjs.map +0 -1
- package/dist/discovery/index.d.mts.map +0 -1
- package/dist/discovery/index.mjs.map +0 -1
- package/dist/docs/index.d.mts.map +0 -1
- package/dist/docs/index.mjs.map +0 -1
- package/dist/elevation-BRy3yFWT.mjs.map +0 -1
- package/dist/elevation-B_2dRLVP.d.mts.map +0 -1
- package/dist/errorHandler-BbcgBmIH.d.mts.map +0 -1
- package/dist/errorHandler-C1okiriz.mjs.map +0 -1
- package/dist/errors-B9bZok84.mjs.map +0 -1
- package/dist/errors-ChKiFz62.d.mts.map +0 -1
- package/dist/eventPlugin-CTrLH3mt.d.mts.map +0 -1
- package/dist/eventPlugin-DGR_B2on.mjs.map +0 -1
- package/dist/events/index.d.mts.map +0 -1
- package/dist/events/index.mjs.map +0 -1
- package/dist/events/transports/redis-stream-entry.mjs.map +0 -1
- package/dist/events/transports/redis.d.mts.map +0 -1
- package/dist/events/transports/redis.mjs.map +0 -1
- package/dist/externalPaths-DlINfKbP.d.mts.map +0 -1
- package/dist/factory/index.d.mts.map +0 -1
- package/dist/fastifyAdapter-BkrGrlFi.d.mts.map +0 -1
- package/dist/fields-DyaDVX4J.d.mts.map +0 -1
- package/dist/fields-iagOozy0.mjs.map +0 -1
- package/dist/idempotency/index.d.mts.map +0 -1
- package/dist/idempotency/index.mjs.map +0 -1
- package/dist/idempotency/mongodb.mjs.map +0 -1
- package/dist/idempotency/redis.mjs.map +0 -1
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/integrations/event-gateway.d.mts.map +0 -1
- package/dist/integrations/event-gateway.mjs.map +0 -1
- package/dist/integrations/jobs.d.mts.map +0 -1
- package/dist/integrations/jobs.mjs.map +0 -1
- package/dist/integrations/streamline.d.mts.map +0 -1
- package/dist/integrations/streamline.mjs.map +0 -1
- package/dist/integrations/websocket.d.mts.map +0 -1
- package/dist/integrations/websocket.mjs.map +0 -1
- package/dist/interface-B01JvPVc.d.mts.map +0 -1
- package/dist/interface-CZe8IkMf.d.mts.map +0 -1
- package/dist/interface-Ch8HU9uM.d.mts.map +0 -1
- package/dist/introspectionPlugin-rFdO8ZUa.mjs.map +0 -1
- package/dist/keys-BqNejWup.mjs.map +0 -1
- package/dist/logger-Df2O2WsW.mjs.map +0 -1
- package/dist/memory-cQgelFOj.mjs.map +0 -1
- package/dist/migrations/index.d.mts.map +0 -1
- package/dist/migrations/index.mjs.map +0 -1
- package/dist/mongodb-BfJVlUJH.mjs.map +0 -1
- package/dist/mongodb-CGzRbfAK.d.mts.map +0 -1
- package/dist/mongodb-JN-9JA7K.d.mts.map +0 -1
- package/dist/openapi-G3Cw7XuM.mjs.map +0 -1
- package/dist/org/index.d.mts.map +0 -1
- package/dist/org/index.mjs.map +0 -1
- package/dist/org/types.d.mts.map +0 -1
- package/dist/permissions/index.d.mts.map +0 -1
- package/dist/permissions/index.mjs.map +0 -1
- package/dist/plugins/index.d.mts.map +0 -1
- package/dist/plugins/index.mjs.map +0 -1
- package/dist/plugins/response-cache.d.mts.map +0 -1
- package/dist/plugins/response-cache.mjs.map +0 -1
- package/dist/plugins/tracing-entry.mjs.map +0 -1
- package/dist/pluralize-CEweyOEm.mjs.map +0 -1
- package/dist/policies/index.d.mts.map +0 -1
- package/dist/policies/index.mjs.map +0 -1
- package/dist/presets/index.d.mts.map +0 -1
- package/dist/presets/index.mjs.map +0 -1
- package/dist/presets/multiTenant.d.mts.map +0 -1
- package/dist/presets/multiTenant.mjs.map +0 -1
- package/dist/presets-BITljm96.mjs.map +0 -1
- package/dist/presets-DzSMwlKj.d.mts.map +0 -1
- package/dist/prisma-DJbMt3yf.mjs.map +0 -1
- package/dist/prisma-Dg9GoVdj.d.mts.map +0 -1
- package/dist/queryCachePlugin-7THaI5mt.d.mts.map +0 -1
- package/dist/queryCachePlugin-DMBnp2Q0.mjs.map +0 -1
- package/dist/redis-D-JAeLtm.d.mts.map +0 -1
- package/dist/redis-stream-Bdh_vUU8.d.mts.map +0 -1
- package/dist/registry/index.d.mts.map +0 -1
- package/dist/requestContext-QQD6ROJc.mjs.map +0 -1
- package/dist/schemaConverter-BwrmWroW.mjs.map +0 -1
- package/dist/schemas/index.d.mts.map +0 -1
- package/dist/schemas/index.mjs.map +0 -1
- package/dist/scope/index.d.mts.map +0 -1
- package/dist/scope/index.mjs.map +0 -1
- package/dist/sessionManager-jPKLbHE0.d.mts.map +0 -1
- package/dist/sse-B3c3_yZp.mjs.map +0 -1
- package/dist/testing/index.d.mts.map +0 -1
- package/dist/testing/index.mjs.map +0 -1
- package/dist/tracing-Cc7vVQPp.d.mts.map +0 -1
- package/dist/typeGuards-DhMNLuvU.mjs.map +0 -1
- package/dist/types/index.d.mts.map +0 -1
- package/dist/types/index.mjs.map +0 -1
- package/dist/types-Beqn1Un7.mjs.map +0 -1
- package/dist/types-CIgB7UUl.d.mts.map +0 -1
- package/dist/types-aYB4V7uN.d.mts.map +0 -1
- package/dist/utils/index.d.mts.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"interface-Ch8HU9uM.d.mts","names":[],"sources":["../src/hooks/HookSystem.ts","../src/pipeline/types.ts","../src/types/repository.ts","../src/core/defineResource.ts","../src/registry/ResourceRegistry.ts","../src/types/handlers.ts","../src/core/AccessControl.ts","../src/core/BodySanitizer.ts","../src/core/QueryResolver.ts","../src/core/BaseController.ts","../src/adapters/interface.ts"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"introspectionPlugin-rFdO8ZUa.mjs","names":[],"sources":["../src/registry/introspectionPlugin.ts"],"sourcesContent":["/**\n * Introspection Plugin\n *\n * Exposes resource registry via API endpoints.\n */\n\nimport fp from 'fastify-plugin';\nimport type { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest } from 'fastify';\nimport type { IntrospectionPluginOptions, FastifyWithAuth, FastifyWithDecorators } from '../types/index.js';\n\nconst introspectionPlugin: FastifyPluginAsync<IntrospectionPluginOptions> = async (\n fastify: FastifyInstance,\n opts: IntrospectionPluginOptions = {}\n) => {\n const {\n prefix = '/_resources',\n authRoles = ['superadmin'],\n enabled = true,\n } = opts;\n\n if (!enabled) {\n fastify.log?.debug?.('Introspection plugin disabled');\n return;\n }\n\n const typedFastify = fastify as FastifyWithAuth;\n\n // Build auth middleware array using any to avoid complex Fastify type constraints\n const authMiddleware: unknown[] =\n authRoles.length > 0 && typedFastify.authenticate\n ? [\n typedFastify.authenticate,\n typedFastify.authorize?.(...authRoles),\n ].filter(Boolean)\n : [];\n\n // Instance-scoped registry access\n const getRegistry = () => (fastify as unknown as FastifyWithDecorators).arc?.registry;\n\n await fastify.register(async (instance) => {\n // GET / - Get all registered resources\n instance.get(\n '/',\n {\n preHandler: authMiddleware as never,\n },\n async (_req: FastifyRequest, _reply: FastifyReply) => {\n return getRegistry()?.getIntrospection() ?? { resources: [], stats: {}, generatedAt: new Date().toISOString() };\n }\n );\n\n // GET /stats - Get registry statistics\n instance.get(\n '/stats',\n {\n preHandler: authMiddleware as never,\n },\n async (_req: FastifyRequest, _reply: FastifyReply) => {\n return getRegistry()?.getStats() ?? { totalResources: 0, byModule: {}, presetUsage: {}, totalRoutes: 0, totalEvents: 0 };\n }\n );\n\n // GET /:name - Get resource by name\n instance.get<{ Params: { name: string } }>(\n '/:name',\n {\n schema: {\n params: {\n type: 'object' as const,\n properties: {\n name: { type: 'string' as const },\n },\n required: ['name' as const],\n },\n },\n preHandler: authMiddleware as never,\n },\n async (req, reply: FastifyReply) => {\n const resource = getRegistry()?.get(req.params.name);\n if (!resource) {\n return reply.code(404).send({\n error: `Resource '${req.params.name}' not found`,\n });\n }\n return resource;\n }\n );\n }, { prefix });\n\n fastify.log?.debug?.(`Introspection API at ${prefix}`);\n};\n\nexport default fp(introspectionPlugin, { name: 'arc-introspection' });\n\nexport { introspectionPlugin };\nexport type { IntrospectionPluginOptions };\n"],"mappings":";;;;;;;;AAUA,MAAM,sBAAsE,OAC1E,SACA,OAAmC,EAAE,KAClC;CACH,MAAM,EACJ,SAAS,eACT,YAAY,CAAC,aAAa,EAC1B,UAAU,SACR;AAEJ,KAAI,CAAC,SAAS;AACZ,UAAQ,KAAK,QAAQ,gCAAgC;AACrD;;CAGF,MAAM,eAAe;CAGrB,MAAM,iBACJ,UAAU,SAAS,KAAK,aAAa,eACjC,CACE,aAAa,cACb,aAAa,YAAY,GAAG,UAAU,CACvC,CAAC,OAAO,QAAQ,GACjB,EAAE;CAGR,MAAM,oBAAqB,QAA6C,KAAK;AAE7E,OAAM,QAAQ,SAAS,OAAO,aAAa;AAEzC,WAAS,IACP,KACA,EACE,YAAY,gBACb,EACD,OAAO,MAAsB,WAAyB;AACpD,UAAO,aAAa,EAAE,kBAAkB,IAAI;IAAE,WAAW,EAAE;IAAE,OAAO,EAAE;IAAE,8BAAa,IAAI,MAAM,EAAC,aAAa;IAAE;IAElH;AAGD,WAAS,IACP,UACA,EACE,YAAY,gBACb,EACD,OAAO,MAAsB,WAAyB;AACpD,UAAO,aAAa,EAAE,UAAU,IAAI;IAAE,gBAAgB;IAAG,UAAU,EAAE;IAAE,aAAa,EAAE;IAAE,aAAa;IAAG,aAAa;IAAG;IAE3H;AAGD,WAAS,IACP,UACA;GACE,QAAQ,EACN,QAAQ;IACN,MAAM;IACN,YAAY,EACV,MAAM,EAAE,MAAM,UAAmB,EAClC;IACD,UAAU,CAAC,OAAgB;IAC5B,EACF;GACD,YAAY;GACb,EACD,OAAO,KAAK,UAAwB;GAClC,MAAM,WAAW,aAAa,EAAE,IAAI,IAAI,OAAO,KAAK;AACpD,OAAI,CAAC,SACH,QAAO,MAAM,KAAK,IAAI,CAAC,KAAK,EAC1B,OAAO,aAAa,IAAI,OAAO,KAAK,cACrC,CAAC;AAEJ,UAAO;IAEV;IACA,EAAE,QAAQ,CAAC;AAEd,SAAQ,KAAK,QAAQ,wBAAwB,SAAS;;AAGxD,kCAAe,GAAG,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"keys-BqNejWup.mjs","names":[],"sources":["../src/cache/keys.ts"],"sourcesContent":["/**\r\n * Cache Key Utilities\r\n *\r\n * Deterministic, scope-safe key generation for QueryCache.\r\n * Keys include resource version, operation, params hash, and user/org scope\r\n * to ensure multi-tenant isolation and O(1) version-based invalidation.\r\n */\r\n\r\n/** Build a deterministic cache key for a query */\r\nexport function buildQueryKey(\r\n resource: string,\r\n operation: string,\r\n resourceVersion: number,\r\n params: Record<string, unknown>,\r\n userId?: string,\r\n orgId?: string,\r\n): string {\r\n const hash = hashParams(params);\r\n const uid = userId ?? 'anon';\r\n const oid = orgId ?? 'pub';\r\n return `arc:${resource}:${resourceVersion}:${operation}:${hash}:u=${uid}:o=${oid}`;\r\n}\r\n\r\n/** Resource version key — stored in CacheStore, bumped on mutations */\r\nexport function versionKey(resource: string): string {\r\n return `arc:ver:${resource}`;\r\n}\r\n\r\n/** Tag version key — stored in CacheStore, bumped on cross-resource invalidation */\r\nexport function tagVersionKey(tag: string): string {\r\n return `arc:tagver:${tag}`;\r\n}\r\n\r\n/**\r\n * Stable hash for query params.\r\n * Sorts keys recursively, serializes to JSON, then applies djb2 hash.\r\n * Returns hex string.\r\n */\r\nexport function hashParams(params: Record<string, unknown>): string {\r\n const stable = stableStringify(params);\r\n return djb2(stable).toString(36);\r\n}\r\n\r\nfunction stableStringify(value: unknown): string {\r\n if (value === null || value === undefined) return '';\r\n if (typeof value !== 'object') return String(value);\r\n if (Array.isArray(value)) return '[' + value.map(stableStringify).join(',') + ']';\r\n\r\n const sorted = Object.keys(value as Record<string, unknown>).sort();\r\n return '{' + sorted.map(k => k + ':' + stableStringify((value as Record<string, unknown>)[k])).join(',') + '}';\r\n}\r\n\r\nfunction djb2(str: string): number {\r\n let hash = 5381;\r\n for (let i = 0; i < str.length; i++) {\r\n hash = ((hash << 5) + hash + str.charCodeAt(i)) >>> 0;\r\n }\r\n return hash;\r\n}\r\n"],"mappings":";;;;;;;;;AASA,SAAgB,cACd,UACA,WACA,iBACA,QACA,QACA,OACQ;AAIR,QAAO,OAAO,SAAS,GAAG,gBAAgB,GAAG,UAAU,GAH1C,WAAW,OAAO,CAGgC,KAFnD,UAAU,OAEkD,KAD5D,SAAS;;;AAKvB,SAAgB,WAAW,UAA0B;AACnD,QAAO,WAAW;;;AAIpB,SAAgB,cAAc,KAAqB;AACjD,QAAO,cAAc;;;;;;;AAQvB,SAAgB,WAAW,QAAyC;AAElE,QAAO,KADQ,gBAAgB,OAAO,CACnB,CAAC,SAAS,GAAG;;AAGlC,SAAS,gBAAgB,OAAwB;AAC/C,KAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,KAAI,OAAO,UAAU,SAAU,QAAO,OAAO,MAAM;AACnD,KAAI,MAAM,QAAQ,MAAM,CAAE,QAAO,MAAM,MAAM,IAAI,gBAAgB,CAAC,KAAK,IAAI,GAAG;AAG9E,QAAO,MADQ,OAAO,KAAK,MAAiC,CAAC,MAAM,CAC/C,KAAI,MAAK,IAAI,MAAM,gBAAiB,MAAkC,GAAG,CAAC,CAAC,KAAK,IAAI,GAAG;;AAG7G,SAAS,KAAK,KAAqB;CACjC,IAAI,OAAO;AACX,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,IAC9B,SAAS,QAAQ,KAAK,OAAO,IAAI,WAAW,EAAE,KAAM;AAEtD,QAAO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger-Df2O2WsW.mjs","names":[],"sources":["../src/logger/index.ts"],"sourcesContent":["/**\n * Arc Logger — Centralized debug & warning system\n *\n * Lightweight, zero-dependency logger for Arc framework internals.\n * Inspired by the `debug` npm package — disabled by default, opt-in via\n * environment variable or `createApp({ debug })` option.\n *\n * @example\n * ```typescript\n * // Enable via env var\n * ARC_DEBUG=1 node server.js // all modules\n * ARC_DEBUG=scope,elevation node server.js // specific modules\n *\n * // Enable via createApp\n * const app = await createApp({ debug: true });\n * const app = await createApp({ debug: 'scope,elevation' });\n *\n * // Suppress warnings (not recommended)\n * ARC_SUPPRESS_WARNINGS=1 node server.js\n *\n * // Framework internals use:\n * import { arcLog } from '../logger/index.js';\n * const log = arcLog('elevation');\n * log.debug('Elevation applied', { userId });\n * log.warn('Something unexpected');\n * ```\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ArcLoggerOptions {\n /**\n * Enable debug output.\n * - `true` or `'*'` — all modules\n * - `string` — comma-separated module names (e.g., `'scope,elevation'`)\n * - `false` — disabled (default)\n */\n debug?: boolean | string;\n\n /**\n * Custom log writer. Defaults to `console`.\n * Useful for routing Arc logs into Fastify's pino logger or test fixtures.\n */\n writer?: ArcLogWriter;\n}\n\nexport interface ArcLogWriter {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\nexport interface ArcLogger {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\n// ============================================================================\n// Global State\n// ============================================================================\n\nlet globalOptions: ArcLoggerOptions = {};\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Configure the Arc logger globally.\n *\n * Called automatically by `createApp({ debug })`, but can also be\n * called manually for standalone usage outside of `createApp`.\n */\nexport function configureArcLogger(options: ArcLoggerOptions): void {\n globalOptions = { ...options };\n}\n\n/**\n * Create a module-scoped logger.\n *\n * Debug and info messages are gated by the `ARC_DEBUG` env var or\n * `createApp({ debug })` option. Warnings always show (unless\n * `ARC_SUPPRESS_WARNINGS=1`). Errors always show.\n *\n * @param module - Module name (e.g., 'scope', 'elevation', 'sse', 'preset')\n * @returns Logger instance for that module\n *\n * @example\n * ```typescript\n * const log = arcLog('elevation');\n * log.debug('Checking elevation header');\n * log.warn('No authenticate decorator found');\n * ```\n */\nexport function arcLog(module: string): ArcLogger {\n const prefix = `[arc:${module}]`;\n\n return {\n debug(...args: unknown[]) {\n if (isDebugEnabled(module)) {\n getWriter().debug(prefix, ...args);\n }\n },\n info(...args: unknown[]) {\n if (isDebugEnabled(module)) {\n getWriter().info(prefix, ...args);\n }\n },\n warn(...args: unknown[]) {\n if (isSuppressed()) return;\n getWriter().warn(prefix, ...args);\n },\n error(...args: unknown[]) {\n getWriter().error(prefix, ...args);\n },\n };\n}\n\n// ============================================================================\n// Internals\n// ============================================================================\n\nfunction getWriter(): ArcLogWriter {\n return globalOptions.writer ?? console;\n}\n\nfunction isDebugEnabled(module: string): boolean {\n // Priority 1: Programmatic config\n const configDebug = globalOptions.debug;\n if (configDebug !== undefined && configDebug !== false) {\n return matchesModule(configDebug, module);\n }\n\n // Priority 2: Environment variable\n const envDebug = typeof process !== 'undefined' ? process.env?.ARC_DEBUG : undefined;\n if (envDebug) {\n return matchesModule(envDebug, module);\n }\n\n return false;\n}\n\nfunction matchesModule(debug: boolean | string, module: string): boolean {\n if (debug === true) return true;\n if (typeof debug === 'string') {\n const normalized = debug.trim();\n if (normalized === '1' || normalized === 'true' || normalized === '*') return true;\n return normalized.split(',').map((s) => s.trim()).includes(module);\n }\n return false;\n}\n\nfunction isSuppressed(): boolean {\n const env = typeof process !== 'undefined' ? process.env?.ARC_SUPPRESS_WARNINGS : undefined;\n return env === '1' || env === 'true';\n}\n"],"mappings":";;;;;;;AAkEA,IAAI,gBAAkC,EAAE;;;;;;;AAYxC,SAAgB,mBAAmB,SAAiC;AAClE,iBAAgB,EAAE,GAAG,SAAS;;;;;;;;;;;;;;;;;;;AAoBhC,SAAgB,OAAO,QAA2B;CAChD,MAAM,SAAS,QAAQ,OAAO;AAE9B,QAAO;EACL,MAAM,GAAG,MAAiB;AACxB,OAAI,eAAe,OAAO,CACxB,YAAW,CAAC,MAAM,QAAQ,GAAG,KAAK;;EAGtC,KAAK,GAAG,MAAiB;AACvB,OAAI,eAAe,OAAO,CACxB,YAAW,CAAC,KAAK,QAAQ,GAAG,KAAK;;EAGrC,KAAK,GAAG,MAAiB;AACvB,OAAI,cAAc,CAAE;AACpB,cAAW,CAAC,KAAK,QAAQ,GAAG,KAAK;;EAEnC,MAAM,GAAG,MAAiB;AACxB,cAAW,CAAC,MAAM,QAAQ,GAAG,KAAK;;EAErC;;AAOH,SAAS,YAA0B;AACjC,QAAO,cAAc,UAAU;;AAGjC,SAAS,eAAe,QAAyB;CAE/C,MAAM,cAAc,cAAc;AAClC,KAAI,gBAAgB,UAAa,gBAAgB,MAC/C,QAAO,cAAc,aAAa,OAAO;CAI3C,MAAM,WAAW,OAAO,YAAY,cAAc,QAAQ,KAAK,YAAY;AAC3E,KAAI,SACF,QAAO,cAAc,UAAU,OAAO;AAGxC,QAAO;;AAGT,SAAS,cAAc,OAAyB,QAAyB;AACvE,KAAI,UAAU,KAAM,QAAO;AAC3B,KAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,aAAa,MAAM,MAAM;AAC/B,MAAI,eAAe,OAAO,eAAe,UAAU,eAAe,IAAK,QAAO;AAC9E,SAAO,WAAW,MAAM,IAAI,CAAC,KAAK,MAAM,EAAE,MAAM,CAAC,CAAC,SAAS,OAAO;;AAEpE,QAAO;;AAGT,SAAS,eAAwB;CAC/B,MAAM,MAAM,OAAO,YAAY,cAAc,QAAQ,KAAK,wBAAwB;AAClF,QAAO,QAAQ,OAAO,QAAQ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"memory-cQgelFOj.mjs","names":[],"sources":["../src/cache/memory.ts"],"sourcesContent":["import type { CacheLogger, CacheSetOptions, CacheStats, CacheStore } from './interface.js';\n\ninterface MemoryEntry<TValue> {\n value: TValue;\n size: number;\n expiresAt: number;\n}\n\nexport interface MemoryCacheStoreOptions {\n /** Default TTL in milliseconds (default: 60_000) */\n defaultTtlMs?: number;\n /** Hard upper bound for entries (default: 1000) */\n maxEntries?: number;\n /** Background cleanup interval in milliseconds (default: 30_000) */\n cleanupIntervalMs?: number;\n /**\n * Maximum serialized entry size in bytes (default: 256 KiB).\n * Oversized entries are skipped to prevent memory pressure.\n */\n maxEntryBytes?: number;\n /**\n * Total memory budget in bytes (default: 50 MiB).\n * When exceeded, LRU entries are evicted until usage drops below watermark.\n * Set to 0 to disable (rely on maxEntries only).\n */\n maxMemoryBytes?: number;\n /**\n * Eviction watermark as fraction of maxMemoryBytes (default: 0.9).\n * When memory exceeds budget, evict until usage drops to budget * watermark.\n */\n evictionWatermark?: number;\n /** Logger for warnings/errors (default: console) */\n logger?: CacheLogger;\n}\n\n/**\n * In-memory LRU+TTL cache store with hard entry cap and memory budget.\n * - LRU eviction when `maxEntries` or `maxMemoryBytes` is reached\n * - TTL expiration on read + periodic cleanup\n * - Entry size guard to avoid runaway memory usage\n * - Stats tracking for observability\n */\nexport class MemoryCacheStore<TValue = unknown> implements CacheStore<TValue> {\n readonly name = 'memory-cache';\n\n private readonly cache = new Map<string, MemoryEntry<TValue>>();\n private readonly defaultTtlMs: number;\n private readonly maxEntries: number;\n private readonly maxEntryBytes: number;\n private readonly maxMemoryBytes: number;\n private readonly evictionWatermark: number;\n private readonly logger: CacheLogger;\n private readonly cleanupTimer: ReturnType<typeof setInterval>;\n\n private currentBytes = 0;\n private _hits = 0;\n private _misses = 0;\n private _evictions = 0;\n\n constructor(options: MemoryCacheStoreOptions = {}) {\n this.defaultTtlMs = options.defaultTtlMs ?? 60_000;\n this.maxEntries = clamp(options.maxEntries ?? 1000, 1, 100_000);\n this.maxEntryBytes = clamp(options.maxEntryBytes ?? 256 * 1024, 1024, 10 * 1024 * 1024);\n this.maxMemoryBytes = options.maxMemoryBytes ?? 50 * 1024 * 1024; // 50 MiB\n this.evictionWatermark = clamp(options.evictionWatermark ?? 0.9, 0.5, 1);\n this.logger = options.logger ?? console;\n\n const cleanupIntervalMs = clamp(options.cleanupIntervalMs ?? 30_000, 1000, 10 * 60 * 1000);\n this.cleanupTimer = setInterval(() => this.cleanupExpired(), cleanupIntervalMs);\n if (this.cleanupTimer.unref) this.cleanupTimer.unref();\n }\n\n async get(key: string): Promise<TValue | undefined> {\n const entry = this.cache.get(key);\n if (!entry) {\n this._misses++;\n return undefined;\n }\n\n if (entry.expiresAt <= Date.now()) {\n this.removeEntry(key, entry);\n this._misses++;\n return undefined;\n }\n\n // LRU refresh: move to most-recent position\n this.cache.delete(key);\n this.cache.set(key, entry);\n this._hits++;\n return entry.value;\n }\n\n async set(key: string, value: TValue, options: CacheSetOptions = {}): Promise<void> {\n const ttlMs = options.ttlMs ?? this.defaultTtlMs;\n if (!Number.isFinite(ttlMs) || ttlMs <= 0) return;\n\n const size = this.estimateSize(value);\n if (size > this.maxEntryBytes) {\n this.logger.warn(\n `[MemoryCacheStore] Skipping oversized entry for key '${key}' (${size} bytes > ${this.maxEntryBytes} bytes)`\n );\n return;\n }\n\n // Remove existing entry first (adjust bytes)\n const existing = this.cache.get(key);\n if (existing) {\n this.currentBytes -= existing.size;\n this.cache.delete(key);\n }\n\n this.cache.set(key, { value, size, expiresAt: Date.now() + ttlMs });\n this.currentBytes += size;\n\n this.evictToLimit();\n if (this.maxMemoryBytes > 0) this.evictToMemoryLimit();\n }\n\n async delete(key: string): Promise<void> {\n const entry = this.cache.get(key);\n if (entry) this.removeEntry(key, entry);\n }\n\n async clear(): Promise<void> {\n this.cache.clear();\n this.currentBytes = 0;\n }\n\n async close(): Promise<void> {\n clearInterval(this.cleanupTimer);\n this.cache.clear();\n this.currentBytes = 0;\n }\n\n stats(): CacheStats {\n return {\n entries: this.cache.size,\n memoryBytes: this.currentBytes,\n hits: this._hits,\n misses: this._misses,\n evictions: this._evictions,\n };\n }\n\n private removeEntry(key: string, entry: MemoryEntry<TValue>): void {\n this.cache.delete(key);\n this.currentBytes -= entry.size;\n }\n\n private evictToLimit(): void {\n while (this.cache.size > this.maxEntries) {\n const oldestKey = this.cache.keys().next().value as string | undefined;\n if (!oldestKey) break;\n const entry = this.cache.get(oldestKey)!;\n this.removeEntry(oldestKey, entry);\n this._evictions++;\n }\n }\n\n private evictToMemoryLimit(): void {\n const target = this.maxMemoryBytes * this.evictionWatermark;\n while (this.currentBytes > this.maxMemoryBytes && this.cache.size > 0) {\n const oldestKey = this.cache.keys().next().value as string | undefined;\n if (!oldestKey) break;\n const entry = this.cache.get(oldestKey)!;\n this.removeEntry(oldestKey, entry);\n this._evictions++;\n if (this.currentBytes <= target) break;\n }\n }\n\n private cleanupExpired(): void {\n const now = Date.now();\n for (const [key, entry] of this.cache.entries()) {\n if (entry.expiresAt <= now) {\n this.removeEntry(key, entry);\n }\n }\n }\n\n private estimateSize(value: TValue): number {\n try {\n const json = JSON.stringify(value);\n if (!json) return 0;\n return Buffer.byteLength(json, 'utf8');\n } catch {\n return this.maxEntryBytes + 1;\n }\n }\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\nexport default MemoryCacheStore;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/migrations/index.ts"],"mappings":";;;UAgCiB,SAAA;EAuBU;EArBzB,OAAA;EAqBY;EAlBZ,QAAA;EAkB6C;EAf7C,WAAA;EAkBe;;;EAbf,EAAA,GAAK,EAAA,EAAI,QAAA,CAAS,KAAA,CAAM,EAAA,KAAO,OAAA;EAc/B;;;EATA,IAAA,GAAO,EAAA,EAAI,QAAA,CAAS,KAAA,CAAM,EAAA,KAAO,OAAA;EAYtB;;;EAPX,QAAA,IAAY,EAAA,EAAI,QAAA,CAAS,KAAA,CAAM,EAAA,KAAO,OAAA;AAAA;AAAA,UAGvB,eAAA;EACf,OAAA;EACA,QAAA;EACA,WAAA;EACA,SAAA,EAAW,IAAA;EACX,aAAA;AAAA;;AAeF;;iBATgB,eAAA,CAAgB,SAAA,EAAW,SAAA,GAAY,SAAA;;;;;;cAS1C,eAAA;EAAA,iBACM,cAAA;EAAA,iBAEA,EAAA;cAEL,EAAA,EAAI,QAAA,CAAS,KAAA,CAAM,EAAA;EAuGQ;;;EAhGjC,EAAA,CAAG,UAAA,EAAY,SAAA,KAAc,OAAA;EAyGQ;;;EA/ErC,IAAA,CAAK,UAAA,EAAY,SAAA,KAAc,OAAA;EAnCpB;;;EAmEX,MAAA,CAAO,UAAA,EAAY,SAAA,IAAa,aAAA,WAAwB,OAAA;EAjE/B;;;EA8FzB,oBAAA,CAAA,GAAwB,OAAA,CAAQ,eAAA;EAvF7B;;;EAgGH,oBAAA,CAAqB,UAAA,EAAY,SAAA,KAAc,OAAA,CAAQ,SAAA;EAtElD;;;EA+EL,UAAA,CAAW,UAAA,EAAY,SAAA,KAAc,OAAA;EA/C9B;;;EAAA,QAuDC,YAAA;EA1BgB;;;EAAA,QA4EhB,eAAA;EAnEa;;;EAAA,QAiFb,eAAA;AAAA;;;;UAYC,aAAA;EACf,OAAA;EACA,UAAA,EAAY,SAAA;AAAA;AAFd;;;;;;;;;AAgBA;;AAhBA,iBAgBgB,iBAAA,CACd,OAAA,UACA,UAAA,EAAY,SAAA,KACX,aAAA;;;;cAOU,iBAAA;EAAA,QACH,UAAA;EARM;;AAOhB;EAME,QAAA,CAAS,SAAA,EAAW,SAAA;;;;EAUpB,YAAA,CAAa,UAAA,EAAY,SAAA;EAgBf;;;EAPV,cAAA,CAAe,QAAA,WAAmB,SAAA;EAxB1B;;;EA+BR,MAAA,CAAA,GAAU,SAAA;EAhBV;;;EA2BA,GAAA,CAAI,QAAA,UAAkB,OAAA,WAAkB,SAAA;EAlBzB;;;EA0Bf,KAAA,CAAA;AAAA;;;;cAQW,iBAAA,EAAiB,iBAAA;;;AAA9B;cAKa,gBAAA;;;;oCAIqB,OAAA,UAAiB,OAAA,aAAiB,SAAA;EAgEnE;;;iCAhD8B,SAAA,UAAmB,YAAA,cAAuB,SAAA;EAkBpB;;;oCAAnB,SAAA,aAAmB,SAAA;EAiBgD;;;oCAAnE,MAAA,EAAU,MAAA,kBAAsB,OAAA,GAAY,MAAA,sBAAuB,SAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/migrations/index.ts"],"sourcesContent":["/**\n * Schema Versioning and Migrations System\n *\n * Manages database schema changes over time with version tracking.\n * Supports forward migrations, rollbacks, and schema compatibility layers.\n *\n * @example\n * import { defineMigration, MigrationRunner } from '@classytic/arc/migrations';\n *\n * const productV2 = defineMigration({\n * version: 2,\n * resource: 'product',\n * up: async (db) => {\n * await db.collection('products').updateMany(\n * {},\n * { $rename: { 'oldField': 'newField' } }\n * );\n * },\n * down: async (db) => {\n * await db.collection('products').updateMany(\n * {},\n * { $rename: { 'newField': 'oldField' } }\n * );\n * },\n * });\n *\n * const runner = new MigrationRunner(mongoose.connection.db);\n * await runner.up(); // Run all pending migrations\n */\n\nimport mongoose, { type Connection } from 'mongoose';\n\nexport interface Migration {\n /** Migration version (sequential number) */\n version: number;\n\n /** Resource name this migration applies to */\n resource: string;\n\n /** Description of the migration */\n description?: string;\n\n /**\n * Forward migration (apply schema change)\n */\n up: (db: mongoose.mongo.Db) => Promise<void>;\n\n /**\n * Backward migration (revert schema change)\n */\n down: (db: mongoose.mongo.Db) => Promise<void>;\n\n /**\n * Optional validation that data is compatible after migration\n */\n validate?: (db: mongoose.mongo.Db) => Promise<boolean>;\n}\n\nexport interface MigrationRecord {\n version: number;\n resource: string;\n description?: string;\n appliedAt: Date;\n executionTime: number;\n}\n\n/**\n * Define a migration\n */\nexport function defineMigration(migration: Migration): Migration {\n return migration;\n}\n\n/**\n * Migration Runner\n *\n * Manages execution of migrations with tracking and rollback support.\n */\nexport class MigrationRunner {\n private readonly collectionName = '_migrations';\n\n private readonly db: mongoose.mongo.Db;\n\n constructor(db: mongoose.mongo.Db) {\n this.db = db;\n }\n\n /**\n * Run all pending migrations\n */\n async up(migrations: Migration[]): Promise<void> {\n const applied = await this.getAppliedMigrations();\n const appliedVersions = new Set(applied.map((m) => `${m.resource}:${m.version}`));\n\n // Sort migrations by version\n const pending = migrations\n .filter((m) => !appliedVersions.has(`${m.resource}:${m.version}`))\n .sort((a, b) => a.version - b.version);\n\n if (pending.length === 0) {\n console.log('No pending migrations');\n return;\n }\n\n console.log(`Running ${pending.length} migration(s)...\\n`);\n\n for (const migration of pending) {\n await this.runMigration(migration, 'up');\n }\n\n console.log('\\nAll migrations completed successfully');\n }\n\n /**\n * Rollback last migration\n */\n async down(migrations: Migration[]): Promise<void> {\n const applied = await this.getAppliedMigrations();\n if (applied.length === 0) {\n console.log('No migrations to rollback');\n return;\n }\n\n // Get last applied migration\n const last = applied[applied.length - 1];\n if (!last) {\n console.log('No migrations to rollback');\n return;\n }\n\n const migration = migrations.find(\n (m) => m.resource === last.resource && m.version === last.version\n );\n\n if (!migration) {\n throw new Error(\n `Migration ${last.resource}:${last.version} not found in migration files`\n );\n }\n\n console.log(`Rolling back ${migration.resource} v${migration.version}...`);\n await this.runMigration(migration, 'down', true);\n console.log('Rollback completed');\n }\n\n /**\n * Rollback to specific version\n */\n async downTo(migrations: Migration[], targetVersion: number): Promise<void> {\n const applied = await this.getAppliedMigrations();\n const toRollback = applied.filter((m) => m.version > targetVersion).reverse();\n\n if (toRollback.length === 0) {\n console.log(`Already at or below version ${targetVersion}`);\n return;\n }\n\n console.log(`Rolling back ${toRollback.length} migration(s)...\\n`);\n\n for (const record of toRollback) {\n const migration = migrations.find(\n (m) => m.resource === record.resource && m.version === record.version\n );\n\n if (!migration) {\n throw new Error(`Migration ${record.resource}:${record.version} not found`);\n }\n\n await this.runMigration(migration, 'down', true);\n }\n\n console.log('\\nRollback completed');\n }\n\n /**\n * Get all applied migrations\n */\n async getAppliedMigrations(): Promise<MigrationRecord[]> {\n const collection = this.db.collection(this.collectionName);\n const records = await collection.find({}).sort({ appliedAt: 1 }).toArray();\n return records as unknown as MigrationRecord[];\n }\n\n /**\n * Get pending migrations\n */\n async getPendingMigrations(migrations: Migration[]): Promise<Migration[]> {\n const applied = await this.getAppliedMigrations();\n const appliedVersions = new Set(applied.map((m) => `${m.resource}:${m.version}`));\n return migrations.filter((m) => !appliedVersions.has(`${m.resource}:${m.version}`));\n }\n\n /**\n * Check if migrations are up to date\n */\n async isUpToDate(migrations: Migration[]): Promise<boolean> {\n const pending = await this.getPendingMigrations(migrations);\n return pending.length === 0;\n }\n\n /**\n * Run a single migration\n */\n private async runMigration(\n migration: Migration,\n direction: 'up' | 'down',\n isRollback = false\n ): Promise<void> {\n const start = Date.now();\n const action = direction === 'up' ? 'Applying' : 'Rolling back';\n\n console.log(\n `${action} ${migration.resource} v${migration.version}${migration.description ? `: ${migration.description}` : ''}...`\n );\n\n try {\n // Run migration\n if (direction === 'up') {\n await migration.up(this.db);\n\n // Validate if provided\n if (migration.validate) {\n const valid = await migration.validate(this.db);\n if (!valid) {\n throw new Error('Migration validation failed');\n }\n }\n\n // Record migration\n await this.recordMigration(migration, Date.now() - start);\n } else {\n await migration.down(this.db);\n\n // Remove record\n if (isRollback) {\n await this.removeMigration(migration);\n }\n }\n\n const duration = Date.now() - start;\n console.log(`✅ ${migration.resource} v${migration.version} (${duration}ms)`);\n } catch (error) {\n console.error(\n `❌ ${migration.resource} v${migration.version} failed:`,\n (error as Error).message\n );\n throw error;\n }\n }\n\n /**\n * Record a completed migration\n */\n private async recordMigration(migration: Migration, executionTime: number): Promise<void> {\n const collection = this.db.collection(this.collectionName);\n await collection.insertOne({\n version: migration.version,\n resource: migration.resource,\n description: migration.description,\n appliedAt: new Date(),\n executionTime,\n });\n }\n\n /**\n * Remove a migration record\n */\n private async removeMigration(migration: Migration): Promise<void> {\n const collection = this.db.collection(this.collectionName);\n await collection.deleteOne({\n version: migration.version,\n resource: migration.resource,\n });\n }\n}\n\n/**\n * Schema version definition for resources\n */\nexport interface SchemaVersion {\n version: number;\n migrations: Migration[];\n}\n\n/**\n * Add versioning to resource definition\n *\n * @example\n * export default defineResource({\n * name: 'product',\n * version: 2,\n * migrations: [productV1ToV2Migration],\n * // ... rest of resource definition\n * });\n */\nexport function withSchemaVersion(\n version: number,\n migrations: Migration[]\n): SchemaVersion {\n return { version, migrations };\n}\n\n/**\n * Global migration registry\n */\nexport class MigrationRegistry {\n private migrations: Map<string, Migration[]> = new Map();\n\n /**\n * Register a migration\n */\n register(migration: Migration): void {\n const existing = this.migrations.get(migration.resource) || [];\n existing.push(migration);\n existing.sort((a, b) => a.version - b.version);\n this.migrations.set(migration.resource, existing);\n }\n\n /**\n * Register multiple migrations\n */\n registerMany(migrations: Migration[]): void {\n for (const migration of migrations) {\n this.register(migration);\n }\n }\n\n /**\n * Get all migrations for a resource\n */\n getForResource(resource: string): Migration[] {\n return this.migrations.get(resource) || [];\n }\n\n /**\n * Get all migrations\n */\n getAll(): Migration[] {\n const all: Migration[] = [];\n for (const migrations of this.migrations.values()) {\n all.push(...migrations);\n }\n return all.sort((a, b) => a.version - b.version);\n }\n\n /**\n * Get migration by resource and version\n */\n get(resource: string, version: number): Migration | undefined {\n const migrations = this.migrations.get(resource) || [];\n return migrations.find((m) => m.version === version);\n }\n\n /**\n * Clear all registrations\n */\n clear(): void {\n this.migrations.clear();\n }\n}\n\n/**\n * Global migration registry instance\n */\nexport const migrationRegistry = new MigrationRegistry();\n\n/**\n * Common migration helpers\n */\nexport const migrationHelpers = {\n /**\n * Rename a field across all documents\n */\n renameField: (collection: string, oldName: string, newName: string) =>\n defineMigration({\n version: 0,\n resource: collection,\n description: `Rename ${oldName} to ${newName}`,\n up: async (db) => {\n await db.collection(collection).updateMany({}, { $rename: { [oldName]: newName } });\n },\n down: async (db) => {\n await db.collection(collection).updateMany({}, { $rename: { [newName]: oldName } });\n },\n }),\n\n /**\n * Add a new field with default value\n */\n addField: (collection: string, fieldName: string, defaultValue: unknown) =>\n defineMigration({\n version: 0,\n resource: collection,\n description: `Add ${fieldName} field`,\n up: async (db) => {\n await db\n .collection(collection)\n .updateMany({ [fieldName]: { $exists: false } }, { $set: { [fieldName]: defaultValue } });\n },\n down: async (db) => {\n await db.collection(collection).updateMany({}, { $unset: { [fieldName]: '' } });\n },\n }),\n\n /**\n * Remove a field\n */\n removeField: (collection: string, fieldName: string) =>\n defineMigration({\n version: 0,\n resource: collection,\n description: `Remove ${fieldName} field`,\n up: async (db) => {\n await db.collection(collection).updateMany({}, { $unset: { [fieldName]: '' } });\n },\n down: async (db) => {\n // Cannot restore data - this is destructive\n console.warn(`Cannot restore ${fieldName} field - data was deleted`);\n },\n }),\n\n /**\n * Create an index\n */\n createIndex: (collection: string, fields: Record<string, 1 | -1>, options?: Record<string, unknown>) =>\n defineMigration({\n version: 0,\n resource: collection,\n description: `Create index on ${Object.keys(fields).join(', ')}`,\n up: async (db) => {\n await db.collection(collection).createIndex(fields, options);\n },\n down: async (db) => {\n const indexName = typeof options?.name === 'string' ? options.name : Object.keys(fields).join('_');\n await db.collection(collection).dropIndex(indexName);\n },\n }),\n};\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mongodb-BfJVlUJH.mjs","names":[],"sources":["../src/audit/stores/mongodb.ts"],"sourcesContent":["/**\n * MongoDB Audit Store\n *\n * Persists audit logs to MongoDB collection with TTL support.\n * Suitable for production use.\n */\n\nimport type { AuditEntry, AuditQueryOptions, AuditStore } from './interface.js';\n\nexport interface MongoAuditStoreOptions {\n /** MongoDB connection or mongoose instance */\n connection: MongoConnection;\n /** Collection name (default: 'audit_logs') */\n collection?: string;\n /** TTL in days (default: 90, 0 = no expiry) */\n ttlDays?: number;\n}\n\n// Minimal MongoDB types to avoid mongoose dependency\nexport interface MongoConnection {\n collection: (name: string) => MongoCollection;\n}\n\ninterface MongoCollection {\n insertOne: (doc: Record<string, unknown>) => Promise<unknown>;\n find: (query: Record<string, unknown>) => MongoCursor;\n createIndex: (spec: Record<string, unknown>, options?: Record<string, unknown>) => Promise<unknown>;\n}\n\ninterface MongoCursor {\n sort: (spec: Record<string, unknown>) => MongoCursor;\n skip: (n: number) => MongoCursor;\n limit: (n: number) => MongoCursor;\n toArray: () => Promise<Record<string, unknown>[]>;\n}\n\nexport class MongoAuditStore implements AuditStore {\n readonly name = 'mongodb';\n private collection: MongoCollection;\n private initialized = false;\n private ttlDays: number;\n\n private options: MongoAuditStoreOptions;\n\n constructor(options: MongoAuditStoreOptions) {\n this.options = options;\n const collectionName = options.collection ?? 'audit_logs';\n this.collection = options.connection.collection(collectionName);\n this.ttlDays = options.ttlDays ?? 90;\n }\n\n private async ensureIndexes(): Promise<void> {\n if (this.initialized) return;\n\n try {\n // Compound index for common queries\n await this.collection.createIndex({\n resource: 1,\n documentId: 1,\n timestamp: -1,\n });\n\n // Index for user queries\n await this.collection.createIndex({ userId: 1, timestamp: -1 });\n\n // Index for org queries\n await this.collection.createIndex({ organizationId: 1, timestamp: -1 });\n\n // TTL index for automatic cleanup\n if (this.ttlDays > 0) {\n await this.collection.createIndex(\n { timestamp: 1 },\n { expireAfterSeconds: this.ttlDays * 24 * 60 * 60 }\n );\n }\n\n this.initialized = true;\n } catch {\n // Indexes may already exist, ignore errors\n this.initialized = true;\n }\n }\n\n async log(entry: AuditEntry): Promise<void> {\n await this.ensureIndexes();\n\n await this.collection.insertOne({\n _id: entry.id,\n resource: entry.resource,\n documentId: entry.documentId,\n action: entry.action,\n userId: entry.userId,\n organizationId: entry.organizationId,\n before: entry.before,\n after: entry.after,\n changes: entry.changes,\n requestId: entry.requestId,\n ipAddress: entry.ipAddress,\n userAgent: entry.userAgent,\n metadata: entry.metadata,\n timestamp: entry.timestamp,\n });\n }\n\n async query(options: AuditQueryOptions = {}): Promise<AuditEntry[]> {\n await this.ensureIndexes();\n\n const query: Record<string, unknown> = {};\n\n if (options.resource) {\n query.resource = options.resource;\n }\n\n if (options.documentId) {\n query.documentId = options.documentId;\n }\n\n if (options.userId) {\n query.userId = options.userId;\n }\n\n if (options.organizationId) {\n query.organizationId = options.organizationId;\n }\n\n if (options.action) {\n const actions = Array.isArray(options.action) ? options.action : [options.action];\n query.action = actions.length === 1 ? actions[0] : { $in: actions };\n }\n\n if (options.from || options.to) {\n query.timestamp = {};\n if (options.from) {\n (query.timestamp as Record<string, unknown>).$gte = options.from;\n }\n if (options.to) {\n (query.timestamp as Record<string, unknown>).$lte = options.to;\n }\n }\n\n const offset = options.offset ?? 0;\n const limit = options.limit ?? 100;\n\n const docs = await this.collection\n .find(query)\n .sort({ timestamp: -1 })\n .skip(offset)\n .limit(limit)\n .toArray();\n\n return docs.map((doc) => ({\n id: String(doc._id),\n resource: doc.resource as string,\n documentId: doc.documentId as string,\n action: doc.action as AuditEntry['action'],\n userId: doc.userId as string | undefined,\n organizationId: doc.organizationId as string | undefined,\n before: doc.before as Record<string, unknown> | undefined,\n after: doc.after as Record<string, unknown> | undefined,\n changes: doc.changes as string[] | undefined,\n requestId: doc.requestId as string | undefined,\n ipAddress: doc.ipAddress as string | undefined,\n userAgent: doc.userAgent as string | undefined,\n metadata: doc.metadata as Record<string, unknown> | undefined,\n timestamp: doc.timestamp as Date,\n }));\n }\n}\n\nexport default MongoAuditStore;\n"],"mappings":";AAoCA,IAAa,kBAAb,MAAmD;CACjD,AAAS,OAAO;CAChB,AAAQ;CACR,AAAQ,cAAc;CACtB,AAAQ;CAER,AAAQ;CAER,YAAY,SAAiC;AAC3C,OAAK,UAAU;EACf,MAAM,iBAAiB,QAAQ,cAAc;AAC7C,OAAK,aAAa,QAAQ,WAAW,WAAW,eAAe;AAC/D,OAAK,UAAU,QAAQ,WAAW;;CAGpC,MAAc,gBAA+B;AAC3C,MAAI,KAAK,YAAa;AAEtB,MAAI;AAEF,SAAM,KAAK,WAAW,YAAY;IAChC,UAAU;IACV,YAAY;IACZ,WAAW;IACZ,CAAC;AAGF,SAAM,KAAK,WAAW,YAAY;IAAE,QAAQ;IAAG,WAAW;IAAI,CAAC;AAG/D,SAAM,KAAK,WAAW,YAAY;IAAE,gBAAgB;IAAG,WAAW;IAAI,CAAC;AAGvE,OAAI,KAAK,UAAU,EACjB,OAAM,KAAK,WAAW,YACpB,EAAE,WAAW,GAAG,EAChB,EAAE,oBAAoB,KAAK,UAAU,KAAK,KAAK,IAAI,CACpD;AAGH,QAAK,cAAc;UACb;AAEN,QAAK,cAAc;;;CAIvB,MAAM,IAAI,OAAkC;AAC1C,QAAM,KAAK,eAAe;AAE1B,QAAM,KAAK,WAAW,UAAU;GAC9B,KAAK,MAAM;GACX,UAAU,MAAM;GAChB,YAAY,MAAM;GAClB,QAAQ,MAAM;GACd,QAAQ,MAAM;GACd,gBAAgB,MAAM;GACtB,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,SAAS,MAAM;GACf,WAAW,MAAM;GACjB,WAAW,MAAM;GACjB,WAAW,MAAM;GACjB,UAAU,MAAM;GAChB,WAAW,MAAM;GAClB,CAAC;;CAGJ,MAAM,MAAM,UAA6B,EAAE,EAAyB;AAClE,QAAM,KAAK,eAAe;EAE1B,MAAM,QAAiC,EAAE;AAEzC,MAAI,QAAQ,SACV,OAAM,WAAW,QAAQ;AAG3B,MAAI,QAAQ,WACV,OAAM,aAAa,QAAQ;AAG7B,MAAI,QAAQ,OACV,OAAM,SAAS,QAAQ;AAGzB,MAAI,QAAQ,eACV,OAAM,iBAAiB,QAAQ;AAGjC,MAAI,QAAQ,QAAQ;GAClB,MAAM,UAAU,MAAM,QAAQ,QAAQ,OAAO,GAAG,QAAQ,SAAS,CAAC,QAAQ,OAAO;AACjF,SAAM,SAAS,QAAQ,WAAW,IAAI,QAAQ,KAAK,EAAE,KAAK,SAAS;;AAGrE,MAAI,QAAQ,QAAQ,QAAQ,IAAI;AAC9B,SAAM,YAAY,EAAE;AACpB,OAAI,QAAQ,KACV,CAAC,MAAM,UAAsC,OAAO,QAAQ;AAE9D,OAAI,QAAQ,GACV,CAAC,MAAM,UAAsC,OAAO,QAAQ;;EAIhE,MAAM,SAAS,QAAQ,UAAU;EACjC,MAAM,QAAQ,QAAQ,SAAS;AAS/B,UAPa,MAAM,KAAK,WACrB,KAAK,MAAM,CACX,KAAK,EAAE,WAAW,IAAI,CAAC,CACvB,KAAK,OAAO,CACZ,MAAM,MAAM,CACZ,SAAS,EAEA,KAAK,SAAS;GACxB,IAAI,OAAO,IAAI,IAAI;GACnB,UAAU,IAAI;GACd,YAAY,IAAI;GAChB,QAAQ,IAAI;GACZ,QAAQ,IAAI;GACZ,gBAAgB,IAAI;GACpB,QAAQ,IAAI;GACZ,OAAO,IAAI;GACX,SAAS,IAAI;GACb,WAAW,IAAI;GACf,WAAW,IAAI;GACf,WAAW,IAAI;GACf,UAAU,IAAI;GACd,WAAW,IAAI;GAChB,EAAE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mongodb-CGzRbfAK.d.mts","names":[],"sources":["../src/audit/stores/interface.ts","../src/audit/stores/mongodb.ts"],"mappings":";;;KASY,WAAA;AAAA,UAEK,UAAA;EAAU;EAEzB,EAAA;EAMQ;EAJR,QAAA;EAYQ;EAVR,UAAA;EAsBW;EApBX,MAAA,EAAQ,WAAA;EAoBO;EAlBf,MAAA;EANA;EAQA,cAAA;EAJA;EAMA,MAAA,GAAS,MAAA;EAJT;EAMA,KAAA,GAAQ,MAAA;EAFR;EAIA,OAAA;EAFA;EAIA,SAAA;EAFA;EAIA,SAAA;EAAA;EAEA,SAAA;EAEA;EAAA,QAAA,GAAW,MAAA;EAEX;EAAA,SAAA,EAAW,IAAA;AAAA;AAAA,UAGI,YAAA;EACf,IAAA,GAAO,QAAA;EACP,cAAA;EACA,SAAA;EACA,SAAA;EACA,SAAA;EAJO;EAMP,QAAA;EAJA;EAMA,QAAA;AAAA;AAAA,UAGe,iBAAA;EAHf;EAKA,IAAA;AAAA;AAFF;;;AAAA,UAQiB,UAAA;EANX;EAAA,SAQK,IAAA;EAFgB;EAKzB,GAAA,CAAI,KAAA,EAAO,UAAA,GAAa,OAAA;EAAb;EAGX,KAAA,EAAO,OAAA,EAAS,iBAAA,GAAoB,OAAA,CAAQ,UAAA;EAA5B;EAGhB,KAAA,KAAU,OAAA;AAAA;AAAA,UAGK,iBAAA;EACf,QAAA;EACA,UAAA;EACA,MAAA;EACA,cAAA;EACA,MAAA,GAAS,WAAA,GAAc,WAAA;EACvB,IAAA,GAAO,IAAA;EACP,EAAA,GAAK,IAAA;EACL,KAAA;EACA,MAAA;AAAA;;;;iBAMc,gBAAA,CACd,QAAA,UACA,UAAA,UACA,MAAA,EAAQ,WAAA,EACR,OAAA,EAAS,YAAA,EACT,IAAA;EACE,MAAA,GAAS,MAAA;EACT,KAAA,GAAQ,MAAA;EACR,QAAA,GAAW,MAAA;AAAA,IAEZ,UAAA;;;UC5Fc,sBAAA;EDEA;ECAf,UAAA,EAAY,eAAA;;EAEZ,UAAA;EDYS;ECVT,OAAA;AAAA;AAAA,UAIe,eAAA;EACf,UAAA,GAAa,IAAA,aAAiB,eAAA;AAAA;AAAA,UAGtB,eAAA;EACR,SAAA,GAAY,GAAA,EAAK,MAAA,sBAA4B,OAAA;EAC7C,IAAA,GAAO,KAAA,EAAO,MAAA,sBAA4B,WAAA;EAC1C,WAAA,GAAc,IAAA,EAAM,MAAA,mBAAyB,OAAA,GAAU,MAAA,sBAA4B,OAAA;AAAA;AAAA,UAG3E,WAAA;EACR,IAAA,GAAO,IAAA,EAAM,MAAA,sBAA4B,WAAA;EACzC,IAAA,GAAO,CAAA,aAAc,WAAA;EACrB,KAAA,GAAQ,CAAA,aAAc,WAAA;EACtB,OAAA,QAAe,OAAA,CAAQ,MAAA;AAAA;AAAA,cAGZ,eAAA,YAA2B,UAAA;EAAA,SAC7B,IAAA;EAAA,QACD,UAAA;EAAA,QACA,WAAA;EAAA,QACA,OAAA;EAAA,QAEA,OAAA;cAEI,OAAA,EAAS,sBAAA;EAAA,QAOP,aAAA;EAgCR,GAAA,CAAI,KAAA,EAAO,UAAA,GAAa,OAAA;EAqBxB,KAAA,CAAM,OAAA,GAAS,iBAAA,GAAyB,OAAA,CAAQ,UAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mongodb-JN-9JA7K.d.mts","names":[],"sources":["../src/idempotency/stores/mongodb.ts"],"mappings":";;;UAoBiB,eAAA;EACf,EAAA;IACE,UAAA,CAAW,IAAA,WAAe,eAAA;EAAA;AAAA;AAAA,UAIpB,eAAA;EACR,OAAA,CAAQ,MAAA,WAAiB,OAAA,CAAQ,mBAAA;EACjC,SAAA,CAAU,GAAA,WAAc,OAAA;IAAU,YAAA;EAAA;EAClC,SAAA,CAAU,MAAA,UAAgB,MAAA,UAAgB,OAAA,YAAmB,OAAA;IAAU,YAAA;IAAuB,YAAA;IAAsB,aAAA;EAAA;EACpH,SAAA,CAAU,MAAA,WAAiB,OAAA;IAAU,YAAA;EAAA;EACrC,UAAA,CAAW,MAAA,WAAiB,OAAA;IAAU,YAAA;EAAA;EACtC,WAAA,CAAY,IAAA,UAAc,OAAA,YAAmB,OAAA;AAAA;AAAA,UAGrC,mBAAA;EACR,GAAA;EACA,MAAA;IACE,UAAA;IACA,OAAA,EAAS,MAAA;IACT,IAAA;EAAA;EAEF,IAAA;IACE,SAAA;IACA,SAAA,EAAW,IAAA;EAAA;EAEb,SAAA,EAAW,IAAA;EACX,SAAA,EAAW,IAAA;AAAA;AAAA,UAGI,4BAAA;EAfY;EAiB3B,UAAA,EAAY,eAAA;EAbD;EAeX,UAAA;EARW;EAUX,WAAA;EATe;EAWf,KAAA;AAAA;AAAA,cAGW,qBAAA,YAAiC,gBAAA;EAAA,SACnC,IAAA;EAAA,QACD,UAAA;EAAA,QACA,cAAA;EAAA,QACA,KAAA;EAAA,QACA,YAAA;cAEI,OAAA,EAAS,4BAAA;EAAA,YAYT,UAAA,CAAA;EAAA,QAIE,WAAA;EAeR,GAAA,CAAI,GAAA,WAAc,OAAA,CAAQ,iBAAA;EAmB1B,GAAA,CAAI,GAAA,UAAa,MAAA,EAAQ,IAAA,CAAK,iBAAA,WAA4B,OAAA;EAmB1D,OAAA,CAAQ,GAAA,UAAa,SAAA,UAAmB,KAAA,WAAgB,OAAA;EAwCxD,MAAA,CAAO,GAAA,UAAa,SAAA,WAAoB,OAAA;EAQxC,QAAA,CAAS,GAAA,WAAc,OAAA;EAMvB,MAAA,CAAO,GAAA,WAAc,OAAA;EAIrB,cAAA,CAAe,MAAA,WAAiB,OAAA;EAOhC,YAAA,CAAa,MAAA,WAAiB,OAAA,CAAQ,iBAAA;EAoBtC,KAAA,CAAA,GAAS,OAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openapi-G3Cw7XuM.mjs","names":[],"sources":["../src/docs/openapi.ts"],"sourcesContent":["/**\n * OpenAPI Spec Generator\n *\n * Auto-generates OpenAPI 3.0 specification from Arc resource registry.\n *\n * @example\n * import { openApiPlugin } from '@classytic/arc/docs';\n *\n * await fastify.register(openApiPlugin, {\n * title: 'My API',\n * version: '1.0.0',\n * });\n *\n * // Spec available at /_docs/openapi.json\n */\n\nimport fp from 'fastify-plugin';\nimport type { FastifyInstance, FastifyPluginAsync } from 'fastify';\nimport type { RegistryEntry, FastifyWithDecorators } from '../types/index.js';\nimport type { PermissionCheck } from '../permissions/types.js';\nimport type { ExternalOpenApiPaths } from './externalPaths.js';\nimport { convertRouteSchema } from '../utils/schemaConverter.js';\n\nexport interface OpenApiOptions {\n /** API title */\n title?: string;\n /** API version */\n version?: string;\n /** API description */\n description?: string;\n /** Server URL */\n serverUrl?: string;\n /** Route prefix for spec endpoint (default: '/_docs') */\n prefix?: string;\n /** API prefix for all resource paths (e.g., '/api/v1') */\n apiPrefix?: string;\n /** Auth roles required to access spec (default: [] = public) */\n authRoles?: string[];\n /** Include internal routes (default: false) */\n includeInternal?: boolean;\n /** Custom OpenAPI extensions */\n extensions?: Record<string, unknown>;\n}\n\nexport interface OpenApiSpec {\n openapi: string;\n info: {\n title: string;\n version: string;\n description?: string;\n };\n servers?: Array<{ url: string; description?: string }>;\n paths: Record<string, PathItem>;\n components: {\n schemas: Record<string, SchemaObject>;\n securitySchemes?: Record<string, SecurityScheme>;\n };\n tags: Array<{ name: string; description?: string }>;\n security?: Array<Record<string, string[]>>;\n}\n\nexport interface OpenApiBuildOptions {\n title?: string;\n version?: string;\n description?: string;\n serverUrl?: string;\n apiPrefix?: string;\n}\n\ninterface PathItem {\n get?: Operation;\n post?: Operation;\n put?: Operation;\n patch?: Operation;\n delete?: Operation;\n options?: Operation;\n head?: Operation;\n}\n\ninterface Operation {\n tags: string[];\n summary: string;\n description?: string;\n operationId: string;\n parameters?: Parameter[];\n requestBody?: RequestBody;\n responses: Record<string, Response>;\n security?: Array<Record<string, string[]>>;\n /** Arc permission metadata (OpenAPI extension) */\n 'x-arc-permission'?: { type: string; roles?: readonly string[] };\n /** Arc pipeline steps (OpenAPI extension) */\n 'x-arc-pipeline'?: Array<{ type: string; name: string }>;\n}\n\ninterface Parameter {\n name: string;\n in: 'path' | 'query' | 'header';\n required?: boolean;\n schema: SchemaObject;\n description?: string;\n}\n\ninterface RequestBody {\n required?: boolean;\n content: Record<string, { schema: SchemaObject }>;\n}\n\ninterface Response {\n description: string;\n content?: Record<string, { schema: SchemaObject }>;\n}\n\ninterface SchemaObject {\n type?: string;\n format?: string;\n properties?: Record<string, SchemaObject>;\n items?: SchemaObject;\n required?: string[];\n $ref?: string;\n description?: string;\n example?: unknown;\n additionalProperties?: boolean | SchemaObject;\n enum?: string[];\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n}\n\ninterface SecurityScheme {\n type: string;\n scheme?: string;\n bearerFormat?: string;\n in?: string;\n name?: string;\n}\n\nconst openApiPlugin: FastifyPluginAsync<OpenApiOptions> = async (\n fastify: FastifyInstance,\n opts: OpenApiOptions = {}\n) => {\n const {\n title = 'Arc API',\n version = '1.0.0',\n description,\n serverUrl,\n prefix = '/_docs',\n apiPrefix = '',\n authRoles = [],\n } = opts;\n\n // Build spec from instance-scoped registry\n const buildSpec = (): OpenApiSpec => {\n const arc = (fastify as unknown as FastifyWithDecorators).arc;\n const resources = arc?.registry?.getAll() ?? [];\n const externalPaths = arc?.externalOpenApiPaths ?? [];\n return buildOpenApiSpec(resources, {\n title,\n version,\n description,\n serverUrl,\n apiPrefix,\n }, externalPaths.length > 0 ? externalPaths : undefined);\n };\n\n // Serve OpenAPI spec\n fastify.get(`${prefix}/openapi.json`, async (request, reply) => {\n // Check auth if required\n if (authRoles.length > 0) {\n const user = (request as { user?: { roles?: string[] } }).user;\n const hasRole = authRoles.some((role) => user?.roles?.includes(role));\n if (!hasRole && !user?.roles?.includes('superadmin')) {\n reply.code(403).send({ error: 'Access denied' });\n return;\n }\n }\n\n const spec = buildSpec();\n // Return object directly - let Fastify handle serialization & compression\n return spec;\n });\n\n fastify.log?.debug?.(`OpenAPI spec available at ${prefix}/openapi.json`);\n};\n\n/**\n * Build OpenAPI spec from registry resources.\n * Shared by HTTP docs endpoint and CLI export command.\n */\nexport function buildOpenApiSpec(\n resources: RegistryEntry[],\n options: OpenApiBuildOptions = {},\n externalPaths?: ExternalOpenApiPaths[],\n): OpenApiSpec {\n const {\n title = 'Arc API',\n version = '1.0.0',\n description,\n serverUrl,\n apiPrefix = '',\n } = options;\n\n const paths: Record<string, PathItem> = {};\n const tags: Array<{ name: string; description?: string }> = [];\n\n // Collect additional security alternatives from external integrations.\n // Each item is OR'd with bearerAuth on authenticated resource operations.\n const additionalSecurity = externalPaths\n ?.flatMap(ext => ext.resourceSecurity ?? []) ?? [];\n\n for (const resource of resources) {\n // Build tag description with preset/pipeline info\n const tagDescParts = [`${resource.displayName || resource.name} operations`];\n if (resource.presets && resource.presets.length > 0) {\n tagDescParts.push(`Presets: ${resource.presets.join(', ')}`);\n }\n if (resource.pipelineSteps && resource.pipelineSteps.length > 0) {\n const stepNames = resource.pipelineSteps.map((s) => `${s.type}(${s.name})`);\n tagDescParts.push(`Pipeline: ${stepNames.join(' → ')}`);\n }\n if (resource.events && resource.events.length > 0) {\n tagDescParts.push(`Events: ${resource.events.join(', ')}`);\n }\n\n tags.push({\n name: resource.tag || resource.name,\n description: tagDescParts.join('. '),\n });\n\n const resourcePaths = generateResourcePaths(resource, apiPrefix, additionalSecurity);\n Object.assign(paths, resourcePaths);\n }\n\n // Merge external paths (Better Auth, custom integrations, etc.)\n if (externalPaths) {\n for (const ext of externalPaths) {\n for (const [path, methods] of Object.entries(ext.paths)) {\n paths[path] = paths[path]\n ? { ...paths[path], ...methods } as PathItem\n : methods as PathItem;\n }\n if (ext.tags) {\n for (const tag of ext.tags) {\n if (!tags.find((t) => t.name === tag.name)) {\n tags.push(tag);\n }\n }\n }\n }\n }\n\n // Merge external security schemes and schemas\n const externalSecuritySchemes = externalPaths\n ?.reduce<Record<string, Record<string, unknown>>>((acc, ext) => ({ ...acc, ...ext.securitySchemes }), {}) ?? {};\n const externalSchemas = externalPaths\n ?.reduce<Record<string, Record<string, unknown>>>((acc, ext) => ({ ...acc, ...ext.schemas }), {}) ?? {};\n\n return {\n openapi: '3.0.3',\n info: {\n title,\n version,\n ...(description && { description }),\n },\n ...(serverUrl && {\n servers: [{ url: serverUrl }],\n }),\n paths,\n components: {\n schemas: {\n ...generateSchemas(resources),\n ...externalSchemas,\n } as Record<string, SchemaObject>,\n securitySchemes: {\n bearerAuth: {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'JWT',\n },\n orgHeader: {\n type: 'apiKey',\n in: 'header',\n name: 'x-organization-id',\n },\n // Plugin-specific schemes (e.g. apiKeyAuth) are auto-detected\n // and injected via externalSecuritySchemes from the auth extractor.\n ...externalSecuritySchemes,\n } as Record<string, SecurityScheme>,\n },\n tags,\n };\n}\n\n/**\n * Convert Fastify-style params (/:id) to OpenAPI-style params (/{id})\n */\nfunction toOpenApiPath(path: string): string {\n return path.replace(/:([^/]+)/g, '{$1}');\n}\n\n/**\n * Convert OpenAPI schema to query parameters array\n * Transforms { properties: { page: { type: 'integer' } } } to [{ name: 'page', in: 'query', schema: { type: 'integer' } }]\n */\nfunction convertSchemaToParameters(schema: Record<string, unknown>): Parameter[] {\n const params: Parameter[] = [];\n const properties = (schema.properties as Record<string, Record<string, unknown>>) || {};\n const required = (schema.required as string[]) || [];\n\n for (const [name, prop] of Object.entries(properties)) {\n // Extract description separately (goes to Parameter level, not schema)\n const description = prop.description as string | undefined;\n const { description: _, ...schemaProps } = prop;\n\n const param: Parameter = {\n name,\n in: 'query',\n required: required.includes(name),\n schema: schemaProps as SchemaObject,\n };\n\n if (description) {\n param.description = description;\n }\n\n params.push(param);\n }\n return params;\n}\n\n/**\n * Default query parameters when no listQuery schema is provided\n */\nconst DEFAULT_LIST_PARAMS: Parameter[] = [\n { name: 'page', in: 'query', schema: { type: 'integer' }, description: 'Page number' },\n { name: 'limit', in: 'query', schema: { type: 'integer' }, description: 'Items per page' },\n { name: 'sort', in: 'query', schema: { type: 'string' }, description: 'Sort field (prefix with - for descending)' },\n];\n\n/**\n * Generate paths for a resource\n */\nfunction generateResourcePaths(\n resource: RegistryEntry,\n apiPrefix = '',\n additionalSecurity: Array<Record<string, string[]>> = [],\n): Record<string, PathItem> {\n const paths: Record<string, PathItem> = {};\n const basePath = `${apiPrefix}${resource.prefix}`;\n\n // Skip if default routes are disabled and no additional routes\n if (resource.disableDefaultRoutes && (!resource.additionalRoutes || resource.additionalRoutes.length === 0)) {\n return paths;\n }\n\n // Default CRUD routes (respects disabledRoutes + updateMethod)\n if (!resource.disableDefaultRoutes) {\n const disabledSet = new Set(resource.disabledRoutes ?? []);\n const updateMethod = resource.updateMethod ?? 'PATCH';\n\n // Collection routes: GET / (list) + POST / (create)\n const collectionPath: PathItem = {};\n\n if (!disabledSet.has('list')) {\n const listParams = resource.openApiSchemas?.listQuery\n ? convertSchemaToParameters(resource.openApiSchemas.listQuery as Record<string, unknown>)\n : DEFAULT_LIST_PARAMS;\n\n collectionPath.get = createOperation(resource, 'list', 'List all', {\n parameters: listParams,\n responses: {\n '200': {\n description: 'List of items',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean' },\n docs: { type: 'array', items: { $ref: `#/components/schemas/${resource.name}` } },\n page: { type: 'integer' },\n limit: { type: 'integer' },\n total: { type: 'integer' },\n pages: { type: 'integer' },\n hasNext: { type: 'boolean' },\n hasPrev: { type: 'boolean' },\n },\n },\n },\n },\n },\n },\n }, undefined, additionalSecurity);\n }\n\n if (!disabledSet.has('create')) {\n collectionPath.post = createOperation(resource, 'create', 'Create new', {\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${resource.name}Input` },\n },\n },\n },\n responses: {\n '201': {\n description: 'Created successfully',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean' },\n data: { $ref: `#/components/schemas/${resource.name}` },\n message: { type: 'string' },\n },\n },\n },\n },\n },\n },\n }, undefined, additionalSecurity);\n }\n\n if (Object.keys(collectionPath).length > 0) {\n paths[basePath] = collectionPath;\n }\n\n // Item routes: GET /:id + UPDATE /:id + DELETE /:id\n const itemPath: PathItem = {};\n\n if (!disabledSet.has('get')) {\n itemPath.get = createOperation(resource, 'get', 'Get by ID', {\n parameters: [\n { name: 'id', in: 'path', required: true, schema: { type: 'string' } },\n ],\n responses: {\n '200': {\n description: 'Item found',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean' },\n data: { $ref: `#/components/schemas/${resource.name}` },\n },\n },\n },\n },\n },\n '404': { description: 'Not found' },\n },\n }, undefined, additionalSecurity);\n }\n\n if (!disabledSet.has('update')) {\n const updateOp = createOperation(resource, 'update', 'Update', {\n parameters: [\n { name: 'id', in: 'path', required: true, schema: { type: 'string' } },\n ],\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${resource.name}Input` },\n },\n },\n },\n responses: {\n '200': {\n description: 'Updated successfully',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean' },\n data: { $ref: `#/components/schemas/${resource.name}` },\n message: { type: 'string' },\n },\n },\n },\n },\n },\n },\n }, undefined, additionalSecurity);\n\n if (updateMethod === 'both') {\n itemPath.put = updateOp;\n itemPath.patch = updateOp;\n } else if (updateMethod === 'PUT') {\n itemPath.put = updateOp;\n } else {\n itemPath.patch = updateOp;\n }\n }\n\n if (!disabledSet.has('delete')) {\n itemPath.delete = createOperation(resource, 'delete', 'Delete', {\n parameters: [\n { name: 'id', in: 'path', required: true, schema: { type: 'string' } },\n ],\n responses: {\n '200': {\n description: 'Deleted successfully',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean' },\n message: { type: 'string' },\n },\n },\n },\n },\n },\n },\n }, undefined, additionalSecurity);\n }\n\n if (Object.keys(itemPath).length > 0) {\n paths[toOpenApiPath(`${basePath}/:id`)] = itemPath;\n }\n }\n\n // Additional routes from presets\n for (const route of resource.additionalRoutes || []) {\n const fullPath = toOpenApiPath(`${basePath}${route.path}`);\n const method = route.method.toLowerCase() as keyof PathItem;\n\n if (!paths[fullPath]) {\n paths[fullPath] = {};\n }\n\n // Check if route requires auth (not public)\n const handlerName = route.operation ?? (typeof route.handler === 'string' ? route.handler : 'handler');\n const isPublicRoute = (route.permissions as PermissionCheck)?._isPublic === true;\n const requiresAuthForRoute = !!route.permissions && !isPublicRoute;\n\n // Build extras from route schema\n const extras: Partial<Operation> = {\n parameters: extractPathParams(route.path),\n responses: {\n '200': { description: route.description || 'Success' },\n },\n };\n\n // Add request body from route.schema.body (for POST, PUT, PATCH)\n // Auto-convert Zod schemas to JSON Schema (no-op for plain JSON Schema)\n const rawSchema = route.schema as Record<string, unknown> | undefined;\n const routeSchema = rawSchema ? convertRouteSchema(rawSchema) : undefined;\n if (routeSchema?.body && ['post', 'put', 'patch'].includes(method)) {\n extras.requestBody = {\n required: true,\n content: {\n 'application/json': {\n schema: routeSchema.body as SchemaObject,\n },\n },\n };\n }\n\n // Add query parameters from route.schema.querystring\n if (routeSchema?.querystring) {\n const queryParams = convertSchemaToParameters(routeSchema.querystring as Record<string, unknown>);\n extras.parameters = [...(extras.parameters || []), ...queryParams];\n }\n\n // Add custom response schema if provided\n if (routeSchema?.response) {\n const responseSchemas = routeSchema.response as Record<string, unknown>;\n for (const [statusCode, schema] of Object.entries(responseSchemas)) {\n extras.responses![statusCode] = {\n description: (schema as Record<string, unknown>).description as string || `Response ${statusCode}`,\n content: {\n 'application/json': {\n schema: schema as SchemaObject,\n },\n },\n };\n }\n }\n\n paths[fullPath][method] = createOperation(\n resource,\n handlerName,\n route.summary ?? handlerName,\n extras,\n requiresAuthForRoute,\n additionalSecurity,\n );\n }\n\n return paths;\n}\n\n/**\n * Create an operation object\n * @param requiresAuthOverride - Override for whether auth is required (for additional routes)\n * @param additionalSecurity - Extra security alternatives from external integrations (OR'd with bearerAuth)\n */\nfunction createOperation(\n resource: RegistryEntry,\n operation: string,\n summary: string,\n extras: Partial<Operation>,\n requiresAuthOverride?: boolean,\n additionalSecurity: Array<Record<string, string[]>> = [],\n): Operation {\n const permissions = resource.permissions || {};\n // Check if permission check is defined for this operation\n const operationPermission = (permissions as Record<string, unknown>)[operation];\n // Check if it's marked as public (allowPublic())\n const isPublic = (operationPermission as PermissionCheck)?._isPublic === true;\n // Check for role requirements\n const requiredRoles = (operationPermission as PermissionCheck)?._roles;\n // If override is provided, use it; otherwise check if operation has a permission check that isn't public\n const requiresAuth = requiresAuthOverride !== undefined\n ? requiresAuthOverride\n : typeof operationPermission === 'function' && !isPublic;\n\n // Build permission annotation\n const permAnnotation = describePermissionForOpenApi(operationPermission);\n\n // Build description with permission + preset info\n const descParts: string[] = [];\n if (permAnnotation) {\n descParts.push(`**Permission**: ${permAnnotation.type === 'public' ? 'Public' : permAnnotation.type === 'requireRoles' ? `Requires roles: ${(permAnnotation.roles ?? []).join(', ')}` : 'Requires authentication'}`);\n }\n if (resource.presets && resource.presets.length > 0) {\n descParts.push(`**Presets**: ${resource.presets.join(', ')}`);\n }\n // Find pipeline steps that apply to this operation\n const applicableSteps = (resource.pipelineSteps ?? []).filter((s) => {\n if (!s.operations) return true; // applies to all\n return s.operations.includes(operation);\n });\n\n const op: Operation = {\n tags: [resource.tag || 'Resource'],\n summary: `${summary} ${(resource.displayName || resource.name).toLowerCase()}`,\n operationId: `${resource.name}_${operation}`,\n ...(descParts.length > 0 && { description: descParts.join('\\n\\n') }),\n // Only add security requirement if route requires auth\n ...(requiresAuth && {\n security: [{ bearerAuth: [] }, ...additionalSecurity],\n }),\n // Permission metadata extension\n ...(permAnnotation && { 'x-arc-permission': permAnnotation }),\n // Pipeline extension\n ...(applicableSteps.length > 0 && {\n 'x-arc-pipeline': applicableSteps.map((s) => ({ type: s.type, name: s.name })),\n }),\n responses: {\n ...(requiresAuth && {\n '401': {\n description: 'Authentication required — no valid Bearer token provided',\n content: {\n 'application/json': {\n schema: { $ref: '#/components/schemas/Error' },\n },\n },\n },\n '403': {\n description: permAnnotation?.roles\n ? `Forbidden — requires one of: ${(permAnnotation.roles as string[]).join(', ')}`\n : 'Forbidden — insufficient permissions',\n content: {\n 'application/json': {\n schema: { $ref: '#/components/schemas/Error' },\n },\n },\n },\n }),\n '500': { description: 'Internal server error' },\n },\n ...extras,\n };\n\n return op;\n}\n\n/**\n * Describe a permission check function for OpenAPI.\n * Extracts role, org role, and team permission metadata from permission functions.\n */\nfunction describePermissionForOpenApi(\n check: unknown,\n): { type: string; roles?: readonly string[]; orgRoles?: readonly string[] } | undefined {\n if (!check || typeof check !== 'function') return undefined;\n\n const fn = check as PermissionCheck & {\n _orgRoles?: readonly string[];\n _orgPermission?: string;\n _teamPermission?: string;\n };\n\n if (fn._isPublic === true) return { type: 'public' };\n\n const result: { type: string; roles?: readonly string[]; orgRoles?: readonly string[] } = {\n type: 'requireAuth',\n };\n\n if (Array.isArray(fn._roles) && fn._roles.length > 0) {\n result.type = 'requireRoles';\n result.roles = fn._roles as string[];\n }\n if (Array.isArray(fn._orgRoles) && fn._orgRoles.length > 0) {\n result.orgRoles = fn._orgRoles;\n }\n\n return result;\n}\n\n/**\n * Extract path parameters from route path\n */\nfunction extractPathParams(path: string): Parameter[] {\n const params: Parameter[] = [];\n const matches = path.matchAll(/:([^/]+)/g);\n\n for (const match of matches) {\n const paramName = match[1];\n if (paramName) {\n params.push({\n name: paramName,\n in: 'path',\n required: true,\n schema: { type: 'string' },\n });\n }\n }\n\n return params;\n}\n\n/**\n * Generate schema definitions from pre-stored registry schemas.\n * Schemas are generated at resource definition time and stored in the registry.\n *\n * Response schema priority:\n * 1. If resource provides explicit `openApiSchemas.response`, use it as-is\n * 2. Otherwise, auto-generate from `createBody` + _id + timestamps\n *\n * Note: This is for OpenAPI documentation only - does NOT affect Fastify serialization.\n */\nfunction generateSchemas(resources: RegistryEntry[]): Record<string, SchemaObject> {\n const schemas: Record<string, SchemaObject> = {\n // Common schemas (pagination fields are inlined in list responses)\n Error: {\n type: 'object',\n properties: {\n success: { type: 'boolean', example: false },\n error: { type: 'string' },\n code: { type: 'string' },\n requestId: { type: 'string' },\n timestamp: { type: 'string' },\n },\n },\n };\n\n for (const resource of resources) {\n const storedSchemas = resource.openApiSchemas;\n const fieldPerms = resource.fieldPermissions;\n\n // === RESPONSE SCHEMA (for GET responses) ===\n // Priority 1: Explicit response schema provided by user\n if (storedSchemas?.response) {\n schemas[resource.name] = {\n type: 'object',\n description: resource.displayName,\n ...(storedSchemas.response as SchemaObject),\n };\n }\n // Priority 2: Auto-generate from createBody\n else if (storedSchemas?.createBody) {\n schemas[resource.name] = {\n type: 'object',\n description: resource.displayName,\n properties: {\n _id: { type: 'string', description: 'Unique identifier' },\n ...((storedSchemas.createBody as SchemaObject).properties ?? {}),\n createdAt: { type: 'string', format: 'date-time', description: 'Creation timestamp' },\n updatedAt: { type: 'string', format: 'date-time', description: 'Last update timestamp' },\n },\n };\n }\n // Fallback: Placeholder schema\n else {\n schemas[resource.name] = {\n type: 'object',\n description: resource.displayName,\n properties: {\n _id: { type: 'string', description: 'Unique identifier' },\n createdAt: { type: 'string', format: 'date-time', description: 'Creation timestamp' },\n updatedAt: { type: 'string', format: 'date-time', description: 'Last update timestamp' },\n },\n };\n }\n\n // Annotate fields with permission info\n if (fieldPerms && schemas[resource.name]?.properties) {\n const props = schemas[resource.name]!.properties!;\n for (const [field, perm] of Object.entries(fieldPerms)) {\n if (props[field]) {\n // Add permission description to existing field\n const desc = props[field]!.description ?? '';\n const permDesc = formatFieldPermDescription(perm);\n props[field]!.description = desc ? `${desc} (${permDesc})` : permDesc;\n } else if (perm.type === 'hidden') {\n // Hidden fields won't appear in schema — note in schema description\n }\n }\n }\n\n // === INPUT SCHEMAS (for POST/PATCH requests) ===\n if (storedSchemas?.createBody) {\n schemas[`${resource.name}Input`] = {\n type: 'object',\n description: `${resource.displayName} create input`,\n ...(storedSchemas.createBody as SchemaObject),\n };\n\n if (storedSchemas.updateBody) {\n schemas[`${resource.name}Update`] = {\n type: 'object',\n description: `${resource.displayName} update input`,\n ...(storedSchemas.updateBody as SchemaObject),\n };\n }\n } else {\n schemas[`${resource.name}Input`] = {\n type: 'object',\n description: `${resource.displayName} input`,\n };\n }\n }\n\n return schemas;\n}\n\n/**\n * Format a field permission description for OpenAPI\n */\nfunction formatFieldPermDescription(\n perm: { type: string; roles?: readonly string[]; redactValue?: unknown },\n): string {\n switch (perm.type) {\n case 'hidden':\n return 'Hidden — never returned in responses';\n case 'visibleTo':\n return `Visible to: ${(perm.roles ?? []).join(', ')}`;\n case 'writableBy':\n return `Writable by: ${(perm.roles ?? []).join(', ')}`;\n case 'redactFor':\n return `Redacted for: ${(perm.roles ?? []).join(', ')}`;\n default:\n return perm.type;\n }\n}\n\nexport default fp(openApiPlugin, {\n name: 'arc-openapi',\n fastify: '5.x',\n});\n\nexport { openApiPlugin };\n"],"mappings":"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"}
|
package/dist/org/index.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/org/orgGuard.ts","../../src/org/orgMembership.ts","../../src/org/organizationPlugin.ts"],"mappings":";;;;;;;;UAsBiB,eAAA;EAYQ;EAVvB,iBAAA;EAUmE;EARnE,KAAA;AAAA;;;;;AAkEF;iBA1DgB,QAAA,CAAS,OAAA,GAAS,eAAA,GAAuB,YAAA;;;;iBAmDzC,UAAA,CAAA,GAAc,YAAA;;;AC7E9B;iBDoFgB,cAAA,CAAA,GAAkB,KAAA,aAAkB,YAAA;;;UCpFnC,oBAAA;;EAEf,YAAA;EDY8B;ECV9B,cAAA,IAAkB,MAAA,UAAgB,KAAA,aAAkB,OAAA;AAAA;AAAA,UAGrC,eAAA;EDmBD;ECjBd,YAAA;AAAA;;;;;;iBAQoB,kBAAA,CACpB,IAAA,EAAM,QAAA,qBACN,KAAA,6BACA,OAAA,GAAS,oBAAA,GACR,OAAA;ADwDH;;;;AAAA,iBCxBgB,eAAA,CACd,IAAA,EAAM,QAAA,qBACN,KAAA,6BACA,OAAA,GAAS,eAAA;AD4BX;;;;AAAA,iBCRgB,UAAA,CACd,IAAA,EAAM,QAAA,qBACN,KAAA,6BACA,KAAA,qBACA,OAAA,GAAS,eAAA;;;;YC3CC,eAAA;IF+CI;IE7CZ,cAAA,GAAiB,KAAA,eAAoB,kBAAA;EAAA;AAAA;AAAA,cA0DnC,kBAAA,EAAoB,kBAAA,CAAmB,yBAAA;AAAA,cAAyB,QAAA"}
|
package/dist/org/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/org/orgGuard.ts","../../src/org/orgMembership.ts","../../src/org/organizationPlugin.ts"],"sourcesContent":["/**\n * Organization Guard Middleware\n *\n * Ensures organization context is present before handler execution.\n *\n * @example\n * // Require org context\n * fastify.get('/invoices', {\n * preHandler: [fastify.authenticate, orgGuard()]\n * }, handler);\n *\n * // Require specific org roles\n * fastify.post('/invoices', {\n * preHandler: [fastify.authenticate, orgGuard({ roles: ['admin', 'accountant'] })]\n * }, handler);\n */\n\nimport type { FastifyReply } from 'fastify';\nimport type { RequestWithExtras, RouteHandler } from '../types/index.js';\nimport type { RequestScope } from '../scope/types.js';\nimport { isMember, isElevated, hasOrgAccess, getOrgRoles, PUBLIC_SCOPE } from '../scope/types.js';\n\nexport interface OrgGuardOptions {\n /** Require organization context (default: true) */\n requireOrgContext?: boolean;\n /** Required org-level roles */\n roles?: string[];\n}\n\n/**\n * Create org guard middleware.\n * Reads `request.scope` for org context and roles.\n * Elevated scope always passes.\n */\nexport function orgGuard(options: OrgGuardOptions = {}): RouteHandler {\n const {\n requireOrgContext = true,\n roles = [],\n } = options;\n\n return async function orgGuardMiddleware(\n request: RequestWithExtras,\n reply: FastifyReply\n ): Promise<void> {\n const scope = request.scope ?? PUBLIC_SCOPE;\n\n // Elevated scope always passes\n if (isElevated(scope)) return;\n\n // Check org context exists\n if (requireOrgContext && !hasOrgAccess(scope)) {\n reply.code(403).send({\n success: false,\n error: 'Organization context required',\n code: 'ORG_CONTEXT_REQUIRED',\n message:\n 'This endpoint requires an organization context. ' +\n 'Please specify organization via x-organization-id header.',\n });\n return;\n }\n\n // Check org-level roles if specified\n if (roles.length > 0 && isMember(scope)) {\n const userOrgRoles = getOrgRoles(scope);\n const hasRequiredRole = roles.some((role) => userOrgRoles.includes(role));\n\n if (!hasRequiredRole) {\n reply.code(403).send({\n success: false,\n error: 'Insufficient organization permissions',\n code: 'ORG_ROLE_REQUIRED',\n message: `This action requires one of these organization roles: ${roles.join(', ')}`,\n required: roles,\n current: userOrgRoles,\n });\n return;\n }\n }\n };\n}\n\n/**\n * Shorthand for requiring org context\n */\nexport function requireOrg(): RouteHandler {\n return orgGuard({ requireOrgContext: true });\n}\n\n/**\n * Require org context with specific roles\n */\nexport function requireOrgRole(...roles: string[]): RouteHandler {\n return orgGuard({ requireOrgContext: true, roles });\n}\n\nexport default orgGuard;\n","/**\n * Organization Membership Utilities\n *\n * Server-side membership validation.\n */\n\nimport type { UserBase, UserOrganization } from '../types/index.js';\n\nexport interface OrgMembershipOptions {\n /** Path to user's organizations array */\n userOrgsPath?: string;\n /** Optional DB lookup function */\n validateFromDb?: (userId: string, orgId: string) => Promise<boolean>;\n}\n\nexport interface OrgRolesOptions {\n /** Path to user's organizations array */\n userOrgsPath?: string;\n}\n\n/**\n * Check if user is member of organization.\n * This is a low-level utility for checking membership from user object data.\n * For request-level checks, use `request.scope` (isMember/isElevated guards).\n */\nexport async function orgMembershipCheck(\n user: UserBase | undefined | null,\n orgId: string | undefined | null,\n options: OrgMembershipOptions = {}\n): Promise<boolean> {\n const {\n userOrgsPath = 'organizations',\n validateFromDb,\n } = options;\n\n if (!user || !orgId) return false;\n\n // Check from user object\n const userOrgs = ((user as UserBase & { [key: string]: unknown })[userOrgsPath] ?? []) as UserOrganization[];\n const isMemberFromUser = userOrgs.some((o) => {\n const memberOrgId = o.organizationId?.toString() ?? String(o);\n return memberOrgId === orgId.toString();\n });\n\n if (isMemberFromUser) return true;\n\n // Optional: validate from database\n if (validateFromDb) {\n const userId = (user._id ?? user.id)?.toString();\n if (userId) {\n return validateFromDb(userId, orgId);\n }\n }\n\n return false;\n}\n\n/**\n * Get user's role in organization from user object data.\n * For request-level role checks, use `request.scope.orgRoles` (when scope is 'member').\n */\nexport function getUserOrgRoles(\n user: UserBase | undefined | null,\n orgId: string | undefined | null,\n options: OrgRolesOptions = {}\n): string[] {\n const { userOrgsPath = 'organizations' } = options;\n\n if (!user || !orgId) return [];\n\n const userOrgs = ((user as UserBase & { [key: string]: unknown })[userOrgsPath] ?? []) as UserOrganization[];\n const membership = userOrgs.find((o) => {\n const memberOrgId = o.organizationId?.toString() ?? String(o);\n return memberOrgId === orgId.toString();\n });\n\n const membershipRoles = membership as { roles?: string[] } | undefined;\n return membershipRoles?.roles ?? [];\n}\n\n/**\n * Check if user has specific role in organization from user object data.\n * For request-level role checks, use `requireOrgRole()` permission or `request.scope`.\n */\nexport function hasOrgRole(\n user: UserBase | undefined | null,\n orgId: string | undefined | null,\n roles: string | string[],\n options: OrgRolesOptions = {}\n): boolean {\n const userOrgRoles = getUserOrgRoles(user, orgId, options);\n const requiredRoles = Array.isArray(roles) ? roles : [roles];\n\n return requiredRoles.some((role) => userOrgRoles.includes(role));\n}\n\nexport default { orgMembershipCheck, getUserOrgRoles, hasOrgRole };\n","/**\n * Organization Plugin -- Full org management with REST endpoints\n *\n * Creates these routes:\n * - POST /api/organizations -- Create org\n * - GET /api/organizations -- List user's orgs\n * - GET /api/organizations/:orgId -- Get org\n * - PATCH /api/organizations/:orgId -- Update org\n * - DELETE /api/organizations/:orgId -- Delete org\n * - GET /api/organizations/:orgId/members -- List members\n * - POST /api/organizations/:orgId/members -- Add member\n * - PATCH /api/organizations/:orgId/members/:userId -- Update role\n * - DELETE /api/organizations/:orgId/members/:userId -- Remove member\n *\n * @example\n * import { organizationPlugin } from '@classytic/arc/org';\n *\n * await fastify.register(organizationPlugin, {\n * adapter: myMongooseOrgAdapter,\n * basePath: '/api/organizations',\n * enableInvitations: false,\n * });\n */\n\nimport fp from 'fastify-plugin';\nimport type {\n FastifyInstance,\n FastifyPluginAsync,\n FastifyReply,\n FastifyRequest,\n RouteHandlerMethod,\n} from 'fastify';\nimport type {\n OrgAdapter,\n OrgRole,\n OrganizationPluginOptions,\n MemberDoc,\n} from './types.js';\nimport type { UserBase } from '../permissions/types.js';\n\n// ---------------------------------------------------------------------------\n// Fastify type augmentations\n// ---------------------------------------------------------------------------\n\ndeclare module 'fastify' {\n interface FastifyInstance {\n /** Middleware: require the caller to hold one of the listed org roles */\n requireOrgRole: (roles: string[]) => RouteHandlerMethod;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Default roles\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_ROLES: OrgRole[] = [\n {\n name: 'owner',\n permissions: [{ resource: '*', action: ['*'] }],\n },\n {\n name: 'admin',\n permissions: [\n { resource: 'org', action: ['read', 'update'] },\n { resource: 'members', action: ['*'] },\n ],\n },\n {\n name: 'member',\n permissions: [\n { resource: 'org', action: ['read'] },\n { resource: 'members', action: ['read'] },\n ],\n },\n];\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Extract a UserBase from the request (set by auth plugin). */\nfunction getUser(request: FastifyRequest): UserBase | undefined {\n return (request as FastifyRequest & { user?: UserBase }).user;\n}\n\n/** Get user id (supports both `id` and `_id`). */\nfunction getUserId(user: UserBase): string | undefined {\n const raw = user.id ?? user._id;\n return raw ? String(raw) : undefined;\n}\n\n/** Standard JSON error reply. */\nfunction sendError(\n reply: FastifyReply,\n statusCode: number,\n code: string,\n message: string,\n): void {\n void reply.code(statusCode).send({ success: false, code, error: message });\n}\n\n// ---------------------------------------------------------------------------\n// Plugin implementation\n// ---------------------------------------------------------------------------\n\nconst organizationPlugin: FastifyPluginAsync<OrganizationPluginOptions> = async (\n fastify: FastifyInstance,\n opts: OrganizationPluginOptions,\n) => {\n const {\n adapter,\n roles = DEFAULT_ROLES,\n basePath = '/api/organizations',\n enableInvitations = false,\n } = opts;\n\n // Collect valid role names for quick validation\n const validRoleNames = new Set(roles.map((r) => r.name));\n\n // --------------------------------------------------\n // requireOrgRole decorator\n // --------------------------------------------------\n\n /**\n * Create a preHandler that:\n * 1. Ensures the request is authenticated\n * 2. Looks up the caller's membership in the org identified by `:orgId`\n * 3. Verifies the caller holds one of the required roles\n */\n fastify.decorate(\n 'requireOrgRole',\n function requireOrgRole(requiredRoles: string[]): RouteHandlerMethod {\n return async function requireOrgRoleHandler(\n request: FastifyRequest,\n reply: FastifyReply,\n ): Promise<void> {\n const user = getUser(request);\n if (!user) {\n sendError(reply, 401, 'UNAUTHORIZED', 'Authentication required');\n return;\n }\n\n const userId = getUserId(user);\n if (!userId) {\n sendError(reply, 401, 'UNAUTHORIZED', 'Unable to determine user identity');\n return;\n }\n\n const { orgId } = request.params as { orgId?: string };\n if (!orgId) {\n sendError(reply, 400, 'MISSING_ORG_ID', 'Organization ID is required');\n return;\n }\n\n const member = await adapter.getMember(orgId, userId);\n if (!member) {\n sendError(reply, 403, 'NOT_A_MEMBER', 'You are not a member of this organization');\n return;\n }\n\n const hasRole = requiredRoles.includes(member.role);\n if (!hasRole) {\n sendError(\n reply,\n 403,\n 'INSUFFICIENT_ROLE',\n `This action requires one of these roles: ${requiredRoles.join(', ')}`,\n );\n return;\n }\n };\n },\n );\n\n // --------------------------------------------------\n // Auth helper -- optional authenticate decorator\n // --------------------------------------------------\n\n /** Wrap preHandlers so that authenticate is called first (if available). */\n function withAuth(...extra: RouteHandlerMethod[]): RouteHandlerMethod[] {\n const handlers: RouteHandlerMethod[] = [];\n const inst = fastify as FastifyInstance & { authenticate?: RouteHandlerMethod };\n if (typeof inst.authenticate === 'function') {\n handlers.push(inst.authenticate);\n }\n handlers.push(...extra);\n return handlers;\n }\n\n // --------------------------------------------------\n // Slug helper\n // --------------------------------------------------\n\n function generateSlug(name: string): string {\n return name\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/[\\s_]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n }\n\n // --------------------------------------------------\n // Organization routes\n // --------------------------------------------------\n\n /**\n * POST / -- Create organization\n *\n * Body: { name: string; slug?: string; [key: string]: unknown }\n * The authenticated user becomes the owner.\n */\n fastify.post(\n basePath,\n { preHandler: withAuth() },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const user = getUser(request);\n if (!user) {\n sendError(reply, 401, 'UNAUTHORIZED', 'Authentication required');\n return;\n }\n\n const userId = getUserId(user);\n if (!userId) {\n sendError(reply, 401, 'UNAUTHORIZED', 'Unable to determine user identity');\n return;\n }\n\n const body = request.body as { name?: string; slug?: string; [key: string]: unknown } | undefined;\n if (!body?.name) {\n sendError(reply, 400, 'VALIDATION_ERROR', 'Organization name is required');\n return;\n }\n\n const slug = body.slug ?? generateSlug(body.name);\n\n // Check slug uniqueness\n const existing = await adapter.getOrgBySlug(slug);\n if (existing) {\n sendError(reply, 409, 'SLUG_TAKEN', `An organization with slug '${slug}' already exists`);\n return;\n }\n\n const org = await adapter.createOrg({ ...body, name: body.name, slug, ownerId: userId });\n\n // Auto-add creator as owner\n await adapter.addMember(org.id, userId, 'owner');\n\n void reply.code(201).send({ success: true, data: org });\n },\n );\n\n /**\n * GET / -- List the authenticated user's organizations\n */\n fastify.get(\n basePath,\n { preHandler: withAuth() },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const user = getUser(request);\n if (!user) {\n sendError(reply, 401, 'UNAUTHORIZED', 'Authentication required');\n return;\n }\n\n const userId = getUserId(user);\n if (!userId) {\n sendError(reply, 401, 'UNAUTHORIZED', 'Unable to determine user identity');\n return;\n }\n\n const orgs = await adapter.listUserOrgs(userId);\n void reply.send({ success: true, data: orgs });\n },\n );\n\n /**\n * GET /:orgId -- Get a single organization\n */\n fastify.get(\n `${basePath}/:orgId`,\n { preHandler: withAuth(fastify.requireOrgRole(['owner', 'admin', 'member'])) },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const { orgId } = request.params as { orgId: string };\n const org = await adapter.getOrg(orgId);\n\n if (!org) {\n sendError(reply, 404, 'NOT_FOUND', 'Organization not found');\n return;\n }\n\n void reply.send({ success: true, data: org });\n },\n );\n\n /**\n * PATCH /:orgId -- Update organization\n */\n fastify.patch(\n `${basePath}/:orgId`,\n { preHandler: withAuth(fastify.requireOrgRole(['owner', 'admin'])) },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const { orgId } = request.params as { orgId: string };\n const body = request.body as Partial<Record<string, unknown>> | undefined;\n\n if (!body || Object.keys(body).length === 0) {\n sendError(reply, 400, 'VALIDATION_ERROR', 'Request body must not be empty');\n return;\n }\n\n // Prevent changing ownerId or id through PATCH\n const { ownerId: _ownerId, id: _id, ...updates } = body;\n\n const org = await adapter.updateOrg(orgId, updates);\n if (!org) {\n sendError(reply, 404, 'NOT_FOUND', 'Organization not found');\n return;\n }\n\n void reply.send({ success: true, data: org });\n },\n );\n\n /**\n * DELETE /:orgId -- Delete organization (owner only)\n */\n fastify.delete(\n `${basePath}/:orgId`,\n { preHandler: withAuth(fastify.requireOrgRole(['owner'])) },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const { orgId } = request.params as { orgId: string };\n\n const org = await adapter.getOrg(orgId);\n if (!org) {\n sendError(reply, 404, 'NOT_FOUND', 'Organization not found');\n return;\n }\n\n await adapter.deleteOrg(orgId);\n void reply.send({ success: true, message: 'Organization deleted' });\n },\n );\n\n // --------------------------------------------------\n // Member routes\n // --------------------------------------------------\n\n /**\n * GET /:orgId/members -- List members\n */\n fastify.get(\n `${basePath}/:orgId/members`,\n { preHandler: withAuth(fastify.requireOrgRole(['owner', 'admin', 'member'])) },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const { orgId } = request.params as { orgId: string };\n const members = await adapter.listMembers(orgId);\n void reply.send({ success: true, data: members });\n },\n );\n\n /**\n * POST /:orgId/members -- Add a member\n *\n * Body: { userId: string; role: string }\n */\n fastify.post(\n `${basePath}/:orgId/members`,\n { preHandler: withAuth(fastify.requireOrgRole(['owner', 'admin'])) },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const { orgId } = request.params as { orgId: string };\n const body = request.body as { userId?: string; role?: string } | undefined;\n\n if (!body?.userId || !body.role) {\n sendError(reply, 400, 'VALIDATION_ERROR', 'userId and role are required');\n return;\n }\n\n if (!validRoleNames.has(body.role)) {\n sendError(\n reply,\n 400,\n 'INVALID_ROLE',\n `Invalid role '${body.role}'. Valid roles: ${[...validRoleNames].join(', ')}`,\n );\n return;\n }\n\n // Prevent duplicate membership\n const existing = await adapter.getMember(orgId, body.userId);\n if (existing) {\n sendError(reply, 409, 'ALREADY_MEMBER', 'User is already a member of this organization');\n return;\n }\n\n const member = await adapter.addMember(orgId, body.userId, body.role);\n void reply.code(201).send({ success: true, data: member });\n },\n );\n\n /**\n * PATCH /:orgId/members/:userId -- Update a member's role\n *\n * Body: { role: string }\n */\n fastify.patch(\n `${basePath}/:orgId/members/:userId`,\n { preHandler: withAuth(fastify.requireOrgRole(['owner', 'admin'])) },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const { orgId, userId } = request.params as { orgId: string; userId: string };\n const body = request.body as { role?: string } | undefined;\n\n if (!body?.role) {\n sendError(reply, 400, 'VALIDATION_ERROR', 'role is required');\n return;\n }\n\n if (!validRoleNames.has(body.role)) {\n sendError(\n reply,\n 400,\n 'INVALID_ROLE',\n `Invalid role '${body.role}'. Valid roles: ${[...validRoleNames].join(', ')}`,\n );\n return;\n }\n\n // Prevent demoting the last owner\n const currentMember = await adapter.getMember(orgId, userId);\n if (!currentMember) {\n sendError(reply, 404, 'NOT_FOUND', 'Member not found');\n return;\n }\n\n if (currentMember.role === 'owner' && body.role !== 'owner') {\n const members = await adapter.listMembers(orgId);\n const ownerCount = members.filter((m: MemberDoc) => m.role === 'owner').length;\n if (ownerCount <= 1) {\n sendError(\n reply,\n 400,\n 'LAST_OWNER',\n 'Cannot change the role of the last owner. Transfer ownership first.',\n );\n return;\n }\n }\n\n const member = await adapter.updateMemberRole(orgId, userId, body.role);\n if (!member) {\n sendError(reply, 404, 'NOT_FOUND', 'Member not found');\n return;\n }\n\n void reply.send({ success: true, data: member });\n },\n );\n\n /**\n * DELETE /:orgId/members/:userId -- Remove a member\n */\n fastify.delete(\n `${basePath}/:orgId/members/:userId`,\n { preHandler: withAuth(fastify.requireOrgRole(['owner', 'admin'])) },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const { orgId, userId } = request.params as { orgId: string; userId: string };\n\n const member = await adapter.getMember(orgId, userId);\n if (!member) {\n sendError(reply, 404, 'NOT_FOUND', 'Member not found');\n return;\n }\n\n // Prevent removing the last owner\n if (member.role === 'owner') {\n const members = await adapter.listMembers(orgId);\n const ownerCount = members.filter((m: MemberDoc) => m.role === 'owner').length;\n if (ownerCount <= 1) {\n sendError(\n reply,\n 400,\n 'LAST_OWNER',\n 'Cannot remove the last owner. Transfer ownership or delete the organization.',\n );\n return;\n }\n }\n\n await adapter.removeMember(orgId, userId);\n void reply.send({ success: true, message: 'Member removed' });\n },\n );\n\n // --------------------------------------------------\n // Invitation routes (optional)\n // --------------------------------------------------\n\n if (enableInvitations && adapter.invitations) {\n const inv = adapter.invitations;\n\n /**\n * POST /:orgId/invitations -- Create invitation\n *\n * Body: { email: string; role: string; expiresAt?: string }\n */\n fastify.post(\n `${basePath}/:orgId/invitations`,\n { preHandler: withAuth(fastify.requireOrgRole(['owner', 'admin'])) },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const user = getUser(request);\n const userId = user ? getUserId(user) : undefined;\n if (!userId) {\n sendError(reply, 401, 'UNAUTHORIZED', 'Authentication required');\n return;\n }\n\n const { orgId } = request.params as { orgId: string };\n const body = request.body as { email?: string; role?: string; expiresAt?: string } | undefined;\n\n if (!body?.email || !body.role) {\n sendError(reply, 400, 'VALIDATION_ERROR', 'email and role are required');\n return;\n }\n\n if (!validRoleNames.has(body.role)) {\n sendError(\n reply,\n 400,\n 'INVALID_ROLE',\n `Invalid role '${body.role}'. Valid roles: ${[...validRoleNames].join(', ')}`,\n );\n return;\n }\n\n const defaultExpiry = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000); // 7 days\n const expiresAt = body.expiresAt ? new Date(body.expiresAt) : defaultExpiry;\n\n const invitation = await inv.create({\n orgId,\n email: body.email,\n role: body.role,\n invitedBy: userId,\n status: 'pending',\n expiresAt,\n });\n\n void reply.code(201).send({ success: true, data: invitation });\n },\n );\n\n /**\n * GET /:orgId/invitations -- List pending invitations\n */\n fastify.get(\n `${basePath}/:orgId/invitations`,\n { preHandler: withAuth(fastify.requireOrgRole(['owner', 'admin'])) },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const { orgId } = request.params as { orgId: string };\n const invitations = await inv.listPending(orgId);\n void reply.send({ success: true, data: invitations });\n },\n );\n\n /**\n * POST /invitations/:invitationId/accept -- Accept invitation\n */\n fastify.post(\n `${basePath}/invitations/:invitationId/accept`,\n { preHandler: withAuth() },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const { invitationId } = request.params as { invitationId: string };\n await inv.accept(invitationId);\n void reply.send({ success: true, message: 'Invitation accepted' });\n },\n );\n\n /**\n * POST /invitations/:invitationId/reject -- Reject invitation\n */\n fastify.post(\n `${basePath}/invitations/:invitationId/reject`,\n { preHandler: withAuth() },\n async (request: FastifyRequest, reply: FastifyReply) => {\n const { invitationId } = request.params as { invitationId: string };\n await inv.reject(invitationId);\n void reply.send({ success: true, message: 'Invitation rejected' });\n },\n );\n }\n\n fastify.log?.debug?.(\n { basePath, roles: [...validRoleNames], invitations: enableInvitations },\n 'Organization plugin registered',\n );\n};\n\nexport default fp(organizationPlugin, {\n name: 'arc-organization',\n fastify: '5.x',\n});\n\nexport { organizationPlugin };\n"],"mappings":"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"}
|
package/dist/org/types.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/org/types.ts"],"mappings":";;AAKA;;;UAAiB,MAAA;EACf,EAAA;EACA,IAAA;EACA,IAAA;EACA,OAAA;EACA,QAAA,GAAW,MAAA;EACX,SAAA,GAAY,IAAA;EACZ,SAAA,GAAY,IAAA;EAAA,CACX,GAAA;AAAA;AAAA,UAGc,SAAA;EACf,EAAA;EACA,KAAA;EACA,MAAA;EACA,IAAA;EACA,SAAA,GAAY,IAAA;EACZ,SAAA,GAAY,IAAA;EAAA,CACX,GAAA;AAAA;AAAA,UAGc,aAAA;EACf,EAAA;EACA,KAAA;EACA,KAAA;EACA,IAAA;EACA,SAAA;EACA,MAAA;EACA,SAAA,EAAW,IAAA;EACX,SAAA,GAAY,IAAA;AAAA;;UAIG,UAAA;EACf,SAAA,CAAU,IAAA;IAAQ,IAAA;IAAc,IAAA;IAAc,OAAA;IAAA,CAAkB,GAAA;EAAA,IAA0B,OAAA,CAAQ,MAAA;EAClG,MAAA,CAAO,EAAA,WAAa,OAAA,CAAQ,MAAA;EAC5B,YAAA,CAAa,IAAA,WAAe,OAAA,CAAQ,MAAA;EACpC,SAAA,CAAU,EAAA,UAAY,IAAA,EAAM,OAAA,CAAQ,MAAA,IAAU,OAAA,CAAQ,MAAA;EACtD,SAAA,CAAU,EAAA,WAAa,OAAA;EACvB,YAAA,CAAa,MAAA,WAAiB,OAAA,CAAQ,MAAA;EAEtC,SAAA,CAAU,KAAA,UAAe,MAAA,UAAgB,IAAA,WAAe,OAAA,CAAQ,SAAA;EAChE,YAAA,CAAa,KAAA,UAAe,MAAA,WAAiB,OAAA;EAC7C,SAAA,CAAU,KAAA,UAAe,MAAA,WAAiB,OAAA,CAAQ,SAAA;EAClD,WAAA,CAAY,KAAA,WAAgB,OAAA,CAAQ,SAAA;EACpC,gBAAA,CAAiB,KAAA,UAAe,MAAA,UAAgB,IAAA,WAAe,OAAA,CAAQ,SAAA;EAEvE,WAAA,GAAc,iBAAA;AAAA;AAAA,UAGC,iBAAA;EACf,MAAA,CAAO,IAAA,EAAM,IAAA,CAAK,aAAA,wBAAqC,OAAA,CAAQ,aAAA;EAC/D,UAAA,CAAW,KAAA,WAAgB,OAAA,CAAQ,aAAA;EACnC,MAAA,CAAO,EAAA,WAAa,OAAA;EACpB,MAAA,CAAO,EAAA,WAAa,OAAA;EACpB,WAAA,CAAY,KAAA,WAAgB,OAAA,CAAQ,aAAA;AAAA;;UAIrB,sBAAA;EACf,QAAA;EACA,MAAA;AAAA;;UAIe,OAAA;EACf,IAAA;EACA,WAAA,EAAa,sBAAA;AAAA;AAAA,UAGE,yBAAA;EACf,OAAA,EAAS,UAAA;EA5ByC;EA8BlD,KAAA,GAAQ,OAAA;EA7B4B;EA+BpC,QAAA;EA9BuE;EAgCvE,iBAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/permissions/index.ts"],"mappings":";;;;;;UAiCiB,6BAAA;EAMb;;;;EADF,sBAAA,GACE,GAAA,EAAK,iBAAA,KAEH,MAAA,SAAe,MAAA,+BACf,OAAA,CAAQ,MAAA,SAAe,MAAA;EAAA;;;;EAK3B,UAAA,GAAa,UAAA,CAAW,MAAA,SAAe,MAAA;EAEvC;EAAA,MAAA,GAAS,WAAA;EAKT;;;;EAAA,KAAA;IAME,gCAJA,KAAA,UAIU;IAFV,GAAA,IAAO,GAAA,EAAK,iBAAA,gCAOmB;IAL/B,UAAA;EAAA;AAAA;;UAKa,kBAAA;EACf,OAAA,MAAa,IAAA,UAAc,OAAA,EAAS,CAAA,KAAM,OAAA;EAC1C,SAAA,GACE,OAAA,UACA,OAAA,GAAU,KAAA;IAAS,OAAA;EAAA,aAA8B,OAAA,WAC9C,OAAA;AAAA;AAAA,UAGU,oBAAA;EAPY;EAS3B,oBAAA,IAAwB,KAAA,oBAAyB,OAAA;EARjD;EAUA,SAAA;AAAA;AAAA,UAGe,uBAAA;EACf,GAAA,GAAM,WAAA,EAAa,MAAA,gCAAsC,eAAA;EACzD,SAAA,GAAY,QAAA,UAAkB,MAAA,aAAmB,eAAA;EACjD,WAAA,MAAiB,KAAA,eAAoB,eAAA;EACrC,iBAAA,QAAyB,eAAA;EACzB,qBAAA,QAA6B,eAAA;EAZd;EAcf,eAAA,GAAkB,KAAA,aAAkB,OAAA;EACpC,UAAA,QAAkB,OAAA;EAbsC;;;;;;;AAK1D;EAkBE,aAAA,CACE,MAAA,EAAQ,kBAAA,EACR,OAAA,GAAU,oBAAA,GACT,OAAA;;EAGH,gBAAA,IAAoB,OAAA;EAvBqC;EAAA,SA0BhD,eAAA;AAAA;;;;;;;;;;;;iBA4DK,WAAA,CAAA,GAAe,eAAA;;;;;;;;;;;;iBAkBf,WAAA,CAAA,GAAe,eAAA;;;;;;;;;;;;AAlB/B;;;;;AAkBA;;;iBA6BgB,YAAA,CACd,KAAA,qBACA,OAAA;EAAY,WAAA;AAAA,IACX,eAAA;;;;;;;;;;AA2CH;;;;;;;iBAAgB,gBAAA,YAAA,CACd,UAAA,GAAY,OAAA,OAAc,IAAA,oBAC1B,OAAA;EAAY,WAAA;AAAA,IACX,eAAA,CAAgB,IAAA;;;;;;;;;;AAuCnB;;;;;iBAAgB,KAAA,CAAA,GAAS,MAAA,EAAQ,eAAA,KAAoB,eAAA;;;;AAwCrD;;;;;;;;;AAmCA;iBAnCgB,KAAA,CAAA,GAAS,MAAA,EAAQ,eAAA,KAAoB,eAAA;;;;AAiDrD;;;;;;;iBAdgB,OAAA,CAAQ,MAAA,YAA2B,eAAA;;;;;;;;;;;iBAcnC,IAAA,YAAA,CACd,SAAA,GAAY,GAAA,EAAK,iBAAA,CAAkB,IAAA,gBAAoB,OAAA,YACtD,eAAA,CAAgB,IAAA;;AAiCnB;;;;;;;;;AA+BA;;;;iBA/BgB,oBAAA,YAAA,CAAA,GAAoC,eAAA,CAAgB,IAAA;;;;;;AA0FpE;;;;;;;;;;iBA3DgB,cAAA,YAAA,CAAA,GACX,IAAA,mCACF,eAAA,CAAgB,IAAA;;;;;;;;;;;;;;;;;;;;;;AA2InB;;;;;iBAlFgB,oBAAA,CAAqB,MAAA;EACnC,UAAA,EAAY,MAAA;EACZ,KAAA,EAAO,MAAA,SAAe,MAAA;AAAA;EAEtB,GAAA,GAAM,WAAA,EAAa,MAAA,uBAA6B,eAAA;EAChD,WAAA,MAAiB,KAAA,eAAoB,eAAA;EACrC,iBAAA,QAAyB,eAAA;EACzB,qBAAA,QAA6B,eAAA;AAAA;;;;;;;;;;;;;iBA2Ef,6BAAA,CACd,MAAA,EAAQ,6BAAA,GACP,uBAAA;;;;;;;;;;;;;;;;iBAgUa,qBAAA,YAAA,CAAA,GAAqC,eAAA,CAAgB,IAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/permissions/index.ts"],"sourcesContent":["/**\r\n * Permission System\r\n *\r\n * Clean, function-based permission system.\r\n * PermissionCheck is THE ONLY way to define permissions.\r\n *\r\n * @example\r\n * ```typescript\r\n * import { allowPublic, requireAuth, requireRoles } from '@classytic/arc/permissions';\r\n *\r\n * defineResource({\r\n * permissions: {\r\n * list: allowPublic(),\r\n * get: allowPublic(),\r\n * create: requireAuth(),\r\n * update: requireRoles(['admin', 'editor']),\r\n * delete: requireRoles(['admin']),\r\n * }\r\n * });\r\n * ```\r\n */\r\n\r\n// Re-export types\r\nexport type {\r\n PermissionCheck,\r\n PermissionContext,\r\n PermissionResult,\r\n UserBase,\r\n} from \"./types.js\";\r\nimport { randomUUID } from \"node:crypto\";\r\nimport { MemoryCacheStore } from \"../cache/memory.js\";\r\nimport type { CacheLogger, CacheStore } from \"../cache/interface.js\";\r\n\r\nexport interface DynamicPermissionMatrixConfig {\r\n /**\r\n * Resolve role → resource → actions map dynamically (DB/API/config service).\r\n * Called at permission-check time (or cache miss if cache enabled).\r\n */\r\n resolveRolePermissions: (\r\n ctx: PermissionContext,\r\n ) =>\r\n | Record<string, Record<string, readonly string[]>>\r\n | Promise<Record<string, Record<string, readonly string[]>>>;\r\n /**\r\n * Optional cache store adapter.\r\n * Use MemoryCacheStore for single-instance apps or RedisCacheStore for distributed setups.\r\n */\r\n cacheStore?: CacheStore<Record<string, Record<string, readonly string[]>>>;\r\n /** Optional logger for cache/runtime failures (default: console) */\r\n logger?: CacheLogger;\r\n /**\r\n * Legacy convenience in-memory cache config.\r\n * If `cacheStore` is not provided and ttlMs > 0, Arc creates an internal MemoryCacheStore.\r\n */\r\n cache?: {\r\n /** Cache TTL in milliseconds */\r\n ttlMs: number;\r\n /** Optional custom cache key builder */\r\n key?: (ctx: PermissionContext) => string | null | undefined;\r\n /** Hard entry cap for internal memory store (default: 1000) */\r\n maxEntries?: number;\r\n };\r\n}\r\n\r\n/** Minimal publish/subscribe interface for cross-node cache invalidation. */\r\nexport interface PermissionEventBus {\r\n publish: <T>(type: string, payload: T) => Promise<void>;\r\n subscribe: (\r\n pattern: string,\r\n handler: (event: { payload: unknown }) => void | Promise<void>,\r\n ) => Promise<(() => void) | void>;\r\n}\r\n\r\nexport interface ConnectEventsOptions {\r\n /** Called on remote invalidation for app-specific cleanup (e.g., resolver cache) */\r\n onRemoteInvalidation?: (orgId: string) => void | Promise<void>;\r\n /** Custom event type (default: 'arc.permissions.invalidated') */\r\n eventType?: string;\r\n}\r\n\r\nexport interface DynamicPermissionMatrix {\r\n can: (permissions: Record<string, readonly string[]>) => PermissionCheck;\r\n canAction: (resource: string, action: string) => PermissionCheck;\r\n requireRole: (...roles: string[]) => PermissionCheck;\r\n requireMembership: () => PermissionCheck;\r\n requireTeamMembership: () => PermissionCheck;\r\n /** Invalidate cached permissions for a specific organization */\r\n invalidateByOrg: (orgId: string) => Promise<void>;\r\n clearCache: () => Promise<void>;\r\n\r\n /**\r\n * Connect to an event system for cross-node cache invalidation.\r\n *\r\n * Late-binding: call after the event plugin is registered (e.g., in onReady hook).\r\n * Once connected, `invalidateByOrg()` auto-publishes an event, and incoming\r\n * events from other nodes trigger local cache invalidation.\r\n * Echo is suppressed via per-process nodeId matching.\r\n */\r\n connectEvents(\r\n events: PermissionEventBus,\r\n options?: ConnectEventsOptions,\r\n ): Promise<void>;\r\n\r\n /** Disconnect from the event system. Safe to call even if never connected. */\r\n disconnectEvents(): Promise<void>;\r\n\r\n /** Whether events are currently connected. */\r\n readonly eventsConnected: boolean;\r\n}\r\n\r\n// Permission presets — common patterns in one call\r\nimport * as presets from \"./presets.js\";\r\nexport { presets as permissions };\r\nexport {\r\n publicRead,\r\n publicReadAdminWrite,\r\n authenticated,\r\n adminOnly,\r\n ownerWithAdminBypass,\r\n fullPublic,\r\n readOnly,\r\n} from \"./presets.js\";\r\n\r\n// Field-level permissions\r\nexport {\r\n fields,\r\n applyFieldReadPermissions,\r\n applyFieldWritePermissions,\r\n resolveEffectiveRoles,\r\n} from \"./fields.js\";\r\nexport type {\r\n FieldPermission,\r\n FieldPermissionMap,\r\n FieldPermissionType,\r\n} from \"./fields.js\";\r\n\r\nimport type {\r\n PermissionCheck,\r\n PermissionContext,\r\n PermissionResult,\r\n} from \"./types.js\";\r\nimport type { FastifyRequest } from \"fastify\";\r\nimport type { RequestScope } from \"../scope/types.js\";\r\nimport {\r\n isMember,\r\n isElevated,\r\n getOrgId,\r\n getOrgRoles,\r\n getTeamId,\r\n PUBLIC_SCOPE,\r\n} from \"../scope/types.js\";\r\n\r\n// ============================================================================\r\n// Permission Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Allow public access (no authentication required)\r\n *\r\n * @example\r\n * ```typescript\r\n * permissions: {\r\n * list: allowPublic(),\r\n * get: allowPublic(),\r\n * }\r\n * ```\r\n */\r\nexport function allowPublic(): PermissionCheck {\r\n const check: PermissionCheck = () => true;\r\n // Mark as public for OpenAPI documentation and introspection\r\n check._isPublic = true;\r\n return check;\r\n}\r\n\r\n/**\r\n * Require authentication (any authenticated user)\r\n *\r\n * @example\r\n * ```typescript\r\n * permissions: {\r\n * create: requireAuth(),\r\n * update: requireAuth(),\r\n * }\r\n * ```\r\n */\r\nexport function requireAuth(): PermissionCheck {\r\n const check: PermissionCheck = (ctx) => {\r\n if (!ctx.user) {\r\n return { granted: false, reason: \"Authentication required\" };\r\n }\r\n return true;\r\n };\r\n return check;\r\n}\r\n\r\n/**\r\n * Require specific roles\r\n *\r\n * @param roles - Required roles (user needs at least one)\r\n * @param options - Optional bypass roles\r\n *\r\n * @example\r\n * ```typescript\r\n * permissions: {\r\n * create: requireRoles(['admin', 'editor']),\r\n * delete: requireRoles(['admin']),\r\n * }\r\n *\r\n * // With bypass roles\r\n * permissions: {\r\n * update: requireRoles(['owner'], { bypassRoles: ['admin', 'superadmin'] }),\r\n * }\r\n * ```\r\n */\r\nexport function requireRoles(\r\n roles: readonly string[],\r\n options?: { bypassRoles?: readonly string[] },\r\n): PermissionCheck {\r\n const check: PermissionCheck = (ctx) => {\r\n if (!ctx.user) {\r\n return { granted: false, reason: \"Authentication required\" };\r\n }\r\n\r\n const userRoles = (ctx.user.roles ?? []) as string[];\r\n\r\n // Check bypass roles first\r\n if (options?.bypassRoles?.some((r) => userRoles.includes(r))) {\r\n return true;\r\n }\r\n\r\n // Check required roles (any match)\r\n if (roles.some((r) => userRoles.includes(r))) {\r\n return true;\r\n }\r\n\r\n return {\r\n granted: false,\r\n reason: `Required roles: ${roles.join(\", \")}`,\r\n };\r\n };\r\n check._roles = roles;\r\n return check;\r\n}\r\n\r\n/**\r\n * Require resource ownership\r\n *\r\n * Returns filters to scope queries to user's owned resources.\r\n *\r\n * @param ownerField - Field containing owner ID (default: 'userId')\r\n * @param options - Optional bypass roles\r\n *\r\n * @example\r\n * ```typescript\r\n * permissions: {\r\n * update: requireOwnership('userId'),\r\n * delete: requireOwnership('createdBy', { bypassRoles: ['admin'] }),\r\n * }\r\n * ```\r\n */\r\nexport function requireOwnership<TDoc = any>(\r\n ownerField: Extract<keyof TDoc, string> | string = \"userId\",\r\n options?: { bypassRoles?: readonly string[] },\r\n): PermissionCheck<TDoc> {\r\n return (ctx) => {\r\n if (!ctx.user) {\r\n return { granted: false, reason: \"Authentication required\" };\r\n }\r\n\r\n const userRoles = (ctx.user.roles ?? []) as string[];\r\n\r\n // Check bypass roles\r\n if (options?.bypassRoles?.some((r) => userRoles.includes(r))) {\r\n return true;\r\n }\r\n\r\n // Return filters to scope to owned resources\r\n const userId = ctx.user.id ?? ctx.user._id;\r\n if (!userId) {\r\n return { granted: false, reason: \"User identity missing (no id or _id)\" };\r\n }\r\n return {\r\n granted: true,\r\n filters: { [ownerField]: userId },\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Combine multiple checks - ALL must pass (AND logic)\r\n *\r\n * @example\r\n * ```typescript\r\n * permissions: {\r\n * update: allOf(\r\n * requireAuth(),\r\n * requireRoles(['editor']),\r\n * requireOwnership('createdBy')\r\n * ),\r\n * }\r\n * ```\r\n */\r\nexport function allOf(...checks: PermissionCheck[]): PermissionCheck {\r\n return async (ctx) => {\r\n let mergedFilters: Record<string, unknown> = {};\r\n\r\n for (const check of checks) {\r\n const result = await check(ctx);\r\n const normalized: PermissionResult =\r\n typeof result === \"boolean\" ? { granted: result } : result;\r\n\r\n if (!normalized.granted) {\r\n return normalized;\r\n }\r\n\r\n // Merge filters\r\n if (normalized.filters) {\r\n mergedFilters = { ...mergedFilters, ...normalized.filters };\r\n }\r\n }\r\n\r\n return {\r\n granted: true,\r\n filters:\r\n Object.keys(mergedFilters).length > 0 ? mergedFilters : undefined,\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Combine multiple checks - ANY must pass (OR logic)\r\n *\r\n * @example\r\n * ```typescript\r\n * permissions: {\r\n * update: anyOf(\r\n * requireRoles(['admin']),\r\n * requireOwnership('createdBy')\r\n * ),\r\n * }\r\n * ```\r\n */\r\nexport function anyOf(...checks: PermissionCheck[]): PermissionCheck {\r\n return async (ctx) => {\r\n const reasons: string[] = [];\r\n\r\n for (const check of checks) {\r\n const result = await check(ctx);\r\n const normalized: PermissionResult =\r\n typeof result === \"boolean\" ? { granted: result } : result;\r\n\r\n if (normalized.granted) {\r\n return normalized;\r\n }\r\n\r\n if (normalized.reason) {\r\n reasons.push(normalized.reason);\r\n }\r\n }\r\n\r\n return {\r\n granted: false,\r\n reason: reasons.join(\"; \"),\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Deny all access\r\n *\r\n * @example\r\n * ```typescript\r\n * permissions: {\r\n * delete: denyAll('Deletion not allowed'),\r\n * }\r\n * ```\r\n */\r\nexport function denyAll(reason = \"Access denied\"): PermissionCheck {\r\n return () => ({ granted: false, reason });\r\n}\r\n\r\n/**\r\n * Dynamic permission based on context\r\n *\r\n * @example\r\n * ```typescript\r\n * permissions: {\r\n * update: when((ctx) => ctx.data?.status === 'draft'),\r\n * }\r\n * ```\r\n */\r\nexport function when<TDoc = any>(\r\n condition: (ctx: PermissionContext<TDoc>) => boolean | Promise<boolean>,\r\n): PermissionCheck<TDoc> {\r\n return async (ctx) => {\r\n const result = await condition(ctx);\r\n return {\r\n granted: result,\r\n reason: result ? undefined : \"Condition not met\",\r\n };\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Organization Permission Helpers\r\n// ============================================================================\r\n\r\n/** Read request.scope safely */\r\nfunction getScope(request: FastifyRequest): RequestScope {\r\n return request.scope ?? PUBLIC_SCOPE;\r\n}\r\n\r\n/**\r\n * Require membership in the active organization.\r\n * User must be authenticated AND have an active org (member or elevated scope).\r\n *\r\n * Reads `request.scope` set by auth adapters.\r\n *\r\n * @example\r\n * ```typescript\r\n * permissions: {\r\n * list: requireOrgMembership(),\r\n * get: requireOrgMembership(),\r\n * }\r\n * ```\r\n */\r\nexport function requireOrgMembership<TDoc = any>(): PermissionCheck<TDoc> {\r\n const check: PermissionCheck<TDoc> = (ctx) => {\r\n if (!ctx.user) {\r\n return { granted: false, reason: \"Authentication required\" };\r\n }\r\n\r\n const scope = getScope(ctx.request);\r\n if (isElevated(scope)) return true;\r\n if (isMember(scope)) return true;\r\n\r\n return { granted: false, reason: \"Organization membership required\" };\r\n };\r\n check._orgPermission = \"membership\";\r\n return check;\r\n}\r\n\r\n/**\r\n * Require specific org-level roles.\r\n * Reads `request.scope.orgRoles` (set by auth adapters).\r\n * Elevated scope always passes (platform admin bypass).\r\n *\r\n * @param roles - Required org roles (user needs at least one)\r\n *\r\n * @example\r\n * ```typescript\r\n * permissions: {\r\n * create: requireOrgRole('admin', 'owner'),\r\n * delete: requireOrgRole('owner'),\r\n * }\r\n * ```\r\n */\r\nexport function requireOrgRole<TDoc = any>(\r\n ...args: string[] | [readonly string[]]\r\n): PermissionCheck<TDoc> {\r\n // Support both: requireOrgRole('admin', 'owner') and requireOrgRole(['admin', 'owner'])\r\n const roles: readonly string[] = Array.isArray(args[0])\r\n ? args[0]\r\n : (args as string[]);\r\n\r\n const check: PermissionCheck<TDoc> = (ctx) => {\r\n if (!ctx.user) {\r\n return { granted: false, reason: \"Authentication required\" };\r\n }\r\n\r\n const scope = getScope(ctx.request);\r\n if (isElevated(scope)) return true;\r\n\r\n if (!isMember(scope)) {\r\n return { granted: false, reason: \"Organization membership required\" };\r\n }\r\n\r\n if (roles.some((r) => scope.orgRoles.includes(r))) {\r\n return true;\r\n }\r\n\r\n return {\r\n granted: false,\r\n reason: `Required org roles: ${roles.join(\", \")}`,\r\n };\r\n };\r\n check._orgRoles = roles;\r\n return check;\r\n}\r\n\r\n/**\r\n * Create a scoped permission system for resource-action patterns.\r\n * Maps org roles to fine-grained permissions without external API calls.\r\n *\r\n * @example\r\n * ```typescript\r\n * const perms = createOrgPermissions({\r\n * statements: {\r\n * product: ['create', 'update', 'delete'],\r\n * order: ['create', 'approve'],\r\n * },\r\n * roles: {\r\n * owner: { product: ['create', 'update', 'delete'], order: ['create', 'approve'] },\r\n * admin: { product: ['create', 'update'], order: ['create'] },\r\n * member: { product: [], order: [] },\r\n * },\r\n * });\r\n *\r\n * defineResource({\r\n * permissions: {\r\n * create: perms.can({ product: ['create'] }),\r\n * delete: perms.can({ product: ['delete'] }),\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function createOrgPermissions(config: {\r\n statements: Record<string, readonly string[]>;\r\n roles: Record<string, Record<string, readonly string[]>>;\r\n}): {\r\n can: (permissions: Record<string, string[]>) => PermissionCheck;\r\n requireRole: (...roles: string[]) => PermissionCheck;\r\n requireMembership: () => PermissionCheck;\r\n requireTeamMembership: () => PermissionCheck;\r\n} {\r\n const { roles: roleMap } = config;\r\n\r\n function hasPermissions(\r\n orgRoles: string[],\r\n required: Record<string, string[]>,\r\n ): boolean {\r\n // User's effective permissions = union of all their role permissions\r\n for (const [resource, actions] of Object.entries(required)) {\r\n for (const action of actions) {\r\n const granted = orgRoles.some((role) => {\r\n const perms = roleMap[role]?.[resource];\r\n return perms?.includes(action);\r\n });\r\n if (!granted) return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n return {\r\n can(permissions: Record<string, string[]>): PermissionCheck {\r\n return (ctx) => {\r\n if (!ctx.user) {\r\n return { granted: false, reason: \"Authentication required\" };\r\n }\r\n\r\n const scope = getScope(ctx.request);\r\n if (isElevated(scope)) return true;\r\n\r\n if (!isMember(scope)) {\r\n return { granted: false, reason: \"Organization membership required\" };\r\n }\r\n\r\n if (hasPermissions(scope.orgRoles, permissions)) {\r\n return true;\r\n }\r\n\r\n const needed = Object.entries(permissions)\r\n .map(([r, a]) => `${r}:[${a.join(\",\")}]`)\r\n .join(\", \");\r\n return {\r\n granted: false,\r\n reason: `Missing permissions: ${needed}`,\r\n };\r\n };\r\n },\r\n\r\n requireRole(...roles: string[]): PermissionCheck {\r\n return requireOrgRole(roles);\r\n },\r\n\r\n requireMembership(): PermissionCheck {\r\n return requireOrgMembership();\r\n },\r\n\r\n requireTeamMembership(): PermissionCheck {\r\n return requireTeamMembership();\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Create a dynamic role-based permission matrix.\r\n *\r\n * Use this when role/action mappings are managed outside code\r\n * (e.g., admin UI matrix, DB-stored ACLs, remote policy service).\r\n *\r\n * Supports:\r\n * - org role union (any assigned org role can grant)\r\n * - global bypass roles\r\n * - wildcard resource/action (`*`)\r\n * - optional in-memory cache\r\n */\r\nexport function createDynamicPermissionMatrix(\r\n config: DynamicPermissionMatrixConfig,\r\n): DynamicPermissionMatrix {\r\n const logger = config.logger ?? console;\r\n const legacyTtlMs = config.cache?.ttlMs ?? 0;\r\n const hasExternalStore = !!config.cacheStore;\r\n const cacheTtlMs =\r\n legacyTtlMs > 0 ? legacyTtlMs : hasExternalStore ? 300_000 : 0;\r\n\r\n const internalStore =\r\n !config.cacheStore && cacheTtlMs > 0\r\n ? new MemoryCacheStore<Record<string, Record<string, readonly string[]>>>(\r\n {\r\n defaultTtlMs: cacheTtlMs,\r\n maxEntries: config.cache?.maxEntries ?? 1000,\r\n },\r\n )\r\n : undefined;\r\n\r\n const cacheStore = config.cacheStore ?? internalStore;\r\n const trackedKeys = new Set<string>();\r\n\r\n // ── Cross-node event bridge (late-binding) ───────────────────────\r\n const nodeId = randomUUID().slice(0, 8);\r\n const DEFAULT_EVENT_TYPE = \"arc.permissions.invalidated\";\r\n\r\n interface InternalEventBridge {\r\n publish: <T>(type: string, payload: T) => Promise<void>;\r\n unsubscribe: (() => void) | null;\r\n eventType: string;\r\n onRemoteInvalidation?: (orgId: string) => void | Promise<void>;\r\n }\r\n\r\n let eventBridge: InternalEventBridge | null = null;\r\n\r\n /** Clear local cache for an org without publishing events (avoids infinite loops). */\r\n async function localInvalidateByOrg(orgId: string): Promise<void> {\r\n if (!cacheStore) return;\r\n const prefix = `${orgId}::`;\r\n const toDelete: string[] = [];\r\n for (const key of trackedKeys) {\r\n if (key.startsWith(prefix)) toDelete.push(key);\r\n }\r\n for (const key of toDelete) {\r\n try {\r\n await cacheStore.delete(key);\r\n trackedKeys.delete(key);\r\n } catch (error) {\r\n logger.warn(\r\n `[DynamicPermissionMatrix] invalidateByOrg delete failed for '${key}': ${error instanceof Error ? error.message : String(error)}`,\r\n );\r\n }\r\n }\r\n }\r\n\r\n function isActionAllowed(\r\n actions: readonly string[] | undefined,\r\n action: string,\r\n ): boolean {\r\n if (!actions || actions.length === 0) return false;\r\n return actions.includes(\"*\") || actions.includes(action);\r\n }\r\n\r\n function roleAllows(\r\n matrix: Record<string, Record<string, readonly string[]>>,\r\n role: string,\r\n resource: string,\r\n action: string,\r\n ): boolean {\r\n const rolePermissions = matrix[role];\r\n if (!rolePermissions) return false;\r\n const resourceActions = rolePermissions[resource];\r\n const wildcardResourceActions = rolePermissions[\"*\"];\r\n return (\r\n isActionAllowed(resourceActions, action) ||\r\n isActionAllowed(wildcardResourceActions, action)\r\n );\r\n }\r\n\r\n function buildDefaultCacheKey(\r\n ctx: PermissionContext,\r\n orgId?: string,\r\n orgRoles?: string[],\r\n ): string {\r\n const userId = String(ctx.user?.id ?? ctx.user?._id ?? \"anon\");\r\n const roles = (orgRoles ?? []).slice().sort().join(\",\");\r\n return `${orgId ?? \"no-org\"}::${roles}::${userId}`;\r\n }\r\n\r\n async function resolveMatrix(\r\n ctx: PermissionContext,\r\n orgId?: string,\r\n orgRoles?: string[],\r\n ): Promise<Record<string, Record<string, readonly string[]>>> {\r\n if (!cacheStore) {\r\n return config.resolveRolePermissions(ctx);\r\n }\r\n\r\n const customKey = config.cache?.key?.(ctx);\r\n const cacheKey = customKey ?? buildDefaultCacheKey(ctx, orgId, orgRoles);\r\n\r\n if (!cacheKey) {\r\n return config.resolveRolePermissions(ctx);\r\n }\r\n\r\n try {\r\n const hit = await cacheStore.get(cacheKey);\r\n if (hit) return hit;\r\n } catch (error) {\r\n logger.warn(\r\n `[DynamicPermissionMatrix] Cache get failed for '${cacheKey}': ${error instanceof Error ? error.message : String(error)}`,\r\n );\r\n }\r\n\r\n const value = await config.resolveRolePermissions(ctx);\r\n\r\n try {\r\n await cacheStore.set(cacheKey, value, { ttlMs: cacheTtlMs });\r\n trackedKeys.add(cacheKey);\r\n\r\n // Cap tracked keys to prevent unbounded memory growth\r\n const maxTracked = config.cache?.maxEntries ?? 10_000;\r\n if (trackedKeys.size > maxTracked) {\r\n const overflow = trackedKeys.size - maxTracked;\r\n const iter = trackedKeys.values();\r\n for (let i = 0; i < overflow; i++) {\r\n const oldest = iter.next().value;\r\n if (oldest) trackedKeys.delete(oldest);\r\n }\r\n }\r\n } catch (error) {\r\n logger.warn(\r\n `[DynamicPermissionMatrix] Cache set failed for '${cacheKey}': ${error instanceof Error ? error.message : String(error)}`,\r\n );\r\n }\r\n\r\n return value;\r\n }\r\n\r\n function can(required: Record<string, readonly string[]>): PermissionCheck {\r\n return async (ctx) => {\r\n if (!ctx.user) {\r\n return { granted: false, reason: \"Authentication required\" };\r\n }\r\n\r\n const scope = getScope(ctx.request);\r\n if (isElevated(scope)) return true;\r\n\r\n if (!isMember(scope)) {\r\n return { granted: false, reason: \"Organization membership required\" };\r\n }\r\n\r\n const orgRoles = scope.orgRoles;\r\n if (orgRoles.length === 0) {\r\n return { granted: false, reason: \"Not a member of this organization\" };\r\n }\r\n\r\n let matrix: Record<string, Record<string, readonly string[]>>;\r\n try {\r\n matrix = await resolveMatrix(ctx, scope.organizationId, orgRoles);\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error);\r\n return {\r\n granted: false,\r\n reason: `Permission matrix resolution failed: ${message}`,\r\n };\r\n }\r\n\r\n for (const [resource, actions] of Object.entries(required)) {\r\n for (const action of actions) {\r\n const granted = orgRoles.some((role) =>\r\n roleAllows(matrix, role, resource, action),\r\n );\r\n if (!granted) {\r\n return {\r\n granted: false,\r\n reason: `Missing permission: ${resource}:${action}`,\r\n };\r\n }\r\n }\r\n }\r\n\r\n return true;\r\n };\r\n }\r\n\r\n return {\r\n can,\r\n canAction(resource: string, action: string): PermissionCheck {\r\n return can({ [resource]: [action] });\r\n },\r\n requireRole(...roles: string[]): PermissionCheck {\r\n return requireOrgRole(roles);\r\n },\r\n requireMembership(): PermissionCheck {\r\n return requireOrgMembership();\r\n },\r\n requireTeamMembership(): PermissionCheck {\r\n return requireTeamMembership();\r\n },\r\n async invalidateByOrg(orgId: string): Promise<void> {\r\n await localInvalidateByOrg(orgId);\r\n\r\n // Publish cross-node invalidation event (fail-open)\r\n if (eventBridge) {\r\n try {\r\n await eventBridge.publish(eventBridge.eventType, { orgId, nodeId });\r\n } catch (error) {\r\n logger.warn(\r\n `[DynamicPermissionMatrix] Failed to publish invalidation event for org '${orgId}': ${error instanceof Error ? error.message : String(error)}`,\r\n );\r\n }\r\n }\r\n },\r\n async clearCache(): Promise<void> {\r\n if (!cacheStore) return;\r\n\r\n if (cacheStore.clear) {\r\n try {\r\n await cacheStore.clear();\r\n trackedKeys.clear();\r\n return;\r\n } catch (error) {\r\n logger.warn(\r\n `[DynamicPermissionMatrix] cacheStore.clear failed: ${error instanceof Error ? error.message : String(error)}`,\r\n );\r\n }\r\n }\r\n\r\n // Fallback for stores without clear(): delete known keys for this process.\r\n for (const key of trackedKeys) {\r\n try {\r\n await cacheStore.delete(key);\r\n } catch (error) {\r\n logger.warn(\r\n `[DynamicPermissionMatrix] Cache delete failed for '${key}': ${error instanceof Error ? error.message : String(error)}`,\r\n );\r\n }\r\n }\r\n trackedKeys.clear();\r\n },\r\n\r\n async connectEvents(\r\n events: PermissionEventBus,\r\n options?: ConnectEventsOptions,\r\n ): Promise<void> {\r\n // Disconnect previous connection if any (idempotent reconnect)\r\n if (eventBridge) {\r\n await this.disconnectEvents();\r\n }\r\n\r\n const eventType = options?.eventType ?? DEFAULT_EVENT_TYPE;\r\n\r\n const unsubscribeFn = await events.subscribe(eventType, async (event) => {\r\n const payload = event.payload as\r\n | { orgId?: string; nodeId?: string }\r\n | undefined;\r\n if (!payload?.orgId) return;\r\n\r\n // Echo dedup: skip events published by this node\r\n if (payload.nodeId === nodeId) return;\r\n\r\n // Clear local permission matrix cache (no re-publish)\r\n await localInvalidateByOrg(payload.orgId);\r\n\r\n // App-specific cleanup callback\r\n if (options?.onRemoteInvalidation) {\r\n try {\r\n await options.onRemoteInvalidation(payload.orgId);\r\n } catch (error) {\r\n logger.warn(\r\n `[DynamicPermissionMatrix] onRemoteInvalidation callback failed for org '${payload.orgId}': ${error instanceof Error ? error.message : String(error)}`,\r\n );\r\n }\r\n }\r\n });\r\n\r\n eventBridge = {\r\n publish: events.publish,\r\n unsubscribe: typeof unsubscribeFn === \"function\" ? unsubscribeFn : null,\r\n eventType,\r\n onRemoteInvalidation: options?.onRemoteInvalidation,\r\n };\r\n },\r\n\r\n async disconnectEvents(): Promise<void> {\r\n if (!eventBridge) return;\r\n try {\r\n eventBridge.unsubscribe?.();\r\n } catch (error) {\r\n logger.warn(\r\n `[DynamicPermissionMatrix] disconnectEvents unsubscribe failed: ${error instanceof Error ? error.message : String(error)}`,\r\n );\r\n }\r\n eventBridge = null;\r\n },\r\n\r\n get eventsConnected(): boolean {\r\n return eventBridge !== null;\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Team Permission Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Require membership in the active team.\r\n * User must be authenticated, a member of the active org, AND have an active team.\r\n *\r\n * Better Auth teams are flat member groups (no team-level roles).\r\n * Reads `request.scope.teamId` set by the Better Auth adapter.\r\n *\r\n * @example\r\n * ```typescript\r\n * permissions: {\r\n * list: requireTeamMembership(),\r\n * create: requireTeamMembership(),\r\n * }\r\n * ```\r\n */\r\nexport function requireTeamMembership<TDoc = any>(): PermissionCheck<TDoc> {\r\n const check: PermissionCheck<TDoc> = (ctx) => {\r\n if (!ctx.user) {\r\n return { granted: false, reason: \"Authentication required\" };\r\n }\r\n\r\n const scope = getScope(ctx.request);\r\n if (isElevated(scope)) return true;\r\n\r\n if (!isMember(scope)) {\r\n return { granted: false, reason: \"Organization membership required\" };\r\n }\r\n\r\n const teamId = getTeamId(scope);\r\n if (!teamId) {\r\n return { granted: false, reason: \"No active team\" };\r\n }\r\n\r\n return true;\r\n };\r\n check._teamPermission = \"membership\";\r\n return check;\r\n}\r\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/plugins/requestId.ts","../../src/plugins/health.ts","../../src/plugins/gracefulShutdown.ts","../../src/plugins/createPlugin.ts","../../src/core/arcCorePlugin.ts"],"mappings":";;;;;;;;;;UAuBiB,gBAAA;EAOhB;EALC,MAAA;EAQU;EANV,SAAA;EAQW;EANX,iBAAA;AAAA;AAAA;EAAA,UAIU,cAAA;IAM8C;IAJtD,SAAA;EAAA;AAAA;AAAA,cAIE,eAAA,EAAiB,kBAAA,CAAmB,gBAAA;AAAA,cAAgB,UAAA;;;;YCd9C,cAAA;IACR,UAAA;EAAA;AAAA;AAAA,UAIa,WAAA;EDiDhB;EC/CC,IAAA;EDOqB;ECLrB,KAAA,QAAa,OAAA;EDK2C;ECHxD,OAAA;;EAEA,QAAA;AAAA;AAAA,UAGe,aAAA;;EAEf,MAAA;EAtBiE;EAwBjE,MAAA,GAAS,WAAA;;EAET,OAAA;EArBY;EAuBZ,gBAAA,SAAyB,OAAA;EAnBV;EAqBf,OAAA;;EAEA,kBAAA;AAAA;AAAA,cA4BI,YAAA,EAAc,kBAAA,CAAmB,aAAA;AAAA,cAAa,UAAA;;;UCjDnC,uBAAA;EFOyC;EELxD,OAAA;;EAEA,UAAA,SAAmB,OAAA;;EAEnB,OAAA,GAAU,MAAA,CAAO,OAAA;;EAEjB,SAAA;EDnBiE;;;;;;AASnE;;;ECoBE,WAAA,IAAe,MAAA;AAAA;AAAA,cAGX,sBAAA,EAAwB,kBAAA,CAAmB,uBAAA;AAAA;EAAA,UAoGrC,eAAA;IDnHV;ICqHE,QAAA,QAAgB,OAAA;EAAA;AAAA;AAAA,cAAO,UAAA;;;UC7GV,oBAAA;;EAEf,gBAAA,GAAmB,eAAA;EFtBP;EEwBZ,WAAA,GAAc,gBAAA;EFpBC;EEsBf,KAAA,GAAQ,UAAA;;EAER,aAAA,GAAgB,kBAAA;AAAA;AAAA,UAGD,sBAAA,mBACG,SAAA,GAAY,SAAA,wBACR,SAAA,GAAY,SAAA;EFzBrB;;;;EE+Bb,OAAA,IAAW,OAAA,EAAS,eAAA,EAAiB,IAAA,EAAM,SAAA,YAAqB,OAAA;EFxBjD;;;;EE8Bf,WAAA,IAAe,cAAA,EAAgB,SAAA,EAAW,IAAA,EAAM,aAAA,KAAkB,oBAAA;AAAA;AAAA,UAGnD,SAAA,mBACG,SAAA,GAAY,SAAA,wBACR,SAAA,GAAY,SAAA;EF7BlC;EAAA,SEgCS,IAAA;EF9BgB;;;;EEoCzB,OAAA,CAAQ,IAAA,GAAO,SAAA,GAAY,kBAAA,CAAmB,SAAA;EFJ1C;;;;EEUJ,WAAA,CAAY,IAAA,GAAO,aAAA,GAAgB,oBAAA;AAAA;;;;;;;;iBAcrB,YAAA,mBACI,SAAA,GAAY,SAAA,wBACR,SAAA,GAAY,SAAA,CAAA,CAElC,IAAA,UACA,UAAA,EAAY,sBAAA,CAAuB,SAAA,EAAW,aAAA,IAC7C,SAAA,CAAU,SAAA,EAAW,aAAA;;;UC5EP,oBAAA;;EAEf,UAAA;EJEwD;EIAxD,UAAA,GAAa,UAAA;;EAEb,QAAA,GAAW,gBAAA;AAAA;AAAA,UAGI,UAAA;EACf,IAAA;EACA,OAAA;EACA,OAAA,GAAU,MAAA;EACV,YAAA;AAAA;AAAA,UAGe,OAAA;EH1BL;EG4BV,KAAA,EAAO,UAAA;EH3BK;EG6BZ,QAAA,EAAU,gBAAA;EHzBgB;EG2B1B,UAAA;EHvBoB;EGyBpB,oBAAA,EAAsB,oBAAA;EHzBtB;EG2BA,OAAA,EAAS,GAAA,SAAY,UAAA;AAAA;AAAA;EAAA,UAIX,eAAA;IACR,GAAA,EAAK,OAAA;EAAA;AAAA;AAAA,cAIH,aAAA,EAAe,kBAAA,CAAmB,oBAAA;AAAA,cAAoB,QAAA"}
|