cloesce 0.0.4-unstable.0 → 0.0.4-unstable.10
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/README.md → README.md} +212 -67
- package/dist/cli.js +37 -21
- package/dist/common.d.ts +89 -41
- package/dist/common.d.ts.map +1 -1
- package/dist/common.js +93 -38
- package/dist/extractor/extract.d.ts +9 -9
- package/dist/extractor/extract.d.ts.map +1 -1
- package/dist/extractor/extract.js +128 -149
- package/dist/generator.wasm +0 -0
- package/dist/orm.wasm +0 -0
- package/dist/router/crud.d.ts.map +1 -1
- package/dist/router/crud.js +25 -20
- package/dist/router/router.d.ts +71 -15
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/router.js +190 -109
- package/dist/router/wasm.d.ts +10 -3
- package/dist/router/wasm.d.ts.map +1 -1
- package/dist/router/wasm.js +12 -6
- package/dist/ui/backend.d.ts +431 -41
- package/dist/ui/backend.d.ts.map +1 -1
- package/dist/ui/backend.js +391 -90
- package/dist/ui/client.d.ts +2 -1
- package/dist/ui/client.d.ts.map +1 -1
- package/dist/ui/client.js +1 -0
- package/package.json +2 -2
package/dist/router/wasm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Either } from "../common.js";
|
|
2
2
|
import { RuntimeContainer } from "./router.js";
|
|
3
3
|
// Requires the ORM binary to have been built
|
|
4
4
|
import mod from "../orm.wasm";
|
|
@@ -41,6 +41,12 @@ export async function loadOrmWasm(ast, wasm) {
|
|
|
41
41
|
// Intentionally leak `modelMeta`, it should exist for the programs lifetime.
|
|
42
42
|
return wasmInstance.exports;
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Invokes a WASM ORM function with the provided arguments, handling memory
|
|
46
|
+
* allocation and deallocation.
|
|
47
|
+
*
|
|
48
|
+
* Returns an Either where Left is an error message and Right the raw string result.
|
|
49
|
+
*/
|
|
44
50
|
export function invokeOrmWasm(fn, args, wasm) {
|
|
45
51
|
let resPtr;
|
|
46
52
|
let resLen;
|
|
@@ -49,7 +55,7 @@ export function invokeOrmWasm(fn, args, wasm) {
|
|
|
49
55
|
resPtr = wasm.get_return_ptr();
|
|
50
56
|
resLen = wasm.get_return_len();
|
|
51
57
|
const result = new TextDecoder().decode(new Uint8Array(wasm.memory.buffer, resPtr, resLen));
|
|
52
|
-
return failed ? left(result) : right(result);
|
|
58
|
+
return failed ? Either.left(result) : Either.right(result);
|
|
53
59
|
}
|
|
54
60
|
finally {
|
|
55
61
|
args.forEach((a) => a.free());
|
|
@@ -61,18 +67,18 @@ export function invokeOrmWasm(fn, args, wasm) {
|
|
|
61
67
|
* Calls `object_relational_mapping` to turn a row of SQL records into
|
|
62
68
|
* an instantiated object.
|
|
63
69
|
*/
|
|
64
|
-
export function
|
|
70
|
+
export function mapSql(ctor, records, includeTree) {
|
|
65
71
|
const { ast, constructorRegistry, wasm } = RuntimeContainer.get();
|
|
66
72
|
const args = [
|
|
67
73
|
WasmResource.fromString(ctor.name, wasm),
|
|
68
74
|
WasmResource.fromString(JSON.stringify(records), wasm),
|
|
69
75
|
WasmResource.fromString(JSON.stringify(includeTree), wasm),
|
|
70
76
|
];
|
|
71
|
-
const jsonResults = invokeOrmWasm(wasm.
|
|
72
|
-
if (
|
|
77
|
+
const jsonResults = invokeOrmWasm(wasm.map_sql, args, wasm);
|
|
78
|
+
if (jsonResults.isLeft())
|
|
73
79
|
return jsonResults;
|
|
74
80
|
const parsed = JSON.parse(jsonResults.value);
|
|
75
|
-
return right(parsed.map((obj) => instantiateDepthFirst(obj, ast.models[ctor.name], includeTree)));
|
|
81
|
+
return Either.right(parsed.map((obj) => instantiateDepthFirst(obj, ast.models[ctor.name], includeTree)));
|
|
76
82
|
function instantiateDepthFirst(m, meta, includeTree) {
|
|
77
83
|
m = Object.assign(new constructorRegistry[meta.name](), m);
|
|
78
84
|
if (!includeTree) {
|
package/dist/ui/backend.d.ts
CHANGED
|
@@ -1,31 +1,345 @@
|
|
|
1
1
|
import { D1Database } from "@cloudflare/workers-types/experimental/index.js";
|
|
2
|
-
import { CrudKind, Either, KeysOfType } from "../common.js";
|
|
3
|
-
export {
|
|
4
|
-
export type {
|
|
5
|
-
export {
|
|
2
|
+
import { CrudKind, DeepPartial, Either, KeysOfType } from "../common.js";
|
|
3
|
+
export { CloesceApp, DependencyInjector } from "../router/router.js";
|
|
4
|
+
export type { MiddlewareFn, ResultMiddlewareFn } from "../router/router.js";
|
|
5
|
+
export { HttpResult, Either } from "../common.js";
|
|
6
|
+
export type { DeepPartial, CrudKind } from "../common.js";
|
|
7
|
+
/**
|
|
8
|
+
* Marks a class as a D1-backed SQL model.
|
|
9
|
+
*
|
|
10
|
+
* Classes annotated with `@D1` are compiled into:
|
|
11
|
+
* - a D1 table definition (via `cloesce migrate`)
|
|
12
|
+
* - backend API endpoints (Workers)
|
|
13
|
+
* - a frontend client API
|
|
14
|
+
* - Cloudflare Wrangler configurations
|
|
15
|
+
*
|
|
16
|
+
* Each `@D1` class must define exactly one `@PrimaryKey`.
|
|
17
|
+
*
|
|
18
|
+
* Example:
|
|
19
|
+
*```ts
|
|
20
|
+
* @D1
|
|
21
|
+
* export class Horse {
|
|
22
|
+
* @PrimaryKey id: number;
|
|
23
|
+
* name: string;
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
6
27
|
export declare const D1: ClassDecorator;
|
|
28
|
+
/**
|
|
29
|
+
* Marks a class as a plain serializable object.
|
|
30
|
+
*
|
|
31
|
+
* `@PlainOldObject` types represent data that can be safely
|
|
32
|
+
* returned from a model method or API endpoint without being
|
|
33
|
+
* treated as a database model.
|
|
34
|
+
*
|
|
35
|
+
* Example:
|
|
36
|
+
* ```ts
|
|
37
|
+
* @PlainOldObject
|
|
38
|
+
* export class CatStuff {
|
|
39
|
+
* catFacts: string[];
|
|
40
|
+
* catNames: string[];
|
|
41
|
+
* }
|
|
42
|
+
*
|
|
43
|
+
* // in a method...
|
|
44
|
+
* foo(): CatStuff {
|
|
45
|
+
* return {
|
|
46
|
+
* catFacts: ["cats sleep 16 hours a day"],
|
|
47
|
+
* catNames: ["Whiskers", "Fluffy"]
|
|
48
|
+
* };
|
|
49
|
+
*
|
|
50
|
+
* // which generates an API like:
|
|
51
|
+
* async function foo(): Promise<HttpResult<CatStuff>> { ... }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
7
54
|
export declare const PlainOldObject: ClassDecorator;
|
|
55
|
+
/**
|
|
56
|
+
* Declares a Wrangler environment definition.
|
|
57
|
+
*
|
|
58
|
+
* A `@WranglerEnv` class describes environment bindings
|
|
59
|
+
* available to your Cloudflare Worker at runtime.
|
|
60
|
+
*
|
|
61
|
+
* The environment instance is automatically injected into
|
|
62
|
+
* decorated methods using `@Inject`.
|
|
63
|
+
*
|
|
64
|
+
* Example:
|
|
65
|
+
* ```ts
|
|
66
|
+
* @WranglerEnv
|
|
67
|
+
* export class Env {
|
|
68
|
+
* db: D1Database;
|
|
69
|
+
* motd: string;
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* // in a method...
|
|
73
|
+
* foo(@Inject env: WranglerEnv) {...}
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
8
76
|
export declare const WranglerEnv: ClassDecorator;
|
|
77
|
+
/**
|
|
78
|
+
* Marks a property as the SQL primary key for a model.
|
|
79
|
+
*
|
|
80
|
+
* Every `@D1` class must define exactly one primary key.
|
|
81
|
+
*
|
|
82
|
+
* Cannot be null.
|
|
83
|
+
*
|
|
84
|
+
* Example:
|
|
85
|
+
* ```ts
|
|
86
|
+
* @D1
|
|
87
|
+
* export class User {
|
|
88
|
+
* @PrimaryKey id: number;
|
|
89
|
+
* name: string;
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
9
93
|
export declare const PrimaryKey: PropertyDecorator;
|
|
94
|
+
/**
|
|
95
|
+
* Exposes a class method as an HTTP GET endpoint.
|
|
96
|
+
* The method will appear in both backend and generated client APIs.
|
|
97
|
+
*/
|
|
10
98
|
export declare const GET: MethodDecorator;
|
|
99
|
+
/**
|
|
100
|
+
* Exposes a class method as an HTTP POST endpoint.
|
|
101
|
+
* The method will appear in both backend and generated client APIs.
|
|
102
|
+
*/
|
|
11
103
|
export declare const POST: MethodDecorator;
|
|
104
|
+
/**
|
|
105
|
+
* Exposes a class method as an HTTP PUT endpoint.
|
|
106
|
+
* The method will appear in both backend and generated client APIs.
|
|
107
|
+
*/
|
|
12
108
|
export declare const PUT: MethodDecorator;
|
|
109
|
+
/**
|
|
110
|
+
* Exposes a class method as an HTTP PATCH endpoint.
|
|
111
|
+
* The method will appear in both backend and generated client APIs.
|
|
112
|
+
*/
|
|
13
113
|
export declare const PATCH: MethodDecorator;
|
|
114
|
+
/**
|
|
115
|
+
* Exposes a class method as an HTTP DEL endpoint.
|
|
116
|
+
* The method will appear in both backend and generated client APIs.
|
|
117
|
+
*/
|
|
14
118
|
export declare const DELETE: MethodDecorator;
|
|
119
|
+
/**
|
|
120
|
+
* Declares a static property as a data source.
|
|
121
|
+
*
|
|
122
|
+
* Data sources describe SQL left joins related to each
|
|
123
|
+
* models navigation properties.
|
|
124
|
+
*
|
|
125
|
+
* Example:
|
|
126
|
+
* ```ts
|
|
127
|
+
* @D1
|
|
128
|
+
* export class Dog {
|
|
129
|
+
* @PrimaryKey
|
|
130
|
+
* id: number;
|
|
131
|
+
*
|
|
132
|
+
* name: string;
|
|
133
|
+
* }
|
|
134
|
+
*
|
|
135
|
+
* @D1
|
|
136
|
+
* export class Person {
|
|
137
|
+
* @PrimaryKey
|
|
138
|
+
* id: number;
|
|
139
|
+
*
|
|
140
|
+
* @ForeignKey(Dog)
|
|
141
|
+
* dogId: number;
|
|
142
|
+
*
|
|
143
|
+
* @OneToOne("dogId")
|
|
144
|
+
* dog: Dog | undefined;
|
|
145
|
+
*
|
|
146
|
+
* @DataSource
|
|
147
|
+
* static readonly default: IncludeTree<Person> = {
|
|
148
|
+
* dog: {}, // join Dog table when querying Person with `default` data source
|
|
149
|
+
* };
|
|
150
|
+
* }
|
|
151
|
+
*
|
|
152
|
+
* // When queried via the ORM or client API:
|
|
153
|
+
* const orm = Orm.fromD1(env.db);
|
|
154
|
+
* const people = await orm.list(Person, Person.default);
|
|
155
|
+
*
|
|
156
|
+
* // => Person { id: 1, dogId: 2, dog: { id: 2, name: "Fido" } }[]
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
15
159
|
export declare const DataSource: PropertyDecorator;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
160
|
+
/**
|
|
161
|
+
* Declares a one-to-many relationship between models.
|
|
162
|
+
*
|
|
163
|
+
* The argument is the foreign key property name on the
|
|
164
|
+
* related model.
|
|
165
|
+
*
|
|
166
|
+
* Example:
|
|
167
|
+
* ```ts
|
|
168
|
+
* @OneToMany("personId")
|
|
169
|
+
* dogs: Dog[];
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
export declare const OneToMany: (_foreignKeyColumn: string) => PropertyDecorator;
|
|
173
|
+
/**
|
|
174
|
+
* Declares a one-to-one relationship between models.
|
|
175
|
+
*
|
|
176
|
+
* The argument is the foreign key property name that links
|
|
177
|
+
* the two tables.
|
|
178
|
+
*
|
|
179
|
+
* Example:
|
|
180
|
+
* ```ts
|
|
181
|
+
* @OneToOne("dogId")
|
|
182
|
+
* dog: Dog | undefined;
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
export declare const OneToOne: (_foreignKeyColumn: string) => PropertyDecorator;
|
|
186
|
+
/**
|
|
187
|
+
* Declares a many-to-many relationship between models.
|
|
188
|
+
*
|
|
189
|
+
* The argument is a unique identifier for the generated
|
|
190
|
+
* junction table used to connect the two entities.
|
|
191
|
+
*
|
|
192
|
+
* Example:
|
|
193
|
+
* ```ts
|
|
194
|
+
* @ManyToMany("StudentsCourses")
|
|
195
|
+
* courses: Course[];
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
export declare const ManyToMany: (_uniqueId: string) => PropertyDecorator;
|
|
199
|
+
/**
|
|
200
|
+
* Declares a foreign key relationship between models.
|
|
201
|
+
* Directly translates to a SQLite foreign key.
|
|
202
|
+
*
|
|
203
|
+
* The argument must reference either a model class or the
|
|
204
|
+
* name of a model class as a string. The property type must
|
|
205
|
+
* match the target model’s primary key type.
|
|
206
|
+
*
|
|
207
|
+
* Example:
|
|
208
|
+
* ```ts
|
|
209
|
+
* @ForeignKey(Dog)
|
|
210
|
+
* dogId: number;
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
export declare const ForeignKey: <T>(_Model: T | string) => PropertyDecorator;
|
|
214
|
+
/**
|
|
215
|
+
* Marks a method parameter for dependency injection.
|
|
216
|
+
*
|
|
217
|
+
* Injected parameters can receive environment bindings,
|
|
218
|
+
* middleware-provided objects, or other registered values.
|
|
219
|
+
*
|
|
220
|
+
* Note that injected parameters will not appear in the client
|
|
221
|
+
* API.
|
|
222
|
+
*
|
|
223
|
+
* Example:
|
|
224
|
+
* ```ts
|
|
225
|
+
* @POST
|
|
226
|
+
* async neigh(@Inject env: WranglerEnv) {
|
|
227
|
+
* return `i am ${this.name}`;
|
|
228
|
+
* }
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
20
231
|
export declare const Inject: ParameterDecorator;
|
|
232
|
+
/**
|
|
233
|
+
* Enables automatic CRUD method generation for a model.
|
|
234
|
+
*
|
|
235
|
+
* The argument is a list of CRUD operation kinds
|
|
236
|
+
* (e.g. `"SAVE"`, `"GET"`, `"LIST"`) to generate for the model.
|
|
237
|
+
*
|
|
238
|
+
* Cloesce will emit corresponding backend methods and frontend
|
|
239
|
+
* client bindings automatically, removing the need to manually
|
|
240
|
+
* define common API operations.
|
|
241
|
+
*
|
|
242
|
+
* CRUD Operations:
|
|
243
|
+
* - **"SAVE"** — Performs an *upsert* (insert, update, or both) for a model instance.
|
|
244
|
+
* - **"GET"** — Retrieves a single record by its primary key, optionally using a `DataSource`.
|
|
245
|
+
* - **"LIST"** — Retrieves all records for the model, using the specified `DataSource`.
|
|
246
|
+
*
|
|
247
|
+
* The generated methods are static, exposed through both the backend
|
|
248
|
+
* and the frontend client API.
|
|
249
|
+
*
|
|
250
|
+
* Example:
|
|
251
|
+
* ```ts
|
|
252
|
+
* @CRUD(["SAVE", "GET", "LIST"])
|
|
253
|
+
* @D1
|
|
254
|
+
* export class CrudHaver {
|
|
255
|
+
* @PrimaryKey id: number;
|
|
256
|
+
* name: string;
|
|
257
|
+
* }
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
21
260
|
export declare const CRUD: (_kinds: CrudKind[]) => ClassDecorator;
|
|
22
261
|
type Primitive = string | number | boolean | bigint | symbol | null | undefined;
|
|
23
|
-
|
|
262
|
+
/**
|
|
263
|
+
* A recursive type describing which related models to include
|
|
264
|
+
* when querying a `@D1` model.
|
|
265
|
+
*
|
|
266
|
+
* An `IncludeTree<T>` mirrors the shape of the model class,
|
|
267
|
+
* where each navigation property can be replaced with another
|
|
268
|
+
* `IncludeTree` describing nested joins.
|
|
269
|
+
*
|
|
270
|
+
* - Scalar properties (string, number, etc.) are excluded automatically.
|
|
271
|
+
* - Navigation properties (e.g. `dogs: Dog[]`, `owner: Person`) may appear
|
|
272
|
+
* as keys with empty objects `{}` or nested trees.
|
|
273
|
+
*
|
|
274
|
+
* Example:
|
|
275
|
+
* ```ts
|
|
276
|
+
* @D1
|
|
277
|
+
* export class Person {
|
|
278
|
+
* @PrimaryKey id: number;
|
|
279
|
+
* @OneToMany("personId") dogs: Dog[];
|
|
280
|
+
*
|
|
281
|
+
* @DataSource
|
|
282
|
+
* static readonly default: IncludeTree<Person> = {
|
|
283
|
+
* dogs: {}, // join Dog table when querying Person
|
|
284
|
+
* };
|
|
285
|
+
* }
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
export type IncludeTree<T> = (T extends Primitive ? never : {
|
|
24
289
|
[K in keyof T]?: T[K] extends (infer U)[] ? IncludeTree<NonNullable<U>> : IncludeTree<NonNullable<T[K]>>;
|
|
290
|
+
}) & {
|
|
291
|
+
__brand?: "IncludeTree";
|
|
292
|
+
};
|
|
293
|
+
/**
|
|
294
|
+
* Represents the name of a `@DataSource` available on a model type `T`,
|
|
295
|
+
* or `"none"` when no data source (no joins) should be applied.
|
|
296
|
+
*
|
|
297
|
+
* All instantiated model methods implicitly have a Data Source param `__dataSource`.
|
|
298
|
+
*
|
|
299
|
+
* Example:
|
|
300
|
+
* ```ts
|
|
301
|
+
* @D1
|
|
302
|
+
* export class Person {
|
|
303
|
+
* @PrimaryKey id: number;
|
|
304
|
+
*
|
|
305
|
+
* @DataSource
|
|
306
|
+
* static readonly default: IncludeTree<Person> = { dogs: {} };
|
|
307
|
+
*
|
|
308
|
+
* @POST
|
|
309
|
+
* foo(ds: DataSourceOf<Person>) {
|
|
310
|
+
* // Cloesce won't append an implicit data source param here since it's explicit
|
|
311
|
+
* }
|
|
312
|
+
* }
|
|
313
|
+
*
|
|
314
|
+
* // on the API client:
|
|
315
|
+
* async foo(ds: "default" | "none"): Promise<void> {...}
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
export type DataSourceOf<T extends object> = (KeysOfType<T, IncludeTree<T>> | "none") & {
|
|
319
|
+
__brand?: "DataSource";
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* A branded `number` type indicating that the corresponding
|
|
323
|
+
* SQL column should be created as an `INTEGER`.
|
|
324
|
+
*
|
|
325
|
+
* While all numbers are valid JavaScript types, annotating a
|
|
326
|
+
* field with `Integer` communicates to the Cloesce compiler
|
|
327
|
+
* that this property represents an integer column in SQLite.
|
|
328
|
+
*
|
|
329
|
+
* Example:
|
|
330
|
+
* ```ts
|
|
331
|
+
* @D1
|
|
332
|
+
* export class Horse {
|
|
333
|
+
* @PrimaryKey id: Integer;
|
|
334
|
+
* height: number; // stored as REAL
|
|
335
|
+
* }
|
|
336
|
+
* ```
|
|
337
|
+
*/
|
|
338
|
+
export type Integer = number & {
|
|
339
|
+
__brand?: "Integer";
|
|
25
340
|
};
|
|
26
|
-
export type DataSourceOf<T extends object> = KeysOfType<T, IncludeTree<T>> | "none";
|
|
27
341
|
/**
|
|
28
|
-
* ORM
|
|
342
|
+
* Exposes the ORM primitives Cloesce uses to interact with D1 databases.
|
|
29
343
|
*/
|
|
30
344
|
export declare class Orm {
|
|
31
345
|
private db;
|
|
@@ -42,31 +356,18 @@ export declare class Orm {
|
|
|
42
356
|
* @param ctor The model constructor
|
|
43
357
|
* @param records D1 Result records
|
|
44
358
|
* @param includeTree Include tree to define the relationships to join.
|
|
45
|
-
* @returns
|
|
46
|
-
*/
|
|
47
|
-
static fromSql<T extends object>(ctor: new () => T, records: Record<string, any>[], includeTree: IncludeTree<T> | null): Either<string, T[]>;
|
|
48
|
-
/**
|
|
49
|
-
* Returns a SQL query to insert a model into the database. Uses an IncludeTree as a guide for
|
|
50
|
-
* foreign key relationships, only inserting the explicitly stated pattern in the tree.
|
|
51
|
-
*
|
|
52
|
-
* TODO: We should be able to leave primary keys and foreign keys undefined, with
|
|
53
|
-
* primary keys being auto incremented and foreign keys being assumed by navigation property
|
|
54
|
-
* context.
|
|
55
|
-
*
|
|
56
|
-
* @param ctor A model constructor.
|
|
57
|
-
* @param newModel The new model to insert.
|
|
58
|
-
* @param includeTree An include tree describing which foreign keys to join.
|
|
59
|
-
* @returns Either an error string, or the insert query string.
|
|
60
359
|
*/
|
|
61
|
-
static
|
|
360
|
+
static mapSql<T extends object>(ctor: new () => T, records: Record<string, any>[], includeTree?: IncludeTree<T> | null): Either<string, T[]>;
|
|
62
361
|
/**
|
|
63
362
|
* Executes an "upsert" query, adding or augmenting a model in the database.
|
|
363
|
+
*
|
|
64
364
|
* If a model's primary key is not defined in `newModel`, the query is assumed to be an insert.
|
|
365
|
+
*
|
|
65
366
|
* If a model's primary key _is_ defined, but some attributes are missing, the query is assumed to be an update.
|
|
367
|
+
*
|
|
66
368
|
* Finally, if the primary key is defined, but all attributes are included, a SQLite upsert will be performed.
|
|
67
369
|
*
|
|
68
|
-
*
|
|
69
|
-
* only if the primary key is an integer, in which case it will be auto incremented and assigned.
|
|
370
|
+
* In any other case, an error string will be returned.
|
|
70
371
|
*
|
|
71
372
|
* ### Inserting a new Model
|
|
72
373
|
* ```ts
|
|
@@ -100,25 +401,114 @@ export declare class Orm {
|
|
|
100
401
|
* @param includeTree An include tree describing which foreign keys to join.
|
|
101
402
|
* @returns An error string, or the primary key of the inserted model.
|
|
102
403
|
*/
|
|
103
|
-
upsert<T extends object>(ctor: new () => T, newModel: T
|
|
404
|
+
upsert<T extends object>(ctor: new () => T, newModel: DeepPartial<T>, includeTree?: IncludeTree<T> | null): Promise<Either<string, any>>;
|
|
104
405
|
/**
|
|
105
|
-
* Returns a query
|
|
406
|
+
* Returns a select query, creating a CTE view for the model using the provided include tree.
|
|
407
|
+
*
|
|
408
|
+
* @param ctor The model constructor.
|
|
409
|
+
* @param includeTree An include tree describing which related models to join.
|
|
410
|
+
* @param from An optional custom `FROM` clause to use instead of the base table.
|
|
411
|
+
* @param tagCte An optional CTE name to tag the query with. Defaults to "Model.view".
|
|
412
|
+
*
|
|
413
|
+
* ### Example:
|
|
414
|
+
* ```ts
|
|
415
|
+
* // Using a data source
|
|
416
|
+
* const query = Orm.listQuery(Person, "default");
|
|
417
|
+
*
|
|
418
|
+
* // Using a custom from statement
|
|
419
|
+
* const query = Orm.listQuery(Person, null, "SELECT * FROM Person WHERE age > 18");
|
|
420
|
+
* ```
|
|
421
|
+
*
|
|
422
|
+
* ### Example SQL output:
|
|
423
|
+
* ```sql
|
|
424
|
+
* WITH Person_view AS (
|
|
425
|
+
* SELECT
|
|
426
|
+
* "Person"."id" AS "id",
|
|
427
|
+
* ...
|
|
428
|
+
* FROM "Person"
|
|
429
|
+
* LEFT JOIN ...
|
|
430
|
+
* )
|
|
431
|
+
* SELECT * FROM Person_view
|
|
432
|
+
* ```
|
|
106
433
|
*/
|
|
107
|
-
static listQuery<T extends object>(ctor: new () => T,
|
|
434
|
+
static listQuery<T extends object>(ctor: new () => T, opts: {
|
|
435
|
+
includeTree?: IncludeTree<T> | null;
|
|
436
|
+
from?: string;
|
|
437
|
+
tagCte?: string;
|
|
438
|
+
}): string;
|
|
108
439
|
/**
|
|
109
|
-
* Returns a query
|
|
110
|
-
*
|
|
440
|
+
* Returns a select query for a single model by primary key, creating a CTE view using the provided include tree.
|
|
441
|
+
*
|
|
442
|
+
* @param ctor The model constructor.
|
|
443
|
+
* @param includeTree An include tree describing which related models to join.
|
|
444
|
+
*
|
|
445
|
+
* ### Example:
|
|
446
|
+
* ```ts
|
|
447
|
+
* // Using a data source
|
|
448
|
+
* const query = Orm.getQuery(Person, "default");
|
|
449
|
+
* ```
|
|
450
|
+
*
|
|
451
|
+
* ### Example SQL output:
|
|
452
|
+
*
|
|
453
|
+
* ```sql
|
|
454
|
+
* WITH Person_view AS (
|
|
455
|
+
* SELECT
|
|
456
|
+
* "Person"."id" AS "id",
|
|
457
|
+
* ...
|
|
458
|
+
* FROM "Person"
|
|
459
|
+
* LEFT JOIN ...
|
|
460
|
+
* )
|
|
461
|
+
* SELECT * FROM Person_view WHERE [Person].[id] = ?
|
|
462
|
+
* ```
|
|
111
463
|
*/
|
|
112
|
-
static getQuery<T extends object>(ctor: new () => T, includeTree
|
|
464
|
+
static getQuery<T extends object>(ctor: new () => T, includeTree?: IncludeTree<T> | null): string;
|
|
113
465
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
466
|
+
* Retrieves all instances of a model from the database.
|
|
467
|
+
* @param ctor The model constructor.
|
|
468
|
+
* @param includeTree An include tree describing which related models to join.
|
|
469
|
+
* @param from An optional custom `FROM` clause to use instead of the base table.
|
|
470
|
+
* @returns Either an error string, or an array of model instances.
|
|
471
|
+
*
|
|
472
|
+
* ### Example:
|
|
473
|
+
* ```ts
|
|
474
|
+
* const orm = Orm.fromD1(env.db);
|
|
475
|
+
* const horses = await orm.list(Horse, Horse.default);
|
|
476
|
+
* ```
|
|
477
|
+
*
|
|
478
|
+
* ### Example with custom from:
|
|
479
|
+
* ```ts
|
|
480
|
+
* const orm = Orm.fromD1(env.db);
|
|
481
|
+
* const adultHorses = await orm.list(Horse, Horse.default, "SELECT * FROM Horse ORDER BY age DESC LIMIT 10");
|
|
482
|
+
* ```
|
|
483
|
+
*
|
|
484
|
+
* =>
|
|
485
|
+
*
|
|
486
|
+
* ```sql
|
|
487
|
+
* SELECT
|
|
488
|
+
* "Horse"."id" AS "id",
|
|
489
|
+
* ...
|
|
490
|
+
* FROM (SELECT * FROM Horse ORDER BY age DESC LIMIT 10)
|
|
491
|
+
* LEFT JOIN ...
|
|
492
|
+
* ```
|
|
493
|
+
*
|
|
116
494
|
*/
|
|
117
|
-
list<T extends object>(ctor: new () => T,
|
|
495
|
+
list<T extends object>(ctor: new () => T, opts: {
|
|
496
|
+
includeTree?: IncludeTree<T> | null;
|
|
497
|
+
from?: string;
|
|
498
|
+
}): Promise<Either<string, T[]>>;
|
|
118
499
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
500
|
+
* Retrieves a single model by primary key.
|
|
501
|
+
* @param ctor The model constructor.
|
|
502
|
+
* @param id The primary key value.
|
|
503
|
+
* @param includeTree An include tree describing which related models to join.
|
|
504
|
+
* @returns Either an error string, or the model instance (null if not found).
|
|
505
|
+
*
|
|
506
|
+
* ### Example:
|
|
507
|
+
* ```ts
|
|
508
|
+
* const orm = Orm.fromD1(env.db);
|
|
509
|
+
* const horse = await orm.get(Horse, 1, Horse.default);
|
|
510
|
+
* ```
|
|
121
511
|
*/
|
|
122
|
-
get<T extends object>(ctor: new () => T, id: any,
|
|
512
|
+
get<T extends object>(ctor: new () => T, id: any, includeTree?: IncludeTree<T> | null): Promise<Either<string, T | null>>;
|
|
123
513
|
}
|
|
124
514
|
//# sourceMappingURL=backend.d.ts.map
|
package/dist/ui/backend.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/ui/backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iDAAiD,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/ui/backend.ts"],"names":[],"mappings":"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"}
|