silgi 0.43.28 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -1
- package/dist/_virtual/_rolldown/runtime.mjs +5 -0
- package/dist/adapters/_fetch-adapter.d.mts +18 -0
- package/dist/adapters/_fetch-adapter.mjs +53 -0
- package/dist/adapters/astro.d.mts +15 -0
- package/dist/adapters/astro.mjs +31 -0
- package/dist/adapters/aws-lambda.d.mts +42 -0
- package/dist/adapters/aws-lambda.mjs +92 -0
- package/dist/adapters/express.d.mts +16 -0
- package/dist/adapters/express.mjs +110 -0
- package/dist/adapters/message-port.d.mts +42 -0
- package/dist/adapters/message-port.mjs +132 -0
- package/dist/adapters/nestjs.d.mts +25 -0
- package/dist/adapters/nestjs.mjs +83 -0
- package/dist/adapters/nextjs.d.mts +14 -0
- package/dist/adapters/nextjs.mjs +29 -0
- package/dist/adapters/peer.d.mts +27 -0
- package/dist/adapters/peer.mjs +36 -0
- package/dist/adapters/remix.d.mts +15 -0
- package/dist/adapters/remix.mjs +30 -0
- package/dist/adapters/solidstart.d.mts +12 -0
- package/dist/adapters/solidstart.mjs +29 -0
- package/dist/adapters/sveltekit.d.mts +14 -0
- package/dist/adapters/sveltekit.mjs +30 -0
- package/dist/broker/index.d.mts +62 -0
- package/dist/broker/index.mjs +153 -0
- package/dist/broker/nats.d.mts +33 -0
- package/dist/broker/nats.mjs +31 -0
- package/dist/broker/redis.d.mts +51 -0
- package/dist/broker/redis.mjs +92 -0
- package/dist/builder.d.mts +55 -0
- package/dist/builder.mjs +70 -0
- package/dist/callable.d.mts +19 -0
- package/dist/callable.mjs +42 -0
- package/dist/caller.mjs +90 -0
- package/dist/client/adapters/fetch/index.d.mts +15 -0
- package/dist/client/adapters/fetch/index.mjs +57 -0
- package/dist/client/adapters/ofetch/index.d.mts +55 -0
- package/dist/client/adapters/ofetch/index.mjs +91 -0
- package/dist/client/adapters/websocket/index.d.mts +20 -0
- package/dist/client/adapters/websocket/index.mjs +101 -0
- package/dist/client/client.d.mts +37 -0
- package/dist/client/client.mjs +80 -0
- package/dist/client/consume.d.mts +50 -0
- package/dist/client/consume.mjs +66 -0
- package/dist/client/dynamic-link.d.mts +16 -0
- package/dist/client/dynamic-link.mjs +19 -0
- package/dist/client/index.d.mts +6 -0
- package/dist/client/index.mjs +5 -0
- package/dist/client/interceptor.d.mts +31 -0
- package/dist/client/interceptor.mjs +34 -0
- package/dist/client/openapi.d.mts +29 -0
- package/dist/client/openapi.mjs +89 -0
- package/dist/client/plugins/batch.d.mts +26 -0
- package/dist/client/plugins/batch.mjs +64 -0
- package/dist/client/plugins/circuit-breaker.d.mts +24 -0
- package/dist/client/plugins/circuit-breaker.mjs +60 -0
- package/dist/client/plugins/csrf.d.mts +13 -0
- package/dist/client/plugins/csrf.mjs +20 -0
- package/dist/client/plugins/dedupe.d.mts +10 -0
- package/dist/client/plugins/dedupe.mjs +28 -0
- package/dist/client/plugins/index.d.mts +8 -0
- package/dist/client/plugins/index.mjs +8 -0
- package/dist/client/plugins/otel.d.mts +12 -0
- package/dist/client/plugins/otel.mjs +27 -0
- package/dist/client/plugins/retry.d.mts +34 -0
- package/dist/client/plugins/retry.mjs +79 -0
- package/dist/client/plugins/timeout.d.mts +10 -0
- package/dist/client/plugins/timeout.mjs +14 -0
- package/dist/client/server.d.mts +16 -0
- package/dist/client/server.mjs +59 -0
- package/dist/client/types.d.mts +29 -0
- package/dist/codec/devalue.d.mts +21 -0
- package/dist/codec/devalue.mjs +33 -0
- package/dist/codec/msgpack.d.mts +18 -0
- package/dist/codec/msgpack.mjs +45 -0
- package/dist/codec/sanitize.mjs +38 -0
- package/dist/codegen/emitters.d.mts +51 -0
- package/dist/codegen/emitters.mjs +143 -0
- package/dist/codegen/generate.d.mts +25 -0
- package/dist/codegen/generate.mjs +224 -0
- package/dist/codegen/index.d.mts +44 -0
- package/dist/codegen/index.mjs +103 -0
- package/dist/codegen/parse.d.mts +124 -0
- package/dist/codegen/parse.mjs +135 -0
- package/dist/codegen/preserve.d.mts +21 -0
- package/dist/codegen/preserve.mjs +62 -0
- package/dist/codegen/schema-to-code.d.mts +57 -0
- package/dist/codegen/schema-to-code.mjs +167 -0
- package/dist/compile.d.mts +46 -0
- package/dist/compile.mjs +332 -0
- package/dist/core/codec.mjs +67 -0
- package/dist/core/context-bridge.mjs +11 -0
- package/dist/core/dispatch.mjs +62 -0
- package/dist/core/error.d.mts +99 -60
- package/dist/core/error.mjs +125 -92
- package/dist/core/handler.d.mts +6 -0
- package/dist/core/handler.mjs +153 -0
- package/dist/core/input.mjs +49 -0
- package/dist/core/iterator.d.mts +17 -0
- package/dist/core/iterator.mjs +79 -0
- package/dist/core/router-utils.mjs +22 -0
- package/dist/core/schema.d.mts +20 -0
- package/dist/core/schema.mjs +33 -0
- package/dist/core/serve.d.mts +51 -0
- package/dist/core/serve.mjs +76 -0
- package/dist/core/sse.d.mts +18 -0
- package/dist/core/sse.mjs +110 -0
- package/dist/core/storage.d.mts +17 -4
- package/dist/core/storage.mjs +60 -13
- package/dist/core/task.d.mts +62 -0
- package/dist/core/task.mjs +165 -0
- package/dist/core/trace-map.d.mts +13 -0
- package/dist/core/trace-map.mjs +13 -0
- package/dist/core/url.mjs +28 -0
- package/dist/core/utils.mjs +24 -0
- package/dist/index.d.mts +17 -21
- package/dist/index.mjs +14 -22
- package/dist/integrations/ai/index.d.mts +25 -0
- package/dist/integrations/ai/index.mjs +117 -0
- package/dist/integrations/better-auth/index.d.mts +41 -0
- package/dist/integrations/better-auth/index.mjs +331 -0
- package/dist/integrations/drizzle/index.d.mts +27 -0
- package/dist/integrations/drizzle/index.mjs +285 -0
- package/dist/integrations/hey-api/index.d.mts +2 -0
- package/dist/integrations/hey-api/index.mjs +2 -0
- package/dist/integrations/hey-api/to-client.d.mts +20 -0
- package/dist/integrations/hey-api/to-client.mjs +39 -0
- package/dist/integrations/pinia-colada/general-utils.d.mts +13 -0
- package/dist/integrations/pinia-colada/general-utils.mjs +9 -0
- package/dist/integrations/pinia-colada/index.d.mts +6 -0
- package/dist/integrations/pinia-colada/index.mjs +5 -0
- package/dist/integrations/pinia-colada/key.d.mts +11 -0
- package/dist/integrations/pinia-colada/key.mjs +11 -0
- package/dist/integrations/pinia-colada/procedure-utils.d.mts +25 -0
- package/dist/integrations/pinia-colada/procedure-utils.mjs +33 -0
- package/dist/integrations/pinia-colada/router-utils.d.mts +17 -0
- package/dist/integrations/pinia-colada/router-utils.mjs +30 -0
- package/dist/integrations/pinia-colada/types.d.mts +25 -0
- package/dist/integrations/react/index.d.mts +83 -0
- package/dist/integrations/react/index.mjs +196 -0
- package/dist/integrations/tanstack-query/index.d.mts +120 -0
- package/dist/integrations/tanstack-query/index.mjs +100 -0
- package/dist/integrations/tanstack-query/ssr.d.mts +60 -0
- package/dist/integrations/tanstack-query/ssr.mjs +102 -0
- package/dist/integrations/zod/converter.d.mts +75 -0
- package/dist/integrations/zod/converter.mjs +345 -0
- package/dist/integrations/zod/index.d.mts +2 -0
- package/dist/integrations/zod/index.mjs +2 -0
- package/dist/lazy.d.mts +22 -0
- package/dist/lazy.mjs +34 -0
- package/dist/lifecycle.d.mts +36 -0
- package/dist/lifecycle.mjs +46 -0
- package/dist/map-input.d.mts +17 -0
- package/dist/map-input.mjs +47 -0
- package/dist/plugins/analytics/accumulator.d.mts +24 -0
- package/dist/plugins/analytics/accumulator.mjs +91 -0
- package/dist/plugins/analytics/alerts.d.mts +59 -0
- package/dist/plugins/analytics/alerts.mjs +140 -0
- package/dist/plugins/analytics/collector.d.mts +38 -0
- package/dist/plugins/analytics/collector.mjs +275 -0
- package/dist/plugins/analytics/cost.d.mts +61 -0
- package/dist/plugins/analytics/cost.mjs +97 -0
- package/dist/plugins/analytics/export.d.mts +7 -0
- package/dist/plugins/analytics/export.mjs +86 -0
- package/dist/plugins/analytics/normalize.mjs +144 -0
- package/dist/plugins/analytics/query.mjs +164 -0
- package/dist/plugins/analytics/request-id.mjs +34 -0
- package/dist/plugins/analytics/routes.d.mts +11 -0
- package/dist/plugins/analytics/routes.mjs +211 -0
- package/dist/plugins/analytics/sse.d.mts +31 -0
- package/dist/plugins/analytics/sse.mjs +74 -0
- package/dist/plugins/analytics/store.mjs +103 -0
- package/dist/plugins/analytics/timeseries.d.mts +50 -0
- package/dist/plugins/analytics/timeseries.mjs +169 -0
- package/dist/plugins/analytics/trace.d.mts +48 -0
- package/dist/plugins/analytics/trace.mjs +83 -0
- package/dist/plugins/analytics/types.d.mts +145 -0
- package/dist/plugins/analytics/types.mjs +40 -0
- package/dist/plugins/analytics/utils.d.mts +4 -0
- package/dist/plugins/analytics/utils.mjs +56 -0
- package/dist/plugins/analytics.d.mts +18 -0
- package/dist/plugins/analytics.mjs +188 -0
- package/dist/plugins/batch-server.d.mts +20 -0
- package/dist/plugins/batch-server.mjs +91 -0
- package/dist/plugins/body-limit.d.mts +19 -0
- package/dist/plugins/body-limit.mjs +49 -0
- package/dist/plugins/cache.d.mts +170 -0
- package/dist/plugins/cache.mjs +212 -0
- package/dist/plugins/coerce.d.mts +24 -0
- package/dist/plugins/coerce.mjs +70 -0
- package/dist/plugins/cookies.d.mts +14 -0
- package/dist/plugins/cookies.mjs +48 -0
- package/dist/plugins/cors.d.mts +43 -0
- package/dist/plugins/cors.mjs +62 -0
- package/dist/plugins/file-upload.d.mts +38 -0
- package/dist/plugins/file-upload.mjs +102 -0
- package/dist/plugins/index.d.mts +18 -0
- package/dist/plugins/index.mjs +17 -0
- package/dist/plugins/otel.d.mts +35 -0
- package/dist/plugins/otel.mjs +40 -0
- package/dist/plugins/pino.d.mts +60 -0
- package/dist/plugins/pino.mjs +42 -0
- package/dist/plugins/pubsub.d.mts +50 -0
- package/dist/plugins/pubsub.mjs +53 -0
- package/dist/plugins/ratelimit.d.mts +53 -0
- package/dist/plugins/ratelimit.mjs +92 -0
- package/dist/plugins/signing.d.mts +41 -0
- package/dist/plugins/signing.mjs +118 -0
- package/dist/plugins/strict-get.d.mts +10 -0
- package/dist/plugins/strict-get.mjs +33 -0
- package/dist/scalar.d.mts +49 -0
- package/dist/scalar.mjs +311 -0
- package/dist/silgi.d.mts +144 -0
- package/dist/silgi.mjs +164 -0
- package/dist/trpc-interop.d.mts +22 -0
- package/dist/trpc-interop.mjs +68 -0
- package/dist/types.d.mts +108 -0
- package/dist/ws.d.mts +88 -0
- package/dist/ws.mjs +205 -0
- package/lib/dashboard/index.html +120 -0
- package/lib/ocache.d.mts +1 -0
- package/lib/ocache.mjs +1 -0
- package/lib/ofetch.d.mts +1 -0
- package/lib/ofetch.mjs +1 -0
- package/lib/srvx.d.mts +1 -0
- package/lib/srvx.mjs +1 -0
- package/lib/unstorage.d.mts +1 -0
- package/lib/unstorage.mjs +1 -0
- package/package.json +314 -150
- package/dist/build.d.mts +0 -3
- package/dist/build.mjs +0 -4
- package/dist/cli/build/build.mjs +0 -15
- package/dist/cli/build/dev.d.mts +0 -10
- package/dist/cli/build/dev.mjs +0 -91
- package/dist/cli/build/prepare.d.mts +0 -6
- package/dist/cli/build/prepare.mjs +0 -15
- package/dist/cli/commands/commands.mjs +0 -90
- package/dist/cli/commands/env.mjs +0 -53
- package/dist/cli/commands/init.mjs +0 -84
- package/dist/cli/commands/install.mjs +0 -52
- package/dist/cli/commands/prepare.mjs +0 -65
- package/dist/cli/commands/reset.mjs +0 -46
- package/dist/cli/commands/run.mjs +0 -31
- package/dist/cli/commands/watch.mjs +0 -153
- package/dist/cli/config/defaults.mjs +0 -117
- package/dist/cli/config/index.d.mts +0 -3
- package/dist/cli/config/index.mjs +0 -4
- package/dist/cli/config/loader.d.mts +0 -6
- package/dist/cli/config/loader.mjs +0 -71
- package/dist/cli/config/resolvers/compatibility.mjs +0 -71
- package/dist/cli/config/resolvers/imports.mjs +0 -35
- package/dist/cli/config/resolvers/paths.mjs +0 -98
- package/dist/cli/config/resolvers/storage.mjs +0 -23
- package/dist/cli/config/resolvers/url.mjs +0 -9
- package/dist/cli/config/types.d.mts +0 -14
- package/dist/cli/config/types.mjs +0 -147
- package/dist/cli/core/apiful.mjs +0 -36
- package/dist/cli/core/devServer.mjs +0 -10
- package/dist/cli/core/env.mjs +0 -68
- package/dist/cli/core/installPackage.mjs +0 -60
- package/dist/cli/core/runtimeConfig.mjs +0 -70
- package/dist/cli/core/scan.mjs +0 -35
- package/dist/cli/core/silgi.mjs +0 -111
- package/dist/cli/framework/emptyFramework.mjs +0 -7
- package/dist/cli/framework/h3.mjs +0 -55
- package/dist/cli/framework/index.mjs +0 -15
- package/dist/cli/framework/nitro.mjs +0 -24
- package/dist/cli/framework/nuxt.mjs +0 -10
- package/dist/cli/index.d.mts +0 -1
- package/dist/cli/index.mjs +0 -29
- package/dist/cli/module/exportScan.mjs +0 -180
- package/dist/cli/module/install.mjs +0 -49
- package/dist/cli/module/scan.mjs +0 -193
- package/dist/cli/scan/prepareCommands.mjs +0 -40
- package/dist/cli/scan/prepareConfigs.mjs +0 -33
- package/dist/cli/scan/prepareCoreFile.mjs +0 -118
- package/dist/cli/scan/prepareScanFile.mjs +0 -59
- package/dist/cli/scan/prepareSchema.mjs +0 -128
- package/dist/cli/scan/scanExportFile.mjs +0 -288
- package/dist/cli/scan/writeCoreFile.mjs +0 -22
- package/dist/cli/scan/writeTypesAndFiles.mjs +0 -72
- package/dist/cli/utils/cancel.mjs +0 -14
- package/dist/cli/utils/common.mjs +0 -15
- package/dist/cli/utils/compatibility.mjs +0 -33
- package/dist/cli/utils/debug.mjs +0 -11
- package/dist/cli/utils/ignore.mjs +0 -56
- package/dist/cli/utils/processManager.mjs +0 -170
- package/dist/cli/utils/readScanFile.mjs +0 -58
- package/dist/cli/utils/storage.mjs +0 -23
- package/dist/core/context.d.mts +0 -30
- package/dist/core/context.mjs +0 -32
- package/dist/core/createSilgi.d.mts +0 -6
- package/dist/core/createSilgi.mjs +0 -153
- package/dist/core/event.d.mts +0 -26
- package/dist/core/event.mjs +0 -44
- package/dist/core/index.d.mts +0 -25
- package/dist/core/index.mjs +0 -30
- package/dist/core/orchestrate.mjs +0 -115
- package/dist/core/response.d.mts +0 -20
- package/dist/core/response.mjs +0 -105
- package/dist/core/silgi.d.mts +0 -19
- package/dist/core/silgi.mjs +0 -141
- package/dist/core/silgiApp.d.mts +0 -9
- package/dist/core/silgiApp.mjs +0 -23
- package/dist/core/unctx.d.mts +0 -21
- package/dist/core/unctx.mjs +0 -35
- package/dist/core/utils/event-stream.d.mts +0 -53
- package/dist/core/utils/event-stream.mjs +0 -38
- package/dist/core/utils/event.d.mts +0 -8
- package/dist/core/utils/event.mjs +0 -12
- package/dist/core/utils/internal/event-stream.d.mts +0 -45
- package/dist/core/utils/internal/event-stream.mjs +0 -137
- package/dist/core/utils/internal/obj.mjs +0 -9
- package/dist/core/utils/internal/object.mjs +0 -29
- package/dist/core/utils/internal/query.mjs +0 -73
- package/dist/core/utils/internal/req.mjs +0 -35
- package/dist/core/utils/merge.d.mts +0 -14
- package/dist/core/utils/merge.mjs +0 -27
- package/dist/core/utils/middleware.d.mts +0 -14
- package/dist/core/utils/middleware.mjs +0 -12
- package/dist/core/utils/request.mjs +0 -35
- package/dist/core/utils/resolver.d.mts +0 -7
- package/dist/core/utils/resolver.mjs +0 -29
- package/dist/core/utils/runtime.d.mts +0 -7
- package/dist/core/utils/runtime.mjs +0 -20
- package/dist/core/utils/sanitize.mjs +0 -22
- package/dist/core/utils/schema.d.mts +0 -34
- package/dist/core/utils/schema.mjs +0 -33
- package/dist/core/utils/service.d.mts +0 -13
- package/dist/core/utils/service.mjs +0 -19
- package/dist/core/utils/shared.d.mts +0 -6
- package/dist/core/utils/shared.mjs +0 -7
- package/dist/core/utils/storage.d.mts +0 -24
- package/dist/core/utils/storage.mjs +0 -54
- package/dist/kit/add/add-commands.d.mts +0 -6
- package/dist/kit/add/add-commands.mjs +0 -12
- package/dist/kit/add/add-core-file.d.mts +0 -9
- package/dist/kit/add/add-core-file.mjs +0 -11
- package/dist/kit/add/add-imports.d.mts +0 -14
- package/dist/kit/add/add-imports.mjs +0 -56
- package/dist/kit/add/add-npm.d.mts +0 -14
- package/dist/kit/add/add-npm.mjs +0 -23
- package/dist/kit/define.d.mts +0 -28
- package/dist/kit/define.mjs +0 -25
- package/dist/kit/errors.d.mts +0 -6
- package/dist/kit/errors.mjs +0 -11
- package/dist/kit/esm.d.mts +0 -11
- package/dist/kit/esm.mjs +0 -21
- package/dist/kit/fs.d.mts +0 -4
- package/dist/kit/fs.mjs +0 -13
- package/dist/kit/function-utils.d.mts +0 -27
- package/dist/kit/function-utils.mjs +0 -75
- package/dist/kit/gen.d.mts +0 -5
- package/dist/kit/gen.mjs +0 -26
- package/dist/kit/hash.d.mts +0 -4
- package/dist/kit/hash.mjs +0 -10
- package/dist/kit/index.d.mts +0 -22
- package/dist/kit/index.mjs +0 -23
- package/dist/kit/isFramework.d.mts +0 -6
- package/dist/kit/isFramework.mjs +0 -21
- package/dist/kit/logger.d.mts +0 -6
- package/dist/kit/logger.mjs +0 -10
- package/dist/kit/migration.d.mts +0 -113
- package/dist/kit/migration.mjs +0 -301
- package/dist/kit/module.d.mts +0 -14
- package/dist/kit/module.mjs +0 -53
- package/dist/kit/path.d.mts +0 -7
- package/dist/kit/path.mjs +0 -26
- package/dist/kit/preset.d.mts +0 -8
- package/dist/kit/preset.mjs +0 -11
- package/dist/kit/resolve.d.mts +0 -37
- package/dist/kit/resolve.mjs +0 -82
- package/dist/kit/template.d.mts +0 -19
- package/dist/kit/template.mjs +0 -91
- package/dist/kit/useRequest.d.mts +0 -19
- package/dist/kit/useRequest.mjs +0 -63
- package/dist/kit/utils.d.mts +0 -34
- package/dist/kit/utils.mjs +0 -91
- package/dist/package.mjs +0 -176
- package/dist/presets/_all.gen.d.mts +0 -6
- package/dist/presets/_all.gen.mjs +0 -18
- package/dist/presets/_resolve.d.mts +0 -12
- package/dist/presets/_resolve.mjs +0 -57
- package/dist/presets/_types.gen.d.mts +0 -8
- package/dist/presets/_types.gen.mjs +0 -5
- package/dist/presets/h3/preset.d.mts +0 -6
- package/dist/presets/h3/preset.mjs +0 -35
- package/dist/presets/hono/preset.d.mts +0 -6
- package/dist/presets/hono/preset.mjs +0 -30
- package/dist/presets/index.d.mts +0 -3
- package/dist/presets/index.mjs +0 -3
- package/dist/presets/nitro/preset.d.mts +0 -6
- package/dist/presets/nitro/preset.mjs +0 -37
- package/dist/presets/npmpackage/preset.d.mts +0 -6
- package/dist/presets/npmpackage/preset.mjs +0 -29
- package/dist/presets/nuxt/preset.d.mts +0 -6
- package/dist/presets/nuxt/preset.mjs +0 -41
- package/dist/runtime/index.d.mts +0 -4
- package/dist/runtime/index.mjs +0 -5
- package/dist/runtime/internal/config.d.mts +0 -11
- package/dist/runtime/internal/config.mjs +0 -97
- package/dist/runtime/internal/debug.d.mts +0 -6
- package/dist/runtime/internal/debug.mjs +0 -11
- package/dist/runtime/internal/defu.d.mts +0 -4
- package/dist/runtime/internal/defu.mjs +0 -9
- package/dist/runtime/internal/index.d.mts +0 -7
- package/dist/runtime/internal/index.mjs +0 -8
- package/dist/runtime/internal/nitro.d.mts +0 -6
- package/dist/runtime/internal/nitro.mjs +0 -36
- package/dist/runtime/internal/nuxt.d.mts +0 -12
- package/dist/runtime/internal/nuxt.mjs +0 -16
- package/dist/runtime/internal/ofetch.d.mts +0 -8
- package/dist/runtime/internal/ofetch.mjs +0 -39
- package/dist/runtime/internal/plugin.d.mts +0 -7
- package/dist/runtime/internal/plugin.mjs +0 -8
- package/dist/types/cliConfig.d.mts +0 -288
- package/dist/types/cliConfig.mjs +0 -0
- package/dist/types/cliHooks.d.mts +0 -142
- package/dist/types/cliHooks.mjs +0 -0
- package/dist/types/compatibility.d.mts +0 -13
- package/dist/types/compatibility.mjs +0 -0
- package/dist/types/config.d.mts +0 -46
- package/dist/types/config.mjs +0 -0
- package/dist/types/dotenv.d.mts +0 -29
- package/dist/types/dotenv.mjs +0 -0
- package/dist/types/event.d.mts +0 -63
- package/dist/types/event.mjs +0 -0
- package/dist/types/global.d.mts +0 -24
- package/dist/types/global.mjs +0 -0
- package/dist/types/helper.d.mts +0 -25
- package/dist/types/helper.mjs +0 -0
- package/dist/types/hooks.d.mts +0 -37
- package/dist/types/hooks.mjs +0 -0
- package/dist/types/index.d.mts +0 -26
- package/dist/types/index.mjs +0 -0
- package/dist/types/kits.d.mts +0 -32
- package/dist/types/kits.mjs +0 -0
- package/dist/types/middleware.d.mts +0 -31
- package/dist/types/middleware.mjs +0 -0
- package/dist/types/module.d.mts +0 -102
- package/dist/types/module.mjs +0 -0
- package/dist/types/preset.d.mts +0 -20
- package/dist/types/preset.mjs +0 -0
- package/dist/types/route.d.mts +0 -59
- package/dist/types/route.mjs +0 -0
- package/dist/types/runtime/index.d.mts +0 -5
- package/dist/types/runtime/index.mjs +0 -0
- package/dist/types/runtime/nuxt.d.mts +0 -13
- package/dist/types/runtime/nuxt.mjs +0 -0
- package/dist/types/runtime/ofetch.d.mts +0 -14
- package/dist/types/runtime/ofetch.mjs +0 -0
- package/dist/types/runtime/plugin.d.mts +0 -8
- package/dist/types/runtime/plugin.mjs +0 -0
- package/dist/types/runtime/silgi.d.mts +0 -11
- package/dist/types/runtime/silgi.mjs +0 -0
- package/dist/types/schema.d.mts +0 -86
- package/dist/types/schema.mjs +0 -0
- package/dist/types/service.d.mts +0 -102
- package/dist/types/service.mjs +0 -0
- package/dist/types/shared.d.mts +0 -19
- package/dist/types/shared.mjs +0 -0
- package/dist/types/silgi.d.mts +0 -71
- package/dist/types/silgi.mjs +0 -0
- package/dist/types/silgiCLI.d.mts +0 -118
- package/dist/types/silgiCLI.mjs +0 -0
- package/dist/types/standard-schema.d.mts +0 -61
- package/dist/types/standard-schema.mjs +0 -0
- package/dist/types/storage.d.mts +0 -30
- package/dist/types/storage.mjs +0 -0
- package/dist/types/tree-kill.d.mts +0 -18
- package/dist/types/tree-kill.mjs +0 -0
- package/lib/config.d.mts +0 -7
- package/lib/config.mjs +0 -5
- package/lib/meta.d.mts +0 -4
- package/lib/meta.mjs +0 -6
- package/lib/runtime-meta.d.mts +0 -4
- package/lib/runtime-meta.mjs +0 -32
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { RAW_INPUT } from "../compile.mjs";
|
|
2
|
+
import { useStorage as useStorage$1 } from "../core/storage.mjs";
|
|
3
|
+
import { defineCachedFunction, setStorage, useStorage } from "ocache";
|
|
4
|
+
import { hash } from "ohash";
|
|
5
|
+
//#region src/plugins/cache.ts
|
|
6
|
+
/**
|
|
7
|
+
* Cache plugin — production-grade response caching powered by ocache.
|
|
8
|
+
*
|
|
9
|
+
* All ocache features exposed:
|
|
10
|
+
* - TTL + Stale-While-Revalidate (SWR)
|
|
11
|
+
* - Request deduplication (concurrent calls share one in-flight promise)
|
|
12
|
+
* - Automatic integrity (redeploy invalidates stale cache)
|
|
13
|
+
* - shouldBypassCache / shouldInvalidateCache callbacks
|
|
14
|
+
* - Entry validation and transformation
|
|
15
|
+
* - Multi-tier storage (read cascade, write to all)
|
|
16
|
+
* - Pluggable storage via `setCacheStorage()` (default: in-memory)
|
|
17
|
+
* - unstorage adapter for Redis, Cloudflare KV, S3, etc.
|
|
18
|
+
* - Mutation-triggered invalidation
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { cacheQuery, setCacheStorage } from 'silgi/cache'
|
|
23
|
+
*
|
|
24
|
+
* // Basic: cache for 60 seconds with SWR
|
|
25
|
+
* const listUsers = k
|
|
26
|
+
* .$use(cacheQuery({ maxAge: 60 }))
|
|
27
|
+
* .$resolve(({ ctx }) => ctx.db.users.findMany())
|
|
28
|
+
*
|
|
29
|
+
* // With unstorage backend (Redis)
|
|
30
|
+
* import { createUnstorageAdapter } from 'silgi/cache'
|
|
31
|
+
* import { createStorage } from 'silgi/unstorage'
|
|
32
|
+
* import redisDriver from 'unstorage/drivers/redis'
|
|
33
|
+
*
|
|
34
|
+
* const storage = createStorage({ driver: redisDriver({ url: 'redis://localhost' }) })
|
|
35
|
+
* setCacheStorage(createUnstorageAdapter(storage))
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Auto-connect ocache to silgi's storage.
|
|
40
|
+
* Called lazily on first cacheQuery() use.
|
|
41
|
+
*/
|
|
42
|
+
let _storageConnected = false;
|
|
43
|
+
function ensureStorageConnected() {
|
|
44
|
+
if (_storageConnected) return;
|
|
45
|
+
_storageConnected = true;
|
|
46
|
+
try {
|
|
47
|
+
const storage = useStorage$1("cache");
|
|
48
|
+
setStorage({
|
|
49
|
+
get: (key) => storage.getItem(key),
|
|
50
|
+
set: (key, value, opts) => {
|
|
51
|
+
if (value === null || value === void 0) {
|
|
52
|
+
storage.removeItem(key);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
storage.setItem(key, value, opts?.ttl ? { ttl: opts.ttl } : void 0);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
} catch {}
|
|
59
|
+
}
|
|
60
|
+
/** Registry of cached function keys for invalidation */
|
|
61
|
+
const cacheKeyRegistry = /* @__PURE__ */ new Map();
|
|
62
|
+
/**
|
|
63
|
+
* Wrap middleware that caches query results.
|
|
64
|
+
*
|
|
65
|
+
* Uses ocache under the hood: TTL, SWR, dedup, integrity, bypass, invalidation.
|
|
66
|
+
* Default: 60s TTL, SWR enabled.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* const listUsers = k
|
|
71
|
+
* .$use(cacheQuery({ maxAge: 60 }))
|
|
72
|
+
* .$resolve(({ ctx }) => ctx.db.users.findMany())
|
|
73
|
+
*
|
|
74
|
+
* // Advanced: bypass cache for admin, custom validation
|
|
75
|
+
* const listPosts = k
|
|
76
|
+
* .$use(cacheQuery({
|
|
77
|
+
* maxAge: 300,
|
|
78
|
+
* swr: true,
|
|
79
|
+
* staleMaxAge: 600,
|
|
80
|
+
* shouldBypassCache: (input) => (input as any)?.noCache,
|
|
81
|
+
* shouldInvalidateCache: (input) => (input as any)?.refresh,
|
|
82
|
+
* validate: (entry) => Array.isArray(entry.value),
|
|
83
|
+
* onError: (err) => console.error('[cache]', err),
|
|
84
|
+
* }))
|
|
85
|
+
* .$resolve(({ ctx }) => ctx.db.posts.findMany())
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
function cacheQuery(options = {}) {
|
|
89
|
+
const maxAge = options.maxAge ?? 60;
|
|
90
|
+
const swr = options.swr ?? true;
|
|
91
|
+
const staleMaxAge = options.staleMaxAge ?? maxAge;
|
|
92
|
+
const customGetKey = options.getKey;
|
|
93
|
+
let cacheName = options.name;
|
|
94
|
+
const pendingNextMap = /* @__PURE__ */ new Map();
|
|
95
|
+
let requestCounter = 0;
|
|
96
|
+
let cachedFn = null;
|
|
97
|
+
let keyFn;
|
|
98
|
+
return {
|
|
99
|
+
kind: "wrap",
|
|
100
|
+
fn: async (ctx, next) => {
|
|
101
|
+
ensureStorageConnected();
|
|
102
|
+
if (!cachedFn) {
|
|
103
|
+
if (!cacheName) cacheName = ctx.__procedurePath || `proc_${hash(next.toString()).slice(0, 8)}`;
|
|
104
|
+
const resolvedName = cacheName;
|
|
105
|
+
const keySet = /* @__PURE__ */ new Set();
|
|
106
|
+
cacheKeyRegistry.set(resolvedName, keySet);
|
|
107
|
+
keyFn = customGetKey ? (input) => customGetKey(input) : (input) => input !== void 0 && input !== null ? hash(input) : "";
|
|
108
|
+
const resolvedBase = options.base ?? "/cache";
|
|
109
|
+
cachedFn = defineCachedFunction(async (_input, requestId) => {
|
|
110
|
+
const mapKey = requestId ?? keyFn(_input);
|
|
111
|
+
const nextFn = pendingNextMap.get(mapKey);
|
|
112
|
+
if (nextFn) {
|
|
113
|
+
pendingNextMap.delete(mapKey);
|
|
114
|
+
return nextFn();
|
|
115
|
+
}
|
|
116
|
+
throw new Error("[silgi/cache] Missing next() for cache resolve");
|
|
117
|
+
}, {
|
|
118
|
+
name: resolvedName,
|
|
119
|
+
group: "silgi",
|
|
120
|
+
maxAge,
|
|
121
|
+
swr,
|
|
122
|
+
staleMaxAge,
|
|
123
|
+
base: resolvedBase,
|
|
124
|
+
integrity: options.integrity,
|
|
125
|
+
onError: options.onError,
|
|
126
|
+
validate: options.validate,
|
|
127
|
+
transform: options.transform,
|
|
128
|
+
shouldBypassCache: options.shouldBypassCache ? (input) => options.shouldBypassCache(input) : void 0,
|
|
129
|
+
shouldInvalidateCache: options.shouldInvalidateCache ? (input) => options.shouldInvalidateCache(input) : void 0,
|
|
130
|
+
getKey: (input) => {
|
|
131
|
+
const key = keyFn(input);
|
|
132
|
+
keySet.add(`${resolvedBase}:silgi:${resolvedName}:${key}.json`);
|
|
133
|
+
return key;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const input = ctx[RAW_INPUT];
|
|
138
|
+
const requestId = `__req_${++requestCounter}`;
|
|
139
|
+
pendingNextMap.set(requestId, next);
|
|
140
|
+
return cachedFn(input, requestId);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Invalidate cached entries for a procedure by name.
|
|
146
|
+
*
|
|
147
|
+
* Call this after mutations to clear related query caches.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* const createUser = k.$resolve(async ({ input, ctx }) => {
|
|
152
|
+
* const user = await ctx.db.users.create(input)
|
|
153
|
+
* await invalidateQueryCache('users_list')
|
|
154
|
+
* return user
|
|
155
|
+
* })
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
async function invalidateQueryCache(name) {
|
|
159
|
+
const keys = cacheKeyRegistry.get(name);
|
|
160
|
+
if (keys) {
|
|
161
|
+
const storage = useStorage();
|
|
162
|
+
await Promise.all([...keys].map((key) => storage.set(key, null)));
|
|
163
|
+
keys.clear();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Set the cache storage backend.
|
|
168
|
+
*
|
|
169
|
+
* Default: in-memory Map with TTL.
|
|
170
|
+
* For production, use `createUnstorageAdapter()` with Redis, Cloudflare KV, etc.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* import { setCacheStorage, createUnstorageAdapter } from 'silgi/cache'
|
|
175
|
+
* import { createStorage } from 'silgi/unstorage'
|
|
176
|
+
* import redisDriver from 'unstorage/drivers/redis'
|
|
177
|
+
*
|
|
178
|
+
* setCacheStorage(createUnstorageAdapter(
|
|
179
|
+
* createStorage({ driver: redisDriver({ url: 'redis://localhost' }) })
|
|
180
|
+
* ))
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
function setCacheStorage(storage) {
|
|
184
|
+
setStorage(storage);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Create an ocache-compatible storage adapter from an unstorage instance.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts
|
|
191
|
+
* import { createStorage } from 'silgi/unstorage'
|
|
192
|
+
* import redisDriver from 'unstorage/drivers/redis'
|
|
193
|
+
*
|
|
194
|
+
* const storage = createStorage({ driver: redisDriver({ url: 'redis://localhost' }) })
|
|
195
|
+
* const adapter = createUnstorageAdapter(storage)
|
|
196
|
+
* setCacheStorage(adapter)
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
function createUnstorageAdapter(storage) {
|
|
200
|
+
return {
|
|
201
|
+
get: (key) => storage.getItem(key),
|
|
202
|
+
set: (key, value, opts) => {
|
|
203
|
+
if (value === null || value === void 0) {
|
|
204
|
+
storage.removeItem(key);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
storage.setItem(key, value, opts);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
//#endregion
|
|
212
|
+
export { cacheQuery, createUnstorageAdapter, invalidateQueryCache, setCacheStorage };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { WrapDef } from "../types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/coerce.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Coerce string values in the input to their proper JavaScript types.
|
|
6
|
+
* Only processes top-level and one-level-deep object values.
|
|
7
|
+
*
|
|
8
|
+
* Rules:
|
|
9
|
+
* - "123", "-42", "3.14" → number
|
|
10
|
+
* - "true", "false" → boolean
|
|
11
|
+
* - "null" → null
|
|
12
|
+
* - "undefined" → undefined
|
|
13
|
+
* - "" → undefined (empty strings become undefined)
|
|
14
|
+
* - Everything else → kept as-is
|
|
15
|
+
*
|
|
16
|
+
* Implemented as a wrap (not a guard) so it runs after __rawInput is populated
|
|
17
|
+
* by the pipeline compiler.
|
|
18
|
+
*/
|
|
19
|
+
declare const coerceGuard: WrapDef<Record<string, unknown>>;
|
|
20
|
+
declare function coerceValue(value: unknown): unknown;
|
|
21
|
+
declare function coerceObject(obj: Record<string, unknown>): void;
|
|
22
|
+
/** Standalone coercion function — use outside of guards */
|
|
23
|
+
//#endregion
|
|
24
|
+
export { coerceGuard, coerceObject, coerceValue };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { RAW_INPUT } from "../compile.mjs";
|
|
2
|
+
//#region src/plugins/coerce.ts
|
|
3
|
+
/**
|
|
4
|
+
* Smart coercion — convert string query parameters to proper types.
|
|
5
|
+
*
|
|
6
|
+
* When procedures receive GET requests, input arrives as strings via
|
|
7
|
+
* query parameters. This wrap coerces common types automatically:
|
|
8
|
+
* "123" → 123, "true" → true, "null" → null, etc.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { coerceGuard } from "silgi/plugins"
|
|
13
|
+
*
|
|
14
|
+
* const getUser = k
|
|
15
|
+
* .$use(coerceGuard)
|
|
16
|
+
* .$input(z.object({ id: z.number(), active: z.boolean().optional() }))
|
|
17
|
+
* .$resolve(({ input }) => db.users.find(input.id))
|
|
18
|
+
*
|
|
19
|
+
* // GET /users/get?data={"id":"42","active":"true"}
|
|
20
|
+
* // → input is coerced to { id: 42, active: true }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Coerce string values in the input to their proper JavaScript types.
|
|
25
|
+
* Only processes top-level and one-level-deep object values.
|
|
26
|
+
*
|
|
27
|
+
* Rules:
|
|
28
|
+
* - "123", "-42", "3.14" → number
|
|
29
|
+
* - "true", "false" → boolean
|
|
30
|
+
* - "null" → null
|
|
31
|
+
* - "undefined" → undefined
|
|
32
|
+
* - "" → undefined (empty strings become undefined)
|
|
33
|
+
* - Everything else → kept as-is
|
|
34
|
+
*
|
|
35
|
+
* Implemented as a wrap (not a guard) so it runs after __rawInput is populated
|
|
36
|
+
* by the pipeline compiler.
|
|
37
|
+
*/
|
|
38
|
+
const coerceGuard = {
|
|
39
|
+
kind: "wrap",
|
|
40
|
+
fn: async (ctx, next) => {
|
|
41
|
+
const input = ctx[RAW_INPUT];
|
|
42
|
+
if (typeof input === "object" && input !== null) coerceObject(input);
|
|
43
|
+
return next();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
function coerceValue(value) {
|
|
47
|
+
if (typeof value !== "string") return value;
|
|
48
|
+
if (value === "") return void 0;
|
|
49
|
+
if (value === "null") return null;
|
|
50
|
+
if (value === "undefined") return void 0;
|
|
51
|
+
if (value === "true") return true;
|
|
52
|
+
if (value === "false") return false;
|
|
53
|
+
if (value.length > 0 && value.length <= 20) {
|
|
54
|
+
const num = Number(value);
|
|
55
|
+
if (!Number.isNaN(num) && String(num) === value) return num;
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
function coerceObject(obj) {
|
|
60
|
+
const keys = Object.keys(obj);
|
|
61
|
+
for (let i = 0; i < keys.length; i++) {
|
|
62
|
+
const key = keys[i];
|
|
63
|
+
const val = obj[key];
|
|
64
|
+
if (typeof val === "string") obj[key] = coerceValue(val);
|
|
65
|
+
else if (typeof val === "object" && val !== null && !Array.isArray(val)) coerceObject(val);
|
|
66
|
+
else if (Array.isArray(val)) for (let j = 0; j < val.length; j++) val[j] = coerceValue(val[j]);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
70
|
+
export { coerceGuard, coerceObject, coerceValue };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CookieSerializeOptions, parseSetCookie, splitSetCookieString } from "cookie-es";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/cookies.d.ts
|
|
4
|
+
type CookieOptions = CookieSerializeOptions;
|
|
5
|
+
/** Parse a specific cookie value by name. */
|
|
6
|
+
declare function getCookie(headers: Record<string, string> | string, name: string): string | undefined;
|
|
7
|
+
/** Parse all cookies into a key-value object. */
|
|
8
|
+
declare function parseCookies(headers: Record<string, string> | string): Record<string, string>;
|
|
9
|
+
/** Serialize a Set-Cookie header. Defaults: path="/", httpOnly, sameSite=lax. */
|
|
10
|
+
declare function setCookie(name: string, value: string, options?: CookieOptions): string;
|
|
11
|
+
/** Delete a cookie by setting maxAge=0. */
|
|
12
|
+
declare function deleteCookie(name: string, options?: Pick<CookieOptions, 'path' | 'domain'>): string;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { CookieOptions, deleteCookie, getCookie, parseCookies, parseSetCookie, setCookie, splitSetCookieString };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { parse, parseSetCookie, serialize, splitSetCookieString } from "cookie-es";
|
|
2
|
+
//#region src/plugins/cookies.ts
|
|
3
|
+
/**
|
|
4
|
+
* Cookie helpers — thin wrapper over cookie-es (unjs).
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { getCookie, setCookie, deleteCookie } from "silgi/cookies"
|
|
9
|
+
*
|
|
10
|
+
* const auth = k.guard((ctx) => {
|
|
11
|
+
* const token = getCookie(ctx.headers, "session")
|
|
12
|
+
* if (!token) throw new SilgiError("UNAUTHORIZED")
|
|
13
|
+
* return { sessionToken: token }
|
|
14
|
+
* })
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
/** Parse a specific cookie value by name. */
|
|
18
|
+
function getCookie(headers, name) {
|
|
19
|
+
const str = typeof headers === "string" ? headers : headers.cookie ?? headers.Cookie ?? "";
|
|
20
|
+
if (!str) return void 0;
|
|
21
|
+
return parse(str)[name];
|
|
22
|
+
}
|
|
23
|
+
/** Parse all cookies into a key-value object. */
|
|
24
|
+
function parseCookies(headers) {
|
|
25
|
+
const str = typeof headers === "string" ? headers : headers.cookie ?? headers.Cookie ?? "";
|
|
26
|
+
if (!str) return {};
|
|
27
|
+
return parse(str);
|
|
28
|
+
}
|
|
29
|
+
/** Serialize a Set-Cookie header. Defaults: path="/", httpOnly, sameSite=lax. */
|
|
30
|
+
function setCookie(name, value, options = {}) {
|
|
31
|
+
const merged = {
|
|
32
|
+
path: "/",
|
|
33
|
+
httpOnly: true,
|
|
34
|
+
sameSite: "lax",
|
|
35
|
+
...options
|
|
36
|
+
};
|
|
37
|
+
if (merged.sameSite === "none") merged.secure = true;
|
|
38
|
+
return serialize(name, value, merged);
|
|
39
|
+
}
|
|
40
|
+
/** Delete a cookie by setting maxAge=0. */
|
|
41
|
+
function deleteCookie(name, options = {}) {
|
|
42
|
+
return setCookie(name, "", {
|
|
43
|
+
...options,
|
|
44
|
+
maxAge: 0
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { deleteCookie, getCookie, parseCookies, parseSetCookie, setCookie, splitSetCookieString };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//#region src/plugins/cors.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* CORS plugin — response header helper.
|
|
4
|
+
*
|
|
5
|
+
* Returns CORS headers to merge into responses.
|
|
6
|
+
* Handles preflight OPTIONS requests automatically via the handler.
|
|
7
|
+
*/
|
|
8
|
+
interface CORSOptions {
|
|
9
|
+
origin?: string | string[] | ((origin: string) => boolean);
|
|
10
|
+
methods?: string[];
|
|
11
|
+
allowedHeaders?: string[];
|
|
12
|
+
exposedHeaders?: string[];
|
|
13
|
+
credentials?: boolean;
|
|
14
|
+
maxAge?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create CORS headers config for silgi().
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { cors } from "silgi/cors"
|
|
22
|
+
*
|
|
23
|
+
* const k = silgi({
|
|
24
|
+
* context: (req) => ({}),
|
|
25
|
+
* hooks: cors({ origin: "https://app.example.com", credentials: true }),
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
declare function cors(options?: CORSOptions): {
|
|
30
|
+
headers: Record<string, string>;
|
|
31
|
+
options: CORSOptions;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* CORS header map — use in custom serve() or middleware.
|
|
35
|
+
* Returns headers object to merge into responses.
|
|
36
|
+
*
|
|
37
|
+
* For dynamic origins (array/function), omits Access-Control-Allow-Origin
|
|
38
|
+
* entirely when the request origin is not allowed — this is the correct
|
|
39
|
+
* behavior per the CORS spec (browsers reject missing header).
|
|
40
|
+
*/
|
|
41
|
+
declare function corsHeaders(options?: CORSOptions, requestOrigin?: string): Record<string, string>;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { CORSOptions, cors, corsHeaders };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
//#region src/plugins/cors.ts
|
|
2
|
+
/**
|
|
3
|
+
* Create CORS headers config for silgi().
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { cors } from "silgi/cors"
|
|
8
|
+
*
|
|
9
|
+
* const k = silgi({
|
|
10
|
+
* context: (req) => ({}),
|
|
11
|
+
* hooks: cors({ origin: "https://app.example.com", credentials: true }),
|
|
12
|
+
* })
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
function cors(options = {}) {
|
|
16
|
+
const origin = options.origin ?? "*";
|
|
17
|
+
if (options.credentials && typeof origin === "string" && origin === "*") throw new Error("[silgi/cors] Cannot use credentials: true with origin: \"*\". Set an explicit origin.");
|
|
18
|
+
return {
|
|
19
|
+
headers: corsHeaders(options),
|
|
20
|
+
options
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* CORS header map — use in custom serve() or middleware.
|
|
25
|
+
* Returns headers object to merge into responses.
|
|
26
|
+
*
|
|
27
|
+
* For dynamic origins (array/function), omits Access-Control-Allow-Origin
|
|
28
|
+
* entirely when the request origin is not allowed — this is the correct
|
|
29
|
+
* behavior per the CORS spec (browsers reject missing header).
|
|
30
|
+
*/
|
|
31
|
+
function corsHeaders(options = {}, requestOrigin) {
|
|
32
|
+
const origin = options.origin ?? "*";
|
|
33
|
+
const methods = options.methods ?? [
|
|
34
|
+
"GET",
|
|
35
|
+
"POST",
|
|
36
|
+
"PUT",
|
|
37
|
+
"PATCH",
|
|
38
|
+
"DELETE",
|
|
39
|
+
"OPTIONS"
|
|
40
|
+
];
|
|
41
|
+
const allowedHeaders = options.allowedHeaders ?? ["Content-Type", "Authorization"];
|
|
42
|
+
const headers = {
|
|
43
|
+
"access-control-allow-methods": methods.join(", "),
|
|
44
|
+
"access-control-allow-headers": allowedHeaders.join(", ")
|
|
45
|
+
};
|
|
46
|
+
if (typeof origin === "string") {
|
|
47
|
+
headers["access-control-allow-origin"] = origin;
|
|
48
|
+
if (origin !== "*") headers["vary"] = "Origin";
|
|
49
|
+
} else if (Array.isArray(origin)) {
|
|
50
|
+
if (requestOrigin && origin.includes(requestOrigin)) headers["access-control-allow-origin"] = requestOrigin;
|
|
51
|
+
headers["vary"] = "Origin";
|
|
52
|
+
} else if (typeof origin === "function") {
|
|
53
|
+
if (requestOrigin && origin(requestOrigin)) headers["access-control-allow-origin"] = requestOrigin;
|
|
54
|
+
headers["vary"] = "Origin";
|
|
55
|
+
}
|
|
56
|
+
if (options.credentials) headers["access-control-allow-credentials"] = "true";
|
|
57
|
+
if (options.maxAge !== void 0) headers["access-control-max-age"] = String(options.maxAge);
|
|
58
|
+
if (options.exposedHeaders) headers["access-control-expose-headers"] = options.exposedHeaders.join(", ");
|
|
59
|
+
return headers;
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { cors, corsHeaders };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { GuardDef } from "../types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/file-upload.d.ts
|
|
4
|
+
interface FileGuardOptions {
|
|
5
|
+
/** Maximum file size in bytes. Default: 10MB */
|
|
6
|
+
maxFileSize?: number;
|
|
7
|
+
/** Allowed MIME types (supports wildcards like "image/*"). Default: all */
|
|
8
|
+
allowedTypes?: string[];
|
|
9
|
+
/** Maximum number of files. Default: 1 */
|
|
10
|
+
maxFiles?: number;
|
|
11
|
+
/** Form field name for the file. Default: "file" */
|
|
12
|
+
fieldName?: string;
|
|
13
|
+
}
|
|
14
|
+
interface UploadedFile {
|
|
15
|
+
name: string;
|
|
16
|
+
size: number;
|
|
17
|
+
type: string;
|
|
18
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
19
|
+
text(): Promise<string>;
|
|
20
|
+
stream(): ReadableStream<Uint8Array>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Guard that parses multipart file uploads from the request.
|
|
24
|
+
*
|
|
25
|
+
* Adds `ctx.file` (single) or `ctx.files` (multiple) to the context.
|
|
26
|
+
* Validates file size and MIME type before the procedure runs.
|
|
27
|
+
*/
|
|
28
|
+
declare function fileGuard(options?: FileGuardOptions): GuardDef<Record<string, unknown>>;
|
|
29
|
+
/**
|
|
30
|
+
* Parse multipart form data from a Request.
|
|
31
|
+
* Returns files and fields separately.
|
|
32
|
+
*/
|
|
33
|
+
declare function parseMultipart(request: Request): Promise<{
|
|
34
|
+
files: UploadedFile[];
|
|
35
|
+
fields: Record<string, string>;
|
|
36
|
+
}>;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { FileGuardOptions, UploadedFile, fileGuard, parseMultipart };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { SilgiError } from "../core/error.mjs";
|
|
2
|
+
//#region src/plugins/file-upload.ts
|
|
3
|
+
/**
|
|
4
|
+
* File upload/download — type-safe File/Blob handling.
|
|
5
|
+
*
|
|
6
|
+
* Parse multipart/form-data requests and pass File objects
|
|
7
|
+
* to procedure handlers. Works with serve() and handler().
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { fileInput, fileGuard } from "silgi/plugins"
|
|
12
|
+
*
|
|
13
|
+
* const uploadAvatar = k
|
|
14
|
+
* .$use(fileGuard({ maxFileSize: 5 * 1024 * 1024, allowedTypes: ["image/*"] }))
|
|
15
|
+
* .$resolve(async ({ ctx }) => {
|
|
16
|
+
* const file = ctx.file
|
|
17
|
+
* const buffer = await file.arrayBuffer()
|
|
18
|
+
* return { name: file.name, size: file.size, type: file.type }
|
|
19
|
+
* })
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Guard that parses multipart file uploads from the request.
|
|
24
|
+
*
|
|
25
|
+
* Adds `ctx.file` (single) or `ctx.files` (multiple) to the context.
|
|
26
|
+
* Validates file size and MIME type before the procedure runs.
|
|
27
|
+
*/
|
|
28
|
+
function fileGuard(options = {}) {
|
|
29
|
+
const { maxFileSize = 10 * 1024 * 1024, allowedTypes, maxFiles = 1, fieldName: _fieldName = "file" } = options;
|
|
30
|
+
return {
|
|
31
|
+
kind: "guard",
|
|
32
|
+
fn: (ctx) => {
|
|
33
|
+
const files = ctx.__files;
|
|
34
|
+
if (!files || files.length === 0) throw new SilgiError("BAD_REQUEST", {
|
|
35
|
+
status: 400,
|
|
36
|
+
message: "No file uploaded"
|
|
37
|
+
});
|
|
38
|
+
if (files.length > maxFiles) throw new SilgiError("BAD_REQUEST", {
|
|
39
|
+
status: 400,
|
|
40
|
+
message: `Too many files: ${files.length} (max ${maxFiles})`
|
|
41
|
+
});
|
|
42
|
+
for (const file of files) {
|
|
43
|
+
if (file.size > maxFileSize) throw new SilgiError("PAYLOAD_TOO_LARGE", {
|
|
44
|
+
status: 413,
|
|
45
|
+
message: `File too large: ${file.size} bytes (max ${maxFileSize})`,
|
|
46
|
+
data: {
|
|
47
|
+
maxFileSize,
|
|
48
|
+
actualSize: file.size,
|
|
49
|
+
fileName: file.name
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
if (allowedTypes && !matchesMimeType(file.type, allowedTypes)) throw new SilgiError("BAD_REQUEST", {
|
|
53
|
+
status: 400,
|
|
54
|
+
message: `File type not allowed: ${file.type}`,
|
|
55
|
+
data: {
|
|
56
|
+
allowedTypes,
|
|
57
|
+
actualType: file.type,
|
|
58
|
+
fileName: file.name
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return maxFiles === 1 ? { file: files[0] } : { files };
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Parse multipart form data from a Request.
|
|
68
|
+
* Returns files and fields separately.
|
|
69
|
+
*/
|
|
70
|
+
async function parseMultipart(request) {
|
|
71
|
+
const formData = await request.formData();
|
|
72
|
+
const files = [];
|
|
73
|
+
const fields = {};
|
|
74
|
+
for (const [key, value] of formData.entries()) if (typeof value !== "string") {
|
|
75
|
+
const file = value;
|
|
76
|
+
files.push({
|
|
77
|
+
name: file.name,
|
|
78
|
+
size: file.size,
|
|
79
|
+
type: file.type,
|
|
80
|
+
arrayBuffer: () => file.arrayBuffer(),
|
|
81
|
+
text: () => file.text(),
|
|
82
|
+
stream: () => file.stream()
|
|
83
|
+
});
|
|
84
|
+
} else fields[key] = value;
|
|
85
|
+
return {
|
|
86
|
+
files,
|
|
87
|
+
fields
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function matchesMimeType(actual, patterns) {
|
|
91
|
+
for (const pattern of patterns) {
|
|
92
|
+
if (pattern === "*" || pattern === "*/*") return true;
|
|
93
|
+
if (pattern === actual) return true;
|
|
94
|
+
if (pattern.endsWith("/*")) {
|
|
95
|
+
const prefix = pattern.slice(0, -2);
|
|
96
|
+
if (actual.startsWith(prefix + "/")) return true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
102
|
+
export { fileGuard, parseMultipart };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AnalyticsOptions, AnalyticsSnapshot, ErrorEntry, ProcedureSnapshot, TraceSpan } from "./analytics/types.mjs";
|
|
2
|
+
import { AnalyticsCollector } from "./analytics/collector.mjs";
|
|
3
|
+
import { RequestTrace, trace } from "./analytics/trace.mjs";
|
|
4
|
+
import { analyticsHTML } from "./analytics/routes.mjs";
|
|
5
|
+
import { errorToMarkdown } from "./analytics/export.mjs";
|
|
6
|
+
import { Span, Tracer, otelWrap } from "./otel.mjs";
|
|
7
|
+
import { CookieOptions, deleteCookie, getCookie, parseCookies, setCookie } from "./cookies.mjs";
|
|
8
|
+
import { CORSOptions, cors, corsHeaders } from "./cors.mjs";
|
|
9
|
+
import { Logger, LoggingOptions, loggingHooks } from "./pino.mjs";
|
|
10
|
+
import { MemoryRateLimiter, MemoryRateLimiterOptions, RateLimitGuardOptions, RateLimitResult, RateLimiter, rateLimitGuard } from "./ratelimit.mjs";
|
|
11
|
+
import { BodyLimitOptions, bodyLimitGuard } from "./body-limit.mjs";
|
|
12
|
+
import { strictGetGuard } from "./strict-get.mjs";
|
|
13
|
+
import { decrypt, encrypt, sign, unsign } from "./signing.mjs";
|
|
14
|
+
import { coerceGuard, coerceObject, coerceValue } from "./coerce.mjs";
|
|
15
|
+
import { BatchHandlerOptions, createBatchHandler } from "./batch-server.mjs";
|
|
16
|
+
import { MemoryPubSub, PubSubBackend, Publisher, createPublisher } from "./pubsub.mjs";
|
|
17
|
+
import { FileGuardOptions, UploadedFile, fileGuard, parseMultipart } from "./file-upload.mjs";
|
|
18
|
+
export { AnalyticsCollector, type AnalyticsOptions, type AnalyticsSnapshot, type BatchHandlerOptions, type BodyLimitOptions, type CORSOptions, type CookieOptions, type ErrorEntry, type FileGuardOptions, type Logger, type LoggingOptions, MemoryPubSub, MemoryRateLimiter, type MemoryRateLimiterOptions, type ProcedureSnapshot, type PubSubBackend, type Publisher, type RateLimitGuardOptions, type RateLimitResult, type RateLimiter, RequestTrace, type Span, type TraceSpan, type Tracer, type UploadedFile, analyticsHTML, bodyLimitGuard, coerceGuard, coerceObject, coerceValue, cors, corsHeaders, createBatchHandler, createPublisher, decrypt, deleteCookie, encrypt, errorToMarkdown, fileGuard, getCookie, loggingHooks, otelWrap, parseCookies, parseMultipart, rateLimitGuard, setCookie, sign, strictGetGuard, trace, unsign };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { cors, corsHeaders } from "./cors.mjs";
|
|
2
|
+
import { otelWrap } from "./otel.mjs";
|
|
3
|
+
import { loggingHooks } from "./pino.mjs";
|
|
4
|
+
import { MemoryRateLimiter, rateLimitGuard } from "./ratelimit.mjs";
|
|
5
|
+
import { bodyLimitGuard } from "./body-limit.mjs";
|
|
6
|
+
import { strictGetGuard } from "./strict-get.mjs";
|
|
7
|
+
import { deleteCookie, getCookie, parseCookies, setCookie } from "./cookies.mjs";
|
|
8
|
+
import { decrypt, encrypt, sign, unsign } from "./signing.mjs";
|
|
9
|
+
import { coerceGuard, coerceObject, coerceValue } from "./coerce.mjs";
|
|
10
|
+
import { createBatchHandler } from "./batch-server.mjs";
|
|
11
|
+
import { MemoryPubSub, createPublisher } from "./pubsub.mjs";
|
|
12
|
+
import { fileGuard, parseMultipart } from "./file-upload.mjs";
|
|
13
|
+
import { AnalyticsCollector } from "./analytics/collector.mjs";
|
|
14
|
+
import { errorToMarkdown } from "./analytics/export.mjs";
|
|
15
|
+
import { analyticsHTML } from "./analytics/routes.mjs";
|
|
16
|
+
import { RequestTrace, trace } from "./analytics/trace.mjs";
|
|
17
|
+
export { AnalyticsCollector, MemoryPubSub, MemoryRateLimiter, RequestTrace, analyticsHTML, bodyLimitGuard, coerceGuard, coerceObject, coerceValue, cors, corsHeaders, createBatchHandler, createPublisher, decrypt, deleteCookie, encrypt, errorToMarkdown, fileGuard, getCookie, loggingHooks, otelWrap, parseCookies, parseMultipart, rateLimitGuard, setCookie, sign, strictGetGuard, trace, unsign };
|