cloesce 0.0.5-unstable.3 → 0.0.5-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.
@@ -18,15 +18,10 @@ import { ConstructorRegistry } from "./router";
18
18
  * @returns the instantiated value (if applicable). On error, returns null.
19
19
  */
20
20
  export declare class RuntimeValidator {
21
- private ast;
22
- private ctorReg;
23
- constructor(ast: CloesceAst, ctorReg: ConstructorRegistry);
24
- static validate(
25
- value: any,
26
- cidlType: CidlType,
27
- ast: CloesceAst,
28
- ctorReg: ConstructorRegistry,
29
- ): Either<null, any>;
30
- private recurse;
21
+ private ast;
22
+ private ctorReg;
23
+ constructor(ast: CloesceAst, ctorReg: ConstructorRegistry);
24
+ static validate(value: any, cidlType: CidlType, ast: CloesceAst, ctorReg: ConstructorRegistry): Either<null, any>;
25
+ private recurse;
31
26
  }
32
- //# sourceMappingURL=validator.d.ts.map
27
+ //# sourceMappingURL=validator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/router/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,UAAU,EAIX,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,MAAM,EAAW,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,OAAO;gBADP,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,mBAAmB;IAGtC,MAAM,CAAC,QAAQ,CACb,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,mBAAmB,GAC3B,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC;IAIpB,OAAO,CAAC,OAAO;CA8KhB"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/router/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,UAAU,EAIX,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,MAAM,EAAW,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,OAAO;gBADP,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,mBAAmB;IAGtC,MAAM,CAAC,QAAQ,CACb,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,mBAAmB,GAC3B,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC;IAIpB,OAAO,CAAC,OAAO;CA+KhB"}
@@ -1,8 +1,4 @@
1
- import {
2
- NO_DATA_SOURCE,
3
- getNavigationPropertyCidlType,
4
- isNullableType,
5
- } from "../ast";
1
+ import { NO_DATA_SOURCE, getNavigationPropertyCidlType, isNullableType, } from "../ast";
6
2
  import { Either, b64ToU8 } from "../ui/common";
7
3
  /**
8
4
  * Runtime type validation, asserting that the structure of a value follows the
@@ -21,173 +17,164 @@ import { Either, b64ToU8 } from "../ui/common";
21
17
  * @returns the instantiated value (if applicable). On error, returns null.
22
18
  */
