cloesce 0.0.4-unstable.5 → 0.0.4-unstable.6

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.
@@ -1,6 +1,7 @@
1
- import { left, right, isNullableType, getNavigationPropertyCidlType, NO_DATA_SOURCE, } from "../common.js";
1
+ import { Either, isNullableType, getNavigationPropertyCidlType, NO_DATA_SOURCE, } from "../common.js";
2
2
  import { mapSql, loadOrmWasm } from "./wasm.js";
3
3
  import { CrudContext } from "./crud.js";
4
+ import { Orm } from "../ui/backend.js";
4
5
  /**
5
6
  * Singleton instance containing the cidl, constructor registry, and wasm binary.
6
7
  * These values are guaranteed to never change throughout a workers lifetime.
@@ -49,10 +50,10 @@ export async function cloesce(request, env, ast, app, constructorRegistry, envMe
49
50
  //#endregion
50
51
  //#region Match the route to a model method
51
52
  const route = matchRoute(request, ast, apiRoute);
52
- if (!route.ok) {
53
+ if (route.isLeft()) {
53
54
  return toResponse(route.value);
54
55
  }
55
- const { method, model, id } = route.value;
56
+ const { method, model, id } = route.unwrap();
56
57
  //#endregion
57
58
  //#region Model Middleware
58
59
  for (const m of app.model.get(model.name) ?? []) {
@@ -64,10 +65,10 @@ export async function cloesce(request, env, ast, app, constructorRegistry, envMe
64
65
  //#endregion
65
66
  //#region Validate request body to the model method
66
67
  const validation = await validateRequest(request, ast, model, method, id);
67
- if (!validation.ok) {
68
+ if (validation.isLeft()) {
68
69
  return toResponse(validation.value);
69
70
  }
70
- const { params, dataSource } = validation.value;
71
+ const { params, dataSource } = validation.unwrap();
71
72
  //#endregion
72
73
  //#region Method Middleware
73
74
  for (const m of app.method.get(model.name)?.get(method.name) ?? []) {
@@ -80,20 +81,17 @@ export async function cloesce(request, env, ast, app, constructorRegistry, envMe
80
81
  //#region Instantatiate the model
81
82
  const crudCtx = await (async () => {
82
83
  if (method.is_static) {
83
- return right(CrudContext.fromCtor(d1, constructorRegistry[model.name]));
84
+ return Either.right(CrudContext.fromCtor(d1, constructorRegistry[model.name]));
84
85
  }
85
86
  const hydratedModel = await hydrateModel(constructorRegistry, d1, model, id, // id must exist after matchRoute
86
87
  dataSource);
87
- if (!hydratedModel.ok) {
88
- return hydratedModel;
89
- }
90
- return right(CrudContext.fromInstance(d1, hydratedModel.value, constructorRegistry[model.name]));
88
+ return hydratedModel.map((_) => CrudContext.fromInstance(d1, hydratedModel.value, constructorRegistry[model.name]));
91
89
  })();
92
- if (!crudCtx.ok) {
90
+ if (crudCtx.isLeft()) {
93
91
  return toResponse(crudCtx.value);
94
92
  }
95
93
  //#endregion
96
- return toResponse(await methodDispatch(crudCtx.value, ir, method, params));
94
+ return toResponse(await methodDispatch(crudCtx.unwrap(), ir, method, params));
97
95
  }
98
96
  /**
99
97
  * Matches a request to a method on a model.
@@ -104,7 +102,7 @@ function matchRoute(request, ast, apiRoute) {
104
102
  const url = new URL(request.url);
105
103
  // Error state: We expect an exact request format, and expect that the model
106
104
  // and are apart of the CIDL
107
- const notFound = (e) => left(errorState(404, `Path not found: ${e} ${url.pathname}`));
105
+ const notFound = (e) => Either.left(errorState(404, `Path not found: ${e} ${url.pathname}`));
108
106
  const routeParts = url.pathname
109
107
  .slice(apiRoute.length)
110
108
  .split("/")
@@ -127,7 +125,7 @@ function matchRoute(request, ast, apiRoute) {
127
125
  if (request.method !== method.http_verb) {
128
126
  return notFound("Unmatched HTTP method");
129
127
  }
130
- return right({
128
+ return Either.right({
131
129
  model,
132
130
  method,
133
131
  id,
@@ -140,7 +138,7 @@ function matchRoute(request, ast, apiRoute) {
140
138
  */
