@smonn/ids 0.15.0 → 1.0.0-rc.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.
Files changed (46) hide show
  1. package/README.md +3 -3
  2. package/dist/{adapter-types-7wWdELSh.mjs → adapter-types-CjzFNDcJ.mjs} +7 -2
  3. package/dist/adapter-types-CjzFNDcJ.mjs.map +1 -0
  4. package/dist/cli.mjs +30 -22
  5. package/dist/cli.mjs.map +1 -1
  6. package/dist/drizzle.d.mts +202 -3
  7. package/dist/drizzle.d.mts.map +1 -1
  8. package/dist/drizzle.mjs +245 -5
  9. package/dist/drizzle.mjs.map +1 -1
  10. package/dist/express.d.mts +44 -2
  11. package/dist/express.d.mts.map +1 -1
  12. package/dist/express.mjs +60 -2
  13. package/dist/express.mjs.map +1 -1
  14. package/dist/fastify.d.mts +49 -2
  15. package/dist/fastify.d.mts.map +1 -1
  16. package/dist/fastify.mjs +61 -2
  17. package/dist/fastify.mjs.map +1 -1
  18. package/dist/hono.d.mts +44 -2
  19. package/dist/hono.d.mts.map +1 -1
  20. package/dist/hono.mjs +54 -2
  21. package/dist/hono.mjs.map +1 -1
  22. package/dist/kysely.d.mts +103 -2
  23. package/dist/kysely.d.mts.map +1 -1
  24. package/dist/kysely.mjs +105 -2
  25. package/dist/kysely.mjs.map +1 -1
  26. package/dist/mikro-orm.d.mts +81 -3
  27. package/dist/mikro-orm.d.mts.map +1 -1
  28. package/dist/mikro-orm.mjs +86 -4
  29. package/dist/mikro-orm.mjs.map +1 -1
  30. package/dist/nestjs.mjs +1 -1
  31. package/dist/{opaque-COAcIIY4.mjs → opaque-Dle3CmSE.mjs} +18 -10
  32. package/dist/opaque-Dle3CmSE.mjs.map +1 -0
  33. package/dist/opaque.d.mts +16 -10
  34. package/dist/opaque.d.mts.map +1 -1
  35. package/dist/opaque.mjs +1 -1
  36. package/dist/prisma.d.mts +135 -3
  37. package/dist/prisma.d.mts.map +1 -1
  38. package/dist/prisma.mjs +141 -3
  39. package/dist/prisma.mjs.map +1 -1
  40. package/dist/typeorm.d.mts +84 -1
  41. package/dist/typeorm.d.mts.map +1 -1
  42. package/dist/typeorm.mjs +87 -2
  43. package/dist/typeorm.mjs.map +1 -1
  44. package/package.json +1 -1
  45. package/dist/adapter-types-7wWdELSh.mjs.map +0 -1
  46. package/dist/opaque-COAcIIY4.mjs.map +0 -1
package/dist/express.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as resolveIdParamFailure } from "./adapter-types-7wWdELSh.mjs";
1
+ import { r as resolveIdParamFailure } from "./adapter-types-CjzFNDcJ.mjs";
2
2
  //#region src/adapters/express.ts
3
3
  /**
4
4
  * Typed error forwarded to Express's error pipeline (`next(err)`) on validation failure.
@@ -79,7 +79,65 @@ function idParam(paramName, codec, options) {
79
79
  next();
80
80
  };
81
81
  }
82
+ /**
83
+ * Express middleware that validates a named query-string param against a codec via `safeParse`.
84
+ *
85
+ * Same failure contract as `idParam` — same `IdParamOptions` / `IdParamFailure` shape, same
86
+ * `IdParamError` forwarded to `next(err)` — but reads `req.query[queryName]` instead of
87
+ * `req.params[queryName]`.
88
+ *
89
+ * **Default (no options):** calls `next(err)` with an `IdParamError` carrying `status` and
90
+ * `reason`, so the app's existing error-handling middleware controls rendering. The adapter
91
+ * does not write a response body itself.
92
+ *
93
+ * **`options.onError`:** when provided, the hook owns the response entirely — the adapter does
94
+ * not call `next(err)`.
95
+ *
96
+ * **`options.status`:** remaps the default HTTP status for a reason without a full handler.
97
+ *
98
+ * - **Brand mismatch (`invalid_prefix`) → `reason: "brand_mismatch"`, default 404**
99
+ * - **Malformed or missing query param → `reason: "malformed"`, default 400**
100
+ *
101
+ * On success, stores the canonical `Id<Brand>` in `res.locals` under `queryName`
102
+ * and calls `next()`.
103
+ *
104
+ * @example
105
+ * ```ts
106
+ * import { idQuery, IdParamError } from "@smonn/ids/express";
107
+ * import { createTimestampId } from "@smonn/ids";
108
+ *
109
+ * const usr = createTimestampId("usr");
110
+ *
111
+ * // Default: forwards error to app error-handling middleware
112
+ * // GET /users?userId=usr_...
113
+ * app.get("/users", idQuery("userId", usr), (req, res) => {
114
+ * const userId = res.locals.userId; // Id<"usr">, canonical
115
+ * });
116
+ *
117
+ * // Override: consumer fully owns the response
118
+ * app.get("/search", idQuery("cursor", usr, {
119
+ * onError: (failure, req, res) => res.status(failure.status).json({ error: failure.reason }),
120
+ * }), handler);
121
+ * ```
122
+ */
123
+ function idQuery(queryName, codec, options) {
124
+ return (req, res, next) => {
125
+ const raw = req.query[queryName];
126
+ const result = codec.safeParse(raw);
127
+ if (!result.ok) {
128
+ const failure = resolveIdParamFailure(result.error, options);
129
+ if (options?.onError) {
130
+ options.onError(failure, req, res, next);
131
+ return;
132
+ }
133
+ next(new IdParamError(failure.reason, failure.status));
134
+ return;
135
+ }
136
+ res.locals[queryName] = result.id;
137
+ next();
138
+ };
139
+ }
82
140
  //#endregion
83
- export { IdParamError, idParam };
141
+ export { IdParamError, idParam, idQuery };
84
142
 
85
143
  //# sourceMappingURL=express.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"express.mjs","names":[],"sources":["../src/adapters/express.ts"],"sourcesContent":["import type { NextFunction, Request, Response } from \"express\";\nimport { type IdCodec, type IdParamFailure, resolveIdParamFailure } from \"./adapter-types.js\";\nimport type { Id } from \"../types.js\";\n\nexport type { IdParamFailure };\n\n/**\n * Typed error forwarded to Express's error pipeline (`next(err)`) on validation failure.\n * Inspect `err.reason` and `err.status` in error-handling middleware.\n */\nexport class IdParamError extends Error {\n readonly status: number;\n readonly reason: \"brand_mismatch\" | \"malformed\";\n\n constructor(reason: \"brand_mismatch\" | \"malformed\", status: number) {\n super(`ID validation failed: ${reason}`);\n this.name = \"IdParamError\";\n this.reason = reason;\n this.status = status;\n }\n}\n\n/** Options for `idParam`. All fields are optional. */\nexport type IdParamOptions = {\n /**\n * Called instead of forwarding to `next(err)` when provided. The hook owns the response\n * entirely — the adapter does not call `next(err)` itself.\n */\n onError?: (failure: IdParamFailure, req: Request, res: Response, next: NextFunction) => void;\n /**\n * Remap the default HTTP status for a failure reason without a full handler.\n * e.g. `{ brand_mismatch: 400 }` treats both failure kinds as 400.\n */\n status?: { brand_mismatch?: number; malformed?: number };\n};\n\n/**\n * Express middleware that validates a named route param against a codec via `safeParse`.\n *\n * **Default (no options):** calls `next(err)` with an `IdParamError` carrying `status` and `reason`,\n * so the app's existing error-handling middleware controls rendering. The adapter does not write\n * a response body itself.\n *\n * **`options.onError`:** when provided, the hook owns the response entirely — the adapter does\n * not call `next(err)`.\n *\n * **`options.status`:** remaps the default HTTP status for a reason without a full handler.\n *\n * - **Brand mismatch (`invalid_prefix`) → `reason: \"brand_mismatch\"`, default 404**\n * - **Malformed or missing ID → `reason: \"malformed\"`, default 400**\n *\n * On success, stores the canonical `Id<Brand>` in `res.locals` under `paramName`\n * and calls `next()`.\n *\n * @example\n * ```ts\n * import { idParam, IdParamError } from \"@smonn/ids/express\";\n * import { createTimestampId } from \"@smonn/ids\";\n *\n * const usr = createTimestampId(\"usr\");\n *\n * // Default: forwards error to app error-handling middleware\n * app.get(\"/users/:id\", idParam(\"id\", usr), (req, res) => {\n * const id = res.locals.id; // Id<\"usr\">, canonical\n * });\n *\n * // Error-handling middleware receives the typed error\n * app.use((err, req, res, next) => {\n * if (err instanceof IdParamError) {\n * res.status(err.status).json({ error: err.reason });\n * return;\n * }\n * next(err);\n * });\n *\n * // Override: consumer fully owns the response\n * app.get(\"/orgs/:id\", idParam(\"id\", org, {\n * onError: (failure, req, res) => res.status(failure.status).json({ error: failure.reason }),\n * }), handler);\n *\n * // Or a lightweight status remap without a full handler\n * app.get(\"/things/:id\", idParam(\"id\", thing, { status: { brand_mismatch: 400 } }), handler);\n * ```\n */\nexport function idParam<ParamKey extends string, Brand extends string>(\n paramName: ParamKey,\n codec: IdCodec<Brand>,\n options?: IdParamOptions,\n): (req: Request, res: Response<unknown, Record<ParamKey, Id<Brand>>>, next: NextFunction) => void {\n return (req, res, next): void => {\n const raw = req.params[paramName];\n const result = codec.safeParse(raw);\n if (!result.ok) {\n const failure = resolveIdParamFailure(result.error, options);\n if (options?.onError) {\n options.onError(failure, req, res, next);\n return;\n }\n next(new IdParamError(failure.reason, failure.status));\n return;\n }\n (res.locals as Record<string, unknown>)[paramName] = result.id;\n next();\n };\n}\n"],"mappings":";;;;;;AAUA,IAAa,eAAb,cAAkC,MAAM;CACtC;CACA;CAEA,YAAY,QAAwC,QAAgB;EAClE,MAAM,yBAAyB,QAAQ;EACvC,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,SAAS;CAChB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgEA,SAAgB,QACd,WACA,OACA,SACiG;CACjG,QAAQ,KAAK,KAAK,SAAe;EAC/B,MAAM,MAAM,IAAI,OAAO;EACvB,MAAM,SAAS,MAAM,UAAU,GAAG;EAClC,IAAI,CAAC,OAAO,IAAI;GACd,MAAM,UAAU,sBAAsB,OAAO,OAAO,OAAO;GAC3D,IAAI,SAAS,SAAS;IACpB,QAAQ,QAAQ,SAAS,KAAK,KAAK,IAAI;IACvC;GACF;GACA,KAAK,IAAI,aAAa,QAAQ,QAAQ,QAAQ,MAAM,CAAC;GACrD;EACF;EACA,IAAK,OAAmC,aAAa,OAAO;EAC5D,KAAK;CACP;AACF"}
