@nanokajs/core 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +72 -27
- package/dist/index.js +99 -12
- package/dist/index.js.map +1 -1
- package/dist/turso.d.ts +15 -0
- package/dist/turso.js +14 -0
- package/dist/turso.js.map +1 -0
- package/dist/types-D2QDVyks.d.ts +28 -0
- package/package.json +12 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,37 +1,14 @@
|
|
|
1
1
|
import { D1Database } from '@cloudflare/workers-types';
|
|
2
|
-
import {
|
|
3
|
-
import { BaseSQLiteDatabase, SQLiteTable } from 'drizzle-orm/sqlite-core';
|
|
2
|
+
import { A as Adapter } from './types-D2QDVyks.js';
|
|
4
3
|
import { F as Field, I as InferFieldType, a as FieldPolicy } from './factories-Cmvx0495.js';
|
|
5
4
|
export { b as FieldModifiers, t } from './factories-Cmvx0495.js';
|
|
6
5
|
import { Hook } from '@hono/zod-validator';
|
|
6
|
+
import { SQLiteTable } from 'drizzle-orm/sqlite-core';
|
|
7
7
|
import * as hono from 'hono';
|
|
8
8
|
import { ValidationTargets, Env, MiddlewareHandler, Hono } from 'hono';
|
|
9
9
|
import { z } from 'zod';
|
|
10
10
|
import { Env as Env$1, BlankEnv } from 'hono/types';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Generic database adapter abstraction for SQLite-compatible databases.
|
|
14
|
-
*
|
|
15
|
-
* Permits implementations over D1, Turso/libSQL, and other SQLite-compatible backends
|
|
16
|
-
* without requiring changes to core query path or router.
|
|
17
|
-
*
|
|
18
|
-
* The `drizzle` property deliberately exposes the raw Drizzle database instance,
|
|
19
|
-
* adhering to rule #4 (escape hatch always open).
|
|
20
|
-
*
|
|
21
|
-
* The `TResultKind` generic is intentionally constrained to `any` to avoid
|
|
22
|
-
* coupling adapter implementations to Drizzle's internal result kind type.
|
|
23
|
-
*/
|
|
24
|
-
interface Adapter<TSchema extends Record<string, unknown> = Record<string, never>> {
|
|
25
|
-
readonly drizzle: BaseSQLiteDatabase<'async', any, TSchema>;
|
|
26
|
-
/**
|
|
27
|
-
* Executes multiple Drizzle queries in a single batch.
|
|
28
|
-
* Returns results in the same order as the input.
|
|
29
|
-
*
|
|
30
|
-
* **重要**: 実装は `this` 非依存であること(`nanoka()` 内で thin wrapper として再公開されるため、
|
|
31
|
-
* `this` バインディングが失われた状態で呼び出される可能性がある)。
|
|
32
|
-
*/
|
|
33
|
-
batch<U extends BatchItem<'sqlite'>, T extends readonly [U, ...U[]]>(queries: T): Promise<BatchResponse<T>>;
|
|
34
|
-
}
|
|
11
|
+
import 'drizzle-orm/batch';
|
|
35
12
|
|
|
36
13
|
/**
|
|
37
14
|
* D1-specific adapter factory. Wraps Cloudflare D1 binding in the generic
|
|
@@ -47,6 +24,59 @@ interface OpenAPIModelComponent {
|
|
|
47
24
|
output: OpenAPISchemaObject;
|
|
48
25
|
}
|
|
49
26
|
type OpenAPIUsage = 'create' | 'update' | 'output';
|
|
27
|
+
type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
|
28
|
+
interface OpenAPIRequestBodySpec {
|
|
29
|
+
readonly description?: string;
|
|
30
|
+
readonly required?: boolean;
|
|
31
|
+
readonly content: {
|
|
32
|
+
readonly 'application/json': {
|
|
33
|
+
readonly schema: OpenAPISchemaObject;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
interface OpenAPIResponseSpec {
|
|
38
|
+
readonly description: string;
|
|
39
|
+
readonly content?: {
|
|
40
|
+
readonly 'application/json': {
|
|
41
|
+
readonly schema: OpenAPISchemaObject;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
interface OpenAPIParamSpec {
|
|
46
|
+
readonly name: string;
|
|
47
|
+
readonly in: 'path' | 'query' | 'header';
|
|
48
|
+
readonly required?: boolean;
|
|
49
|
+
readonly schema: OpenAPISchemaObject;
|
|
50
|
+
readonly description?: string;
|
|
51
|
+
}
|
|
52
|
+
interface OpenAPIRouteMetadata {
|
|
53
|
+
readonly path: string;
|
|
54
|
+
readonly method: HttpMethod;
|
|
55
|
+
readonly operationId?: string;
|
|
56
|
+
readonly summary?: string;
|
|
57
|
+
readonly description?: string;
|
|
58
|
+
readonly tags?: readonly string[];
|
|
59
|
+
readonly requestBody?: OpenAPIRequestBodySpec;
|
|
60
|
+
readonly params?: OpenAPIParamSpec[];
|
|
61
|
+
readonly responses: Record<string, OpenAPIResponseSpec>;
|
|
62
|
+
}
|
|
63
|
+
interface OpenAPISpecOptions {
|
|
64
|
+
readonly info: {
|
|
65
|
+
readonly title: string;
|
|
66
|
+
readonly version: string;
|
|
67
|
+
readonly description?: string;
|
|
68
|
+
};
|
|
69
|
+
readonly servers?: ReadonlyArray<{
|
|
70
|
+
readonly url: string;
|
|
71
|
+
readonly description?: string;
|
|
72
|
+
}>;
|
|
73
|
+
}
|
|
74
|
+
interface OpenAPIDocument {
|
|
75
|
+
readonly openapi: '3.1.0';
|
|
76
|
+
readonly info: OpenAPISpecOptions['info'];
|
|
77
|
+
readonly servers?: OpenAPISpecOptions['servers'];
|
|
78
|
+
readonly paths: Record<string, Record<string, unknown>>;
|
|
79
|
+
}
|
|
50
80
|
|
|
51
81
|
/**
|
|
52
82
|
* Options for findMany query.
|
|
@@ -415,6 +445,12 @@ interface Model<Fields extends Record<string, Field<any, any, any>>> {
|
|
|
415
445
|
}>;
|
|
416
446
|
}
|
|
417
447
|
|
|
448
|
+
interface SwaggerUIOptions {
|
|
449
|
+
readonly url: string;
|
|
450
|
+
readonly title?: string;
|
|
451
|
+
}
|
|
452
|
+
declare function swaggerUI(options: SwaggerUIOptions): MiddlewareHandler;
|
|
453
|
+
|
|
418
454
|
/**
|
|
419
455
|
* Creates a Model instance from a tableName and fields definition.
|
|
420
456
|
* The model supports deriving Zod schemas, Hono validators, and CRUD operations.
|
|
@@ -523,6 +559,15 @@ interface Nanoka<E extends Env$1 = BlankEnv> extends Hono<E> {
|
|
|
523
559
|
* const users = await User.findMany({ limit: 20 })
|
|
524
560
|
*/
|
|
525
561
|
model<Fields extends Record<string, Field<any, any, any>>>(name: string, fields: Fields): NanokaModel<Fields>;
|
|
562
|
+
/**
|
|
563
|
+
* Registers OpenAPI metadata for a route.
|
|
564
|
+
* Does NOT register the actual Hono handler — call app.get/post/... separately.
|
|
565
|
+
*/
|
|
566
|
+
openapi(metadata: OpenAPIRouteMetadata): this;
|
|
567
|
+
/**
|
|
568
|
+
* Builds the full OpenAPI 3.1 document from all registered openapi() metadata.
|
|
569
|
+
*/
|
|
570
|
+
generateOpenAPISpec(options: OpenAPISpecOptions): OpenAPIDocument;
|
|
526
571
|
}
|
|
527
572
|
|
|
528
573
|
/**
|
|
@@ -546,4 +591,4 @@ interface Nanoka<E extends Env$1 = BlankEnv> extends Hono<E> {
|
|
|
546
591
|
*/
|
|
547
592
|
declare function nanoka<E extends Env$1 = BlankEnv>(adapter: Adapter): Nanoka<E>;
|
|
548
593
|
|
|
549
|
-
export {
|
|
594
|
+
export { Adapter, type CreateInput, Field, FieldPolicy, type FindManyOptions, type HttpMethod, type IdOrWhere, InferFieldType, type Model, type Nanoka, type NanokaModel, type OpenAPIDocument, type OpenAPIModelComponent, type OpenAPIParamSpec, type OpenAPIRequestBodySpec, type OpenAPIResponseSpec, type OpenAPIRouteMetadata, type OpenAPISchemaObject, type OpenAPISpecOptions, type OpenAPIUsage, type OrderBy, type RowType, type SchemaOptions, type Where, d1Adapter, defineModel, nanoka, swaggerUI };
|
package/dist/index.js
CHANGED
|
@@ -129,7 +129,7 @@ function toOpenAPISchema(fields, usage, opts) {
|
|
|
129
129
|
for (const [key, zodSchema] of Object.entries(shape)) {
|
|
130
130
|
const field = fields[key];
|
|
131
131
|
if (field === void 0) continue;
|
|
132
|
-
properties[key] = fieldToOpenAPISchema(field);
|
|
132
|
+
properties[key] = fieldToOpenAPISchema(field, opts?.strict);
|
|
133
133
|
if (field.modifiers.policy === "writeOnly" && (usage === "create" || usage === "update")) {
|
|
134
134
|
properties[key].writeOnly = true;
|
|
135
135
|
}
|
|
@@ -146,8 +146,8 @@ function toOpenAPISchema(fields, usage, opts) {
|
|
|
146
146
|
...required.length > 0 ? { required } : {}
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
|
-
function fieldToOpenAPISchema(field) {
|
|
150
|
-
const schema = field.kind === "json" ? zodToOpenAPISchema(field.zodBase) : field.kind === "string" ? { type: "string" } : field.kind === "uuid" ? { type: "string", format: "uuid" } : field.kind === "number" ? { type: "number" } : field.kind === "integer" ? { type: "integer" } : field.kind === "boolean" ? { type: "boolean" } : field.kind === "timestamp" ? { type: "string", format: "date-time" } : {};
|
|
149
|
+
function fieldToOpenAPISchema(field, strict = false) {
|
|
150
|
+
const schema = field.kind === "json" ? zodToOpenAPISchema(field.zodBase, strict) : field.kind === "string" ? { type: "string" } : field.kind === "uuid" ? { type: "string", format: "uuid" } : field.kind === "number" ? { type: "number" } : field.kind === "integer" ? { type: "integer" } : field.kind === "boolean" ? { type: "boolean" } : field.kind === "timestamp" ? { type: "string", format: "date-time" } : {};
|
|
151
151
|
if (field.modifiers.format === "email") {
|
|
152
152
|
schema.format = "email";
|
|
153
153
|
}
|
|
@@ -167,25 +167,25 @@ function fieldToOpenAPISchema(field) {
|
|
|
167
167
|
}
|
|
168
168
|
return schema;
|
|
169
169
|
}
|
|
170
|
-
function zodToOpenAPISchema(schema) {
|
|
170
|
+
function zodToOpenAPISchema(schema, strict = false) {
|
|
171
171
|
const def = getZodDef(schema);
|
|
172
172
|
if (def === void 0) return {};
|
|
173
173
|
const typeName = getZodTypeName(def);
|
|
174
174
|
if (typeName === "ZodOptional" || typeName === "optional") {
|
|
175
|
-
return zodToOpenAPISchema(def.innerType);
|
|
175
|
+
return zodToOpenAPISchema(def.innerType, strict);
|
|
176
176
|
}
|
|
177
177
|
if (typeName === "ZodDefault" || typeName === "default") {
|
|
178
|
-
return zodToOpenAPISchema(def.innerType);
|
|
178
|
+
return zodToOpenAPISchema(def.innerType, strict);
|
|
179
179
|
}
|
|
180
180
|
if (typeName === "ZodNullable" || typeName === "nullable") {
|
|
181
|
-
return { ...zodToOpenAPISchema(def.innerType), nullable: true };
|
|
181
|
+
return { ...zodToOpenAPISchema(def.innerType, strict), nullable: true };
|
|
182
182
|
}
|
|
183
183
|
if (typeName === "ZodObject" || typeName === "object") {
|
|
184
184
|
const shape = getZodObjectShape(schema);
|
|
185
185
|
const properties = {};
|
|
186
186
|
const required = [];
|
|
187
187
|
for (const [key, childSchema] of Object.entries(shape)) {
|
|
188
|
-
properties[key] = zodToOpenAPISchema(childSchema);
|
|
188
|
+
properties[key] = zodToOpenAPISchema(childSchema, strict);
|
|
189
189
|
if (isRequiredZodSchema(childSchema)) {
|
|
190
190
|
required.push(key);
|
|
191
191
|
}
|
|
@@ -209,16 +209,25 @@ function zodToOpenAPISchema(schema) {
|
|
|
209
209
|
const itemSchema = def.element ?? def.type;
|
|
210
210
|
return {
|
|
211
211
|
type: "array",
|
|
212
|
-
items: zodToOpenAPISchema(itemSchema)
|
|
212
|
+
items: zodToOpenAPISchema(itemSchema, strict)
|
|
213
213
|
};
|
|
214
214
|
}
|
|
215
215
|
if (typeName === "ZodRecord" || typeName === "record") {
|
|
216
216
|
return {
|
|
217
217
|
type: "object",
|
|
218
|
-
additionalProperties: zodToOpenAPISchema(def.valueType)
|
|
218
|
+
additionalProperties: zodToOpenAPISchema(def.valueType, strict)
|
|
219
219
|
};
|
|
220
220
|
}
|
|
221
|
-
|
|
221
|
+
if (typeName === "ZodUnknown" || typeName === "unknown") {
|
|
222
|
+
return {};
|
|
223
|
+
}
|
|
224
|
+
if (strict) {
|
|
225
|
+
throw new Error(`Unsupported Zod type for strict OpenAPI generation: ${typeName ?? "unknown"}`);
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
"x-nanoka-zod-unsupported": true,
|
|
229
|
+
...typeName ? { "x-nanoka-zod-type": typeName } : {}
|
|
230
|
+
};
|
|
222
231
|
}
|
|
223
232
|
function getZodObjectShape(schema) {
|
|
224
233
|
if (typeof schema === "object" && schema !== null && "shape" in schema && typeof schema.shape === "object" && schema.shape !== null) {
|
|
@@ -530,13 +539,91 @@ function defineModel(tableName, fields) {
|
|
|
530
539
|
}
|
|
531
540
|
};
|
|
532
541
|
}
|
|
542
|
+
|
|
543
|
+
// src/openapi/route.ts
|
|
544
|
+
function honoPathToOpenAPI(path) {
|
|
545
|
+
return path.replace(/:([^/]+)/g, "{$1}");
|
|
546
|
+
}
|
|
547
|
+
function buildOpenAPIDocument(routes, options) {
|
|
548
|
+
const paths = {};
|
|
549
|
+
for (const route of routes) {
|
|
550
|
+
const openAPIPath = honoPathToOpenAPI(route.path);
|
|
551
|
+
if (!paths[openAPIPath]) {
|
|
552
|
+
paths[openAPIPath] = {};
|
|
553
|
+
}
|
|
554
|
+
const operation = {};
|
|
555
|
+
if (route.operationId) operation.operationId = route.operationId;
|
|
556
|
+
if (route.summary) operation.summary = route.summary;
|
|
557
|
+
if (route.description) operation.description = route.description;
|
|
558
|
+
if (route.tags) operation.tags = route.tags;
|
|
559
|
+
const parameters = [];
|
|
560
|
+
const pathParams = [...route.path.matchAll(/:([^/]+)/g)].map((m) => m[1]);
|
|
561
|
+
for (const param of pathParams) {
|
|
562
|
+
const alreadyDefined = route.params?.some((p) => p.name === param && p.in === "path");
|
|
563
|
+
if (!alreadyDefined) {
|
|
564
|
+
parameters.push({ name: param, in: "path", required: true, schema: { type: "string" } });
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
if (route.params) {
|
|
568
|
+
parameters.push(...route.params);
|
|
569
|
+
}
|
|
570
|
+
if (parameters.length > 0) operation.parameters = parameters;
|
|
571
|
+
if (route.requestBody) operation.requestBody = route.requestBody;
|
|
572
|
+
operation.responses = route.responses;
|
|
573
|
+
paths[openAPIPath][route.method] = operation;
|
|
574
|
+
}
|
|
575
|
+
const doc = {
|
|
576
|
+
openapi: "3.1.0",
|
|
577
|
+
info: options.info,
|
|
578
|
+
...options.servers ? { servers: options.servers } : {},
|
|
579
|
+
paths
|
|
580
|
+
};
|
|
581
|
+
return doc;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// src/openapi/swagger-ui.ts
|
|
585
|
+
function escapeHtml(str) {
|
|
586
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
587
|
+
}
|
|
588
|
+
function swaggerUI(options) {
|
|
589
|
+
const title = escapeHtml(options.title ?? "API Documentation");
|
|
590
|
+
const html = `<!DOCTYPE html>
|
|
591
|
+
<html lang="en">
|
|
592
|
+
<head>
|
|
593
|
+
<meta charset="UTF-8" />
|
|
594
|
+
<title>${title}</title>
|
|
595
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
|
|
596
|
+
</head>
|
|
597
|
+
<body>
|
|
598
|
+
<div id="swagger-ui"></div>
|
|
599
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
600
|
+
<script>
|
|
601
|
+
SwaggerUIBundle({
|
|
602
|
+
url: ${JSON.stringify(options.url)},
|
|
603
|
+
dom_id: '#swagger-ui',
|
|
604
|
+
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
|
|
605
|
+
layout: 'BaseLayout',
|
|
606
|
+
})
|
|
607
|
+
</script>
|
|
608
|
+
</body>
|
|
609
|
+
</html>`;
|
|
610
|
+
return async (c) => {
|
|
611
|
+
return c.html(html);
|
|
612
|
+
};
|
|
613
|
+
}
|
|
533
614
|
function nanoka(adapter) {
|
|
534
615
|
const app = new Hono();
|
|
616
|
+
const openapiRoutes = [];
|
|
535
617
|
Object.defineProperty(app, "db", {
|
|
536
618
|
get: () => adapter.drizzle,
|
|
537
619
|
enumerable: true
|
|
538
620
|
});
|
|
539
621
|
app.batch = ((queries) => adapter.batch(queries));
|
|
622
|
+
app.openapi = (metadata) => {
|
|
623
|
+
openapiRoutes.push(metadata);
|
|
624
|
+
return app;
|
|
625
|
+
};
|
|
626
|
+
app.generateOpenAPISpec = (options) => buildOpenAPIDocument(openapiRoutes, options);
|
|
540
627
|
app.model = function model(name, fields) {
|
|
541
628
|
const inner = defineModel(name, fields);
|
|
542
629
|
return {
|
|
@@ -562,6 +649,6 @@ function nanoka(adapter) {
|
|
|
562
649
|
return app;
|
|
563
650
|
}
|
|
564
651
|
|
|
565
|
-
export { d1Adapter, defineModel, nanoka };
|
|
652
|
+
export { d1Adapter, defineModel, nanoka, swaggerUI };
|
|
566
653
|
//# sourceMappingURL=index.js.map
|
|
567
654
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapter/d1.ts","../src/model/types.ts","../src/model/schema.ts","../src/openapi/generate.ts","../src/model/crud.ts","../src/model/table.ts","../src/model/define.ts","../src/router/nanoka.ts"],"names":["partial","combinedOmit"],"mappings":"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","file":"index.js","sourcesContent":["import type { D1Database } from '@cloudflare/workers-types'\nimport { drizzle } from 'drizzle-orm/d1'\nimport type { Adapter } from './types'\n\n/**\n * D1-specific adapter factory. Wraps Cloudflare D1 binding in the generic\n * Adapter abstraction, enabling the core query path and router to remain\n * implementation-agnostic.\n */\nexport function d1Adapter<TSchema extends Record<string, unknown> = Record<string, never>>(\n d1: D1Database,\n): Adapter<TSchema> {\n // drizzle-orm/d1's drizzle() returns DrizzleD1Database which embeds D1-specific\n // result types. We cast to BaseSQLiteDatabase via the Adapter interface to keep\n // the D1 dependency local to this file (see CLAUDE.md rule #3). Consumers receive\n // the typed Adapter interface, so this `any` is intentionally local.\n //\n // Note: drizzle-orm/d1 internally stores the D1 binding in db.$client. When\n // handling multiple D1 bindings, call d1Adapter() fresh for each binding rather\n // than caching the return value across binding switches.\n // biome-ignore lint/suspicious/noExplicitAny: intentional - Drizzle returns complex union type\n const db = drizzle(d1) as any\n\n return {\n drizzle: db,\n batch: (queries) => db.batch(queries),\n }\n}\n","import type { Hook } from '@hono/zod-validator'\nimport type { SQLiteTable } from 'drizzle-orm/sqlite-core'\nimport type { Env, MiddlewareHandler, ValidationTargets } from 'hono'\nimport type { z } from 'zod'\nimport type { Adapter } from '../adapter/types'\nimport type { Field, FieldPolicy, InferFieldType } from '../field/types'\nimport type { OpenAPIModelComponent, OpenAPISchemaObject, OpenAPIUsage } from '../openapi/types'\n\n/**\n * Options for findMany query.\n * `limit` is required (no default).\n * `offset` defaults to 0 if omitted.\n * `orderBy` is optional for column ordering.\n */\nexport interface FindManyOptions<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> {\n readonly limit: number\n readonly offset?: number\n readonly orderBy?: OrderBy<Fields>\n}\n\n/**\n * Order-by specification: single field, or field with direction, or array of multiple.\n */\nexport type OrderBy<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> =\n | (keyof Fields & string)\n | { readonly column: keyof Fields & string; readonly direction?: 'asc' | 'desc' }\n | ReadonlyArray<\n | (keyof Fields & string)\n | { readonly column: keyof Fields & string; readonly direction?: 'asc' | 'desc' }\n >\n\n/**\n * Where clause object: each key is a field name, each value is the desired equality.\n */\nexport type Where<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> = {\n readonly [K in keyof Fields]?: InferFieldType<Fields[K]>\n}\n\n/**\n * Identifier or Where clause: can be a primary key value or a Where object.\n */\nexport type IdOrWhere<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> = string | number | Where<Fields>\n\n/**\n * Row type: full record type from fields.\n */\nexport type RowType<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> = {\n [K in keyof Fields]: InferFieldType<Fields[K]>\n}\n\n/**\n * @internal\n * Extracts the policy from a Field's modifiers.\n *\n * Uses `Field<any, { policy: infer P }, any>` rather than a two-step\n * `infer M` + `M extends { policy: infer P }` pattern.\n * The two-step pattern is broken when TypeScript widens `M` to the constraint\n * `FieldModifiers` (which has `policy?: FieldPolicy` as optional), causing\n * `M extends { policy: infer P }` to be true for ALL fields regardless of their\n * actual policy value. Directly matching `{ policy: infer P }` avoids this.\n */\ntype PolicyOf<F> =\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n F extends Field<any, { policy: infer P extends FieldPolicy }, any> ? P : never\n\n/**\n * @internal\n * Computes which field keys should be omitted based on policy and usage.\n * Mirrors the runtime logic in derivePolicyOptions() in schema.ts.\n *\n * NOTE: `[PolicyOf<Fields[K]>] extends [never]` (non-distributive form) is used to\n * short-circuit fields with no policy to `never` (do not omit). Without this guard,\n * `never extends 'serverOnly'` evaluates to `true` (vacuously), causing every field\n * without a policy to be incorrectly included in the omit set.\n */\nexport type PolicyOmitKeys<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n Usage extends 'input-create' | 'input-update' | 'output',\n> = {\n [K in keyof Fields]: [PolicyOf<Fields[K]>] extends [never]\n ? never\n : PolicyOf<Fields[K]> extends 'serverOnly'\n ? K\n : Usage extends 'output'\n ? PolicyOf<Fields[K]> extends 'writeOnly'\n ? K\n : never\n : Usage extends 'input-create' | 'input-update'\n ? PolicyOf<Fields[K]> extends 'readOnly'\n ? K\n : never\n : never\n}[keyof Fields]\n\n/**\n * @internal\n * Computes which field keys have the serverOnly policy.\n * serverOnly fields are completely excluded from CreateInput\n * (cannot be passed even from library internals — they are server-side only).\n *\n * Uses `[PolicyOf<Fields[K]>] extends [never]` (non-distributive form) to short-circuit\n * fields with no policy to `never`. Without this guard, `never extends 'serverOnly'`\n * evaluates to `true` (vacuously), causing every field without a policy to be included.\n */\ntype ServerOnlyKeys<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> = {\n [K in keyof Fields]: [PolicyOf<Fields[K]>] extends [never]\n ? never\n : PolicyOf<Fields[K]> extends 'serverOnly'\n ? K\n : never\n}[keyof Fields]\n\n/**\n * @internal\n * Determines if a field is required for create input.\n * A field is optional if it has a default, is optional, or is readOnly.\n *\n * Uses direct shape matching (`Field<any, { hasDefault: true }, any>`) to avoid\n * the TypeScript infer-widening issue where `infer M` resolves to `FieldModifiers`\n * (the constraint bound) instead of the concrete Mods type, causing `M extends\n * { policy: 'readOnly' }` to be false even for readOnly fields.\n */\n// biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\ntype IsRequired<F extends Field<any, any, any>> =\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n F extends Field<any, { hasDefault: true }, any>\n ? false\n : // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n F extends Field<any, { optional: true }, any>\n ? false\n : // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n F extends Field<any, { policy: 'readOnly' }, any>\n ? false\n : true\n\n/**\n * Create input with precise types:\n * - `readOnly` fields are optional (library internals can pass them; API callers\n * are excluded via inputSchema — but CreateInput itself keeps them as optional\n * so handlers can supply generated values like `id` or `createdAt`)\n * - fields with `default` are optional\n * - fields marked `optional` are optional\n * - all other fields are required\n * - `serverOnly` fields are completely excluded (cannot be passed even internally)\n * - `writeOnly` fields are included as required (they are input fields by design)\n */\nexport type CreateInput<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> = {\n [K in keyof Fields as IsRequired<Fields[K]> extends true\n ? K extends ServerOnlyKeys<Fields>\n ? never\n : K\n : never]: InferFieldType<Fields[K]>\n} & {\n [K in keyof Fields as IsRequired<Fields[K]> extends true\n ? never\n : K extends ServerOnlyKeys<Fields>\n ? never\n : K]?: InferFieldType<Fields[K]>\n}\n\nexport type FieldAccessor<K extends string> = { readonly [Key in K]: Key }\n\nexport interface SchemaOptions<K extends string = string> {\n readonly pick?: readonly K[] | ((f: FieldAccessor<K>) => readonly K[])\n readonly omit?: readonly K[] | ((f: FieldAccessor<K>) => readonly K[])\n readonly partial?: boolean\n}\n\n/**\n * @internal\n * Resolves pick/omit option to string array using the accessor when it's a function.\n */\nexport function resolveSchemaOptionKeys<K extends string>(\n opt: readonly K[] | ((f: FieldAccessor<K>) => readonly K[]) | undefined,\n accessor: FieldAccessor<K>,\n): readonly K[] | undefined {\n if (opt === undefined) return undefined\n if (typeof opt === 'function') return opt(accessor)\n return opt\n}\n\n/**\n * @internal\n * Builds a frozen field accessor object for use in schema/validator options.\n * Each key maps to itself, providing typo detection at type level.\n */\nexport function buildFieldAccessor<Fields extends Record<string, unknown>>(\n fields: Fields,\n): { readonly [K in keyof Fields]: K } {\n const acc: Record<string, string> = {}\n for (const k of Object.keys(fields)) acc[k] = k\n return Object.freeze(acc) as { readonly [K in keyof Fields]: K }\n}\n\n/**\n * @internal\n * Extracts a Zod shape from fields for the Apply type.\n * Each field's zodBase becomes a property in the shape.\n * Indexed access ensures concrete Zod types are preserved (not `any`).\n */\nexport type FieldsToZodShape<\n Fields extends Record<\n string,\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Field<any, any, any>\n >,\n> = {\n [K in keyof Fields]: Fields[K]['zodBase']\n}\n\n/**\n * @internal\n * Utility to narrow array literal types to union of strings.\n */\ntype ArrayKeys<A> = A extends readonly (infer U)[] ? U : never\n\n/**\n * @internal\n * Resolves pick/omit option type to the array type.\n * Handles both array form and accessor function form.\n */\ntype ResolveOptKeys<Opt> = Opt extends readonly string[]\n ? Opt\n : Opt extends (f: FieldAccessor<infer _K>) => readonly (infer R)[]\n ? readonly R[]\n : never\n\n/**\n * @internal\n * Apply pick transformation to a shape.\n */\ntype ApplyPickToShape<Shape extends z.ZodRawShape, PickOpt> =\n ResolveOptKeys<PickOpt> extends readonly string[]\n ? Pick<Shape, ArrayKeys<ResolveOptKeys<PickOpt>> & keyof Shape>\n : Shape\n\n/**\n * @internal\n * Apply omit transformation to a shape.\n */\ntype ApplyOmitToShape<Shape extends z.ZodRawShape, OmitOpt> =\n ResolveOptKeys<OmitOpt> extends readonly string[]\n ? Omit<Shape, ArrayKeys<ResolveOptKeys<OmitOpt>> & keyof Shape>\n : Shape\n\n/**\n * @internal\n * Apply partial transformation to a shape.\n */\ntype ApplyPartialToShape<Shape extends z.ZodRawShape> = {\n [K in keyof Shape]: z.ZodOptional<Shape[K]>\n}\n\n/**\n * @internal\n * Checks if an option value (array or function) is present (i.e. not undefined and not never).\n * Uses distributive conditional to handle union types like `T | undefined`.\n */\ntype HasOpt<Opt> = undefined extends Opt ? false : [Opt] extends [never] ? false : true\n\n/**\n * @internal\n * Apply pick/omit/partial transformations to a Zod raw shape.\n * Order: pick → omit → partial\n * Handles both array form and accessor function form for pick/omit.\n */\ntype ApplyShape<\n Shape extends z.ZodRawShape,\n Opts extends SchemaOptions | undefined,\n> = Opts extends SchemaOptions\n ? HasOpt<Opts['pick']> extends true\n ? HasOpt<Opts['omit']> extends true\n ? Opts extends { partial: true }\n ? ApplyPartialToShape<ApplyOmitToShape<ApplyPickToShape<Shape, Opts['pick']>, Opts['omit']>>\n : ApplyOmitToShape<ApplyPickToShape<Shape, Opts['pick']>, Opts['omit']>\n : Opts extends { partial: true }\n ? ApplyPartialToShape<ApplyPickToShape<Shape, Opts['pick']>>\n : ApplyPickToShape<Shape, Opts['pick']>\n : HasOpt<Opts['omit']> extends true\n ? Opts extends { partial: true }\n ? ApplyPartialToShape<ApplyOmitToShape<Shape, Opts['omit']>>\n : ApplyOmitToShape<Shape, Opts['omit']>\n : Opts extends { partial: true }\n ? ApplyPartialToShape<Shape>\n : Shape\n : Shape\n\n/**\n * @internal\n * Returns the correct Zod object type after applying pick/omit/partial transformations.\n */\nexport type Apply<\n Shape extends z.ZodRawShape,\n Opts extends SchemaOptions | undefined,\n> = z.ZodObject<ApplyShape<Shape, Opts>>\n\n/**\n * @internal\n * Apply pick transformation to a TS record type.\n */\ntype ApplyPickToRecord<R, PickOpt> =\n ResolveOptKeys<PickOpt> extends readonly string[]\n ? Pick<R, ArrayKeys<ResolveOptKeys<PickOpt>> & keyof R>\n : R\n\n/**\n * @internal\n * Apply omit transformation to a TS record type.\n */\ntype ApplyOmitToRecord<R, OmitOpt> =\n ResolveOptKeys<OmitOpt> extends readonly string[]\n ? Omit<R, ArrayKeys<ResolveOptKeys<OmitOpt>> & keyof R>\n : R\n\n/**\n * @internal\n * Apply pick/omit/partial transformations to a TypeScript record type.\n * Mirrors ApplyShape but operates on TS types directly, not Zod shapes.\n * Used for Zod v3/v4 compatible middleware input/output type computation.\n */\ntype ApplyToRecord<R, Opts extends SchemaOptions | undefined> = Opts extends SchemaOptions\n ? HasOpt<Opts['pick']> extends true\n ? HasOpt<Opts['omit']> extends true\n ? Opts extends { partial: true }\n ? Partial<ApplyOmitToRecord<ApplyPickToRecord<R, Opts['pick']>, Opts['omit']>>\n : ApplyOmitToRecord<ApplyPickToRecord<R, Opts['pick']>, Opts['omit']>\n : Opts extends { partial: true }\n ? Partial<ApplyPickToRecord<R, Opts['pick']>>\n : ApplyPickToRecord<R, Opts['pick']>\n : HasOpt<Opts['omit']> extends true\n ? Opts extends { partial: true }\n ? Partial<ApplyOmitToRecord<R, Opts['omit']>>\n : ApplyOmitToRecord<R, Opts['omit']>\n : Opts extends { partial: true }\n ? Partial<R>\n : R\n : R\n\n/**\n * @internal\n * Mirrors @hono/zod-validator's middleware Input type.\n * Aligned with @hono/zod-validator@0.4.x; revisit on version bump.\n */\ntype HasUndefined<T> = undefined extends T ? true : false\n\n/**\n * @internal\n * Hono middleware input/output type for validator middleware.\n * Aligned with @hono/zod-validator@0.4.x; revisit on version bump.\n *\n * WARNING (Zod 4): `z.input<ZodTypeAny>` resolves to `unknown` in Zod 4, making\n * `c.req.valid(target)` return `unknown` if `In`/`Out` are left as defaults.\n * When using this type directly (outside of `ModelValidatorReturn`), always pass\n * explicit `In` and `Out` type arguments — do NOT rely on the defaults.\n *\n * Internal usages in this file (ModelValidatorReturn and preset overloads) already\n * pass `In`/`Out` explicitly via `ApplyToRecord` or `Omit<RowType<Fields>, ...>`.\n */\nexport type ValidatorInput<\n Target extends keyof ValidationTargets,\n Schema extends z.ZodTypeAny,\n In = z.input<Schema>,\n Out = z.output<Schema>,\n> = {\n in: HasUndefined<In> extends true\n ? {\n [K in Target]?:\n | (In extends ValidationTargets[K]\n ? In\n : { [K2 in keyof In]?: ValidationTargets[K][K2] | undefined })\n | undefined\n }\n : {\n [K in Target]: In extends ValidationTargets[K]\n ? In\n : { [K2 in keyof In]: ValidationTargets[K][K2] }\n }\n out: { [K in Target]: Out }\n}\n\n/**\n * @internal\n * Type-safe Hono middleware handler return for Model.validator().\n * Provides proper type narrowing for c.req.valid(target).\n *\n * Uses RowType<Fields> directly for input/output type computation\n * to ensure Zod v3/v4 compatibility (z.input<ZodTypeAny> returns unknown in Zod v4).\n */\nexport type ModelValidatorReturn<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n Target extends keyof ValidationTargets,\n Opts extends SchemaOptions<keyof Fields & string> | undefined,\n> = MiddlewareHandler<\n any,\n string,\n ValidatorInput<\n Target,\n Apply<FieldsToZodShape<Fields>, Opts>,\n ApplyToRecord<RowType<Fields>, Opts>,\n ApplyToRecord<RowType<Fields>, Opts>\n >\n>\n\n/**\n * Hook type for Model.validator() third argument.\n * Re-exported from @hono/zod-validator for convenience.\n */\nexport type { Hook }\n\n/**\n * Represents a database model with type-safe schema derivation and CRUD operations.\n */\n// biome-ignore lint/suspicious/noExplicitAny: any is necessary for the generic Field constraint\nexport interface Model<Fields extends Record<string, Field<any, any, any>>> {\n readonly fields: Fields\n readonly tableName: string\n readonly table: SQLiteTable\n\n /**\n * Returns a Zod schema derived from this model's fields.\n * Supports pick, omit, and partial transformations.\n *\n * @example\n * const CreateSchema = User.schema({ omit: ['passwordHash'] })\n * const UpdateSchema = User.schema({ partial: true, pick: ['name', 'email'] })\n */\n schema<Opts extends SchemaOptions<keyof Fields & string> | undefined>(\n opts?: Opts,\n ): Apply<FieldsToZodShape<Fields>, Opts>\n\n /**\n * Returns a Hono middleware validator derived from this model's schema.\n * Integrates with @hono/zod-validator to validate request inputs.\n * The optional `hook` argument is passed through to @hono/zod-validator.\n *\n * Accepts a preset ('create' | 'update') as second argument to use inputSchema.\n * When a preset is used, the return type is a MiddlewareHandler (loosely typed in Phase 2A).\n * Precise type narrowing for preset is deferred to Phase 2B M2.3.\n *\n * @example\n * app.post('/users', User.validator('json', 'create'), c => {\n * const body = c.req.valid('json')\n * })\n * app.post('/users', User.validator('json', { omit: ['passwordHash'] }), c => {\n * const body = c.req.valid('json')\n * })\n * // With hook:\n * app.post('/users', User.validator('json', opts, (result, c) => {\n * if (!result.success) return c.json({ error: 'Invalid request' }, 400)\n * }), handler)\n */\n validator<Target extends keyof ValidationTargets, E extends Env = Env, P extends string = string>(\n target: Target,\n preset: 'create',\n hook?: Hook<\n Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-create'> & string>,\n E,\n P,\n Target\n >,\n ): MiddlewareHandler<\n E,\n P,\n ValidatorInput<\n Target,\n z.ZodObject<z.ZodRawShape>,\n Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-create'> & string>,\n Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-create'> & string>\n >\n >\n validator<Target extends keyof ValidationTargets, E extends Env = Env, P extends string = string>(\n target: Target,\n preset: 'update',\n hook?: Hook<\n Partial<Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-update'> & string>>,\n E,\n P,\n Target\n >,\n ): MiddlewareHandler<\n E,\n P,\n ValidatorInput<\n Target,\n z.ZodObject<z.ZodRawShape>,\n Partial<Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-update'> & string>>,\n Partial<Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-update'> & string>>\n >\n >\n validator<\n Target extends keyof ValidationTargets,\n Opts extends SchemaOptions<keyof Fields & string> | undefined,\n E extends Env = Env,\n P extends string = string,\n >(\n target: Target,\n opts?: Opts,\n hook?: Hook<z.output<Apply<FieldsToZodShape<Fields>, Opts>>, E, P, Target>,\n ): ModelValidatorReturn<Fields, Target, Opts>\n\n /**\n * Returns a Zod schema for API input, with policy-based field exclusions applied.\n * - 'create': serverOnly and readOnly fields are excluded\n * - 'update': same exclusions + all fields become optional (partial: true)\n *\n * The return type precisely reflects policy-derived omissions using PolicyOmitKeys.\n */\n inputSchema<Opts extends SchemaOptions<keyof Fields & string> | undefined = undefined>(\n usage: 'create',\n opts?: Opts,\n ): z.ZodObject<\n ApplyShape<\n Omit<FieldsToZodShape<Fields>, PolicyOmitKeys<Fields, 'input-create'> & string>,\n Opts\n >\n >\n inputSchema<Opts extends SchemaOptions<keyof Fields & string> | undefined = undefined>(\n usage: 'update',\n opts?: Opts,\n ): z.ZodObject<\n ApplyShape<\n Omit<FieldsToZodShape<Fields>, PolicyOmitKeys<Fields, 'input-update'> & string>,\n Opts extends undefined ? { partial: true } : Opts & { partial: true }\n >\n >\n inputSchema(\n usage: 'create' | 'update',\n opts?: SchemaOptions<keyof Fields & string>,\n ): z.ZodObject<z.ZodRawShape>\n\n /**\n * Returns a Zod schema for API output, with policy-based field exclusions applied.\n * - serverOnly and writeOnly fields are excluded\n * - readOnly fields remain present\n *\n * The return type precisely reflects policy-derived omissions using PolicyOmitKeys.\n */\n outputSchema<Opts extends SchemaOptions<keyof Fields & string> | undefined = undefined>(\n opts?: Opts,\n ): z.ZodObject<\n ApplyShape<Omit<FieldsToZodShape<Fields>, PolicyOmitKeys<Fields, 'output'> & string>, Opts>\n >\n\n /**\n * Parses a DB row through outputSchema and returns the safe response object.\n * Equivalent to `User.outputSchema().parse(row)`.\n */\n toResponse(row: RowType<Fields>): unknown\n\n toOpenAPIComponent(): OpenAPIModelComponent\n\n toOpenAPISchema(usage: OpenAPIUsage): OpenAPISchemaObject\n\n /**\n * Fetches multiple rows with pagination and optional ordering.\n * `limit` is required (no default) to prevent accidental unbounded queries.\n * Offset defaults to 0 if omitted.\n *\n * @example\n * const users = await User.findMany(adapter, { limit: 20 })\n * const page2 = await User.findMany(adapter, { limit: 20, offset: 20 })\n * const sorted = await User.findMany(adapter, { limit: 10, orderBy: 'name' })\n */\n findMany(adapter: Adapter, options: FindManyOptions<Fields>): Promise<RowType<Fields>[]>\n\n /**\n * Fetches a single row by primary key or where clause.\n * Returns null if not found.\n *\n * @example\n * const user = await User.findOne(adapter, id)\n * const byEmail = await User.findOne(adapter, { email: 'john@example.com' })\n */\n findOne(adapter: Adapter, idOrWhere: IdOrWhere<Fields>): Promise<RowType<Fields> | null>\n\n /**\n * Creates a new row and returns the created record.\n *\n * @example\n * const user = await User.create(adapter, { name: 'John', email: 'john@example.com' })\n */\n create(adapter: Adapter, data: CreateInput<Fields>): Promise<RowType<Fields>>\n\n /**\n * Updates rows matching the given id or where clause.\n * Returns the updated row(s), or null if no rows matched.\n *\n * @example\n * const updated = await User.update(adapter, id, { name: 'Jane' })\n * const byEmail = await User.update(adapter, { email: '...' }, { name: 'Jane' })\n */\n update(\n adapter: Adapter,\n idOrWhere: IdOrWhere<Fields>,\n data: Partial<RowType<Fields>>,\n ): Promise<RowType<Fields> | null>\n\n /**\n * Deletes rows matching the given id or where clause.\n * Returns the number of deleted rows.\n *\n * @example\n * const result = await User.delete(adapter, id)\n * console.log(result.deleted) // number\n */\n delete(adapter: Adapter, idOrWhere: IdOrWhere<Fields>): Promise<{ readonly deleted: number }>\n}\n","import { z } from 'zod'\nimport type { Field } from '../field/types'\nimport { type FieldAccessor, resolveSchemaOptionKeys, type SchemaOptions } from './types'\n\ntype PolicyUsage = 'input-create' | 'input-update' | 'output'\n\n/**\n * Returns field names that are security-critical and must always be omitted from API schemas.\n * Currently only serverOnly fields. These cannot be overridden by user pick/omit.\n */\nfunction computeForcedOmit(\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Field handling\n fields: Record<string, Field<any, any, any>>,\n): string[] {\n const omit: string[] = []\n for (const [key, field] of Object.entries(fields)) {\n if (field.modifiers.policy === 'serverOnly') {\n omit.push(key)\n }\n }\n return omit\n}\n\n/**\n * Returns field names to omit based on UX-oriented policy (writeOnly / readOnly).\n * These can be overridden when user explicitly provides pick.\n *\n * Policy mapping:\n * - `writeOnly`: omitted from output only. For input targets (input-create, input-update),\n * writeOnly fields are NOT omitted — they are intentionally part of the input (e.g. password).\n * - `readOnly`: omitted from input targets (input-create, input-update) only. Remains in output.\n *\n * The asymmetry is by design: writeOnly means \"accepted on write, hidden on read\";\n * readOnly means \"visible on read, rejected on write\".\n */\nfunction computeOptionalOmit(\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Field handling\n fields: Record<string, Field<any, any, any>>,\n target: PolicyUsage,\n): string[] {\n const omit: string[] = []\n for (const [key, field] of Object.entries(fields)) {\n const policy = field.modifiers.policy\n if (!policy) continue\n if (policy === 'writeOnly' && target === 'output') {\n omit.push(key)\n } else if (policy === 'readOnly' && (target === 'input-create' || target === 'input-update')) {\n omit.push(key)\n }\n }\n return omit\n}\n\n/**\n * Merges policy-derived omit with user-provided SchemaOptions.\n *\n * serverOnly fields are always omitted regardless of user pick/omit (security invariant).\n * writeOnly / readOnly are UX-oriented and can be overridden when user provides pick.\n * For 'input-update', partial defaults to true unless user specifies otherwise.\n */\nexport function derivePolicyOptions(\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Field handling\n fields: Record<string, Field<any, any, any>>,\n usage: PolicyUsage,\n userOpts?: SchemaOptions,\n // biome-ignore lint/suspicious/noExplicitAny: accessor is a plain object with string keys\n accessor?: FieldAccessor<any>,\n): SchemaOptions {\n const forced = computeForcedOmit(fields)\n const optional = computeOptionalOmit(fields, usage)\n\n const acc = accessor ?? ({} as FieldAccessor<string>)\n const resolvedPick = resolveSchemaOptionKeys(userOpts?.pick, acc)\n const resolvedOmit = resolveSchemaOptionKeys(userOpts?.omit, acc)\n\n if (resolvedPick !== undefined) {\n const partial = usage === 'input-update' ? (userOpts?.partial ?? true) : userOpts?.partial\n // serverOnly fields are stripped from pick even if user explicitly listed them\n const sanitizedPick = Array.from(resolvedPick).filter((k) => !forced.includes(k))\n // Combine forced omit with user-provided omit to preserve both constraints\n const combinedOmit = [...new Set([...forced, ...(resolvedOmit ?? [])])]\n return {\n ...userOpts,\n pick: sanitizedPick,\n ...(combinedOmit.length > 0 ? { omit: combinedOmit } : {}),\n partial,\n }\n }\n\n const combinedOmit = [...new Set([...forced, ...optional, ...(resolvedOmit ?? [])])]\n const partial =\n usage === 'input-update' ? (userOpts?.partial ?? true) : (userOpts?.partial ?? undefined)\n\n return {\n ...(userOpts ?? {}),\n pick: undefined,\n ...(combinedOmit.length > 0 ? { omit: combinedOmit } : {}),\n ...(partial !== undefined ? { partial } : {}),\n }\n}\n\n/**\n * Builds a Zod object schema from a fields definition.\n * Returns a ZodObject with all fields required and present.\n */\n// biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Field handling and Zod shape\nexport function buildBaseObject(fields: Record<string, Field<any, any, any>>): z.ZodObject<any> {\n // biome-ignore lint/suspicious/noExplicitAny: Record key-value pairs have any type for shape\n const shape: Record<string, any> = {}\n for (const [key, field] of Object.entries(fields)) {\n shape[key] = field.zodBase\n }\n return z.object(shape)\n}\n\n/**\n * Applies pick, omit, and partial transformations to a Zod object schema.\n * Order: pick → omit → partial\n *\n * Returns the transformed schema, cast to Apply<Shape, Opts> at the call site.\n */\nexport function applySchemaOptions(\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Zod shape operations\n baseSchema: z.ZodObject<any>,\n opts: SchemaOptions | undefined,\n // biome-ignore lint/suspicious/noExplicitAny: accessor is a plain object with string keys\n accessor?: FieldAccessor<any>,\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for return type\n): z.ZodObject<any> {\n if (!opts) {\n return baseSchema\n }\n\n const acc = accessor ?? ({} as FieldAccessor<string>)\n const resolvedPick = resolveSchemaOptionKeys(opts.pick, acc)\n const resolvedOmit = resolveSchemaOptionKeys(opts.omit, acc)\n\n let schema = baseSchema\n\n // Apply pick\n if (resolvedPick !== undefined) {\n const pickArray = Array.from(resolvedPick)\n schema = schema.pick(\n // biome-ignore lint/suspicious/noExplicitAny: Zod API\n Object.fromEntries(pickArray.map((k) => [k, true])) as any,\n )\n }\n\n // Apply omit\n if (resolvedOmit !== undefined) {\n const omitArray = Array.from(resolvedOmit)\n schema = schema.omit(\n // biome-ignore lint/suspicious/noExplicitAny: Zod API\n Object.fromEntries(omitArray.map((k) => [k, true])) as any,\n )\n }\n\n // Apply partial\n // `partial: false` を渡してもこの条件で何もしない。スキーマは required のまま。\n if (opts.partial === true) {\n schema = schema.partial()\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: Cast to Apply type at call site\n return schema as any\n}\n","import type { Field } from '../field/types'\nimport { applySchemaOptions, buildBaseObject, derivePolicyOptions } from '../model/schema'\nimport type { SchemaOptions } from '../model/types'\nimport type { OpenAPIModelComponent, OpenAPISchemaObject, OpenAPIUsage } from './types'\n\n// biome-ignore lint/suspicious/noExplicitAny: OpenAPI generation accepts any concrete field builder.\ntype AnyField = Field<any, any, any>\ntype FieldsRecord = Record<string, AnyField>\n\ninterface OpenAPIOptions {\n readonly opts?: SchemaOptions\n}\n\nexport function toOpenAPIComponent(\n fields: FieldsRecord,\n opts?: OpenAPIOptions,\n): OpenAPIModelComponent {\n return {\n create: toOpenAPISchema(fields, 'create', opts),\n update: toOpenAPISchema(fields, 'update', opts),\n output: toOpenAPISchema(fields, 'output', opts),\n }\n}\n\nexport function toOpenAPISchema(\n fields: FieldsRecord,\n usage: OpenAPIUsage,\n opts?: OpenAPIOptions,\n): OpenAPISchemaObject {\n const policyUsage =\n usage === 'create' ? 'input-create' : usage === 'update' ? 'input-update' : 'output'\n const merged = derivePolicyOptions(fields, policyUsage, opts?.opts)\n const schema = applySchemaOptions(buildBaseObject(fields), merged)\n const shape = getZodObjectShape(schema)\n const properties: Record<string, OpenAPISchemaObject> = {}\n const required: string[] = []\n\n for (const [key, zodSchema] of Object.entries(shape)) {\n const field = fields[key]\n if (field === undefined) continue\n\n properties[key] = fieldToOpenAPISchema(field)\n if (field.modifiers.policy === 'writeOnly' && (usage === 'create' || usage === 'update')) {\n properties[key].writeOnly = true\n }\n if (field.modifiers.policy === 'readOnly' && usage === 'output') {\n properties[key].readOnly = true\n }\n if (usage !== 'update' && isRequiredZodSchema(zodSchema)) {\n required.push(key)\n }\n }\n\n return {\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n }\n}\n\nfunction fieldToOpenAPISchema(field: AnyField): OpenAPISchemaObject {\n const schema: OpenAPISchemaObject =\n field.kind === 'json'\n ? zodToOpenAPISchema(field.zodBase)\n : field.kind === 'string'\n ? { type: 'string' }\n : field.kind === 'uuid'\n ? { type: 'string', format: 'uuid' }\n : field.kind === 'number'\n ? { type: 'number' }\n : field.kind === 'integer'\n ? { type: 'integer' }\n : field.kind === 'boolean'\n ? { type: 'boolean' }\n : field.kind === 'timestamp'\n ? { type: 'string', format: 'date-time' }\n : {}\n\n if (field.modifiers.format === 'email') {\n schema.format = 'email'\n }\n if (field.modifiers.min !== undefined) {\n if (field.kind === 'string' || field.kind === 'uuid') {\n schema.minLength = field.modifiers.min\n } else {\n schema.minimum = field.modifiers.min\n }\n }\n if (field.modifiers.max !== undefined) {\n if (field.kind === 'string' || field.kind === 'uuid') {\n schema.maxLength = field.modifiers.max\n } else {\n schema.maximum = field.modifiers.max\n }\n }\n\n return schema\n}\n\nfunction zodToOpenAPISchema(schema: unknown): OpenAPISchemaObject {\n const def = getZodDef(schema)\n if (def === undefined) return {}\n\n const typeName = getZodTypeName(def)\n\n if (typeName === 'ZodOptional' || typeName === 'optional') {\n return zodToOpenAPISchema(def.innerType)\n }\n if (typeName === 'ZodDefault' || typeName === 'default') {\n return zodToOpenAPISchema(def.innerType)\n }\n if (typeName === 'ZodNullable' || typeName === 'nullable') {\n return { ...zodToOpenAPISchema(def.innerType), nullable: true }\n }\n\n if (typeName === 'ZodObject' || typeName === 'object') {\n const shape = getZodObjectShape(schema)\n const properties: Record<string, OpenAPISchemaObject> = {}\n const required: string[] = []\n\n for (const [key, childSchema] of Object.entries(shape)) {\n properties[key] = zodToOpenAPISchema(childSchema)\n if (isRequiredZodSchema(childSchema)) {\n required.push(key)\n }\n }\n\n return {\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n }\n }\n\n if (typeName === 'ZodString' || typeName === 'string') {\n return applyStringChecks({ type: 'string' }, def)\n }\n\n if (typeName === 'ZodNumber' || typeName === 'number') {\n return applyNumberChecks({ type: hasIntegerCheck(def) ? 'integer' : 'number' }, def)\n }\n\n if (typeName === 'ZodBoolean' || typeName === 'boolean') {\n return { type: 'boolean' }\n }\n\n if (typeName === 'ZodArray' || typeName === 'array') {\n const itemSchema = def.element ?? def.type\n return {\n type: 'array',\n items: zodToOpenAPISchema(itemSchema),\n }\n }\n\n if (typeName === 'ZodRecord' || typeName === 'record') {\n return {\n type: 'object',\n additionalProperties: zodToOpenAPISchema(def.valueType),\n }\n }\n\n return {}\n}\n\nfunction getZodObjectShape(schema: unknown): Record<string, unknown> {\n if (\n typeof schema === 'object' &&\n schema !== null &&\n 'shape' in schema &&\n typeof schema.shape === 'object' &&\n schema.shape !== null\n ) {\n return schema.shape as Record<string, unknown>\n }\n\n if (\n typeof schema === 'object' &&\n schema !== null &&\n '_def' in schema &&\n typeof schema._def === 'object' &&\n schema._def !== null &&\n 'shape' in schema._def\n ) {\n const shape = schema._def.shape\n return (typeof shape === 'function' ? shape() : shape) as Record<string, unknown>\n }\n\n return {}\n}\n\nfunction isRequiredZodSchema(schema: unknown): boolean {\n const def = getZodDef(schema)\n if (def === undefined) {\n return true\n }\n\n const typeName = getZodTypeName(def)\n return (\n typeName !== 'ZodOptional' &&\n typeName !== 'optional' &&\n typeName !== 'ZodDefault' &&\n typeName !== 'default'\n )\n}\n\nfunction getZodDef(schema: unknown): Record<string, unknown> | undefined {\n if (\n typeof schema === 'object' &&\n schema !== null &&\n '_def' in schema &&\n typeof schema._def === 'object' &&\n schema._def !== null\n ) {\n return schema._def as Record<string, unknown>\n }\n\n return undefined\n}\n\nfunction getZodTypeName(def: Record<string, unknown>): string | undefined {\n return typeof def.typeName === 'string'\n ? def.typeName\n : typeof def.type === 'string'\n ? def.type\n : undefined\n}\n\nfunction applyStringChecks(\n schema: OpenAPISchemaObject,\n def: Record<string, unknown>,\n): OpenAPISchemaObject {\n for (const check of getZodChecks(def)) {\n const checkDef = getZodCheckDef(check)\n if (checkDef.kind === 'email' || checkDef.format === 'email') {\n schema.format = 'email'\n }\n if (checkDef.kind === 'min' && typeof checkDef.value === 'number') {\n schema.minLength = checkDef.value\n }\n if (checkDef.kind === 'max' && typeof checkDef.value === 'number') {\n schema.maxLength = checkDef.value\n }\n if (checkDef.check === 'min_length' && typeof checkDef.minimum === 'number') {\n schema.minLength = checkDef.minimum\n }\n if (checkDef.check === 'max_length' && typeof checkDef.maximum === 'number') {\n schema.maxLength = checkDef.maximum\n }\n }\n\n return schema\n}\n\nfunction applyNumberChecks(\n schema: OpenAPISchemaObject,\n def: Record<string, unknown>,\n): OpenAPISchemaObject {\n for (const check of getZodChecks(def)) {\n const checkDef = getZodCheckDef(check)\n if (checkDef.kind === 'min' && typeof checkDef.value === 'number') {\n schema.minimum = checkDef.value\n }\n if (checkDef.kind === 'max' && typeof checkDef.value === 'number') {\n schema.maximum = checkDef.value\n }\n if (\n (checkDef.check === 'greater_than' || checkDef.check === 'number_format') &&\n typeof checkDef.minimum === 'number'\n ) {\n schema.minimum = checkDef.minimum\n }\n if (\n (checkDef.check === 'less_than' || checkDef.check === 'number_format') &&\n typeof checkDef.maximum === 'number'\n ) {\n schema.maximum = checkDef.maximum\n }\n }\n\n return schema\n}\n\nfunction hasIntegerCheck(def: Record<string, unknown>): boolean {\n return getZodChecks(def).some((check) => {\n const checkDef = getZodCheckDef(check)\n return (\n checkDef.kind === 'int' ||\n checkDef.format === 'safeint' ||\n checkDef.format === 'int32' ||\n checkDef.format === 'int64'\n )\n })\n}\n\nfunction getZodChecks(def: Record<string, unknown>): readonly unknown[] {\n return Array.isArray(def.checks) ? def.checks : []\n}\n\nfunction getZodCheckDef(check: unknown): Record<string, unknown> {\n if (typeof check !== 'object' || check === null) {\n return {}\n }\n if (\n '_zod' in check &&\n typeof check._zod === 'object' &&\n check._zod !== null &&\n 'def' in check._zod &&\n typeof check._zod.def === 'object' &&\n check._zod.def !== null\n ) {\n return check._zod.def as Record<string, unknown>\n }\n\n return check as Record<string, unknown>\n}\n","import { and, asc, desc, eq } from 'drizzle-orm'\nimport type { SQLiteTable } from 'drizzle-orm/sqlite-core'\nimport { HTTPException } from 'hono/http-exception'\nimport type { Adapter } from '../adapter/types'\nimport type { Field } from '../field/types'\nimport type { CreateInput, IdOrWhere, OrderBy, RowType, Where } from './types'\n\nconst MAX_LIMIT = 100\n\n/**\n * Validates and guards limit/offset parameters.\n * @internal\n */\nfunction guardLimit(limit: unknown): number {\n if (!Number.isInteger(limit)) {\n throw new HTTPException(400, { message: 'limit must be an integer' })\n }\n const n = limit as number\n if (n < 0) {\n throw new HTTPException(400, { message: 'limit must be >= 0' })\n }\n if (n > MAX_LIMIT) {\n throw new HTTPException(400, { message: `limit must be <= ${MAX_LIMIT}` })\n }\n return n\n}\n\nfunction guardOffset(offset: unknown): number {\n if (!Number.isInteger(offset)) {\n throw new HTTPException(400, { message: 'offset must be an integer' })\n }\n const n = offset as number\n if (n < 0) {\n throw new HTTPException(400, { message: 'offset must be >= 0' })\n }\n return n\n}\n\n/**\n * Finds the primary key field from fields record.\n * @internal\n */\nfunction findPrimaryKey(\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n fields: Record<string, Field<any, any, any>>,\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n): [string, Field<any, any, any>] | null {\n let pkKey: string | undefined\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n let pkField: Field<any, any, any> | undefined\n let pkCount = 0\n\n for (const [key, field] of Object.entries(fields)) {\n if (field.modifiers.primary === true) {\n pkCount++\n if (pkCount === 1) {\n pkKey = key\n pkField = field\n }\n }\n }\n\n if (pkCount === 0) {\n return null\n }\n if (pkCount > 1) {\n throw new HTTPException(500, { message: 'model has multiple primary keys' })\n }\n if (pkKey === undefined || pkField === undefined) {\n return null\n }\n\n return [pkKey, pkField]\n}\n\n/**\n * Constructs a Drizzle where clause from an object.\n * All entries are combined with AND.\n * @internal\n */\nfunction buildWhereClause(\n table: SQLiteTable,\n fields: Record<string, Field<any, any, any>>,\n where: Where<Record<string, any>>,\n): ReturnType<typeof and> | null {\n const conditions: ReturnType<typeof eq>[] = []\n\n for (const [key, value] of Object.entries(where)) {\n // Multi-layered guard against identifier injection\n if (!Object.hasOwn(fields, key)) {\n throw new HTTPException(400, { message: 'invalid field in where clause' })\n }\n if (!Object.hasOwn(table, key)) {\n throw new HTTPException(400, { message: 'invalid column in table' })\n }\n // biome-ignore lint/suspicious/noExplicitAny: table column access is runtime-guarded by hasOwn\n const col = (table as unknown as Record<string, any>)[key]\n conditions.push(eq(col, value))\n }\n\n if (conditions.length === 0) {\n return null\n }\n if (conditions.length === 1) {\n return conditions[0]\n }\n return and(...conditions)\n}\n\n/**\n * Fetches multiple rows with limit, offset, and optional ordering.\n * @internal\n */\nexport async function findManyImpl<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n>(\n adapter: Adapter,\n table: SQLiteTable,\n _fields: Fields,\n options: {\n limit: unknown\n offset?: unknown\n orderBy?: OrderBy<Fields>\n },\n): Promise<RowType<Fields>[]> {\n const limit = guardLimit(options.limit)\n const offset = options.offset !== undefined ? guardOffset(options.offset) : 0\n\n // biome-ignore lint/suspicious/noExplicitAny: drizzle query builder type narrowing\n let query: any = adapter.drizzle.select().from(table).limit(limit).offset(offset)\n\n // Apply ordering\n if (options.orderBy !== undefined) {\n const orderByList = Array.isArray(options.orderBy) ? options.orderBy : [options.orderBy]\n\n for (const orderByItem of orderByList) {\n let column: string\n let direction: 'asc' | 'desc' = 'asc'\n\n if (typeof orderByItem === 'string') {\n column = orderByItem\n } else if (\n typeof orderByItem === 'object' &&\n orderByItem !== null &&\n 'column' in orderByItem\n ) {\n column = orderByItem.column\n if (orderByItem.direction) {\n direction = orderByItem.direction\n }\n } else {\n throw new HTTPException(400, { message: 'invalid orderBy format' })\n }\n\n // Runtime guard against identifier injection\n if (!Object.hasOwn(table, column)) {\n throw new HTTPException(400, { message: 'invalid field in orderBy' })\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: table column access is runtime-guarded by hasOwn\n const col = (table as unknown as Record<string, any>)[column]\n query = query.orderBy(direction === 'asc' ? asc(col) : desc(col))\n }\n }\n\n const rows = await query\n return rows\n}\n\n/**\n * Fetches a single row by primary key or where clause.\n * @internal\n */\nexport async function findOneImpl<Fields extends Record<string, Field<any, any, any>>>(\n adapter: Adapter,\n table: SQLiteTable,\n fields: Fields,\n idOrWhere: IdOrWhere<Fields>,\n): Promise<RowType<Fields> | null> {\n let where: Where<Fields> | null = null\n\n if (typeof idOrWhere === 'string' || typeof idOrWhere === 'number') {\n // PK mode\n const pk = findPrimaryKey(fields)\n if (!pk) {\n throw new HTTPException(500, { message: 'model has no primary key' })\n }\n where = { [pk[0]]: idOrWhere } as Where<Fields>\n } else {\n where = idOrWhere as Where<Fields>\n }\n\n const whereClause = buildWhereClause(table, fields, where)\n if (!whereClause) {\n throw new HTTPException(400, { message: 'where clause must not be empty' })\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: drizzle query type\n const rows = await (adapter.drizzle.select().from(table).where(whereClause).limit(1) as any)\n return rows.length > 0 ? rows[0] : null\n}\n\n/**\n * Creates a new row and returns the created record.\n * @internal\n */\nexport async function createImpl<Fields extends Record<string, Field<any, any, any>>>(\n adapter: Adapter,\n table: SQLiteTable,\n data: CreateInput<Fields>,\n): Promise<RowType<Fields>> {\n const rows = await (adapter.drizzle\n .insert(table)\n .values(data as any)\n .returning() as any)\n return rows[0]\n}\n\n/**\n * Updates rows matching the given id or where clause.\n * @internal\n */\nexport async function updateImpl<Fields extends Record<string, Field<any, any, any>>>(\n adapter: Adapter,\n table: SQLiteTable,\n fields: Fields,\n idOrWhere: IdOrWhere<Fields>,\n data: Partial<RowType<Fields>>,\n): Promise<RowType<Fields> | null> {\n let where: Where<Fields> | null = null\n\n if (typeof idOrWhere === 'string' || typeof idOrWhere === 'number') {\n // PK mode\n const pk = findPrimaryKey(fields)\n if (!pk) {\n throw new HTTPException(500, { message: 'model has no primary key' })\n }\n where = { [pk[0]]: idOrWhere } as Where<Fields>\n } else {\n where = idOrWhere as Where<Fields>\n }\n\n const whereClause = buildWhereClause(table, fields, where)\n if (!whereClause) {\n throw new HTTPException(400, { message: 'where clause must not be empty' })\n }\n\n const rows = await (adapter.drizzle\n .update(table)\n .set(data as any)\n .where(whereClause)\n .returning() as any)\n return rows.length > 0 ? rows[0] : null\n}\n\n/**\n * Deletes rows matching the given id or where clause.\n * @internal\n */\nexport async function deleteImpl<Fields extends Record<string, Field<any, any, any>>>(\n adapter: Adapter,\n table: SQLiteTable,\n fields: Fields,\n idOrWhere: IdOrWhere<Fields>,\n): Promise<{ readonly deleted: number }> {\n let where: Where<Fields> | null = null\n\n if (typeof idOrWhere === 'string' || typeof idOrWhere === 'number') {\n // PK mode\n const pk = findPrimaryKey(fields)\n if (!pk) {\n throw new HTTPException(500, { message: 'model has no primary key' })\n }\n where = { [pk[0]]: idOrWhere } as Where<Fields>\n } else {\n where = idOrWhere as Where<Fields>\n }\n\n const whereClause = buildWhereClause(table, fields, where)\n if (!whereClause) {\n throw new HTTPException(400, { message: 'where clause must not be empty' })\n }\n\n const result = await adapter.drizzle.delete(table).where(whereClause).returning()\n return { deleted: result.length }\n}\n","import { type SQLiteTable, sqliteTable } from 'drizzle-orm/sqlite-core'\nimport type { Field } from '../field/types'\n\n/**\n * Constructs a Drizzle SQLiteTable from a tableName and fields.\n * Each field is converted to a Drizzle column via field.drizzleColumn(key).\n * @internal\n */\nexport function buildTable(\n tableName: string,\n fields: Record<string, Field<any, any, any>>,\n): SQLiteTable {\n const columns: Record<string, any> = {}\n for (const [key, field] of Object.entries(fields)) {\n columns[key] = field.drizzleColumn(key)\n }\n return sqliteTable(tableName, columns)\n}\n","import { type Hook, zValidator } from '@hono/zod-validator'\nimport type { Env, ValidationTargets } from 'hono'\nimport type { z } from 'zod'\nimport type { Adapter } from '../adapter/types'\nimport type { Field } from '../field/types'\nimport { toOpenAPIComponent, toOpenAPISchema } from '../openapi/generate'\nimport type { OpenAPIUsage } from '../openapi/types'\nimport { createImpl, deleteImpl, findManyImpl, findOneImpl, updateImpl } from './crud'\nimport { applySchemaOptions, buildBaseObject, derivePolicyOptions } from './schema'\nimport { buildTable } from './table'\nimport type {\n Apply,\n CreateInput,\n FieldsToZodShape,\n FindManyOptions,\n IdOrWhere,\n Model,\n RowType,\n SchemaOptions,\n} from './types'\nimport { buildFieldAccessor } from './types'\n\n/**\n * Creates a Model instance from a tableName and fields definition.\n * The model supports deriving Zod schemas, Hono validators, and CRUD operations.\n *\n * @example\n * const User = defineModel('users', {\n * id: t.uuid().primary(),\n * name: t.string(),\n * email: t.string().email(),\n * passwordHash: t.string(),\n * })\n *\n * const CreateSchema = User.schema({ omit: ['passwordHash'] })\n * const users = await User.findMany(adapter, { limit: 20 })\n */\n// biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Field constraint\nexport function defineModel<Fields extends Record<string, Field<any, any, any>>>(\n tableName: string,\n fields: Fields,\n): Model<Fields> {\n const table = buildTable(tableName, fields)\n const accessor = buildFieldAccessor(fields)\n\n return {\n fields,\n tableName,\n table,\n\n schema<Opts extends SchemaOptions<keyof Fields & string> | undefined>(\n opts?: Opts,\n ): Apply<FieldsToZodShape<Fields>, Opts> {\n const baseSchema = buildBaseObject(fields)\n const schema = applySchemaOptions(baseSchema, opts, accessor)\n // biome-ignore lint/suspicious/noExplicitAny: Zod .pick()/.omit() return type narrowing requires cast at boundary\n return schema as any\n },\n\n validator(\n target: keyof ValidationTargets,\n optsOrPreset?: 'create' | 'update' | SchemaOptions<keyof Fields & string>,\n // biome-ignore lint/suspicious/noExplicitAny: Hook<T> is contravariant in T; any is required to bridge overload implementations\n hook?: Hook<any, Env, string, keyof ValidationTargets>,\n ) {\n let schema: z.ZodTypeAny\n if (optsOrPreset === 'create' || optsOrPreset === 'update') {\n schema = this.inputSchema(optsOrPreset)\n } else {\n schema = this.schema(optsOrPreset as SchemaOptions<keyof Fields & string>)\n }\n // biome-ignore lint/suspicious/noExplicitAny: zValidator return type cast required at overload boundary\n return zValidator(target, schema, hook) as any\n },\n\n inputSchema(\n usage: 'create' | 'update',\n opts?: SchemaOptions<keyof Fields & string>,\n // biome-ignore lint/suspicious/noExplicitAny: precise return type is enforced by Model<Fields> overload signatures\n ): any {\n const merged = derivePolicyOptions(\n fields,\n usage === 'create' ? 'input-create' : 'input-update',\n opts,\n accessor,\n )\n const baseSchema = buildBaseObject(fields)\n return applySchemaOptions(baseSchema, merged)\n },\n\n outputSchema(\n opts?: SchemaOptions<keyof Fields & string>,\n // biome-ignore lint/suspicious/noExplicitAny: precise return type is enforced by Model<Fields> overload signatures\n ): any {\n const merged = derivePolicyOptions(fields, 'output', opts, accessor)\n const baseSchema = buildBaseObject(fields)\n return applySchemaOptions(baseSchema, merged)\n },\n\n toResponse(row: RowType<Fields>): unknown {\n return this.outputSchema().parse(row)\n },\n\n toOpenAPIComponent() {\n return toOpenAPIComponent(fields)\n },\n\n toOpenAPISchema(usage: OpenAPIUsage) {\n return toOpenAPISchema(fields, usage)\n },\n\n findMany(adapter: Adapter, options: FindManyOptions<Fields>): Promise<RowType<Fields>[]> {\n return findManyImpl(adapter, table, fields, options)\n },\n\n findOne(adapter: Adapter, idOrWhere: IdOrWhere<Fields>): Promise<RowType<Fields> | null> {\n return findOneImpl(adapter, table, fields, idOrWhere)\n },\n\n create(adapter: Adapter, data: CreateInput<Fields>): Promise<RowType<Fields>> {\n return createImpl(adapter, table, data)\n },\n\n update(\n adapter: Adapter,\n idOrWhere: IdOrWhere<Fields>,\n data: Partial<RowType<Fields>>,\n ): Promise<RowType<Fields> | null> {\n return updateImpl(adapter, table, fields, idOrWhere, data)\n },\n\n delete(adapter: Adapter, idOrWhere: IdOrWhere<Fields>): Promise<{ readonly deleted: number }> {\n return deleteImpl(adapter, table, fields, idOrWhere)\n },\n }\n}\n","import { Hono } from 'hono'\nimport type { BlankEnv, Env } from 'hono/types'\nimport type { Adapter } from '../adapter/types'\nimport type { Field } from '../field/types'\nimport { defineModel } from '../model/define'\nimport type { Nanoka, NanokaModel } from './types'\n\n/**\n * Creates a Nanoka application instance with the given database adapter.\n *\n * @param adapter - The database adapter (e.g., d1Adapter(env.DB))\n * @returns A Nanoka application (Hono extended with model(), db, and batch)\n *\n * @example\n * export default {\n * fetch(req: Request, env: Env, ctx: ExecutionContext) {\n * const app = nanoka(d1Adapter(env.DB))\n * const User = app.model('users', { id, name, email, passwordHash })\n * app.get('/users', async (c) => {\n * const users = await User.findMany({ limit: 20 })\n * return c.json(users)\n * })\n * return app.fetch(req, env, ctx)\n * }\n * }\n */\nexport function nanoka<E extends Env = BlankEnv>(adapter: Adapter): Nanoka<E> {\n const app = new Hono<E>() as Nanoka<E>\n\n Object.defineProperty(app, 'db', {\n get: () => adapter.drizzle,\n enumerable: true,\n })\n\n app.batch = ((queries: Parameters<Adapter['batch']>[0]) =>\n adapter.batch(queries)) as unknown as Adapter['batch']\n\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field generic constraint\n app.model = function model<Fields extends Record<string, Field<any, any, any>>>(\n name: string,\n fields: Fields,\n ): NanokaModel<Fields> {\n const inner = defineModel(name, fields)\n\n return {\n fields: inner.fields,\n tableName: inner.tableName,\n table: inner.table,\n\n schema: (opts) => inner.schema(opts),\n\n validator: (\n ...args: [\n keyof import('hono').ValidationTargets,\n ('create' | 'update' | import('../model/types').SchemaOptions<keyof Fields & string>)?,\n import('@hono/zod-validator').Hook<\n // biome-ignore lint/suspicious/noExplicitAny: Hook<T> is contravariant in T; any is required to bridge overload implementations\n any,\n import('hono').Env,\n string,\n keyof import('hono').ValidationTargets\n >?,\n ]\n ) => {\n // `NanokaModel` interface の overload 定義 (router/types.ts) で type safety は担保する。\n // 実装は inner.validator に委譲するだけで、型は interface 側の overload に従う。\n // biome-ignore lint/suspicious/noExplicitAny: NanokaModel interface overloads provide type safety\n return (inner.validator as (...a: typeof args) => any)(...args)\n },\n\n inputSchema: (usage, opts) => inner.inputSchema(usage, opts),\n\n outputSchema: (opts) => inner.outputSchema(opts),\n\n toResponse: (row) => inner.toResponse(row),\n\n toOpenAPIComponent: () => inner.toOpenAPIComponent(),\n\n toOpenAPISchema: (usage) => inner.toOpenAPISchema(usage),\n\n findMany: (options) => inner.findMany(adapter, options),\n\n findOne: (idOrWhere) => inner.findOne(adapter, idOrWhere),\n\n create: (data) => inner.create(adapter, data),\n\n update: (idOrWhere, data) => inner.update(adapter, idOrWhere, data),\n\n delete: (idOrWhere) => inner.delete(adapter, idOrWhere),\n }\n }\n\n return app\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/adapter/d1.ts","../src/model/types.ts","../src/model/schema.ts","../src/openapi/generate.ts","../src/model/crud.ts","../src/model/table.ts","../src/model/define.ts","../src/openapi/route.ts","../src/openapi/swagger-ui.ts","../src/router/nanoka.ts"],"names":["partial","combinedOmit"],"mappings":"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","file":"index.js","sourcesContent":["import type { D1Database } from '@cloudflare/workers-types'\nimport { drizzle } from 'drizzle-orm/d1'\nimport type { Adapter } from './types'\n\n/**\n * D1-specific adapter factory. Wraps Cloudflare D1 binding in the generic\n * Adapter abstraction, enabling the core query path and router to remain\n * implementation-agnostic.\n */\nexport function d1Adapter<TSchema extends Record<string, unknown> = Record<string, never>>(\n d1: D1Database,\n): Adapter<TSchema> {\n // drizzle-orm/d1's drizzle() returns DrizzleD1Database which embeds D1-specific\n // result types. We cast to BaseSQLiteDatabase via the Adapter interface to keep\n // the D1 dependency local to this file (see CLAUDE.md rule #3). Consumers receive\n // the typed Adapter interface, so this `any` is intentionally local.\n //\n // Note: drizzle-orm/d1 internally stores the D1 binding in db.$client. When\n // handling multiple D1 bindings, call d1Adapter() fresh for each binding rather\n // than caching the return value across binding switches.\n // biome-ignore lint/suspicious/noExplicitAny: intentional - Drizzle returns complex union type\n const db = drizzle(d1) as any\n\n return {\n drizzle: db,\n batch: (queries) => db.batch(queries),\n }\n}\n","import type { Hook } from '@hono/zod-validator'\nimport type { SQLiteTable } from 'drizzle-orm/sqlite-core'\nimport type { Env, MiddlewareHandler, ValidationTargets } from 'hono'\nimport type { z } from 'zod'\nimport type { Adapter } from '../adapter/types'\nimport type { Field, FieldPolicy, InferFieldType } from '../field/types'\nimport type { OpenAPIModelComponent, OpenAPISchemaObject, OpenAPIUsage } from '../openapi/types'\n\n/**\n * Options for findMany query.\n * `limit` is required (no default).\n * `offset` defaults to 0 if omitted.\n * `orderBy` is optional for column ordering.\n */\nexport interface FindManyOptions<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> {\n readonly limit: number\n readonly offset?: number\n readonly orderBy?: OrderBy<Fields>\n}\n\n/**\n * Order-by specification: single field, or field with direction, or array of multiple.\n */\nexport type OrderBy<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> =\n | (keyof Fields & string)\n | { readonly column: keyof Fields & string; readonly direction?: 'asc' | 'desc' }\n | ReadonlyArray<\n | (keyof Fields & string)\n | { readonly column: keyof Fields & string; readonly direction?: 'asc' | 'desc' }\n >\n\n/**\n * Where clause object: each key is a field name, each value is the desired equality.\n */\nexport type Where<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> = {\n readonly [K in keyof Fields]?: InferFieldType<Fields[K]>\n}\n\n/**\n * Identifier or Where clause: can be a primary key value or a Where object.\n */\nexport type IdOrWhere<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> = string | number | Where<Fields>\n\n/**\n * Row type: full record type from fields.\n */\nexport type RowType<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> = {\n [K in keyof Fields]: InferFieldType<Fields[K]>\n}\n\n/**\n * @internal\n * Extracts the policy from a Field's modifiers.\n *\n * Uses `Field<any, { policy: infer P }, any>` rather than a two-step\n * `infer M` + `M extends { policy: infer P }` pattern.\n * The two-step pattern is broken when TypeScript widens `M` to the constraint\n * `FieldModifiers` (which has `policy?: FieldPolicy` as optional), causing\n * `M extends { policy: infer P }` to be true for ALL fields regardless of their\n * actual policy value. Directly matching `{ policy: infer P }` avoids this.\n */\ntype PolicyOf<F> =\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n F extends Field<any, { policy: infer P extends FieldPolicy }, any> ? P : never\n\n/**\n * @internal\n * Computes which field keys should be omitted based on policy and usage.\n * Mirrors the runtime logic in derivePolicyOptions() in schema.ts.\n *\n * NOTE: `[PolicyOf<Fields[K]>] extends [never]` (non-distributive form) is used to\n * short-circuit fields with no policy to `never` (do not omit). Without this guard,\n * `never extends 'serverOnly'` evaluates to `true` (vacuously), causing every field\n * without a policy to be incorrectly included in the omit set.\n */\nexport type PolicyOmitKeys<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n Usage extends 'input-create' | 'input-update' | 'output',\n> = {\n [K in keyof Fields]: [PolicyOf<Fields[K]>] extends [never]\n ? never\n : PolicyOf<Fields[K]> extends 'serverOnly'\n ? K\n : Usage extends 'output'\n ? PolicyOf<Fields[K]> extends 'writeOnly'\n ? K\n : never\n : Usage extends 'input-create' | 'input-update'\n ? PolicyOf<Fields[K]> extends 'readOnly'\n ? K\n : never\n : never\n}[keyof Fields]\n\n/**\n * @internal\n * Computes which field keys have the serverOnly policy.\n * serverOnly fields are completely excluded from CreateInput\n * (cannot be passed even from library internals — they are server-side only).\n *\n * Uses `[PolicyOf<Fields[K]>] extends [never]` (non-distributive form) to short-circuit\n * fields with no policy to `never`. Without this guard, `never extends 'serverOnly'`\n * evaluates to `true` (vacuously), causing every field without a policy to be included.\n */\ntype ServerOnlyKeys<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> = {\n [K in keyof Fields]: [PolicyOf<Fields[K]>] extends [never]\n ? never\n : PolicyOf<Fields[K]> extends 'serverOnly'\n ? K\n : never\n}[keyof Fields]\n\n/**\n * @internal\n * Determines if a field is required for create input.\n * A field is optional if it has a default, is optional, or is readOnly.\n *\n * Uses direct shape matching (`Field<any, { hasDefault: true }, any>`) to avoid\n * the TypeScript infer-widening issue where `infer M` resolves to `FieldModifiers`\n * (the constraint bound) instead of the concrete Mods type, causing `M extends\n * { policy: 'readOnly' }` to be false even for readOnly fields.\n */\n// biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\ntype IsRequired<F extends Field<any, any, any>> =\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n F extends Field<any, { hasDefault: true }, any>\n ? false\n : // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n F extends Field<any, { optional: true }, any>\n ? false\n : // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n F extends Field<any, { policy: 'readOnly' }, any>\n ? false\n : true\n\n/**\n * Create input with precise types:\n * - `readOnly` fields are optional (library internals can pass them; API callers\n * are excluded via inputSchema — but CreateInput itself keeps them as optional\n * so handlers can supply generated values like `id` or `createdAt`)\n * - fields with `default` are optional\n * - fields marked `optional` are optional\n * - all other fields are required\n * - `serverOnly` fields are completely excluded (cannot be passed even internally)\n * - `writeOnly` fields are included as required (they are input fields by design)\n */\nexport type CreateInput<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n> = {\n [K in keyof Fields as IsRequired<Fields[K]> extends true\n ? K extends ServerOnlyKeys<Fields>\n ? never\n : K\n : never]: InferFieldType<Fields[K]>\n} & {\n [K in keyof Fields as IsRequired<Fields[K]> extends true\n ? never\n : K extends ServerOnlyKeys<Fields>\n ? never\n : K]?: InferFieldType<Fields[K]>\n}\n\nexport type FieldAccessor<K extends string> = { readonly [Key in K]: Key }\n\nexport interface SchemaOptions<K extends string = string> {\n readonly pick?: readonly K[] | ((f: FieldAccessor<K>) => readonly K[])\n readonly omit?: readonly K[] | ((f: FieldAccessor<K>) => readonly K[])\n readonly partial?: boolean\n}\n\n/**\n * @internal\n * Resolves pick/omit option to string array using the accessor when it's a function.\n */\nexport function resolveSchemaOptionKeys<K extends string>(\n opt: readonly K[] | ((f: FieldAccessor<K>) => readonly K[]) | undefined,\n accessor: FieldAccessor<K>,\n): readonly K[] | undefined {\n if (opt === undefined) return undefined\n if (typeof opt === 'function') return opt(accessor)\n return opt\n}\n\n/**\n * @internal\n * Builds a frozen field accessor object for use in schema/validator options.\n * Each key maps to itself, providing typo detection at type level.\n */\nexport function buildFieldAccessor<Fields extends Record<string, unknown>>(\n fields: Fields,\n): { readonly [K in keyof Fields]: K } {\n const acc: Record<string, string> = {}\n for (const k of Object.keys(fields)) acc[k] = k\n return Object.freeze(acc) as { readonly [K in keyof Fields]: K }\n}\n\n/**\n * @internal\n * Extracts a Zod shape from fields for the Apply type.\n * Each field's zodBase becomes a property in the shape.\n * Indexed access ensures concrete Zod types are preserved (not `any`).\n */\nexport type FieldsToZodShape<\n Fields extends Record<\n string,\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Field<any, any, any>\n >,\n> = {\n [K in keyof Fields]: Fields[K]['zodBase']\n}\n\n/**\n * @internal\n * Utility to narrow array literal types to union of strings.\n */\ntype ArrayKeys<A> = A extends readonly (infer U)[] ? U : never\n\n/**\n * @internal\n * Resolves pick/omit option type to the array type.\n * Handles both array form and accessor function form.\n */\ntype ResolveOptKeys<Opt> = Opt extends readonly string[]\n ? Opt\n : Opt extends (f: FieldAccessor<infer _K>) => readonly (infer R)[]\n ? readonly R[]\n : never\n\n/**\n * @internal\n * Apply pick transformation to a shape.\n */\ntype ApplyPickToShape<Shape extends z.ZodRawShape, PickOpt> =\n ResolveOptKeys<PickOpt> extends readonly string[]\n ? Pick<Shape, ArrayKeys<ResolveOptKeys<PickOpt>> & keyof Shape>\n : Shape\n\n/**\n * @internal\n * Apply omit transformation to a shape.\n */\ntype ApplyOmitToShape<Shape extends z.ZodRawShape, OmitOpt> =\n ResolveOptKeys<OmitOpt> extends readonly string[]\n ? Omit<Shape, ArrayKeys<ResolveOptKeys<OmitOpt>> & keyof Shape>\n : Shape\n\n/**\n * @internal\n * Apply partial transformation to a shape.\n */\ntype ApplyPartialToShape<Shape extends z.ZodRawShape> = {\n [K in keyof Shape]: z.ZodOptional<Shape[K]>\n}\n\n/**\n * @internal\n * Checks if an option value (array or function) is present (i.e. not undefined and not never).\n * Uses distributive conditional to handle union types like `T | undefined`.\n */\ntype HasOpt<Opt> = undefined extends Opt ? false : [Opt] extends [never] ? false : true\n\n/**\n * @internal\n * Apply pick/omit/partial transformations to a Zod raw shape.\n * Order: pick → omit → partial\n * Handles both array form and accessor function form for pick/omit.\n */\ntype ApplyShape<\n Shape extends z.ZodRawShape,\n Opts extends SchemaOptions | undefined,\n> = Opts extends SchemaOptions\n ? HasOpt<Opts['pick']> extends true\n ? HasOpt<Opts['omit']> extends true\n ? Opts extends { partial: true }\n ? ApplyPartialToShape<ApplyOmitToShape<ApplyPickToShape<Shape, Opts['pick']>, Opts['omit']>>\n : ApplyOmitToShape<ApplyPickToShape<Shape, Opts['pick']>, Opts['omit']>\n : Opts extends { partial: true }\n ? ApplyPartialToShape<ApplyPickToShape<Shape, Opts['pick']>>\n : ApplyPickToShape<Shape, Opts['pick']>\n : HasOpt<Opts['omit']> extends true\n ? Opts extends { partial: true }\n ? ApplyPartialToShape<ApplyOmitToShape<Shape, Opts['omit']>>\n : ApplyOmitToShape<Shape, Opts['omit']>\n : Opts extends { partial: true }\n ? ApplyPartialToShape<Shape>\n : Shape\n : Shape\n\n/**\n * @internal\n * Returns the correct Zod object type after applying pick/omit/partial transformations.\n */\nexport type Apply<\n Shape extends z.ZodRawShape,\n Opts extends SchemaOptions | undefined,\n> = z.ZodObject<ApplyShape<Shape, Opts>>\n\n/**\n * @internal\n * Apply pick transformation to a TS record type.\n */\ntype ApplyPickToRecord<R, PickOpt> =\n ResolveOptKeys<PickOpt> extends readonly string[]\n ? Pick<R, ArrayKeys<ResolveOptKeys<PickOpt>> & keyof R>\n : R\n\n/**\n * @internal\n * Apply omit transformation to a TS record type.\n */\ntype ApplyOmitToRecord<R, OmitOpt> =\n ResolveOptKeys<OmitOpt> extends readonly string[]\n ? Omit<R, ArrayKeys<ResolveOptKeys<OmitOpt>> & keyof R>\n : R\n\n/**\n * @internal\n * Apply pick/omit/partial transformations to a TypeScript record type.\n * Mirrors ApplyShape but operates on TS types directly, not Zod shapes.\n * Used for Zod v3/v4 compatible middleware input/output type computation.\n */\ntype ApplyToRecord<R, Opts extends SchemaOptions | undefined> = Opts extends SchemaOptions\n ? HasOpt<Opts['pick']> extends true\n ? HasOpt<Opts['omit']> extends true\n ? Opts extends { partial: true }\n ? Partial<ApplyOmitToRecord<ApplyPickToRecord<R, Opts['pick']>, Opts['omit']>>\n : ApplyOmitToRecord<ApplyPickToRecord<R, Opts['pick']>, Opts['omit']>\n : Opts extends { partial: true }\n ? Partial<ApplyPickToRecord<R, Opts['pick']>>\n : ApplyPickToRecord<R, Opts['pick']>\n : HasOpt<Opts['omit']> extends true\n ? Opts extends { partial: true }\n ? Partial<ApplyOmitToRecord<R, Opts['omit']>>\n : ApplyOmitToRecord<R, Opts['omit']>\n : Opts extends { partial: true }\n ? Partial<R>\n : R\n : R\n\n/**\n * @internal\n * Mirrors @hono/zod-validator's middleware Input type.\n * Aligned with @hono/zod-validator@0.4.x; revisit on version bump.\n */\ntype HasUndefined<T> = undefined extends T ? true : false\n\n/**\n * @internal\n * Hono middleware input/output type for validator middleware.\n * Aligned with @hono/zod-validator@0.4.x; revisit on version bump.\n *\n * WARNING (Zod 4): `z.input<ZodTypeAny>` resolves to `unknown` in Zod 4, making\n * `c.req.valid(target)` return `unknown` if `In`/`Out` are left as defaults.\n * When using this type directly (outside of `ModelValidatorReturn`), always pass\n * explicit `In` and `Out` type arguments — do NOT rely on the defaults.\n *\n * Internal usages in this file (ModelValidatorReturn and preset overloads) already\n * pass `In`/`Out` explicitly via `ApplyToRecord` or `Omit<RowType<Fields>, ...>`.\n */\nexport type ValidatorInput<\n Target extends keyof ValidationTargets,\n Schema extends z.ZodTypeAny,\n In = z.input<Schema>,\n Out = z.output<Schema>,\n> = {\n in: HasUndefined<In> extends true\n ? {\n [K in Target]?:\n | (In extends ValidationTargets[K]\n ? In\n : { [K2 in keyof In]?: ValidationTargets[K][K2] | undefined })\n | undefined\n }\n : {\n [K in Target]: In extends ValidationTargets[K]\n ? In\n : { [K2 in keyof In]: ValidationTargets[K][K2] }\n }\n out: { [K in Target]: Out }\n}\n\n/**\n * @internal\n * Type-safe Hono middleware handler return for Model.validator().\n * Provides proper type narrowing for c.req.valid(target).\n *\n * Uses RowType<Fields> directly for input/output type computation\n * to ensure Zod v3/v4 compatibility (z.input<ZodTypeAny> returns unknown in Zod v4).\n */\nexport type ModelValidatorReturn<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n Target extends keyof ValidationTargets,\n Opts extends SchemaOptions<keyof Fields & string> | undefined,\n> = MiddlewareHandler<\n any,\n string,\n ValidatorInput<\n Target,\n Apply<FieldsToZodShape<Fields>, Opts>,\n ApplyToRecord<RowType<Fields>, Opts>,\n ApplyToRecord<RowType<Fields>, Opts>\n >\n>\n\n/**\n * Hook type for Model.validator() third argument.\n * Re-exported from @hono/zod-validator for convenience.\n */\nexport type { Hook }\n\n/**\n * Represents a database model with type-safe schema derivation and CRUD operations.\n */\n// biome-ignore lint/suspicious/noExplicitAny: any is necessary for the generic Field constraint\nexport interface Model<Fields extends Record<string, Field<any, any, any>>> {\n readonly fields: Fields\n readonly tableName: string\n readonly table: SQLiteTable\n\n /**\n * Returns a Zod schema derived from this model's fields.\n * Supports pick, omit, and partial transformations.\n *\n * @example\n * const CreateSchema = User.schema({ omit: ['passwordHash'] })\n * const UpdateSchema = User.schema({ partial: true, pick: ['name', 'email'] })\n */\n schema<Opts extends SchemaOptions<keyof Fields & string> | undefined>(\n opts?: Opts,\n ): Apply<FieldsToZodShape<Fields>, Opts>\n\n /**\n * Returns a Hono middleware validator derived from this model's schema.\n * Integrates with @hono/zod-validator to validate request inputs.\n * The optional `hook` argument is passed through to @hono/zod-validator.\n *\n * Accepts a preset ('create' | 'update') as second argument to use inputSchema.\n * When a preset is used, the return type is a MiddlewareHandler (loosely typed in Phase 2A).\n * Precise type narrowing for preset is deferred to Phase 2B M2.3.\n *\n * @example\n * app.post('/users', User.validator('json', 'create'), c => {\n * const body = c.req.valid('json')\n * })\n * app.post('/users', User.validator('json', { omit: ['passwordHash'] }), c => {\n * const body = c.req.valid('json')\n * })\n * // With hook:\n * app.post('/users', User.validator('json', opts, (result, c) => {\n * if (!result.success) return c.json({ error: 'Invalid request' }, 400)\n * }), handler)\n */\n validator<Target extends keyof ValidationTargets, E extends Env = Env, P extends string = string>(\n target: Target,\n preset: 'create',\n hook?: Hook<\n Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-create'> & string>,\n E,\n P,\n Target\n >,\n ): MiddlewareHandler<\n E,\n P,\n ValidatorInput<\n Target,\n z.ZodObject<z.ZodRawShape>,\n Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-create'> & string>,\n Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-create'> & string>\n >\n >\n validator<Target extends keyof ValidationTargets, E extends Env = Env, P extends string = string>(\n target: Target,\n preset: 'update',\n hook?: Hook<\n Partial<Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-update'> & string>>,\n E,\n P,\n Target\n >,\n ): MiddlewareHandler<\n E,\n P,\n ValidatorInput<\n Target,\n z.ZodObject<z.ZodRawShape>,\n Partial<Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-update'> & string>>,\n Partial<Omit<RowType<Fields>, PolicyOmitKeys<Fields, 'input-update'> & string>>\n >\n >\n validator<\n Target extends keyof ValidationTargets,\n Opts extends SchemaOptions<keyof Fields & string> | undefined,\n E extends Env = Env,\n P extends string = string,\n >(\n target: Target,\n opts?: Opts,\n hook?: Hook<z.output<Apply<FieldsToZodShape<Fields>, Opts>>, E, P, Target>,\n ): ModelValidatorReturn<Fields, Target, Opts>\n\n /**\n * Returns a Zod schema for API input, with policy-based field exclusions applied.\n * - 'create': serverOnly and readOnly fields are excluded\n * - 'update': same exclusions + all fields become optional (partial: true)\n *\n * The return type precisely reflects policy-derived omissions using PolicyOmitKeys.\n */\n inputSchema<Opts extends SchemaOptions<keyof Fields & string> | undefined = undefined>(\n usage: 'create',\n opts?: Opts,\n ): z.ZodObject<\n ApplyShape<\n Omit<FieldsToZodShape<Fields>, PolicyOmitKeys<Fields, 'input-create'> & string>,\n Opts\n >\n >\n inputSchema<Opts extends SchemaOptions<keyof Fields & string> | undefined = undefined>(\n usage: 'update',\n opts?: Opts,\n ): z.ZodObject<\n ApplyShape<\n Omit<FieldsToZodShape<Fields>, PolicyOmitKeys<Fields, 'input-update'> & string>,\n Opts extends undefined ? { partial: true } : Opts & { partial: true }\n >\n >\n inputSchema(\n usage: 'create' | 'update',\n opts?: SchemaOptions<keyof Fields & string>,\n ): z.ZodObject<z.ZodRawShape>\n\n /**\n * Returns a Zod schema for API output, with policy-based field exclusions applied.\n * - serverOnly and writeOnly fields are excluded\n * - readOnly fields remain present\n *\n * The return type precisely reflects policy-derived omissions using PolicyOmitKeys.\n */\n outputSchema<Opts extends SchemaOptions<keyof Fields & string> | undefined = undefined>(\n opts?: Opts,\n ): z.ZodObject<\n ApplyShape<Omit<FieldsToZodShape<Fields>, PolicyOmitKeys<Fields, 'output'> & string>, Opts>\n >\n\n /**\n * Parses a DB row through outputSchema and returns the safe response object.\n * Equivalent to `User.outputSchema().parse(row)`.\n */\n toResponse(row: RowType<Fields>): unknown\n\n toOpenAPIComponent(): OpenAPIModelComponent\n\n toOpenAPISchema(usage: OpenAPIUsage): OpenAPISchemaObject\n\n /**\n * Fetches multiple rows with pagination and optional ordering.\n * `limit` is required (no default) to prevent accidental unbounded queries.\n * Offset defaults to 0 if omitted.\n *\n * @example\n * const users = await User.findMany(adapter, { limit: 20 })\n * const page2 = await User.findMany(adapter, { limit: 20, offset: 20 })\n * const sorted = await User.findMany(adapter, { limit: 10, orderBy: 'name' })\n */\n findMany(adapter: Adapter, options: FindManyOptions<Fields>): Promise<RowType<Fields>[]>\n\n /**\n * Fetches a single row by primary key or where clause.\n * Returns null if not found.\n *\n * @example\n * const user = await User.findOne(adapter, id)\n * const byEmail = await User.findOne(adapter, { email: 'john@example.com' })\n */\n findOne(adapter: Adapter, idOrWhere: IdOrWhere<Fields>): Promise<RowType<Fields> | null>\n\n /**\n * Creates a new row and returns the created record.\n *\n * @example\n * const user = await User.create(adapter, { name: 'John', email: 'john@example.com' })\n */\n create(adapter: Adapter, data: CreateInput<Fields>): Promise<RowType<Fields>>\n\n /**\n * Updates rows matching the given id or where clause.\n * Returns the updated row(s), or null if no rows matched.\n *\n * @example\n * const updated = await User.update(adapter, id, { name: 'Jane' })\n * const byEmail = await User.update(adapter, { email: '...' }, { name: 'Jane' })\n */\n update(\n adapter: Adapter,\n idOrWhere: IdOrWhere<Fields>,\n data: Partial<RowType<Fields>>,\n ): Promise<RowType<Fields> | null>\n\n /**\n * Deletes rows matching the given id or where clause.\n * Returns the number of deleted rows.\n *\n * @example\n * const result = await User.delete(adapter, id)\n * console.log(result.deleted) // number\n */\n delete(adapter: Adapter, idOrWhere: IdOrWhere<Fields>): Promise<{ readonly deleted: number }>\n}\n","import { z } from 'zod'\nimport type { Field } from '../field/types'\nimport { type FieldAccessor, resolveSchemaOptionKeys, type SchemaOptions } from './types'\n\ntype PolicyUsage = 'input-create' | 'input-update' | 'output'\n\n/**\n * Returns field names that are security-critical and must always be omitted from API schemas.\n * Currently only serverOnly fields. These cannot be overridden by user pick/omit.\n */\nfunction computeForcedOmit(\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Field handling\n fields: Record<string, Field<any, any, any>>,\n): string[] {\n const omit: string[] = []\n for (const [key, field] of Object.entries(fields)) {\n if (field.modifiers.policy === 'serverOnly') {\n omit.push(key)\n }\n }\n return omit\n}\n\n/**\n * Returns field names to omit based on UX-oriented policy (writeOnly / readOnly).\n * These can be overridden when user explicitly provides pick.\n *\n * Policy mapping:\n * - `writeOnly`: omitted from output only. For input targets (input-create, input-update),\n * writeOnly fields are NOT omitted — they are intentionally part of the input (e.g. password).\n * - `readOnly`: omitted from input targets (input-create, input-update) only. Remains in output.\n *\n * The asymmetry is by design: writeOnly means \"accepted on write, hidden on read\";\n * readOnly means \"visible on read, rejected on write\".\n */\nfunction computeOptionalOmit(\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Field handling\n fields: Record<string, Field<any, any, any>>,\n target: PolicyUsage,\n): string[] {\n const omit: string[] = []\n for (const [key, field] of Object.entries(fields)) {\n const policy = field.modifiers.policy\n if (!policy) continue\n if (policy === 'writeOnly' && target === 'output') {\n omit.push(key)\n } else if (policy === 'readOnly' && (target === 'input-create' || target === 'input-update')) {\n omit.push(key)\n }\n }\n return omit\n}\n\n/**\n * Merges policy-derived omit with user-provided SchemaOptions.\n *\n * serverOnly fields are always omitted regardless of user pick/omit (security invariant).\n * writeOnly / readOnly are UX-oriented and can be overridden when user provides pick.\n * For 'input-update', partial defaults to true unless user specifies otherwise.\n */\nexport function derivePolicyOptions(\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Field handling\n fields: Record<string, Field<any, any, any>>,\n usage: PolicyUsage,\n userOpts?: SchemaOptions,\n // biome-ignore lint/suspicious/noExplicitAny: accessor is a plain object with string keys\n accessor?: FieldAccessor<any>,\n): SchemaOptions {\n const forced = computeForcedOmit(fields)\n const optional = computeOptionalOmit(fields, usage)\n\n const acc = accessor ?? ({} as FieldAccessor<string>)\n const resolvedPick = resolveSchemaOptionKeys(userOpts?.pick, acc)\n const resolvedOmit = resolveSchemaOptionKeys(userOpts?.omit, acc)\n\n if (resolvedPick !== undefined) {\n const partial = usage === 'input-update' ? (userOpts?.partial ?? true) : userOpts?.partial\n // serverOnly fields are stripped from pick even if user explicitly listed them\n const sanitizedPick = Array.from(resolvedPick).filter((k) => !forced.includes(k))\n // Combine forced omit with user-provided omit to preserve both constraints\n const combinedOmit = [...new Set([...forced, ...(resolvedOmit ?? [])])]\n return {\n ...userOpts,\n pick: sanitizedPick,\n ...(combinedOmit.length > 0 ? { omit: combinedOmit } : {}),\n partial,\n }\n }\n\n const combinedOmit = [...new Set([...forced, ...optional, ...(resolvedOmit ?? [])])]\n const partial =\n usage === 'input-update' ? (userOpts?.partial ?? true) : (userOpts?.partial ?? undefined)\n\n return {\n ...(userOpts ?? {}),\n pick: undefined,\n ...(combinedOmit.length > 0 ? { omit: combinedOmit } : {}),\n ...(partial !== undefined ? { partial } : {}),\n }\n}\n\n/**\n * Builds a Zod object schema from a fields definition.\n * Returns a ZodObject with all fields required and present.\n */\n// biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Field handling and Zod shape\nexport function buildBaseObject(fields: Record<string, Field<any, any, any>>): z.ZodObject<any> {\n // biome-ignore lint/suspicious/noExplicitAny: Record key-value pairs have any type for shape\n const shape: Record<string, any> = {}\n for (const [key, field] of Object.entries(fields)) {\n shape[key] = field.zodBase\n }\n return z.object(shape)\n}\n\n/**\n * Applies pick, omit, and partial transformations to a Zod object schema.\n * Order: pick → omit → partial\n *\n * Returns the transformed schema, cast to Apply<Shape, Opts> at the call site.\n */\nexport function applySchemaOptions(\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Zod shape operations\n baseSchema: z.ZodObject<any>,\n opts: SchemaOptions | undefined,\n // biome-ignore lint/suspicious/noExplicitAny: accessor is a plain object with string keys\n accessor?: FieldAccessor<any>,\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for return type\n): z.ZodObject<any> {\n if (!opts) {\n return baseSchema\n }\n\n const acc = accessor ?? ({} as FieldAccessor<string>)\n const resolvedPick = resolveSchemaOptionKeys(opts.pick, acc)\n const resolvedOmit = resolveSchemaOptionKeys(opts.omit, acc)\n\n let schema = baseSchema\n\n // Apply pick\n if (resolvedPick !== undefined) {\n const pickArray = Array.from(resolvedPick)\n schema = schema.pick(\n // biome-ignore lint/suspicious/noExplicitAny: Zod API\n Object.fromEntries(pickArray.map((k) => [k, true])) as any,\n )\n }\n\n // Apply omit\n if (resolvedOmit !== undefined) {\n const omitArray = Array.from(resolvedOmit)\n schema = schema.omit(\n // biome-ignore lint/suspicious/noExplicitAny: Zod API\n Object.fromEntries(omitArray.map((k) => [k, true])) as any,\n )\n }\n\n // Apply partial\n // `partial: false` を渡してもこの条件で何もしない。スキーマは required のまま。\n if (opts.partial === true) {\n schema = schema.partial()\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: Cast to Apply type at call site\n return schema as any\n}\n","import type { Field } from '../field/types'\nimport { applySchemaOptions, buildBaseObject, derivePolicyOptions } from '../model/schema'\nimport type { SchemaOptions } from '../model/types'\nimport type { OpenAPIModelComponent, OpenAPISchemaObject, OpenAPIUsage } from './types'\n\n// biome-ignore lint/suspicious/noExplicitAny: OpenAPI generation accepts any concrete field builder.\ntype AnyField = Field<any, any, any>\ntype FieldsRecord = Record<string, AnyField>\n\ninterface OpenAPIOptions {\n readonly opts?: SchemaOptions\n readonly strict?: boolean\n}\n\nexport function toOpenAPIComponent(\n fields: FieldsRecord,\n opts?: OpenAPIOptions,\n): OpenAPIModelComponent {\n return {\n create: toOpenAPISchema(fields, 'create', opts),\n update: toOpenAPISchema(fields, 'update', opts),\n output: toOpenAPISchema(fields, 'output', opts),\n }\n}\n\nexport function toOpenAPISchema(\n fields: FieldsRecord,\n usage: OpenAPIUsage,\n opts?: OpenAPIOptions,\n): OpenAPISchemaObject {\n const policyUsage =\n usage === 'create' ? 'input-create' : usage === 'update' ? 'input-update' : 'output'\n const merged = derivePolicyOptions(fields, policyUsage, opts?.opts)\n const schema = applySchemaOptions(buildBaseObject(fields), merged)\n const shape = getZodObjectShape(schema)\n const properties: Record<string, OpenAPISchemaObject> = {}\n const required: string[] = []\n\n for (const [key, zodSchema] of Object.entries(shape)) {\n const field = fields[key]\n if (field === undefined) continue\n\n properties[key] = fieldToOpenAPISchema(field, opts?.strict)\n if (field.modifiers.policy === 'writeOnly' && (usage === 'create' || usage === 'update')) {\n properties[key].writeOnly = true\n }\n if (field.modifiers.policy === 'readOnly' && usage === 'output') {\n properties[key].readOnly = true\n }\n if (usage !== 'update' && isRequiredZodSchema(zodSchema)) {\n required.push(key)\n }\n }\n\n return {\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n }\n}\n\nfunction fieldToOpenAPISchema(field: AnyField, strict = false): OpenAPISchemaObject {\n const schema: OpenAPISchemaObject =\n field.kind === 'json'\n ? zodToOpenAPISchema(field.zodBase, strict)\n : field.kind === 'string'\n ? { type: 'string' }\n : field.kind === 'uuid'\n ? { type: 'string', format: 'uuid' }\n : field.kind === 'number'\n ? { type: 'number' }\n : field.kind === 'integer'\n ? { type: 'integer' }\n : field.kind === 'boolean'\n ? { type: 'boolean' }\n : field.kind === 'timestamp'\n ? { type: 'string', format: 'date-time' }\n : {}\n\n if (field.modifiers.format === 'email') {\n schema.format = 'email'\n }\n if (field.modifiers.min !== undefined) {\n if (field.kind === 'string' || field.kind === 'uuid') {\n schema.minLength = field.modifiers.min\n } else {\n schema.minimum = field.modifiers.min\n }\n }\n if (field.modifiers.max !== undefined) {\n if (field.kind === 'string' || field.kind === 'uuid') {\n schema.maxLength = field.modifiers.max\n } else {\n schema.maximum = field.modifiers.max\n }\n }\n\n return schema\n}\n\nfunction zodToOpenAPISchema(schema: unknown, strict = false): OpenAPISchemaObject {\n const def = getZodDef(schema)\n if (def === undefined) return {}\n\n const typeName = getZodTypeName(def)\n\n if (typeName === 'ZodOptional' || typeName === 'optional') {\n return zodToOpenAPISchema(def.innerType, strict)\n }\n if (typeName === 'ZodDefault' || typeName === 'default') {\n return zodToOpenAPISchema(def.innerType, strict)\n }\n if (typeName === 'ZodNullable' || typeName === 'nullable') {\n return { ...zodToOpenAPISchema(def.innerType, strict), nullable: true }\n }\n\n if (typeName === 'ZodObject' || typeName === 'object') {\n const shape = getZodObjectShape(schema)\n const properties: Record<string, OpenAPISchemaObject> = {}\n const required: string[] = []\n\n for (const [key, childSchema] of Object.entries(shape)) {\n properties[key] = zodToOpenAPISchema(childSchema, strict)\n if (isRequiredZodSchema(childSchema)) {\n required.push(key)\n }\n }\n\n return {\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n }\n }\n\n if (typeName === 'ZodString' || typeName === 'string') {\n return applyStringChecks({ type: 'string' }, def)\n }\n\n if (typeName === 'ZodNumber' || typeName === 'number') {\n return applyNumberChecks({ type: hasIntegerCheck(def) ? 'integer' : 'number' }, def)\n }\n\n if (typeName === 'ZodBoolean' || typeName === 'boolean') {\n return { type: 'boolean' }\n }\n\n if (typeName === 'ZodArray' || typeName === 'array') {\n const itemSchema = def.element ?? def.type\n return {\n type: 'array',\n items: zodToOpenAPISchema(itemSchema, strict),\n }\n }\n\n if (typeName === 'ZodRecord' || typeName === 'record') {\n return {\n type: 'object',\n additionalProperties: zodToOpenAPISchema(def.valueType, strict),\n }\n }\n\n if (typeName === 'ZodUnknown' || typeName === 'unknown') {\n return {}\n }\n\n if (strict) {\n throw new Error(`Unsupported Zod type for strict OpenAPI generation: ${typeName ?? 'unknown'}`)\n }\n return {\n 'x-nanoka-zod-unsupported': true,\n ...(typeName ? { 'x-nanoka-zod-type': typeName } : {}),\n }\n}\n\nfunction getZodObjectShape(schema: unknown): Record<string, unknown> {\n if (\n typeof schema === 'object' &&\n schema !== null &&\n 'shape' in schema &&\n typeof schema.shape === 'object' &&\n schema.shape !== null\n ) {\n return schema.shape as Record<string, unknown>\n }\n\n if (\n typeof schema === 'object' &&\n schema !== null &&\n '_def' in schema &&\n typeof schema._def === 'object' &&\n schema._def !== null &&\n 'shape' in schema._def\n ) {\n const shape = schema._def.shape\n return (typeof shape === 'function' ? shape() : shape) as Record<string, unknown>\n }\n\n return {}\n}\n\nfunction isRequiredZodSchema(schema: unknown): boolean {\n const def = getZodDef(schema)\n if (def === undefined) {\n return true\n }\n\n const typeName = getZodTypeName(def)\n return (\n typeName !== 'ZodOptional' &&\n typeName !== 'optional' &&\n typeName !== 'ZodDefault' &&\n typeName !== 'default'\n )\n}\n\nfunction getZodDef(schema: unknown): Record<string, unknown> | undefined {\n if (\n typeof schema === 'object' &&\n schema !== null &&\n '_def' in schema &&\n typeof schema._def === 'object' &&\n schema._def !== null\n ) {\n return schema._def as Record<string, unknown>\n }\n\n return undefined\n}\n\nfunction getZodTypeName(def: Record<string, unknown>): string | undefined {\n return typeof def.typeName === 'string'\n ? def.typeName\n : typeof def.type === 'string'\n ? def.type\n : undefined\n}\n\nfunction applyStringChecks(\n schema: OpenAPISchemaObject,\n def: Record<string, unknown>,\n): OpenAPISchemaObject {\n for (const check of getZodChecks(def)) {\n const checkDef = getZodCheckDef(check)\n if (checkDef.kind === 'email' || checkDef.format === 'email') {\n schema.format = 'email'\n }\n if (checkDef.kind === 'min' && typeof checkDef.value === 'number') {\n schema.minLength = checkDef.value\n }\n if (checkDef.kind === 'max' && typeof checkDef.value === 'number') {\n schema.maxLength = checkDef.value\n }\n if (checkDef.check === 'min_length' && typeof checkDef.minimum === 'number') {\n schema.minLength = checkDef.minimum\n }\n if (checkDef.check === 'max_length' && typeof checkDef.maximum === 'number') {\n schema.maxLength = checkDef.maximum\n }\n }\n\n return schema\n}\n\nfunction applyNumberChecks(\n schema: OpenAPISchemaObject,\n def: Record<string, unknown>,\n): OpenAPISchemaObject {\n for (const check of getZodChecks(def)) {\n const checkDef = getZodCheckDef(check)\n if (checkDef.kind === 'min' && typeof checkDef.value === 'number') {\n schema.minimum = checkDef.value\n }\n if (checkDef.kind === 'max' && typeof checkDef.value === 'number') {\n schema.maximum = checkDef.value\n }\n if (\n (checkDef.check === 'greater_than' || checkDef.check === 'number_format') &&\n typeof checkDef.minimum === 'number'\n ) {\n schema.minimum = checkDef.minimum\n }\n if (\n (checkDef.check === 'less_than' || checkDef.check === 'number_format') &&\n typeof checkDef.maximum === 'number'\n ) {\n schema.maximum = checkDef.maximum\n }\n }\n\n return schema\n}\n\nfunction hasIntegerCheck(def: Record<string, unknown>): boolean {\n return getZodChecks(def).some((check) => {\n const checkDef = getZodCheckDef(check)\n return (\n checkDef.kind === 'int' ||\n checkDef.format === 'safeint' ||\n checkDef.format === 'int32' ||\n checkDef.format === 'int64'\n )\n })\n}\n\nfunction getZodChecks(def: Record<string, unknown>): readonly unknown[] {\n return Array.isArray(def.checks) ? def.checks : []\n}\n\nfunction getZodCheckDef(check: unknown): Record<string, unknown> {\n if (typeof check !== 'object' || check === null) {\n return {}\n }\n if (\n '_zod' in check &&\n typeof check._zod === 'object' &&\n check._zod !== null &&\n 'def' in check._zod &&\n typeof check._zod.def === 'object' &&\n check._zod.def !== null\n ) {\n return check._zod.def as Record<string, unknown>\n }\n\n return check as Record<string, unknown>\n}\n","import { and, asc, desc, eq } from 'drizzle-orm'\nimport type { SQLiteTable } from 'drizzle-orm/sqlite-core'\nimport { HTTPException } from 'hono/http-exception'\nimport type { Adapter } from '../adapter/types'\nimport type { Field } from '../field/types'\nimport type { CreateInput, IdOrWhere, OrderBy, RowType, Where } from './types'\n\nconst MAX_LIMIT = 100\n\n/**\n * Validates and guards limit/offset parameters.\n * @internal\n */\nfunction guardLimit(limit: unknown): number {\n if (!Number.isInteger(limit)) {\n throw new HTTPException(400, { message: 'limit must be an integer' })\n }\n const n = limit as number\n if (n < 0) {\n throw new HTTPException(400, { message: 'limit must be >= 0' })\n }\n if (n > MAX_LIMIT) {\n throw new HTTPException(400, { message: `limit must be <= ${MAX_LIMIT}` })\n }\n return n\n}\n\nfunction guardOffset(offset: unknown): number {\n if (!Number.isInteger(offset)) {\n throw new HTTPException(400, { message: 'offset must be an integer' })\n }\n const n = offset as number\n if (n < 0) {\n throw new HTTPException(400, { message: 'offset must be >= 0' })\n }\n return n\n}\n\n/**\n * Finds the primary key field from fields record.\n * @internal\n */\nfunction findPrimaryKey(\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n fields: Record<string, Field<any, any, any>>,\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n): [string, Field<any, any, any>] | null {\n let pkKey: string | undefined\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n let pkField: Field<any, any, any> | undefined\n let pkCount = 0\n\n for (const [key, field] of Object.entries(fields)) {\n if (field.modifiers.primary === true) {\n pkCount++\n if (pkCount === 1) {\n pkKey = key\n pkField = field\n }\n }\n }\n\n if (pkCount === 0) {\n return null\n }\n if (pkCount > 1) {\n throw new HTTPException(500, { message: 'model has multiple primary keys' })\n }\n if (pkKey === undefined || pkField === undefined) {\n return null\n }\n\n return [pkKey, pkField]\n}\n\n/**\n * Constructs a Drizzle where clause from an object.\n * All entries are combined with AND.\n * @internal\n */\nfunction buildWhereClause(\n table: SQLiteTable,\n fields: Record<string, Field<any, any, any>>,\n where: Where<Record<string, any>>,\n): ReturnType<typeof and> | null {\n const conditions: ReturnType<typeof eq>[] = []\n\n for (const [key, value] of Object.entries(where)) {\n // Multi-layered guard against identifier injection\n if (!Object.hasOwn(fields, key)) {\n throw new HTTPException(400, { message: 'invalid field in where clause' })\n }\n if (!Object.hasOwn(table, key)) {\n throw new HTTPException(400, { message: 'invalid column in table' })\n }\n // biome-ignore lint/suspicious/noExplicitAny: table column access is runtime-guarded by hasOwn\n const col = (table as unknown as Record<string, any>)[key]\n conditions.push(eq(col, value))\n }\n\n if (conditions.length === 0) {\n return null\n }\n if (conditions.length === 1) {\n return conditions[0]\n }\n return and(...conditions)\n}\n\n/**\n * Fetches multiple rows with limit, offset, and optional ordering.\n * @internal\n */\nexport async function findManyImpl<\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field constraint\n Fields extends Record<string, Field<any, any, any>>,\n>(\n adapter: Adapter,\n table: SQLiteTable,\n _fields: Fields,\n options: {\n limit: unknown\n offset?: unknown\n orderBy?: OrderBy<Fields>\n },\n): Promise<RowType<Fields>[]> {\n const limit = guardLimit(options.limit)\n const offset = options.offset !== undefined ? guardOffset(options.offset) : 0\n\n // biome-ignore lint/suspicious/noExplicitAny: drizzle query builder type narrowing\n let query: any = adapter.drizzle.select().from(table).limit(limit).offset(offset)\n\n // Apply ordering\n if (options.orderBy !== undefined) {\n const orderByList = Array.isArray(options.orderBy) ? options.orderBy : [options.orderBy]\n\n for (const orderByItem of orderByList) {\n let column: string\n let direction: 'asc' | 'desc' = 'asc'\n\n if (typeof orderByItem === 'string') {\n column = orderByItem\n } else if (\n typeof orderByItem === 'object' &&\n orderByItem !== null &&\n 'column' in orderByItem\n ) {\n column = orderByItem.column\n if (orderByItem.direction) {\n direction = orderByItem.direction\n }\n } else {\n throw new HTTPException(400, { message: 'invalid orderBy format' })\n }\n\n // Runtime guard against identifier injection\n if (!Object.hasOwn(table, column)) {\n throw new HTTPException(400, { message: 'invalid field in orderBy' })\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: table column access is runtime-guarded by hasOwn\n const col = (table as unknown as Record<string, any>)[column]\n query = query.orderBy(direction === 'asc' ? asc(col) : desc(col))\n }\n }\n\n const rows = await query\n return rows\n}\n\n/**\n * Fetches a single row by primary key or where clause.\n * @internal\n */\nexport async function findOneImpl<Fields extends Record<string, Field<any, any, any>>>(\n adapter: Adapter,\n table: SQLiteTable,\n fields: Fields,\n idOrWhere: IdOrWhere<Fields>,\n): Promise<RowType<Fields> | null> {\n let where: Where<Fields> | null = null\n\n if (typeof idOrWhere === 'string' || typeof idOrWhere === 'number') {\n // PK mode\n const pk = findPrimaryKey(fields)\n if (!pk) {\n throw new HTTPException(500, { message: 'model has no primary key' })\n }\n where = { [pk[0]]: idOrWhere } as Where<Fields>\n } else {\n where = idOrWhere as Where<Fields>\n }\n\n const whereClause = buildWhereClause(table, fields, where)\n if (!whereClause) {\n throw new HTTPException(400, { message: 'where clause must not be empty' })\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: drizzle query type\n const rows = await (adapter.drizzle.select().from(table).where(whereClause).limit(1) as any)\n return rows.length > 0 ? rows[0] : null\n}\n\n/**\n * Creates a new row and returns the created record.\n * @internal\n */\nexport async function createImpl<Fields extends Record<string, Field<any, any, any>>>(\n adapter: Adapter,\n table: SQLiteTable,\n data: CreateInput<Fields>,\n): Promise<RowType<Fields>> {\n const rows = await (adapter.drizzle\n .insert(table)\n .values(data as any)\n .returning() as any)\n return rows[0]\n}\n\n/**\n * Updates rows matching the given id or where clause.\n * @internal\n */\nexport async function updateImpl<Fields extends Record<string, Field<any, any, any>>>(\n adapter: Adapter,\n table: SQLiteTable,\n fields: Fields,\n idOrWhere: IdOrWhere<Fields>,\n data: Partial<RowType<Fields>>,\n): Promise<RowType<Fields> | null> {\n let where: Where<Fields> | null = null\n\n if (typeof idOrWhere === 'string' || typeof idOrWhere === 'number') {\n // PK mode\n const pk = findPrimaryKey(fields)\n if (!pk) {\n throw new HTTPException(500, { message: 'model has no primary key' })\n }\n where = { [pk[0]]: idOrWhere } as Where<Fields>\n } else {\n where = idOrWhere as Where<Fields>\n }\n\n const whereClause = buildWhereClause(table, fields, where)\n if (!whereClause) {\n throw new HTTPException(400, { message: 'where clause must not be empty' })\n }\n\n const rows = await (adapter.drizzle\n .update(table)\n .set(data as any)\n .where(whereClause)\n .returning() as any)\n return rows.length > 0 ? rows[0] : null\n}\n\n/**\n * Deletes rows matching the given id or where clause.\n * @internal\n */\nexport async function deleteImpl<Fields extends Record<string, Field<any, any, any>>>(\n adapter: Adapter,\n table: SQLiteTable,\n fields: Fields,\n idOrWhere: IdOrWhere<Fields>,\n): Promise<{ readonly deleted: number }> {\n let where: Where<Fields> | null = null\n\n if (typeof idOrWhere === 'string' || typeof idOrWhere === 'number') {\n // PK mode\n const pk = findPrimaryKey(fields)\n if (!pk) {\n throw new HTTPException(500, { message: 'model has no primary key' })\n }\n where = { [pk[0]]: idOrWhere } as Where<Fields>\n } else {\n where = idOrWhere as Where<Fields>\n }\n\n const whereClause = buildWhereClause(table, fields, where)\n if (!whereClause) {\n throw new HTTPException(400, { message: 'where clause must not be empty' })\n }\n\n const result = await adapter.drizzle.delete(table).where(whereClause).returning()\n return { deleted: result.length }\n}\n","import { type SQLiteTable, sqliteTable } from 'drizzle-orm/sqlite-core'\nimport type { Field } from '../field/types'\n\n/**\n * Constructs a Drizzle SQLiteTable from a tableName and fields.\n * Each field is converted to a Drizzle column via field.drizzleColumn(key).\n * @internal\n */\nexport function buildTable(\n tableName: string,\n fields: Record<string, Field<any, any, any>>,\n): SQLiteTable {\n const columns: Record<string, any> = {}\n for (const [key, field] of Object.entries(fields)) {\n columns[key] = field.drizzleColumn(key)\n }\n return sqliteTable(tableName, columns)\n}\n","import { type Hook, zValidator } from '@hono/zod-validator'\nimport type { Env, ValidationTargets } from 'hono'\nimport type { z } from 'zod'\nimport type { Adapter } from '../adapter/types'\nimport type { Field } from '../field/types'\nimport { toOpenAPIComponent, toOpenAPISchema } from '../openapi/generate'\nimport type { OpenAPIUsage } from '../openapi/types'\nimport { createImpl, deleteImpl, findManyImpl, findOneImpl, updateImpl } from './crud'\nimport { applySchemaOptions, buildBaseObject, derivePolicyOptions } from './schema'\nimport { buildTable } from './table'\nimport type {\n Apply,\n CreateInput,\n FieldsToZodShape,\n FindManyOptions,\n IdOrWhere,\n Model,\n RowType,\n SchemaOptions,\n} from './types'\nimport { buildFieldAccessor } from './types'\n\n/**\n * Creates a Model instance from a tableName and fields definition.\n * The model supports deriving Zod schemas, Hono validators, and CRUD operations.\n *\n * @example\n * const User = defineModel('users', {\n * id: t.uuid().primary(),\n * name: t.string(),\n * email: t.string().email(),\n * passwordHash: t.string(),\n * })\n *\n * const CreateSchema = User.schema({ omit: ['passwordHash'] })\n * const users = await User.findMany(adapter, { limit: 20 })\n */\n// biome-ignore lint/suspicious/noExplicitAny: any is necessary for generic Field constraint\nexport function defineModel<Fields extends Record<string, Field<any, any, any>>>(\n tableName: string,\n fields: Fields,\n): Model<Fields> {\n const table = buildTable(tableName, fields)\n const accessor = buildFieldAccessor(fields)\n\n return {\n fields,\n tableName,\n table,\n\n schema<Opts extends SchemaOptions<keyof Fields & string> | undefined>(\n opts?: Opts,\n ): Apply<FieldsToZodShape<Fields>, Opts> {\n const baseSchema = buildBaseObject(fields)\n const schema = applySchemaOptions(baseSchema, opts, accessor)\n // biome-ignore lint/suspicious/noExplicitAny: Zod .pick()/.omit() return type narrowing requires cast at boundary\n return schema as any\n },\n\n validator(\n target: keyof ValidationTargets,\n optsOrPreset?: 'create' | 'update' | SchemaOptions<keyof Fields & string>,\n // biome-ignore lint/suspicious/noExplicitAny: Hook<T> is contravariant in T; any is required to bridge overload implementations\n hook?: Hook<any, Env, string, keyof ValidationTargets>,\n ) {\n let schema: z.ZodTypeAny\n if (optsOrPreset === 'create' || optsOrPreset === 'update') {\n schema = this.inputSchema(optsOrPreset)\n } else {\n schema = this.schema(optsOrPreset as SchemaOptions<keyof Fields & string>)\n }\n // biome-ignore lint/suspicious/noExplicitAny: zValidator return type cast required at overload boundary\n return zValidator(target, schema, hook) as any\n },\n\n inputSchema(\n usage: 'create' | 'update',\n opts?: SchemaOptions<keyof Fields & string>,\n // biome-ignore lint/suspicious/noExplicitAny: precise return type is enforced by Model<Fields> overload signatures\n ): any {\n const merged = derivePolicyOptions(\n fields,\n usage === 'create' ? 'input-create' : 'input-update',\n opts,\n accessor,\n )\n const baseSchema = buildBaseObject(fields)\n return applySchemaOptions(baseSchema, merged)\n },\n\n outputSchema(\n opts?: SchemaOptions<keyof Fields & string>,\n // biome-ignore lint/suspicious/noExplicitAny: precise return type is enforced by Model<Fields> overload signatures\n ): any {\n const merged = derivePolicyOptions(fields, 'output', opts, accessor)\n const baseSchema = buildBaseObject(fields)\n return applySchemaOptions(baseSchema, merged)\n },\n\n toResponse(row: RowType<Fields>): unknown {\n return this.outputSchema().parse(row)\n },\n\n toOpenAPIComponent() {\n return toOpenAPIComponent(fields)\n },\n\n toOpenAPISchema(usage: OpenAPIUsage) {\n return toOpenAPISchema(fields, usage)\n },\n\n findMany(adapter: Adapter, options: FindManyOptions<Fields>): Promise<RowType<Fields>[]> {\n return findManyImpl(adapter, table, fields, options)\n },\n\n findOne(adapter: Adapter, idOrWhere: IdOrWhere<Fields>): Promise<RowType<Fields> | null> {\n return findOneImpl(adapter, table, fields, idOrWhere)\n },\n\n create(adapter: Adapter, data: CreateInput<Fields>): Promise<RowType<Fields>> {\n return createImpl(adapter, table, data)\n },\n\n update(\n adapter: Adapter,\n idOrWhere: IdOrWhere<Fields>,\n data: Partial<RowType<Fields>>,\n ): Promise<RowType<Fields> | null> {\n return updateImpl(adapter, table, fields, idOrWhere, data)\n },\n\n delete(adapter: Adapter, idOrWhere: IdOrWhere<Fields>): Promise<{ readonly deleted: number }> {\n return deleteImpl(adapter, table, fields, idOrWhere)\n },\n }\n}\n","import type { OpenAPIDocument, OpenAPIRouteMetadata, OpenAPISpecOptions } from './types'\n\nfunction honoPathToOpenAPI(path: string): string {\n return path.replace(/:([^/]+)/g, '{$1}')\n}\n\nexport function buildOpenAPIDocument(\n routes: readonly OpenAPIRouteMetadata[],\n options: OpenAPISpecOptions,\n): OpenAPIDocument {\n const paths: Record<string, Record<string, unknown>> = {}\n\n for (const route of routes) {\n const openAPIPath = honoPathToOpenAPI(route.path)\n if (!paths[openAPIPath]) {\n paths[openAPIPath] = {}\n }\n\n const operation: Record<string, unknown> = {}\n if (route.operationId) operation.operationId = route.operationId\n if (route.summary) operation.summary = route.summary\n if (route.description) operation.description = route.description\n if (route.tags) operation.tags = route.tags\n\n const parameters: unknown[] = []\n const pathParams = [...route.path.matchAll(/:([^/]+)/g)].map((m) => m[1])\n for (const param of pathParams) {\n const alreadyDefined = route.params?.some((p) => p.name === param && p.in === 'path')\n if (!alreadyDefined) {\n parameters.push({ name: param, in: 'path', required: true, schema: { type: 'string' } })\n }\n }\n if (route.params) {\n parameters.push(...route.params)\n }\n if (parameters.length > 0) operation.parameters = parameters\n\n if (route.requestBody) operation.requestBody = route.requestBody\n operation.responses = route.responses\n\n paths[openAPIPath][route.method] = operation\n }\n\n const doc: OpenAPIDocument = {\n openapi: '3.1.0',\n info: options.info,\n ...(options.servers ? { servers: options.servers } : {}),\n paths,\n }\n\n return doc\n}\n","import type { MiddlewareHandler } from 'hono'\n\nexport interface SwaggerUIOptions {\n readonly url: string\n readonly title?: string\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n}\n\nexport function swaggerUI(options: SwaggerUIOptions): MiddlewareHandler {\n const title = escapeHtml(options.title ?? 'API Documentation')\n const html = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <title>${title}</title>\n <link rel=\"stylesheet\" href=\"https://unpkg.com/swagger-ui-dist@5/swagger-ui.css\" />\n</head>\n<body>\n <div id=\"swagger-ui\"></div>\n <script src=\"https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js\"></script>\n <script>\n SwaggerUIBundle({\n url: ${JSON.stringify(options.url)},\n dom_id: '#swagger-ui',\n presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],\n layout: 'BaseLayout',\n })\n </script>\n</body>\n</html>`\n\n return async (c) => {\n return c.html(html)\n }\n}\n","import { Hono } from 'hono'\nimport type { BlankEnv, Env } from 'hono/types'\nimport type { Adapter } from '../adapter/types'\nimport type { Field } from '../field/types'\nimport { defineModel } from '../model/define'\nimport { buildOpenAPIDocument } from '../openapi/route'\nimport type { OpenAPIRouteMetadata } from '../openapi/types'\nimport type { Nanoka, NanokaModel } from './types'\n\n/**\n * Creates a Nanoka application instance with the given database adapter.\n *\n * @param adapter - The database adapter (e.g., d1Adapter(env.DB))\n * @returns A Nanoka application (Hono extended with model(), db, and batch)\n *\n * @example\n * export default {\n * fetch(req: Request, env: Env, ctx: ExecutionContext) {\n * const app = nanoka(d1Adapter(env.DB))\n * const User = app.model('users', { id, name, email, passwordHash })\n * app.get('/users', async (c) => {\n * const users = await User.findMany({ limit: 20 })\n * return c.json(users)\n * })\n * return app.fetch(req, env, ctx)\n * }\n * }\n */\nexport function nanoka<E extends Env = BlankEnv>(adapter: Adapter): Nanoka<E> {\n const app = new Hono<E>() as Nanoka<E>\n const openapiRoutes: OpenAPIRouteMetadata[] = []\n\n Object.defineProperty(app, 'db', {\n get: () => adapter.drizzle,\n enumerable: true,\n })\n\n app.batch = ((queries: Parameters<Adapter['batch']>[0]) =>\n adapter.batch(queries)) as unknown as Adapter['batch']\n\n app.openapi = (metadata: OpenAPIRouteMetadata) => {\n openapiRoutes.push(metadata)\n return app\n }\n\n app.generateOpenAPISpec = (options) => buildOpenAPIDocument(openapiRoutes, options)\n\n // biome-ignore lint/suspicious/noExplicitAny: any is necessary for Field generic constraint\n app.model = function model<Fields extends Record<string, Field<any, any, any>>>(\n name: string,\n fields: Fields,\n ): NanokaModel<Fields> {\n const inner = defineModel(name, fields)\n\n return {\n fields: inner.fields,\n tableName: inner.tableName,\n table: inner.table,\n\n schema: (opts) => inner.schema(opts),\n\n validator: (\n ...args: [\n keyof import('hono').ValidationTargets,\n ('create' | 'update' | import('../model/types').SchemaOptions<keyof Fields & string>)?,\n import('@hono/zod-validator').Hook<\n // biome-ignore lint/suspicious/noExplicitAny: Hook<T> is contravariant in T; any is required to bridge overload implementations\n any,\n import('hono').Env,\n string,\n keyof import('hono').ValidationTargets\n >?,\n ]\n ) => {\n // `NanokaModel` interface の overload 定義 (router/types.ts) で type safety は担保する。\n // 実装は inner.validator に委譲するだけで、型は interface 側の overload に従う。\n // biome-ignore lint/suspicious/noExplicitAny: NanokaModel interface overloads provide type safety\n return (inner.validator as (...a: typeof args) => any)(...args)\n },\n\n inputSchema: (usage, opts) => inner.inputSchema(usage, opts),\n\n outputSchema: (opts) => inner.outputSchema(opts),\n\n toResponse: (row) => inner.toResponse(row),\n\n toOpenAPIComponent: () => inner.toOpenAPIComponent(),\n\n toOpenAPISchema: (usage) => inner.toOpenAPISchema(usage),\n\n findMany: (options) => inner.findMany(adapter, options),\n\n findOne: (idOrWhere) => inner.findOne(adapter, idOrWhere),\n\n create: (data) => inner.create(adapter, data),\n\n update: (idOrWhere, data) => inner.update(adapter, idOrWhere, data),\n\n delete: (idOrWhere) => inner.delete(adapter, idOrWhere),\n }\n }\n\n return app\n}\n"]}
|
package/dist/turso.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Client } from '@libsql/client';
|
|
2
|
+
import { A as Adapter } from './types-D2QDVyks.js';
|
|
3
|
+
import 'drizzle-orm/batch';
|
|
4
|
+
import 'drizzle-orm/sqlite-core';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Turso/libSQL adapter factory. Wraps a libSQL Client in the generic Adapter
|
|
8
|
+
* abstraction, making it a drop-in replacement for d1Adapter.
|
|
9
|
+
*
|
|
10
|
+
* `@libsql/client` is an optional peer dependency; callers are responsible
|
|
11
|
+
* for installing it separately.
|
|
12
|
+
*/
|
|
13
|
+
declare function tursoAdapter<TSchema extends Record<string, unknown> = Record<string, never>>(client: Client): Adapter<TSchema>;
|
|
14
|
+
|
|
15
|
+
export { tursoAdapter };
|
package/dist/turso.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { drizzle } from 'drizzle-orm/libsql';
|
|
2
|
+
|
|
3
|
+
// src/adapter/turso.ts
|
|
4
|
+
function tursoAdapter(client) {
|
|
5
|
+
const db = drizzle(client);
|
|
6
|
+
return {
|
|
7
|
+
drizzle: db,
|
|
8
|
+
batch: (queries) => db.batch(queries)
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { tursoAdapter };
|
|
13
|
+
//# sourceMappingURL=turso.js.map
|
|
14
|
+
//# sourceMappingURL=turso.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapter/turso.ts"],"names":[],"mappings":";;;AAWO,SAAS,aACd,MAAA,EACkB;AAElB,EAAA,MAAM,EAAA,GAAK,QAAQ,MAAM,CAAA;AAEzB,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,EAAA;AAAA,IACT,KAAA,EAAO,CAAC,OAAA,KAAY,EAAA,CAAG,MAAM,OAAO;AAAA,GACtC;AACF","file":"turso.js","sourcesContent":["import type { Client } from '@libsql/client'\nimport { drizzle } from 'drizzle-orm/libsql'\nimport type { Adapter } from './types'\n\n/**\n * Turso/libSQL adapter factory. Wraps a libSQL Client in the generic Adapter\n * abstraction, making it a drop-in replacement for d1Adapter.\n *\n * `@libsql/client` is an optional peer dependency; callers are responsible\n * for installing it separately.\n */\nexport function tursoAdapter<TSchema extends Record<string, unknown> = Record<string, never>>(\n client: Client,\n): Adapter<TSchema> {\n // biome-ignore lint/suspicious/noExplicitAny: intentional - Drizzle returns complex union type\n const db = drizzle(client) as any\n\n return {\n drizzle: db,\n batch: (queries) => db.batch(queries),\n }\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { BatchItem, BatchResponse } from 'drizzle-orm/batch';
|
|
2
|
+
import { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generic database adapter abstraction for SQLite-compatible databases.
|
|
6
|
+
*
|
|
7
|
+
* Permits implementations over D1, Turso/libSQL, and other SQLite-compatible backends
|
|
8
|
+
* without requiring changes to core query path or router.
|
|
9
|
+
*
|
|
10
|
+
* The `drizzle` property deliberately exposes the raw Drizzle database instance,
|
|
11
|
+
* adhering to rule #4 (escape hatch always open).
|
|
12
|
+
*
|
|
13
|
+
* The `TResultKind` generic is intentionally constrained to `any` to avoid
|
|
14
|
+
* coupling adapter implementations to Drizzle's internal result kind type.
|
|
15
|
+
*/
|
|
16
|
+
interface Adapter<TSchema extends Record<string, unknown> = Record<string, never>> {
|
|
17
|
+
readonly drizzle: BaseSQLiteDatabase<'async', any, TSchema>;
|
|
18
|
+
/**
|
|
19
|
+
* Executes multiple Drizzle queries in a single batch.
|
|
20
|
+
* Returns results in the same order as the input.
|
|
21
|
+
*
|
|
22
|
+
* **重要**: 実装は `this` 非依存であること(`nanoka()` 内で thin wrapper として再公開されるため、
|
|
23
|
+
* `this` バインディングが失われた状態で呼び出される可能性がある)。
|
|
24
|
+
*/
|
|
25
|
+
batch<U extends BatchItem<'sqlite'>, T extends readonly [U, ...U[]]>(queries: T): Promise<BatchResponse<T>>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type { Adapter as A };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nanokajs/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Thin wrapper over Hono + Drizzle + Zod for Cloudflare Workers + D1. 80% automatic, 20% explicit.",
|
|
6
6
|
"author": "Eiichiro Iriguchi <eiichiro_iriguchi@a-1ro.dev>",
|
|
@@ -31,6 +31,10 @@
|
|
|
31
31
|
"types": "./dist/index.d.ts",
|
|
32
32
|
"import": "./dist/index.js"
|
|
33
33
|
},
|
|
34
|
+
"./turso": {
|
|
35
|
+
"types": "./dist/turso.d.ts",
|
|
36
|
+
"import": "./dist/turso.js"
|
|
37
|
+
},
|
|
34
38
|
"./config": {
|
|
35
39
|
"types": "./dist/config.d.ts",
|
|
36
40
|
"import": "./dist/config.js"
|
|
@@ -59,10 +63,16 @@
|
|
|
59
63
|
},
|
|
60
64
|
"peerDependencies": {
|
|
61
65
|
"@cloudflare/workers-types": "^4.20240925.0",
|
|
66
|
+
"@libsql/client": "^0.14.0",
|
|
62
67
|
"drizzle-orm": "^0.45.2",
|
|
63
68
|
"hono": "^4.0.0",
|
|
64
69
|
"zod": "^3.23.0 || ^4.0.0"
|
|
65
70
|
},
|
|
71
|
+
"peerDependenciesMeta": {
|
|
72
|
+
"@libsql/client": {
|
|
73
|
+
"optional": true
|
|
74
|
+
}
|
|
75
|
+
},
|
|
66
76
|
"dependencies": {
|
|
67
77
|
"@hono/zod-validator": "^0.4.0",
|
|
68
78
|
"jiti": "^2.6.1"
|
|
@@ -70,6 +80,7 @@
|
|
|
70
80
|
"devDependencies": {
|
|
71
81
|
"@cloudflare/vitest-pool-workers": "^0.5.0",
|
|
72
82
|
"@cloudflare/workers-types": "^4.20240925.0",
|
|
83
|
+
"@libsql/client": "^0.14.0",
|
|
73
84
|
"@types/node": "^25.6.0",
|
|
74
85
|
"drizzle-orm": "^0.45.2",
|
|
75
86
|
"hono": "^4.0.0",
|