141
139
  async function validateRequest(request, ast, model, method, id) {
142
140
  // Error state: any missing parameter, body, or malformed input will exit with 400.
143
- const invalidRequest = (e) => left(errorState(400, `Invalid Request Body: ${e}`));
141
+ const invalidRequest = (e) => Either.left(errorState(400, `Invalid Request Body: ${e}`));
144
142
  if (!method.is_static && id == null) {
145
143
  return invalidRequest("Id's are required for instantiated methods.");
146
144
  }
@@ -183,7 +181,7 @@ async function validateRequest(request, ast, model, method, id) {
183
181
  !(dataSource in model.data_sources)) {
184
182
  return invalidRequest(`Unknown data source ${dataSource}`);
185
183
  }
186
- return right({ params, dataSource });
184
+ return Either.right({ params, dataSource });
187
185
  }
188
186
  /**
189
187
  * Queries D1 for a particular model's ID, then transforms the SQL column output into
@@ -195,17 +193,19 @@ async function validateRequest(request, ast, model, method, id) {
195
193
  async function hydrateModel(constructorRegistry, d1, model, id, dataSource) {
196
194
  // Error state: If the D1 database has been tweaked outside of Cloesce
197
195
  // resulting in a malformed query, exit with a 500.
198
- const malformedQuery = (e) => left(errorState(500, `Error in hydration query, is the database out of sync with the backend?: ${e instanceof Error ? e.message : String(e)}`));
196
+ const malformedQuery = (e) => Either.left(errorState(500, `Error in hydration query, is the database out of sync with the backend?: ${e instanceof Error ? e.message : String(e)}`));
199
197
  // Error state: If no record is found for the id, return a 404
200
- const missingRecord = left(errorState(404, "Record not found"));
201
- const pk = model.primary_key.name;
202
- const query = dataSource !== NO_DATA_SOURCE
203
- ? `SELECT * FROM "${model.name}.${dataSource}" WHERE "${pk}" = ?`
204
- : `SELECT * FROM "${model.name}" WHERE "${pk}" = ?`;
198
+ const missingRecord = Either.left(errorState(404, "Record not found"));
205
199
  // Query DB
206
200
  let records;
207
201
  try {
208
- records = await d1.prepare(query).bind(id).run();
202
+ let includeTree = dataSource === NO_DATA_SOURCE
203
+ ? null
204
+ : constructorRegistry[model.name][dataSource];
205
+ records = await d1
206
+ .prepare(Orm.getQuery(constructorRegistry[model.name], includeTree).unwrap())
207
+ .bind(id)
208
+ .run();
209
209
  if (!records?.results) {
210
210
  return missingRecord;
211
211
  }
@@ -218,7 +218,7 @@ async function hydrateModel(constructorRegistry, d1, model, id, dataSource) {
218
218
  }
219
219
  // Hydrate
220
220
  const models = mapSql(constructorRegistry[model.name], records.results, model.data_sources[dataSource]?.tree ?? {}).value;
221
- return right(models[0]);
221
+ return Either.right(models[0]);
222
222
  }
223
223
  /**
224
224
  * Calls a method on a model given a list of parameters.
@@ -326,6 +326,7 @@ function validateCidlType(ast, value, cidlType, isPartial) {
326
326
  if (!poo.attributes.every((attr) => validateCidlType(ast, valueObj[attr.name], attr.cidl_type, isPartial))) {
327
327
  return false;
328
328
  }
329
+ return true;
329
330
  }
330
331
  if ("Array" in cidlType) {
331
332
  const arr = cidlType.Array;
@@ -10,8 +10,9 @@ export interface OrmWasmExports {
10
10
  set_meta_ptr(ptr: number, len: number): number;
11
11
  alloc(len: number): number;
12
12
  dealloc(ptr: number, len: number): void;
13
- object_relational_mapping(model_name_ptr: number, model_name_len: number, sql_rows_ptr: number, sql_rows_len: number, include_tree_ptr: number, include_tree_len: number): boolean;
13
+ map_sql(model_name_ptr: number, model_name_len: number, sql_rows_ptr: number, sql_rows_len: number, include_tree_ptr: number, include_tree_len: number): boolean;
14
14
  upsert_model(model_name_ptr: number, model_name_len: number, new_model_ptr: number, new_model_len: number, include_tree_ptr: number, include_tree_len: number): boolean;
15
+ list_models(model_name_ptr: number, model_name_len: number, include_tree_ptr: number, include_tree_len: number, tag_cte_ptr: number, tag_cte_len: number, custom_from_ptr: number, custom_from_len: number): boolean;
15
16
  }
16
17
  /**
17
18
  * RAII for wasm memory
@@ -28,7 +29,13 @@ export declare class WasmResource {
28
29
  static fromString(str: string, wasm: OrmWasmExports): WasmResource;
29
30
  }
30
31
  export declare function loadOrmWasm(ast: CloesceAst, wasm?: WebAssembly.Instance): Promise<OrmWasmExports>;
31
- export declare function invokeOrmWasm<T>(fn: (...args: number[]) => boolean, args: WasmResource[], wasm: OrmWasmExports): Either<string, T>;
32
+ /**
33
+ * Invokes a WASM ORM function with the provided arguments, handling memory
34
+ * allocation and deallocation.
35
+ *
36
+ * Returns an Either where Left is an error message and Right the raw string result.
37
+ */
38
+ export declare function invokeOrmWasm(fn: (...args: number[]) => boolean, args: WasmResource[], wasm: OrmWasmExports): Either<string, string>;
32
39
  /**
33
40
  * Calls `object_relational_mapping` to turn a row of SQL records into
34
41
  * an instantiated object.
@@ -1 +1 @@
1
- {"version":3,"file":"wasm.d.ts","sourceRoot":"","sources":["../../src/router/wasm.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,UAAU,EACV,MAAM,EAIP,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAM/C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;IAC3B,cAAc,IAAI,MAAM,CAAC;IACzB,cAAc,IAAI,MAAM,CAAC;IACzB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/C,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC,yBAAyB,CACvB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC;IAEX,YAAY,CACV,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC;CACZ;AAED;;GAEG;AACH,qBAAa,YAAY;IAErB,OAAO,CAAC,IAAI;IACL,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;gBAFV,IAAI,EAAE,cAAc,EACrB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM;IAEpB,IAAI;IAIJ;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,YAAY;CAQnE;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,UAAU,EACf,IAAI,CAAC,EAAE,WAAW,CAAC,QAAQ,GAC1B,OAAO,CAAC,cAAc,CAAC,CAmBzB;AAED,wBAAgB,aAAa,CAAC,CAAC,EAC7B,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,EAClC,IAAI,EAAE,YAAY,EAAE,EACpB,IAAI,EAAE,cAAc,GACnB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAkBnB;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EACrC,IAAI,EAAE,UAAU,CAAC,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAC9B,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,eAAe,GAAG,IAAI,GACnD,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CA0DrB"}
1
+ {"version":3,"file":"wasm.d.ts","sourceRoot":"","sources":["../../src/router/wasm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,EAAS,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAM/C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;IAC3B,cAAc,IAAI,MAAM,CAAC;IACzB,cAAc,IAAI,MAAM,CAAC;IACzB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/C,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC,OAAO,CACL,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC;IAEX,YAAY,CACV,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC;IAEX,WAAW,CACT,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,EAAE,MAAM,EACxB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC;CACZ;AAED;;GAEG;AACH,qBAAa,YAAY;IAErB,OAAO,CAAC,IAAI;IACL,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;gBAFV,IAAI,EAAE,cAAc,EACrB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM;IAEpB,IAAI;IAIJ;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,YAAY;CAQnE;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,UAAU,EACf,IAAI,CAAC,EAAE,WAAW,CAAC,QAAQ,GAC1B,OAAO,CAAC,cAAc,CAAC,CAmBzB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,EAClC,IAAI,EAAE,YAAY,EAAE,EACpB,IAAI,EAAE,cAAc,GACnB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBxB;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EACrC,IAAI,EAAE,UAAU,CAAC,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAC9B,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,eAAe,GAAG,IAAI,GACnD,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAsDrB"}
@@ -1,4 +1,4 @@
1
- import { left, right, } from "../common.js";
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());
@@ -68,11 +74,11 @@ export function mapSql(ctor, records, includeTree) {
68
74
  WasmResource.fromString(JSON.stringify(records), wasm),
69
75
  WasmResource.fromString(JSON.stringify(includeTree), wasm),
70
76
  ];
71
- const jsonResults = invokeOrmWasm(wasm.object_relational_mapping, args, wasm);
72
- if (!jsonResults.ok)
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) {
@@ -31,8 +31,6 @@ export declare const D1: ClassDecorator;
31
31
  * returned from a model method or API endpoint without being
32
32
  * treated as a database model.
33
33
  *
34
- * These are often used for DTOs or view models.
35
- *
36
34
  * Example:
37
35
  * ```ts
38
36
  * @PlainOldObject
@@ -40,6 +38,16 @@ export declare const D1: ClassDecorator;
40
38
  * catFacts: string[];
41
39
  * catNames: string[];
42
40
  * }
41
+ *
42
+ * // in a method...
43
+ * foo(): CatStuff {
44
+ * return {
45
+ * catFacts: ["cats sleep 16 hours a day"],
46
+ * catNames: ["Whiskers", "Fluffy"]
47
+ * };
48
+ *
49
+ * // which generates an API like:
50
+ * async function foo(): Promise<HttpResult<CatStuff>> { ... }
43
51
  * ```
44
52
  */