1
+ {"version":3,"file":"express.mjs","names":[],"sources":["../src/adapters/express.ts"],"sourcesContent":["import type { NextFunction, Request, Response } from \"express\";\nimport { type IdCodec, type IdParamFailure, resolveIdParamFailure } from \"./adapter-types.js\";\nimport type { Id } from \"../types.js\";\n\nexport type { IdParamFailure };\n\n/**\n * Typed error forwarded to Express's error pipeline (`next(err)`) on validation failure.\n * Inspect `err.reason` and `err.status` in error-handling middleware.\n */\nexport class IdParamError extends Error {\n readonly status: number;\n readonly reason: \"brand_mismatch\" | \"malformed\";\n\n constructor(reason: \"brand_mismatch\" | \"malformed\", status: number) {\n super(`ID validation failed: ${reason}`);\n this.name = \"IdParamError\";\n this.reason = reason;\n this.status = status;\n }\n}\n\n/** Options for `idParam` and `idQuery`. All fields are optional. */\nexport type IdParamOptions = {\n /**\n * Called instead of forwarding to `next(err)` when provided. The hook owns the response\n * entirely — the adapter does not call `next(err)` itself.\n */\n onError?: (failure: IdParamFailure, req: Request, res: Response, next: NextFunction) => void;\n /**\n * Remap the default HTTP status for a failure reason without a full handler.\n * e.g. `{ brand_mismatch: 400 }` treats both failure kinds as 400.\n */\n status?: { brand_mismatch?: number; malformed?: number };\n};\n\n/**\n * Express middleware that validates a named route param against a codec via `safeParse`.\n *\n * **Default (no options):** calls `next(err)` with an `IdParamError` carrying `status` and `reason`,\n * so the app's existing error-handling middleware controls rendering. The adapter does not write\n * a response body itself.\n *\n * **`options.onError`:** when provided, the hook owns the response entirely — the adapter does\n * not call `next(err)`.\n *\n * **`options.status`:** remaps the default HTTP status for a reason without a full handler.\n *\n * - **Brand mismatch (`invalid_prefix`) → `reason: \"brand_mismatch\"`, default 404**\n * - **Malformed or missing ID → `reason: \"malformed\"`, default 400**\n *\n * On success, stores the canonical `Id<Brand>` in `res.locals` under `paramName`\n * and calls `next()`.\n *\n * @example\n * ```ts\n * import { idParam, IdParamError } from \"@smonn/ids/express\";\n * import { createTimestampId } from \"@smonn/ids\";\n *\n * const usr = createTimestampId(\"usr\");\n *\n * // Default: forwards error to app error-handling middleware\n * app.get(\"/users/:id\", idParam(\"id\", usr), (req, res) => {\n * const id = res.locals.id; // Id<\"usr\">, canonical\n * });\n *\n * // Error-handling middleware receives the typed error\n * app.use((err, req, res, next) => {\n * if (err instanceof IdParamError) {\n * res.status(err.status).json({ error: err.reason });\n * return;\n * }\n * next(err);\n * });\n *\n * // Override: consumer fully owns the response\n * app.get(\"/orgs/:id\", idParam(\"id\", org, {\n * onError: (failure, req, res) => res.status(failure.status).json({ error: failure.reason }),\n * }), handler);\n *\n * // Or a lightweight status remap without a full handler\n * app.get(\"/things/:id\", idParam(\"id\", thing, { status: { brand_mismatch: 400 } }), handler);\n * ```\n */\nexport function idParam<ParamKey extends string, Brand extends string>(\n paramName: ParamKey,\n codec: IdCodec<Brand>,\n options?: IdParamOptions,\n): (req: Request, res: Response<unknown, Record<ParamKey, Id<Brand>>>, next: NextFunction) => void {\n return (req, res, next): void => {\n const raw = req.params[paramName];\n const result = codec.safeParse(raw);\n if (!result.ok) {\n const failure = resolveIdParamFailure(result.error, options);\n if (options?.onError) {\n options.onError(failure, req, res, next);\n return;\n }\n next(new IdParamError(failure.reason, failure.status));\n return;\n }\n (res.locals as Record<string, unknown>)[paramName] = result.id;\n next();\n };\n}\n\n/**\n * Express middleware that validates a named query-string param against a codec via `safeParse`.\n *\n * Same failure contract as `idParam` — same `IdParamOptions` / `IdParamFailure` shape, same\n * `IdParamError` forwarded to `next(err)` — but reads `req.query[queryName]` instead of\n * `req.params[queryName]`.\n *\n * **Default (no options):** calls `next(err)` with an `IdParamError` carrying `status` and\n * `reason`, so the app's existing error-handling middleware controls rendering. The adapter\n * does not write a response body itself.\n *\n * **`options.onError`:** when provided, the hook owns the response entirely — the adapter does\n * not call `next(err)`.\n *\n * **`options.status`:** remaps the default HTTP status for a reason without a full handler.\n *\n * - **Brand mismatch (`invalid_prefix`) → `reason: \"brand_mismatch\"`, default 404**\n * - **Malformed or missing query param → `reason: \"malformed\"`, default 400**\n *\n * On success, stores the canonical `Id<Brand>` in `res.locals` under `queryName`\n * and calls `next()`.\n *\n * @example\n * ```ts\n * import { idQuery, IdParamError } from \"@smonn/ids/express\";\n * import { createTimestampId } from \"@smonn/ids\";\n *\n * const usr = createTimestampId(\"usr\");\n *\n * // Default: forwards error to app error-handling middleware\n * // GET /users?userId=usr_...\n * app.get(\"/users\", idQuery(\"userId\", usr), (req, res) => {\n * const userId = res.locals.userId; // Id<\"usr\">, canonical\n * });\n *\n * // Override: consumer fully owns the response\n * app.get(\"/search\", idQuery(\"cursor\", usr, {\n * onError: (failure, req, res) => res.status(failure.status).json({ error: failure.reason }),\n * }), handler);\n * ```\n */\nexport function idQuery<ParamKey extends string, Brand extends string>(\n queryName: ParamKey,\n codec: IdCodec<Brand>,\n options?: IdParamOptions,\n): (req: Request, res: Response<unknown, Record<ParamKey, Id<Brand>>>, next: NextFunction) => void {\n return (req, res, next): void => {\n const raw = req.query[queryName] as string | undefined;\n const result = codec.safeParse(raw);\n if (!result.ok) {\n const failure = resolveIdParamFailure(result.error, options);\n if (options?.onError) {\n options.onError(failure, req, res, next);\n return;\n }\n next(new IdParamError(failure.reason, failure.status));\n return;\n }\n (res.locals as Record<string, unknown>)[queryName] = result.id;\n next();\n };\n}\n"],"mappings":";;;;;;AAUA,IAAa,eAAb,cAAkC,MAAM;CACtC;CACA;CAEA,YAAY,QAAwC,QAAgB;EAClE,MAAM,yBAAyB,QAAQ;EACvC,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,SAAS;CAChB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgEA,SAAgB,QACd,WACA,OACA,SACiG;CACjG,QAAQ,KAAK,KAAK,SAAe;EAC/B,MAAM,MAAM,IAAI,OAAO;EACvB,MAAM,SAAS,MAAM,UAAU,GAAG;EAClC,IAAI,CAAC,OAAO,IAAI;GACd,MAAM,UAAU,sBAAsB,OAAO,OAAO,OAAO;GAC3D,IAAI,SAAS,SAAS;IACpB,QAAQ,QAAQ,SAAS,KAAK,KAAK,IAAI;IACvC;GACF;GACA,KAAK,IAAI,aAAa,QAAQ,QAAQ,QAAQ,MAAM,CAAC;GACrD;EACF;EACA,IAAK,OAAmC,aAAa,OAAO;EAC5D,KAAK;CACP;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,SAAgB,QACd,WACA,OACA,SACiG;CACjG,QAAQ,KAAK,KAAK,SAAe;EAC/B,MAAM,MAAM,IAAI,MAAM;EACtB,MAAM,SAAS,MAAM,UAAU,GAAG;EAClC,IAAI,CAAC,OAAO,IAAI;GACd,MAAM,UAAU,sBAAsB,OAAO,OAAO,OAAO;GAC3D,IAAI,SAAS,SAAS;IACpB,QAAQ,QAAQ,SAAS,KAAK,KAAK,IAAI;IACvC;GACF;GACA,KAAK,IAAI,aAAa,QAAQ,QAAQ,QAAQ,MAAM,CAAC;GACrD;EACF;EACA,IAAK,OAAmC,aAAa,OAAO;EAC5D,KAAK;CACP;AACF"}
@@ -12,7 +12,7 @@ declare class IdParamError extends Error {
12
12
  readonly reason: "brand_mismatch" | "malformed";
13
13
  constructor(reason: "brand_mismatch" | "malformed", statusCode: number);
14
14
  }
