@liminalfunctions/framework 1.0.0

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.
Files changed (181) hide show
  1. package/.mocharc.json +5 -0
  2. package/dist/F_Client_Collection_Registry.d.ts +18 -0
  3. package/dist/F_Client_Collection_Registry.js +36 -0
  4. package/dist/F_Client_Collection_Registry.js.map +1 -0
  5. package/dist/F_Collection.d.ts +21 -0
  6. package/dist/F_Collection.js +36 -0
  7. package/dist/F_Collection.js.map +1 -0
  8. package/dist/F_Collection_Registry.d.ts +11 -0
  9. package/dist/F_Collection_Registry.js +18 -0
  10. package/dist/F_Collection_Registry.js.map +1 -0
  11. package/dist/F_Compile.d.ts +4 -0
  12. package/dist/F_Compile.js +298 -0
  13. package/dist/F_Compile.js.map +1 -0
  14. package/dist/F_Security_Models/F_SM_Open_Access.d.ts +11 -0
  15. package/dist/F_Security_Models/F_SM_Open_Access.js +14 -0
  16. package/dist/F_Security_Models/F_SM_Open_Access.js.map +1 -0
  17. package/dist/F_Security_Models/F_SM_Ownership.d.ts +12 -0
  18. package/dist/F_Security_Models/F_SM_Ownership.js +46 -0
  19. package/dist/F_Security_Models/F_SM_Ownership.js.map +1 -0
  20. package/dist/F_Security_Models/F_SM_Role_Membership.d.ts +19 -0
  21. package/dist/F_Security_Models/F_SM_Role_Membership.js +73 -0
  22. package/dist/F_Security_Models/F_SM_Role_Membership.js.map +1 -0
  23. package/dist/F_Security_Models/F_Security_Model.d.ts +41 -0
  24. package/dist/F_Security_Models/F_Security_Model.js +29 -0
  25. package/dist/F_Security_Models/F_Security_Model.js.map +1 -0
  26. package/dist/code_generation/generate_client_library.d.ts +4 -0
  27. package/dist/code_generation/generate_client_library.js +158 -0
  28. package/dist/code_generation/generate_client_library.js.map +1 -0
  29. package/dist/code_generation/templates/.gitignore.mustache +383 -0
  30. package/dist/code_generation/templates/collection.mustache +106 -0
  31. package/dist/code_generation/templates/main.mustache +24 -0
  32. package/dist/code_generation/templates/package.json.mustache +18 -0
  33. package/dist/code_generation/templates/tsconfig.json.mustache +14 -0
  34. package/dist/code_generation/templates/types.mustache +4 -0
  35. package/dist/code_generation/templates/utils.ts.mustache +17 -0
  36. package/dist/code_generation/utils/tab_indent.d.ts +1 -0
  37. package/dist/code_generation/utils/tab_indent.js +4 -0
  38. package/dist/code_generation/utils/tab_indent.js.map +1 -0
  39. package/dist/code_generation/utils/type_from_zod.d.ts +2 -0
  40. package/dist/code_generation/utils/type_from_zod.js +102 -0
  41. package/dist/code_generation/utils/type_from_zod.js.map +1 -0
  42. package/dist/utils/cache.d.ts +13 -0
  43. package/dist/utils/cache.js +101 -0
  44. package/dist/utils/cache.js.map +1 -0
  45. package/dist/utils/mongoose_from_zod.d.ts +13 -0
  46. package/dist/utils/mongoose_from_zod.js +164 -0
  47. package/dist/utils/mongoose_from_zod.js.map +1 -0
  48. package/dist/utils/pretty_print_zod.d.ts +2 -0
  49. package/dist/utils/pretty_print_zod.js +63 -0
  50. package/dist/utils/pretty_print_zod.js.map +1 -0
  51. package/dist/utils/query_object_to_mongodb_query.d.ts +3 -0
  52. package/dist/utils/query_object_to_mongodb_query.js +61 -0
  53. package/dist/utils/query_object_to_mongodb_query.js.map +1 -0
  54. package/dist/utils/query_validator_from_zod.d.ts +6 -0
  55. package/dist/utils/query_validator_from_zod.js +216 -0
  56. package/dist/utils/query_validator_from_zod.js.map +1 -0
  57. package/package.json +36 -0
  58. package/src/F_Collection.ts +50 -0
  59. package/src/F_Collection_Registry.ts +29 -0
  60. package/src/F_Compile.ts +368 -0
  61. package/src/F_Security_Models/F_SM_Open_Access.ts +21 -0
  62. package/src/F_Security_Models/F_SM_Ownership.ts +72 -0
  63. package/src/F_Security_Models/F_SM_Role_Membership.ts +87 -0
  64. package/src/F_Security_Models/F_Security_Model.ts +85 -0
  65. package/src/code_generation/generate_client_library.ts +197 -0
  66. package/src/code_generation/templates/.gitignore.mustache +383 -0
  67. package/src/code_generation/templates/collection.mustache +106 -0
  68. package/src/code_generation/templates/main.mustache +24 -0
  69. package/src/code_generation/templates/package.json.mustache +18 -0
  70. package/src/code_generation/templates/tsconfig.json.mustache +14 -0
  71. package/src/code_generation/templates/types.mustache +4 -0
  72. package/src/code_generation/templates/utils.ts.mustache +17 -0
  73. package/src/code_generation/utils/tab_indent.ts +3 -0
  74. package/src/code_generation/utils/type_from_zod.ts +140 -0
  75. package/src/utils/cache.ts +149 -0
  76. package/src/utils/mongoose_from_zod.ts +191 -0
  77. package/src/utils/pretty_print_zod.ts +75 -0
  78. package/src/utils/query_object_to_mongodb_query.ts +73 -0
  79. package/src/utils/query_validator_from_zod.ts +246 -0
  80. package/test/0_0_mongoose_from_zod.test.ts +260 -0
  81. package/test/0_1_query_validator_from_zod.test.ts +518 -0
  82. package/test/0_2_query_validator_to_mongodb_query.test.ts +365 -0
  83. package/test/0_3_cache.test.ts +204 -0
  84. package/test/1_0_basic_server.test.ts +530 -0
  85. package/test/1_1_security_ownership.test.ts +328 -0
  86. package/test/1_2_role_membership.test.ts +731 -0
  87. package/test/2_0_client_library_basic_type_generation.test.ts +444 -0
  88. package/test/2_0_client_library_query_type_generation.test.ts +352 -0
  89. package/test/2_1_client_library_generation.test.ts +255 -0
  90. package/test/tmp/dist/Brief_News_Category.d.ts +16 -0
  91. package/test/tmp/dist/Brief_News_Category.js +85 -0
  92. package/test/tmp/dist/Brief_News_Category.js.map +1 -0
  93. package/test/tmp/dist/Client.d.ts +19 -0
  94. package/test/tmp/dist/Client.js +97 -0
  95. package/test/tmp/dist/Client.js.map +1 -0
  96. package/test/tmp/dist/Institution.d.ts +18 -0
  97. package/test/tmp/dist/Institution.js +94 -0
  98. package/test/tmp/dist/Institution.js.map +1 -0
  99. package/test/tmp/dist/Project.d.ts +16 -0
  100. package/test/tmp/dist/Project.js +85 -0
  101. package/test/tmp/dist/Project.js.map +1 -0
  102. package/test/tmp/dist/index.d.ts +4 -0
  103. package/test/tmp/dist/index.js +14 -0
  104. package/test/tmp/dist/index.js.map +1 -0
  105. package/test/tmp/dist/types/brief_news_category.d.ts +7 -0
  106. package/test/tmp/dist/types/brief_news_category.js +2 -0
  107. package/test/tmp/dist/types/brief_news_category.js.map +1 -0
  108. package/test/tmp/dist/types/brief_news_category_post.d.ts +7 -0
  109. package/test/tmp/dist/types/brief_news_category_post.js +2 -0
  110. package/test/tmp/dist/types/brief_news_category_post.js.map +1 -0
  111. package/test/tmp/dist/types/brief_news_category_put.d.ts +7 -0
  112. package/test/tmp/dist/types/brief_news_category_put.js +2 -0
  113. package/test/tmp/dist/types/brief_news_category_put.js.map +1 -0
  114. package/test/tmp/dist/types/brief_news_category_query.d.ts +26 -0
  115. package/test/tmp/dist/types/brief_news_category_query.js +2 -0
  116. package/test/tmp/dist/types/brief_news_category_query.js.map +1 -0
  117. package/test/tmp/dist/types/client.d.ts +5 -0
  118. package/test/tmp/dist/types/client.js +2 -0
  119. package/test/tmp/dist/types/client.js.map +1 -0
  120. package/test/tmp/dist/types/client_post.d.ts +5 -0
  121. package/test/tmp/dist/types/client_post.js +2 -0
  122. package/test/tmp/dist/types/client_post.js.map +1 -0
  123. package/test/tmp/dist/types/client_put.d.ts +5 -0
  124. package/test/tmp/dist/types/client_put.js +2 -0
  125. package/test/tmp/dist/types/client_put.js.map +1 -0
  126. package/test/tmp/dist/types/client_query.d.ts +18 -0
  127. package/test/tmp/dist/types/client_query.js +2 -0
  128. package/test/tmp/dist/types/client_query.js.map +1 -0
  129. package/test/tmp/dist/types/institution.d.ts +4 -0
  130. package/test/tmp/dist/types/institution.js +2 -0
  131. package/test/tmp/dist/types/institution.js.map +1 -0
  132. package/test/tmp/dist/types/institution_post.d.ts +4 -0
  133. package/test/tmp/dist/types/institution_post.js +2 -0
  134. package/test/tmp/dist/types/institution_post.js.map +1 -0
  135. package/test/tmp/dist/types/institution_put.d.ts +4 -0
  136. package/test/tmp/dist/types/institution_put.js +2 -0
  137. package/test/tmp/dist/types/institution_put.js.map +1 -0
  138. package/test/tmp/dist/types/institution_query.d.ts +14 -0
  139. package/test/tmp/dist/types/institution_query.js +2 -0
  140. package/test/tmp/dist/types/institution_query.js.map +1 -0
  141. package/test/tmp/dist/types/project.d.ts +7 -0
  142. package/test/tmp/dist/types/project.js +2 -0
  143. package/test/tmp/dist/types/project.js.map +1 -0
  144. package/test/tmp/dist/types/project_post.d.ts +7 -0
  145. package/test/tmp/dist/types/project_post.js +2 -0
  146. package/test/tmp/dist/types/project_post.js.map +1 -0
  147. package/test/tmp/dist/types/project_put.d.ts +7 -0
  148. package/test/tmp/dist/types/project_put.js +2 -0
  149. package/test/tmp/dist/types/project_put.js.map +1 -0
  150. package/test/tmp/dist/types/project_query.d.ts +27 -0
  151. package/test/tmp/dist/types/project_query.js +2 -0
  152. package/test/tmp/dist/types/project_query.js.map +1 -0
  153. package/test/tmp/dist/utils/utils.d.ts +11 -0
  154. package/test/tmp/dist/utils/utils.js +13 -0
  155. package/test/tmp/dist/utils/utils.js.map +1 -0
  156. package/test/tmp/package-lock.json +573 -0
  157. package/test/tmp/package.json +18 -0
  158. package/test/tmp/src/Brief_News_Category.ts +94 -0
  159. package/test/tmp/src/Client.ts +106 -0
  160. package/test/tmp/src/Institution.ts +103 -0
  161. package/test/tmp/src/Project.ts +94 -0
  162. package/test/tmp/src/index.ts +20 -0
  163. package/test/tmp/src/types/brief_news_category.ts +7 -0
  164. package/test/tmp/src/types/brief_news_category_post.ts +7 -0
  165. package/test/tmp/src/types/brief_news_category_put.ts +7 -0
  166. package/test/tmp/src/types/brief_news_category_query.ts +26 -0
  167. package/test/tmp/src/types/client.ts +5 -0
  168. package/test/tmp/src/types/client_post.ts +5 -0
  169. package/test/tmp/src/types/client_put.ts +5 -0
  170. package/test/tmp/src/types/client_query.ts +18 -0
  171. package/test/tmp/src/types/institution.ts +4 -0
  172. package/test/tmp/src/types/institution_post.ts +4 -0
  173. package/test/tmp/src/types/institution_put.ts +4 -0
  174. package/test/tmp/src/types/institution_query.ts +14 -0
  175. package/test/tmp/src/types/project.ts +7 -0
  176. package/test/tmp/src/types/project_post.ts +7 -0
  177. package/test/tmp/src/types/project_put.ts +7 -0
  178. package/test/tmp/src/types/project_query.ts +27 -0
  179. package/test/tmp/src/utils/utils.ts +17 -0
  180. package/test/tmp/tsconfig.json +14 -0
  181. package/tsconfig.json +14 -0