45
53
  export declare const PlainOldObject: ClassDecorator;
@@ -110,11 +118,8 @@ export declare const DELETE: MethodDecorator;
110
118
  /**
111
119
  * Declares a static property as a data source.
112
120
  *
113
- * Data sources describe SQL view definitions (joins) for
114
- * model relationships. They define which related models
115
- * are automatically included when querying. Data sources
116
- * can only reference navigation properties, not scalar
117
- * attributes.
121
+ * Data sources describe SQL left joins related to each
122
+ * models navigation properties.
118
123
  *
119
124
  * Example:
120
125
  * ```ts
@@ -137,27 +142,17 @@ export declare const DELETE: MethodDecorator;
137
142
  * @OneToOne("dogId")
138
143
  * dog: Dog | undefined;
139
144
  *
140
- * // 👇 Defines a data source that joins the related Dog record
141
145
  * @DataSource
142
146
  * static readonly default: IncludeTree<Person> = {
143
- * dog: {},
147
+ * dog: {}, // join Dog table when querying Person with `default` data source
144
148
  * };
145
149
  * }
146
150
  *
147
- * // The above will generate an SQL view similar to:
148
- * // CREATE VIEW "Person.default" AS
149
- * // SELECT
150
- * // "Person"."id" AS "id",
151
- * // "Person"."dogId" AS "dogId",
152
- * // "Dog"."id" AS "dog.id",
153
- * // "Dog"."name" AS "dog.name"
154
- * // FROM "Person"
155
- * // LEFT JOIN "Dog" ON "Person"."dogId" = "Dog"."id";
156
- *
157
151
  * // When queried via the ORM or client API:
158
152
  * const orm = Orm.fromD1(env.db);
159
- * const people = (await orm.list(Person, "default")).value;
160
- * // Each Person instance will now include a populated .dog property.
153
+ * const people = await orm.list(Person, Person.default);
154
+ *
155
+ * // => Person { id: 1, dogId: 2, dog: { id: 2, name: "Fido" } }[]
161
156
  * ```
162
157
  */