15
- /** Options for `idParam`. All fields are optional. */
15
+ /** Options for `idParam` and `idQuery`. All fields are optional. */
16
16
  type IdParamOptions = {
17
17
  /**
18
18
  * Called instead of throwing when provided. The hook owns the response entirely —
@@ -89,6 +89,53 @@ type IdParamOptions = {
89
89
  declare function idParam<ParamKey extends string, Brand extends string>(paramName: ParamKey, codec: IdCodec<Brand>, options?: IdParamOptions): (request: FastifyRequest<{
90
90
  Params: Record<string, Id<Brand>>;
91
91
  }>, reply: FastifyReply) => Promise<void>;
92
+ /**
93
+ * Fastify `preHandler` hook factory that validates a named query-string param against a codec
94
+ * via `safeParse`.
95
+ *
96
+ * Same failure contract as `idParam` — same `IdParamOptions` / `IdParamFailure` shape, same
97
+ * `IdParamError` thrown into `setErrorHandler` — but reads `request.query[queryName]` instead of
98
+ * `request.params`.
99
+ *
100
+ * **Default (no options):** throws `IdParamError` carrying `statusCode` and `reason` so the
101
+ * app's existing `setErrorHandler` controls rendering. The adapter does not write a response
102
+ * body itself.
103
+ *
104
+ * **`options.onError`:** when provided, the hook calls `onError` and does not throw; the
105
+ * consumer fully owns the response via `reply`.
106
+ *
107
+ * **`options.status`:** remaps the default HTTP status for a reason without a full handler.
108
+ *
109
+ * - **Brand mismatch (`invalid_prefix`) → `reason: "brand_mismatch"`, default 404**
110
+ * - **Malformed or missing query param → `reason: "malformed"`, default 400**
111
+ *
112
+ * On success, stores the canonical `Id<Brand>` in `request.query` under `queryName`.
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * import { idQuery, IdParamError } from "@smonn/ids/fastify";
117
+ * import { createTimestampId } from "@smonn/ids";
118
+ *
119
+ * const usr = createTimestampId("usr");
120
+ *
121
+ * // Default: throws IdParamError → setErrorHandler renders it
122
+ * // GET /users?userId=usr_...
123
+ * fastify.get("/users", { preHandler: idQuery("userId", usr) }, (request, reply) => {
124
+ * const userId = request.query.userId; // string (compile-time); Id<"usr"> at runtime
125
+ * });
126
+ *
127
+ * // Override: consumer fully owns the error response
128
+ * fastify.get("/search", {
129
+ * preHandler: idQuery("cursor", usr, {
130
+ * onError: (failure, request, reply) =>
131
+ * reply.status(failure.status).send({ error: failure.reason }),
132
+ * }),
133
+ * }, handler);
134
+ * ```
135
+ */
136
+ declare function idQuery<ParamKey extends string, Brand extends string>(queryName: ParamKey, codec: IdCodec<Brand>, options?: IdParamOptions): (request: FastifyRequest<{
137
+ Querystring: Record<string, Id<Brand>>;
138
+ }>, reply: FastifyReply) => Promise<void>;
92
139
  //#endregion
93
- export { IdParamError, type IdParamFailure, IdParamOptions, idParam };
140
+ export { IdParamError, type IdParamFailure, IdParamOptions, idParam, idQuery };
94
141
  //# sourceMappingURL=fastify.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fastify.d.mts","names":[],"sources":["../src/adapters/fastify.ts"],"mappings":";;;;;;AAUA;;;cAAa,YAAA,SAAqB,KAAA;EAAA,SACvB,UAAA;EAAA,SACA,MAAA;EAET,WAAA,CAAY,MAAA,kCAAwC,UAAA;AAAA;;KAS1C,cAAA;EAT0C;AAAA;AAStD;;EAKE,OAAA,IACE,OAAA,EAAS,cAAA,EACT,OAAA,EAAS,cAAA,EACT,KAAA,EAAO,YAAA,YACG,OAAA;;;;;EAKZ,MAAA;IAAW,cAAA;IAAyB,SAAA;EAAA;AAAA;;;;;;;;;;AAAA;AA6DtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOK;;;;;;;;;;;;;;iBAPW,OAAA,gDACd,SAAA,EAAW,QAAA,EACX,KAAA,EAAO,OAAA,CAAQ,KAAA,GACf,OAAA,GAAU,cAAA,IAEV,OAAA,EAAS,cAAA;EAAiB,MAAA,EAAQ,MAAA,SAAe,EAAA,CAAG,KAAA;AAAA,IACpD,KAAA,EAAO,YAAA,KACJ,OAAA"}
1
+ {"version":3,"file":"fastify.d.mts","names":[],"sources":["../src/adapters/fastify.ts"],"mappings":";;;;;;AAUA;;;cAAa,YAAA,SAAqB,KAAA;EAAA,SACvB,UAAA;EAAA,SACA,MAAA;EAET,WAAA,CAAY,MAAA,kCAAwC,UAAA;AAAA;;KAS1C,cAAA;EAT0C;AAAA;AAStD;;EAKE,OAAA,IACE,OAAA,EAAS,cAAA,EACT,OAAA,EAAS,cAAA,EACT,KAAA,EAAO,YAAA,YACG,OAAA;;;;;EAKZ,MAAA;IAAW,cAAA;IAAyB,SAAA;EAAA;AAAA;;;;;;;;;;AAAA;AA6DtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOK;AA4DL;;;;;;;;;;;;;iBAnEgB,OAAA,gDACd,SAAA,EAAW,QAAA,EACX,KAAA,EAAO,OAAA,CAAQ,KAAA,GACf,OAAA,GAAU,cAAA,IAEV,OAAA,EAAS,cAAA;EAAiB,MAAA,EAAQ,MAAA,SAAe,EAAA,CAAG,KAAA;AAAA,IACpD,KAAA,EAAO,YAAA,KACJ,OAAA;;;;;;;;;;;;;;;;AAmEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAPW,OAAA,gDACd,SAAA,EAAW,QAAA,EACX,KAAA,EAAO,OAAA,CAAQ,KAAA,GACf,OAAA,GAAU,cAAA,IAEV,OAAA,EAAS,cAAA;EAAiB,WAAA,EAAa,MAAA,SAAe,EAAA,CAAG,KAAA;AAAA,IACzD,KAAA,EAAO,YAAA,KACJ,OAAA"}
package/dist/fastify.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as resolveIdParamFailure } from "./adapter-types-7wWdELSh.mjs";
1
+ import { r as resolveIdParamFailure } from "./adapter-types-CjzFNDcJ.mjs";
2
2
  //#region src/adapters/fastify.ts
