@liminalfunctions/framework 1.0.52 → 1.0.54
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/F_Collection.d.ts +2 -0
- package/dist/F_Collection.js +9 -0
- package/dist/F_Collection.js.map +1 -1
- package/dist/F_Compile.js +247 -0
- package/dist/F_Compile.js.map +1 -1
- package/dist/F_Security_Models/F_Security_Model.d.ts +1 -0
- package/dist/code_generation/generate_client_library.d.ts +1 -0
- package/dist/code_generation/generate_client_library.js +37 -16
- package/dist/code_generation/generate_client_library.js.map +1 -1
- package/dist/code_generation/templates/collection.mustache +79 -1
- package/dist/utils/array_children_from_zod.d.ts +3 -0
- package/dist/utils/array_children_from_zod.js +39 -0
- package/dist/utils/array_children_from_zod.js.map +1 -0
- package/dist/utils/mongoose_from_zod.js +6 -1
- package/dist/utils/mongoose_from_zod.js.map +1 -1
- package/package.json +1 -1
- package/src/F_Collection.ts +14 -3
- package/src/F_Compile.ts +294 -16
- package/src/F_Security_Models/F_Security_Model.ts +1 -0
- package/src/code_generation/generate_client_library.ts +35 -8
- package/src/code_generation/templates/collection.mustache +79 -1
- package/src/utils/array_children_from_zod.ts +44 -0
- package/src/utils/mongoose_from_zod.ts +7 -3
- package/test/0_1_mongoose_from_zod.test.ts +16 -10
- package/test/0_6_array_children.test.ts +127 -0
- package/test/1_0_basic_server.test.ts +107 -2
- package/test/1_1_security_ownership.test.ts +186 -6
- package/test/1_2_role_membership.test.ts +329 -9
- package/test/2_1_client_library_generation.test.ts +125 -1
- package/test/tmp/dist/Brief_News_Category.js.map +1 -1
- package/test/tmp/dist/Client.js.map +1 -1
- package/test/tmp/dist/Institution.js.map +1 -1
- package/test/tmp/dist/Project.d.ts +20 -0
- package/test/tmp/dist/Project.js +63 -0
- package/test/tmp/dist/Project.js.map +1 -1
- package/test/tmp/dist/types/project.d.ts +4 -0
- package/test/tmp/dist/types/project_post.d.ts +4 -0
- package/test/tmp/dist/types/project_put.d.ts +4 -0
- package/test/tmp/package-lock.json +114 -114
- package/test/tmp/src/Brief_News_Category.ts +3 -1
- package/test/tmp/src/Client.ts +3 -1
- package/test/tmp/src/Institution.ts +3 -1
- package/test/tmp/src/Project.ts +73 -1
- package/test/tmp/src/types/project.ts +4 -0
- package/test/tmp/src/types/project_post.ts +4 -0
- package/test/tmp/src/types/project_put.ts +4 -0
|
@@ -130,4 +130,82 @@ class Document {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
{{/has_subcollections}}
|
|
133
|
-
|
|
133
|
+
|
|
134
|
+
{{#has_array_children}}
|
|
135
|
+
{{#array_children}}
|
|
136
|
+
array(key: "{{array_name}}"): Collection_{{my_built_collection}}_Array_{{array_name}};
|
|
137
|
+
{{/array_children}}
|
|
138
|
+
array(key: string) {
|
|
139
|
+
switch(key) {
|
|
140
|
+
{{#array_children}}
|
|
141
|
+
case "{{array_name}}":
|
|
142
|
+
return new Collection_{{my_built_collection}}_Array_{{array_name}}([...this.path, this.document_id, "{{array_name}}"], this.get_auth);
|
|
143
|
+
{{/array_children}}
|
|
144
|
+
default:
|
|
145
|
+
throw new Error(`Collection ${this.collection_id} does not have an array at the key ${key}`)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
{{/has_array_children}}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
{{#array_children}}
|
|
152
|
+
{{array_type_put_definition}}
|
|
153
|
+
{{array_type_post_definition}}
|
|
154
|
+
|
|
155
|
+
export class Collection_{{my_built_collection}}_Array_{{array_name}} {
|
|
156
|
+
path: string[]
|
|
157
|
+
get_auth: () => Promise<any>
|
|
158
|
+
collection_id: string
|
|
159
|
+
collection_name_plural: string
|
|
160
|
+
array_key: string
|
|
161
|
+
|
|
162
|
+
constructor(path: string[], get_auth: () => Promise<any>) {
|
|
163
|
+
this.path = path;
|
|
164
|
+
this.get_auth = get_auth;
|
|
165
|
+
this.collection_id = "{{collection_id}}";
|
|
166
|
+
this.collection_name_plural = "{{collection_name_plural}}"
|
|
167
|
+
this.array_key = "{{array_name}}"
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async push(document: {{type_array_child_post}}): Promise<{{type_return}}>{
|
|
171
|
+
try {
|
|
172
|
+
let result = await ky.post(this.path.join('/'), {
|
|
173
|
+
headers: {
|
|
174
|
+
authorization: await this.get_auth()
|
|
175
|
+
},
|
|
176
|
+
json: document
|
|
177
|
+
}).json() as Response<{{type_return}}>;
|
|
178
|
+
return result.data;
|
|
179
|
+
} catch(err){
|
|
180
|
+
return Promise.reject(err)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async replace(document: {{type_array_child_put}}): Promise<{{type_return}}>{
|
|
185
|
+
try {
|
|
186
|
+
let result = await ky.put([...this.path, document._id].join('/'), {
|
|
187
|
+
headers: {
|
|
188
|
+
authorization: await this.get_auth()
|
|
189
|
+
},
|
|
190
|
+
json: document
|
|
191
|
+
}).json() as Response<{{type_return}}>;
|
|
192
|
+
return result.data;
|
|
193
|
+
} catch(err){
|
|
194
|
+
return Promise.reject(err)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async delete(document_id: string): Promise<{{type_return}}>{
|
|
199
|
+
try {
|
|
200
|
+
let result = await ky.delete([...this.path, document_id].join('/'), {
|
|
201
|
+
headers: {
|
|
202
|
+
authorization: await this.get_auth()
|
|
203
|
+
}
|
|
204
|
+
}).json() as Response<{{type_return}}>;
|
|
205
|
+
return result.data;
|
|
206
|
+
} catch(err){
|
|
207
|
+
return Promise.reject(err)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
{{/array_children}}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import z from "zod/v4";
|
|
2
|
+
import { validator_group } from './zod_loop_seperator.js';
|
|
3
|
+
export declare function array_children_from_zod(zod_definition: z.ZodObject, loop_detector?: Map<any, validator_group>, built_map?: Map<string, z.ZodObject>, prefix?: string): Map<string, z.ZodObject>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { find_loops } from './zod_loop_seperator.js';
|
|
2
|
+
export function array_children_from_zod(zod_definition, loop_detector, built_map, prefix = '') {
|
|
3
|
+
let loops = loop_detector ?? find_loops(zod_definition);
|
|
4
|
+
let results = built_map ?? new Map();
|
|
5
|
+
for (let [key, value] of Object.entries(zod_definition.shape)) {
|
|
6
|
+
if (loops.has(value._zod.def)) {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
let real_value = distill_zod(value);
|
|
10
|
+
switch (real_value._zod.def.type) {
|
|
11
|
+
case "object":
|
|
12
|
+
array_children_from_zod(real_value, loop_detector, results, prefix.length > 0 ? `${prefix}.${key}` : key);
|
|
13
|
+
break;
|
|
14
|
+
case "array":
|
|
15
|
+
let element = distill_zod(real_value.element);
|
|
16
|
+
if (element._zod.def.type === 'object') {
|
|
17
|
+
let objdef = element._zod.def;
|
|
18
|
+
if (objdef.shape._id) {
|
|
19
|
+
results.set(prefix.length > 0 ? `${prefix}.${key}` : key, element);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
break;
|
|
23
|
+
default:
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return results;
|
|
28
|
+
}
|
|
29
|
+
function distill_zod(zod_definition) {
|
|
30
|
+
switch (zod_definition._zod.def.type) {
|
|
31
|
+
case "nullable":
|
|
32
|
+
return zod_definition._zod.def.innerType;
|
|
33
|
+
case "optional":
|
|
34
|
+
return zod_definition._zod.def.innerType;
|
|
35
|
+
default:
|
|
36
|
+
return zod_definition;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=array_children_from_zod.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array_children_from_zod.js","sourceRoot":"","sources":["../../src/utils/array_children_from_zod.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAmB,MAAM,yBAAyB,CAAA;AAErE,MAAM,UAAU,uBAAuB,CAAC,cAA2B,EAAE,aAAyC,EAAE,SAAoC,EAAE,SAAiB,EAAE;IACrK,IAAI,KAAK,GAAG,aAAa,IAAI,UAAU,CAAC,cAA2B,CAAC,CAAC;IACrE,IAAI,OAAO,GAAG,SAAS,IAAI,IAAI,GAAG,EAAuB,CAAC;IAE1D,KAAI,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,EAAC,CAAC;QAC1D,IAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC1C,IAAI,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QACpC,QAAQ,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAC/B,KAAK,QAAQ;gBACT,uBAAuB,CAAC,UAAyB,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;gBACxH,MAAM;YACV,KAAK,OAAO;gBAER,IAAI,OAAO,GAAG,WAAW,CAAE,UAAyB,CAAC,OAAO,CAAC,CAAC;gBAC9D,IAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACpC,IAAI,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAA2B,CAAC;oBACtD,IAAG,MAAM,CAAC,KAAK,CAAC,GAAG,EAAC,CAAC;wBACjB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAG,OAAsB,CAAC,CAAC;oBACvF,CAAC;gBACL,CAAC;gBACD,MAAM;YACV;gBACI,MAAM;QACd,CAAC;IAEL,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,WAAW,CAAC,cAAyB;IAC1C,QAAQ,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACnC,KAAK,UAAU;YAEX,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;QAC7C,KAAK,UAAU;YAEX,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;QAC7C;YACI,OAAO,cAAc,CAAC;IAC9B,CAAC;AACL,CAAC"}
|
|
@@ -95,7 +95,6 @@ export function schema_entry_from_zod(zod_definition, loop_detector) {
|
|
|
95
95
|
result.required = !zod_definition.safeParse(undefined).success;
|
|
96
96
|
return result;
|
|
97
97
|
case "nullable":
|
|
98
|
-
return schema_entry_from_zod(zod_definition._zod.def.innerType, loop_detector);
|
|
99
98
|
case "optional":
|
|
100
99
|
return parse_optional(zod_definition._zod.def, loop_detector);
|
|
101
100
|
case "record":
|
|
@@ -158,6 +157,12 @@ function parse_object(def, loop_detector) {
|
|
|
158
157
|
}
|
|
159
158
|
retval[key] = schema_entry_from_zod(value, loop_detector);
|
|
160
159
|
}
|
|
160
|
+
if (!retval._id) {
|
|
161
|
+
retval._id = false;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
delete retval._id;
|
|
165
|
+
}
|
|
161
166
|
return { mongoose_type: retval, required: true };
|
|
162
167
|
}
|
|
163
168
|
function parse_array(def, loop_detector) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mongoose_from_zod.js","sourceRoot":"","sources":["../../src/utils/mongoose_from_zod.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"mongoose_from_zod.js","sourceRoot":"","sources":["../../src/utils/mongoose_from_zod.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/F_Collection.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { mongoose_from_zod, schema_from_zod } from "./utils/mongoose_from_zod.js
|
|
|
3
3
|
import mongoose, { Collection, Model, ObjectId } from "mongoose";
|
|
4
4
|
import { F_Security_Model } from "./F_Security_Models/F_Security_Model.js";
|
|
5
5
|
import { query_validator_from_zod } from "./utils/query_validator_from_zod.js";
|
|
6
|
+
import { array_children_from_zod } from "./utils/array_children_from_zod.js";
|
|
6
7
|
|
|
7
8
|
export type CollectionType<Col extends F_Collection<string, Validator>, Validator extends z.ZodObject> = z.output<Col['validator']>;
|
|
8
9
|
|
|
@@ -29,6 +30,9 @@ export class F_Collection<Collection_ID extends string, ZodSchema extends z.ZodO
|
|
|
29
30
|
post_validator: ZodPartial_Return_Type<ZodSchema['partial']>;
|
|
30
31
|
is_compiled: boolean;
|
|
31
32
|
|
|
33
|
+
array_children_map: Map<string, z.ZodType>;
|
|
34
|
+
array_children_post_map: Map<string, z.ZodType>;
|
|
35
|
+
|
|
32
36
|
access_layers: F_Layer<Collection_ID, ZodSchema>[];
|
|
33
37
|
create_hooks: ((session: mongoose.mongo.ClientSession, created_document: z.output<ZodSchema>) => Promise<void>)[];
|
|
34
38
|
update_hooks: ((session: mongoose.mongo.ClientSession, updated_document: z.output<ZodSchema>) => Promise<void>)[];
|
|
@@ -43,8 +47,6 @@ export class F_Collection<Collection_ID extends string, ZodSchema extends z.ZodO
|
|
|
43
47
|
this.validator = validator;
|
|
44
48
|
this.mongoose_schema = schema_from_zod(validator);
|
|
45
49
|
this.mongoose_model = mongoose_from_zod(collection_name, validator, database);
|
|
46
|
-
// TODO: validate that the model doesn't use any fields that have special meaning in the query validator; for example: [param]_gt, [param]_in, sort,
|
|
47
|
-
//@ts-ignore
|
|
48
50
|
this.query_validator_server = query_validator_from_zod(validator, 'server');
|
|
49
51
|
this.query_validator_client = query_validator_from_zod(validator, 'client');
|
|
50
52
|
// TODO: we can make this more closely match the mongoDB PUT operation and allow updates to eg array.3.element fields
|
|
@@ -55,13 +57,22 @@ export class F_Collection<Collection_ID extends string, ZodSchema extends z.ZodO
|
|
|
55
57
|
if(this.validator._zod.def.shape._id.meta()?.framework_override_type !== 'mongodb_id'){
|
|
56
58
|
throw new Error(`_id must be a mongoDB ID. Use the z_mongodb_id special field.`)
|
|
57
59
|
}
|
|
58
|
-
|
|
60
|
+
|
|
61
|
+
this.array_children_map = array_children_from_zod(validator);
|
|
62
|
+
|
|
59
63
|
// TODO: find a more elegant way to do this so that the types don't have a cow
|
|
60
64
|
//@ts-ignore
|
|
61
65
|
this.put_validator = validator.partial();
|
|
62
66
|
// @ts-ignore
|
|
63
67
|
this.post_validator = Object.hasOwn(this.validator._zod.def.shape, '_id') ? validator.partial({ _id: true }) : validator;
|
|
64
68
|
|
|
69
|
+
this.array_children_post_map = new Map<string, z.ZodType>();
|
|
70
|
+
Array.from(this.array_children_map.entries()).forEach((keyval: [string, z.ZodType]) => {
|
|
71
|
+
let [key, value] = keyval;
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
this.array_children_post_map.set(key, value.partial({ _id: true }));
|
|
74
|
+
})
|
|
75
|
+
|
|
65
76
|
this.access_layers = [];
|
|
66
77
|
this.is_compiled = false;
|
|
67
78
|
this.create_hooks = [];
|
package/src/F_Compile.ts
CHANGED
|
@@ -24,6 +24,12 @@ export function compile<Collection_ID extends string, ZodSchema extends z.ZodObj
|
|
|
24
24
|
next();
|
|
25
25
|
})*/
|
|
26
26
|
|
|
27
|
+
let me_path = [api_prefix, 'me'].join('/');
|
|
28
|
+
app.get(me_path, async (req: Request, res: Response) => {
|
|
29
|
+
let auth_data = await F_Security_Model.auth_fetcher(req);
|
|
30
|
+
res.json(auth_data)
|
|
31
|
+
});
|
|
32
|
+
|
|
27
33
|
|
|
28
34
|
for(let access_layers of collection.access_layers){
|
|
29
35
|
for(let layer of access_layers.layers){
|
|
@@ -193,6 +199,12 @@ export function compile<Collection_ID extends string, ZodSchema extends z.ZodObj
|
|
|
193
199
|
return;
|
|
194
200
|
}
|
|
195
201
|
|
|
202
|
+
if(req.body._id && req.body._id !== req.params.document_id){
|
|
203
|
+
res.status(400);
|
|
204
|
+
res.json({ error: `mismatch between document ID and request body _id` });
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
196
208
|
let find = { '_id': req.params.document_id } as { [key: string]: any } ;
|
|
197
209
|
for(let layer of access_layers.layers){
|
|
198
210
|
find[`${layer}_id`] = req.params[layer];
|
|
@@ -254,19 +266,11 @@ export function compile<Collection_ID extends string, ZodSchema extends z.ZodObj
|
|
|
254
266
|
return;
|
|
255
267
|
}
|
|
256
268
|
}
|
|
257
|
-
|
|
258
|
-
/*let { error: pre_save_error } = await req.schema.handle_pre_save(req, value);
|
|
259
|
-
if (pre_save_error) {
|
|
260
|
-
res.status(400);
|
|
261
|
-
res.json({ error: pre_save_error.message });
|
|
262
|
-
return;
|
|
263
|
-
}*/
|
|
264
269
|
|
|
265
270
|
|
|
266
271
|
let results;
|
|
267
272
|
try {
|
|
268
273
|
results = await collection.perform_update_and_side_effects(find, validated_request_body);
|
|
269
|
-
//results = await collection.mongoose_model.findOneAndUpdate(find, validated_request_body, { returnDocument: 'after', lean: true });
|
|
270
274
|
} catch(err){
|
|
271
275
|
res.status(500);
|
|
272
276
|
res.json({ error: `there was a novel error` });
|
|
@@ -358,17 +362,9 @@ export function compile<Collection_ID extends string, ZodSchema extends z.ZodObj
|
|
|
358
362
|
}
|
|
359
363
|
}
|
|
360
364
|
|
|
361
|
-
/*let { error: pre_save_error } = await req.schema.handle_pre_save(req, validated_request_body);
|
|
362
|
-
if (pre_save_error) {
|
|
363
|
-
res.status(400);
|
|
364
|
-
res.json({ error: pre_save_error.message });
|
|
365
|
-
return;
|
|
366
|
-
}*/
|
|
367
|
-
|
|
368
365
|
let results;
|
|
369
366
|
try {
|
|
370
367
|
results = await collection.perform_create_and_side_effects(validated_request_body);
|
|
371
|
-
//results = await collection.mongoose_model.create(validated_request_body);
|
|
372
368
|
} catch(err){
|
|
373
369
|
res.status(500);
|
|
374
370
|
res.json({ error: `there was a novel error` });
|
|
@@ -428,5 +424,287 @@ export function compile<Collection_ID extends string, ZodSchema extends z.ZodObj
|
|
|
428
424
|
}
|
|
429
425
|
// await req.schema.fire_api_event('delete', req, results);
|
|
430
426
|
});
|
|
427
|
+
|
|
428
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
429
|
+
//////////////////////////////////////// operate on array children /////////////////////////////////////
|
|
430
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
431
|
+
|
|
432
|
+
for(let [array_child_path, array_child_validator] of collection.array_children_map.entries()){
|
|
433
|
+
|
|
434
|
+
let post_validator = collection.array_children_post_map.get(array_child_path);
|
|
435
|
+
|
|
436
|
+
let array_child_post_path = [
|
|
437
|
+
api_prefix,
|
|
438
|
+
...base_layers_path_components,
|
|
439
|
+
`${collection.collection_id}/:document_id`,
|
|
440
|
+
array_child_path
|
|
441
|
+
].join('/');
|
|
442
|
+
|
|
443
|
+
app.post(array_child_post_path, async (req, res) => {
|
|
444
|
+
if (!isValidObjectId(req.params.document_id)) {
|
|
445
|
+
res.status(400);
|
|
446
|
+
res.json({ error: `${req.params.document_id} is not a valid document ID.` });
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
let find = { '_id': req.params.document_id } as { [key: string]: any } ;
|
|
451
|
+
for(let layer of access_layers.layers){
|
|
452
|
+
find[`${layer}_id`] = req.params[layer];
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// I'd like to have a validator here. I think it might need to be a map or record validator?
|
|
456
|
+
let permissive_security_model = await F_Security_Model.model_with_permission(access_layers.security_models, req, res, find, 'update');
|
|
457
|
+
if (!permissive_security_model) {
|
|
458
|
+
res.status(403);
|
|
459
|
+
res.json({ error: `You do not have permission to update documents from ${collection.collection_id}.` });
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
let metadata_updater: any = {};
|
|
464
|
+
if(collection.mongoose_schema.updated_by?.type === String) {
|
|
465
|
+
// if the security schema required the user to be logged in, then req.auth.user_id will not be null
|
|
466
|
+
if((req as Authenticated_Request).auth?.user_id){
|
|
467
|
+
metadata_updater.updated_by = (req as Authenticated_Request).auth?.user_id;
|
|
468
|
+
} else {
|
|
469
|
+
metadata_updater.updated_by = null;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if(collection.mongoose_schema.updated_at?.type === Date) {
|
|
474
|
+
metadata_updater.updated_at = new Date();
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
let validated_request_body;
|
|
478
|
+
try {
|
|
479
|
+
validated_request_body = await post_validator.parse(req.body);
|
|
480
|
+
} catch(err){
|
|
481
|
+
if(err instanceof z.ZodError){
|
|
482
|
+
res.status(400);
|
|
483
|
+
res.json({ error: err.issues });
|
|
484
|
+
return;
|
|
485
|
+
} else {
|
|
486
|
+
console.error(err);
|
|
487
|
+
res.status(500);
|
|
488
|
+
res.json({ error: `there was a novel error` });
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
try {
|
|
494
|
+
detect_malicious_keys(validated_request_body);
|
|
495
|
+
} catch(err){
|
|
496
|
+
res.status(403);
|
|
497
|
+
res.json({ error: `Found an unacceptable JSON key in the request body.` });
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
let results;
|
|
502
|
+
try {
|
|
503
|
+
//array_child_path
|
|
504
|
+
results = await collection.perform_update_and_side_effects(find, {
|
|
505
|
+
$push: {
|
|
506
|
+
[array_child_path]: validated_request_body,
|
|
507
|
+
},
|
|
508
|
+
...metadata_updater
|
|
509
|
+
});
|
|
510
|
+
} catch(err){
|
|
511
|
+
res.status(500);
|
|
512
|
+
res.json({ error: `there was a novel error` });
|
|
513
|
+
console.error(err);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
if (!results) {
|
|
518
|
+
let sendable = await permissive_security_model.handle_empty_query_results(req, res, 'update');
|
|
519
|
+
res.json(sendable);
|
|
520
|
+
} else {
|
|
521
|
+
res.json({ data: results });
|
|
522
|
+
}
|
|
523
|
+
//await req.schema.fire_api_event('update', req, results);
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
let array_child_put_path = [
|
|
529
|
+
api_prefix,
|
|
530
|
+
...base_layers_path_components,
|
|
531
|
+
`${collection.collection_id}/:document_id`,
|
|
532
|
+
array_child_path,
|
|
533
|
+
':array_item_id'
|
|
534
|
+
].join('/')
|
|
535
|
+
|
|
536
|
+
app.put(array_child_put_path, async (req, res) => {
|
|
537
|
+
if (!isValidObjectId(req.params.document_id)) {
|
|
538
|
+
res.status(400);
|
|
539
|
+
res.json({ error: `${req.params.document_id} is not a valid document ID.` });
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
if (!isValidObjectId(req.params.array_item_id)) {
|
|
544
|
+
res.status(400);
|
|
545
|
+
res.json({ error: `${req.params.array_item_id} is not a valid document ID.` });
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
if(req.body._id && req.body._id !== req.params.array_item_id){
|
|
550
|
+
res.status(400);
|
|
551
|
+
res.json({ error: `cannot update element _id.` });
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
let find = { '_id': req.params.document_id } as { [key: string]: any } ;
|
|
556
|
+
for(let layer of access_layers.layers){
|
|
557
|
+
find[`${layer}_id`] = req.params[layer];
|
|
558
|
+
}
|
|
559
|
+
find[`${array_child_path}._id`] = req.params.array_item_id;
|
|
560
|
+
|
|
561
|
+
// I'd like to have a validator here. I think it might need to be a map or record validator?
|
|
562
|
+
let permissive_security_model = await F_Security_Model.model_with_permission(access_layers.security_models, req, res, find, 'update');
|
|
563
|
+
if (!permissive_security_model) {
|
|
564
|
+
res.status(403);
|
|
565
|
+
res.json({ error: `You do not have permission to update documents from ${collection.collection_id}.` });
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
let metadata_updater: any = {};
|
|
570
|
+
if(collection.mongoose_schema.updated_by?.type === String) {
|
|
571
|
+
// if the security schema required the user to be logged in, then req.auth.user_id will not be null
|
|
572
|
+
if((req as Authenticated_Request).auth?.user_id){
|
|
573
|
+
metadata_updater.updated_by = (req as Authenticated_Request).auth?.user_id;
|
|
574
|
+
} else {
|
|
575
|
+
metadata_updater.updated_by = null;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
if(collection.mongoose_schema.updated_at?.type === Date) {
|
|
580
|
+
metadata_updater.updated_at = new Date();
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
let validated_request_body;
|
|
584
|
+
try {
|
|
585
|
+
validated_request_body = await array_child_validator.parse(req.body);
|
|
586
|
+
} catch(err){
|
|
587
|
+
if(err instanceof z.ZodError){
|
|
588
|
+
res.status(400);
|
|
589
|
+
res.json({ error: err.issues });
|
|
590
|
+
return;
|
|
591
|
+
} else {
|
|
592
|
+
console.error(err);
|
|
593
|
+
res.status(500);
|
|
594
|
+
res.json({ error: `there was a novel error` });
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
try {
|
|
600
|
+
detect_malicious_keys(validated_request_body);
|
|
601
|
+
} catch(err){
|
|
602
|
+
res.status(403);
|
|
603
|
+
res.json({ error: `Found an unacceptable JSON key in the request body.` });
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
let results;
|
|
608
|
+
try {
|
|
609
|
+
//array_child_path
|
|
610
|
+
results = await collection.perform_update_and_side_effects(find, {
|
|
611
|
+
$set: {
|
|
612
|
+
[`${array_child_path}.$`]: validated_request_body,
|
|
613
|
+
},
|
|
614
|
+
...metadata_updater
|
|
615
|
+
});
|
|
616
|
+
} catch(err){
|
|
617
|
+
res.status(500);
|
|
618
|
+
res.json({ error: `there was a novel error` });
|
|
619
|
+
console.error(err);
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
if (!results) {
|
|
624
|
+
let sendable = await permissive_security_model.handle_empty_query_results(req, res, 'update');
|
|
625
|
+
res.json(sendable);
|
|
626
|
+
} else {
|
|
627
|
+
res.json({ data: results });
|
|
628
|
+
}
|
|
629
|
+
//await req.schema.fire_api_event('update', req, results);
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
let array_child_delete_path = [
|
|
633
|
+
api_prefix,
|
|
634
|
+
...base_layers_path_components,
|
|
635
|
+
`${collection.collection_id}/:document_id`,
|
|
636
|
+
array_child_path,
|
|
637
|
+
':array_item_id'
|
|
638
|
+
].join('/')
|
|
639
|
+
|
|
640
|
+
app.delete(array_child_delete_path, async (req, res) => {
|
|
641
|
+
if (!isValidObjectId(req.params.document_id)) {
|
|
642
|
+
res.status(400);
|
|
643
|
+
res.json({ error: `${req.params.document_id} is not a valid document ID.` });
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
if (!isValidObjectId(req.params.array_item_id)) {
|
|
648
|
+
res.status(400);
|
|
649
|
+
res.json({ error: `${req.params.array_item_id} is not a valid document ID.` });
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
let find = { '_id': req.params.document_id } as { [key: string]: any } ;
|
|
654
|
+
for(let layer of access_layers.layers){
|
|
655
|
+
find[`${layer}_id`] = req.params[layer];
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// I'd like to have a validator here. I think it might need to be a map or record validator?
|
|
659
|
+
let permissive_security_model = await F_Security_Model.model_with_permission(access_layers.security_models, req, res, find, 'update');
|
|
660
|
+
if (!permissive_security_model) {
|
|
661
|
+
res.status(403);
|
|
662
|
+
res.json({ error: `You do not have permission to update documents from ${collection.collection_id}.` });
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
let metadata_updater: any = {};
|
|
667
|
+
if(collection.mongoose_schema.updated_by?.type === String) {
|
|
668
|
+
// if the security schema required the user to be logged in, then req.auth.user_id will not be null
|
|
669
|
+
if((req as Authenticated_Request).auth?.user_id){
|
|
670
|
+
metadata_updater.updated_by = (req as Authenticated_Request).auth?.user_id;
|
|
671
|
+
} else {
|
|
672
|
+
metadata_updater.updated_by = null;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
if(collection.mongoose_schema.updated_at?.type === Date) {
|
|
677
|
+
metadata_updater.updated_at = new Date();
|
|
678
|
+
}
|
|
679
|
+
let results;
|
|
680
|
+
try {
|
|
681
|
+
//array_child_path
|
|
682
|
+
results = await collection.perform_update_and_side_effects(find, {
|
|
683
|
+
$pull: {
|
|
684
|
+
[array_child_path]: {_id: req.params.array_item_id},
|
|
685
|
+
},
|
|
686
|
+
...metadata_updater
|
|
687
|
+
});
|
|
688
|
+
} catch(err){
|
|
689
|
+
res.status(500);
|
|
690
|
+
res.json({ error: `there was a novel error` });
|
|
691
|
+
console.error(err);
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
if (!results) {
|
|
696
|
+
let sendable = await permissive_security_model.handle_empty_query_results(req, res, 'update');
|
|
697
|
+
res.json(sendable);
|
|
698
|
+
} else {
|
|
699
|
+
res.json({ data: results });
|
|
700
|
+
}
|
|
701
|
+
//await req.schema.fire_api_event('update', req, results);
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
|
|
431
709
|
}
|
|
432
710
|
}
|
|
@@ -72,6 +72,7 @@ export abstract class F_Security_Model<Collection_ID extends string, ZodSchema e
|
|
|
72
72
|
export type Auth_Data = {
|
|
73
73
|
user_id: string,
|
|
74
74
|
layers: {
|
|
75
|
+
layer: string,
|
|
75
76
|
layer_id: string,
|
|
76
77
|
permissions: {[key: string]: Operation[]},
|
|
77
78
|
special_permissions: {[key: string]: string[]}
|