163
158
  export declare const DataSource: PropertyDecorator;
@@ -173,7 +168,7 @@ export declare const DataSource: PropertyDecorator;
173
168
  * dogs: Dog[];
174
169
  * ```
175
170
  */
176
- export declare const OneToMany: (_: string) => PropertyDecorator;
171
+ export declare const OneToMany: (_foreignKeyColumn: string) => PropertyDecorator;
177
172
  /**
178
173
  * Declares a one-to-one relationship between models.
179
174
  *
@@ -186,7 +181,7 @@ export declare const OneToMany: (_: string) => PropertyDecorator;
186
181
  * dog: Dog | undefined;
187
182
  * ```
188
183
  */
189
- export declare const OneToOne: (_: string) => PropertyDecorator;
184
+ export declare const OneToOne: (_foreignKeyColumn: string) => PropertyDecorator;
190
185
  /**
191
186
  * Declares a many-to-many relationship between models.
192
187
  *
@@ -199,7 +194,7 @@ export declare const OneToOne: (_: string) => PropertyDecorator;
199
194
  * courses: Course[];
200
195
  * ```
201
196
  */
202
- export declare const ManyToMany: (_: string) => PropertyDecorator;
197
+ export declare const ManyToMany: (_uniqueId: string) => PropertyDecorator;
203
198
  /**
204
199
  * Declares a foreign key relationship between models.
205
200
  * Directly translates to a SQLite foreign key.
@@ -214,13 +209,16 @@ export declare const ManyToMany: (_: string) => PropertyDecorator;
214
209
  * dogId: number;
215
210
  * ```
216
211
  */