3
3
  /**
4
4
  * Typed error thrown into Fastify's `setErrorHandler` on validation failure.
@@ -87,7 +87,66 @@ function idParam(paramName, codec, options) {
87
87
  request.params[paramName] = result.id;
88
88
  };
89
89
  }
90
+ /**
91
+ * Fastify `preHandler` hook factory that validates a named query-string param against a codec
92
+ * via `safeParse`.
93
+ *
94
+ * Same failure contract as `idParam` — same `IdParamOptions` / `IdParamFailure` shape, same
95
+ * `IdParamError` thrown into `setErrorHandler` — but reads `request.query[queryName]` instead of
96
+ * `request.params`.
97
+ *
98
+ * **Default (no options):** throws `IdParamError` carrying `statusCode` and `reason` so the
99
+ * app's existing `setErrorHandler` controls rendering. The adapter does not write a response
100
+ * body itself.
101
+ *
102
+ * **`options.onError`:** when provided, the hook calls `onError` and does not throw; the
103
+ * consumer fully owns the response via `reply`.
104
+ *
105
+ * **`options.status`:** remaps the default HTTP status for a reason without a full handler.
106
+ *
107
+ * - **Brand mismatch (`invalid_prefix`) → `reason: "brand_mismatch"`, default 404**
108
+ * - **Malformed or missing query param → `reason: "malformed"`, default 400**
109
+ *
110
+ * On success, stores the canonical `Id<Brand>` in `request.query` under `queryName`.
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * import { idQuery, IdParamError } from "@smonn/ids/fastify";
115
+ * import { createTimestampId } from "@smonn/ids";
116
+ *
117
+ * const usr = createTimestampId("usr");
118
+ *
119
+ * // Default: throws IdParamError → setErrorHandler renders it
120
+ * // GET /users?userId=usr_...
121
+ * fastify.get("/users", { preHandler: idQuery("userId", usr) }, (request, reply) => {
122
+ * const userId = request.query.userId; // string (compile-time); Id<"usr"> at runtime
123
+ * });
124
+ *
125
+ * // Override: consumer fully owns the error response
126
+ * fastify.get("/search", {
127
+ * preHandler: idQuery("cursor", usr, {
128
+ * onError: (failure, request, reply) =>
129
+ * reply.status(failure.status).send({ error: failure.reason }),
130
+ * }),
131
+ * }, handler);
132
+ * ```
133
+ */
134
+ function idQuery(queryName, codec, options) {
135
+ return async (request, reply) => {
136
+ const raw = request.query[queryName];
137
+ const result = codec.safeParse(raw);
138
+ if (!result.ok) {
139
+ const failure = resolveIdParamFailure(result.error, options);
140
+ if (options?.onError) {
141
+ await options.onError(failure, request, reply);
142
+ return;
143
+ }
144
+ throw new IdParamError(failure.reason, failure.status);
145
+ }
146
+ request.query[queryName] = result.id;
147
+ };
148
+ }
90
149
  //#endregion
91
- export { IdParamError, idParam };
150
+ export { IdParamError, idParam, idQuery };
92
151
 
93
152
  //# sourceMappingURL=fastify.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"fastify.mjs","names":[],"sources":["../src/adapters/fastify.ts"],"sourcesContent":["import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport { type IdCodec, type IdParamFailure, resolveIdParamFailure } from \"./adapter-types.js\";\nimport type { Id } from \"../types.js\";\n\nexport type { IdParamFailure };\n\n/**\n * Typed error thrown into Fastify's `setErrorHandler` on validation failure.\n * Inspect `err.reason` and `err.statusCode` in your error handler.\n */\nexport class IdParamError extends Error {\n readonly statusCode: number;\n readonly reason: \"brand_mismatch\" | \"malformed\";\n\n constructor(reason: \"brand_mismatch\" | \"malformed\", statusCode: number) {\n super(`ID validation failed: ${reason}`);\n this.name = \"IdParamError\";\n this.reason = reason;\n this.statusCode = statusCode;\n }\n}\n\n/** Options for `idParam`. All fields are optional. */\nexport type IdParamOptions = {\n /**\n * Called instead of throwing when provided. The hook owns the response entirely —\n * the adapter does not throw.\n */\n onError?: (\n failure: IdParamFailure,\n request: FastifyRequest,\n reply: FastifyReply,\n ) => void | Promise<void>;\n /**\n * Remap the default HTTP status for a failure reason without a full handler.\n * e.g. `{ brand_mismatch: 400 }` treats both failure kinds as 400.\n */\n status?: { brand_mismatch?: number; malformed?: number };\n};\n\n/**\n * Fastify `preHandler` hook factory that validates a named route param against a codec via `safeParse`.\n *\n * **Default (no options):** throws `IdParamError` carrying `statusCode` and `reason` so the app's\n * existing `setErrorHandler` controls rendering. The adapter does not write a response body itself.\n *\n * **`options.onError`:** when provided, the hook calls `onError` and does not throw; the consumer\n * fully owns the response via `reply`.\n *\n * **`options.status`:** remaps the default HTTP status for a reason without a full handler.\n *\n * - **Brand mismatch (`invalid_prefix`) → `reason: \"brand_mismatch\"`, default 404**\n * - **Malformed or missing ID → `reason: \"malformed\"`, default 400**\n *\n * On success, stores the canonical `Id<Brand>` in `request.params` under `paramName`.\n *\n * **Return type note:** the returned hook is typed as\n * `(request: FastifyRequest<{ Params: Record<string, Id<Brand>> }>, reply: FastifyReply) => Promise<void>`.\n * Assigning it to a Fastify `preHandler` slot is backward-compatible (method-signature bivariance applies).\n * However, a locally-annotated variable typed as the bare `(request: FastifyRequest, reply: FastifyReply) => Promise<void>`\n * will produce a TypeScript error under `--strictFunctionTypes` because function parameter types are contravariant.\n * Use `preHandler` assignment or let TypeScript infer the type to avoid this.\n *\n * @example\n * ```ts\n * import { idParam, IdParamError } from \"@smonn/ids/fastify\";\n * import { createTimestampId } from \"@smonn/ids\";\n *\n * const usr = createTimestampId(\"usr\");\n *\n * // Default: throws IdParamError → setErrorHandler renders it\n * fastify.get(\"/users/:id\", { preHandler: idParam(\"id\", usr) }, (request, reply) => {\n * const id = request.params.id; // string (compile-time); Id<\"usr\"> at runtime after preHandler\n * });\n *\n * // Error handler receives the typed error\n * fastify.setErrorHandler((err, request, reply) => {\n * if (err instanceof IdParamError) {\n * reply.status(err.statusCode).send({ error: err.reason });\n * return;\n * }\n * reply.send(err);\n * });\n *\n * // Override: consumer fully owns the error response\n * fastify.get(\"/orgs/:id\", {\n * preHandler: idParam(\"id\", org, {\n * onError: (failure, request, reply) =>\n * reply.status(failure.status).send({ error: failure.reason }),\n * }),\n * }, handler);\n *\n * // Or a lightweight status remap without a full handler\n * fastify.get(\"/things/:id\", {\n * preHandler: idParam(\"id\", thing, { status: { brand_mismatch: 400 } }),\n * }, handler);\n * ```\n */\nexport function idParam<ParamKey extends string, Brand extends string>(\n paramName: ParamKey,\n codec: IdCodec<Brand>,\n options?: IdParamOptions,\n): (\n request: FastifyRequest<{ Params: Record<string, Id<Brand>> }>,\n reply: FastifyReply,\n) => Promise<void> {\n return async (request, reply): Promise<void> => {\n const raw = request.params[paramName];\n const result = codec.safeParse(raw);\n if (!result.ok) {\n const failure = resolveIdParamFailure(result.error, options);\n if (options?.onError) {\n await options.onError(failure, request, reply);\n return;\n }\n throw new IdParamError(failure.reason, failure.status);\n }\n request.params[paramName] = result.id;\n };\n}\n"],"mappings":";;;;;;AAUA,IAAa,eAAb,cAAkC,MAAM;CACtC;CACA;CAEA,YAAY,QAAwC,YAAoB;EACtE,MAAM,yBAAyB,QAAQ;EACvC,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,aAAa;CACpB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8EA,SAAgB,QACd,WACA,OACA,SAIiB;CACjB,OAAO,OAAO,SAAS,UAAyB;EAC9C,MAAM,MAAM,QAAQ,OAAO;EAC3B,MAAM,SAAS,MAAM,UAAU,GAAG;EAClC,IAAI,CAAC,OAAO,IAAI;GACd,MAAM,UAAU,sBAAsB,OAAO,OAAO,OAAO;GAC3D,IAAI,SAAS,SAAS;IACpB,MAAM,QAAQ,QAAQ,SAAS,SAAS,KAAK;IAC7C;GACF;GACA,MAAM,IAAI,aAAa,QAAQ,QAAQ,QAAQ,MAAM;EACvD;EACA,QAAQ,OAAO,aAAa,OAAO;CACrC;AACF"}
