@ontrails/store 1.0.0-beta.14
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/.agents/notes/2026-04-04/handoff-202604032309-9e85a104.md +38 -0
- package/.turbo/turbo-build.log +1 -0
- package/.turbo/turbo-lint.log +3 -0
- package/.turbo/turbo-typecheck.log +1 -0
- package/CHANGELOG.md +12 -0
- package/README.md +213 -0
- package/dist/drizzle/index.d.ts +3 -0
- package/dist/drizzle/index.d.ts.map +1 -0
- package/dist/drizzle/index.js +2 -0
- package/dist/drizzle/index.js.map +1 -0
- package/dist/drizzle/runtime.d.ts +21 -0
- package/dist/drizzle/runtime.d.ts.map +1 -0
- package/dist/drizzle/runtime.js +458 -0
- package/dist/drizzle/runtime.js.map +1 -0
- package/dist/drizzle/schema.d.ts +15 -0
- package/dist/drizzle/schema.d.ts.map +1 -0
- package/dist/drizzle/schema.js +322 -0
- package/dist/drizzle/schema.js.map +1 -0
- package/dist/drizzle/types.d.ts +40 -0
- package/dist/drizzle/types.d.ts.map +1 -0
- package/dist/drizzle/types.js +2 -0
- package/dist/drizzle/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/store.d.ts +26 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +192 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +224 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +29 -0
- package/src/__tests__/store.test.ts +333 -0
- package/src/drizzle/__tests__/drizzle.test.ts +469 -0
- package/src/drizzle/index.ts +17 -0
- package/src/drizzle/runtime.ts +853 -0
- package/src/drizzle/schema.ts +577 -0
- package/src/drizzle/types.ts +70 -0
- package/src/index.ts +39 -0
- package/src/store.ts +367 -0
- package/src/types.ts +361 -0
- package/tsconfig.json +9 -0
- package/tsconfig.tsbuildinfo +1 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Object schema accepted by the store definition layer.
|
|
5
|
+
*/
|
|
6
|
+
export type StoreObjectSchema = z.ZodObject<Record<string, z.ZodType>>;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* String field names available on a store-backed entity schema.
|
|
10
|
+
*/
|
|
11
|
+
export type StoreFieldKey<TSchema extends StoreObjectSchema> = Extract<
|
|
12
|
+
keyof z.output<TSchema>,
|
|
13
|
+
string
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
type GeneratedFieldNames<
|
|
17
|
+
TSchema extends StoreObjectSchema,
|
|
18
|
+
TGenerated extends readonly StoreFieldKey<TSchema>[] | undefined,
|
|
19
|
+
> = TGenerated extends readonly StoreFieldKey<TSchema>[]
|
|
20
|
+
? TGenerated[number]
|
|
21
|
+
: never;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Seed row accepted for one table fixture.
|
|
25
|
+
*
|
|
26
|
+
* Generated fields may be supplied explicitly, but they are optional so test
|
|
27
|
+
* fixtures can omit timestamps and similar server-managed values when the mock
|
|
28
|
+
* store can synthesize them.
|
|
29
|
+
*/
|
|
30
|
+
export type StoreFixtureInput<
|
|
31
|
+
TSchema extends StoreObjectSchema,
|
|
32
|
+
TGenerated extends readonly StoreFieldKey<TSchema>[] | undefined =
|
|
33
|
+
| readonly StoreFieldKey<TSchema>[]
|
|
34
|
+
| undefined,
|
|
35
|
+
> = Omit<
|
|
36
|
+
z.input<TSchema>,
|
|
37
|
+
Extract<GeneratedFieldNames<TSchema, TGenerated>, keyof z.input<TSchema>>
|
|
38
|
+
> &
|
|
39
|
+
Partial<
|
|
40
|
+
Pick<
|
|
41
|
+
z.input<TSchema>,
|
|
42
|
+
Extract<GeneratedFieldNames<TSchema, TGenerated>, keyof z.input<TSchema>>
|
|
43
|
+
>
|
|
44
|
+
>;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Normalized fixture row after schema validation and default application.
|
|
48
|
+
*/
|
|
49
|
+
export type StoreFixtureRow<
|
|
50
|
+
TSchema extends StoreObjectSchema,
|
|
51
|
+
TGenerated extends readonly StoreFieldKey<TSchema>[] | undefined =
|
|
52
|
+
| readonly StoreFieldKey<TSchema>[]
|
|
53
|
+
| undefined,
|
|
54
|
+
> = Omit<
|
|
55
|
+
z.output<TSchema>,
|
|
56
|
+
Extract<GeneratedFieldNames<TSchema, TGenerated>, keyof z.output<TSchema>>
|
|
57
|
+
> &
|
|
58
|
+
Partial<
|
|
59
|
+
Pick<
|
|
60
|
+
z.output<TSchema>,
|
|
61
|
+
Extract<GeneratedFieldNames<TSchema, TGenerated>, keyof z.output<TSchema>>
|
|
62
|
+
>
|
|
63
|
+
>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Connector-owned search metadata.
|
|
67
|
+
*
|
|
68
|
+
* The core package keeps this opaque on purpose. Search behavior is declared
|
|
69
|
+
* here and interpreted by a concrete connector later.
|
|
70
|
+
*/
|
|
71
|
+
export type StoreSearchDefinition = Readonly<Record<string, unknown>>;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Authored metadata for one store table.
|
|
75
|
+
*/
|
|
76
|
+
export interface StoreTableInput<
|
|
77
|
+
TSchema extends StoreObjectSchema = StoreObjectSchema,
|
|
78
|
+
TGenerated extends readonly StoreFieldKey<TSchema>[] | undefined =
|
|
79
|
+
| readonly StoreFieldKey<TSchema>[]
|
|
80
|
+
| undefined,
|
|
81
|
+
> {
|
|
82
|
+
readonly fixtures?: readonly StoreFixtureInput<TSchema, TGenerated>[];
|
|
83
|
+
readonly generated?: TGenerated;
|
|
84
|
+
readonly indexes?: readonly StoreFieldKey<TSchema>[];
|
|
85
|
+
readonly primaryKey: StoreFieldKey<TSchema>;
|
|
86
|
+
readonly references?: Readonly<
|
|
87
|
+
Partial<Record<StoreFieldKey<TSchema>, string>>
|
|
88
|
+
>;
|
|
89
|
+
readonly schema: TSchema;
|
|
90
|
+
readonly search?: StoreSearchDefinition;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Record of authored tables passed to `store(...)`.
|
|
95
|
+
*/
|
|
96
|
+
export type StoreTablesInput = Record<
|
|
97
|
+
string,
|
|
98
|
+
StoreTableInput<
|
|
99
|
+
StoreObjectSchema,
|
|
100
|
+
readonly StoreFieldKey<StoreObjectSchema>[] | undefined
|
|
101
|
+
>
|
|
102
|
+
>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Preserve generated fields when present, otherwise normalize to an empty tuple.
|
|
106
|
+
*/
|
|
107
|
+
export type GeneratedFieldsOfInput<TInput extends StoreTableInput> =
|
|
108
|
+
TInput['generated'] extends readonly StoreFieldKey<TInput['schema']>[]
|
|
109
|
+
? TInput['generated']
|
|
110
|
+
: readonly [];
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Preserve index fields when present, otherwise normalize to an empty tuple.
|
|
114
|
+
*/
|
|
115
|
+
export type IndexFieldsOfInput<TInput extends StoreTableInput> =
|
|
116
|
+
TInput['indexes'] extends readonly StoreFieldKey<TInput['schema']>[]
|
|
117
|
+
? TInput['indexes']
|
|
118
|
+
: readonly [];
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Preserve references when present, otherwise normalize to an empty object.
|
|
122
|
+
*/
|
|
123
|
+
export type ReferencesOfInput<TInput extends StoreTableInput> =
|
|
124
|
+
TInput['references'] extends Readonly<
|
|
125
|
+
Partial<Record<StoreFieldKey<TInput['schema']>, string>>
|
|
126
|
+
>
|
|
127
|
+
? TInput['references']
|
|
128
|
+
: Readonly<Record<never, never>>;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Preserve fixtures when present, otherwise normalize to an empty tuple.
|
|
132
|
+
*/
|
|
133
|
+
export type FixturesOfInput<TInput extends StoreTableInput> =
|
|
134
|
+
TInput['fixtures'] extends readonly StoreFixtureInput<
|
|
135
|
+
TInput['schema'],
|
|
136
|
+
GeneratedFieldsOfInput<TInput>
|
|
137
|
+
>[]
|
|
138
|
+
? readonly StoreFixtureRow<
|
|
139
|
+
TInput['schema'],
|
|
140
|
+
GeneratedFieldsOfInput<TInput>
|
|
141
|
+
>[]
|
|
142
|
+
: readonly [];
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Generated store table contract derived from authored metadata.
|
|
146
|
+
*/
|
|
147
|
+
export interface StoreTable<
|
|
148
|
+
TInput extends StoreTableInput = StoreTableInput,
|
|
149
|
+
TName extends string = string,
|
|
150
|
+
> {
|
|
151
|
+
readonly fixtureSchema: StoreObjectSchema;
|
|
152
|
+
readonly fixtures: FixturesOfInput<TInput>;
|
|
153
|
+
readonly generated: GeneratedFieldsOfInput<TInput>;
|
|
154
|
+
readonly indexes: IndexFieldsOfInput<TInput>;
|
|
155
|
+
readonly insertSchema: StoreObjectSchema;
|
|
156
|
+
readonly name: TName;
|
|
157
|
+
readonly primaryKey: TInput['primaryKey'];
|
|
158
|
+
readonly references: ReferencesOfInput<TInput>;
|
|
159
|
+
readonly schema: TInput['schema'];
|
|
160
|
+
readonly search?: TInput['search'];
|
|
161
|
+
readonly updateSchema: StoreObjectSchema;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Full store definition returned by `store(...)`.
|
|
166
|
+
*/
|
|
167
|
+
export interface StoreDefinition<
|
|
168
|
+
TTables extends StoreTablesInput = StoreTablesInput,
|
|
169
|
+
> {
|
|
170
|
+
readonly get: <TName extends Extract<keyof TTables, string>>(
|
|
171
|
+
name: TName
|
|
172
|
+
) => StoreTable<TTables[TName], TName>;
|
|
173
|
+
readonly kind: 'store';
|
|
174
|
+
readonly tableNames: readonly Extract<keyof TTables, string>[];
|
|
175
|
+
readonly tables: {
|
|
176
|
+
readonly [TName in keyof TTables]: StoreTable<
|
|
177
|
+
TTables[TName],
|
|
178
|
+
Extract<TName, string>
|
|
179
|
+
>;
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Structural view of any normalized store table.
|
|
185
|
+
*
|
|
186
|
+
* This stays broad on purpose so connector packages can accept concrete store
|
|
187
|
+
* definitions returned by `store(...)` without erasing their table-specific
|
|
188
|
+
* types back to one canonical generic instantiation.
|
|
189
|
+
*/
|
|
190
|
+
export interface AnyStoreTable {
|
|
191
|
+
readonly fixtureSchema: StoreObjectSchema;
|
|
192
|
+
readonly fixtures: readonly Record<string, unknown>[];
|
|
193
|
+
readonly generated: readonly string[];
|
|
194
|
+
readonly indexes: readonly string[];
|
|
195
|
+
readonly insertSchema: StoreObjectSchema;
|
|
196
|
+
readonly name: string;
|
|
197
|
+
readonly primaryKey: string;
|
|
198
|
+
readonly references: Readonly<Partial<Record<string, string>>>;
|
|
199
|
+
readonly schema: StoreObjectSchema;
|
|
200
|
+
readonly search?: StoreSearchDefinition | undefined;
|
|
201
|
+
readonly updateSchema: StoreObjectSchema;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Structural view of any normalized store definition.
|
|
206
|
+
*/
|
|
207
|
+
export interface AnyStoreDefinition {
|
|
208
|
+
readonly kind: 'store';
|
|
209
|
+
readonly tableNames: readonly string[];
|
|
210
|
+
readonly tables: Readonly<Record<string, AnyStoreTable>>;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
type GeneratedFieldKeysOf<TTable extends AnyStoreTable> = readonly Extract<
|
|
214
|
+
TTable['generated'][number],
|
|
215
|
+
StoreFieldKey<TTable['schema']>
|
|
216
|
+
>[];
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Full entity type represented by one store table.
|
|
220
|
+
*/
|
|
221
|
+
export type EntityOf<TTable extends AnyStoreTable> = z.output<TTable['schema']>;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Fixture seed input accepted for one table.
|
|
225
|
+
*/
|
|
226
|
+
export type FixtureInputOf<TTable extends AnyStoreTable> = StoreFixtureInput<
|
|
227
|
+
TTable['schema'],
|
|
228
|
+
GeneratedFieldKeysOf<TTable>
|
|
229
|
+
>;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Normalized fixture row available on one table.
|
|
233
|
+
*/
|
|
234
|
+
export type FixtureOf<TTable extends AnyStoreTable> = StoreFixtureRow<
|
|
235
|
+
TTable['schema'],
|
|
236
|
+
GeneratedFieldKeysOf<TTable>
|
|
237
|
+
>;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Primary-key field name for one store table.
|
|
241
|
+
*/
|
|
242
|
+
export type PrimaryKeyOf<TTable extends AnyStoreTable> = TTable['primaryKey'];
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Server-managed fields for one store table.
|
|
246
|
+
*/
|
|
247
|
+
export type GeneratedKeysOf<TTable extends AnyStoreTable> = Extract<
|
|
248
|
+
TTable['generated'][number],
|
|
249
|
+
StoreFieldKey<TTable['schema']>
|
|
250
|
+
>;
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Insert shape: entity minus generated fields, with defaulted fields optional.
|
|
254
|
+
*
|
|
255
|
+
* Uses `z.input` so that fields with `.default()` are correctly represented as
|
|
256
|
+
* optional in the insert shape (matching the runtime insert schema behavior).
|
|
257
|
+
*/
|
|
258
|
+
export type InsertOf<TTable extends AnyStoreTable> = Omit<
|
|
259
|
+
z.input<TTable['schema']>,
|
|
260
|
+
GeneratedKeysOf<TTable>
|
|
261
|
+
>;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Update shape: partial insert minus the primary key (immutable identifier).
|
|
265
|
+
*/
|
|
266
|
+
export type UpdateOf<TTable extends AnyStoreTable> = Partial<
|
|
267
|
+
Omit<InsertOf<TTable>, PrimaryKeyOf<TTable>>
|
|
268
|
+
>;
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Typed filter shape for list operations.
|
|
272
|
+
*/
|
|
273
|
+
export type FiltersOf<TTable extends AnyStoreTable> = Partial<EntityOf<TTable>>;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Common pagination controls for store list operations.
|
|
277
|
+
*/
|
|
278
|
+
export interface StoreListOptions {
|
|
279
|
+
readonly limit?: number;
|
|
280
|
+
readonly offset?: number;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Shared identifier type for read/write accessors.
|
|
285
|
+
*/
|
|
286
|
+
export type StoreIdentifierOf<TTable extends AnyStoreTable> =
|
|
287
|
+
EntityOf<TTable>[Extract<PrimaryKeyOf<TTable>, keyof EntityOf<TTable>>];
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Access mode for a bound store connection or provision.
|
|
291
|
+
*/
|
|
292
|
+
export type StoreAccessMode = 'readonly' | 'readwrite';
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Read-only table operations that every bound store must expose.
|
|
296
|
+
*/
|
|
297
|
+
export interface ReadOnlyStoreTableAccessor<TTable extends AnyStoreTable> {
|
|
298
|
+
/** Retrieve a single entity by primary key. Returns `null` when not found. */
|
|
299
|
+
get(id: StoreIdentifierOf<TTable>): Promise<EntityOf<TTable> | null>;
|
|
300
|
+
/**
|
|
301
|
+
* List entities, optionally filtered. Returns all rows when no filters are
|
|
302
|
+
* provided. Returns an empty array when no rows match.
|
|
303
|
+
*/
|
|
304
|
+
list(
|
|
305
|
+
filters?: FiltersOf<TTable>,
|
|
306
|
+
options?: StoreListOptions
|
|
307
|
+
): Promise<readonly EntityOf<TTable>[]>;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Writable table operations layered on top of the read contract.
|
|
312
|
+
*/
|
|
313
|
+
export interface StoreTableAccessor<
|
|
314
|
+
TTable extends AnyStoreTable,
|
|
315
|
+
> extends ReadOnlyStoreTableAccessor<TTable> {
|
|
316
|
+
/**
|
|
317
|
+
* Insert a new entity.
|
|
318
|
+
*
|
|
319
|
+
* @throws {AlreadyExistsError} On primary key or unique constraint violation.
|
|
320
|
+
*
|
|
321
|
+
* @remarks
|
|
322
|
+
* This is an intentional throw-based boundary: store connectors throw typed
|
|
323
|
+
* errors (`AlreadyExistsError`) rather than returning `Result`. Trail
|
|
324
|
+
* implementations that call store accessors should catch and convert to
|
|
325
|
+
* `Result.err()` at their level. A future `safeInsert` returning `Result`
|
|
326
|
+
* is planned but deferred to avoid cascading changes across all connectors.
|
|
327
|
+
*/
|
|
328
|
+
insert(input: InsertOf<TTable>): Promise<EntityOf<TTable>>;
|
|
329
|
+
/**
|
|
330
|
+
* Remove an entity by primary key. Returns `{ deleted: true }` when the
|
|
331
|
+
* row was found and removed, `{ deleted: false }` when no matching row
|
|
332
|
+
* existed (not an error).
|
|
333
|
+
*/
|
|
334
|
+
remove(id: StoreIdentifierOf<TTable>): Promise<{ readonly deleted: boolean }>;
|
|
335
|
+
/**
|
|
336
|
+
* Patch an entity by primary key with partial fields. Returns the updated
|
|
337
|
+
* entity, or `null` when no row with that ID exists.
|
|
338
|
+
*/
|
|
339
|
+
update(
|
|
340
|
+
id: StoreIdentifierOf<TTable>,
|
|
341
|
+
input: UpdateOf<TTable>
|
|
342
|
+
): Promise<EntityOf<TTable> | null>;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Connection shape exposed by a read-only bound store.
|
|
347
|
+
*/
|
|
348
|
+
export type ReadOnlyStoreConnection<TStore extends AnyStoreDefinition> = {
|
|
349
|
+
readonly [TName in keyof TStore['tables']]: ReadOnlyStoreTableAccessor<
|
|
350
|
+
TStore['tables'][TName]
|
|
351
|
+
>;
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Connection shape exposed by a writable bound store.
|
|
356
|
+
*/
|
|
357
|
+
export type StoreConnection<TStore extends AnyStoreDefinition> = {
|
|
358
|
+
readonly [TName in keyof TStore['tables']]: StoreTableAccessor<
|
|
359
|
+
TStore['tables'][TName]
|
|
360
|
+
>;
|
|
361
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/index.ts","./src/store.ts","./src/types.ts","./src/drizzle/index.ts","./src/drizzle/runtime.ts","./src/drizzle/schema.ts","./src/drizzle/types.ts"],"version":"5.9.3"}
|