217
- export declare const ForeignKey: <T>(_: T | string) => PropertyDecorator;
212
+ export declare const ForeignKey: <T>(_Model: T | string) => PropertyDecorator;
218
213
  /**
219
214
  * Marks a method parameter for dependency injection.
220
215
  *
221
216
  * Injected parameters can receive environment bindings,
222
217
  * middleware-provided objects, or other registered values.
223
218
  *
219
+ * Note that injected parameters will not appear in the client
220
+ * API.
221
+ *
224
222
  * Example:
225
223
  * ```ts
226
224
  * @POST
@@ -240,14 +238,13 @@ export declare const Inject: ParameterDecorator;
240
238
  * client bindings automatically, removing the need to manually
241
239
  * define common API operations.
242
240
  *
243
- * Supported kinds:
244
- * - **"SAVE"** — Performs an *upsert* (insert or update) for a model instance.
241
+ * CRUD Operations:
242
+ * - **"SAVE"** — Performs an *upsert* (insert, update, or both) for a model instance.
245
243
  * - **"GET"** — Retrieves a single record by its primary key, optionally using a `DataSource`.
246
244
  * - **"LIST"** — Retrieves all records for the model, using the specified `DataSource`.
247
- * - **(future)** `"DELETE"` — Will remove a record by primary key once implemented.
248
245
  *
249
246
  * The generated methods are static, exposed through both the backend
250
- * (Worker endpoints) and the frontend client API.
247
+ * and the frontend client API.
251
248
  *
252
249
  * Example:
253
250
  * ```ts
@@ -257,11 +254,6 @@ export declare const Inject: ParameterDecorator;
257
254
  * @PrimaryKey id: number;
258
255
  * name: string;
259
256
  * }
260
- *
261
- * // Generated methods (conceptually):
262
- * // static async save(item: CrudHaver): Promise<HttpResult<CrudHaver>>
263
- * // static async get(id: number, dataSource?: string): Promise<HttpResult<CrudHaver>>
264
- * // static async list(dataSource?: string): Promise<HttpResult<CrudHaver[]>>
265
257
  * ```
266
258
  */
267
259
  export declare const CRUD: (_kinds: CrudKind[]) => ClassDecorator;