1
+ {"version":3,"file":"fastify.mjs","names":[],"sources":["../src/adapters/fastify.ts"],"sourcesContent":["import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport { type IdCodec, type IdParamFailure, resolveIdParamFailure } from \"./adapter-types.js\";\nimport type { Id } from \"../types.js\";\n\nexport type { IdParamFailure };\n\n/**\n * Typed error thrown into Fastify's `setErrorHandler` on validation failure.\n * Inspect `err.reason` and `err.statusCode` in your error handler.\n */\nexport class IdParamError extends Error {\n readonly statusCode: number;\n readonly reason: \"brand_mismatch\" | \"malformed\";\n\n constructor(reason: \"brand_mismatch\" | \"malformed\", statusCode: number) {\n super(`ID validation failed: ${reason}`);\n this.name = \"IdParamError\";\n this.reason = reason;\n this.statusCode = statusCode;\n }\n}\n\n/** Options for `idParam` and `idQuery`. All fields are optional. */\nexport type IdParamOptions = {\n /**\n * Called instead of throwing when provided. The hook owns the response entirely —\n * the adapter does not throw.\n */\n onError?: (\n failure: IdParamFailure,\n request: FastifyRequest,\n reply: FastifyReply,\n ) => void | Promise<void>;\n /**\n * Remap the default HTTP status for a failure reason without a full handler.\n * e.g. `{ brand_mismatch: 400 }` treats both failure kinds as 400.\n */\n status?: { brand_mismatch?: number; malformed?: number };\n};\n\n/**\n * Fastify `preHandler` hook factory that validates a named route param against a codec via `safeParse`.\n *\n * **Default (no options):** throws `IdParamError` carrying `statusCode` and `reason` so the app's\n * existing `setErrorHandler` controls rendering. The adapter does not write a response body itself.\n *\n * **`options.onError`:** when provided, the hook calls `onError` and does not throw; the consumer\n * fully owns the response via `reply`.\n *\n * **`options.status`:** remaps the default HTTP status for a reason without a full handler.\n *\n * - **Brand mismatch (`invalid_prefix`) → `reason: \"brand_mismatch\"`, default 404**\n * - **Malformed or missing ID → `reason: \"malformed\"`, default 400**\n *\n * On success, stores the canonical `Id<Brand>` in `request.params` under `paramName`.\n *\n * **Return type note:** the returned hook is typed as\n * `(request: FastifyRequest<{ Params: Record<string, Id<Brand>> }>, reply: FastifyReply) => Promise<void>`.\n * Assigning it to a Fastify `preHandler` slot is backward-compatible (method-signature bivariance applies).\n * However, a locally-annotated variable typed as the bare `(request: FastifyRequest, reply: FastifyReply) => Promise<void>`\n * will produce a TypeScript error under `--strictFunctionTypes` because function parameter types are contravariant.\n * Use `preHandler` assignment or let TypeScript infer the type to avoid this.\n *\n * @example\n * ```ts\n * import { idParam, IdParamError } from \"@smonn/ids/fastify\";\n * import { createTimestampId } from \"@smonn/ids\";\n *\n * const usr = createTimestampId(\"usr\");\n *\n * // Default: throws IdParamError → setErrorHandler renders it\n * fastify.get(\"/users/:id\", { preHandler: idParam(\"id\", usr) }, (request, reply) => {\n * const id = request.params.id; // string (compile-time); Id<\"usr\"> at runtime after preHandler\n * });\n *\n * // Error handler receives the typed error\n * fastify.setErrorHandler((err, request, reply) => {\n * if (err instanceof IdParamError) {\n * reply.status(err.statusCode).send({ error: err.reason });\n * return;\n * }\n * reply.send(err);\n * });\n *\n * // Override: consumer fully owns the error response\n * fastify.get(\"/orgs/:id\", {\n * preHandler: idParam(\"id\", org, {\n * onError: (failure, request, reply) =>\n * reply.status(failure.status).send({ error: failure.reason }),\n * }),\n * }, handler);\n *\n * // Or a lightweight status remap without a full handler\n * fastify.get(\"/things/:id\", {\n * preHandler: idParam(\"id\", thing, { status: { brand_mismatch: 400 } }),\n * }, handler);\n * ```\n */\nexport function idParam<ParamKey extends string, Brand extends string>(\n paramName: ParamKey,\n codec: IdCodec<Brand>,\n options?: IdParamOptions,\n): (\n request: FastifyRequest<{ Params: Record<string, Id<Brand>> }>,\n reply: FastifyReply,\n) => Promise<void> {\n return async (request, reply): Promise<void> => {\n const raw = request.params[paramName];\n const result = codec.safeParse(raw);\n if (!result.ok) {\n const failure = resolveIdParamFailure(result.error, options);\n if (options?.onError) {\n await options.onError(failure, request, reply);\n return;\n }\n throw new IdParamError(failure.reason, failure.status);\n }\n request.params[paramName] = result.id;\n };\n}\n\n/**\n * Fastify `preHandler` hook factory that validates a named query-string param against a codec\n * via `safeParse`.\n *\n * Same failure contract as `idParam` — same `IdParamOptions` / `IdParamFailure` shape, same\n * `IdParamError` thrown into `setErrorHandler` — but reads `request.query[queryName]` instead of\n * `request.params`.\n *\n * **Default (no options):** throws `IdParamError` carrying `statusCode` and `reason` so the\n * app's existing `setErrorHandler` controls rendering. The adapter does not write a response\n * body itself.\n *\n * **`options.onError`:** when provided, the hook calls `onError` and does not throw; the\n * consumer fully owns the response via `reply`.\n *\n * **`options.status`:** remaps the default HTTP status for a reason without a full handler.\n *\n * - **Brand mismatch (`invalid_prefix`) → `reason: \"brand_mismatch\"`, default 404**\n * - **Malformed or missing query param → `reason: \"malformed\"`, default 400**\n *\n * On success, stores the canonical `Id<Brand>` in `request.query` under `queryName`.\n *\n * @example\n * ```ts\n * import { idQuery, IdParamError } from \"@smonn/ids/fastify\";\n * import { createTimestampId } from \"@smonn/ids\";\n *\n * const usr = createTimestampId(\"usr\");\n *\n * // Default: throws IdParamError → setErrorHandler renders it\n * // GET /users?userId=usr_...\n * fastify.get(\"/users\", { preHandler: idQuery(\"userId\", usr) }, (request, reply) => {\n * const userId = request.query.userId; // string (compile-time); Id<\"usr\"> at runtime\n * });\n *\n * // Override: consumer fully owns the error response\n * fastify.get(\"/search\", {\n * preHandler: idQuery(\"cursor\", usr, {\n * onError: (failure, request, reply) =>\n * reply.status(failure.status).send({ error: failure.reason }),\n * }),\n * }, handler);\n * ```\n */\nexport function idQuery<ParamKey extends string, Brand extends string>(\n queryName: ParamKey,\n codec: IdCodec<Brand>,\n options?: IdParamOptions,\n): (\n request: FastifyRequest<{ Querystring: Record<string, Id<Brand>> }>,\n reply: FastifyReply,\n) => Promise<void> {\n return async (request, reply): Promise<void> => {\n const raw = request.query[queryName];\n const result = codec.safeParse(raw);\n if (!result.ok) {\n const failure = resolveIdParamFailure(result.error, options);\n if (options?.onError) {\n await options.onError(failure, request, reply);\n return;\n }\n throw new IdParamError(failure.reason, failure.status);\n }\n request.query[queryName] = result.id;\n };\n}\n"],"mappings":";;;;;;AAUA,IAAa,eAAb,cAAkC,MAAM;CACtC;CACA;CAEA,YAAY,QAAwC,YAAoB;EACtE,MAAM,yBAAyB,QAAQ;EACvC,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,aAAa;CACpB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8EA,SAAgB,QACd,WACA,OACA,SAIiB;CACjB,OAAO,OAAO,SAAS,UAAyB;EAC9C,MAAM,MAAM,QAAQ,OAAO;EAC3B,MAAM,SAAS,MAAM,UAAU,GAAG;EAClC,IAAI,CAAC,OAAO,IAAI;GACd,MAAM,UAAU,sBAAsB,OAAO,OAAO,OAAO;GAC3D,IAAI,SAAS,SAAS;IACpB,MAAM,QAAQ,QAAQ,SAAS,SAAS,KAAK;IAC7C;GACF;GACA,MAAM,IAAI,aAAa,QAAQ,QAAQ,QAAQ,MAAM;EACvD;EACA,QAAQ,OAAO,aAAa,OAAO;CACrC;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA,SAAgB,QACd,WACA,OACA,SAIiB;CACjB,OAAO,OAAO,SAAS,UAAyB;EAC9C,MAAM,MAAM,QAAQ,MAAM;EAC1B,MAAM,SAAS,MAAM,UAAU,GAAG;EAClC,IAAI,CAAC,OAAO,IAAI;GACd,MAAM,UAAU,sBAAsB,OAAO,OAAO,OAAO;GAC3D,IAAI,SAAS,SAAS;IACpB,MAAM,QAAQ,QAAQ,SAAS,SAAS,KAAK;IAC7C;GACF;GACA,MAAM,IAAI,aAAa,QAAQ,QAAQ,QAAQ,MAAM;EACvD;EACA,QAAQ,MAAM,aAAa,OAAO;CACpC;AACF"}
package/dist/hono.d.mts CHANGED
@@ -4,7 +4,7 @@ import { ContentfulStatusCode } from "hono/utils/http-status";
4
4
  import { Context, MiddlewareHandler } from "hono";
5
5
 
6
6
  //#region src/adapters/hono.d.ts
