@geekmidas/constructs 9.0.2 → 10.0.0-alpha.1
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 +71 -44
- package/dist/{AWSScheduledFunction-Bn99MceY.d.cts → AWSScheduledFunction-9bJS4WdJ.d.cts} +8 -3
- package/dist/{AWSScheduledFunction-ysaCsdWx.d.mts.map → AWSScheduledFunction-9bJS4WdJ.d.cts.map} +1 -1
- package/dist/{AWSScheduledFunction-CufMMhGB.mjs → AWSScheduledFunction-BJjj8B5V.mjs} +3 -3
- package/dist/{AWSScheduledFunction-CufMMhGB.mjs.map → AWSScheduledFunction-BJjj8B5V.mjs.map} +1 -1
- package/dist/{AWSScheduledFunction-ysaCsdWx.d.mts → AWSScheduledFunction-BO5iEMSh.d.mts} +9 -4
- package/dist/{AWSScheduledFunction-Bn99MceY.d.cts.map → AWSScheduledFunction-BO5iEMSh.d.mts.map} +1 -1
- package/dist/{AWSScheduledFunction-DbkDr8CA.cjs → AWSScheduledFunction-qu4ieRZR.cjs} +9 -9
- package/dist/{AWSScheduledFunction-DbkDr8CA.cjs.map → AWSScheduledFunction-qu4ieRZR.cjs.map} +1 -1
- package/dist/{Construct-_1wX7p_Y.d.cts → Construct-B-xc0SE9.d.mts} +27 -5
- package/dist/Construct-B-xc0SE9.d.mts.map +1 -0
- package/dist/{Construct-r0U2zBwW.mjs → Construct-CdhThxDI.mjs} +3 -2
- package/dist/Construct-CdhThxDI.mjs.map +1 -0
- package/dist/{Construct-DCMuYOox.d.mts → Construct-WhCXIOPV.d.cts} +29 -7
- package/dist/Construct-WhCXIOPV.d.cts.map +1 -0
- package/dist/{Construct-vXMZJgRp.cjs → Construct-roId57cU.cjs} +7 -43
- package/dist/Construct-roId57cU.cjs.map +1 -0
- package/dist/{lazyAccessors-DmTG8sQH.cjs → Endpoint-BBkV6l0k.cjs} +869 -1079
- package/dist/Endpoint-BBkV6l0k.cjs.map +1 -0
- package/dist/{Endpoint-DgfRslct.d.cts → Endpoint-BKR5QH6O.d.mts} +57 -8
- package/dist/Endpoint-BKR5QH6O.d.mts.map +1 -0
- package/dist/{Endpoint-CLPSIl6S.d.mts → Endpoint-BQ9O0P1w.d.cts} +58 -9
- package/dist/Endpoint-BQ9O0P1w.d.cts.map +1 -0
- package/dist/{lazyAccessors-DfqZR6C4.mjs → Endpoint-BTj58Gob.mjs} +840 -1003
- package/dist/Endpoint-BTj58Gob.mjs.map +1 -0
- package/dist/EndpointFactory-BejSTzbB.mjs +808 -0
- package/dist/EndpointFactory-BejSTzbB.mjs.map +1 -0
- package/dist/EndpointFactory-DYoGLaIT.cjs +850 -0
- package/dist/EndpointFactory-DYoGLaIT.cjs.map +1 -0
- package/dist/{HonoEndpointAdaptor-DJDT3PMx.mjs → HonoEndpointAdaptor-7aYNdqJq.mjs} +5 -4
- package/dist/HonoEndpointAdaptor-7aYNdqJq.mjs.map +1 -0
- package/dist/{HonoEndpointAdaptor-CkJENANP.cjs → HonoEndpointAdaptor-wMsCyMgt.cjs} +24 -23
- package/dist/HonoEndpointAdaptor-wMsCyMgt.cjs.map +1 -0
- package/dist/{Queue-DaxjwmOQ.d.cts → Queue-D6WeziRD.d.cts} +43 -4
- package/dist/Queue-D6WeziRD.d.cts.map +1 -0
- package/dist/{Queue-HBDf0fqz.d.mts → Queue-DpUeqdC8.d.mts} +43 -4
- package/dist/Queue-DpUeqdC8.d.mts.map +1 -0
- package/dist/{Subscriber-B69ngPwl.d.cts → Subscriber-4rBJgDKI.d.mts} +9 -4
- package/dist/{Subscriber-B69ngPwl.d.cts.map → Subscriber-4rBJgDKI.d.mts.map} +1 -1
- package/dist/{Subscriber-D8Xm-86W.d.mts → Subscriber-DVQowdyj.d.cts} +11 -6
- package/dist/Subscriber-DVQowdyj.d.cts.map +1 -0
- package/dist/{Topic-C5ZMfveW.d.cts → Topic-Ohx9dvWr.d.cts} +33 -2
- package/dist/Topic-Ohx9dvWr.d.cts.map +1 -0
- package/dist/{Topic-DT10AqHk.d.mts → Topic-cmy2jOUy.d.mts} +33 -2
- package/dist/Topic-cmy2jOUy.d.mts.map +1 -0
- package/dist/adaptors/aws.cjs +39 -26
- package/dist/adaptors/aws.cjs.map +1 -1
- package/dist/adaptors/aws.d.cts +24 -16
- package/dist/adaptors/aws.d.cts.map +1 -1
- package/dist/adaptors/aws.d.mts +25 -17
- package/dist/adaptors/aws.d.mts.map +1 -1
- package/dist/adaptors/aws.mjs +26 -14
- package/dist/adaptors/aws.mjs.map +1 -1
- package/dist/adaptors/hono.cjs +9 -6
- package/dist/adaptors/hono.d.cts +7 -6
- package/dist/adaptors/hono.d.cts.map +1 -1
- package/dist/adaptors/hono.d.mts +8 -7
- package/dist/adaptors/hono.d.mts.map +1 -1
- package/dist/adaptors/hono.mjs +9 -6
- package/dist/adaptors/testing.cjs +18 -14
- package/dist/adaptors/testing.cjs.map +1 -1
- package/dist/adaptors/testing.d.cts +7 -6
- package/dist/adaptors/testing.d.cts.map +1 -1
- package/dist/adaptors/testing.d.mts +11 -10
- package/dist/adaptors/testing.d.mts.map +1 -1
- package/dist/adaptors/testing.mjs +10 -7
- package/dist/adaptors/testing.mjs.map +1 -1
- package/dist/auth.cjs +165 -0
- package/dist/auth.cjs.map +1 -0
- package/dist/auth.d.cts +108 -0
- package/dist/auth.d.cts.map +1 -0
- package/dist/auth.d.mts +108 -0
- package/dist/auth.d.mts.map +1 -0
- package/dist/auth.mjs +164 -0
- package/dist/auth.mjs.map +1 -0
- package/dist/cache-0ANvRQnD.mjs +51 -0
- package/dist/cache-0ANvRQnD.mjs.map +1 -0
- package/dist/cache-3WSvAulx.cjs +57 -0
- package/dist/cache-3WSvAulx.cjs.map +1 -0
- package/dist/cache-CdQ7OLpR.d.cts +47 -0
- package/dist/cache-CdQ7OLpR.d.cts.map +1 -0
- package/dist/cache-DYoJFcfd.d.mts +47 -0
- package/dist/cache-DYoJFcfd.d.mts.map +1 -0
- package/dist/cache.cjs +3 -0
- package/dist/cache.d.cts +3 -0
- package/dist/cache.d.mts +3 -0
- package/dist/cache.mjs +3 -0
- package/dist/chunk-DWy1uDak.cjs +39 -0
- package/dist/clone-DblgEZZa.mjs +39 -0
- package/dist/clone-DblgEZZa.mjs.map +1 -0
- package/dist/clone-Dy0cR2SZ.cjs +45 -0
- package/dist/clone-Dy0cR2SZ.cjs.map +1 -0
- package/dist/construct-interface-BfjcOD_E.cjs +117 -0
- package/dist/construct-interface-BfjcOD_E.cjs.map +1 -0
- package/dist/construct-interface-BqwRNYA2.d.mts +131 -0
- package/dist/construct-interface-BqwRNYA2.d.mts.map +1 -0
- package/dist/construct-interface-D2nNkHUN.d.cts +131 -0
- package/dist/construct-interface-D2nNkHUN.d.cts.map +1 -0
- package/dist/construct-interface-Z4CpS8tK.mjs +81 -0
- package/dist/construct-interface-Z4CpS8tK.mjs.map +1 -0
- package/dist/construct-interface.cjs +8 -0
- package/dist/construct-interface.d.cts +2 -0
- package/dist/construct-interface.d.mts +2 -0
- package/dist/construct-interface.mjs +3 -0
- package/dist/credential.cjs +96 -0
- package/dist/credential.cjs.map +1 -0
- package/dist/credential.d.cts +61 -0
- package/dist/credential.d.cts.map +1 -0
- package/dist/credential.d.mts +61 -0
- package/dist/credential.d.mts.map +1 -0
- package/dist/credential.mjs +94 -0
- package/dist/credential.mjs.map +1 -0
- package/dist/crons/index.cjs +39 -37
- package/dist/crons/index.cjs.map +1 -1
- package/dist/crons/index.d.cts +21 -8
- package/dist/crons/index.d.cts.map +1 -1
- package/dist/crons/index.d.mts +29 -13
- package/dist/crons/index.d.mts.map +1 -1
- package/dist/crons/index.mjs +37 -36
- package/dist/crons/index.mjs.map +1 -1
- package/dist/database/kysely.cjs +181 -0
- package/dist/database/kysely.cjs.map +1 -0
- package/dist/database/kysely.d.cts +152 -0
- package/dist/database/kysely.d.cts.map +1 -0
- package/dist/database/kysely.d.mts +152 -0
- package/dist/database/kysely.d.mts.map +1 -0
- package/dist/database/kysely.mjs +180 -0
- package/dist/database/kysely.mjs.map +1 -0
- package/dist/email.cjs +59 -0
- package/dist/email.cjs.map +1 -0
- package/dist/email.d.cts +50 -0
- package/dist/email.d.cts.map +1 -0
- package/dist/email.d.mts +50 -0
- package/dist/email.d.mts.map +1 -0
- package/dist/email.mjs +58 -0
- package/dist/email.mjs.map +1 -0
- package/dist/endpoints/index.cjs +21 -747
- package/dist/endpoints/index.d.cts +7 -343
- package/dist/endpoints/index.d.mts +7 -342
- package/dist/endpoints/index.mjs +11 -738
- package/dist/file-server.cjs +154 -0
- package/dist/file-server.cjs.map +1 -0
- package/dist/file-server.d.cts +156 -0
- package/dist/file-server.d.cts.map +1 -0
- package/dist/file-server.d.mts +156 -0
- package/dist/file-server.d.mts.map +1 -0
- package/dist/file-server.mjs +152 -0
- package/dist/file-server.mjs.map +1 -0
- package/dist/functions/index.cjs +4 -2
- package/dist/functions/index.d.cts +3 -2
- package/dist/functions/index.d.mts +3 -2
- package/dist/functions/index.mjs +4 -2
- package/dist/{functions-B-qt91O7.mjs → functions-Cpff1uZH.mjs} +55 -51
- package/dist/functions-Cpff1uZH.mjs.map +1 -0
- package/dist/{functions-C8i1kCMM.cjs → functions-DukjG8ov.cjs} +62 -57
- package/dist/functions-DukjG8ov.cjs.map +1 -0
- package/dist/{index-BVs9DvIj.d.cts → index-BTvozlUD.d.cts} +36 -9
- package/dist/index-BTvozlUD.d.cts.map +1 -0
- package/dist/index-Cvz551AO.d.mts +419 -0
- package/dist/index-Cvz551AO.d.mts.map +1 -0
- package/dist/index-D5zqAJ2e.d.cts +419 -0
- package/dist/index-D5zqAJ2e.d.cts.map +1 -0
- package/dist/{index-DP6fqv0I.d.mts → index-L7pz0R0T.d.mts} +48 -19
- package/dist/index-L7pz0R0T.d.mts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +1 -1
- package/dist/lazyAccessors-DM6HcXQk.mjs +175 -0
- package/dist/lazyAccessors-DM6HcXQk.mjs.map +1 -0
- package/dist/lazyAccessors-DrJj8NpA.cjs +223 -0
- package/dist/lazyAccessors-DrJj8NpA.cjs.map +1 -0
- package/dist/object-storage.cjs +48 -0
- package/dist/object-storage.cjs.map +1 -0
- package/dist/object-storage.d.cts +36 -0
- package/dist/object-storage.d.cts.map +1 -0
- package/dist/object-storage.d.mts +36 -0
- package/dist/object-storage.d.mts.map +1 -0
- package/dist/object-storage.mjs +47 -0
- package/dist/object-storage.mjs.map +1 -0
- package/dist/{processAudits-CKjjivyz.cjs → processAudits-Bc8rz6Ev.cjs} +3 -3
- package/dist/{processAudits-CKjjivyz.cjs.map → processAudits-Bc8rz6Ev.cjs.map} +1 -1
- package/dist/{processAudits-ySnizdMG.mjs → processAudits-D89tICM4.mjs} +1 -1
- package/dist/{processAudits-ySnizdMG.mjs.map → processAudits-D89tICM4.mjs.map} +1 -1
- package/dist/{publisher-BrFOF847.mjs → publisher-CGEo8UKD.mjs} +1 -1
- package/dist/{publisher-BrFOF847.mjs.map → publisher-CGEo8UKD.mjs.map} +1 -1
- package/dist/{publisher-lFQleddL.cjs → publisher-CqGsXB2X.cjs} +1 -1
- package/dist/{publisher-lFQleddL.cjs.map → publisher-CqGsXB2X.cjs.map} +1 -1
- package/dist/queue/index.cjs +92 -30
- package/dist/queue/index.cjs.map +1 -1
- package/dist/queue/index.d.cts +19 -4
- package/dist/queue/index.d.cts.map +1 -1
- package/dist/queue/index.d.mts +22 -6
- package/dist/queue/index.d.mts.map +1 -1
- package/dist/queue/index.mjs +90 -29
- package/dist/queue/index.mjs.map +1 -1
- package/dist/rest-api.cjs +187 -0
- package/dist/rest-api.cjs.map +1 -0
- package/dist/rest-api.d.cts +221 -0
- package/dist/rest-api.d.cts.map +1 -0
- package/dist/rest-api.d.mts +221 -0
- package/dist/rest-api.d.mts.map +1 -0
- package/dist/rest-api.mjs +186 -0
- package/dist/rest-api.mjs.map +1 -0
- package/dist/site.cjs +48 -0
- package/dist/site.cjs.map +1 -0
- package/dist/site.d.cts +101 -0
- package/dist/site.d.cts.map +1 -0
- package/dist/site.d.mts +101 -0
- package/dist/site.d.mts.map +1 -0
- package/dist/site.mjs +47 -0
- package/dist/site.mjs.map +1 -0
- package/dist/subscribers/index.cjs +35 -27
- package/dist/subscribers/index.cjs.map +1 -1
- package/dist/subscribers/index.d.cts +20 -5
- package/dist/subscribers/index.d.cts.map +1 -1
- package/dist/subscribers/index.d.mts +23 -7
- package/dist/subscribers/index.d.mts.map +1 -1
- package/dist/subscribers/index.mjs +34 -27
- package/dist/subscribers/index.mjs.map +1 -1
- package/dist/surfaceEnv-BFXEms2f.cjs +39 -0
- package/dist/surfaceEnv-BFXEms2f.cjs.map +1 -0
- package/dist/surfaceEnv-C3Ktahea.mjs +27 -0
- package/dist/surfaceEnv-C3Ktahea.mjs.map +1 -0
- package/dist/{telemetry-3vdxGn4q.d.mts → telemetry-C3L0iS28.d.cts} +2 -2
- package/dist/{telemetry-3vdxGn4q.d.mts.map → telemetry-C3L0iS28.d.cts.map} +1 -1
- package/dist/{telemetry-Dqx-D3F7.d.cts → telemetry-D7bVFLGi.d.mts} +2 -2
- package/dist/{telemetry-Dqx-D3F7.d.cts.map → telemetry-D7bVFLGi.d.mts.map} +1 -1
- package/dist/topic/index.cjs +56 -13
- package/dist/topic/index.cjs.map +1 -1
- package/dist/topic/index.d.cts +2 -2
- package/dist/topic/index.d.cts.map +1 -1
- package/dist/topic/index.d.mts +2 -2
- package/dist/topic/index.d.mts.map +1 -1
- package/dist/topic/index.mjs +54 -12
- package/dist/topic/index.mjs.map +1 -1
- package/dist/{types-BDNGr7pv.d.mts → types-BlAkSuGI.d.cts} +1 -1
- package/dist/{types-BDNGr7pv.d.mts.map → types-BlAkSuGI.d.cts.map} +1 -1
- package/dist/{types-BdAaYDvd.d.cts → types-aKksMEWL.d.mts} +1 -1
- package/dist/{types-BdAaYDvd.d.cts.map → types-aKksMEWL.d.mts.map} +1 -1
- package/dist/types.d.cts +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +155 -23
- package/CHANGELOG.md +0 -396
- package/dist/Construct-DCMuYOox.d.mts.map +0 -1
- package/dist/Construct-_1wX7p_Y.d.cts.map +0 -1
- package/dist/Construct-r0U2zBwW.mjs.map +0 -1
- package/dist/Construct-vXMZJgRp.cjs.map +0 -1
- package/dist/Endpoint-CLPSIl6S.d.mts.map +0 -1
- package/dist/Endpoint-DgfRslct.d.cts.map +0 -1
- package/dist/HonoEndpointAdaptor-CkJENANP.cjs.map +0 -1
- package/dist/HonoEndpointAdaptor-DJDT3PMx.mjs.map +0 -1
- package/dist/Queue-DaxjwmOQ.d.cts.map +0 -1
- package/dist/Queue-HBDf0fqz.d.mts.map +0 -1
- package/dist/Subscriber-D8Xm-86W.d.mts.map +0 -1
- package/dist/Topic-C5ZMfveW.d.cts.map +0 -1
- package/dist/Topic-DT10AqHk.d.mts.map +0 -1
- package/dist/endpoints/index.cjs.map +0 -1
- package/dist/endpoints/index.d.cts.map +0 -1
- package/dist/endpoints/index.d.mts.map +0 -1
- package/dist/endpoints/index.mjs.map +0 -1
- package/dist/functions-B-qt91O7.mjs.map +0 -1
- package/dist/functions-C8i1kCMM.cjs.map +0 -1
- package/dist/index-BVs9DvIj.d.cts.map +0 -1
- package/dist/index-DP6fqv0I.d.mts.map +0 -1
- package/dist/lazyAccessors-DfqZR6C4.mjs.map +0 -1
- package/dist/lazyAccessors-DmTG8sQH.cjs.map +0 -1
- package/src/Construct.ts +0 -204
- package/src/__benchmarks__/build-time-optimization.bench.ts +0 -274
- package/src/__benchmarks__/endpoint.bench.ts +0 -494
- package/src/__benchmarks__/fixtures.ts +0 -241
- package/src/__benchmarks__/hono-adaptor.bench.ts +0 -533
- package/src/__benchmarks__/hono-server.bench.ts +0 -249
- package/src/__benchmarks__/response-builder.bench.ts +0 -428
- package/src/__benchmarks__/strategies/strategy-a-lazy-services.ts +0 -319
- package/src/__benchmarks__/strategies/strategy-c-middleware.ts +0 -530
- package/src/__benchmarks__/strategies/strategy-d-opt-in-events.ts +0 -567
- package/src/__tests__/Construct.environment.spec.ts +0 -704
- package/src/__tests__/publisher.setting.spec.ts +0 -508
- package/src/__tests__/publisher.spec.ts +0 -452
- package/src/adaptors/aws.ts +0 -6
- package/src/adaptors/hono.ts +0 -1
- package/src/adaptors/testing.ts +0 -11
- package/src/crons/AWSScheduledFunction.ts +0 -73
- package/src/crons/Cron.ts +0 -149
- package/src/crons/CronBuilder.ts +0 -271
- package/src/crons/__tests__/AWSScheduledFunction.spec.ts +0 -152
- package/src/crons/__tests__/Cron.spec.ts +0 -464
- package/src/crons/__tests__/CronBuilder.state-isolation.spec.ts +0 -227
- package/src/crons/index.ts +0 -12
- package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +0 -677
- package/src/endpoints/AmazonApiGatewayV1EndpointAdaptor.ts +0 -105
- package/src/endpoints/AmazonApiGatewayV2EndpointAdaptor.ts +0 -97
- package/src/endpoints/Authorizer.ts +0 -152
- package/src/endpoints/Endpoint.ts +0 -1287
- package/src/endpoints/EndpointBuilder.ts +0 -758
- package/src/endpoints/EndpointFactory.ts +0 -1148
- package/src/endpoints/HonoEndpointAdaptor.ts +0 -677
- package/src/endpoints/MswEndpointAdaptor.ts +0 -226
- package/src/endpoints/TestEndpointAdaptor.ts +0 -422
- package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.audits.spec.ts +0 -499
- package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.events.spec.ts +0 -560
- package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.spec.ts +0 -1304
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.audits.spec.ts +0 -626
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.events.spec.ts +0 -732
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.factory-publisher.spec.ts +0 -296
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.kysely-audit.integration.spec.ts +0 -951
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.responseType.spec.ts +0 -111
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.rls.spec.ts +0 -307
- package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.spec.ts +0 -629
- package/src/endpoints/__tests__/Authorizer.spec.ts +0 -286
- package/src/endpoints/__tests__/Endpoint.cookies.spec.ts +0 -207
- package/src/endpoints/__tests__/Endpoint.headers.spec.ts +0 -187
- package/src/endpoints/__tests__/Endpoint.manifest.spec.ts +0 -175
- package/src/endpoints/__tests__/Endpoint.spec.ts +0 -857
- package/src/endpoints/__tests__/EndpointBuilder.audit.spec.ts +0 -448
- package/src/endpoints/__tests__/EndpointBuilder.responseType.spec.ts +0 -47
- package/src/endpoints/__tests__/EndpointBuilder.spec.ts +0 -523
- package/src/endpoints/__tests__/EndpointFactory.authorizers.spec.ts +0 -492
- package/src/endpoints/__tests__/EndpointFactory.database-auditor.spec.ts +0 -509
- package/src/endpoints/__tests__/EndpointFactory.reference-audit.spec.ts +0 -190
- package/src/endpoints/__tests__/EndpointFactory.spec.ts +0 -479
- package/src/endpoints/__tests__/EndpointFactory.state-isolation.spec.ts +0 -155
- package/src/endpoints/__tests__/HonoEndpointAdaptor.audit-transactions.spec.ts +0 -703
- package/src/endpoints/__tests__/HonoEndpointAdaptor.audits.spec.ts +0 -632
- package/src/endpoints/__tests__/HonoEndpointAdaptor.events.spec.ts +0 -577
- package/src/endpoints/__tests__/HonoEndpointAdaptor.kysely-audit.integration.spec.ts +0 -1067
- package/src/endpoints/__tests__/HonoEndpointAdaptor.openapi.spec.ts +0 -317
- package/src/endpoints/__tests__/HonoEndpointAdaptor.pgboss-publisher.spec.ts +0 -289
- package/src/endpoints/__tests__/HonoEndpointAdaptor.responseType.spec.ts +0 -128
- package/src/endpoints/__tests__/HonoEndpointAdaptor.spec.ts +0 -1207
- package/src/endpoints/__tests__/MswEndpointAdaptor.spec.ts +0 -211
- package/src/endpoints/__tests__/ResponseBuilder.spec.ts +0 -235
- package/src/endpoints/__tests__/TestEndpointAdaptor.audits.spec.ts +0 -602
- package/src/endpoints/__tests__/TestEndpointAdaptor.spec.ts +0 -1044
- package/src/endpoints/__tests__/__snapshots__/HonoEndpointAdaptor.spec.ts.snap +0 -54
- package/src/endpoints/__tests__/endpoint-types.test.ts +0 -88
- package/src/endpoints/__tests__/helpers.spec.ts +0 -37
- package/src/endpoints/__tests__/lazyAccessors.spec.ts +0 -330
- package/src/endpoints/__tests__/processAudits.spec.ts +0 -631
- package/src/endpoints/audit.ts +0 -87
- package/src/endpoints/helpers.ts +0 -98
- package/src/endpoints/index.ts +0 -42
- package/src/endpoints/lazyAccessors.ts +0 -241
- package/src/endpoints/parseHonoQuery.ts +0 -16
- package/src/endpoints/parseQueryParams.ts +0 -32
- package/src/endpoints/processAudits.ts +0 -371
- package/src/endpoints/rls.ts +0 -67
- package/src/functions/AWSLambdaFunction.ts +0 -348
- package/src/functions/BaseFunctionBuilder.ts +0 -201
- package/src/functions/Function.ts +0 -238
- package/src/functions/FunctionBuilder.ts +0 -391
- package/src/functions/FunctionExecutionWrapper.ts +0 -216
- package/src/functions/TestFunctionAdaptor.ts +0 -217
- package/src/functions/__tests__/AWSLambdaFunctionAdaptor.spec.ts +0 -513
- package/src/functions/__tests__/Function.audits.spec.ts +0 -393
- package/src/functions/__tests__/Function.spec.ts +0 -477
- package/src/functions/__tests__/FunctionBuilder.state-isolation.spec.ts +0 -207
- package/src/functions/__tests__/TestFunctionAdaptor.spec.ts +0 -480
- package/src/functions/index.ts +0 -12
- package/src/index.ts +0 -23
- package/src/publisher.ts +0 -93
- package/src/queue/AWSLambdaQueueAdaptor.ts +0 -162
- package/src/queue/Queue.ts +0 -128
- package/src/queue/QueueBuilder.ts +0 -115
- package/src/queue/TestQueueAdaptor.ts +0 -63
- package/src/queue/__tests__/QueueBuilder.spec.ts +0 -137
- package/src/queue/index.ts +0 -12
- package/src/subscribers/AWSLambdaSubscriberAdaptor.ts +0 -342
- package/src/subscribers/Subscriber.ts +0 -117
- package/src/subscribers/SubscriberBuilder.ts +0 -186
- package/src/subscribers/TestSubscriberAdaptor.ts +0 -133
- package/src/subscribers/__tests__/AWSLambdaSubscriberAdaptor.spec.ts +0 -1018
- package/src/subscribers/__tests__/Subscriber.spec.ts +0 -430
- package/src/subscribers/__tests__/TestSubscriberAdaptor.spec.ts +0 -652
- package/src/subscribers/index.ts +0 -6
- package/src/telemetry.ts +0 -103
- package/src/topic/Topic.ts +0 -103
- package/src/topic/TopicBuilder.ts +0 -51
- package/src/topic/__tests__/TopicBuilder.spec.ts +0 -82
- package/src/topic/index.ts +0 -11
- package/src/types.ts +0 -13
- package/test.ts +0 -91
- package/tsconfig.json +0 -9
- package/tsdown.config.ts +0 -34
package/dist/auth.d.mts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Construct, Consumable } from "./construct-interface-BqwRNYA2.mjs";
|
|
2
|
+
import { AppSpec, ConstructName, Declaration } from "@geekmidas/manifest";
|
|
3
|
+
import { betterAuth } from "better-auth";
|
|
4
|
+
import { Service, ServiceRegisterOptions } from "@geekmidas/services";
|
|
5
|
+
import { Hono } from "hono";
|
|
6
|
+
|
|
7
|
+
//#region src/auth.d.ts
|
|
8
|
+
|
|
9
|
+
/** The server better-auth hands back. */
|
|
10
|
+
type AuthServer = ReturnType<typeof betterAuth>;
|
|
11
|
+
/** Everything better-auth takes, minus what the construct owns. */
|
|
12
|
+
type BetterAuthOptions = Omit<Parameters<typeof betterAuth>[0], 'database' | 'secret' | 'basePath' | 'baseURL'>;
|
|
13
|
+
interface BetterAuthConfig<TDatabase extends Consumable> {
|
|
14
|
+
/**
|
|
15
|
+
* The schema tenant its tables live in.
|
|
16
|
+
*
|
|
17
|
+
* A construct rather than a URL: the tenant already declares its schema and
|
|
18
|
+
* its role, and taking the declaration is what puts the edge in the graph
|
|
19
|
+
* instead of a connection string in two places.
|
|
20
|
+
*/
|
|
21
|
+
database: TDatabase;
|
|
22
|
+
/**
|
|
23
|
+
* Where the auth routes are mounted, e.g. `/api/auth`.
|
|
24
|
+
*
|
|
25
|
+
* Structural — it is part of the URL every client calls, so it cannot differ
|
|
26
|
+
* between stages the way the host can.
|
|
27
|
+
*/
|
|
28
|
+
basePath?: string;
|
|
29
|
+
/**
|
|
30
|
+
* The app that serves this auth server — its own container.
|
|
31
|
+
*
|
|
32
|
+
* An auth server holds the session secret and reaches the identity tables.
|
|
33
|
+
* Its own process is the default because sharing one means the surface it
|
|
34
|
+
* shares with can read both.
|
|
35
|
+
*/
|
|
36
|
+
app?: AppSpec;
|
|
37
|
+
/**
|
|
38
|
+
* The rest of better-auth's options: providers, plugins, email settings.
|
|
39
|
+
*
|
|
40
|
+
* A function when they need another construct — a magic-link plugin has to
|
|
41
|
+
* *send* the link, and the thing that sends mail is a construct whose client
|
|
42
|
+
* has to be registered. It is handed the same `ServiceRegisterOptions` this
|
|
43
|
+
* construct was, so the env parser flows through the graph rather than being
|
|
44
|
+
* imported out of application config.
|
|
45
|
+
*/
|
|
46
|
+
options?: BetterAuthOptions | ((options: ServiceRegisterOptions) => BetterAuthOptions | Promise<BetterAuthOptions>);
|
|
47
|
+
}
|
|
48
|
+
declare class BetterAuth<TName extends string = string, TDatabase extends Consumable = Consumable> implements Construct<TName, AuthServer> {
|
|
49
|
+
private readonly config;
|
|
50
|
+
readonly id: TName;
|
|
51
|
+
readonly service: Service<Uncapitalize<TName>, AuthServer>;
|
|
52
|
+
readonly basePath: string;
|
|
53
|
+
/**
|
|
54
|
+
* Declared once and read by both `declare()` and `connect()`, so the keys the
|
|
55
|
+
* target publishes and the keys the server reads cannot drift.
|
|
56
|
+
*/
|
|
57
|
+
private readonly keys;
|
|
58
|
+
constructor(id: ConstructName<TName>, config: BetterAuthConfig<TDatabase>);
|
|
59
|
+
/**
|
|
60
|
+
* A signing secret and a surface.
|
|
61
|
+
*
|
|
62
|
+
* The database is *not* declared here — the tenant that was passed in
|
|
63
|
+
* declares it, and declaring it twice is the duplication the whole model
|
|
64
|
+
* removes. What is declared is what this construct owns: the key it signs
|
|
65
|
+
* with, and the routes it answers on.
|
|
66
|
+
*
|
|
67
|
+
* One endpoint, wildcarded. Better Auth routes internally and the set of
|
|
68
|
+
* paths depends on which capabilities are enabled, so enumerating them here
|
|
69
|
+
* would be a copy of its router that goes stale on its next release. The
|
|
70
|
+
* surface's job is to send everything under `basePath` to one handler, which
|
|
71
|
+
* is exactly what the declaration says.
|
|
72
|
+
*/
|
|
73
|
+
declare(): Declaration[];
|
|
74
|
+
/**
|
|
75
|
+
* Better Auth's own migrations, for the app's migrate step.
|
|
76
|
+
*
|
|
77
|
+
* It brings its own schema — users, sessions, accounts, verifications — so
|
|
78
|
+
* the app never writes those tables and never gets to drift from them.
|
|
79
|
+
*/
|
|
80
|
+
migrations(options: ServiceRegisterOptions): Promise<() => Promise<void>>;
|
|
81
|
+
/**
|
|
82
|
+
* The server this surface runs as, built from its own declaration.
|
|
83
|
+
*
|
|
84
|
+
* A surface is a deploy unit, so something has to serve it, and the thing
|
|
85
|
+
* that knows how is the construct — not a generator writing a mount into
|
|
86
|
+
* somebody else's entry point. That is how the auth server came to be
|
|
87
|
+
* mounted by a hook in the application it was supposed to be separate from,
|
|
88
|
+
* and then to be served by nothing at all when the hook was deleted.
|
|
89
|
+
*
|
|
90
|
+
* The routes come from {@link declare}: one wildcard under `basePath`, read
|
|
91
|
+
* off the same declaration the manifest carries, so the surface the graph
|
|
92
|
+
* describes and the surface that answers requests cannot disagree.
|
|
93
|
+
*
|
|
94
|
+
* ```ts
|
|
95
|
+
* // .gkm/server/app.ts — the whole generated entry
|
|
96
|
+
* import { auth } from '@acme/constructs/auth.js';
|
|
97
|
+
* export const { app } = await auth.server({ envParser });
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
server(options: ServiceRegisterOptions): Promise<{
|
|
101
|
+
app: Hono;
|
|
102
|
+
}>;
|
|
103
|
+
private connect;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
106
|
+
//#endregion
|
|
107
|
+
export { AuthServer, BetterAuth, BetterAuthConfig, BetterAuthOptions };
|
|
108
|
+
//# sourceMappingURL=auth.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.mts","names":[],"sources":["../src/auth.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AA+FgC,KApDpB,UAAA,GAAa,UAoDO,CAAA,OApDW,UAoDX,CAAA;;AACF,KAlDlB,iBAAA,GAAoB,IAkDF,CAjD7B,UAiD6B,CAAA,OAjDX,UAiDW,CAAA,CAAA,CAAA,CAAA,EAAA,UAAA,GAAA,QAAA,GAAA,UAAA,GAAA,SAAA,CAAA;AAEhB,UA/CG,gBA+CH,CAAA,kBA/CsC,UA+CtC,CAAA,CAAA;EAAK;;;;;;;EAkBkC,QAA1B,EAzDhB,SAyDgB;EAAgB;;;;;;EAgHwB,QAAnB,CAAA,EAAA,MAAA;EAAO;AApIjC;;;;;;QAtBf;;;;;;;;;;YAWH,+BAES,2BACJ,oBAAoB,QAAQ;;cAKxB,4DAEM,aAAa,uBACnB,UAAU,OAAO;;eAEhB;oBACK,QAAQ,aAAa,QAAQ;;;;;;;kBAgB1C,cAAc,gBACO,iBAAiB;;;;;;;;;;;;;;;aAuChC;;;;;;;sBAyCD,yBACP,cAAc;;;;;;;;;;;;;;;;;;;;kBA+BK,yBAAyB;SAAe"}
|
package/dist/auth.mjs
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { edgeTo } from "./construct-interface-Z4CpS8tK.mjs";
|
|
2
|
+
import { canonicalId, environmentCase, provideKey, serviceKey } from "@geekmidas/manifest";
|
|
3
|
+
import { betterAuth } from "better-auth";
|
|
4
|
+
|
|
5
|
+
//#region src/auth.ts
|
|
6
|
+
const DEFAULT_BASE_PATH = "/api/auth";
|
|
7
|
+
var BetterAuth = class {
|
|
8
|
+
id;
|
|
9
|
+
service;
|
|
10
|
+
basePath;
|
|
11
|
+
/**
|
|
12
|
+
* Declared once and read by both `declare()` and `connect()`, so the keys the
|
|
13
|
+
* target publishes and the keys the server reads cannot drift.
|
|
14
|
+
*/
|
|
15
|
+
keys;
|
|
16
|
+
constructor(id, config) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
const canonical = canonicalId(id);
|
|
19
|
+
this.id = canonical;
|
|
20
|
+
this.basePath = config.basePath ?? DEFAULT_BASE_PATH;
|
|
21
|
+
const secretId = `${canonical}Secret`;
|
|
22
|
+
this.keys = {
|
|
23
|
+
secretId,
|
|
24
|
+
secret: environmentCase(secretId),
|
|
25
|
+
url: provideKey(canonical, "url"),
|
|
26
|
+
trustedOrigins: provideKey(canonical, "trustedOrigins"),
|
|
27
|
+
cookieDomain: provideKey(canonical, "cookieDomain")
|
|
28
|
+
};
|
|
29
|
+
this.service = {
|
|
30
|
+
serviceName: serviceKey(canonical),
|
|
31
|
+
register: (options) => this.connect(options)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A signing secret and a surface.
|
|
36
|
+
*
|
|
37
|
+
* The database is *not* declared here — the tenant that was passed in
|
|
38
|
+
* declares it, and declaring it twice is the duplication the whole model
|
|
39
|
+
* removes. What is declared is what this construct owns: the key it signs
|
|
40
|
+
* with, and the routes it answers on.
|
|
41
|
+
*
|
|
42
|
+
* One endpoint, wildcarded. Better Auth routes internally and the set of
|
|
43
|
+
* paths depends on which capabilities are enabled, so enumerating them here
|
|
44
|
+
* would be a copy of its router that goes stale on its next release. The
|
|
45
|
+
* surface's job is to send everything under `basePath` to one handler, which
|
|
46
|
+
* is exactly what the declaration says.
|
|
47
|
+
*/
|
|
48
|
+
declare() {
|
|
49
|
+
return [{
|
|
50
|
+
kind: "secret",
|
|
51
|
+
id: this.keys.secretId,
|
|
52
|
+
provides: [this.keys.secret]
|
|
53
|
+
}, {
|
|
54
|
+
kind: "rest-api",
|
|
55
|
+
id: this.id,
|
|
56
|
+
...this.config.app ? { app: this.config.app } : {},
|
|
57
|
+
provides: [
|
|
58
|
+
this.keys.url,
|
|
59
|
+
this.keys.trustedOrigins,
|
|
60
|
+
this.keys.cookieDomain
|
|
61
|
+
],
|
|
62
|
+
endpoints: [{
|
|
63
|
+
id: `${this.id}Handler`,
|
|
64
|
+
handler: `${this.id}.handler`,
|
|
65
|
+
method: "ANY",
|
|
66
|
+
path: `${this.basePath}/*`,
|
|
67
|
+
dependencies: [edgeTo(this.config.database)],
|
|
68
|
+
requires: [this.keys.secret]
|
|
69
|
+
}]
|
|
70
|
+
}];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Better Auth's own migrations, for the app's migrate step.
|
|
74
|
+
*
|
|
75
|
+
* It brings its own schema — users, sessions, accounts, verifications — so
|
|
76
|
+
* the app never writes those tables and never gets to drift from them.
|
|
77
|
+
*/
|
|
78
|
+
async migrations(options) {
|
|
79
|
+
const auth = await this.connect(options, { owner: true });
|
|
80
|
+
const { getMigrations } = await import("better-auth/db");
|
|
81
|
+
const { runMigrations } = await getMigrations(auth.options);
|
|
82
|
+
return runMigrations;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The server this surface runs as, built from its own declaration.
|
|
86
|
+
*
|
|
87
|
+
* A surface is a deploy unit, so something has to serve it, and the thing
|
|
88
|
+
* that knows how is the construct — not a generator writing a mount into
|
|
89
|
+
* somebody else's entry point. That is how the auth server came to be
|
|
90
|
+
* mounted by a hook in the application it was supposed to be separate from,
|
|
91
|
+
* and then to be served by nothing at all when the hook was deleted.
|
|
92
|
+
*
|
|
93
|
+
* The routes come from {@link declare}: one wildcard under `basePath`, read
|
|
94
|
+
* off the same declaration the manifest carries, so the surface the graph
|
|
95
|
+
* describes and the surface that answers requests cannot disagree.
|
|
96
|
+
*
|
|
97
|
+
* ```ts
|
|
98
|
+
* // .gkm/server/app.ts — the whole generated entry
|
|
99
|
+
* import { auth } from '@acme/constructs/auth.js';
|
|
100
|
+
* export const { app } = await auth.server({ envParser });
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
async server(options) {
|
|
104
|
+
const { Hono } = await import("hono");
|
|
105
|
+
const { cors } = await import("hono/cors");
|
|
106
|
+
const app = new Hono();
|
|
107
|
+
const server = await this.connect(options);
|
|
108
|
+
const { origins } = options.envParser.create((get) => ({ origins: get(this.keys.trustedOrigins).string().default("").transform((value) => value.split(",").map((origin) => origin.trim()).filter(Boolean)) })).parse();
|
|
109
|
+
app.use("*", cors({
|
|
110
|
+
origin: origins,
|
|
111
|
+
credentials: true,
|
|
112
|
+
maxAge: 3600
|
|
113
|
+
}));
|
|
114
|
+
const [surface] = this.declare().filter((d) => d.kind === "rest-api");
|
|
115
|
+
for (const endpoint of surface?.endpoints ?? []) {
|
|
116
|
+
const methods = endpoint.method === "ANY" ? [
|
|
117
|
+
"GET",
|
|
118
|
+
"POST",
|
|
119
|
+
"PUT",
|
|
120
|
+
"PATCH",
|
|
121
|
+
"DELETE",
|
|
122
|
+
"OPTIONS"
|
|
123
|
+
] : [endpoint.method];
|
|
124
|
+
app.on([...methods], endpoint.path, (c) => server.handler(c.req.raw));
|
|
125
|
+
}
|
|
126
|
+
return { app };
|
|
127
|
+
}
|
|
128
|
+
async connect(options, as = {}) {
|
|
129
|
+
const { secret, baseUrl, trustedOrigins, cookieDomain } = options.envParser.create((get) => ({
|
|
130
|
+
secret: get(this.keys.secret).string(),
|
|
131
|
+
baseUrl: get(this.keys.url).string(),
|
|
132
|
+
trustedOrigins: get(this.keys.trustedOrigins).string().default("").transform((value) => value.split(",").map((origin) => origin.trim()).filter(Boolean)),
|
|
133
|
+
cookieDomain: get(this.keys.cookieDomain).string().optional()
|
|
134
|
+
})).parse();
|
|
135
|
+
const tenant = this.config.database;
|
|
136
|
+
const source = as.owner && tenant.owner ? tenant.owner : tenant.service;
|
|
137
|
+
const db = await source.register(options);
|
|
138
|
+
const configure = this.config.options;
|
|
139
|
+
const configured = typeof configure === "function" ? await configure(options) : configure ?? {};
|
|
140
|
+
return betterAuth({
|
|
141
|
+
...configured,
|
|
142
|
+
secret,
|
|
143
|
+
baseURL: baseUrl,
|
|
144
|
+
basePath: this.basePath,
|
|
145
|
+
database: {
|
|
146
|
+
db,
|
|
147
|
+
type: "postgres"
|
|
148
|
+
},
|
|
149
|
+
trustedOrigins: [...trustedOrigins, ...configured.trustedOrigins && Array.isArray(configured.trustedOrigins) ? configured.trustedOrigins : []],
|
|
150
|
+
advanced: {
|
|
151
|
+
...configured.advanced,
|
|
152
|
+
...cookieDomain ? { crossSubDomainCookies: {
|
|
153
|
+
enabled: true,
|
|
154
|
+
domain: cookieDomain,
|
|
155
|
+
...configured.advanced?.crossSubDomainCookies
|
|
156
|
+
} } : {}
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
//#endregion
|
|
163
|
+
export { BetterAuth };
|
|
164
|
+
//# sourceMappingURL=auth.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.mjs","names":["id: ConstructName<TName>","config: BetterAuthConfig<TDatabase>","options: ServiceRegisterOptions","value: string","as: { owner?: boolean }","configured: BetterAuthOptions"],"sources":["../src/auth.ts"],"sourcesContent":["/**\n * `BetterAuth` — a declared auth server.\n *\n * It is three things at once, which is what makes it the construct that\n * exercises most of the model: a consumer of a database, a producer of an\n * authorizer, and a set of endpoints. This lands the first two.\n *\n * Its tables live in a schema tenant it is *given* — `orders.schema('AuthDb')`\n * — rather than one it invents. The tenant declares the schema and the role;\n * this declares the one thing left, the signing secret, and reads back the keys\n * it needs.\n *\n * :::caution\n * The isolation that arrangement is *for* — the application's own role holding\n * no grant on these tables, so a compromised handler cannot read sessions — does\n * **not hold yet**. No target creates the per-schema role: both connect as the\n * database owner, so today the tenant is a `search_path`, which is a namespace\n * and not a privilege boundary. See \"Roles are declared and never created\" in\n * `docs/design/constructs-outstanding.md`.\n * :::\n *\n * It declares its own surface, so where it answers, who may call it, and the\n * domain its cookies are scoped to all arrive as environment resolved by the\n * target — none of them guessed from a port, and none of them listed by hand in\n * application config.\n */\n\nimport {\n\ttype AppSpec,\n\ttype ConstructName,\n\tcanonicalId,\n\ttype Declaration,\n\tenvironmentCase,\n\tprovideKey,\n\tserviceKey,\n} from '@geekmidas/manifest';\nimport type { Service, ServiceRegisterOptions } from '@geekmidas/services';\nimport { betterAuth } from 'better-auth';\nimport type { Hono } from 'hono';\nimport type { Kysely } from 'kysely';\nimport { type Construct, type Consumable, edgeTo } from './construct-interface';\n\n/** The server better-auth hands back. */\nexport type AuthServer = ReturnType<typeof betterAuth>;\n\n/** Everything better-auth takes, minus what the construct owns. */\nexport type BetterAuthOptions = Omit<\n\tParameters<typeof betterAuth>[0],\n\t'database' | 'secret' | 'basePath' | 'baseURL'\n>;\n\nexport interface BetterAuthConfig<TDatabase extends Consumable> {\n\t/**\n\t * The schema tenant its tables live in.\n\t *\n\t * A construct rather than a URL: the tenant already declares its schema and\n\t * its role, and taking the declaration is what puts the edge in the graph\n\t * instead of a connection string in two places.\n\t */\n\tdatabase: TDatabase;\n\t/**\n\t * Where the auth routes are mounted, e.g. `/api/auth`.\n\t *\n\t * Structural — it is part of the URL every client calls, so it cannot differ\n\t * between stages the way the host can.\n\t */\n\tbasePath?: string;\n\t/**\n\t * The app that serves this auth server — its own container.\n\t *\n\t * An auth server holds the session secret and reaches the identity tables.\n\t * Its own process is the default because sharing one means the surface it\n\t * shares with can read both.\n\t */\n\tapp?: AppSpec;\n\t/**\n\t * The rest of better-auth's options: providers, plugins, email settings.\n\t *\n\t * A function when they need another construct — a magic-link plugin has to\n\t * *send* the link, and the thing that sends mail is a construct whose client\n\t * has to be registered. It is handed the same `ServiceRegisterOptions` this\n\t * construct was, so the env parser flows through the graph rather than being\n\t * imported out of application config.\n\t */\n\toptions?:\n\t\t| BetterAuthOptions\n\t\t| ((\n\t\t\t\toptions: ServiceRegisterOptions,\n\t\t ) => BetterAuthOptions | Promise<BetterAuthOptions>);\n}\n\nconst DEFAULT_BASE_PATH = '/api/auth';\n\nexport class BetterAuth<\n\tTName extends string = string,\n\tTDatabase extends Consumable = Consumable,\n> implements Construct<TName, AuthServer>\n{\n\treadonly id: TName;\n\treadonly service: Service<Uncapitalize<TName>, AuthServer>;\n\treadonly basePath: string;\n\n\t/**\n\t * Declared once and read by both `declare()` and `connect()`, so the keys the\n\t * target publishes and the keys the server reads cannot drift.\n\t */\n\tprivate readonly keys: {\n\t\tsecretId: string;\n\t\tsecret: string;\n\t\turl: string;\n\t\ttrustedOrigins: string;\n\t\tcookieDomain: string;\n\t};\n\n\tconstructor(\n\t\tid: ConstructName<TName>,\n\t\tprivate readonly config: BetterAuthConfig<TDatabase>,\n\t) {\n\t\tconst canonical = canonicalId(id as string);\n\n\t\tthis.id = canonical as TName;\n\t\tthis.basePath = config.basePath ?? DEFAULT_BASE_PATH;\n\n\t\t// A secret's name is its key: `Auth` signs with `AUTH_SECRET`, which is\n\t\t// also what better-auth's own tooling looks for.\n\t\tconst secretId = `${canonical}Secret`;\n\t\tthis.keys = {\n\t\t\tsecretId,\n\t\t\tsecret: environmentCase(secretId),\n\t\t\turl: provideKey(canonical, 'url'),\n\t\t\ttrustedOrigins: provideKey(canonical, 'trustedOrigins'),\n\t\t\tcookieDomain: provideKey(canonical, 'cookieDomain'),\n\t\t};\n\n\t\t// A field, not a getter: consumers cache services by object identity.\n\t\tthis.service = {\n\t\t\tserviceName: serviceKey(canonical) as Uncapitalize<TName>,\n\t\t\tregister: (options) => this.connect(options),\n\t\t};\n\t}\n\n\t/**\n\t * A signing secret and a surface.\n\t *\n\t * The database is *not* declared here — the tenant that was passed in\n\t * declares it, and declaring it twice is the duplication the whole model\n\t * removes. What is declared is what this construct owns: the key it signs\n\t * with, and the routes it answers on.\n\t *\n\t * One endpoint, wildcarded. Better Auth routes internally and the set of\n\t * paths depends on which capabilities are enabled, so enumerating them here\n\t * would be a copy of its router that goes stale on its next release. The\n\t * surface's job is to send everything under `basePath` to one handler, which\n\t * is exactly what the declaration says.\n\t */\n\tdeclare(): Declaration[] {\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'secret',\n\t\t\t\tid: this.keys.secretId,\n\t\t\t\tprovides: [this.keys.secret],\n\t\t\t},\n\t\t\t{\n\t\t\t\tkind: 'rest-api',\n\t\t\t\tid: this.id,\n\t\t\t\t...(this.config.app ? { app: this.config.app } : {}),\n\t\t\t\tprovides: [\n\t\t\t\t\tthis.keys.url,\n\t\t\t\t\tthis.keys.trustedOrigins,\n\t\t\t\t\tthis.keys.cookieDomain,\n\t\t\t\t],\n\t\t\t\tendpoints: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: `${this.id}Handler`,\n\t\t\t\t\t\thandler: `${this.id}.handler`,\n\t\t\t\t\t\tmethod: 'ANY',\n\t\t\t\t\t\tpath: `${this.basePath}/*`,\n\t\t\t\t\t\t// Read off the tenant rather than written down: this\n\t\t\t\t\t\t// construct takes whatever database it is given, and a\n\t\t\t\t\t\t// hardcoded kind is a second statement of a fact the\n\t\t\t\t\t\t// tenant already makes.\n\t\t\t\t\t\tdependencies: [edgeTo(this.config.database)],\n\t\t\t\t\t\trequires: [this.keys.secret],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t];\n\t}\n\n\t/**\n\t * Better Auth's own migrations, for the app's migrate step.\n\t *\n\t * It brings its own schema — users, sessions, accounts, verifications — so\n\t * the app never writes those tables and never gets to drift from them.\n\t */\n\tasync migrations(\n\t\toptions: ServiceRegisterOptions,\n\t): Promise<() => Promise<void>> {\n\t\t// As the owner, not the runtime role. Creating tables is DDL, and the\n\t\t// whole point of the split is that a handler's role cannot do it — so a\n\t\t// migrator that connected the way a handler does would fail on the first\n\t\t// `CREATE TABLE` rather than working by accident.\n\t\tconst auth = await this.connect(options, { owner: true });\n\t\tconst { getMigrations } = await import('better-auth/db');\n\t\tconst { runMigrations } = await getMigrations(auth.options);\n\n\t\treturn runMigrations;\n\t}\n\n\t/**\n\t * The server this surface runs as, built from its own declaration.\n\t *\n\t * A surface is a deploy unit, so something has to serve it, and the thing\n\t * that knows how is the construct — not a generator writing a mount into\n\t * somebody else's entry point. That is how the auth server came to be\n\t * mounted by a hook in the application it was supposed to be separate from,\n\t * and then to be served by nothing at all when the hook was deleted.\n\t *\n\t * The routes come from {@link declare}: one wildcard under `basePath`, read\n\t * off the same declaration the manifest carries, so the surface the graph\n\t * describes and the surface that answers requests cannot disagree.\n\t *\n\t * ```ts\n\t * // .gkm/server/app.ts — the whole generated entry\n\t * import { auth } from '@acme/constructs/auth.js';\n\t * export const { app } = await auth.server({ envParser });\n\t * ```\n\t */\n\tasync server(options: ServiceRegisterOptions): Promise<{ app: Hono }> {\n\t\tconst { Hono } = await import('hono');\n\t\tconst { cors } = await import('hono/cors');\n\t\tconst app = new Hono();\n\t\tconst server = await this.connect(options);\n\n\t\t// Who may call this surface, read off the graph. The same list Better\n\t\t// Auth checks for CSRF — it arrives as `<ID>_TRUSTED_ORIGINS`, composed\n\t\t// by the target from whatever declared an edge to this construct, so a\n\t\t// site that depends on the auth server is allowed to reach it and\n\t\t// nothing else is. Nobody writes an origin down.\n\t\tconst { origins } = options.envParser\n\t\t\t.create((get) => ({\n\t\t\t\torigins: get(this.keys.trustedOrigins)\n\t\t\t\t\t.string()\n\t\t\t\t\t.default('')\n\t\t\t\t\t.transform((value: string) =>\n\t\t\t\t\t\tvalue\n\t\t\t\t\t\t\t.split(',')\n\t\t\t\t\t\t\t.map((origin) => origin.trim())\n\t\t\t\t\t\t\t.filter(Boolean),\n\t\t\t\t\t),\n\t\t\t}))\n\t\t\t.parse();\n\n\t\tapp.use('*', cors({ origin: origins, credentials: true, maxAge: 3600 }));\n\n\t\t// Read off the declaration rather than restated here. `ANY` is every\n\t\t// method Better Auth routes internally, which is the reason the\n\t\t// declaration wildcards rather than enumerating.\n\t\tconst [surface] = this.declare().filter(\n\t\t\t(d): d is Extract<Declaration, { kind: 'rest-api' }> =>\n\t\t\t\td.kind === 'rest-api',\n\t\t);\n\n\t\tfor (const endpoint of surface?.endpoints ?? []) {\n\t\t\tconst methods =\n\t\t\t\tendpoint.method === 'ANY'\n\t\t\t\t\t? (['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'] as const)\n\t\t\t\t\t: ([endpoint.method] as const);\n\n\t\t\tapp.on([...methods], endpoint.path, (c) => server.handler(c.req.raw));\n\t\t}\n\n\t\treturn { app };\n\t}\n\n\tprivate async connect(\n\t\toptions: ServiceRegisterOptions,\n\t\tas: { owner?: boolean } = {},\n\t): Promise<AuthServer> {\n\t\tconst { secret, baseUrl, trustedOrigins, cookieDomain } = options.envParser\n\t\t\t.create((get) => ({\n\t\t\t\tsecret: get(this.keys.secret).string(),\n\t\t\t\t// The surface's own URL, resolved by the target — not guessed from\n\t\t\t\t// a port, which was wrong the moment the server moved to 3001.\n\t\t\t\tbaseUrl: get(this.keys.url).string(),\n\t\t\t\t// Better Auth's CSRF check applies to every caller, not just\n\t\t\t\t// browsers, so an API calling the auth server is rejected unless\n\t\t\t\t// its origin is trusted. The list is derived from the graph and\n\t\t\t\t// arrives as one comma-separated value, for the same reason every\n\t\t\t\t// other derived value arrives as a string: it crosses a process\n\t\t\t\t// boundary as env.\n\t\t\t\ttrustedOrigins: get(this.keys.trustedOrigins)\n\t\t\t\t\t.string()\n\t\t\t\t\t.default('')\n\t\t\t\t\t.transform((value) =>\n\t\t\t\t\t\tvalue\n\t\t\t\t\t\t\t.split(',')\n\t\t\t\t\t\t\t.map((origin) => origin.trim())\n\t\t\t\t\t\t\t.filter(Boolean),\n\t\t\t\t\t),\n\t\t\t\t// The domain a session cookie has to carry to be readable by a\n\t\t\t\t// frontend on a sibling host. Optional because there is often\n\t\t\t\t// nothing to widen to: locally everything shares `localhost`,\n\t\t\t\t// where cookies ignore the port and a `Domain` would only be a\n\t\t\t\t// value the browser refuses.\n\t\t\t\tcookieDomain: get(this.keys.cookieDomain).string().optional(),\n\t\t\t}))\n\t\t\t.parse();\n\n\t\t// The tenant's own client: one construct, one connection, so what auth\n\t\t// writes and what the browser inspects cannot be two different databases.\n\t\t// A migration asks the tenant for its owner connection, which the tenant\n\t\t// exposes as a `Service` and not as anything `.dependsOn()` would take.\n\t\tconst tenant = this.config.database as Consumable & {\n\t\t\towner?: Service<string, unknown>;\n\t\t};\n\t\tconst source = as.owner && tenant.owner ? tenant.owner : tenant.service;\n\n\t\tconst db = (await source.register(options)) as Kysely<\n\t\t\tRecord<string, never>\n\t\t>;\n\n\t\t// Hoisted: narrowing a property of `this` is not preserved across the\n\t\t// await, and the false branch is the plain-object form.\n\t\tconst configure = this.config.options;\n\t\tconst configured: BetterAuthOptions =\n\t\t\ttypeof configure === 'function'\n\t\t\t\t? await configure(options)\n\t\t\t\t: (configure ?? {});\n\n\t\treturn betterAuth({\n\t\t\t...configured,\n\t\t\tsecret,\n\t\t\tbaseURL: baseUrl,\n\t\t\tbasePath: this.basePath,\n\t\t\tdatabase: { db, type: 'postgres' },\n\t\t\t// Whatever the app added wins over the derived list rather than\n\t\t\t// replacing it: an origin nobody declared is still sometimes real.\n\t\t\ttrustedOrigins: [\n\t\t\t\t...trustedOrigins,\n\t\t\t\t...(configured.trustedOrigins &&\n\t\t\t\tArray.isArray(configured.trustedOrigins)\n\t\t\t\t\t? configured.trustedOrigins\n\t\t\t\t\t: []),\n\t\t\t],\n\t\t\tadvanced: {\n\t\t\t\t...configured.advanced,\n\t\t\t\t// Only when a domain was derived. Better Auth reads the presence\n\t\t\t\t// of this block as intent, so enabling it with no domain would\n\t\t\t\t// widen the cookie to whatever host happened to set it — and the\n\t\t\t\t// case with nothing to widen to is the common one, not an error.\n\t\t\t\t...(cookieDomain\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tcrossSubDomainCookies: {\n\t\t\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\t\t\tdomain: cookieDomain,\n\t\t\t\t\t\t\t\t...configured.advanced?.crossSubDomainCookies,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t});\n\t}\n}\n"],"mappings":";;;;;AA2FA,MAAM,oBAAoB;AAE1B,IAAa,aAAb,MAIA;CACC,AAAS;CACT,AAAS;CACT,AAAS;;;;;CAMT,AAAiB;CAQjB,YACCA,IACiBC,QAChB;EADgB;EAEjB,MAAM,YAAY,YAAY,GAAa;AAE3C,OAAK,KAAK;AACV,OAAK,WAAW,OAAO,YAAY;EAInC,MAAM,YAAY,EAAE,UAAU;AAC9B,OAAK,OAAO;GACX;GACA,QAAQ,gBAAgB,SAAS;GACjC,KAAK,WAAW,WAAW,MAAM;GACjC,gBAAgB,WAAW,WAAW,iBAAiB;GACvD,cAAc,WAAW,WAAW,eAAe;EACnD;AAGD,OAAK,UAAU;GACd,aAAa,WAAW,UAAU;GAClC,UAAU,CAAC,YAAY,KAAK,QAAQ,QAAQ;EAC5C;CACD;;;;;;;;;;;;;;;CAgBD,UAAyB;AACxB,SAAO,CACN;GACC,MAAM;GACN,IAAI,KAAK,KAAK;GACd,UAAU,CAAC,KAAK,KAAK,MAAO;EAC5B,GACD;GACC,MAAM;GACN,IAAI,KAAK;GACT,GAAI,KAAK,OAAO,MAAM,EAAE,KAAK,KAAK,OAAO,IAAK,IAAG,CAAE;GACnD,UAAU;IACT,KAAK,KAAK;IACV,KAAK,KAAK;IACV,KAAK,KAAK;GACV;GACD,WAAW,CACV;IACC,KAAK,EAAE,KAAK,GAAG;IACf,UAAU,EAAE,KAAK,GAAG;IACpB,QAAQ;IACR,OAAO,EAAE,KAAK,SAAS;IAKvB,cAAc,CAAC,OAAO,KAAK,OAAO,SAAS,AAAC;IAC5C,UAAU,CAAC,KAAK,KAAK,MAAO;GAC5B,CACD;EACD,CACD;CACD;;;;;;;CAQD,MAAM,WACLC,SAC+B;EAK/B,MAAM,OAAO,MAAM,KAAK,QAAQ,SAAS,EAAE,OAAO,KAAM,EAAC;EACzD,MAAM,EAAE,eAAe,GAAG,MAAM,OAAO;EACvC,MAAM,EAAE,eAAe,GAAG,MAAM,cAAc,KAAK,QAAQ;AAE3D,SAAO;CACP;;;;;;;;;;;;;;;;;;;;CAqBD,MAAM,OAAOA,SAAyD;EACrE,MAAM,EAAE,MAAM,GAAG,MAAM,OAAO;EAC9B,MAAM,EAAE,MAAM,GAAG,MAAM,OAAO;EAC9B,MAAM,MAAM,IAAI;EAChB,MAAM,SAAS,MAAM,KAAK,QAAQ,QAAQ;EAO1C,MAAM,EAAE,SAAS,GAAG,QAAQ,UAC1B,OAAO,CAAC,SAAS,EACjB,SAAS,IAAI,KAAK,KAAK,eAAe,CACpC,QAAQ,CACR,QAAQ,GAAG,CACX,UAAU,CAACC,UACX,MACE,MAAM,IAAI,CACV,IAAI,CAAC,WAAW,OAAO,MAAM,CAAC,CAC9B,OAAO,QAAQ,CACjB,CACF,GAAE,CACF,OAAO;AAET,MAAI,IAAI,KAAK,KAAK;GAAE,QAAQ;GAAS,aAAa;GAAM,QAAQ;EAAM,EAAC,CAAC;EAKxE,MAAM,CAAC,QAAQ,GAAG,KAAK,SAAS,CAAC,OAChC,CAAC,MACA,EAAE,SAAS,WACZ;AAED,OAAK,MAAM,YAAY,SAAS,aAAa,CAAE,GAAE;GAChD,MAAM,UACL,SAAS,WAAW,QAChB;IAAC;IAAO;IAAQ;IAAO;IAAS;IAAU;GAAU,IACpD,CAAC,SAAS,MAAO;AAEtB,OAAI,GAAG,CAAC,GAAG,OAAQ,GAAE,SAAS,MAAM,CAAC,MAAM,OAAO,QAAQ,EAAE,IAAI,IAAI,CAAC;EACrE;AAED,SAAO,EAAE,IAAK;CACd;CAED,MAAc,QACbD,SACAE,KAA0B,CAAE,GACN;EACtB,MAAM,EAAE,QAAQ,SAAS,gBAAgB,cAAc,GAAG,QAAQ,UAChE,OAAO,CAAC,SAAS;GACjB,QAAQ,IAAI,KAAK,KAAK,OAAO,CAAC,QAAQ;GAGtC,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC,QAAQ;GAOpC,gBAAgB,IAAI,KAAK,KAAK,eAAe,CAC3C,QAAQ,CACR,QAAQ,GAAG,CACX,UAAU,CAAC,UACX,MACE,MAAM,IAAI,CACV,IAAI,CAAC,WAAW,OAAO,MAAM,CAAC,CAC9B,OAAO,QAAQ,CACjB;GAMF,cAAc,IAAI,KAAK,KAAK,aAAa,CAAC,QAAQ,CAAC,UAAU;EAC7D,GAAE,CACF,OAAO;EAMT,MAAM,SAAS,KAAK,OAAO;EAG3B,MAAM,SAAS,GAAG,SAAS,OAAO,QAAQ,OAAO,QAAQ,OAAO;EAEhE,MAAM,KAAM,MAAM,OAAO,SAAS,QAAQ;EAM1C,MAAM,YAAY,KAAK,OAAO;EAC9B,MAAMC,oBACE,cAAc,aAClB,MAAM,UAAU,QAAQ,GACvB,aAAa,CAAE;AAEpB,SAAO,WAAW;GACjB,GAAG;GACH;GACA,SAAS;GACT,UAAU,KAAK;GACf,UAAU;IAAE;IAAI,MAAM;GAAY;GAGlC,gBAAgB,CACf,GAAG,gBACH,GAAI,WAAW,kBACf,MAAM,QAAQ,WAAW,eAAe,GACrC,WAAW,iBACX,CAAE,CACL;GACD,UAAU;IACT,GAAG,WAAW;IAKd,GAAI,eACD,EACA,uBAAuB;KACtB,SAAS;KACT,QAAQ;KACR,GAAG,WAAW,UAAU;IACxB,EACD,IACA,CAAE;GACL;EACD,EAAC;CACF;AACD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { canonicalId, provideKey, serviceKey } from "@geekmidas/manifest";
|
|
2
|
+
import { createCacheClient } from "@geekmidas/cache";
|
|
3
|
+
|
|
4
|
+
//#region src/cache.ts
|
|
5
|
+
var Cache$1 = class {
|
|
6
|
+
id;
|
|
7
|
+
service;
|
|
8
|
+
/**
|
|
9
|
+
* Declared once and read by both `declare()` and `connect()`, so the key the
|
|
10
|
+
* target publishes and the key the client reads cannot drift.
|
|
11
|
+
*/
|
|
12
|
+
key;
|
|
13
|
+
constructor(id, options = {}) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
const canonical = canonicalId(id);
|
|
16
|
+
this.id = canonical;
|
|
17
|
+
this.key = provideKey(canonical, "url");
|
|
18
|
+
this.service = {
|
|
19
|
+
serviceName: serviceKey(canonical),
|
|
20
|
+
register: (options$1) => this.connect(options$1)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
declare() {
|
|
24
|
+
return [{
|
|
25
|
+
kind: "cache",
|
|
26
|
+
id: this.id,
|
|
27
|
+
...this.options.of ? { of: this.options.of } : {},
|
|
28
|
+
...this.options.table ? { table: this.options.table } : {},
|
|
29
|
+
provides: [this.key]
|
|
30
|
+
}];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Builds the client from the single URL the target supplied.
|
|
34
|
+
*
|
|
35
|
+
* Any credential travels in that URL's userinfo rather than in a second key,
|
|
36
|
+
* for the same reason a Postgres password does: an address and the thing that
|
|
37
|
+
* opens it are one fact, and splitting them is one more thing to keep in step.
|
|
38
|
+
*
|
|
39
|
+
* The scheme selects the driver, so this construct imports no provider and
|
|
40
|
+
* an app that caches in Postgres never resolves a Redis client. Whoever
|
|
41
|
+
* assembles the application registers the drivers its target needs.
|
|
42
|
+
*/
|
|
43
|
+
async connect({ envParser }) {
|
|
44
|
+
const { url } = envParser.create((get) => ({ url: get(this.key).string() })).parse();
|
|
45
|
+
return createCacheClient(url);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { Cache$1 as Cache };
|
|
51
|
+
//# sourceMappingURL=cache-0ANvRQnD.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-0ANvRQnD.mjs","names":["Cache","id: ConstructName<TName>","options: CacheOptions","options"],"sources":["../src/cache.ts"],"sourcesContent":["/**\n * `Cache` — a declared key/value cache.\n *\n * The same three-package meeting point as `ObjectStorage` and `Email`: it\n * implements the construct contract, derives its env key through\n * `@geekmidas/manifest`, and hands back a `@geekmidas/cache` client.\n *\n * It names no provider — and unlike `Email`, it cannot name one protocol\n * either. Every mail backend speaks SMTP, so an `smtp://` URL is true of all of\n * them; cache backends genuinely differ, because Upstash speaks HTTP, a Redis\n * speaks its wire protocol, and a table in Postgres speaks SQL. So the scheme in\n * the URL picks the driver, exactly as it does for object storage, and which\n * drivers exist is the generated entry point's decision.\n *\n * The backend is chosen at deploy, not here. An app caching in Postgres and an\n * app caching in Upstash are the same application code.\n */\n\nimport { type Cache as CacheClient, createCacheClient } from '@geekmidas/cache';\nimport {\n\ttype ConstructName,\n\tcanonicalId,\n\ttype Declaration,\n\tprovideKey,\n\tserviceKey,\n} from '@geekmidas/manifest';\nimport type { Service, ServiceRegisterOptions } from '@geekmidas/services';\nimport type { Construct } from './construct-interface';\n\nexport interface CacheOptions {\n\t/**\n\t * The database this cache lives in.\n\t *\n\t * Set by `database.cache()` rather than written by hand — the point of the\n\t * method is that the parent's id comes from the parent rather than from a\n\t * string somebody has to keep in step.\n\t */\n\tof?: string;\n\t/** The table entries are kept in. Defaults to `cache`. */\n\ttable?: string;\n}\n\nexport class Cache<TName extends string = string>\n\timplements Construct<TName, CacheClient>\n{\n\treadonly id: TName;\n\treadonly service: Service<Uncapitalize<TName>, CacheClient>;\n\n\t/**\n\t * Declared once and read by both `declare()` and `connect()`, so the key the\n\t * target publishes and the key the client reads cannot drift.\n\t */\n\tprivate readonly key: string;\n\n\tconstructor(\n\t\tid: ConstructName<TName>,\n\t\tprivate readonly options: CacheOptions = {},\n\t) {\n\t\tconst canonical = canonicalId(id as string);\n\n\t\tthis.id = canonical as TName;\n\t\tthis.key = provideKey(canonical, 'url');\n\n\t\t// A field, not a getter: consumers cache services by object identity.\n\t\tthis.service = {\n\t\t\tserviceName: serviceKey(canonical) as Uncapitalize<TName>,\n\t\t\tregister: (options) => this.connect(options),\n\t\t};\n\t}\n\n\tdeclare(): Declaration[] {\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'cache',\n\t\t\t\tid: this.id,\n\t\t\t\t...(this.options.of ? { of: this.options.of } : {}),\n\t\t\t\t...(this.options.table ? { table: this.options.table } : {}),\n\t\t\t\tprovides: [this.key],\n\t\t\t},\n\t\t];\n\t}\n\n\t/**\n\t * Builds the client from the single URL the target supplied.\n\t *\n\t * Any credential travels in that URL's userinfo rather than in a second key,\n\t * for the same reason a Postgres password does: an address and the thing that\n\t * opens it are one fact, and splitting them is one more thing to keep in step.\n\t *\n\t * The scheme selects the driver, so this construct imports no provider and\n\t * an app that caches in Postgres never resolves a Redis client. Whoever\n\t * assembles the application registers the drivers its target needs.\n\t */\n\tprivate async connect({\n\t\tenvParser,\n\t}: ServiceRegisterOptions): Promise<CacheClient> {\n\t\tconst { url } = envParser\n\t\t\t.create((get) => ({ url: get(this.key).string() }))\n\t\t\t.parse();\n\n\t\treturn createCacheClient(url);\n\t}\n}\n"],"mappings":";;;;AA0CA,IAAaA,UAAb,MAEA;CACC,AAAS;CACT,AAAS;;;;;CAMT,AAAiB;CAEjB,YACCC,IACiBC,UAAwB,CAAE,GAC1C;EADgB;EAEjB,MAAM,YAAY,YAAY,GAAa;AAE3C,OAAK,KAAK;AACV,OAAK,MAAM,WAAW,WAAW,MAAM;AAGvC,OAAK,UAAU;GACd,aAAa,WAAW,UAAU;GAClC,UAAU,CAACC,cAAY,KAAK,QAAQA,UAAQ;EAC5C;CACD;CAED,UAAyB;AACxB,SAAO,CACN;GACC,MAAM;GACN,IAAI,KAAK;GACT,GAAI,KAAK,QAAQ,KAAK,EAAE,IAAI,KAAK,QAAQ,GAAI,IAAG,CAAE;GAClD,GAAI,KAAK,QAAQ,QAAQ,EAAE,OAAO,KAAK,QAAQ,MAAO,IAAG,CAAE;GAC3D,UAAU,CAAC,KAAK,GAAI;EACpB,CACD;CACD;;;;;;;;;;;;CAaD,MAAc,QAAQ,EACrB,WACwB,EAAwB;EAChD,MAAM,EAAE,KAAK,GAAG,UACd,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAE,GAAE,CAClD,OAAO;AAET,SAAO,kBAAkB,IAAI;CAC7B;AACD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-DWy1uDak.cjs');
|
|
2
|
+
const __geekmidas_manifest = require_chunk.__toESM(require("@geekmidas/manifest"));
|
|
3
|
+
const __geekmidas_cache = require_chunk.__toESM(require("@geekmidas/cache"));
|
|
4
|
+
|
|
5
|
+
//#region src/cache.ts
|
|
6
|
+
var Cache = class {
|
|
7
|
+
id;
|
|
8
|
+
service;
|
|
9
|
+
/**
|
|
10
|
+
* Declared once and read by both `declare()` and `connect()`, so the key the
|
|
11
|
+
* target publishes and the key the client reads cannot drift.
|
|
12
|
+
*/
|
|
13
|
+
key;
|
|
14
|
+
constructor(id, options = {}) {
|
|
15
|
+
this.options = options;
|
|
16
|
+
const canonical = (0, __geekmidas_manifest.canonicalId)(id);
|
|
17
|
+
this.id = canonical;
|
|
18
|
+
this.key = (0, __geekmidas_manifest.provideKey)(canonical, "url");
|
|
19
|
+
this.service = {
|
|
20
|
+
serviceName: (0, __geekmidas_manifest.serviceKey)(canonical),
|
|
21
|
+
register: (options$1) => this.connect(options$1)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
declare() {
|
|
25
|
+
return [{
|
|
26
|
+
kind: "cache",
|
|
27
|
+
id: this.id,
|
|
28
|
+
...this.options.of ? { of: this.options.of } : {},
|
|
29
|
+
...this.options.table ? { table: this.options.table } : {},
|
|
30
|
+
provides: [this.key]
|
|
31
|
+
}];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Builds the client from the single URL the target supplied.
|
|
35
|
+
*
|
|
36
|
+
* Any credential travels in that URL's userinfo rather than in a second key,
|
|
37
|
+
* for the same reason a Postgres password does: an address and the thing that
|
|
38
|
+
* opens it are one fact, and splitting them is one more thing to keep in step.
|
|
39
|
+
*
|
|
40
|
+
* The scheme selects the driver, so this construct imports no provider and
|
|
41
|
+
* an app that caches in Postgres never resolves a Redis client. Whoever
|
|
42
|
+
* assembles the application registers the drivers its target needs.
|
|
43
|
+
*/
|
|
44
|
+
async connect({ envParser }) {
|
|
45
|
+
const { url } = envParser.create((get) => ({ url: get(this.key).string() })).parse();
|
|
46
|
+
return (0, __geekmidas_cache.createCacheClient)(url);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
Object.defineProperty(exports, 'Cache', {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
get: function () {
|
|
54
|
+
return Cache;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=cache-3WSvAulx.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-3WSvAulx.cjs","names":["id: ConstructName<TName>","options: CacheOptions","options"],"sources":["../src/cache.ts"],"sourcesContent":["/**\n * `Cache` — a declared key/value cache.\n *\n * The same three-package meeting point as `ObjectStorage` and `Email`: it\n * implements the construct contract, derives its env key through\n * `@geekmidas/manifest`, and hands back a `@geekmidas/cache` client.\n *\n * It names no provider — and unlike `Email`, it cannot name one protocol\n * either. Every mail backend speaks SMTP, so an `smtp://` URL is true of all of\n * them; cache backends genuinely differ, because Upstash speaks HTTP, a Redis\n * speaks its wire protocol, and a table in Postgres speaks SQL. So the scheme in\n * the URL picks the driver, exactly as it does for object storage, and which\n * drivers exist is the generated entry point's decision.\n *\n * The backend is chosen at deploy, not here. An app caching in Postgres and an\n * app caching in Upstash are the same application code.\n */\n\nimport { type Cache as CacheClient, createCacheClient } from '@geekmidas/cache';\nimport {\n\ttype ConstructName,\n\tcanonicalId,\n\ttype Declaration,\n\tprovideKey,\n\tserviceKey,\n} from '@geekmidas/manifest';\nimport type { Service, ServiceRegisterOptions } from '@geekmidas/services';\nimport type { Construct } from './construct-interface';\n\nexport interface CacheOptions {\n\t/**\n\t * The database this cache lives in.\n\t *\n\t * Set by `database.cache()` rather than written by hand — the point of the\n\t * method is that the parent's id comes from the parent rather than from a\n\t * string somebody has to keep in step.\n\t */\n\tof?: string;\n\t/** The table entries are kept in. Defaults to `cache`. */\n\ttable?: string;\n}\n\nexport class Cache<TName extends string = string>\n\timplements Construct<TName, CacheClient>\n{\n\treadonly id: TName;\n\treadonly service: Service<Uncapitalize<TName>, CacheClient>;\n\n\t/**\n\t * Declared once and read by both `declare()` and `connect()`, so the key the\n\t * target publishes and the key the client reads cannot drift.\n\t */\n\tprivate readonly key: string;\n\n\tconstructor(\n\t\tid: ConstructName<TName>,\n\t\tprivate readonly options: CacheOptions = {},\n\t) {\n\t\tconst canonical = canonicalId(id as string);\n\n\t\tthis.id = canonical as TName;\n\t\tthis.key = provideKey(canonical, 'url');\n\n\t\t// A field, not a getter: consumers cache services by object identity.\n\t\tthis.service = {\n\t\t\tserviceName: serviceKey(canonical) as Uncapitalize<TName>,\n\t\t\tregister: (options) => this.connect(options),\n\t\t};\n\t}\n\n\tdeclare(): Declaration[] {\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'cache',\n\t\t\t\tid: this.id,\n\t\t\t\t...(this.options.of ? { of: this.options.of } : {}),\n\t\t\t\t...(this.options.table ? { table: this.options.table } : {}),\n\t\t\t\tprovides: [this.key],\n\t\t\t},\n\t\t];\n\t}\n\n\t/**\n\t * Builds the client from the single URL the target supplied.\n\t *\n\t * Any credential travels in that URL's userinfo rather than in a second key,\n\t * for the same reason a Postgres password does: an address and the thing that\n\t * opens it are one fact, and splitting them is one more thing to keep in step.\n\t *\n\t * The scheme selects the driver, so this construct imports no provider and\n\t * an app that caches in Postgres never resolves a Redis client. Whoever\n\t * assembles the application registers the drivers its target needs.\n\t */\n\tprivate async connect({\n\t\tenvParser,\n\t}: ServiceRegisterOptions): Promise<CacheClient> {\n\t\tconst { url } = envParser\n\t\t\t.create((get) => ({ url: get(this.key).string() }))\n\t\t\t.parse();\n\n\t\treturn createCacheClient(url);\n\t}\n}\n"],"mappings":";;;;;AA0CA,IAAa,QAAb,MAEA;CACC,AAAS;CACT,AAAS;;;;;CAMT,AAAiB;CAEjB,YACCA,IACiBC,UAAwB,CAAE,GAC1C;EADgB;EAEjB,MAAM,YAAY,sCAAY,GAAa;AAE3C,OAAK,KAAK;AACV,OAAK,MAAM,qCAAW,WAAW,MAAM;AAGvC,OAAK,UAAU;GACd,aAAa,qCAAW,UAAU;GAClC,UAAU,CAACC,cAAY,KAAK,QAAQA,UAAQ;EAC5C;CACD;CAED,UAAyB;AACxB,SAAO,CACN;GACC,MAAM;GACN,IAAI,KAAK;GACT,GAAI,KAAK,QAAQ,KAAK,EAAE,IAAI,KAAK,QAAQ,GAAI,IAAG,CAAE;GAClD,GAAI,KAAK,QAAQ,QAAQ,EAAE,OAAO,KAAK,QAAQ,MAAO,IAAG,CAAE;GAC3D,UAAU,CAAC,KAAK,GAAI;EACpB,CACD;CACD;;;;;;;;;;;;CAaD,MAAc,QAAQ,EACrB,WACwB,EAAwB;EAChD,MAAM,EAAE,KAAK,GAAG,UACd,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAE,GAAE,CAClD,OAAO;AAET,SAAO,yCAAkB,IAAI;CAC7B;AACD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Construct } from "./construct-interface-D2nNkHUN.cjs";
|
|
2
|
+
import { Service } from "@geekmidas/services";
|
|
3
|
+
import { ConstructName, Declaration } from "@geekmidas/manifest";
|
|
4
|
+
import { Cache } from "@geekmidas/cache";
|
|
5
|
+
|
|
6
|
+
//#region src/cache.d.ts
|
|
7
|
+
|
|
8
|
+
interface CacheOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The database this cache lives in.
|
|
11
|
+
*
|
|
12
|
+
* Set by `database.cache()` rather than written by hand — the point of the
|
|
13
|
+
* method is that the parent's id comes from the parent rather than from a
|
|
14
|
+
* string somebody has to keep in step.
|
|
15
|
+
*/
|
|
16
|
+
of?: string;
|
|
17
|
+
/** The table entries are kept in. Defaults to `cache`. */
|
|
18
|
+
table?: string;
|
|
19
|
+
}
|
|
20
|
+
declare class Cache$1<TName extends string = string> implements Construct<TName, Cache> {
|
|
21
|
+
private readonly options;
|
|
22
|
+
readonly id: TName;
|
|
23
|
+
readonly service: Service<Uncapitalize<TName>, Cache>;
|
|
24
|
+
/**
|
|
25
|
+
* Declared once and read by both `declare()` and `connect()`, so the key the
|
|
26
|
+
* target publishes and the key the client reads cannot drift.
|
|
27
|
+
*/
|
|
28
|
+
private readonly key;
|
|
29
|
+
constructor(id: ConstructName<TName>, options?: CacheOptions);
|
|
30
|
+
declare(): Declaration[];
|
|
31
|
+
/**
|
|
32
|
+
* Builds the client from the single URL the target supplied.
|
|
33
|
+
*
|
|
34
|
+
* Any credential travels in that URL's userinfo rather than in a second key,
|
|
35
|
+
* for the same reason a Postgres password does: an address and the thing that
|
|
36
|
+
* opens it are one fact, and splitting them is one more thing to keep in step.
|
|
37
|
+
*
|
|
38
|
+
* The scheme selects the driver, so this construct imports no provider and
|
|
39
|
+
* an app that caches in Postgres never resolves a Redis client. Whoever
|
|
40
|
+
* assembles the application registers the drivers its target needs.
|
|
41
|
+
*/
|
|
42
|
+
private connect;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
45
|
+
//#endregion
|
|
46
|
+
export { Cache$1 as Cache, CacheOptions };
|
|
47
|
+
//# sourceMappingURL=cache-CdQ7OLpR.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-CdQ7OLpR.d.cts","names":[],"sources":["../src/cache.ts"],"sourcesContent":[],"mappings":";;;;;;;AA2CqB,UAdJ,YAAA,CAcI;;;;;;;;;;;;cADR,kDACD,UAAU,OAAO;;eAEf;oBACK,QAAQ,aAAa,QAAQ;;;;;;kBAS1C,cAAc,kBACQ;aAchB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Construct } from "./construct-interface-BqwRNYA2.mjs";
|
|
2
|
+
import { ConstructName, Declaration } from "@geekmidas/manifest";
|
|
3
|
+
import { Cache } from "@geekmidas/cache";
|
|
4
|
+
import { Service } from "@geekmidas/services";
|
|
5
|
+
|
|
6
|
+
//#region src/cache.d.ts
|
|
7
|
+
|
|
8
|
+
interface CacheOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The database this cache lives in.
|
|
11
|
+
*
|
|
12
|
+
* Set by `database.cache()` rather than written by hand — the point of the
|
|
13
|
+
* method is that the parent's id comes from the parent rather than from a
|
|
14
|
+
* string somebody has to keep in step.
|
|
15
|
+
*/
|
|
16
|
+
of?: string;
|
|
17
|
+
/** The table entries are kept in. Defaults to `cache`. */
|
|
18
|
+
table?: string;
|
|
19
|
+
}
|
|
20
|
+
declare class Cache$1<TName extends string = string> implements Construct<TName, Cache> {
|
|
21
|
+
private readonly options;
|
|
22
|
+
readonly id: TName;
|
|
23
|
+
readonly service: Service<Uncapitalize<TName>, Cache>;
|
|
24
|
+
/**
|
|
25
|
+
* Declared once and read by both `declare()` and `connect()`, so the key the
|
|
26
|
+
* target publishes and the key the client reads cannot drift.
|
|
27
|
+
*/
|
|
28
|
+
private readonly key;
|
|
29
|
+
constructor(id: ConstructName<TName>, options?: CacheOptions);
|
|
30
|
+
declare(): Declaration[];
|
|
31
|
+
/**
|
|
32
|
+
* Builds the client from the single URL the target supplied.
|
|
33
|
+
*
|
|
34
|
+
* Any credential travels in that URL's userinfo rather than in a second key,
|
|
35
|
+
* for the same reason a Postgres password does: an address and the thing that
|
|
36
|
+
* opens it are one fact, and splitting them is one more thing to keep in step.
|
|
37
|
+
*
|
|
38
|
+
* The scheme selects the driver, so this construct imports no provider and
|
|
39
|
+
* an app that caches in Postgres never resolves a Redis client. Whoever
|
|
40
|
+
* assembles the application registers the drivers its target needs.
|
|
41
|
+
*/
|
|
42
|
+
private connect;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
45
|
+
//#endregion
|
|
46
|
+
export { Cache$1 as Cache, CacheOptions };
|
|
47
|
+
//# sourceMappingURL=cache-DYoJFcfd.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-DYoJFcfd.d.mts","names":[],"sources":["../src/cache.ts"],"sourcesContent":[],"mappings":";;;;;;;AA2CqB,UAdJ,YAAA,CAcI;;;;;;;;;;;;cADR,kDACD,UAAU,OAAO;;eAEf;oBACK,QAAQ,aAAa,QAAQ;;;;;;kBAS1C,cAAc,kBACQ;aAchB"}
|
package/dist/cache.cjs
ADDED
package/dist/cache.d.cts
ADDED
package/dist/cache.d.mts
ADDED
package/dist/cache.mjs
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __commonJS = (cb, mod) => function() {
|
|
9
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
13
|
+
key = keys[i];
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
15
|
+
get: ((k) => from[k]).bind(null, key),
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
22
|
+
value: mod,
|
|
23
|
+
enumerable: true
|
|
24
|
+
}) : target, mod));
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
|
|
28
|
+
Object.defineProperty(exports, '__commonJS', {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function () {
|
|
31
|
+
return __commonJS;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
Object.defineProperty(exports, '__toESM', {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get: function () {
|
|
37
|
+
return __toESM;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/clone.ts
|
|
2
|
+
/**
|
|
3
|
+
* Cloning a builder, without enumerating its fields.
|
|
4
|
+
*
|
|
5
|
+
* The builders were mutable singletons that reset themselves by listing every
|
|
6
|
+
* field at the end of `.handle()`. Two things followed from that, and both were
|
|
7
|
+
* real:
|
|
8
|
+
*
|
|
9
|
+
* A configured base could not be reused. `const fn = f.logger(log)` handed back
|
|
10
|
+
* `f` itself, and the first `.handle()` reset `_logger` to the default — so the
|
|
11
|
+
* second handler built from that base silently logged somewhere else. Every
|
|
12
|
+
* field in the reset block behaved the same way, which made
|
|
13
|
+
* `f.logger(l).timeout(60_000)` a base that worked exactly once.
|
|
14
|
+
*
|
|
15
|
+
* And a field left out of the reset list leaked into the next handler instead.
|
|
16
|
+
* `_constructs` was left out, so a function was granted a bucket a *previous*
|
|
17
|
+
* function had declared — an over-grant in the field a deploy reads to size an
|
|
18
|
+
* IAM policy.
|
|
19
|
+
*
|
|
20
|
+
* Both are the same defect: a hand-maintained list of fields that has to be
|
|
21
|
+
* edited every time a field is added, and is silent when it isn't. So this
|
|
22
|
+
* copies whatever the instance actually has, and the list stops existing. The
|
|
23
|
+
* prototype is carried over, so `instanceof` and every method still resolve,
|
|
24
|
+
* and the constructor is deliberately not re-run — this copies state rather
|
|
25
|
+
* than initialising it.
|
|
26
|
+
*
|
|
27
|
+
* Fields must be replaced rather than mutated in place: a clone and its parent
|
|
28
|
+
* share whatever array a field points at, so `_events.push(…)` would be seen by
|
|
29
|
+
* both. Every builder assigns a fresh array instead, which is what makes
|
|
30
|
+
* sharing the reference safe.
|
|
31
|
+
*/
|
|
32
|
+
function cloneWith(instance, delta) {
|
|
33
|
+
const next = Object.create(Object.getPrototypeOf(instance));
|
|
34
|
+
return Object.assign(next, instance, delta);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { cloneWith };
|
|
39
|
+
//# sourceMappingURL=clone-DblgEZZa.mjs.map
|