@@ -301,8 +293,7 @@ export type IncludeTree<T> = (T extends Primitive ? never : {
301
293
  * Represents the name of a `@DataSource` available on a model type `T`,
302
294
  * or `"none"` when no data source (no joins) should be applied.
303
295
  *
304
- * This type is used by ORM and CRUD methods to restrict valid
305
- * data source names to the actual static properties declared on the model.
296
+ * All instantiated model methods implicitly have a Data Source param `__dataSource`.
306
297
  *
307
298
  * Example:
308
299
  * ```ts
@@ -312,10 +303,15 @@ export type IncludeTree<T> = (T extends Primitive ? never : {
312
303
  *
313
304
  * @DataSource
314
305
  * static readonly default: IncludeTree<Person> = { dogs: {} };
306
+ *
307
+ * @POST
308
+ * foo(ds: DataSourceOf<Person>) {
309
+ * // Cloesce won't append an implicit data source param here since it's explicit
310
+ * }
315
311
  * }
316
312
  *
317
- * type DS = DataSourceOf<Person>;
318
- * // => "default" | "none"
313
+ * // on the API client:
314
+ * async foo(ds: "default" | "none"): Promise<void> {...}
319
315
  * ```
320
316
  */
321
317
  export type DataSourceOf<T extends object> = (KeysOfType<T, IncludeTree<T>> | "none") & {
@@ -342,22 +338,7 @@ export type Integer = number & {
342
338
  __brand?: "Integer";
343
339
  };
344
340
  /**
345
- * Provides helper methods for performing ORM operations against a D1 database.
346
- *
347
- * The `Orm` class uses the Cloesce metadata system to generate, execute,
348
- * and map SQL queries for model classes decorated with `@D1`.
349
- *
350
- * Typical operations include:
351
- * - `fromD1(db)` — create an ORM instance bound to a `D1Database`
352
- * - `upsert()` — insert or update a model
353
- * - `list()` — fetch all instances of a model
354
- * - `get()` — fetch one instance by primary key
355
- *
356
- * Example:
357
- * ```ts
358
- * const orm = Orm.fromD1(env.db);
359
- * const horses = (await orm.list(Horse, "default")).value;
360
- * ```
341
+ * Exposes the ORM primitives Cloesce uses to interact with D1 databases.
361
342
  */
362
343
  export declare class Orm {
363
344
  private db;
@@ -376,28 +357,16 @@ export declare class Orm {
376
357
  * @param includeTree Include tree to define the relationships to join.
377
358
  */
378
359
  static mapSql<T extends object>(ctor: new () => T, records: Record<string, any>[], includeTree?: IncludeTree<T> | null): Either<string, T[]>;
379
- /**
380
- * Returns a SQL query to insert a model into the database. Uses an IncludeTree as a guide for
381
- * foreign key relationships, only inserting the explicitly stated pattern in the tree.
382
- *
383
- * TODO: We should be able to leave primary keys and foreign keys undefined, with
384
- * primary keys being auto incremented and foreign keys being assumed by navigation property
385
- * context.
386
- *
387
- * @param ctor A model constructor.
388
- * @param newModel The new model to insert.
389
- * @param includeTree An include tree describing which foreign keys to join.
390
- * @returns Either an error string, or the insert query string.
391
- */
392
- static upsertQuery<T extends object>(ctor: new () => T, newModel: DeepPartial<T>, includeTree?: IncludeTree<T> | null): Either<string, string>;
393
360
  /**
394
361
  * Executes an "upsert" query, adding or augmenting a model in the database.
362
+ *
395
363
  * If a model's primary key is not defined in `newModel`, the query is assumed to be an insert.
364
+ *
396
365
  * If a model's primary key _is_ defined, but some attributes are missing, the query is assumed to be an update.
366
+ *
397
367
  * Finally, if the primary key is defined, but all attributes are included, a SQLite upsert will be performed.
398
368
  *
399
- * Capable of inferring foreign keys from the surrounding context of the model. A missing primary key is allowed
400
- * only if the primary key is an integer, in which case it will be auto incremented and assigned.
369
+ * In any other case, an error string will be returned.
401
370
  *
402
371
  * ### Inserting a new Model
403
372
  * ```ts
@@ -433,23 +402,112 @@ export declare class Orm {
433
402
  */
434
403
  upsert<T extends object>(ctor: new () => T, newModel: DeepPartial<T>, includeTree?: IncludeTree<T> | null): Promise<Either<string, any>>;
435
404
  /**
436
- * Returns a query of the form `SELECT * FROM [Model.DataSource]`
405
+ * Returns a select query, creating a CTE view for the model using the provided include tree.
406
+ *
407
+ * @param ctor The model constructor.
408
+ * @param includeTree An include tree describing which related models to join.
409
+ * @param from An optional custom `FROM` clause to use instead of the base table.
410
+ * @param tagCte An optional CTE name to tag the query with. Defaults to "Model.view".
411
+ *
412
+ * ### Example:
413
+ * ```ts
414
+ * // Using a data source
415
+ * const query = Orm.listQuery(Person, "default");
416
+ *
417
+ * // Using a custom from statement
418
+ * const query = Orm.listQuery(Person, null, "SELECT * FROM Person WHERE age > 18");
419
+ * ```
420
+ *
421
+ * ### Example SQL output:
422
+ * ```sql
423
+ * WITH Person_view AS (
424
+ * SELECT
425
+ * "Person"."id" AS "id",
426
+ * ...
427
+ * FROM "Person"
428
+ * LEFT JOIN ...
429
+ * )
430
+ * SELECT * FROM Person_view
431
+ * ```
437
432
  */
438
- static listQuery<T extends object>(ctor: new () => T, includeTree?: KeysOfType<T, IncludeTree<T>> | null): string;
433
+ static listQuery<T extends object>(ctor: new () => T, opts: {
434
+ includeTree?: IncludeTree<T> | null;
435
+ from?: string;
436
+ tagCte?: string;
437
+ }): Either<string, string>;
439
438
  /**
440
- * Returns a query of the form `SELECT * FROM [Model.DataSource] WHERE [PrimaryKey] = ?`.
441
- * Requires the id parameter to be bound (use db.prepare().bind)
439
+ * Returns a select query for a single model by primary key, creating a CTE view using the provided include tree.
440
+ *
441
+ * @param ctor The model constructor.
442
+ * @param includeTree An include tree describing which related models to join.
443
+ *
444
+ * ### Example:
445
+ * ```ts
446
+ * // Using a data source
447
+ * const query = Orm.getQuery(Person, "default");
448
+ * ```
449
+ *
450
+ * ### Example SQL output:
451
+ *
452
+ * ```sql
453
+ * WITH Person_view AS (
454
+ * SELECT
455
+ * "Person"."id" AS "id",
456
+ * ...
457
+ * FROM "Person"
458
+ * LEFT JOIN ...
459
+ * )
460
+ * SELECT * FROM Person_view WHERE [Person].[id] = ?
461
+ * ```
442
462
  */
443
- static getQuery<T extends object>(ctor: new () => T, includeTree?: KeysOfType<T, IncludeTree<T>> | null): string;
463
+ static getQuery<T extends object>(ctor: new () => T, includeTree?: IncludeTree<T> | null): Either<string, string>;
444
464
  /**
445
- * Executes a query of the form `SELECT * FROM [Model.DataSource]`, returning all results
446
- * as instantiated models.
465
+ * Retrieves all instances of a model from the database.
466
+ * @param ctor The model constructor.
467
+ * @param includeTree An include tree describing which related models to join.
468
+ * @param from An optional custom `FROM` clause to use instead of the base table.
469
+ * @returns Either an error string, or an array of model instances.
470
+ *
471
+ * ### Example:
472
+ * ```ts
473
+ * const orm = Orm.fromD1(env.db);
474
+ * const horses = await orm.list(Horse, Horse.default);
475
+ * ```
476
+ *
477
+ * ### Example with custom from:
478
+ * ```ts
479
+ * const orm = Orm.fromD1(env.db);
480
+ * const adultHorses = await orm.list(Horse, Horse.default, "SELECT * FROM Horse ORDER BY age DESC LIMIT 10");
481
+ * ```
482
+ *
483
+ * =>
484
+ *
485
+ * ```sql
486
+ * SELECT
487
+ * "Horse"."id" AS "id",
488
+ * ...
489
+ * FROM (SELECT * FROM Horse ORDER BY age DESC LIMIT 10)
490
+ * LEFT JOIN ...
491
+ * ```
492
+ *
447
493
  */
448
- list<T extends object>(ctor: new () => T, includeTreeKey?: KeysOfType<T, IncludeTree<T>> | null): Promise<Either<string, T[]>>;
494
+ list<T extends object>(ctor: new () => T, opts: {
495
+ includeTree?: IncludeTree<T> | null;
496
+ from?: string;
497
+ }): Promise<Either<string, T[]>>;
449
498
  /**
450
- * Executes a query of the form `SELECT * FROM [Model.DataSource] WHERE [Model.PrimaryKey] = ?`
451
- * returning all results as instantiated models.
499
+ * Retrieves a single model by primary key.
500
+ * @param ctor The model constructor.
501
+ * @param id The primary key value.
502
+ * @param includeTree An include tree describing which related models to join.
503
+ * @returns Either an error string, or the model instance (null if not found).
504
+ *
505
+ * ### Example:
506
+ * ```ts
507
+ * const orm = Orm.fromD1(env.db);
508
+ * const horse = await orm.get(Horse, 1, Horse.default);
509
+ * ```
452
510
  */
453
- get<T extends object>(ctor: new () => T, id: any, includeTreeKey?: KeysOfType<T, IncludeTree<T>> | null): Promise<Either<string, T>>;
511
+ get<T extends object>(ctor: new () => T, id: any, includeTree?: IncludeTree<T> | null): Promise<Either<string, T | null>>;
454
512
  }
455
513
  //# sourceMappingURL=backend.d.ts.map
@@ -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,EACL,QAAQ,EACR,WAAW,EACX,MAAM,EACN,UAAU,EAGX,MAAM,cAAc,CAAC;AAQtB,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,YAAY,EACV,UAAU,EACV,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,QAAQ,GACT,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,EAAE,EAAE,cAAyB,CAAC;AAE3C;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc,EAAE,cAAyB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,WAAW,EAAE,cAAyB,CAAC;AAEpD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,UAAU,EAAE,iBAA4B,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,GAAG,EAAE,eAA0B,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,IAAI,EAAE,eAA0B,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,GAAG,EAAE,eAA0B,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,eAA0B,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,eAA0B,CAAC;AAChD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,eAAO,MAAM,UAAU,EAAE,iBAA4B,CAAC;AAEtD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,GACnB,GAAG,MAAM,KAAG,iBACL,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ,GAClB,GAAG,MAAM,KAAG,iBACL,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,GACpB,GAAG,MAAM,KAAG,iBACL,CAAC;AAEX;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU,GACpB,CAAC,EAAE,GAAG,CAAC,GAAG,MAAM,KAAG,iBACZ,CAAC;AAEX;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,MAAM,EAAE,kBAA6B,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,IAAI,GACd,QAAQ,QAAQ,EAAE,KAAG,cACd,CAAC;AAEX,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,SAAS,GAC7C,KAAK,GACL;KACG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GACrC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAC3B,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACnC,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,aAAa,CAAA;CAAE,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,MAAM,IAAI,CACzC,UAAU,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAC7B,MAAM,CACT,GAAG;IAAE,OAAO,CAAC,EAAE,YAAY,CAAA;CAAE,CAAC;AAE/B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,OAAO,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC;AAEvD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,GAAG;IACM,OAAO,CAAC,EAAE;IAA9B,OAAO;IAEP;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,GAAG,GAAG;IAIlC;;;;;;;OAOG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,MAAM,EAC5B,IAAI,EAAE,UAAU,CAAC,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAC9B,WAAW,GAAE,WAAW,CAAC,CAAC,CAAC,GAAG,IAAW,GACxC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;IAItB;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,MAAM,EACjC,IAAI,EAAE,UAAU,CAAC,EACjB,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EACxB,WAAW,GAAE,WAAW,CAAC,CAAC,CAAC,GAAG,IAAW,GACxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAUzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACG,MAAM,CAAC,CAAC,SAAS,MAAM,EAC3B,IAAI,EAAE,UAAU,CAAC,EACjB,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EACxB,WAAW,GAAE,WAAW,CAAC,CAAC,CAAC,GAAG,IAAW,GACxC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAuC/B;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,MAAM,EAC/B,IAAI,EAAE,UAAU,CAAC,EACjB,WAAW,GAAE,UAAU,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAW,GACvD,MAAM;IAQT;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,MAAM,EAC9B,IAAI,EAAE,UAAU,CAAC,EACjB,WAAW,GAAE,UAAU,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAW,GACvD,MAAM;IAST;;;OAGG;IACG,IAAI,CAAC,CAAC,SAAS,MAAM,EACzB,IAAI,EAAE,UAAU,CAAC,EACjB,cAAc,GAAE,UAAU,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAW,GAC1D,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAsB/B;;;OAGG;IACG,GAAG,CAAC,CAAC,SAAS,MAAM,EACxB,IAAI,EAAE,UAAU,CAAC,EACjB,EAAE,EAAE,GAAG,EACP,cAAc,GAAE,UAAU,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAW,GAC1D,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CAqB9B"}
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/ui/backend.ts"],"names":[],"mappings":"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"}