7
- /** Options for `idParam`. All fields are optional. */
7
+ /** Options for `idParam` and `idQuery`. All fields are optional. */
8
8
  type IdParamOptions = {
9
9
  /**
10
10
  * Called instead of throwing when provided. The hook owns the response entirely —
@@ -61,6 +61,48 @@ type IdParamOptions = {
61
61
  declare function idParam<ParamKey extends string, Brand extends string>(paramName: ParamKey, codec: IdCodec<Brand>, options?: IdParamOptions): MiddlewareHandler<{
62
62
  Variables: Record<ParamKey, Id<Brand>>;
63
63
  }>;
64
+ /**
65
+ * Hono middleware that validates a named query-string param against a codec via `safeParse`.
66
+ *
67
+ * Same failure contract as `idParam` — same `IdParamFailure` shape, same `onError` / `status`
68
+ * options — but reads `c.req.query(queryName)` instead of `c.req.param(queryName)`.
69
+ *
70
+ * **Default (no options):** throws `HTTPException(status)` so the app's existing `onError` handler
71
+ * controls rendering and content negotiation. The adapter does not write a response body itself.
72
+ *
73
+ * **`options.onError`:** when provided, the hook owns the response entirely — the adapter neither
74
+ * throws nor writes a response.
75
+ *
76
+ * **`options.status`:** remaps the default HTTP status for a reason without a full handler.
77
+ *
78
+ * - **Brand mismatch (`invalid_prefix`) → `reason: "brand_mismatch"`, default 404**
79
+ * - **Malformed or missing query param → `reason: "malformed"`, default 400**
80
+ *
81
+ * On success, stores the canonical `Id<Brand>` in the Hono context under `queryName`
82
+ * and calls `next()`.
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * import { idQuery } from "@smonn/ids/hono";
87
+ * import { createTimestampId } from "@smonn/ids";
88
+ *
89
+ * const usr = createTimestampId("usr");
90
+ *
91
+ * // Default: throws HTTPException → app.onError renders it
92
+ * // GET /users?userId=usr_...
93
+ * app.get("/users", idQuery("userId", usr), (c) => {
94
+ * const userId = c.get("userId"); // Id<"usr">, canonical
95
+ * });
96
+ *
97
+ * // Override: consumer fully owns the response
98
+ * app.get("/search", idQuery("cursor", usr, {
99
+ * onError: (failure, c) => c.json({ error: failure.reason }, failure.status),
100
+ * }), handler);
101
+ * ```
102
+ */
103
+ declare function idQuery<ParamKey extends string, Brand extends string>(queryName: ParamKey, codec: IdCodec<Brand>, options?: IdParamOptions): MiddlewareHandler<{
104
+ Variables: Record<ParamKey, Id<Brand>>;
105
+ }>;
64
106
  //#endregion
65
- export { type IdParamFailure, IdParamOptions, idParam };
107
+ export { type IdParamFailure, IdParamOptions, idParam, idQuery };
66
108
  //# sourceMappingURL=hono.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hono.d.mts","names":[],"sources":["../src/adapters/hono.ts"],"mappings":";;;;;;;KASY,cAAA;EAAA;;;;EAKV,OAAA,IAAW,OAAA,EAAS,cAAA,EAAgB,CAAA,EAAG,OAAA,KAAY,QAAA,GAAW,OAAA,CAAQ,QAAA;;;;;EAKtE,MAAA;IAAW,cAAA,GAAiB,oBAAA;IAAsB,SAAA,GAAY,oBAAA;EAAA;AAAA;;;;;;;;;;;;AAAA;AAyChE;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,OAAA,gDACd,SAAA,EAAW,QAAA,EACX,KAAA,EAAO,OAAA,CAAQ,KAAA,GACf,OAAA,GAAU,cAAA,GACT,iBAAA;EAAoB,SAAA,EAAW,MAAA,CAAO,QAAA,EAAU,EAAA,CAAG,KAAA;AAAA"}
1
+ {"version":3,"file":"hono.d.mts","names":[],"sources":["../src/adapters/hono.ts"],"mappings":";;;;;;;KASY,cAAA;EAAA;;;;EAKV,OAAA,IAAW,OAAA,EAAS,cAAA,EAAgB,CAAA,EAAG,OAAA,KAAY,QAAA,GAAW,OAAA,CAAQ,QAAA;;;;;EAKtE,MAAA;IAAW,cAAA,GAAiB,oBAAA;IAAsB,SAAA,GAAY,oBAAA;EAAA;AAAA;;;;;;;;;;;;AAAA;AAyChE;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,OAAA,gDACd,SAAA,EAAW,QAAA,EACX,KAAA,EAAO,OAAA,CAAQ,KAAA,GACf,OAAA,GAAU,cAAA,GACT,iBAAA;EAAoB,SAAA,EAAW,MAAA,CAAO,QAAA,EAAU,EAAA,CAAG,KAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA;;;;;;;;;;iBAJtC,OAAA,gDACd,SAAA,EAAW,QAAA,EACX,KAAA,EAAO,OAAA,CAAQ,KAAA,GACf,OAAA,GAAU,cAAA,GACT,iBAAA;EAAoB,SAAA,EAAW,MAAA,CAAO,QAAA,EAAU,EAAA,CAAG,KAAA;AAAA"}
package/dist/hono.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as resolveIdParamFailure } from "./adapter-types-7wWdELSh.mjs";
1
+ import { r as resolveIdParamFailure } from "./adapter-types-CjzFNDcJ.mjs";
2
2
  import { HTTPException } from "hono/http-exception";
3
3
  //#region src/adapters/hono.ts
4
4
  /**
@@ -52,7 +52,59 @@ function idParam(paramName, codec, options) {
52
52
  await next();
53
53
  };
54
54
  }
55
+ /**
56
+ * Hono middleware that validates a named query-string param against a codec via `safeParse`.
57
+ *
58
+ * Same failure contract as `idParam` — same `IdParamFailure` shape, same `onError` / `status`
59
+ * options — but reads `c.req.query(queryName)` instead of `c.req.param(queryName)`.
60
+ *
61
+ * **Default (no options):** throws `HTTPException(status)` so the app's existing `onError` handler
62
+ * controls rendering and content negotiation. The adapter does not write a response body itself.
63
+ *
64
+ * **`options.onError`:** when provided, the hook owns the response entirely — the adapter neither
65
+ * throws nor writes a response.
66
+ *
67
+ * **`options.status`:** remaps the default HTTP status for a reason without a full handler.
68
+ *
69
+ * - **Brand mismatch (`invalid_prefix`) → `reason: "brand_mismatch"`, default 404**
70
+ * - **Malformed or missing query param → `reason: "malformed"`, default 400**
71
+ *
72
+ * On success, stores the canonical `Id<Brand>` in the Hono context under `queryName`
73
+ * and calls `next()`.
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * import { idQuery } from "@smonn/ids/hono";
78
+ * import { createTimestampId } from "@smonn/ids";
79
+ *
80
+ * const usr = createTimestampId("usr");
81
+ *
82
+ * // Default: throws HTTPException → app.onError renders it
83
+ * // GET /users?userId=usr_...
84
+ * app.get("/users", idQuery("userId", usr), (c) => {
85
+ * const userId = c.get("userId"); // Id<"usr">, canonical
86
+ * });
87
+ *
88
+ * // Override: consumer fully owns the response
89
+ * app.get("/search", idQuery("cursor", usr, {
90
+ * onError: (failure, c) => c.json({ error: failure.reason }, failure.status),
91
+ * }), handler);
92
+ * ```
93
+ */
94
+ function idQuery(queryName, codec, options) {
95
+ return async (c, next) => {
96
+ const raw = c.req.query(queryName);
97
+ const result = codec.safeParse(raw);
98
+ if (!result.ok) {
99
+ const failure = resolveIdParamFailure(result.error, options);
100
+ if (options?.onError) return options.onError(failure, c);
101
+ throw new HTTPException(failure.status);
102
+ }
103
+ c.set(queryName, result.id);
104
+ await next();
105
+ };
106
+ }
55
107
  //#endregion
56
- export { idParam };
108
+ export { idParam, idQuery };
57
109
 
58
110
  //# sourceMappingURL=hono.mjs.map
