@nest-my-admin/core 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -0
- package/dist/api/admin-api.service.d.ts +20 -0
- package/dist/api/admin-api.service.js +132 -21
- package/dist/api/admin-api.service.js.map +1 -1
- package/dist/api/write-participant.d.ts +5 -0
- package/dist/audit/audit-participant.js +4 -2
- package/dist/audit/audit-participant.js.map +1 -1
- package/dist/audit/audit-reader.d.ts +2 -0
- package/dist/audit/audit-reader.js +9 -1
- package/dist/audit/audit-reader.js.map +1 -1
- package/dist/audit/entities.d.ts +5 -0
- package/dist/audit/entities.js.map +1 -1
- package/dist/contract.d.ts +76 -4
- package/dist/crud/validate-write.d.ts +2 -0
- package/dist/crud/validate-write.js +2 -0
- package/dist/crud/validate-write.js.map +1 -1
- package/dist/files/admin-files.service.d.ts +19 -1
- package/dist/files/admin-files.service.js +20 -0
- package/dist/files/admin-files.service.js.map +1 -1
- package/dist/files/files.service.d.ts +42 -1
- package/dist/files/files.service.js +127 -0
- package/dist/files/files.service.js.map +1 -1
- package/dist/files/transaction-files.d.ts +25 -0
- package/dist/files/transaction-files.js +63 -0
- package/dist/files/transaction-files.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js.map +1 -1
- package/dist/inlines/inline-config.d.ts +36 -0
- package/dist/inlines/inline-config.js +130 -0
- package/dist/inlines/inline-config.js.map +1 -0
- package/dist/inlines/inline-reader.d.ts +38 -0
- package/dist/inlines/inline-reader.js +84 -0
- package/dist/inlines/inline-reader.js.map +1 -0
- package/dist/inlines/inline-writer.d.ts +102 -0
- package/dist/inlines/inline-writer.js +545 -0
- package/dist/inlines/inline-writer.js.map +1 -0
- package/dist/policy/admin-policy.service.d.ts +12 -0
- package/dist/policy/admin-policy.service.js +49 -6
- package/dist/policy/admin-policy.service.js.map +1 -1
- package/dist/registry/resource-registry.d.ts +3 -0
- package/dist/registry/resource-registry.js +10 -2
- package/dist/registry/resource-registry.js.map +1 -1
- package/dist/schema/build-resource-schema.js +1 -1
- package/dist/schema/build-resource-schema.js.map +1 -1
- package/dist/schema/field-config.d.ts +52 -6
- package/dist/schema/field-config.js +89 -11
- package/dist/schema/field-config.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
import { HttpException } from '@nestjs/common';
|
|
2
|
+
import { QueryFailedError } from 'typeorm';
|
|
3
|
+
import { parseRecordId, recordIdOf } from '../crud/record-id.js';
|
|
4
|
+
import { relationIdsOf } from '../crud/relation-writes.js';
|
|
5
|
+
import { whereOf } from '../crud/stored-row.js';
|
|
6
|
+
import { validateWrite } from '../crud/validate-write.js';
|
|
7
|
+
import { AdminBadRequestError, AdminError, AdminForbiddenError, AdminForbiddenFieldsError, AdminNotFoundError, AdminValidationError } from '../errors.js';
|
|
8
|
+
import { codeForStatus, hostError, toErrorResponse } from '../http/error-response.js';
|
|
9
|
+
import { MAX_INLINE_ROWS } from '../schema/field-config.js';
|
|
10
|
+
const KEY = /^.{1,64}$/su;
|
|
11
|
+
const isObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
12
|
+
/**
|
|
13
|
+
* Saves the `_inlines` of a parent's POST or PATCH inside the parent's write (spec §5.2 inlines), in three steps:
|
|
14
|
+
*
|
|
15
|
+
* 1. `prepare` (before the transaction): the shape, the child's permissions (403), its field rules (403
|
|
16
|
+
* FORBIDDEN_FIELDS) and each entry's validation by the child's DTO, as its own endpoints would (422);
|
|
17
|
+
* 2. `check` (in the transaction, before the parent is written): every `_id` is a child of THIS parent inside the
|
|
18
|
+
* user's view scope and the operation's scope (else 404), `_version`s (409), `@AdminCan` rules (403), `readonlyIf`
|
|
19
|
+
* (422), the order list and the resulting count (`min`/`max`, 422). A refused save has written nothing;
|
|
20
|
+
* 3. `apply` (after the parent): deletes, updates, then creates, each through the CHILD resource's own method inside
|
|
21
|
+
* `change()`, so host overrides, hooks, files and the audit log (with `meta.parent`) apply as on its endpoints. A
|
|
22
|
+
* failure there rolls back the transaction, parent included (inlines need `transactions`, checked at boot).
|
|
23
|
+
*/
|
|
24
|
+
export class InlineWriter {
|
|
25
|
+
deps;
|
|
26
|
+
constructor(deps) {
|
|
27
|
+
this.deps = deps;
|
|
28
|
+
}
|
|
29
|
+
/** Step 1, before the transaction. `raw` is the body's `_inlines` (undefined when it has none). */
|
|
30
|
+
async prepare(parent, raw, ctx, creating) {
|
|
31
|
+
const { policy } = this.deps;
|
|
32
|
+
const perms = policy.permissionsOf(ctx);
|
|
33
|
+
// An inline whose child or link field the user may not see is not there for them (as in the schema).
|
|
34
|
+
const viewable = parent.inlines.filter((inline) => policy.canSeeInline(inline.child, inline.link, ctx));
|
|
35
|
+
const sent = raw === undefined ? {} : raw;
|
|
36
|
+
const shape = {};
|
|
37
|
+
if (!isObject(sent))
|
|
38
|
+
throw new AdminValidationError({ _inlines: ['must be an object of inline name → changes'] });
|
|
39
|
+
for (const name of Object.keys(sent)) {
|
|
40
|
+
// An inline the user cannot view is not there for them (as in the schema).
|
|
41
|
+
if (!viewable.some((inline) => inline.name === name))
|
|
42
|
+
shape[`_inlines.${name}`] = [`is not an inline of ${parent.schema.label}`];
|
|
43
|
+
}
|
|
44
|
+
if (Object.keys(shape).length > 0)
|
|
45
|
+
throw new AdminValidationError(shape);
|
|
46
|
+
// A new parent checks every inline it shows (`min` counts rows that will exist); an update only those it changes.
|
|
47
|
+
const inlines = viewable.filter((inline) => creating || Object.hasOwn(sent, inline.name));
|
|
48
|
+
const parsed = inlines.map((inline) => parseChanges(inline, sent[inline.name] ?? {}, shape));
|
|
49
|
+
if (Object.keys(shape).length > 0)
|
|
50
|
+
throw new AdminValidationError(shape, 'The inline changes are malformed');
|
|
51
|
+
// 403 before anything else: the child's operations, then its field rules.
|
|
52
|
+
for (const { inline, creates, updates, deletes, order } of parsed) {
|
|
53
|
+
const { child } = inline;
|
|
54
|
+
if (creates.length > 0) {
|
|
55
|
+
// As the child's own create endpoint answers it.
|
|
56
|
+
if (!child.schema.creatable)
|
|
57
|
+
throw new AdminBadRequestError(`${child.schema.label} records are created as one of their kinds`);
|
|
58
|
+
policy.require(child, 'create', ctx);
|
|
59
|
+
}
|
|
60
|
+
if (updates.length > 0)
|
|
61
|
+
policy.require(child, 'update', ctx);
|
|
62
|
+
if (deletes.length > 0)
|
|
63
|
+
policy.require(child, 'delete', ctx);
|
|
64
|
+
// Ruling 4: reordering writes the order field, so it takes the right to update that field.
|
|
65
|
+
if (order !== undefined && inline.order !== undefined && !this.deps.view(child, ctx).schema.form.update.includes(inline.order)) {
|
|
66
|
+
throw new AdminForbiddenError(`You may not reorder ${child.schema.label} records`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const forbidden = {};
|
|
70
|
+
for (const { inline, creates, updates } of parsed) {
|
|
71
|
+
const at = `_inlines.${inline.name}`;
|
|
72
|
+
creates.forEach((entry, index) => collect(forbidden, `${at}.create.${index}`, () => policy.checkWriteFields(inline.child, entry.body, inline.child.schema.form.create, ctx)));
|
|
73
|
+
for (const entry of updates)
|
|
74
|
+
collect(forbidden, `${at}.update.${entry.raw}`, () => policy.checkWriteFields(inline.child, entry.body, inline.child.schema.form.update, ctx));
|
|
75
|
+
}
|
|
76
|
+
if (Object.keys(forbidden).length > 0)
|
|
77
|
+
throw new AdminForbiddenFieldsError(forbidden);
|
|
78
|
+
// Each entry as the child's own endpoint validates it; all errors of the save at once.
|
|
79
|
+
const errors = {};
|
|
80
|
+
const planned = [];
|
|
81
|
+
for (const { inline, creates, updates, deletes, order } of parsed) {
|
|
82
|
+
const { child } = inline;
|
|
83
|
+
const schema = this.deps.view(child, ctx).schema;
|
|
84
|
+
const resource = child.resource;
|
|
85
|
+
const at = `_inlines.${inline.name}`;
|
|
86
|
+
const setsOrder = (body, path) => {
|
|
87
|
+
if (order !== undefined && inline.order !== undefined && Object.hasOwn(body, inline.order))
|
|
88
|
+
errors[`${path}.${inline.order}`] = ['is set by the order list'];
|
|
89
|
+
};
|
|
90
|
+
const result = { inline, creates: [], updates: [], deletes, ...(order !== undefined ? { order } : {}) };
|
|
91
|
+
for (const [index, entry] of creates.entries()) {
|
|
92
|
+
const path = `${at}.create.${index}`;
|
|
93
|
+
setsOrder(entry.body, path);
|
|
94
|
+
const dto = await validated(errors, path, () => validateWrite(entry.body, { allowed: schema.form.create, dto: resource.form?.create, fields: schema.fields, sanitizeHtml: this.deps.sanitizeHtml, ignore: [inline.link] }));
|
|
95
|
+
const relationIds = dto ? relationsOf(errors, path, dto, schema) : undefined;
|
|
96
|
+
if (dto && relationIds)
|
|
97
|
+
result.creates.push({ key: entry.key, index, dto: dto, relationIds });
|
|
98
|
+
}
|
|
99
|
+
for (const entry of updates) {
|
|
100
|
+
const path = `${at}.update.${entry.raw}`;
|
|
101
|
+
setsOrder(entry.body, path);
|
|
102
|
+
const dto = await validated(errors, path, () => validateWrite(entry.body, { allowed: schema.form.update, dto: resource.form?.update ?? resource.form?.create, partial: true, fields: schema.fields, sanitizeHtml: this.deps.sanitizeHtml }));
|
|
103
|
+
const relationIds = dto ? relationsOf(errors, path, dto, schema) : undefined;
|
|
104
|
+
if (dto && relationIds)
|
|
105
|
+
result.updates.push({ raw: entry.raw, canonical: entry.canonical, id: entry.id, ...(entry.version !== undefined ? { version: entry.version } : {}), dto: dto, relationIds });
|
|
106
|
+
}
|
|
107
|
+
planned.push(result);
|
|
108
|
+
}
|
|
109
|
+
if (Object.keys(errors).length > 0)
|
|
110
|
+
throw new AdminValidationError(errors);
|
|
111
|
+
return { parent, creating, inlines: planned };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Inside the transaction, before the parent is written: reads what the save touches and decides every 404, 409,
|
|
115
|
+
* 403 and 422 left, so that a refused save writes nothing. `parentEntity` is the stored parent (undefined when it
|
|
116
|
+
* is being created: it has no children yet, so any `_id` is not one of them).
|
|
117
|
+
*/
|
|
118
|
+
async check(plan, parentEntity, tx) {
|
|
119
|
+
const out = [];
|
|
120
|
+
const errors = {};
|
|
121
|
+
for (const planned of plan.inlines)
|
|
122
|
+
out.push(await this.checkInline(planned, parentEntity, tx, errors));
|
|
123
|
+
if (Object.keys(errors).length > 0)
|
|
124
|
+
throw new AdminValidationError(errors);
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
async checkInline(planned, parentEntity, tx, errors) {
|
|
128
|
+
const { policy } = this.deps;
|
|
129
|
+
const { inline, creates, updates, deletes, order } = planned;
|
|
130
|
+
const { child } = inline;
|
|
131
|
+
const keys = child.schema.primaryKeys;
|
|
132
|
+
const at = `_inlines.${inline.name}`;
|
|
133
|
+
const label = child.schema.label;
|
|
134
|
+
const notFound = (raw) => new AdminNotFoundError(`${label} "${raw}" not found`);
|
|
135
|
+
const linkValue = parentEntity ? parentEntity[inline.referenced] : undefined;
|
|
136
|
+
const positions = new Map();
|
|
137
|
+
const moves = new Map();
|
|
138
|
+
const rows = new Map();
|
|
139
|
+
if (!parentEntity || linkValue === null || linkValue === undefined) {
|
|
140
|
+
// No children can be named: a new parent (or one whose referenced value is empty) has none.
|
|
141
|
+
const first = updates[0]?.raw ?? deletes[0]?.raw ?? order?.find((item) => !creates.some((entry) => entry.key === item));
|
|
142
|
+
if (first !== undefined)
|
|
143
|
+
throw notFound(first);
|
|
144
|
+
if (order !== undefined)
|
|
145
|
+
this.checkOrder(planned, [], new Set(), errors, positions);
|
|
146
|
+
this.checkCount(inline, creates.length, errors);
|
|
147
|
+
return { planned, rows, moves, positions };
|
|
148
|
+
}
|
|
149
|
+
// Children of THIS parent that the user sees: the child's query() and the user's view scopes, as its findOne.
|
|
150
|
+
const children = () => {
|
|
151
|
+
const manager = tx.manager ?? child.dataSource.manager;
|
|
152
|
+
const qb = manager.getRepository(child.metadata.target).createQueryBuilder('nma_child');
|
|
153
|
+
const restricted = policy.applyScopes(child.resource.query(qb, tx), child, 'view', tx);
|
|
154
|
+
return restricted.andWhere(`nma_child.${inline.link} = :nmaInlineParent`, { nmaInlineParent: linkValue });
|
|
155
|
+
};
|
|
156
|
+
// The order list is checked against the rows the user sees, and decides which of them move.
|
|
157
|
+
let visible;
|
|
158
|
+
if (order !== undefined && inline.order !== undefined) {
|
|
159
|
+
visible = await children()
|
|
160
|
+
.select([...keys, inline.order].map((name) => `nma_child.${name}`))
|
|
161
|
+
.take(MAX_INLINE_ROWS + 1)
|
|
162
|
+
.getMany();
|
|
163
|
+
if (visible.length > MAX_INLINE_ROWS) {
|
|
164
|
+
errors[at] = [`has more than ${MAX_INLINE_ROWS} rows; reorder them in their own list`];
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
const existing = visible.map((row) => recordIdOf(row, keys));
|
|
168
|
+
const deleted = new Set(deletes.map((entry) => entry.canonical));
|
|
169
|
+
const known = new Map(existing.map((id, index) => [id, visible[index]]));
|
|
170
|
+
// Named in `order` but not a row of this parent the user sees (nor a new row's `_key`): as for update and delete.
|
|
171
|
+
for (const item of order) {
|
|
172
|
+
if (creates.some((entry) => entry.key === item))
|
|
173
|
+
continue;
|
|
174
|
+
const canonical = canonicalId(child, item);
|
|
175
|
+
if (canonical === undefined || !known.has(canonical))
|
|
176
|
+
throw notFound(item);
|
|
177
|
+
}
|
|
178
|
+
for (const entry of creates)
|
|
179
|
+
if (known.has(entry.key))
|
|
180
|
+
errors[`${at}.create.${entry.index}._key`] = ['is the id of an existing row'];
|
|
181
|
+
const remaining = existing.filter((id) => !deleted.has(id));
|
|
182
|
+
this.checkOrder(planned, remaining, deleted, errors, positions);
|
|
183
|
+
for (const [item, position] of positions) {
|
|
184
|
+
const row = known.get(item);
|
|
185
|
+
if (row && Number(row[inline.order]) !== position)
|
|
186
|
+
moves.set(item, position);
|
|
187
|
+
}
|
|
188
|
+
// Positions of new rows are kept by `_key`; those of existing rows only when they move.
|
|
189
|
+
for (const id of existing)
|
|
190
|
+
positions.delete(id);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Every named row: a child of this parent in the user's view (404 for the whole save otherwise).
|
|
194
|
+
const named = new Map();
|
|
195
|
+
for (const entry of [...updates, ...deletes])
|
|
196
|
+
named.set(entry.canonical, { raw: entry.raw, id: entry.id });
|
|
197
|
+
for (const canonical of moves.keys())
|
|
198
|
+
if (!named.has(canonical))
|
|
199
|
+
named.set(canonical, { raw: canonical, id: parseRecordId(canonical, child.schema) });
|
|
200
|
+
if (named.size > 0) {
|
|
201
|
+
const found = await children()
|
|
202
|
+
.select(keys.map((key) => `nma_child.${key}`))
|
|
203
|
+
.andWhereInIds([...named.values()].map((entry) => entry.id))
|
|
204
|
+
.getMany();
|
|
205
|
+
const owned = new Set(found.map((entity) => recordIdOf(entity, keys)));
|
|
206
|
+
for (const [canonical, entry] of named)
|
|
207
|
+
if (!owned.has(canonical))
|
|
208
|
+
throw notFound(entry.raw);
|
|
209
|
+
// ...and inside the scopes of what is done to it.
|
|
210
|
+
const updated = [...updates.map((entry) => entry.canonical), ...[...moves.keys()]];
|
|
211
|
+
const allowedUpdates = await policy.allowedIds(child, [...new Set(updated)].map((canonical) => named.get(canonical).id), 'update', tx);
|
|
212
|
+
for (const canonical of updated)
|
|
213
|
+
if (!allowedUpdates.has(canonical))
|
|
214
|
+
throw notFound(named.get(canonical).raw);
|
|
215
|
+
const allowedDeletes = await policy.allowedIds(child, deletes.map((entry) => entry.id), 'delete', tx);
|
|
216
|
+
for (const entry of deletes)
|
|
217
|
+
if (!allowedDeletes.has(entry.canonical))
|
|
218
|
+
throw notFound(entry.raw);
|
|
219
|
+
// Then each row as the child's own PATCH and DELETE read it: its findOne (an override may refuse a row or load
|
|
220
|
+
// more). That entity is what @AdminCan, readonlyIf, relationOptions() values and the participants see.
|
|
221
|
+
for (const [canonical, entry] of named) {
|
|
222
|
+
const entity = await child.resource.findOne(entry.id, tx);
|
|
223
|
+
if (!entity)
|
|
224
|
+
throw notFound(entry.raw);
|
|
225
|
+
rows.set(canonical, entity);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// Versions (409 naming the row), then `@AdminCan` (403), then `readonlyIf` (422).
|
|
229
|
+
for (const entry of updates) {
|
|
230
|
+
if (entry.version === undefined)
|
|
231
|
+
continue;
|
|
232
|
+
try {
|
|
233
|
+
await this.deps.checkVersion(child, entry.id, entry.version, tx);
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
throw atRow(error, `${at}.update.${entry.raw}`, child, this.deps.errorMapper);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
for (const entry of deletes) {
|
|
240
|
+
if (!policy.recordRule(child, 'delete', rows.get(entry.canonical), tx))
|
|
241
|
+
throw new AdminForbiddenError(`You may not delete ${label} "${entry.raw}"`);
|
|
242
|
+
}
|
|
243
|
+
for (const canonical of new Set([...updates.map((entry) => entry.canonical), ...moves.keys()])) {
|
|
244
|
+
if (!policy.recordRule(child, 'update', rows.get(canonical), tx))
|
|
245
|
+
throw new AdminForbiddenError(`You may not update ${label} "${named.get(canonical).raw}"`);
|
|
246
|
+
}
|
|
247
|
+
for (const entry of updates) {
|
|
248
|
+
const locked = this.deps.lockedFields(child, rows.get(entry.canonical)).filter((name) => Object.hasOwn(entry.dto, name));
|
|
249
|
+
for (const name of locked)
|
|
250
|
+
errors[`${at}.update.${entry.raw}.${name}`] = ['is read-only'];
|
|
251
|
+
}
|
|
252
|
+
if (inline.order !== undefined) {
|
|
253
|
+
for (const canonical of moves.keys()) {
|
|
254
|
+
if (this.deps.lockedFields(child, rows.get(canonical)).includes(inline.order))
|
|
255
|
+
errors[at] = [`${label} "${named.get(canonical).raw}" cannot be moved`];
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// The count of rows that will exist (as the user sees them). Read without a lock: two saves of the same parent at
|
|
259
|
+
// the same time can each stay within `max` and together exceed it (or go below `min`).
|
|
260
|
+
if (creates.length > 0 || (deletes.length > 0 && inline.min !== undefined)) {
|
|
261
|
+
const before = visible && visible.length <= MAX_INLINE_ROWS ? visible.length : await children().getCount();
|
|
262
|
+
this.checkCount(inline, before - deletes.length + creates.length, errors);
|
|
263
|
+
}
|
|
264
|
+
return { planned, rows, moves, positions };
|
|
265
|
+
}
|
|
266
|
+
/** `order` lists every row left (`remaining` ids, then the new rows' keys) exactly once; positions by index. */
|
|
267
|
+
checkOrder(planned, remaining, deleted, errors, positions) {
|
|
268
|
+
const { inline, creates, order } = planned;
|
|
269
|
+
const at = `_inlines.${inline.name}`;
|
|
270
|
+
const expected = new Set([...remaining, ...creates.map((entry) => entry.key)]);
|
|
271
|
+
const seen = new Set();
|
|
272
|
+
for (const [index, item] of order.entries()) {
|
|
273
|
+
const canonical = creates.some((entry) => entry.key === item) ? item : (canonicalId(inline.child, item) ?? item);
|
|
274
|
+
if (deleted.has(canonical)) {
|
|
275
|
+
errors[at] = [`order names "${item}", which this save deletes`];
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (seen.has(canonical)) {
|
|
279
|
+
errors[at] = [`order names "${item}" twice`];
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
seen.add(canonical);
|
|
283
|
+
positions.set(canonical, index);
|
|
284
|
+
}
|
|
285
|
+
const missing = [...expected].filter((item) => !seen.has(item));
|
|
286
|
+
if (missing.length > 0)
|
|
287
|
+
errors[at] = [`order must list every row; missing: ${missing.join(', ')}`];
|
|
288
|
+
}
|
|
289
|
+
checkCount(inline, count, errors) {
|
|
290
|
+
const at = `_inlines.${inline.name}`;
|
|
291
|
+
if (inline.min !== undefined && count < inline.min)
|
|
292
|
+
errors[at] = [`must have at least ${inline.min} ${inline.min === 1 ? 'row' : 'rows'}`];
|
|
293
|
+
else if (count > inline.max)
|
|
294
|
+
errors[at] = [`may have at most ${inline.max} rows`];
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* After the parent: every change through the child resource's own method, inside the parent's write. Deletes, then
|
|
298
|
+
* updates (with their new positions), rows that only move, then creates (link and position set by the server).
|
|
299
|
+
*/
|
|
300
|
+
async apply(plan, checked, parentEntity, tx) {
|
|
301
|
+
const { parent } = plan;
|
|
302
|
+
const parentRef = { resource: parent.schema.name, recordId: recordIdOf(parentEntity, parent.schema.primaryKeys) };
|
|
303
|
+
let parentValues;
|
|
304
|
+
// The parent's values as the user sees them, body over stored (`values._parent` of relationOptions()).
|
|
305
|
+
const withParent = async (values) => ({ ...values, _parent: (parentValues ??= { _resource: parent.schema.name, ...(await this.deps.values(parent, parentEntity, tx)) }) });
|
|
306
|
+
const hasIds = (ids) => [...ids.values()].some((list) => list.length > 0);
|
|
307
|
+
for (const { planned, rows, moves, positions } of checked) {
|
|
308
|
+
const { inline, creates, updates, deletes } = planned;
|
|
309
|
+
const { child } = inline;
|
|
310
|
+
const resource = child.resource;
|
|
311
|
+
const at = `_inlines.${inline.name}`;
|
|
312
|
+
const run = async (path, change, method) => {
|
|
313
|
+
try {
|
|
314
|
+
return await this.deps.change({ ...change, parent: parentRef }, tx, method);
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
throw atRow(error, path, child, this.deps.errorMapper);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
for (const entry of deletes) {
|
|
321
|
+
await run(`${at}.delete.${entry.raw}`, { kind: 'delete', target: child, existing: rows.get(entry.canonical), id: entry.id }, () => resource.delete(entry.id, tx));
|
|
322
|
+
}
|
|
323
|
+
for (const entry of updates) {
|
|
324
|
+
const existing = rows.get(entry.canonical);
|
|
325
|
+
const dto = moves.has(entry.canonical) ? { ...entry.dto, [inline.order]: moves.get(entry.canonical) } : entry.dto;
|
|
326
|
+
await run(`${at}.update.${entry.raw}`, { kind: 'update', target: child, existing, id: entry.id, dto }, async () => {
|
|
327
|
+
if (hasIds(entry.relationIds)) {
|
|
328
|
+
const values = { ...(await this.deps.values(child, existing, tx)), ...dto };
|
|
329
|
+
await this.deps.checkRelationsExist(child, entry.relationIds, tx, await withParent(values));
|
|
330
|
+
}
|
|
331
|
+
return this.deps.reloadIfEmpty(child, await resource.update(entry.id, dto, tx), entry.id, tx);
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
const updated = new Set(updates.map((entry) => entry.canonical));
|
|
335
|
+
for (const [canonical, position] of moves) {
|
|
336
|
+
if (updated.has(canonical))
|
|
337
|
+
continue;
|
|
338
|
+
const id = parseRecordId(canonical, child.schema);
|
|
339
|
+
const dto = { [inline.order]: position };
|
|
340
|
+
await run(at, { kind: 'update', target: child, existing: rows.get(canonical), id, dto }, async () => this.deps.reloadIfEmpty(child, await resource.update(id, dto, tx), id, tx));
|
|
341
|
+
}
|
|
342
|
+
const link = parentEntity[inline.referenced];
|
|
343
|
+
// The link is checked like any relation id the client sends: the child's relationOptions() may exclude parents.
|
|
344
|
+
const linkId = parentEntity[inline.relation.inverseEntityMetadata.primaryColumns[0].propertyName];
|
|
345
|
+
for (const entry of creates) {
|
|
346
|
+
const position = positions.get(entry.key);
|
|
347
|
+
const dto = { ...entry.dto, ...(position !== undefined ? { [inline.order]: position } : {}), [inline.link]: link };
|
|
348
|
+
await run(`${at}.create.${entry.index}`, { kind: 'create', target: child, dto }, async () => {
|
|
349
|
+
await this.deps.checkRelationsExist(child, new Map([...entry.relationIds, [inline.link, [linkId]]]), tx, await withParent(dto));
|
|
350
|
+
const result = await resource.create(dto, tx);
|
|
351
|
+
if (typeof result !== 'object' || result === null)
|
|
352
|
+
throw new Error(`${child.className}.create() must return the created entity`);
|
|
353
|
+
return result;
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/** The shape of one inline's changes; problems go to `errors` by path. Invalid `_id`s are 404s, as on the child's own routes. */
|
|
360
|
+
function parseChanges(inline, raw, errors) {
|
|
361
|
+
const { child } = inline;
|
|
362
|
+
const at = `_inlines.${inline.name}`;
|
|
363
|
+
const out = { inline, creates: [], updates: [], deletes: [] };
|
|
364
|
+
if (!isObject(raw)) {
|
|
365
|
+
errors[at] = ['must be an object with create, update, delete and order'];
|
|
366
|
+
return out;
|
|
367
|
+
}
|
|
368
|
+
for (const key of Object.keys(raw))
|
|
369
|
+
if (!['create', 'update', 'delete', 'order'].includes(key))
|
|
370
|
+
errors[`${at}.${key}`] = ['is not create, update, delete or order'];
|
|
371
|
+
const list = (name) => {
|
|
372
|
+
const value = raw[name];
|
|
373
|
+
if (value === undefined)
|
|
374
|
+
return undefined;
|
|
375
|
+
if (!Array.isArray(value)) {
|
|
376
|
+
errors[`${at}.${name}`] = ['must be a list'];
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
if (value.length > MAX_INLINE_ROWS) {
|
|
380
|
+
errors[at] = [`takes at most ${MAX_INLINE_ROWS} entries in ${name}`];
|
|
381
|
+
return undefined;
|
|
382
|
+
}
|
|
383
|
+
return value;
|
|
384
|
+
};
|
|
385
|
+
const creates = list('create') ?? [];
|
|
386
|
+
const updates = list('update') ?? [];
|
|
387
|
+
const deletes = list('delete') ?? [];
|
|
388
|
+
const order = list('order');
|
|
389
|
+
if (creates.length + updates.length + deletes.length > MAX_INLINE_ROWS)
|
|
390
|
+
errors[at] = [`takes at most ${MAX_INLINE_ROWS} entries`];
|
|
391
|
+
if (errors[at])
|
|
392
|
+
return out;
|
|
393
|
+
// Nested inlines are refused; so is the link, which the server sets (and an update may not change).
|
|
394
|
+
const bodyOf = (entry, path, own) => {
|
|
395
|
+
if (Object.hasOwn(entry, '_inlines'))
|
|
396
|
+
errors[`${path}._inlines`] = ['inlines are one level deep'];
|
|
397
|
+
if (Object.hasOwn(entry, inline.link))
|
|
398
|
+
errors[`${path}.${inline.link}`] = ['is set by the parent'];
|
|
399
|
+
return Object.fromEntries(Object.entries(entry).filter(([key]) => !own.includes(key) && key !== '_inlines' && key !== inline.link));
|
|
400
|
+
};
|
|
401
|
+
const keys = new Set();
|
|
402
|
+
creates.forEach((entry, index) => {
|
|
403
|
+
const path = `${at}.create.${index}`;
|
|
404
|
+
if (!isObject(entry)) {
|
|
405
|
+
errors[path] = ['must be an object'];
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
const key = entry._key;
|
|
409
|
+
if (typeof key !== 'string' || !KEY.test(key))
|
|
410
|
+
errors[`${path}._key`] = ['must be a text of 1 to 64 characters'];
|
|
411
|
+
else if (keys.has(key))
|
|
412
|
+
errors[`${path}._key`] = ['is used twice'];
|
|
413
|
+
else
|
|
414
|
+
keys.add(key);
|
|
415
|
+
out.creates.push({ key: String(key), body: bodyOf(entry, path, ['_key']) });
|
|
416
|
+
});
|
|
417
|
+
const ids = new Set();
|
|
418
|
+
updates.forEach((entry, index) => {
|
|
419
|
+
if (!isObject(entry)) {
|
|
420
|
+
errors[`${at}.update.${index}`] = ['must be an object'];
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
const raw = entry._id;
|
|
424
|
+
if (typeof raw !== 'string' || raw === '') {
|
|
425
|
+
errors[`${at}.update.${index}._id`] = ['must be the id of a row'];
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
const path = `${at}.update.${raw}`;
|
|
429
|
+
const version = entry._version;
|
|
430
|
+
if (version !== undefined && (typeof version !== 'number' || !Number.isInteger(version)))
|
|
431
|
+
errors[`${path}._version`] = ['must be the version of the row (an integer)'];
|
|
432
|
+
const id = parseRecordId(raw, child.schema); // an id that cannot exist is a 404, as on the child's own routes
|
|
433
|
+
const canonical = recordIdOf(whereOf(child, id), child.schema.primaryKeys);
|
|
434
|
+
if (ids.has(canonical))
|
|
435
|
+
errors[at] = [`"${raw}" is updated twice`];
|
|
436
|
+
ids.add(canonical);
|
|
437
|
+
out.updates.push({ raw, canonical, id, ...(typeof version === 'number' ? { version } : {}), body: bodyOf(entry, path, ['_id', '_version']) });
|
|
438
|
+
});
|
|
439
|
+
if (deletes.some((entry) => typeof entry !== 'string' || entry === ''))
|
|
440
|
+
errors[`${at}.delete`] = ['must be a list of row ids'];
|
|
441
|
+
else {
|
|
442
|
+
const removed = new Set();
|
|
443
|
+
for (const raw of deletes) {
|
|
444
|
+
const id = parseRecordId(raw, child.schema);
|
|
445
|
+
const canonical = recordIdOf(whereOf(child, id), child.schema.primaryKeys);
|
|
446
|
+
if (ids.has(canonical))
|
|
447
|
+
errors[at] = [`"${raw}" is both updated and deleted`];
|
|
448
|
+
else if (removed.has(canonical))
|
|
449
|
+
errors[at] = [`"${raw}" is deleted twice`];
|
|
450
|
+
removed.add(canonical);
|
|
451
|
+
out.deletes.push({ raw, canonical, id });
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
if (order !== undefined) {
|
|
455
|
+
if (inline.order === undefined)
|
|
456
|
+
errors[`${at}.order`] = ['this inline has no order'];
|
|
457
|
+
else if (order.some((item) => typeof item !== 'string' || item === ''))
|
|
458
|
+
errors[`${at}.order`] = ['must be a list of row ids and new rows\' keys'];
|
|
459
|
+
else
|
|
460
|
+
out.order = order;
|
|
461
|
+
}
|
|
462
|
+
return out;
|
|
463
|
+
}
|
|
464
|
+
/** The canonical `_id` of a sent id, or undefined when it cannot be one. */
|
|
465
|
+
function canonicalId(child, raw) {
|
|
466
|
+
try {
|
|
467
|
+
return recordIdOf(whereOf(child, parseRecordId(raw, child.schema)), child.schema.primaryKeys);
|
|
468
|
+
}
|
|
469
|
+
catch {
|
|
470
|
+
return undefined;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/** Runs a field check; its FORBIDDEN_FIELDS go to `out` under `path`. */
|
|
474
|
+
function collect(out, path, check) {
|
|
475
|
+
try {
|
|
476
|
+
check();
|
|
477
|
+
}
|
|
478
|
+
catch (error) {
|
|
479
|
+
if (!(error instanceof AdminForbiddenFieldsError))
|
|
480
|
+
throw error;
|
|
481
|
+
for (const [field, messages] of Object.entries(error.fields ?? {}))
|
|
482
|
+
out[`${path}.${field}`] = messages;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
/** The validated DTO, or undefined with its errors put under `path`. */
|
|
486
|
+
async function validated(errors, path, run) {
|
|
487
|
+
try {
|
|
488
|
+
return await run();
|
|
489
|
+
}
|
|
490
|
+
catch (error) {
|
|
491
|
+
if (!(error instanceof AdminValidationError))
|
|
492
|
+
throw error;
|
|
493
|
+
for (const [field, messages] of Object.entries(error.fields ?? {}))
|
|
494
|
+
errors[`${path}.${field}`] = messages;
|
|
495
|
+
return undefined;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
function relationsOf(errors, path, dto, schema) {
|
|
499
|
+
try {
|
|
500
|
+
return relationIdsOf(dto, schema);
|
|
501
|
+
}
|
|
502
|
+
catch (error) {
|
|
503
|
+
if (!(error instanceof AdminValidationError))
|
|
504
|
+
throw error;
|
|
505
|
+
for (const [field, messages] of Object.entries(error.fields ?? {}))
|
|
506
|
+
errors[`${path}.${field}`] = messages;
|
|
507
|
+
return undefined;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* An error of one child row as the save answers it: a client error keeps its status and code, with its fields under
|
|
512
|
+
* the row's path (a message without fields goes on the row itself), so the UI shows it on that row. Database
|
|
513
|
+
* constraint errors are read with the CHILD's names. A host 401 is a 400 (`hostError`). Anything else is left as
|
|
514
|
+
* it is (a 500, logged by the HTTP layer).
|
|
515
|
+
*/
|
|
516
|
+
function atRow(error, path, child, errorMapper) {
|
|
517
|
+
error = hostError(error);
|
|
518
|
+
let status;
|
|
519
|
+
let code;
|
|
520
|
+
let message;
|
|
521
|
+
let fields;
|
|
522
|
+
if (error instanceof AdminError) {
|
|
523
|
+
({ status, code, message, fields } = error);
|
|
524
|
+
}
|
|
525
|
+
else if (error instanceof HttpException && error.getStatus() < 500) {
|
|
526
|
+
status = error.getStatus();
|
|
527
|
+
code = codeForStatus(status);
|
|
528
|
+
message = error.message;
|
|
529
|
+
}
|
|
530
|
+
else if (error instanceof QueryFailedError || errorMapper) {
|
|
531
|
+
const mapped = toErrorResponse(error, '', { error: () => undefined }, { dbNames: child.dbNames, errorMapper, deleting: path.includes('.delete.') });
|
|
532
|
+
if (mapped.status >= 500)
|
|
533
|
+
return error;
|
|
534
|
+
({ status } = mapped);
|
|
535
|
+
({ code, message, fields } = mapped.body);
|
|
536
|
+
}
|
|
537
|
+
else {
|
|
538
|
+
return error;
|
|
539
|
+
}
|
|
540
|
+
if (status >= 500)
|
|
541
|
+
return error;
|
|
542
|
+
const placed = fields && Object.keys(fields).length > 0 ? Object.fromEntries(Object.entries(fields).map(([field, messages]) => [`${path}.${field}`, messages])) : { [path]: [message] };
|
|
543
|
+
return new AdminError(code, status, message, placed);
|
|
544
|
+
}
|
|
545
|
+
//# sourceMappingURL=inline-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inline-writer.js","sourceRoot":"","sources":["../../src/inlines/inline-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -62,6 +62,18 @@ export declare class AdminPolicy implements OnApplicationBootstrap {
|
|
|
62
62
|
private pathLevel;
|
|
63
63
|
/** The schema as this user may see and use it (spec §6.5): anti-oracle allow-lists, forms, permissions. */
|
|
64
64
|
view(entry: RegisteredResource, schema: ResourceSchema, ctx: AdminContext): ResourceView;
|
|
65
|
+
/**
|
|
66
|
+
* Whether the user may see an inline at all (its schema, its rows, its changes): they may view the child resource
|
|
67
|
+
* AND see its link field. Rows listed under a parent reveal their link's value, so a link hidden (or restricted and
|
|
68
|
+
* not granted) makes the inline as absent as a child they cannot view.
|
|
69
|
+
*/
|
|
70
|
+
canSeeInline(child: RegisteredResource, link: string, ctx: AdminContext): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* The layout as this user sees it: sections keep their visible fields; an inline stays only when the user may see it
|
|
73
|
+
* (`canSeeInline`), with the child's fields they may see and its `order` only when they may see that field (the
|
|
74
|
+
* reader then sorts by key too); a tab left without sections by that goes too.
|
|
75
|
+
*/
|
|
76
|
+
private cutLayout;
|
|
65
77
|
/** Writes naming hidden or read-only fields are refused with their names, before anything else (spec §6.5). */
|
|
66
78
|
checkWriteFields(entry: RegisteredResource, body: unknown, allowed: string[], ctx: AdminContext): void;
|
|
67
79
|
/** Whether a query for `operation` needs restricting at all. */
|