cloesce 0.0.4-unstable.3 → 0.0.4-unstable.4

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/README.md CHANGED
@@ -17,8 +17,7 @@ Internal documentation going over design decisions and general thoughts for each
17
17
  - Create an NPM project and install cloesce
18
18
 
19
19
  ```sh
20
- # check https://www.npmjs.com/package/cloesce/v/0.0.4-unstable.0?activeTab=versions for the most recent patch
21
- npm i cloesce@0.0.4-unstable.2
20
+ npm i cloesce@0.0.4-unstable.3
22
21
  ```
23
22
 
24
23
  2. TypeScript
@@ -293,7 +292,7 @@ export class Person {
293
292
  .bind(id)
294
293
  .run();
295
294
 
296
- let persons = Orm.fromSql(Person, records.results, Person.default);
295
+ let persons = Orm.mapSql(Person, records.results, Person.default);
297
296
  return persons.value[0];
298
297
  }
299
298
  }
@@ -495,10 +494,12 @@ class Horse {
495
494
 
496
495
  ### CRUD Methods
497
496
 
498
- Generic GET, POST, PATCH (and in a future version, DEL) boilerplate methods do not need to be copied around. Cloesce supports CRUD generation, a syntactic sugar that adds the methods to the compiler output.
497
+ Generic `GET, POST, PATCH` (and in a future version, DEL) boilerplate methods do not need to be copied around. Cloesce supports CRUD generation, a syntactic sugar that adds the methods to the compiler output.
498
+
499
+ The `SAVE` method is an `upsert`, meaning it both inserts and updates in the same query.
499
500
 
500
501
  ```ts
501
- @CRUD(["POST", "GET", "LIST"])
502
+ @CRUD(["SAVE", "GET", "LIST"])
502
503
  @D1
503
504
  export class CrudHaver {
504
505
  @PrimaryKey
package/dist/common.d.ts CHANGED
@@ -1,18 +1,3 @@
1
- type DeepPartialInner<T> = T extends (infer U)[] ? DeepPartialInner<U>[] : T extends object ? {
2
- [K in keyof T]?: DeepPartialInner<T[K]>;
3
- } : T | (null extends T ? null : never);
4
- export type DeepPartial<T> = DeepPartialInner<T> & {
5
- __brand?: "Partial";
6
- };
7
- export type Either<L, R> = {
8
- ok: false;
9
- value: L;
10
- } | {
11
- ok: true;
12
- value: R;
13
- };
14
- export declare function left<L>(value: L): Either<L, never>;
15
- export declare function right<R>(value: R): Either<never, R>;
16
1
  export declare enum ExtractorErrorCode {
17
2
  MissingExport = 0,
18
3
  AppMissingDefaultExport = 1,
@@ -44,6 +29,141 @@ export declare class ExtractorError {
44
29
  constructor(code: ExtractorErrorCode);
45
30
  addContext(fn: (val: string | undefined) => string | undefined): void;
46
31
  }
32
+ type DeepPartialInner<T> = T extends (infer U)[] ? DeepPartialInner<U>[] : T extends object ? {
33
+ [K in keyof T]?: DeepPartialInner<T[K]>;
34
+ } : T | (null extends T ? null : never);
35
+ /**
36
+ * Recursively makes all properties of a type optional — including nested objects and arrays.
37
+ *
38
+ * Similar to TypeScript's built-in `Partial<T>`, but applies the transformation deeply across
39
+ * all nested structures. Useful for defining "patch" or "update" objects where only a subset
40
+ * of properties may be provided.
41
+ *
42
+ * **Apart of the Cloesce method grammar**, meaning the type can be apart of method parameters
43
+ * or return types and the generated workers and client API will act accordingly.
44
+ *
45
+ * @template T
46
+ * The target type to make deeply partial.
47
+ *
48
+ * @remarks
49
+ * - **Objects:** All properties become optional, and their values are recursively wrapped in `DeepPartial`.
50
+ * - **Arrays:** Arrays are preserved, but their elements are recursively made partial.
51
+ * - **Scalars:** Primitive values (string, number, boolean, etc.) remain unchanged.
52
+ * - **Nullable types:** If `null` is assignable to the type, it remains allowed.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * class User {
57
+ * id: string;
58
+ * profile: {
59
+ * name: string;
60
+ * age: number;
61
+ * };
62
+ * tags: string[];
63
+ * }
64
+ *
65
+ * // The resulting type:
66
+ * // {
67
+ * // id?: string;
68
+ * // profile?: { name?: string; age?: number };
69
+ * // tags?: (string | undefined)[];
70
+ * // }
71
+ * type PartialUser = DeepPartial<User>;
72
+ *
73
+ * const patch: PartialUser = {
74
+ * profile: { age: 30 } // ok
75
+ * };
76
+ * ```
77
+ */
78
+ export type DeepPartial<T> = DeepPartialInner<T> & {
79
+ __brand?: "Partial";
80
+ };
81
+ /**
82
+ * A functional result type representing a computation that can either succeed (`ok: true`)
83
+ * or fail (`ok: false`).
84
+ *
85
+ * `Either<L, R>` is used throughout Cloesce to return structured success/error values
86
+ * instead of throwing exceptions.
87
+ * - When `ok` is `true`, `value` contains the success result of type `R`.
88
+ * - When `ok` is `false`, `value` contains the error information of type `L`.
89
+ *
90
+ * This pattern makes control flow predictable and encourages explicit handling
91
+ * of failure cases.
92
+ *
93
+ * Example:
94
+ * ```ts
95
+ * const result: Either<string, number> = compute();
96
+ *
97
+ * if (!result.ok) {
98
+ * console.error("Failed:", result.value);
99
+ * } else {
100
+ * console.log("Success:", result.value);
101
+ * }
102
+ * ```
103
+ */
104
+ export type Either<L, R> = {
105
+ ok: false;
106
+ value: L;
107
+ } | {
108
+ ok: true;
109
+ value: R;
110
+ };
111
+ /**
112
+ * Creates a failed `Either` result.
113
+ *
114
+ * Typically used to represent an error condition or unsuccessful operation.
115
+ *
116
+ * @param value The error or failure value to wrap.
117
+ * @returns An `Either` with `ok: false` and the given value.
118
+ */
119
+ export declare function left<L>(value: L): Either<L, never>;
120
+ /**
121
+ * Creates a successful `Either` result.
122
+ *
123
+ * Typically used to represent a successful operation while maintaining
124
+ * a consistent `Either`-based return type.
125
+ *
126
+ * @param value The success value to wrap.
127
+ * @returns An `Either` with `ok: true` and the given value.
128
+ */
129
+ export declare function right<R>(value: R): Either<never, R>;
130
+ /**
131
+ * Represents the result of an HTTP operation in a monadic style.
132
+ *
133
+ * This type provides a uniform way to handle both success and error
134
+ * outcomes of HTTP requests, similar to a `Result` or `Either` monad.
135
+ *
136
+ * It ensures that every HTTP response can be handled in a type-safe,
137
+ * predictable way without throwing exceptions.
138
+ *
139
+ * @template T The type of the successful response data.
140
+ *
141
+ * @property {boolean} ok
142
+ * Indicates whether the HTTP request was successful (`true` for success, `false` for error).
143
+ * This is analogous to `Response.ok` in the Fetch API.
144
+ *
145
+ * @property {number} status
146
+ * The numeric HTTP status code (e.g., 200, 404, 500).
147
+ *
148
+ * @property {T} [data]
149
+ * The parsed response payload, present only when `ok` is `true`.
150
+ *
151
+ * @property {string} [message]
152
+ * An optional human-readable error message or diagnostic information,
153
+ * typically provided when `ok` is `false`.
154
+ *
155
+ * ## Worker APIs
156
+ *
157
+ * HttpResult is a first-class-citizen in the grammar in Cloesce. Methods can return HttpResults
158
+ * which will be serialized on the client api.
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * bar(): HttpResult<Integer> {
163
+ * return { ok: false, status: 401, message: "forbidden"}
164
+ * }
165
+ * ```
166
+ */
47
167
  export type HttpResult<T = unknown> = {
48
168
  ok: boolean;
49
169
  status: number;
@@ -61,18 +181,93 @@ export type KeysOfType<T, U> = {
61
181
  [K in keyof T]: T[K] extends U ? (K extends string ? K : never) : never;
62
182
  }[keyof T];
63
183
  /**
64
- * A container for middleware. If an instance is exported from `app.cloesce.ts`, it will be used in the
65
- * appropriate location, with global middleware happening before any routing occurs.
184
+ * Represents the core middleware container for a Cloesce application.
185
+ *
186
+ * The `CloesceApp` class provides scoped middleware registration and
187
+ * management across three primary levels of execution:
188
+ *
189
+ * 1. **Global Middleware** — Executed before any routing or model resolution occurs.
190
+ * 2. **Model-Level Middleware** — Executed for requests targeting a specific model type.
191
+ * 3. **Method-Level Middleware** — Executed for requests targeting a specific method on a model.
192
+ *
193
+ * When an instance of `CloesceApp` is exported from `app.cloesce.ts`,
194
+ * it becomes the central container that the Cloesce runtime uses to
195
+ * assemble and apply middleware in the correct execution order.
196
+ *
197
+ * ### Middleware Execution Order
198
+ * Middleware is executed in FIFO order per scope. For example:
199
+ * ```ts
200
+ * app.use(Foo, A);
201
+ * app.use(Foo, B);
202
+ * app.use(Foo, C);
203
+ * // Executed in order: A → B → C
204
+ * ```
205
+ *
206
+ * Each middleware function (`MiddlewareFn`) can optionally short-circuit
207
+ * execution by returning a result, in which case subsequent middleware
208
+ * at the same or lower scope will not run.
209
+ *
210
+ * ### Example Usage
211
+ * ```ts
212
+ * import { app } from "cloesce";
213
+ *
214
+ * // Global authentication middleware
215
+ * app.useGlobal((request, env, di) => {
216
+ * // ... authenticate and inject user
217
+ * });
218
+ *
219
+ * // Model-level authorization
220
+ * app.useModel(User, (user) => user.hasPermissions([UserPermissions.canUseFoo]));
221
+ *
222
+ * // Method-level middleware (e.g., CRUD operation)
223
+ * app.useMethod(Foo, "someMethod", (user) => user.hasPermissions([UserPermissions.canUseFooMethod]));
224
+ * ```
66
225
  */
67
226
  export declare class CloesceApp {
68
227
  global: MiddlewareFn[];
69
228
  model: Map<string, MiddlewareFn[]>;
70
229
  method: Map<string, Map<string, MiddlewareFn[]>>;
230
+ /**
231
+ * Registers a new global middleware function.
232
+ *
233
+ * Global middleware runs before all routing and model resolution.
234
+ * It is the ideal place to perform tasks such as:
235
+ * - Authentication (e.g., JWT verification)
236
+ * - Global request logging
237
+ * - Dependency injection of shared context
238
+ *
239
+ * @param m - The middleware function to register.
240
+ */
71
241
  useGlobal(m: MiddlewareFn): void;
242
+ /**
243
+ * Registers middleware for a specific model type.
244
+ *
245
+ * Model-level middleware runs after all global middleware,
246
+ * but before method-specific middleware. This scope allows
247
+ * logic to be applied consistently across all endpoints
248
+ * associated with a given model (e.g., authorization).
249
+ *
250
+ * @typeParam T - The model type.
251
+ * @param ctor - The model constructor (used to derive its name).
252
+ * @param m - The middleware function to register.
253
+ */
72
254
  useModel<T>(ctor: new () => T, m: MiddlewareFn): void;
255
+ /**
256
+ * Registers middleware for a specific method on a model.
257
+ *
258
+ * Method-level middleware is executed after model middleware,
259
+ * and before the method implementation itself. It can be used for:
260
+ * - Fine-grained permission checks
261
+ * - Custom logging or tracing per endpoint
262
+ *
263
+ * @typeParam T - The model type.
264
+ * @param ctor - The model constructor (used to derive its name).
265
+ * @param method - The method name on the model.
266
+ * @param m - The middleware function to register.
267
+ */
73
268
  useMethod<T>(ctor: new () => T, method: KeysOfType<T, (...args: any) => any>, m: MiddlewareFn): void;
74
269
  }
75
- export type CrudKind = "POST" | "GET" | "LIST";
270
+ export type CrudKind = "SAVE" | "GET" | "LIST";
76
271
  export type CidlType = "Void" | "Integer" | "Real" | "Text" | "Blob" | "DateIso" | "Boolean" | {
77
272
  DataSource: string;
78
273
  } | {
@@ -137,6 +332,7 @@ export interface Model {
137
332
  navigation_properties: NavigationProperty[];
138
333
  methods: Record<string, ModelMethod>;
139
334
  data_sources: Record<string, DataSource>;
335
+ cruds: CrudKind[];
140
336
  source_path: string;
141
337
  }
142
338
  export interface PlainOldObject {
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"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"}
package/dist/common.js CHANGED
@@ -1,9 +1,3 @@
1
- export function left(value) {
2
- return { ok: false, value };
3
- }
4
- export function right(value) {
5
- return { ok: true, value };
6
- }
7
1
  export var ExtractorErrorCode;
8
2
  (function (ExtractorErrorCode) {
9
3
  ExtractorErrorCode[ExtractorErrorCode["MissingExport"] = 0] = "MissingExport";
@@ -114,16 +108,101 @@ export class ExtractorError {
114
108
  }
115
109
  }
116
110
  /**
117
- * A container for middleware. If an instance is exported from `app.cloesce.ts`, it will be used in the
118
- * appropriate location, with global middleware happening before any routing occurs.
111
+ * Creates a failed `Either` result.
112
+ *
113
+ * Typically used to represent an error condition or unsuccessful operation.
114
+ *
115
+ * @param value The error or failure value to wrap.
116
+ * @returns An `Either` with `ok: false` and the given value.
117
+ */
118
+ export function left(value) {
119
+ return { ok: false, value };
120
+ }
121
+ /**
122
+ * Creates a successful `Either` result.
123
+ *
124
+ * Typically used to represent a successful operation while maintaining
125
+ * a consistent `Either`-based return type.
126
+ *
127
+ * @param value The success value to wrap.
128
+ * @returns An `Either` with `ok: true` and the given value.
129
+ */
130
+ export function right(value) {
131
+ return { ok: true, value };
132
+ }
133
+ /**
134
+ * Represents the core middleware container for a Cloesce application.
135
+ *
136
+ * The `CloesceApp` class provides scoped middleware registration and
137
+ * management across three primary levels of execution:
138
+ *
139
+ * 1. **Global Middleware** — Executed before any routing or model resolution occurs.
140
+ * 2. **Model-Level Middleware** — Executed for requests targeting a specific model type.
141
+ * 3. **Method-Level Middleware** — Executed for requests targeting a specific method on a model.
142
+ *
143
+ * When an instance of `CloesceApp` is exported from `app.cloesce.ts`,
144
+ * it becomes the central container that the Cloesce runtime uses to
145
+ * assemble and apply middleware in the correct execution order.
146
+ *
147
+ * ### Middleware Execution Order
148
+ * Middleware is executed in FIFO order per scope. For example:
149
+ * ```ts
150
+ * app.use(Foo, A);
151
+ * app.use(Foo, B);
152
+ * app.use(Foo, C);
153
+ * // Executed in order: A → B → C
154
+ * ```
155
+ *
156
+ * Each middleware function (`MiddlewareFn`) can optionally short-circuit
157
+ * execution by returning a result, in which case subsequent middleware
158
+ * at the same or lower scope will not run.
159
+ *
160
+ * ### Example Usage
161
+ * ```ts
162
+ * import { app } from "cloesce";
163
+ *
164
+ * // Global authentication middleware
165
+ * app.useGlobal((request, env, di) => {
166
+ * // ... authenticate and inject user
167
+ * });
168
+ *
169
+ * // Model-level authorization
170
+ * app.useModel(User, (user) => user.hasPermissions([UserPermissions.canUseFoo]));
171
+ *
172
+ * // Method-level middleware (e.g., CRUD operation)
173
+ * app.useMethod(Foo, "someMethod", (user) => user.hasPermissions([UserPermissions.canUseFooMethod]));
174
+ * ```
119
175
  */
120
176
  export class CloesceApp {
121
177
  global = [];
122
178
  model = new Map();
123
179
  method = new Map();
180
+ /**
181
+ * Registers a new global middleware function.
182
+ *
183
+ * Global middleware runs before all routing and model resolution.
184
+ * It is the ideal place to perform tasks such as:
185
+ * - Authentication (e.g., JWT verification)
186
+ * - Global request logging
187
+ * - Dependency injection of shared context
188
+ *
189
+ * @param m - The middleware function to register.
190
+ */
124
191
  useGlobal(m) {
125
192
  this.global.push(m);
126
193
  }
194
+ /**
195
+ * Registers middleware for a specific model type.
196
+ *
197
+ * Model-level middleware runs after all global middleware,
198
+ * but before method-specific middleware. This scope allows
199
+ * logic to be applied consistently across all endpoints
200
+ * associated with a given model (e.g., authorization).
201
+ *
202
+ * @typeParam T - The model type.
203
+ * @param ctor - The model constructor (used to derive its name).
204
+ * @param m - The middleware function to register.
205
+ */
127
206
  useModel(ctor, m) {
128
207
  if (this.model.has(ctor.name)) {
129
208
  this.model.get(ctor.name).push(m);
@@ -132,6 +211,19 @@ export class CloesceApp {
132
211
  this.model.set(ctor.name, [m]);
133
212
  }
134
213
  }
214
+ /**
215
+ * Registers middleware for a specific method on a model.
216
+ *
217
+ * Method-level middleware is executed after model middleware,
218
+ * and before the method implementation itself. It can be used for:
219
+ * - Fine-grained permission checks
220
+ * - Custom logging or tracing per endpoint
221
+ *
222
+ * @typeParam T - The model type.
223
+ * @param ctor - The model constructor (used to derive its name).
224
+ * @param method - The method name on the model.
225
+ * @param m - The middleware function to register.
226
+ */
135
227
  useMethod(ctor, method, m) {
136
228
  if (!this.method.has(ctor.name)) {
137
229
  this.method.set(ctor.name, new Map());
@@ -1,5 +1,5 @@
1
1
  import { Project, Type, SourceFile, MethodDeclaration, ClassDeclaration, Expression } from "ts-morph";
2
- import { CidlIncludeTree, CloesceAst, CidlType, Either, HttpVerb, Model, ModelMethod, NamedTypedValue, WranglerEnv, ExtractorError, PlainOldObject, CrudKind } from "../common.js";
2
+ import { CidlIncludeTree, CloesceAst, CidlType, Either, HttpVerb, Model, ModelMethod, WranglerEnv, ExtractorError, PlainOldObject } from "../common.js";
3
3
  export declare class CidlExtractor {
4
4
  projectName: string;
5
5
  version: string;
@@ -13,6 +13,5 @@ export declare class CidlExtractor {
13
13
  static cidlType(type: Type, inject?: boolean): Either<ExtractorError, CidlType>;
14
14
  static includeTree(expr: Expression | undefined, currentClass: ClassDeclaration, sf: SourceFile): Either<ExtractorError, CidlIncludeTree>;
15
15
  static method(modelName: string, method: MethodDeclaration, httpVerb: HttpVerb): Either<ExtractorError, ModelMethod>;
16
- static crudMethod(crud: CrudKind, primaryKey: NamedTypedValue, modelName: string): ModelMethod;
17
16
  }
18
17
  //# sourceMappingURL=extract.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/extractor/extract.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,OAAO,EACP,IAAI,EACJ,UAAU,EAEV,iBAAiB,EAEjB,gBAAgB,EAEhB,UAAU,EAEX,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,eAAe,EACf,UAAU,EACV,QAAQ,EAER,MAAM,EACN,QAAQ,EACR,KAAK,EAEL,WAAW,EACX,eAAe,EAEf,WAAW,EAGX,cAAc,EAEd,cAAc,EAEd,QAAQ,EACT,MAAM,cAAc,CAAC;AAuBtB,qBAAa,aAAa;IAEf,WAAW,EAAE,MAAM;IACnB,OAAO,EAAE,MAAM;gBADf,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM;IAGxB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,cAAc,EAAE,UAAU,CAAC;IA8F7D,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC;IA8BlE,MAAM,CAAC,KAAK,CACV,SAAS,EAAE,gBAAgB,EAC3B,UAAU,EAAE,UAAU,GACrB,MAAM,CAAC,cAAc,EAAE,KAAK,CAAC;IAsQhC,MAAM,CAAC,GAAG,CACR,SAAS,EAAE,gBAAgB,EAC3B,UAAU,EAAE,UAAU,GACrB,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC;IAmCzC,MAAM,CAAC,GAAG,CACR,SAAS,EAAE,gBAAgB,EAC3B,UAAU,EAAE,UAAU,GACrB,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC;IAuBtC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CASjC;IAEF,MAAM,CAAC,QAAQ,CACb,IAAI,EAAE,IAAI,EACV,MAAM,GAAE,OAAe,GACtB,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC;IAsJnC,MAAM,CAAC,WAAW,CAChB,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,YAAY,EAAE,gBAAgB,EAC9B,EAAE,EAAE,UAAU,GACb,MAAM,CAAC,cAAc,EAAE,eAAe,CAAC;IAiF1C,MAAM,CAAC,MAAM,CACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,QAAQ,GACjB,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC;IA2EtC,MAAM,CAAC,UAAU,CACf,IAAI,EAAE,QAAQ,EACd,UAAU,EAAE,eAAe,EAC3B,SAAS,EAAE,MAAM,GAChB,WAAW;CAkDf"}
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/extractor/extract.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,OAAO,EACP,IAAI,EACJ,UAAU,EAEV,iBAAiB,EAEjB,gBAAgB,EAEhB,UAAU,EAEX,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,eAAe,EACf,UAAU,EACV,QAAQ,EAER,MAAM,EACN,QAAQ,EACR,KAAK,EAEL,WAAW,EAGX,WAAW,EAGX,cAAc,EAEd,cAAc,EAGf,MAAM,cAAc,CAAC;AAuBtB,qBAAa,aAAa;IAEf,WAAW,EAAE,MAAM;IACnB,OAAO,EAAE,MAAM;gBADf,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM;IAGxB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,cAAc,EAAE,UAAU,CAAC;IA8F7D,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC;IA8BlE,MAAM,CAAC,KAAK,CACV,SAAS,EAAE,gBAAgB,EAC3B,UAAU,EAAE,UAAU,GACrB,MAAM,CAAC,cAAc,EAAE,KAAK,CAAC;IAgQhC,MAAM,CAAC,GAAG,CACR,SAAS,EAAE,gBAAgB,EAC3B,UAAU,EAAE,UAAU,GACrB,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC;IAmCzC,MAAM,CAAC,GAAG,CACR,SAAS,EAAE,gBAAgB,EAC3B,UAAU,EAAE,UAAU,GACrB,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC;IAuBtC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CASjC;IAEF,MAAM,CAAC,QAAQ,CACb,IAAI,EAAE,IAAI,EACV,MAAM,GAAE,OAAe,GACtB,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC;IAsJnC,MAAM,CAAC,WAAW,CAChB,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,YAAY,EAAE,gBAAgB,EAC9B,EAAE,EAAE,UAAU,GACb,MAAM,CAAC,cAAc,EAAE,eAAe,CAAC;IAiF1C,MAAM,CAAC,MAAM,CACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,QAAQ,GACjB,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC;CA0EvC"}
@@ -131,17 +131,17 @@ export class CidlExtractor {
131
131
  static model(classDecl, sourceFile) {
132
132
  const name = classDecl.getName();
133
133
  const attributes = [];
134
- const navigationProperties = [];
135
- const dataSources = {};
134
+ const navigation_properties = [];
135
+ const data_sources = {};
136
136
  const methods = {};
137
- let cruds = [];
137
+ const cruds = new Set();
138
138
  let primary_key = undefined;
139
139
  // Extract crud methods
140
140
  const crudDecorator = classDecl
141
141
  .getDecorators()
142
142
  .find((d) => getDecoratorName(d) === ClassDecoratorKind.CRUD);
143
143
  if (crudDecorator) {
144
- cruds = getCrudKinds(crudDecorator);
144
+ setCrudKinds(crudDecorator, cruds);
145
145
  }
146
146
  // Iterate attribtutes
147
147
  for (const prop of classDecl.getProperties()) {
@@ -215,7 +215,7 @@ export class CidlExtractor {
215
215
  e.context = prop.getName();
216
216
  });
217
217
  }
218
- navigationProperties.push({
218
+ navigation_properties.push({
219
219
  var_name: prop.getName(),
220
220
  model_name,
221
221
  kind: { OneToOne: { reference } },
@@ -239,7 +239,7 @@ export class CidlExtractor {
239
239
  e.context = prop.getName();
240
240
  });
241
241
  }
242
- navigationProperties.push({
242
+ navigation_properties.push({
243
243
  var_name: prop.getName(),
244
244
  model_name,
245
245
  kind: { OneToMany: { reference } },
@@ -262,7 +262,7 @@ export class CidlExtractor {
262
262
  e.context = prop.getName();
263
263
  });
264
264
  }
265
- navigationProperties.push({
265
+ navigation_properties.push({
266
266
  var_name: prop.getName(),
267
267
  model_name,
268
268
  kind: { ManyToMany: { unique_id } },
@@ -287,7 +287,7 @@ export class CidlExtractor {
287
287
  treeRes.value.snippet = prop.getText();
288
288
  return treeRes;
289
289
  }
290
- dataSources[prop.getName()] = {
290
+ data_sources[prop.getName()] = {
291
291
  name: prop.getName(),
292
292
  tree: treeRes.value,
293
293
  };
@@ -316,19 +316,14 @@ export class CidlExtractor {
316
316
  }
317
317
  methods[result.value.name] = result.value;
318
318
  }
319
- // Add CRUD methods
320
- for (const crud of cruds) {
321
- // TODO: This overwrites any exisiting impl-- is that what we want?
322
- const crudMethod = CidlExtractor.crudMethod(crud, primary_key, name);
323
- methods[crudMethod.name] = crudMethod;
324
- }
325
319
  return right({
326
320
  name,
327
321
  attributes,
328
322
  primary_key,
329
- navigation_properties: navigationProperties,
323
+ navigation_properties,
330
324
  methods,
331
- data_sources: dataSources,
325
+ data_sources,
326
+ cruds: Array.from(cruds).sort(),
332
327
  source_path: sourceFile.getFilePath().toString(),
333
328
  });
334
329
  }
@@ -611,56 +606,6 @@ export class CidlExtractor {
611
606
  parameters,
612
607
  });
613
608
  }
614
- static crudMethod(crud, primaryKey, modelName) {
615
- // TODO: Should this impementation be in some JSON project file s.t. other
616
- // langs can use it?
617
- return {
618
- POST: {
619
- name: "post",
620
- is_static: true,
621
- http_verb: HttpVerb.POST,
622
- return_type: { HttpResult: { Object: modelName } },
623
- parameters: [
624
- {
625
- name: "obj",
626
- cidl_type: { Partial: modelName },
627
- },
628
- {
629
- name: "dataSource",
630
- cidl_type: { DataSource: modelName },
631
- },
632
- ],
633
- },
634
- GET: {
635
- name: "get",
636
- is_static: true,
637
- http_verb: HttpVerb.GET,
638
- return_type: { HttpResult: { Object: modelName } },
639
- parameters: [
640
- {
641
- name: "id",
642
- cidl_type: primaryKey.cidl_type,
643
- },
644
- {
645
- name: "dataSource",
646
- cidl_type: { DataSource: modelName },
647
- },
648
- ],
649
- },
650
- LIST: {
651
- name: "list",
652
- is_static: true,
653
- http_verb: HttpVerb.GET,
654
- return_type: { HttpResult: { Array: { Object: modelName } } },
655
- parameters: [
656
- {
657
- name: "dataSource",
658
- cidl_type: { DataSource: modelName },
659
- },
660
- ],
661
- },
662
- }[crud];
663
- }
664
609
  }
665
610
  function err(code, fn) {
666
611
  let e = new ExtractorError(code);
@@ -705,18 +650,18 @@ function getObjectName(t) {
705
650
  }
706
651
  return undefined;
707
652
  }
708
- function getCrudKinds(d) {
653
+ function setCrudKinds(d, cruds) {
709
654
  const arg = d.getArguments()[0];
710
- if (!arg)
711
- return [];
655
+ if (!arg) {
656
+ return;
657
+ }
712
658
  if (MorphNode.isArrayLiteralExpression(arg)) {
713
- return arg
714
- .getElements()
715
- .map((e) => (MorphNode.isStringLiteral(e)
716
- ? e.getLiteralValue()
717
- : e.getText()));
659
+ for (const a of arg.getElements()) {
660
+ cruds.add((MorphNode.isStringLiteral(a)
661
+ ? a.getLiteralValue()
662
+ : a.getText()));
663
+ }
718
664
  }
719
- return [];
720
665
  }
721
666
  function findPropertyByName(cls, name) {
722
667
  const exactMatch = cls.getProperties().find((p) => p.getName() === name);
Binary file
package/dist/orm.wasm CHANGED
Binary file
@@ -24,7 +24,7 @@ export class CrudContext {
24
24
  */
25
25
  interceptCrud(methodName) {
26
26
  const map = {
27
- post: this.upsert.bind(this),
27
+ save: this.upsert.bind(this),
28
28
  get: this.get.bind(this),
29
29
  list: this.list.bind(this),
30
30
  };
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/router/router.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,MAAM,EACN,WAAW,EAIX,UAAU,EAEV,KAAK,EAGL,UAAU,EACV,gBAAgB,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,cAAc,EAAwB,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC;;;;;GAKG;AACH,KAAK,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,CAAC,CAAC;AAE9D;;;GAGG;AACH,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C;;GAEG;AACH,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,gBAAgB;aAGT,GAAG,EAAE,UAAU;aACf,mBAAmB,EAAE,wBAAwB;aAC7C,IAAI,EAAE,cAAc;IAJtC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA+B;IACtD,OAAO;WAMM,IAAI,CACf,GAAG,EAAE,UAAU,EACf,mBAAmB,EAAE,wBAAwB,EAC7C,IAAI,CAAC,EAAE,WAAW,CAAC,QAAQ;IAO7B,MAAM,CAAC,GAAG,IAAI,gBAAgB;CAG/B;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,UAAU,EACf,mBAAmB,EAAE,wBAAwB,EAC7C,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,QAAQ,CAAC,CAqFnB;AAED;;;;GAIG;AACH,iBAAS,UAAU,CACjB,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,MAAM,GACf,MAAM,CACP,UAAU,EACV;IACE,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACnB,CACF,CAyCA;AAED;;;;GAIG;AACH,iBAAe,eAAe,CAC5B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,WAAW,EACnB,EAAE,EAAE,MAAM,GAAG,IAAI,GAChB,OAAO,CACR,MAAM,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAC3E,CA4DA;AA2DD;;;GAGG;AACH,iBAAe,cAAc,CAC3B,OAAO,EAAE,WAAW,EACpB,gBAAgB,EAAE,gBAAgB,EAClC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAkD9B;AAkID;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;CAK5B,CAAC"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/router/router.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,MAAM,EACN,WAAW,EAIX,UAAU,EAEV,KAAK,EAGL,UAAU,EACV,gBAAgB,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,cAAc,EAAuB,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC;;;;;GAKG;AACH,KAAK,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,CAAC,CAAC;AAE9D;;;GAGG;AACH,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C;;GAEG;AACH,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,gBAAgB;aAGT,GAAG,EAAE,UAAU;aACf,mBAAmB,EAAE,wBAAwB;aAC7C,IAAI,EAAE,cAAc;IAJtC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA+B;IACtD,OAAO;WAMM,IAAI,CACf,GAAG,EAAE,UAAU,EACf,mBAAmB,EAAE,wBAAwB,EAC7C,IAAI,CAAC,EAAE,WAAW,CAAC,QAAQ;IAO7B,MAAM,CAAC,GAAG,IAAI,gBAAgB;CAG/B;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,UAAU,EACf,mBAAmB,EAAE,wBAAwB,EAC7C,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,QAAQ,CAAC,CAqFnB;AAED;;;;GAIG;AACH,iBAAS,UAAU,CACjB,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,MAAM,GACf,MAAM,CACP,UAAU,EACV;IACE,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACnB,CACF,CAyCA;AAED;;;;GAIG;AACH,iBAAe,eAAe,CAC5B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,WAAW,EACnB,EAAE,EAAE,MAAM,GAAG,IAAI,GAChB,OAAO,CACR,MAAM,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAC3E,CA4DA;AA2DD;;;GAGG;AACH,iBAAe,cAAc,CAC3B,OAAO,EAAE,WAAW,EACpB,gBAAgB,EAAE,gBAAgB,EAClC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAkD9B;AAkID;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;CAK5B,CAAC"}