23
19
  export class RuntimeValidator {
24
- ast;
25
- ctorReg;
26
- constructor(ast, ctorReg) {
27
- this.ast = ast;
28
- this.ctorReg = ctorReg;
29
- }
30
- static validate(value, cidlType, ast, ctorReg) {
31
- return new RuntimeValidator(ast, ctorReg).recurse(value, cidlType, false);
32
- }
33
- recurse(value, cidlType, isPartial) {
34
- isPartial ||= typeof cidlType !== "string" && "Partial" in cidlType;
35
- if (value === undefined) {
36
- // We will let arrays be undefined and interpret that as an empty array.
37
- if (typeof cidlType !== "string" && "Array" in cidlType) {
38
- return Either.right([]);
39
- }
40
- return rightIf(() => value, isPartial === true);
20
+ ast;
21
+ ctorReg;
22
+ constructor(ast, ctorReg) {
23
+ this.ast = ast;
24
+ this.ctorReg = ctorReg;
41
25
  }
42
- // TODO: consequences of null checking like this? 'null' is passed in
43
- // as a string for GET requests
44
- const nullable = isNullableType(cidlType);
45
- if (value == null || value === "null") {
46
- return rightIf(() => null, nullable);
26
+ static validate(value, cidlType, ast, ctorReg) {
27
+ return new RuntimeValidator(ast, ctorReg).recurse(value, cidlType, false);
47
28
  }
48
- // Unwrap nullable types
49
- if (nullable) {
50
- cidlType = cidlType.Nullable;
51
- }
52
- // Primitives
53
- if (typeof cidlType === "string") {
54
- switch (cidlType) {
55
- case "Integer":
56
- return rightIf(() => Number(value), Number.isInteger(Number(value)));
57
- case "Real":
58
- return rightIf(() => Number(value), !Number.isNaN(Number(value)));
59
- case "Text":
60
- return rightIf(() => String(value), typeof value === "string");
61
- case "Boolean": {
62
- if (typeof value === "boolean") return Either.right(value);
63
- if (value === "true") return Either.right(true);
64
- if (value === "false") return Either.right(false);
65
- return Either.left(null);
29
+ recurse(value, cidlType, isPartial) {
30
+ isPartial ||= typeof cidlType !== "string" && "Partial" in cidlType;
31
+ if (value === undefined) {
32
+ // We will let arrays be undefined and interpret that as an empty array.
33
+ if (typeof cidlType !== "string" && "Array" in cidlType) {
34
+ return Either.right([]);
35
+ }
36
+ return rightIf(() => value, isPartial === true);
66
37
  }
67
- case "DateIso": {
68
- // Instantiate
69
- const date = new Date(value);
70
- return rightIf(() => date, !isNaN(date.getTime()));
38
+ // TODO: consequences of null checking like this? 'null' is passed in
39
+ // as a string for GET requests
40
+ const nullable = isNullableType(cidlType);
41
+ if (value == null || value === "null") {
42
+ // NOTE: Partial types are always nullable.
43
+ return rightIf(() => null, nullable || isPartial);
71
44
  }
72
- case "Blob": {
73
- // Instantiate
74
- return Either.right(b64ToU8(value));
45
+ // Unwrap nullable types
46
+ if (nullable) {
47
+ cidlType = cidlType.Nullable;
75
48
  }
76
- default:
77
- return Either.left(null);
78
- }
79
- }
80
- // Data Sources
81
- if ("DataSource" in cidlType) {
82
- const objectName = cidlType.DataSource;
83
- return rightIf(
84
- () => value,
85
- typeof value === "string" &&
86
- (value === NO_DATA_SOURCE ||
87
- this.ast.models[objectName]?.data_sources[value] !== undefined),
88
- );
89
- }
90
- const objName = getObjectName(cidlType);
91
- // Models
92
- if (objName && this.ast.models[objName]) {
93
- const model = this.ast.models[objName];
94
- if (!model || typeof value !== "object") return Either.left(null);
95
- const valueObj = value;
96
- // Validate + instantiate PK
97
- {
98
- const pk = model.primary_key;
99
- const res = this.recurse(valueObj[pk.name], pk.cidl_type, isPartial);
100
- if (res.isLeft()) {
101
- return res;
49
+ // Primitives
50
+ if (typeof cidlType === "string") {
51
+ switch (cidlType) {
52
+ case "Integer":
53
+ return rightIf(() => Number(value), Number.isInteger(Number(value)));
54
+ case "Real":
55
+ return rightIf(() => Number(value), !Number.isNaN(Number(value)));
56
+ case "Text":
57
+ return rightIf(() => String(value), typeof value === "string");
58
+ case "Boolean": {
59
+ if (typeof value === "boolean")
60
+ return Either.right(value);
61
+ if (value === "true")
62
+ return Either.right(true);
63
+ if (value === "false")
64
+ return Either.right(false);
65
+ return Either.left(null);
66
+ }
67
+ case "DateIso": {
68
+ // Instantiate
69
+ const date = new Date(value);
70
+ return rightIf(() => date, !isNaN(date.getTime()));
71
+ }
72
+ case "Blob": {
73
+ // Instantiate
74
+ return Either.right(b64ToU8(value));
75
+ }
76
+ default:
77
+ return Either.left(null);
78
+ }
102
79
  }
103
- value[pk.name] = res.unwrap();
104
- }
105
- // Validate + instantiate attributes
106
- for (let i = 0; i < model.attributes.length; i++) {
107
- const attr = model.attributes[i];
108
- const res = this.recurse(
109
- valueObj[attr.value.name],
110
- attr.value.cidl_type,
111
- isPartial,
112
- );
113
- if (res.isLeft()) {
114
- return res;
80
+ // Data Sources
81
+ if ("DataSource" in cidlType) {
82
+ const objectName = cidlType.DataSource;
83
+ return rightIf(() => value, typeof value === "string" &&
84
+ (value === NO_DATA_SOURCE ||
85
+ this.ast.models[objectName]?.data_sources[value] !== undefined));
115
86
  }
116
- value[attr.value.name] = res.unwrap();
117
- }
118
- // Validate + instantiate navigation properties
119
- for (let i = 0; i < model.navigation_properties.length; i++) {
120
- const nav = model.navigation_properties[i];
121
- const res = this.recurse(
122
- valueObj[nav.var_name],
123
- getNavigationPropertyCidlType(nav),
124
- isPartial,
125
- );
126
- if (res.isLeft()) {
127
- return res;
87
+ const objName = getObjectName(cidlType);
88
+ // Models
89
+ if (objName && this.ast.models[objName]) {
90
+ const model = this.ast.models[objName];
91
+ if (!model || typeof value !== "object")
92
+ return Either.left(null);
93
+ const valueObj = value;
94
+ // Validate + instantiate PK
95
+ {
96
+ const pk = model.primary_key;
97
+ const res = this.recurse(valueObj[pk.name], pk.cidl_type, isPartial);
98
+ if (res.isLeft()) {
99
+ return res;
100
+ }
101
+ value[pk.name] = res.unwrap();
102
+ }
103
+ // Validate + instantiate attributes
104
+ for (let i = 0; i < model.attributes.length; i++) {
105
+ const attr = model.attributes[i];
106
+ const res = this.recurse(valueObj[attr.value.name], attr.value.cidl_type, isPartial);
107
+ if (res.isLeft()) {
108
+ return res;
109
+ }
110
+ value[attr.value.name] = res.unwrap();
111
+ }
112
+ // Validate + instantiate navigation properties
113
+ for (let i = 0; i < model.navigation_properties.length; i++) {
114
+ const nav = model.navigation_properties[i];
115
+ const res = this.recurse(valueObj[nav.var_name], getNavigationPropertyCidlType(nav), isPartial);
116
+ if (res.isLeft()) {
117
+ return res;
118
+ }
119
+ value[nav.var_name] = res.unwrap();
120
+ }
121
+ // Don't instantiate partials
122
+ if (isPartial) {
123
+ return Either.right(value);
124
+ }
125
+ // Instantiate
126
+ return Either.right(Object.assign(new this.ctorReg[objName](), value));
128
127
  }
129
- value[nav.var_name] = res.unwrap();
130
- }
131
- // Don't instantiate partials
132
- if (isPartial) {
133
- return Either.right(value);
134
- }
135
- // Instantiate
136
- return Either.right(Object.assign(new this.ctorReg[objName](), value));
137
- }
138
- // Plain old Objects
139
- if (objName && this.ast.poos[objName]) {
140
- const poo = this.ast.poos[objName];
141
- if (!poo || typeof value !== "object") return Either.left(null);
142
- const valueObj = value;
143
- // Validate + instantiate attributes
144
- for (let i = 0; i < poo.attributes.length; i++) {
145
- const attr = poo.attributes[i];
146
- const res = this.recurse(
147
- valueObj[attr.name],
148
- attr.cidl_type,
149
- isPartial,
150
- );
151
- if (res.isLeft()) {
152
- return res;
128
+ // Plain old Objects
129
+ if (objName && this.ast.poos[objName]) {
130
+ const poo = this.ast.poos[objName];
131
+ if (!poo || typeof value !== "object")
132
+ return Either.left(null);
133
+ const valueObj = value;
134
+ // Validate + instantiate attributes
135
+ for (let i = 0; i < poo.attributes.length; i++) {
136
+ const attr = poo.attributes[i];
137
+ const res = this.recurse(valueObj[attr.name], attr.cidl_type, isPartial);
138
+ if (res.isLeft()) {
139
+ return res;
140
+ }
141
+ value[attr.name] = res.unwrap();
142
+ }
143
+ if (isPartial) {
144
+ return Either.right(value);
145
+ }
146
+ // Instantiate
147
+ return Either.right(Object.assign(new this.ctorReg[objName](), value));
153
148
  }
154
- value[attr.name] = res.unwrap();
155
- }
156
- if (isPartial) {
157
- return Either.right(value);
158
- }
159
- // Instantiate
160
- return Either.right(Object.assign(new this.ctorReg[objName](), value));
161
- }
162
- // Arrays
163
- if ("Array" in cidlType) {
164
- if (!Array.isArray(value)) {
165
- return Either.left(null);
166
- }
167
- for (let i = 0; i < value.length; i++) {
168
- const res = this.recurse(value[i], cidlType.Array, isPartial);
169
- if (res.isLeft()) {
170
- return res;
149
+ // Arrays
150
+ if ("Array" in cidlType) {
151
+ if (!Array.isArray(value)) {
152
+ return Either.left(null);
153
+ }
154
+ for (let i = 0; i < value.length; i++) {
155
+ const res = this.recurse(value[i], cidlType.Array, isPartial);
156
+ if (res.isLeft()) {
157
+ return res;
158
+ }
159
+ value[i] = res.unwrap();
160
+ }
161
+ return Either.right(value);
171
162
  }
172
- value[i] = res.unwrap();
173
- }
174
- return Either.right(value);
163
+ return Either.left(null);
175
164
  }
176
- return Either.left(null);
177
- }
178
165
  }
179
166
  function getObjectName(ty) {
180
- if (typeof ty === "string") {
167
+ if (typeof ty === "string") {
168
+ return undefined;
169
+ }
170
+ if ("Partial" in ty) {
171
+ return ty.Partial;
172
+ }
173
+ if ("Object" in ty) {
174
+ return ty.Object;
175
+ }
181
176
  return undefined;
182
- }
183
- if ("Partial" in ty) {
184
- return ty.Partial;
185
- }
186
- if ("Object" in ty) {
187
- return ty.Object;
188
- }
189
- return undefined;
190
177
  }
191
178
  function rightIf(value, cond) {
192
- return cond ? Either.right(value()) : Either.left(null);
179
+ return cond ? Either.right(value()) : Either.left(null);
193
180
  }
@@ -5,75 +5,41 @@ import { Either } from "../ui/common.js";
5
5
  * WASM ABI
6
6
  */
7
7
  export interface OrmWasmExports {
8
- memory: WebAssembly.Memory;
9
- get_return_len(): number;
10
- get_return_ptr(): number;
11
- set_meta_ptr(ptr: number, len: number): number;
12
- alloc(len: number): number;
13
- dealloc(ptr: number, len: number): void;
14
- map_sql(
15
- model_name_ptr: number,
16
- model_name_len: number,
17
- sql_rows_ptr: number,
18
- sql_rows_len: number,
19
- include_tree_ptr: number,
20
- include_tree_len: number,
21
- ): boolean;
22
- upsert_model(
23
- model_name_ptr: number,
24
- model_name_len: number,
25
- new_model_ptr: number,
26
- new_model_len: number,
27
- include_tree_ptr: number,
28
- include_tree_len: number,
29
- ): boolean;
30
- list_models(
31
- model_name_ptr: number,
32
- model_name_len: number,
33
- include_tree_ptr: number,
34
- include_tree_len: number,
35
- tag_cte_ptr: number,
36
- tag_cte_len: number,
37
- custom_from_ptr: number,
38
- custom_from_len: number,
39
- ): boolean;
8
+ memory: WebAssembly.Memory;
9
+ get_return_len(): number;
10
+ get_return_ptr(): number;
11
+ set_meta_ptr(ptr: number, len: number): number;
12
+ alloc(len: number): number;
13
+ dealloc(ptr: number, len: number): void;
14
+ 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;
15
+ 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;
16
+ 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;
40
17
  }
41
18
  /**
42
19
  * RAII for wasm memory
43
20
  */
44
21
  export declare class WasmResource {
45
- private wasm;
46
- ptr: number;
47
- len: number;
48
- constructor(wasm: OrmWasmExports, ptr: number, len: number);
49
- free(): void;
50
- /**
51
- * Copies a value from TS memory to WASM memory. A subsequent `free` is necessary.
52
- */
53
- static fromString(str: string, wasm: OrmWasmExports): WasmResource;
22
+ private wasm;
23
+ ptr: number;
24
+ len: number;
25
+ constructor(wasm: OrmWasmExports, ptr: number, len: number);
26
+ free(): void;
27
+ /**
28
+ * Copies a value from TS memory to WASM memory. A subsequent `free` is necessary.
29
+ */
30
+ static fromString(str: string, wasm: OrmWasmExports): WasmResource;
54
31
  }
55
- export declare function loadOrmWasm(
56
- ast: CloesceAst,
57
- wasm?: WebAssembly.Instance,
58
- ): Promise<OrmWasmExports>;
32
+ export declare function loadOrmWasm(ast: CloesceAst, wasm?: WebAssembly.Instance): Promise<OrmWasmExports>;
59
33
  /**
60
34
  * Invokes a WASM ORM function with the provided arguments, handling memory
61
35
  * allocation and deallocation.
62
36
  *
63
37
  * Returns an Either where Left is an error message and Right the raw string result.
64
38
  */
65
- export declare function invokeOrmWasm(
66
- fn: (...args: number[]) => boolean,
67
- args: WasmResource[],
68
- wasm: OrmWasmExports,
69
- ): Either<string, string>;
39
+ export declare function invokeOrmWasm(fn: (...args: number[]) => boolean, args: WasmResource[], wasm: OrmWasmExports): Either<string, string>;
70
40
  /**
71
41
  * Calls the object relational mapping function to turn a row of SQL records into
72
42
  * an instantiated object.
73
43
  */
74
- export declare function mapSql<T extends object>(
75
- ctor: new () => T,
76
- records: Record<string, any>[],
77
- includeTree: IncludeTree<T> | CidlIncludeTree | null,
78
- ): Either<string, T[]>;
79
- //# sourceMappingURL=wasm.d.ts.map
44
+ export declare function mapSql<T extends object>(ctor: new () => T, records: Record<string, any>[], includeTree: IncludeTree<T> | CidlIncludeTree | null): Either<string, T[]>;
45
+ //# sourceMappingURL=wasm.d.ts.map
@@ -6,42 +6,40 @@ import { Either } from "../ui/common.js";
6
6
  * RAII for wasm memory
7
7
  */
8
8
  export class WasmResource {
9
- wasm;
10
- ptr;
11
- len;
12
- constructor(wasm, ptr, len) {
13
- this.wasm = wasm;
14
- this.ptr = ptr;
15
- this.len = len;
16
- }
17
- free() {
18
- this.wasm.dealloc(this.ptr, this.len);
19
- }
20
- /**
21
- * Copies a value from TS memory to WASM memory. A subsequent `free` is necessary.
22
- */
23
- static fromString(str, wasm) {
24
- const encoder = new TextEncoder();
25
- const bytes = encoder.encode(str);
26
- const ptr = wasm.alloc(bytes.length);
27
- const mem = new Uint8Array(wasm.memory.buffer, ptr, bytes.length);
28
- mem.set(bytes);
29
- return new this(wasm, ptr, bytes.length);
30
- }
9
+ wasm;
10
+ ptr;
11
+ len;
12
+ constructor(wasm, ptr, len) {
13
+ this.wasm = wasm;
14
+ this.ptr = ptr;
15
+ this.len = len;
16
+ }
17
+ free() {
18
+ this.wasm.dealloc(this.ptr, this.len);
19
+ }
20
+ /**
21
+ * Copies a value from TS memory to WASM memory. A subsequent `free` is necessary.
22
+ */
23
+ static fromString(str, wasm) {
24
+ const encoder = new TextEncoder();
25
+ const bytes = encoder.encode(str);
26
+ const ptr = wasm.alloc(bytes.length);
27
+ const mem = new Uint8Array(wasm.memory.buffer, ptr, bytes.length);
28
+ mem.set(bytes);
29
+ return new this(wasm, ptr, bytes.length);
30
+ }
31
31
  }
32
32
  export async function loadOrmWasm(ast, wasm) {
33
- // Load WASM
34
- const wasmInstance = wasm ?? (await WebAssembly.instantiate(mod));
35
- const modelMeta = WasmResource.fromString(
36
- JSON.stringify(ast.models),
37
- wasmInstance.exports,
38
- );
39
- if (wasmInstance.exports.set_meta_ptr(modelMeta.ptr, modelMeta.len) != 0) {
40
- modelMeta.free();
41
- throw Error("The WASM Module failed to load due to an invalid CIDL");
42
- }
43
- // Intentionally leak `modelMeta`, it should exist for the programs lifetime.
44
- return wasmInstance.exports;
33
+ // Load WASM
34
+ const wasmInstance = (wasm ??
35
+ (await WebAssembly.instantiate(mod)));
36
+ const modelMeta = WasmResource.fromString(JSON.stringify(ast.models), wasmInstance.exports);
37
+ if (wasmInstance.exports.set_meta_ptr(modelMeta.ptr, modelMeta.len) != 0) {
38
+ modelMeta.free();
39
+ throw Error("The WASM Module failed to load due to an invalid CIDL");
40
+ }
41
+ // Intentionally leak `modelMeta`, it should exist for the programs lifetime.
42
+ return wasmInstance.exports;
45
43
  }
46
44
  /**
47
45
  * Invokes a WASM ORM function with the provided arguments, handling memory
@@ -50,69 +48,59 @@ export async function loadOrmWasm(ast, wasm) {
50
48
  * Returns an Either where Left is an error message and Right the raw string result.
51
49
  */
52
50
  export function invokeOrmWasm(fn, args, wasm) {
53
- let resPtr;
54
- let resLen;
55
- try {
56
- const failed = fn(...args.flatMap((a) => [a.ptr, a.len]));
57
- resPtr = wasm.get_return_ptr();
58
- resLen = wasm.get_return_len();
59
- const result = new TextDecoder().decode(
60
- new Uint8Array(wasm.memory.buffer, resPtr, resLen),
61
- );
62
- return failed ? Either.left(result) : Either.right(result);
63
- } finally {
64
- args.forEach((a) => a.free());
65
- if (resPtr && resLen) wasm.dealloc(resPtr, resLen);
66
- }
51
+ let resPtr;
52
+ let resLen;
53
+ try {
54
+ const failed = fn(...args.flatMap((a) => [a.ptr, a.len]));
55
+ resPtr = wasm.get_return_ptr();
56
+ resLen = wasm.get_return_len();
57
+ const result = new TextDecoder().decode(new Uint8Array(wasm.memory.buffer, resPtr, resLen));
58
+ return failed ? Either.left(result) : Either.right(result);
59
+ }
60
+ finally {
61
+ args.forEach((a) => a.free());
62
+ if (resPtr && resLen)
63
+ wasm.dealloc(resPtr, resLen);
64
+ }
67
65
  }
68
66
  /**
69
67
  * Calls the object relational mapping function to turn a row of SQL records into
70
68
  * an instantiated object.
71
69
  */
72
70
  export function mapSql(ctor, records, includeTree) {
73
- const { ast, constructorRegistry, wasm } = RuntimeContainer.get();
74
- const args = [
75
- WasmResource.fromString(ctor.name, wasm),
76
- WasmResource.fromString(JSON.stringify(records), wasm),
77
- WasmResource.fromString(JSON.stringify(includeTree), wasm),
78
- ];
79
- const jsonResults = invokeOrmWasm(wasm.map_sql, args, wasm);
80
- if (jsonResults.isLeft()) return jsonResults;
81
- const parsed = JSON.parse(jsonResults.value);
82
- return Either.right(
83
- parsed.map((obj) =>
84
- instantiateDepthFirst(obj, ast.models[ctor.name], includeTree),
85
- ),
86
- );
87
- // TODO: Lazy instantiation via Proxy?
88
- function instantiateDepthFirst(m, meta, includeTree) {
89
- m = Object.assign(new constructorRegistry[meta.name](), m);
90
- if (!includeTree) {
91
- return m;
92
- }
93
- for (const navProp of meta.navigation_properties) {
94
- const nestedIncludeTree = includeTree[navProp.var_name];
95
- if (!nestedIncludeTree) continue;
96
- const nestedMeta = ast.models[navProp.model_name];
97
- // One to Many, Many to Many
98
- if (Array.isArray(m[navProp.var_name])) {
99
- for (let i = 0; i < m[navProp.var_name].length; i++) {
100
- m[navProp.var_name][i] = instantiateDepthFirst(
101
- m[navProp.var_name][i],
102
- nestedMeta,
103
- nestedIncludeTree,
104
- );
71
+ const { ast, constructorRegistry, wasm } = RuntimeContainer.get();
72
+ const args = [
73
+ WasmResource.fromString(ctor.name, wasm),
74
+ WasmResource.fromString(JSON.stringify(records), wasm),
75
+ WasmResource.fromString(JSON.stringify(includeTree), wasm),
76
+ ];
77
+ const jsonResults = invokeOrmWasm(wasm.map_sql, args, wasm);
78
+ if (jsonResults.isLeft())
79
+ return jsonResults;
80
+ const parsed = JSON.parse(jsonResults.value);
81
+ return Either.right(parsed.map((obj) => instantiateDepthFirst(obj, ast.models[ctor.name], includeTree)));
82
+ // TODO: Lazy instantiation via Proxy?
83
+ function instantiateDepthFirst(m, meta, includeTree) {
84
+ m = Object.assign(new constructorRegistry[meta.name](), m);
85
+ if (!includeTree) {
86
+ return m;
87
+ }
88
+ for (const navProp of meta.navigation_properties) {
89
+ const nestedIncludeTree = includeTree[navProp.var_name];
90
+ if (!nestedIncludeTree)
91
+ continue;
92
+ const nestedMeta = ast.models[navProp.model_name];
93
+ // One to Many, Many to Many
94
+ if (Array.isArray(m[navProp.var_name])) {
95
+ for (let i = 0; i < m[navProp.var_name].length; i++) {
96
+ m[navProp.var_name][i] = instantiateDepthFirst(m[navProp.var_name][i], nestedMeta, nestedIncludeTree);
97
+ }
98
+ }
99
+ // One to one
100
+ else if (m[navProp.var_name]) {
101
+ m[navProp.var_name] = instantiateDepthFirst(m[navProp.var_name], nestedMeta, nestedIncludeTree);
102
+ }
105
103
  }
106
- }
107
- // One to one
108
- else if (m[navProp.var_name]) {
109
- m[navProp.var_name] = instantiateDepthFirst(
110
- m[navProp.var_name],
111
- nestedMeta,
112
- nestedIncludeTree,
113
- );
114
- }
104
+ return m;
115
105
  }
116
- return m;
117
- }
118
106
  }