package/dist/hono.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hono.mjs","names":[],"sources":["../src/adapters/hono.ts"],"sourcesContent":["import { HTTPException } from \"hono/http-exception\";\nimport type { ContentfulStatusCode } from \"hono/utils/http-status\";\nimport type { Context, MiddlewareHandler } from \"hono\";\nimport { type IdCodec, type IdParamFailure, resolveIdParamFailure } from \"./adapter-types.js\";\nimport type { Id } from \"../types.js\";\n\nexport type { IdParamFailure };\n\n/** Options for `idParam`. All fields are optional. */\nexport type IdParamOptions = {\n /**\n * Called instead of throwing when provided. The hook owns the response entirely —\n * the adapter neither throws nor writes a body.\n */\n onError?: (failure: IdParamFailure, c: Context) => Response | Promise<Response>;\n /**\n * Remap the default HTTP status for a failure reason without a full handler.\n * e.g. `{ brand_mismatch: 400 }` treats both failure kinds as 400.\n */\n status?: { brand_mismatch?: ContentfulStatusCode; malformed?: ContentfulStatusCode };\n};\n\n/**\n * Hono middleware that validates a named route param against a codec via `safeParse`.\n *\n * **Default (no options):** throws `HTTPException(status)` so the app's existing `onError` handler\n * controls rendering and content negotiation. The adapter does not write a response body itself.\n *\n * **`options.onError`:** when provided, the hook owns the response entirely — the adapter neither\n * throws nor writes a response.\n *\n * **`options.status`:** remaps the default HTTP status for a reason without a full handler.\n *\n * - **Brand mismatch (`invalid_prefix`) → `reason: \"brand_mismatch\"`, default 404**\n * - **Malformed or missing ID → `reason: \"malformed\"`, default 400**\n *\n * On success, stores the canonical `Id<Brand>` in the Hono context under `paramName`\n * and calls `next()`.\n *\n * @example\n * ```ts\n * import { idParam } from \"@smonn/ids/hono\";\n * import { createTimestampId } from \"@smonn/ids\";\n *\n * const usr = createTimestampId(\"usr\");\n *\n * // Default: throws HTTPException → app.onError renders it\n * app.get(\"/users/:id\", idParam(\"id\", usr), (c) => {\n * const id = c.get(\"id\"); // Id<\"usr\">, canonical\n * });\n *\n * // Override: consumer fully owns the response\n * app.get(\"/orgs/:id\", idParam(\"id\", org, {\n * onError: (failure, c) => c.json({ error: failure.reason }, failure.status),\n * }), handler);\n *\n * // Or a lightweight status remap without a full handler\n * app.get(\"/things/:id\", idParam(\"id\", thing, { status: { brand_mismatch: 400 } }), handler);\n * ```\n */\nexport function idParam<ParamKey extends string, Brand extends string>(\n paramName: ParamKey,\n codec: IdCodec<Brand>,\n options?: IdParamOptions,\n): MiddlewareHandler<{ Variables: Record<ParamKey, Id<Brand>> }> {\n return async (c, next) => {\n const raw = c.req.param(paramName);\n const result = codec.safeParse(raw);\n if (!result.ok) {\n const failure = resolveIdParamFailure(result.error, options);\n if (options?.onError) {\n return options.onError(failure, c);\n }\n throw new HTTPException(failure.status as ContentfulStatusCode);\n }\n c.set(paramName, result.id);\n await next();\n return;\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA,SAAgB,QACd,WACA,OACA,SAC+D;CAC/D,OAAO,OAAO,GAAG,SAAS;EACxB,MAAM,MAAM,EAAE,IAAI,MAAM,SAAS;EACjC,MAAM,SAAS,MAAM,UAAU,GAAG;EAClC,IAAI,CAAC,OAAO,IAAI;GACd,MAAM,UAAU,sBAAsB,OAAO,OAAO,OAAO;GAC3D,IAAI,SAAS,SACX,OAAO,QAAQ,QAAQ,SAAS,CAAC;GAEnC,MAAM,IAAI,cAAc,QAAQ,MAA8B;EAChE;EACA,EAAE,IAAI,WAAW,OAAO,EAAE;EAC1B,MAAM,KAAK;CAEb;AACF"}
1
+ {"version":3,"file":"hono.mjs","names":[],"sources":["../src/adapters/hono.ts"],"sourcesContent":["import { HTTPException } from \"hono/http-exception\";\nimport type { ContentfulStatusCode } from \"hono/utils/http-status\";\nimport type { Context, MiddlewareHandler } from \"hono\";\nimport { type IdCodec, type IdParamFailure, resolveIdParamFailure } from \"./adapter-types.js\";\nimport type { Id } from \"../types.js\";\n\nexport type { IdParamFailure };\n\n/** Options for `idParam` and `idQuery`. All fields are optional. */\nexport type IdParamOptions = {\n /**\n * Called instead of throwing when provided. The hook owns the response entirely —\n * the adapter neither throws nor writes a body.\n */\n onError?: (failure: IdParamFailure, c: Context) => Response | Promise<Response>;\n /**\n * Remap the default HTTP status for a failure reason without a full handler.\n * e.g. `{ brand_mismatch: 400 }` treats both failure kinds as 400.\n */\n status?: { brand_mismatch?: ContentfulStatusCode; malformed?: ContentfulStatusCode };\n};\n\n/**\n * Hono middleware that validates a named route param against a codec via `safeParse`.\n *\n * **Default (no options):** throws `HTTPException(status)` so the app's existing `onError` handler\n * controls rendering and content negotiation. The adapter does not write a response body itself.\n *\n * **`options.onError`:** when provided, the hook owns the response entirely — the adapter neither\n * throws nor writes a response.\n *\n * **`options.status`:** remaps the default HTTP status for a reason without a full handler.\n *\n * - **Brand mismatch (`invalid_prefix`) → `reason: \"brand_mismatch\"`, default 404**\n * - **Malformed or missing ID → `reason: \"malformed\"`, default 400**\n *\n * On success, stores the canonical `Id<Brand>` in the Hono context under `paramName`\n * and calls `next()`.\n *\n * @example\n * ```ts\n * import { idParam } from \"@smonn/ids/hono\";\n * import { createTimestampId } from \"@smonn/ids\";\n *\n * const usr = createTimestampId(\"usr\");\n *\n * // Default: throws HTTPException → app.onError renders it\n * app.get(\"/users/:id\", idParam(\"id\", usr), (c) => {\n * const id = c.get(\"id\"); // Id<\"usr\">, canonical\n * });\n *\n * // Override: consumer fully owns the response\n * app.get(\"/orgs/:id\", idParam(\"id\", org, {\n * onError: (failure, c) => c.json({ error: failure.reason }, failure.status),\n * }), handler);\n *\n * // Or a lightweight status remap without a full handler\n * app.get(\"/things/:id\", idParam(\"id\", thing, { status: { brand_mismatch: 400 } }), handler);\n * ```\n */\nexport function idParam<ParamKey extends string, Brand extends string>(\n paramName: ParamKey,\n codec: IdCodec<Brand>,\n options?: IdParamOptions,\n): MiddlewareHandler<{ Variables: Record<ParamKey, Id<Brand>> }> {\n return async (c, next) => {\n const raw = c.req.param(paramName);\n const result = codec.safeParse(raw);\n if (!result.ok) {\n const failure = resolveIdParamFailure(result.error, options);\n if (options?.onError) {\n return options.onError(failure, c);\n }\n throw new HTTPException(failure.status as ContentfulStatusCode);\n }\n c.set(paramName, result.id);\n await next();\n return;\n };\n}\n\n/**\n * Hono middleware that validates a named query-string param against a codec via `safeParse`.\n *\n * Same failure contract as `idParam` — same `IdParamFailure` shape, same `onError` / `status`\n * options — but reads `c.req.query(queryName)` instead of `c.req.param(queryName)`.\n *\n * **Default (no options):** throws `HTTPException(status)` so the app's existing `onError` handler\n * controls rendering and content negotiation. The adapter does not write a response body itself.\n *\n * **`options.onError`:** when provided, the hook owns the response entirely — the adapter neither\n * throws nor writes a response.\n *\n * **`options.status`:** remaps the default HTTP status for a reason without a full handler.\n *\n * - **Brand mismatch (`invalid_prefix`) → `reason: \"brand_mismatch\"`, default 404**\n * - **Malformed or missing query param → `reason: \"malformed\"`, default 400**\n *\n * On success, stores the canonical `Id<Brand>` in the Hono context under `queryName`\n * and calls `next()`.\n *\n * @example\n * ```ts\n * import { idQuery } from \"@smonn/ids/hono\";\n * import { createTimestampId } from \"@smonn/ids\";\n *\n * const usr = createTimestampId(\"usr\");\n *\n * // Default: throws HTTPException → app.onError renders it\n * // GET /users?userId=usr_...\n * app.get(\"/users\", idQuery(\"userId\", usr), (c) => {\n * const userId = c.get(\"userId\"); // Id<\"usr\">, canonical\n * });\n *\n * // Override: consumer fully owns the response\n * app.get(\"/search\", idQuery(\"cursor\", usr, {\n * onError: (failure, c) => c.json({ error: failure.reason }, failure.status),\n * }), handler);\n * ```\n */\nexport function idQuery<ParamKey extends string, Brand extends string>(\n queryName: ParamKey,\n codec: IdCodec<Brand>,\n options?: IdParamOptions,\n): MiddlewareHandler<{ Variables: Record<ParamKey, Id<Brand>> }> {\n return async (c, next) => {\n const raw = c.req.query(queryName);\n const result = codec.safeParse(raw);\n if (!result.ok) {\n const failure = resolveIdParamFailure(result.error, options);\n if (options?.onError) {\n return options.onError(failure, c);\n }\n throw new HTTPException(failure.status as ContentfulStatusCode);\n }\n c.set(queryName, result.id);\n await next();\n return;\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA,SAAgB,QACd,WACA,OACA,SAC+D;CAC/D,OAAO,OAAO,GAAG,SAAS;EACxB,MAAM,MAAM,EAAE,IAAI,MAAM,SAAS;EACjC,MAAM,SAAS,MAAM,UAAU,GAAG;EAClC,IAAI,CAAC,OAAO,IAAI;GACd,MAAM,UAAU,sBAAsB,OAAO,OAAO,OAAO;GAC3D,IAAI,SAAS,SACX,OAAO,QAAQ,QAAQ,SAAS,CAAC;GAEnC,MAAM,IAAI,cAAc,QAAQ,MAA8B;EAChE;EACA,EAAE,IAAI,WAAW,OAAO,EAAE;EAC1B,MAAM,KAAK;CAEb;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,SAAgB,QACd,WACA,OACA,SAC+D;CAC/D,OAAO,OAAO,GAAG,SAAS;EACxB,MAAM,MAAM,EAAE,IAAI,MAAM,SAAS;EACjC,MAAM,SAAS,MAAM,UAAU,GAAG;EAClC,IAAI,CAAC,OAAO,IAAI;GACd,MAAM,UAAU,sBAAsB,OAAO,OAAO,OAAO;GAC3D,IAAI,SAAS,SACX,OAAO,QAAQ,QAAQ,SAAS,CAAC;GAEnC,MAAM,IAAI,cAAc,QAAQ,MAA8B;EAChE;EACA,EAAE,IAAI,WAAW,OAAO,EAAE;EAC1B,MAAM,KAAK;CAEb;AACF"}
package/dist/kysely.d.mts CHANGED
@@ -1,10 +1,21 @@
1
1
  import { t as Id } from "./types-hGBnCpJj.mjs";
2
2
  import { n as IdColumnCodec } from "./adapter-types-Bia_w9sg.mjs";
3
3
  import { n as IdsErrorCode, r as isIdsError, t as IdsError } from "./error-CifcKKOG.mjs";
4
- import { ColumnType } from "kysely";
4
+ import { ColumnType, KyselyPlugin } from "kysely";
5
5
 
6
6
  //#region src/adapters/kysely.d.ts
7
7
  /**
8
+ * Extension of {@link IdColumnCodec} that also exposes synchronous `generate()`.
9
+ * Required by {@link insertId} so that the insert-time call site can produce a
10
+ * fresh `Id<Brand>` with a compile-time constraint enforcing codec capability.
11
+ * Only the **Timestamp codec** and **Reverse Timestamp codec** satisfy this;
12
+ * async-generate codecs (Opaque, Signed, Wrapped, Digest) do not and are
13
+ * therefore rejected at the TypeScript level.
14
+ */
15
+ type IdGeneratingCodec<Brand extends string> = IdColumnCodec<Brand> & {
16
+ generate(): Id<Brand>;
17
+ };
18
+ /**
8
19
  * Kysely column type mapping for `Id<Brand>`.
9
20
  *
10
21
  * Use this in your Kysely `Database` interface to type a column as `Id<Brand>` at
@@ -23,6 +34,24 @@ import { ColumnType } from "kysely";
23
34
  */
24
35
  type IdColumnType<Brand extends string> = ColumnType<Id<Brand>, Id<Brand>, Id<Brand>>;
25
36
  /**
37
+ * Kysely column type mapping for a nullable `Id<Brand>` column.
38
+ *
39
+ * Use in your Kysely `Database` interface for optional foreign keys or any
40
+ * column that can be `NULL`. Pair with `nullableIdColumn(codec)` for runtime
41
+ * transformation.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * import type { NullableIdColumnType } from "@smonn/ids/kysely";
46
+ * import type { Id } from "@smonn/ids";
47
+ *
48
+ * interface Database {
49
+ * posts: { authorId: NullableIdColumnType<"usr"> };
50
+ * }
51
+ * ```
52
+ */
53
+ type NullableIdColumnType<Brand extends string> = ColumnType<Id<Brand> | null, Id<Brand> | null, Id<Brand> | null>;
54
+ /**
26
55
  * Kysely column adapter bound to a codec.
27
56
  *
28
57
  * Returns an object with `fromDriver` / `toDriver` helpers that mirror the read/write
@@ -51,6 +80,78 @@ declare function idColumn<Brand extends string>(codec: IdColumnCodec<Brand>): {
51
80
  toDriver(value: Id<Brand>): string;
52
81
  fromDriver(value: string): Id<Brand>;
53
82
  };
83
+ /**
84
+ * Generates a fresh `Id<Brand>` for use at a Kysely insert call site.
85
+ *
86
+ * Requires a codec variant that exposes a synchronous `generate()` — see
87
+ * {@link IdGeneratingCodec}. Only the **Timestamp codec** and **Reverse
88
+ * Timestamp codec** qualify; Opaque, Signed, Wrapped, and Digest codecs
89
+ * are rejected at compile time.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * import { insertId } from "@smonn/ids/kysely";
94
+ * import { createTimestampId } from "@smonn/ids";
95
+ *
96
+ * const usr = createTimestampId("usr");
97
+ *
98
+ * await db.insertInto("users").values({ id: insertId(usr), name: "Alice" }).execute();
99
+ * ```
100
+ */
101
+ declare function insertId<Brand extends string>(codec: IdGeneratingCodec<Brand>): Id<Brand>;
102
+ /**
103
+ * Kysely plugin that automatically transforms result columns using the provided codec map.
104
+ *
105
+ * Keys in `map` are plain column names (`"id"`) or `"table.column"` qualified names
106
+ * (`"users.id"`). Plain names match any result column with that name; qualified names
107
+ * match by the column-name part (after the last `.`). If both a plain key and a qualified
108
+ * key resolve to the same column name, the qualified key takes precedence.
109
+ *
110
+ * `transformResult` calls `readIdColumn(codec, rawValue)` for each matched column, returning
111
+ * a branded `Id<Brand>` on success and throwing `IdsError("invalid_id")` on parse failure.
112
+ * `transformQuery` is a no-op identity pass-through.
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * import { idPlugin } from "@smonn/ids/kysely";
117
+ * import { createTimestampId } from "@smonn/ids";
118
+ * import { Kysely } from "kysely";
119
+ *
120
+ * const usr = createTimestampId("usr");
121
+ *
122
+ * const db = new Kysely<Database>({
123
+ * // ...
124
+ * plugins: [idPlugin({ "users.id": usr })],
125
+ * });
126
+ *
127
+ * // result.id is automatically validated and branded as Id<"usr">
128
+ * const row = await db.selectFrom("users").selectAll().executeTakeFirstOrThrow();
129
+ * ```
130
+ */
131
+ declare function idPlugin(map: Record<string, IdColumnCodec<string>>): KyselyPlugin;
132
+ /**
133
+ * Kysely column adapter for a **nullable** `Id<Brand>` column.
134
+ *
135
+ * Behaves like {@link idColumn} but `fromDriver` returns `null` for `null` /
136
+ * `undefined` driver values and `toDriver` passes `null` through unchanged.
137
+ * Use for optional foreign keys and `LEFT JOIN` results.
138
+ *
139
+ * @example
140
+ * ```ts
141
+ * import { nullableIdColumn } from "@smonn/ids/kysely";
142
+ * import { createTimestampId } from "@smonn/ids";
143
+ *
144
+ * const usr = createTimestampId("usr");
145
+ * const authorCol = nullableIdColumn(usr);
146
+ *
147
+ * // In a query result handler:
148
+ * const authorId = authorCol.fromDriver(row.author_id); // Id<"usr"> | null
149
+ * ```
150
+ */
151
+ declare function nullableIdColumn<Brand extends string>(codec: IdColumnCodec<Brand>): {
152
+ toDriver(value: Id<Brand> | null): string | null;
153
+ fromDriver(value: string | null): Id<Brand> | null;
154
+ };
54
155
  //#endregion
55
- export { type IdColumnCodec, IdColumnType, IdsError, type IdsErrorCode, idColumn, isIdsError };
156
+ export { type IdColumnCodec, IdColumnType, IdGeneratingCodec, IdsError, type IdsErrorCode, NullableIdColumnType, idColumn, idPlugin, insertId, isIdsError, nullableIdColumn };
56
157
  //# sourceMappingURL=kysely.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"kysely.d.mts","names":[],"sources":["../src/adapters/kysely.ts"],"mappings":";;;;;;AAyBA;;;;;;;;;;;;;;;;;AAAA,KAAY,YAAA,yBAAqC,UAAA,CAAW,EAAA,CAAG,KAAA,GAAQ,EAAA,CAAG,KAAA,GAAQ,EAAA,CAAG,KAAA;;;;AAAA;AA2BrF;;;;;;;;;;;;;;;;;;;;;iBAAgB,QAAA,uBACd,KAAA,EAAO,aAAA,CAAc,KAAA;EAErB,QAAA,CAAS,KAAA,EAAO,EAAA,CAAG,KAAA;EACnB,UAAA,CAAW,KAAA,WAAgB,EAAA,CAAG,KAAA;AAAA"}
1
+ {"version":3,"file":"kysely.d.mts","names":[],"sources":["../src/adapters/kysely.ts"],"mappings":";;;;;;AAuBA;;;;;;;;AAAA,KAAY,iBAAA,yBAA0C,aAAA,CAAc,KAAA;EAClE,QAAA,IAAY,EAAA,CAAG,KAAA;AAAA;;;;;;AAAA;AAoBjB;;;;;;;;;;;KAAY,YAAA,yBAAqC,UAAA,CAAW,EAAA,CAAG,KAAA,GAAQ,EAAA,CAAG,KAAA,GAAQ,EAAA,CAAG,KAAA;;;;;;;;;;AAAA;AAmBrF;;;;;;;KAAY,oBAAA,yBAA6C,UAAA,CACvD,EAAA,CAAG,KAAA,UACH,EAAA,CAAG,KAAA,UACH,EAAA,CAAG,KAAA;;;;;;;;;;;;;;AAAA;AA4BL;;;;;;;;;;;iBAAgB,QAAA,uBACd,KAAA,EAAO,aAAA,CAAc,KAAA;EAErB,QAAA,CAAS,KAAA,EAAO,EAAA,CAAG,KAAA;EACnB,UAAA,CAAW,KAAA,WAAgB,EAAA,CAAG,KAAA;AAAA;;;;;;;;;;AAAA;AA8BhC;;;;;;;;iBAAgB,QAAA,uBAA+B,KAAA,EAAO,iBAAA,CAAkB,KAAA,IAAS,EAAA,CAAG,KAAA;;;;;;;;AAAA;AAiCpF;;;;;;;;;;;;;AAAsE;AAqDtE;;;;;;;iBArDgB,QAAA,CAAS,GAAA,EAAK,MAAA,SAAe,aAAA,YAAyB,YAAA;;;;;;;;;;;;;;;;;AAyD/B;;;iBAJvB,gBAAA,uBACd,KAAA,EAAO,aAAA,CAAc,KAAA;EAErB,QAAA,CAAS,KAAA,EAAO,EAAA,CAAG,KAAA;EACnB,UAAA,CAAW,KAAA,kBAAuB,EAAA,CAAG,KAAA;AAAA"}