@yongdall/api-model 0.1.0 → 0.1.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/package.json +1 -1
- package/routers.yongdall.mjs +30 -35
- package/routers.yongdall.mjs.map +1 -1
package/package.json
CHANGED
package/routers.yongdall.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { Search, getPatternFields, runPattern, yieldPermissionConstraintFields }
|
|
|
3
3
|
import { Query, Where, getLabelPattern, getModelOptions } from "@yongdall/model";
|
|
4
4
|
import { ApiRouter, Param, e404, enumRouter, useBody } from "@yongdall/http";
|
|
5
5
|
import { useDatabase } from "@yongdall/connection";
|
|
6
|
-
import { createPermissionMatches, filterPermissionDocument, filterPermissionUpdate, getModel, getModelAuthorizationPermissions,
|
|
6
|
+
import { createPermissionMatches, filterPermissionDocument, filterPermissionUpdate, getModel, getModelAuthorizationPermissions, search2where, testPermissions, toDocumentFields } from "@yongdall/core";
|
|
7
7
|
|
|
8
8
|
//#region api/api-model/utils.mjs
|
|
9
9
|
/** @import { ModelTable, TableDefine } from '@yongdall/model'*/
|
|
@@ -27,7 +27,6 @@ async function loadDocumentLabel(list, model, databaseId) {
|
|
|
27
27
|
if (primaryFields.length === 1) {
|
|
28
28
|
const [field] = primaryFields;
|
|
29
29
|
where = where.and(field, "in", ids);
|
|
30
|
-
return;
|
|
31
30
|
} else {
|
|
32
31
|
/** @type {} */
|
|
33
32
|
const idsMap = [];
|
|
@@ -97,10 +96,10 @@ documentsRouter.get(async function(ctx) {
|
|
|
97
96
|
const model = await useModel();
|
|
98
97
|
const modelId = await useModelId();
|
|
99
98
|
if (!model || !modelId) return e404(ctx);
|
|
100
|
-
const permissions = await
|
|
101
|
-
if (
|
|
99
|
+
const permissions = await getModelAuthorizationPermissions(modelId, "query");
|
|
100
|
+
if (!permissions?.length) return e404(ctx);
|
|
102
101
|
const { sort, offset, limit, select, where, orWhere, or } = Search.merge(Search.parse(ctx.url.search.slice(1)), await useBody() || {});
|
|
103
|
-
const permissionMatches =
|
|
102
|
+
const permissionMatches = await createPermissionMatches(permissions);
|
|
104
103
|
let modelQuery = new Query(model, true).offset(offset).limit(limit);
|
|
105
104
|
if (permissionMatches) modelQuery = modelQuery.where(permissionMatches);
|
|
106
105
|
const searchWhere = await search2where(model.fields, where, orWhere, or);
|
|
@@ -110,10 +109,10 @@ documentsRouter.get(async function(ctx) {
|
|
|
110
109
|
const allFields = [
|
|
111
110
|
select || [],
|
|
112
111
|
Object.entries(model.fields).filter((v) => v[1].primary).map((v) => v[0]),
|
|
113
|
-
permissionMatches && permissions
|
|
112
|
+
permissionMatches && permissions.flatMap((v) => [...yieldPermissionConstraintFields(v)]) || []
|
|
114
113
|
].flat();
|
|
115
114
|
const [result, total] = await useDatabase(model.databaseId).transaction((t) => Promise.all([t.search(modelQuery, allFields), t.count(modelQuery)]));
|
|
116
|
-
const documents =
|
|
115
|
+
const documents = await Promise.all(result.map((v) => filterPermissionDocument(model, permissions, v)));
|
|
117
116
|
await loadDocumentsLabel(documents, model);
|
|
118
117
|
return {
|
|
119
118
|
documents,
|
|
@@ -124,11 +123,11 @@ documentsRouter.post(async (ctx) => {
|
|
|
124
123
|
const model = await useModel();
|
|
125
124
|
const modelId = await useModelId();
|
|
126
125
|
if (!model || !modelId) return e404(ctx);
|
|
127
|
-
const permissions =
|
|
128
|
-
if (
|
|
126
|
+
const permissions = await getModelAuthorizationPermissions(modelId, "create");
|
|
127
|
+
if (!permissions?.length) return e404(ctx);
|
|
129
128
|
const newDocument = (await useBody() || {}).document;
|
|
130
129
|
if (!newDocument) return e404(ctx);
|
|
131
|
-
const document =
|
|
130
|
+
const document = await filterPermissionDocument(model, permissions, newDocument);
|
|
132
131
|
if (!document) return e404(ctx);
|
|
133
132
|
return await useDatabase(model.databaseId).create(model, document);
|
|
134
133
|
});
|
|
@@ -149,7 +148,7 @@ async function loadPermissions() {
|
|
|
149
148
|
}
|
|
150
149
|
modelRouter.get(async function getDefine(ctx) {
|
|
151
150
|
const model = await useModel();
|
|
152
|
-
if (!model) return
|
|
151
|
+
if (!model) return null;
|
|
153
152
|
return {
|
|
154
153
|
...getModelOptions(model),
|
|
155
154
|
id: await useModelId() || "",
|
|
@@ -167,11 +166,10 @@ documentRouter.get(async (ctx) => {
|
|
|
167
166
|
const model = await useModel();
|
|
168
167
|
const modelId = await useModelId();
|
|
169
168
|
if (!model || !modelId) return e404(ctx);
|
|
170
|
-
const readPermissions =
|
|
171
|
-
if (
|
|
169
|
+
const readPermissions = await getModelAuthorizationPermissions(modelId, "read");
|
|
170
|
+
if (!readPermissions?.length) return e404(ctx);
|
|
172
171
|
const document = await useDocument();
|
|
173
172
|
if (!document) return e404(ctx);
|
|
174
|
-
if (!readPermissions) return { document: { ...await document.toJSON?.() || document } };
|
|
175
173
|
const doc = await filterPermissionDocument(model, readPermissions, document);
|
|
176
174
|
if (!doc) return e404(ctx);
|
|
177
175
|
return { document: doc };
|
|
@@ -180,31 +178,30 @@ documentRouter.put(async (ctx) => {
|
|
|
180
178
|
const model = await useModel();
|
|
181
179
|
const modelId = await useModelId();
|
|
182
180
|
if (!model || !modelId) return e404(ctx);
|
|
183
|
-
const updatePermissions =
|
|
184
|
-
if (
|
|
181
|
+
const updatePermissions = await getModelAuthorizationPermissions(modelId, "update");
|
|
182
|
+
if (!updatePermissions?.length) return e404(ctx);
|
|
185
183
|
const document = await useDocument();
|
|
186
184
|
if (!document) return e404(ctx);
|
|
187
185
|
const data = await useBody();
|
|
188
186
|
if (!data) return;
|
|
189
187
|
const newValue = data.document;
|
|
190
188
|
if (!newValue) return;
|
|
191
|
-
const newData =
|
|
192
|
-
const result = Object.keys(newData).length ? await useDatabase(model.databaseId).save(model, document, newData) : document;
|
|
189
|
+
const newData = await filterPermissionUpdate(model, updatePermissions, document, newValue);
|
|
190
|
+
const result = newData && Object.keys(newData).length ? await useDatabase(model.databaseId).save(model, document, newData) : document;
|
|
193
191
|
if (!result) return {};
|
|
194
|
-
const readPermissions =
|
|
195
|
-
if (!readPermissions) return
|
|
196
|
-
if (!readPermissions.length) return {};
|
|
192
|
+
const readPermissions = await getModelAuthorizationPermissions(modelId, "read");
|
|
193
|
+
if (!readPermissions?.length) return {};
|
|
197
194
|
return await filterPermissionDocument(model, readPermissions, result);
|
|
198
195
|
});
|
|
199
196
|
documentRouter.delete(async (ctx) => {
|
|
200
197
|
const model = await useModel();
|
|
201
198
|
const modelId = await useModelId();
|
|
202
199
|
if (!model || !modelId) return e404(ctx);
|
|
203
|
-
const permissions =
|
|
204
|
-
if (
|
|
200
|
+
const permissions = await getModelAuthorizationPermissions(modelId, "read");
|
|
201
|
+
if (!permissions?.length) return e404(ctx);
|
|
205
202
|
const document = await useDocument();
|
|
206
203
|
if (!document) return e404(ctx);
|
|
207
|
-
if (
|
|
204
|
+
if (!await testPermissions(permissions, document)) return e404(ctx);
|
|
208
205
|
await useDatabase(model.databaseId).destroy(model, document).then(Boolean);
|
|
209
206
|
ctx.status = 204;
|
|
210
207
|
});
|
|
@@ -219,8 +216,8 @@ documentRouter.route`fields/${fieldParam}`().get(async (ctx) => {
|
|
|
219
216
|
if (!Object.hasOwn(fields, fieldName)) return e404(ctx);
|
|
220
217
|
const field = fields[fieldName];
|
|
221
218
|
if (!field) return e404(ctx);
|
|
222
|
-
const readPermissions =
|
|
223
|
-
if (
|
|
219
|
+
const readPermissions = await getModelAuthorizationPermissions(modelId, "read");
|
|
220
|
+
if (!readPermissions?.length) return e404(ctx);
|
|
224
221
|
if (readPermissions) {
|
|
225
222
|
const group = field.group;
|
|
226
223
|
if (!readPermissions.find((v) => {
|
|
@@ -232,7 +229,6 @@ documentRouter.route`fields/${fieldParam}`().get(async (ctx) => {
|
|
|
232
229
|
}
|
|
233
230
|
const document = await useDocument();
|
|
234
231
|
if (!document) return e404(ctx);
|
|
235
|
-
if (!readPermissions) return { document: { ...await document.toJSON?.() || document } };
|
|
236
232
|
const doc = await filterPermissionDocument(model, readPermissions, document);
|
|
237
233
|
if (!doc) return e404(ctx);
|
|
238
234
|
if (!Object.hasOwn(doc, fieldName)) return e404(ctx);
|
|
@@ -249,10 +245,10 @@ optionsRouter.get(async function(ctx) {
|
|
|
249
245
|
const model = await useModel();
|
|
250
246
|
const modelId = await useModelId();
|
|
251
247
|
if (!model || !modelId) return e404(ctx);
|
|
252
|
-
const permissions = await
|
|
253
|
-
if (
|
|
248
|
+
const permissions = await getModelAuthorizationPermissions(modelId, "options");
|
|
249
|
+
if (!permissions?.length) return e404(ctx);
|
|
254
250
|
const { sort, offset, limit, select, where, orWhere, or } = Search.merge(Search.parse(ctx.url.search.slice(1)), await useBody() || {});
|
|
255
|
-
const permissionMatches =
|
|
251
|
+
const permissionMatches = await createPermissionMatches(permissions);
|
|
256
252
|
let modelQuery = new Query(model, true).offset(offset).limit(limit);
|
|
257
253
|
if (permissionMatches) modelQuery = modelQuery.where(permissionMatches);
|
|
258
254
|
const searchWhere = await search2where(model.fields, where, orWhere, or);
|
|
@@ -262,10 +258,10 @@ optionsRouter.get(async function(ctx) {
|
|
|
262
258
|
modelQuery = modelQuery.select([...new Set([
|
|
263
259
|
select || [],
|
|
264
260
|
Object.entries(model.fields).filter(([, { type }]) => type && typeof type === "string").map((v) => v[0]),
|
|
265
|
-
permissionMatches && permissions
|
|
261
|
+
permissionMatches && permissions.flatMap((v) => [...yieldPermissionConstraintFields(v)]) || []
|
|
266
262
|
].flat())]);
|
|
267
263
|
const documents = await useDatabase(model.databaseId).transaction((t) => t.select(modelQuery));
|
|
268
|
-
const options =
|
|
264
|
+
const options = await Promise.all(documents.map((v) => filterPermissionDocument(model, permissions, v)));
|
|
269
265
|
await loadDocumentsLabel(options, model);
|
|
270
266
|
return { options };
|
|
271
267
|
});
|
|
@@ -273,11 +269,10 @@ optionsRouter.get`${documentId}`(async (ctx) => {
|
|
|
273
269
|
const model = await useModel();
|
|
274
270
|
const modelId = await useModelId();
|
|
275
271
|
if (!model || !modelId) return e404(ctx);
|
|
276
|
-
const permissions =
|
|
277
|
-
if (
|
|
272
|
+
const permissions = await getModelAuthorizationPermissions(modelId, "options");
|
|
273
|
+
if (!permissions?.length) return e404(ctx);
|
|
278
274
|
const document = await useDocument();
|
|
279
275
|
if (!document) return e404(ctx);
|
|
280
|
-
if (!permissions) return { document: { ...await document.toJSON?.() || document } };
|
|
281
276
|
const option = await filterPermissionDocument(model, permissions, document);
|
|
282
277
|
if (!option) return e404(ctx);
|
|
283
278
|
return { option };
|
package/routers.yongdall.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routers.yongdall.mjs","names":["documentRouter","modelsRouter","documentsRouter","optionsRouter","documentRouter"],"sources":["../../api/api-model/utils.mjs","../../api/api-model/routers/model.documents.mjs","../../api/api-model/routers/models.mjs","../../api/api-model/routers/model.document.mjs","../../api/api-model/routers/model.options.mjs","../../api/api-model/routers/index.mjs"],"sourcesContent":["/** @import { ModelTable, TableDefine } from '@yongdall/model'*/\nimport { getPatternFields, runPattern } from '@yongdall/common';\nimport { Query, getLabelPattern, Where } from '@yongdall/model';\nimport { useDatabase } from '@yongdall/connection';\nimport { getModel } from '@yongdall/core';\n\n\n/**\n * \n * @param {[model: string, id: any, data: Record<string, any>, field: string][]} list\n * @param {TableDefine} model\n * @param {string?} [databaseId]\n */\nasync function loadDocumentLabel(list, model, databaseId) {\n\tconst labelPattern = getLabelPattern(model);\n\tif (!labelPattern) { return; }\n\tconst labelFields = getPatternFields(labelPattern);\n\tif (!labelFields.length) { return; }\n\tconst primaryFields = Object.entries(model.fields)\n\t\t.filter(([, v]) => v.primary)\n\t\t.sort(([, a], [, b]) => Number(a.primary) - Number(b.primary))\n\t\t.map(([v]) => v);\n\tif (!primaryFields.length) { return; }\n\tlet query = new Query(model, true);\n\tquery = query.select(primaryFields).select(labelFields);\n\tconst ids = [...new Set(list.map(([, id]) => id))];\n\tlet where = new Where();\n\tif (primaryFields.length === 1) {\n\t\tconst [field] = primaryFields;\n\t\twhere = where.and(field, 'in', ids);\n\t\treturn;\n\t} else {\n\t\t/** @type {} */\n\t\tconst idsMap = [];\n\t\tids.map(v => `${v}`.split('$'));\n\t\tfor (const id of ids) {\n\t\t\tconst values = `${id}`.split('$');\n\t\t\tif (values.length !== primaryFields.length) { continue; }\n\t\t\tidsMap.push([values]);\n\t\t}\n\t\tif (!idsMap.length) { return; }\n\t\twhere = where.and(primaryFields, 'in', idsMap);\n\n\n\t}\n\tconst result = await useDatabase(databaseId).select(query.where(where));\n\tif (!result.length) { return; }\n\tconst labels = Object.fromEntries(result.map(v => [\n\t\tprimaryFields.map(f => v[f]).join('$'),\n\t\trunPattern(labelPattern, v)\n\t]));\n\tfor (const [, id, data, field] of list) {\n\t\tconst label = Object.hasOwn(labels, id) && labels[id];\n\t\tif (!label) { continue; }\n\t\tdata[`${field}~label`] = label;\n\t}\n}\n/**\n * \n * @param {any[]} list \n * @param {ModelTable} model \n */\nexport async function loadDocumentsLabel(list, model) {\n\t/** @type {[model: string, id: any, data: Record<string, any>, field: string][]} */\n\tconst setList = [];\n\t/** @type {[model: ModelTable, list: any[]][]} */\n\tconst queue = [[model, list]];\n\tfor (let line = queue.shift(); line; line = queue.shift()) {\n\t\tconst [model, list] = line;\n\t\tfor (const [name, field] of Object.entries(model.fields)) {\n\t\t\tconst type = field.type;\n\t\t\tif (!type) { continue; }\n\t\t\tif (typeof type === 'object') {\n\t\t\t\tqueue.push([type, list.flatMap(v => v[name] || [])]);\n\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst modelName = field.model;\n\t\t\tif (!modelName) { continue; }\n\t\t\tfor (const item of list) {\n\t\t\t\tconst id = item[name];\n\t\t\t\tif (!id) { continue; }\n\t\t\t\tsetList.push([modelName, id, item, name]);\n\t\t\t}\n\t\t}\n\t}\n\tconst promises = [];\n\tfor (const [modelName, list] of Object.entries(Object.groupBy(setList, v => v[0]))) {\n\t\tif (!list) { continue; }\n\t\tpromises.push(\n\t\t\tgetModel(modelName)\n\t\t\t\t.then(model => model && loadDocumentLabel(list, model, model.databaseId)),\n\t\t);\n\t}\n\tawait Promise.all(promises);\n\n}\n","import { Search, yieldPermissionConstraintFields } from '@yongdall/common';\nimport { Query } from '@yongdall/model';\nimport { useBody, e404, enumRouter } from '@yongdall/http';\nimport { ApiRouter } from '@yongdall/http';\nimport useDocument, { documentId } from './useDocument.mjs';\nimport { useDatabase } from '@yongdall/connection';\nimport useModel, { useModelId } from './useModel.mjs';\nimport { createPermissionMatches, getModelAuthorizationPermissions, filterPermissionDocument, isSingleUser, search2where } from '@yongdall/core';\nimport { loadDocumentsLabel } from '../utils.mjs';\n\nconst documentsRouter = new ApiRouter();\n\n\n\ndocumentsRouter.get(async function (ctx) {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst permissions = await isSingleUser() ? null : await getModelAuthorizationPermissions(modelId, 'query');\n\tif (permissions && !permissions.length) { return e404(ctx); }\n\tconst { sort, offset, limit, select, where, orWhere, or } = Search.merge(\n\t\tSearch.parse(ctx.url.search.slice(1)),\n\t\tawait useBody() || {},\n\t);\n\n\tconst permissionMatches = permissions && await createPermissionMatches(permissions) || null;\n\n\tlet modelQuery = new Query(model, true).offset(offset).limit(limit);\n\tif (permissionMatches) {\n\t\tmodelQuery = modelQuery.where(permissionMatches);\n\t}\n\tconst searchWhere = await search2where(model.fields, where, orWhere, or);\n\tif (searchWhere) { modelQuery = modelQuery.where(searchWhere); }\n\n\tmodelQuery = modelQuery.sort();\n\tif (sort) { modelQuery = modelQuery.sort(...sort); }\n\tconst allFields = [\n\t\tselect || [],\n\t\tObject.entries(model.fields).filter(v => v[1].primary).map(v => v[0]),\n\t\tpermissionMatches && permissions?.flatMap(v => [...yieldPermissionConstraintFields(v)]) || [],\n\t].flat();\n\n\tconst [result, total] = await useDatabase(model.databaseId).transaction(t => Promise.all([t.search(modelQuery, allFields), t.count(modelQuery)]));\n\n\tconst documents = permissions ? await Promise.all(result.map(v => filterPermissionDocument(model, permissions, v))) : result;\n\tawait loadDocumentsLabel(documents, model);\n\treturn { documents, total };\n});\n\ndocumentsRouter.post(async ctx => {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst permissions = !await isSingleUser() && await getModelAuthorizationPermissions(modelId, 'create');\n\tif (permissions && !permissions.length) { return e404(ctx); }\n\tconst data = await useBody() || {};\n\tconst newDocument = data.document;\n\tif (!newDocument) { return e404(ctx); }\n\tconst document = permissions ? await filterPermissionDocument(model, permissions, newDocument) : newDocument;\n\tif (!document) { return e404(ctx); }\n\tconst doc = await useDatabase(model.databaseId).create(model, document);\n\treturn doc;\n});\n\nconst documentRouter = documentsRouter.route`${documentId}`();\ndocumentRouter.onionskin(async (ctx, next) => {\n\tconst doc = await useDocument();\n\tif (!doc) { return e404(ctx); }\n\treturn next();\n});\n\ndocumentRouter.route(enumRouter('documentApi'));\n\nexport default documentsRouter;\n","import { ApiRouter } from '@yongdall/http';\nimport { e404, enumRouter } from '@yongdall/http';\nimport {toDocumentFields} from '@yongdall/core';\nimport useModel, { modelId, useModelId } from './useModel.mjs';\nimport { getModelOptions } from '@yongdall/model';\n\n\n\nconst modelsRouter = new ApiRouter();\nconst modelRouter = modelsRouter.route`${modelId}`();\n\nasync function loadPermissions() {\n\treturn {};\n}\nmodelRouter.get(async function getDefine(ctx) {\n\tconst model = await useModel();\n\tif (!model) { return e404(ctx); }\n\treturn {\n\t\t...getModelOptions(model),\n\t\tid: await useModelId() || '',\n\t\tfields: toDocumentFields(model.fields),\n\t\tpermission: await loadPermissions(),\n\t}\n});\nmodelRouter.route(enumRouter('modelApi'));\n\nexport default modelsRouter;\n","import { e404, Param, useBody } from '@yongdall/http';\nimport { ApiRouter } from '@yongdall/http';\nimport useDocument from './useDocument.mjs';\nimport { useDatabase } from '@yongdall/connection';\nimport useModel, { useModelId } from './useModel.mjs';\nimport { filterPermissionDocument, filterPermissionUpdate, getModelAuthorizationPermissions, testPermissions } from '@yongdall/core';\nimport { isSingleUser } from '@yongdall/core';\n\n\nconst documentRouter = new ApiRouter();\n\n\ndocumentRouter.get(async ctx => {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst readPermissions = !await isSingleUser() && await getModelAuthorizationPermissions(modelId, 'read');\n\tif (readPermissions && !readPermissions.length) { return e404(ctx); }\n\tconst document = await useDocument();\n\tif (!document) { return e404(ctx); }\n\tif (!readPermissions) { return { document: { ...await document.toJSON?.() || document } }; }\n\tconst doc = await filterPermissionDocument(model, readPermissions, document);\n\tif (!doc) { return e404(ctx); }\n\treturn { document: doc };\n});\n\ndocumentRouter.put(async ctx => {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst updatePermissions = !await isSingleUser() && await getModelAuthorizationPermissions(modelId, 'update');\n\tif (updatePermissions && !updatePermissions.length) { return e404(ctx); }\n\tconst document = await useDocument();\n\tif (!document) { return e404(ctx); }\n\tconst data = await useBody();\n\tif (!data) { return; }\n\tconst newValue = data.document;\n\tif (!newValue) { return; }\n\tconst newData = updatePermissions\n\t\t? await filterPermissionUpdate(model, updatePermissions, document, newValue)\n\t\t: newValue;\n\tconst result = Object.keys(newData).length\n\t\t? await useDatabase(model.databaseId).save(model, document, newData)\n\t\t: document;\n\tif (!result) { return {}; }\n\t// TODO: 更新附加文档\n\tconst readPermissions = !await isSingleUser() && await getModelAuthorizationPermissions(modelId, 'read');\n\tif (!readPermissions) { return result || {}; }\n\tif (!readPermissions.length) { return {}; }\n\n\treturn await filterPermissionDocument(model, readPermissions, result);\n});\n\ndocumentRouter.delete(async ctx => {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst permissions = !await isSingleUser() && await getModelAuthorizationPermissions(modelId, 'read');\n\tif (permissions && !permissions.length) { return e404(ctx); }\n\tconst document = await useDocument();\n\tif (!document) { return e404(ctx); }\n\tif (permissions && !await testPermissions(permissions, document)) { return e404(ctx); }\n\tawait useDatabase(model.databaseId).destroy(model, document).then(Boolean);\n\t// TODO: 删除附加文档\n\tctx.status = 204;\n});\n\n\nconst fieldParam = new Param();\n\n// TODO: GET :field\n// TODO: POST :field\n// TODO: PUT :field\n// TODO: DELETE :field\nconst documentFieldsRouter = documentRouter.route`fields/${fieldParam}`();\ndocumentFieldsRouter.get(async ctx => {\n\tconst fieldName =fieldParam.param(ctx);\n\tif (!fieldName) { return e404(ctx); }\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst {fields} = model;\n\tif (!Object.hasOwn(fields, fieldName)) { return e404(ctx); }\n\tconst field = fields[fieldName];\n\tif (!field) { return e404(ctx) }\n\tconst readPermissions = !await isSingleUser() && await getModelAuthorizationPermissions(modelId, 'read');\n\tif (readPermissions && !readPermissions.length) { return e404(ctx); }\n\tif (readPermissions) {\n\t\tconst group = field.group;\n\t\tif (!readPermissions.find(v => {\n\t\t\tconst field = v.fields;\n\t\t\tif (field === fieldName || field === '*' || Array.isArray(field) && (field.includes(fieldName) || field.includes('*'))) {return true; }\n\t\t\tif (!group || v.group) { return false; }\n\t\t\tif (v.group === group || Array.isArray(v.group) && v.group.includes(group)) {return true; }\n\t\t})) { return e404(ctx); }\n\t}\n\tconst document = await useDocument();\n\tif (!document) { return e404(ctx); }\n\tif (!readPermissions) { return { document: { ...await document.toJSON?.() || document } }; }\n\tconst doc = await filterPermissionDocument(model, readPermissions, document);\n\tif (!doc) { return e404(ctx); }\n\tif (!Object.hasOwn(doc, fieldName)) { return e404(ctx); }\n\treturn { value: doc[fieldName] };\n\n})\n\n// TODO: GET :value\n// TODO: POST :value\n// TODO: PUT :value\n// TODO: DELETE :field\nconst documentValuesRouter = documentRouter.route`values`();\n\n// TODO: GET :dataset/records\n// TODO: POST :dataset/records\n// TODO: GET :dataset/records/:record\n// TODO: PUT :dataset/records/:record\n// TODO: DELETE :dataset/records/:record\nconst documentDatasetsRouter = documentRouter.route`datasets`();\n\n\n\n\nexport default documentRouter;\n","import { useBody } from '@yongdall/http';\nimport { Search, yieldPermissionConstraintFields } from '@yongdall/common';\nimport { Query } from '@yongdall/model';\nimport { ApiRouter } from '@yongdall/http';\nimport useDocument, { documentId } from './useDocument.mjs';\nimport { useDatabase } from '@yongdall/connection';\nimport useModel, { useModelId } from './useModel.mjs';\nimport { createPermissionMatches, getModelAuthorizationPermissions, filterPermissionDocument, isSingleUser, search2where } from '@yongdall/core';\nimport { e404 } from '@yongdall/http';\nimport { loadDocumentsLabel } from '../utils.mjs';\n\n\n\n\nconst optionsRouter = new ApiRouter();\n\n\n\noptionsRouter.get(async function (ctx) {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst permissions = await isSingleUser() ? null : await getModelAuthorizationPermissions(modelId, 'options');\n\tif (permissions && !permissions.length) { return e404(ctx); }\n\tconst { sort, offset, limit, select, where, orWhere, or } = Search.merge(\n\t\tSearch.parse(ctx.url.search.slice(1)),\n\t\tawait useBody() || {},\n\t);\n\n\tconst permissionMatches = permissions && await createPermissionMatches(permissions) || null;\n\n\tlet modelQuery = new Query(model, true).offset(offset).limit(limit);\n\tif (permissionMatches) {\n\t\tmodelQuery = modelQuery.where(permissionMatches);\n\t}\n\tconst searchWhere = await search2where(model.fields, where, orWhere, or);\n\tif (searchWhere) { modelQuery = modelQuery.where(searchWhere); }\n\n\tmodelQuery = modelQuery.sort();\n\tif (sort) { modelQuery = modelQuery.sort(...sort); }\n\tmodelQuery = modelQuery.select([...new Set([\n\t\tselect || [],\n\t\tObject.entries(model.fields).filter(([, { type }]) => type && typeof type === 'string').map(v => v[0]),\n\t\tpermissionMatches && permissions?.flatMap(v => [...yieldPermissionConstraintFields(v)]) || [],\n\t].flat())]);\n\n\tconst documents = await useDatabase(model.databaseId).transaction(t => t.select(modelQuery));\n\n\tconst options = permissions ? await Promise.all(documents.map(v => filterPermissionDocument(model, permissions, v))) : documents;\n\tawait loadDocumentsLabel(options, model);\n\treturn { options };\n});\n\n\noptionsRouter.get`${documentId}`(async ctx => {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst permissions = !await isSingleUser() && await getModelAuthorizationPermissions(modelId, 'options');\n\tif (permissions && !permissions.length) { return e404(ctx); }\n\tconst document = await useDocument();\n\tif (!document) { return e404(ctx); }\n\tif (!permissions) { return { document: { ...await document.toJSON?.() || document } }; }\n\tconst option = await filterPermissionDocument(model, permissions, document);\n\tif (!option) { return e404(ctx); }\n\treturn { option };\n});\n\nexport default optionsRouter;\n","import documentsRouter from './model.documents.mjs';\n\nimport modelsRouter from './models.mjs';\nimport documentRouter from './model.document.mjs';\nimport optionsRouter from './model.options.mjs';\n\nexport const api = {\n\tmodels: modelsRouter,\n}\nexport const modelApi = {\n\tdocuments: documentsRouter,\n\toptions: optionsRouter,\n}\nexport const documentApi = {\n\t'': documentRouter,\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"routers.yongdall.mjs","names":["documentRouter","modelsRouter","documentsRouter","optionsRouter","documentRouter"],"sources":["../../api/api-model/utils.mjs","../../api/api-model/routers/model.documents.mjs","../../api/api-model/routers/models.mjs","../../api/api-model/routers/model.document.mjs","../../api/api-model/routers/model.options.mjs","../../api/api-model/routers/index.mjs"],"sourcesContent":["/** @import { ModelTable, TableDefine } from '@yongdall/model'*/\nimport { getPatternFields, runPattern } from '@yongdall/common';\nimport { Query, getLabelPattern, Where } from '@yongdall/model';\nimport { useDatabase } from '@yongdall/connection';\nimport { getModel } from '@yongdall/core';\n\n\n/**\n * \n * @param {[model: string, id: any, data: Record<string, any>, field: string][]} list\n * @param {TableDefine} model\n * @param {string?} [databaseId]\n */\nasync function loadDocumentLabel(list, model, databaseId) {\n\tconst labelPattern = getLabelPattern(model);\n\tif (!labelPattern) { return; }\n\tconst labelFields = getPatternFields(labelPattern);\n\tif (!labelFields.length) { return; }\n\tconst primaryFields = Object.entries(model.fields)\n\t\t.filter(([, v]) => v.primary)\n\t\t.sort(([, a], [, b]) => Number(a.primary) - Number(b.primary))\n\t\t.map(([v]) => v);\n\tif (!primaryFields.length) { return; }\n\tlet query = new Query(model, true);\n\tquery = query.select(primaryFields).select(labelFields);\n\tconst ids = [...new Set(list.map(([, id]) => id))];\n\tlet where = new Where();\n\tif (primaryFields.length === 1) {\n\t\tconst [field] = primaryFields;\n\t\twhere = where.and(field, 'in', ids);\n\t} else {\n\t\t/** @type {} */\n\t\tconst idsMap = [];\n\t\tids.map(v => `${v}`.split('$'));\n\t\tfor (const id of ids) {\n\t\t\tconst values = `${id}`.split('$');\n\t\t\tif (values.length !== primaryFields.length) { continue; }\n\t\t\tidsMap.push([values]);\n\t\t}\n\t\tif (!idsMap.length) { return; }\n\t\twhere = where.and(primaryFields, 'in', idsMap);\n\n\n\t}\n\tconst result = await useDatabase(databaseId).select(query.where(where));\n\tif (!result.length) { return; }\n\tconst labels = Object.fromEntries(result.map(v => [\n\t\tprimaryFields.map(f => v[f]).join('$'),\n\t\trunPattern(labelPattern, v)\n\t]));\n\tfor (const [, id, data, field] of list) {\n\t\tconst label = Object.hasOwn(labels, id) && labels[id];\n\t\tif (!label) { continue; }\n\t\tdata[`${field}~label`] = label;\n\t}\n}\n/**\n * \n * @param {any[]} list \n * @param {ModelTable} model \n */\nexport async function loadDocumentsLabel(list, model) {\n\t/** @type {[model: string, id: any, data: Record<string, any>, field: string][]} */\n\tconst setList = [];\n\t/** @type {[model: ModelTable, list: any[]][]} */\n\tconst queue = [[model, list]];\n\tfor (let line = queue.shift(); line; line = queue.shift()) {\n\t\tconst [model, list] = line;\n\t\tfor (const [name, field] of Object.entries(model.fields)) {\n\t\t\tconst type = field.type;\n\t\t\tif (!type) { continue; }\n\t\t\tif (typeof type === 'object') {\n\t\t\t\tqueue.push([type, list.flatMap(v => v[name] || [])]);\n\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst modelName = field.model;\n\t\t\tif (!modelName) { continue; }\n\t\t\tfor (const item of list) {\n\t\t\t\tconst id = item[name];\n\t\t\t\tif (!id) { continue; }\n\t\t\t\tsetList.push([modelName, id, item, name]);\n\t\t\t}\n\t\t}\n\t}\n\tconst promises = [];\n\tfor (const [modelName, list] of Object.entries(Object.groupBy(setList, v => v[0]))) {\n\t\tif (!list) { continue; }\n\t\tpromises.push(\n\t\t\tgetModel(modelName)\n\t\t\t\t.then(model => model && loadDocumentLabel(list, model, model.databaseId)),\n\t\t);\n\t}\n\tawait Promise.all(promises);\n\n}\n","import { Search, yieldPermissionConstraintFields } from '@yongdall/common';\nimport { Query } from '@yongdall/model';\nimport { useBody, e404, enumRouter } from '@yongdall/http';\nimport { ApiRouter } from '@yongdall/http';\nimport useDocument, { documentId } from './useDocument.mjs';\nimport { useDatabase } from '@yongdall/connection';\nimport useModel, { useModelId } from './useModel.mjs';\nimport { createPermissionMatches, getModelAuthorizationPermissions, filterPermissionDocument, search2where } from '@yongdall/core';\nimport { loadDocumentsLabel } from '../utils.mjs';\n\nconst documentsRouter = new ApiRouter();\n\n\n\ndocumentsRouter.get(async function (ctx) {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst permissions = await getModelAuthorizationPermissions(modelId, 'query');\n\tif (!permissions?.length) { return e404(ctx); }\n\tconst { sort, offset, limit, select, where, orWhere, or } = Search.merge(\n\t\tSearch.parse(ctx.url.search.slice(1)),\n\t\tawait useBody() || {},\n\t);\n\n\tconst permissionMatches = await createPermissionMatches(permissions);\n\n\tlet modelQuery = new Query(model, true).offset(offset).limit(limit);\n\tif (permissionMatches) {\n\t\tmodelQuery = modelQuery.where(permissionMatches);\n\t}\n\tconst searchWhere = await search2where(model.fields, where, orWhere, or);\n\tif (searchWhere) { modelQuery = modelQuery.where(searchWhere); }\n\n\tmodelQuery = modelQuery.sort();\n\tif (sort) { modelQuery = modelQuery.sort(...sort); }\n\tconst allFields = [\n\t\tselect || [],\n\t\tObject.entries(model.fields).filter(v => v[1].primary).map(v => v[0]),\n\t\tpermissionMatches && permissions.flatMap(v => [...yieldPermissionConstraintFields(v)]) || [],\n\t].flat();\n\n\tconst [result, total] = await useDatabase(model.databaseId).transaction(t => Promise.all([t.search(modelQuery, allFields), t.count(modelQuery)]));\n\n\tconst documents = await Promise.all(result.map(v => filterPermissionDocument(model, permissions, v)));\n\tawait loadDocumentsLabel(documents, model);\n\treturn { documents, total };\n});\n\ndocumentsRouter.post(async ctx => {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst permissions = await getModelAuthorizationPermissions(modelId, 'create');\n\tif (!permissions?.length) { return e404(ctx); }\n\tconst data = await useBody() || {};\n\tconst newDocument = data.document;\n\tif (!newDocument) { return e404(ctx); }\n\tconst document = await filterPermissionDocument(model, permissions, newDocument);\n\tif (!document) { return e404(ctx); }\n\tconst doc = await useDatabase(model.databaseId).create(model, document);\n\treturn doc;\n});\n\nconst documentRouter = documentsRouter.route`${documentId}`();\ndocumentRouter.onionskin(async (ctx, next) => {\n\tconst doc = await useDocument();\n\tif (!doc) { return e404(ctx); }\n\treturn next();\n});\n\ndocumentRouter.route(enumRouter('documentApi'));\n\nexport default documentsRouter;\n","import { ApiRouter } from '@yongdall/http';\nimport { e404, enumRouter } from '@yongdall/http';\nimport {toDocumentFields} from '@yongdall/core';\nimport useModel, { modelId, useModelId } from './useModel.mjs';\nimport { getModelOptions } from '@yongdall/model';\n\n\n\nconst modelsRouter = new ApiRouter();\nconst modelRouter = modelsRouter.route`${modelId}`();\n\nasync function loadPermissions() {\n\treturn {};\n}\nmodelRouter.get(async function getDefine(ctx) {\n\tconst model = await useModel();\n\tif (!model) { return null; }\n\treturn {\n\t\t...getModelOptions(model),\n\t\tid: await useModelId() || '',\n\t\tfields: toDocumentFields(model.fields),\n\t\tpermission: await loadPermissions(),\n\t}\n});\nmodelRouter.route(enumRouter('modelApi'));\n\nexport default modelsRouter;\n","import { e404, Param, useBody } from '@yongdall/http';\nimport { ApiRouter } from '@yongdall/http';\nimport useDocument from './useDocument.mjs';\nimport { useDatabase } from '@yongdall/connection';\nimport useModel, { useModelId } from './useModel.mjs';\nimport { filterPermissionDocument, filterPermissionUpdate, getModelAuthorizationPermissions, testPermissions } from '@yongdall/core';\n\n\nconst documentRouter = new ApiRouter();\n\n\ndocumentRouter.get(async ctx => {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst readPermissions = await getModelAuthorizationPermissions(modelId, 'read');\n\tif (!readPermissions?.length) { return e404(ctx); }\n\tconst document = await useDocument();\n\tif (!document) { return e404(ctx); }\n\tconst doc = await filterPermissionDocument(model, readPermissions, document);\n\tif (!doc) { return e404(ctx); }\n\treturn { document: doc };\n});\n\ndocumentRouter.put(async ctx => {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst updatePermissions = await getModelAuthorizationPermissions(modelId, 'update');\n\tif (!updatePermissions?.length) { return e404(ctx); }\n\tconst document = await useDocument();\n\tif (!document) { return e404(ctx); }\n\tconst data = await useBody();\n\tif (!data) { return; }\n\tconst newValue = data.document;\n\tif (!newValue) { return; }\n\tconst newData = await filterPermissionUpdate(model, updatePermissions, document, newValue);\n\tconst result = newData && Object.keys(newData).length\n\t\t? await useDatabase(model.databaseId).save(model, document, newData)\n\t\t: document;\n\tif (!result) { return {}; }\n\tconst readPermissions = await getModelAuthorizationPermissions(modelId, 'read');\n\tif (!readPermissions?.length) { return {}; }\n\n\treturn await filterPermissionDocument(model, readPermissions, result);\n});\n\ndocumentRouter.delete(async ctx => {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst permissions = await getModelAuthorizationPermissions(modelId, 'read');\n\tif (!permissions?.length) { return e404(ctx); }\n\tconst document = await useDocument();\n\tif (!document) { return e404(ctx); }\n\tif (!await testPermissions(permissions, document)) { return e404(ctx); }\n\tawait useDatabase(model.databaseId).destroy(model, document).then(Boolean);\n\tctx.status = 204;\n});\n\n\nconst fieldParam = new Param();\n\n// TODO: GET :field\n// TODO: POST :field\n// TODO: PUT :field\n// TODO: DELETE :field\nconst documentFieldsRouter = documentRouter.route`fields/${fieldParam}`();\ndocumentFieldsRouter.get(async ctx => {\n\tconst fieldName =fieldParam.param(ctx);\n\tif (!fieldName) { return e404(ctx); }\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst {fields} = model;\n\tif (!Object.hasOwn(fields, fieldName)) { return e404(ctx); }\n\tconst field = fields[fieldName];\n\tif (!field) { return e404(ctx) }\n\tconst readPermissions = await getModelAuthorizationPermissions(modelId, 'read');\n\tif (!readPermissions?.length) { return e404(ctx); }\n\tif (readPermissions) {\n\t\tconst group = field.group;\n\t\tif (!readPermissions.find(v => {\n\t\t\tconst field = v.fields;\n\t\t\tif (field === fieldName || field === '*' || Array.isArray(field) && (field.includes(fieldName) || field.includes('*'))) {return true; }\n\t\t\tif (!group || v.group) { return false; }\n\t\t\tif (v.group === group || Array.isArray(v.group) && v.group.includes(group)) {return true; }\n\t\t})) { return e404(ctx); }\n\t}\n\tconst document = await useDocument();\n\tif (!document) { return e404(ctx); }\n\tconst doc = await filterPermissionDocument(model, readPermissions, document);\n\tif (!doc) { return e404(ctx); }\n\tif (!Object.hasOwn(doc, fieldName)) { return e404(ctx); }\n\treturn { value: doc[fieldName] };\n\n})\n\n// TODO: GET :value\n// TODO: POST :value\n// TODO: PUT :value\n// TODO: DELETE :field\nconst documentValuesRouter = documentRouter.route`values`();\n\n// TODO: GET :dataset/records\n// TODO: POST :dataset/records\n// TODO: GET :dataset/records/:record\n// TODO: PUT :dataset/records/:record\n// TODO: DELETE :dataset/records/:record\nconst documentDatasetsRouter = documentRouter.route`datasets`();\n\n\n\n\nexport default documentRouter;\n","import { useBody } from '@yongdall/http';\nimport { Search, yieldPermissionConstraintFields } from '@yongdall/common';\nimport { Query } from '@yongdall/model';\nimport { ApiRouter } from '@yongdall/http';\nimport useDocument, { documentId } from './useDocument.mjs';\nimport { useDatabase } from '@yongdall/connection';\nimport useModel, { useModelId } from './useModel.mjs';\nimport { createPermissionMatches, getModelAuthorizationPermissions, filterPermissionDocument, search2where } from '@yongdall/core';\nimport { e404 } from '@yongdall/http';\nimport { loadDocumentsLabel } from '../utils.mjs';\n\n\n\n\nconst optionsRouter = new ApiRouter();\n\n\n\noptionsRouter.get(async function (ctx) {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst permissions = await getModelAuthorizationPermissions(modelId, 'options');\n\tif (!permissions?.length) { return e404(ctx); }\n\tconst { sort, offset, limit, select, where, orWhere, or } = Search.merge(\n\t\tSearch.parse(ctx.url.search.slice(1)),\n\t\tawait useBody() || {},\n\t);\n\n\tconst permissionMatches = await createPermissionMatches(permissions);\n\n\tlet modelQuery = new Query(model, true).offset(offset).limit(limit);\n\tif (permissionMatches) {\n\t\tmodelQuery = modelQuery.where(permissionMatches);\n\t}\n\tconst searchWhere = await search2where(model.fields, where, orWhere, or);\n\tif (searchWhere) { modelQuery = modelQuery.where(searchWhere); }\n\n\tmodelQuery = modelQuery.sort();\n\tif (sort) { modelQuery = modelQuery.sort(...sort); }\n\tmodelQuery = modelQuery.select([...new Set([\n\t\tselect || [],\n\t\tObject.entries(model.fields).filter(([, { type }]) => type && typeof type === 'string').map(v => v[0]),\n\t\tpermissionMatches && permissions.flatMap(v => [...yieldPermissionConstraintFields(v)]) || [],\n\t].flat())]);\n\n\tconst documents = await useDatabase(model.databaseId).transaction(t => t.select(modelQuery));\n\n\tconst options = await Promise.all(documents.map(v => filterPermissionDocument(model, permissions, v)));\n\tawait loadDocumentsLabel(options, model);\n\treturn { options };\n});\n\n\noptionsRouter.get`${documentId}`(async ctx => {\n\tconst model = await useModel();\n\tconst modelId = await useModelId();\n\tif (!model || !modelId) { return e404(ctx); }\n\tconst permissions = await getModelAuthorizationPermissions(modelId, 'options');\n\tif (!permissions?.length) { return e404(ctx); }\n\tconst document = await useDocument();\n\tif (!document) { return e404(ctx); }\n\tconst option = await filterPermissionDocument(model, permissions, document);\n\tif (!option) { return e404(ctx); }\n\treturn { option };\n});\n\nexport default optionsRouter;\n","import documentsRouter from './model.documents.mjs';\n\nimport modelsRouter from './models.mjs';\nimport documentRouter from './model.document.mjs';\nimport optionsRouter from './model.options.mjs';\n\nexport const api = {\n\tmodels: modelsRouter,\n}\nexport const modelApi = {\n\tdocuments: documentsRouter,\n\toptions: optionsRouter,\n}\nexport const documentApi = {\n\t'': documentRouter,\n}\n"],"mappings":"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"}
|