@@ -0,0 +1,216 @@
1
+ import { z } from "zod/v4";
2
+ import { magic_values, z_mongodb_id } from "./mongoose_from_zod.js";
3
+ export function query_validator_from_zod(zod_definition, mode = 'server') {
4
+ let retval = {
5
+ limit: z.coerce.number().int().optional(),
6
+ cursor: z_mongodb_id.optional(),
7
+ sort_order: z.enum(['ascending', 'descending']).optional()
8
+ };
9
+ let object_filters = parse_object(zod_definition._zod.def, '', new Set(), mode);
10
+ for (let filter of object_filters) {
11
+ retval[filter.path.slice(1)] = filter.filter;
12
+ }
13
+ retval.sort = z.enum(object_filters.filter(ele => ele.sortable).map(ele => ele.path.slice(1))).optional();
14
+ return z.object(retval).strict();
15
+ }
16
+ function parse_any(zod_definition, prefix, loop_detector = new Set(), mode = 'server') {
17
+ switch (zod_definition._zod.def.type) {
18
+ case "enum":
19
+ return parse_enum(zod_definition._zod.def, prefix, mode);
20
+ case "string":
21
+ return parse_string(prefix, mode);
22
+ case "number":
23
+ case "int":
24
+ return parse_number(prefix, mode);
25
+ case "object":
26
+ return parse_object(zod_definition._zod.def, prefix, loop_detector, mode);
27
+ case "boolean":
28
+ return parse_boolean(prefix, mode);
29
+ case "date":
30
+ return parse_date(prefix, mode);
31
+ case "array":
32
+ return parse_array(zod_definition._zod.def, prefix, loop_detector, mode);
33
+ case "union":
34
+ return parse_union(zod_definition._zod.def, prefix, mode);
35
+ case "custom":
36
+ if (!magic_values.has(zod_definition)) {
37
+ throw new Error(`could not find custom parser in the magic value dictionary`);
38
+ }
39
+ let { override_type } = magic_values.get(zod_definition);
40
+ if (override_type === 'mongodb_id') {
41
+ return parse_mongodb_id(prefix, mode);
42
+ }
43
+ else {
44
+ throw new Error(`could not find custom parser for ${override_type} in the magic value dictionary`);
45
+ }
46
+ case "default":
47
+ return parse_any(zod_definition._zod.def.innerType, prefix, loop_detector, mode);
48
+ default:
49
+ return [];
50
+ }
51
+ }
52
+ function parse_array(def, prefix, loop_detector, mode) {
53
+ let simple_children = ['enum', 'string', 'number', 'int', 'boolean'];
54
+ if (simple_children.includes(def.element._zod.def.type)) {
55
+ return parse_any(def.element, prefix, loop_detector, mode).filter(ele => ele.path == prefix);
56
+ }
57
+ else if (def.element._zod.def.type === 'custom') {
58
+ if (!magic_values.has(def.element)) {
59
+ return [];
60
+ }
61
+ let { override_type } = magic_values.get(def.element);
62
+ if (override_type === 'mongodb_id') {
63
+ return parse_mongodb_id(prefix, mode).filter(ele => ele.path == prefix);
64
+ }
65
+ }
66
+ return [];
67
+ }
68
+ function parse_object(def, prefix, loop_detector, mode) {
69
+ if (loop_detector.has(def)) {
70
+ return [];
71
+ }
72
+ loop_detector.add(def);
73
+ let retval = [];
74
+ for (let [key, value] of Object.entries(def.shape)) {
75
+ let filters = parse_any(value, `${prefix}.${key}`, loop_detector, mode);
76
+ retval.push(...filters);
77
+ }
78
+ return retval;
79
+ }
80
+ function parse_union(def, prefix, mode) {
81
+ let simple_children = ['enum', 'string', 'number', 'int', 'boolean'];
82
+ let filter_queue = def.options.slice().filter(ele => simple_children.includes(ele._zod.def.type));
83
+ let root = filter_queue.shift();
84
+ for (let filter of filter_queue) {
85
+ root = root.or(filter);
86
+ }
87
+ return [
88
+ {
89
+ path: prefix,
90
+ filter: root,
91
+ sortable: true,
92
+ }
93
+ ];
94
+ }
95
+ function parse_string(prefix, mode) {
96
+ let array_parser = mode === 'client' ? z.array(z.string()) : z.string().transform(val => val.split(',').filter(ele => ele.length > 0));
97
+ return [
98
+ {
99
+ path: prefix,
100
+ filter: z.string().optional(),
101
+ sortable: true,
102
+ },
103
+ {
104
+ path: prefix + '_gt',
105
+ filter: z.string().optional(),
106
+ sortable: false,
107
+ },
108
+ {
109
+ path: prefix + '_lt',
110
+ filter: z.string().optional(),
111
+ sortable: false,
112
+ },
113
+ {
114
+ path: prefix + '_in',
115
+ filter: array_parser.optional(),
116
+ sortable: false,
117
+ },
118
+ ];
119
+ }
120
+ function parse_enum(definition, prefix, mode) {
121
+ let array_parser = mode === 'client' ? z.array(z.enum(definition.entries)) : z.string().transform(val => val.split(',').filter(ele => ele.length > 0));
122
+ return [
123
+ {
124
+ path: prefix,
125
+ filter: z.enum(definition.entries).optional(),
126
+ sortable: true,
127
+ },
128
+ {
129
+ path: prefix + '_in',
130
+ filter: array_parser.optional(),
131
+ sortable: false,
132
+ },
133
+ ];
134
+ }
135
+ function parse_boolean(prefix, mode) {
136
+ let boolean_parser = mode === 'client' ? z.boolean() : z.stringbool();
137
+ return [{
138
+ path: prefix,
139
+ filter: boolean_parser.optional(),
140
+ sortable: true,
141
+ }];
142
+ }
143
+ function parse_number(prefix, mode) {
144
+ let number_parser = mode === 'client' ? z.number() : z.coerce.number();
145
+ return [
146
+ {
147
+ path: prefix,
148
+ filter: number_parser.optional(),
149
+ sortable: true,
150
+ },
151
+ {
152
+ path: prefix + '_gt',
153
+ filter: number_parser.optional(),
154
+ sortable: false,
155
+ },
156
+ {
157
+ path: prefix + '_gte',
158
+ filter: number_parser.optional(),
159
+ sortable: false,
160
+ },
161
+ {
162
+ path: prefix + '_lt',
163
+ filter: number_parser.optional(),
164
+ sortable: false,
165
+ },
166
+ {
167
+ path: prefix + '_lte',
168
+ filter: number_parser.optional(),
169
+ sortable: false,
170
+ },
171
+ ];
172
+ }
173
+ function parse_date(prefix, mode) {
174
+ let date_parser = mode === 'client' ? z.date() : z.coerce.date();
175
+ return [{
176
+ path: prefix,
177
+ filter: date_parser.optional(),
178
+ sortable: true,
179
+ },
180
+ {
181
+ path: prefix + '_gt',
182
+ filter: date_parser.optional(),
183
+ sortable: false,
184
+ },
185
+ {
186
+ path: prefix + '_lt',
187
+ filter: date_parser.optional(),
188
+ sortable: false,
189
+ }];
190
+ }
191
+ function parse_mongodb_id(prefix, mode) {
192
+ let array_parser = mode === 'client' ? z.array(z_mongodb_id) : z.string().transform(val => val.split(',').filter(ele => ele.length > 0));
193
+ return [
194
+ {
195
+ path: prefix,
196
+ filter: z_mongodb_id.optional(),
197
+ sortable: true,
198
+ },
199
+ {
200
+ path: prefix + '_gt',
201
+ filter: z_mongodb_id.optional(),
202
+ sortable: false,
203
+ },
204
+ {
205
+ path: prefix + '_lt',
206
+ filter: z_mongodb_id.optional(),
207
+ sortable: false,
208
+ },
209
+ {
210
+ path: prefix + '_in',
211
+ filter: array_parser.optional(),
212
+ sortable: false,
213
+ },
214
+ ];
215
+ }
216
+ //# sourceMappingURL=query_validator_from_zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query_validator_from_zod.js","sourceRoot":"","sources":["../../src/utils/query_validator_from_zod.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@liminalfunctions/framework",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "type": "module",
6
+ "scripts": {
7
+ "test": "npm run-script build && mocha",
8
+ "build": "tsc && rimraf \"./dist/code_generation/templates\" && copyfiles -a -u 3 \"./src/code_generation/templates/*.mustache\" \"./dist/code_generation/templates\""
9
+ },
10
+ "author": "",
11
+ "license": "ISC",
12
+ "description": "",
13
+ "devDependencies": {
14
+ "@openapitools/openapi-generator-cli": "^2.22.0",
15
+ "@types/express": "^5.0.0",
16
+ "@types/mocha": "^10.0.10",
17
+ "@types/mustache": "^4.2.6",
18
+ "@types/node": "^22.10.7",
19
+ "copyfiles": "^2.4.1",
20
+ "got": "^14.4.6",
21
+ "mocha": "^11.1.0",
22
+ "rimraf": "^6.0.1",
23
+ "tsx": "^4.19.3",
24
+ "typescript": "^5.7.3",
25
+ "zod": "^4.0.17"
26
+ },
27
+ "peerDependencies": {
28
+ "express": "^4.21.2",
29
+ "ky": "^1.9.0",
30
+ "mongoose": "^8.17.0",
31
+ "zod": "^4.0.0"
32
+ },
33
+ "dependencies": {
34
+ "mustache": "^4.2.0"
35
+ }
36
+ }
@@ -0,0 +1,50 @@
1
+ import * as z from "zod/v4";
2
+ import { mongoose_from_zod, schema_from_zod } from "./utils/mongoose_from_zod.js";
3
+ import { Model } from "mongoose";
4
+ import { F_Security_Model } from "./F_Security_Models/F_Security_Model.js";
5
+ import { query_validator_from_zod } from "./utils/query_validator_from_zod.js";
6
+ import ky, { SearchParamsOption } from 'ky';
7
+
8
+ export type F_Layer<Collection_ID extends string, ZodSchema extends z.ZodObject> = {
9
+ layers: string[],
10
+ security_models: F_Security_Model<Collection_ID, ZodSchema>[]
11
+ }
12
+
13
+ export class F_Collection<Collection_ID extends string, ZodSchema extends z.ZodObject> {
14
+ collection_id: Collection_ID;
15
+ validator: ZodSchema;
16
+ mongoose_schema: any;
17
+ mongoose_model: Model<z.infer<ZodSchema>>;
18
+
19
+ query_validator_server: z.ZodType;
20
+ query_validator_client: z.ZodType;
21
+ put_validator: z.ZodType;
22
+ post_validator: z.ZodType;
23
+ is_compiled: boolean;
24
+
25
+ access_layers: F_Layer<Collection_ID, ZodSchema>[];
26
+
27
+ constructor(collection_name: Collection_ID, validator: ZodSchema){
28
+ this.collection_id = collection_name;
29
+ this.validator = validator;
30
+ this.mongoose_schema = schema_from_zod(validator);
31
+ this.mongoose_model = mongoose_from_zod(collection_name, validator);
32
+ // 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,
33
+ //@ts-ignore
34
+ this.query_validator_server = query_validator_from_zod(validator, 'server');
35
+ this.query_validator_client = query_validator_from_zod(validator, 'client');
36
+ // TODO: we can make this more closely match the mongoDB PUT operation and allow updates to eg array.3.element fields
37
+ this.put_validator = validator.partial();
38
+ this.post_validator = Object.hasOwn(this.validator._zod.def.shape, '_id') ? validator.partial({_id: true}) : validator;
39
+ this.access_layers = [];
40
+ this.is_compiled = false;
41
+ }
42
+
43
+ add_layers(layers: string[], security_models: F_Security_Model<Collection_ID, ZodSchema>[], is_layer_owner = false){
44
+ if(this.is_compiled){ throw new Error(`Manipulating a model post-compilation doesn't work.`); }
45
+ this.access_layers.push({
46
+ layers: layers,
47
+ security_models: security_models
48
+ });
49
+ }
50
+ }
@@ -0,0 +1,29 @@
1
+ import * as z from 'zod/v4'
2
+ import { F_Collection } from './F_Collection.js';
3
+ import { compile/*, to_openapi*/ } from './F_Compile.js'
4
+ import { Router } from 'express';
5
+ //import { createDocument } from 'zod-openapi';
6
+
7
+
8
+ export class F_Collection_Registry<Collections = {}> {
9
+ collections: Collections;
10
+
11
+
12
+
13
+ constructor() {
14
+ this.collections = {} as Collections;
15
+ }
16
+
17
+ register<Collection_ID extends string, ZodSchema extends z.ZodObject>(collection: F_Collection<Collection_ID, ZodSchema>): F_Collection_Registry<Collections & { [key in Collection_ID]: F_Collection<Collection_ID, ZodSchema>}>{
18
+ let collections = this.collections as Collections & { [key in Collection_ID]: F_Collection<Collection_ID, ZodSchema>};
19
+ // @ts-expect-error
20
+ collections[collection.collection_id] = collection;
21
+ return this as F_Collection_Registry<Collections & { [key in Collection_ID]: F_Collection<Collection_ID, ZodSchema>}>;
22
+ }
23
+
24
+ compile(app: Router, api_prefix: string) {
25
+ for(let collection of Object.values(this.collections)){
26
+ compile(app, collection, api_prefix)
27
+ }
28
+ }
29
+ }