@adminiumjs/adminium 0.3.29 → 0.3.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assistant/actions.js +13 -9
- package/dist/assistant/actions.js.map +1 -1
- package/dist/automations/actions/record-write.d.ts.map +1 -1
- package/dist/automations/actions/record-write.js +18 -2
- package/dist/automations/actions/record-write.js.map +1 -1
- package/dist/compose.d.ts.map +1 -1
- package/dist/compose.js +42 -9
- package/dist/compose.js.map +1 -1
- package/dist/connections/column-rules-validation.d.ts.map +1 -1
- package/dist/connections/column-rules-validation.js +4 -0
- package/dist/connections/column-rules-validation.js.map +1 -1
- package/dist/connections/effective-schema.d.ts +4 -0
- package/dist/connections/effective-schema.d.ts.map +1 -1
- package/dist/connections/effective-schema.js +1 -0
- package/dist/connections/effective-schema.js.map +1 -1
- package/dist/crud/row-writes.d.ts.map +1 -1
- package/dist/crud/row-writes.js +30 -2
- package/dist/crud/row-writes.js.map +1 -1
- package/dist/crud/states.d.ts +2 -0
- package/dist/crud/states.d.ts.map +1 -1
- package/dist/crud/states.js +42 -2
- package/dist/crud/states.js.map +1 -1
- package/dist/crud/unbuilt-rules.d.ts.map +1 -1
- package/dist/crud/unbuilt-rules.js +2 -0
- package/dist/crud/unbuilt-rules.js.map +1 -1
- package/dist/crud/write-service.d.ts.map +1 -1
- package/dist/crud/write-service.js +64 -4
- package/dist/crud/write-service.js.map +1 -1
- package/dist/crud/write-tree.d.ts +3 -0
- package/dist/crud/write-tree.d.ts.map +1 -1
- package/dist/crud/write-tree.js.map +1 -1
- package/dist/email/file-reach.d.ts +16 -6
- package/dist/email/file-reach.d.ts.map +1 -1
- package/dist/email/file-reach.js +17 -8
- package/dist/email/file-reach.js.map +1 -1
- package/dist/files/named-uploads.d.ts +35 -0
- package/dist/files/named-uploads.d.ts.map +1 -0
- package/dist/files/named-uploads.js +72 -0
- package/dist/files/named-uploads.js.map +1 -0
- package/dist/files/reconcile.d.ts +2 -0
- package/dist/files/reconcile.d.ts.map +1 -1
- package/dist/files/reconcile.js +15 -5
- package/dist/files/reconcile.js.map +1 -1
- package/dist/project/code/db.d.ts.map +1 -1
- package/dist/project/code/db.js +4 -2
- package/dist/project/code/db.js.map +1 -1
- package/dist/routes/data/index.d.ts.map +1 -1
- package/dist/routes/data/index.js +90 -11
- package/dist/routes/data/index.js.map +1 -1
- package/dist/routes/data/refusal-scrub.d.ts +8 -0
- package/dist/routes/data/refusal-scrub.d.ts.map +1 -1
- package/dist/routes/data/refusal-scrub.js +14 -0
- package/dist/routes/data/refusal-scrub.js.map +1 -1
- package/dist/routes/email-templates/index.d.ts.map +1 -1
- package/dist/routes/email-templates/index.js +5 -1
- package/dist/routes/email-templates/index.js.map +1 -1
- package/dist/routes/files/index.d.ts.map +1 -1
- package/dist/routes/files/index.js +5 -2
- package/dist/routes/files/index.js.map +1 -1
- package/dist/routes/public/index.d.ts.map +1 -1
- package/dist/routes/public/index.js +21 -5
- package/dist/routes/public/index.js.map +1 -1
- package/node_modules/@adminium/adapter-mysql/package.json +1 -1
- package/node_modules/@adminium/adapter-postgres/package.json +1 -1
- package/node_modules/@adminium/adapter-sqlite/package.json +1 -1
- package/node_modules/@adminium/add-on-contracts/package.json +1 -1
- package/node_modules/@adminium/engine/package.json +1 -1
- package/node_modules/@adminium/i18n/package.json +1 -1
- package/node_modules/@adminium/llm/package.json +1 -1
- package/node_modules/@adminium/manifest/dist/roles.d.ts +3 -0
- package/node_modules/@adminium/manifest/dist/roles.d.ts.map +1 -1
- package/node_modules/@adminium/manifest/dist/roles.js +5 -0
- package/node_modules/@adminium/manifest/dist/roles.js.map +1 -1
- package/node_modules/@adminium/manifest/dist/schema.d.ts +8 -0
- package/node_modules/@adminium/manifest/dist/schema.d.ts.map +1 -1
- package/node_modules/@adminium/manifest/dist/schema.js +1 -0
- package/node_modules/@adminium/manifest/dist/schema.js.map +1 -1
- package/node_modules/@adminium/manifest/dist/shapes.js +4 -0
- package/node_modules/@adminium/manifest/dist/shapes.js.map +1 -1
- package/node_modules/@adminium/manifest/dist/states.d.ts +8 -1
- package/node_modules/@adminium/manifest/dist/states.d.ts.map +1 -1
- package/node_modules/@adminium/manifest/dist/states.js +40 -3
- package/node_modules/@adminium/manifest/dist/states.js.map +1 -1
- package/node_modules/@adminium/manifest/dist/words.d.ts +1 -1
- package/node_modules/@adminium/manifest/dist/words.d.ts.map +1 -1
- package/node_modules/@adminium/manifest/dist/words.js +7 -0
- package/node_modules/@adminium/manifest/dist/words.js.map +1 -1
- package/node_modules/@adminium/manifest/package.json +1 -1
- package/node_modules/@adminium/meta/dist/repos/files.d.ts +23 -3
- package/node_modules/@adminium/meta/dist/repos/files.d.ts.map +1 -1
- package/node_modules/@adminium/meta/dist/repos/files.js +63 -15
- package/node_modules/@adminium/meta/dist/repos/files.js.map +1 -1
- package/node_modules/@adminium/meta/dist/schema/json-payloads.d.ts +1 -0
- package/node_modules/@adminium/meta/dist/schema/json-payloads.d.ts.map +1 -1
- package/node_modules/@adminium/meta/dist/schema/json-payloads.js +2 -0
- package/node_modules/@adminium/meta/dist/schema/json-payloads.js.map +1 -1
- package/node_modules/@adminium/meta/package.json +1 -1
- package/node_modules/@adminium/schema-import/package.json +1 -1
- package/node_modules/@adminium/widgets/package.json +1 -1
- package/package.json +12 -12
- package/skills/adminium-app/references/manifest/INDEX.md +3 -3
- package/skills/adminium-app/references/manifest/requiredschema--states-3.md +15 -7
- package/skills/adminium-app/references/manifest/requiredschema--states-4.md +43 -0
- package/skills/adminium-app/references/manifest/requiredschema--states.md +1 -0
|
@@ -63,7 +63,8 @@ import { recipientLocale } from '../../i18n/server-i18n.js';
|
|
|
63
63
|
import { TreeCheckRefused } from '../../public-api/tree-checks.js';
|
|
64
64
|
import { staffTreeRules } from './tree.js';
|
|
65
65
|
import { declaredColumns, expectColumnOf, priceCheck, staffRetryKey } from './staff-quote.js';
|
|
66
|
-
import { scrubRefusal } from './refusal-scrub.js';
|
|
66
|
+
import { scrubRefusal, scrubUnreadRefusal } from './refusal-scrub.js';
|
|
67
|
+
import { refusalTableOf } from '../../crud/refusal-table.js';
|
|
67
68
|
import { clientKeySecret } from '../public/tree.js';
|
|
68
69
|
/**
|
|
69
70
|
* How many links one record's field reads and replaces.
|
|
@@ -301,6 +302,24 @@ export function dataRoutes(deps) {
|
|
|
301
302
|
Object.defineProperty(error, 'message', { value: scrubbed.message, configurable: true, writable: true });
|
|
302
303
|
}
|
|
303
304
|
});
|
|
305
|
+
/*
|
|
306
|
+
* A refusal about another row than the one written (an effect's row, the
|
|
307
|
+
* parent a new child moves) told to somebody who may not read that row's
|
|
308
|
+
* table: it names nothing of the row — its state, what its move waits for.
|
|
309
|
+
*/
|
|
310
|
+
app.addHook('onError', async (request, _reply, error) => {
|
|
311
|
+
if (!(error instanceof AppError))
|
|
312
|
+
return;
|
|
313
|
+
const about = refusalTableOf(error);
|
|
314
|
+
const connectionId = request.params?.connectionId;
|
|
315
|
+
if (about === undefined || typeof connectionId !== 'string')
|
|
316
|
+
return;
|
|
317
|
+
if (await request.can(`table:${connectionId}:${about}:read`))
|
|
318
|
+
return;
|
|
319
|
+
const scrubbed = scrubUnreadRefusal(error);
|
|
320
|
+
Object.defineProperty(error, 'details', { value: scrubbed.details, configurable: true });
|
|
321
|
+
Object.defineProperty(error, 'message', { value: scrubbed.message, configurable: true, writable: true });
|
|
322
|
+
});
|
|
304
323
|
/*
|
|
305
324
|
* A REQUEST OF SOMEBODY WHO REACHES ONLY SOME ROWS (`crud/row-limit.ts`).
|
|
306
325
|
*
|
|
@@ -817,6 +836,8 @@ export function dataRoutes(deps) {
|
|
|
817
836
|
})();
|
|
818
837
|
undo.added.push(keyOf(written));
|
|
819
838
|
(undo.addedRows ??= []).push(written);
|
|
839
|
+
// The parent outside this record a new child moved (`moveOnCreate`).
|
|
840
|
+
options.effects?.push(...effectsOf(prepared.values));
|
|
820
841
|
settled.push({ action: 'create', record: written, before: null });
|
|
821
842
|
options.events?.push({ table: child.child, action: 'create', pk: keyOf(written), row: written });
|
|
822
843
|
}
|
|
@@ -1544,6 +1565,28 @@ export function dataRoutes(deps) {
|
|
|
1544
1565
|
if (entry.fileIds.length > 0 && deps.files !== undefined) {
|
|
1545
1566
|
await deps.files.restoreAll(entry.fileIds);
|
|
1546
1567
|
}
|
|
1568
|
+
/*
|
|
1569
|
+
* A change taken back puts its files back too: a file of the record's
|
|
1570
|
+
* it names again comes out of the bin the change put it in, and one it
|
|
1571
|
+
* names no more goes there, as a replaced one does. A new row taken
|
|
1572
|
+
* back takes its files with it, as a deleted one does.
|
|
1573
|
+
*/
|
|
1574
|
+
if (deps.files !== undefined && entry.action !== 'delete') {
|
|
1575
|
+
for (const row of changed) {
|
|
1576
|
+
const entity = { connectionId: entry.connectionId, table: table.id, pk: row.pk, label: pkLabel(table, row.pk) };
|
|
1577
|
+
if (entry.action === 'create') {
|
|
1578
|
+
if (row.record !== null)
|
|
1579
|
+
await trashRecordFiles(undone, entity, row.record);
|
|
1580
|
+
continue;
|
|
1581
|
+
}
|
|
1582
|
+
if (row.before === null)
|
|
1583
|
+
continue;
|
|
1584
|
+
const after = await fetchByPk(db, table, row.pk);
|
|
1585
|
+
if (after === undefined)
|
|
1586
|
+
continue;
|
|
1587
|
+
await deps.files.reconcile({ connectionId: entry.connectionId, table: table.id, entity, before: row.before, after, ruled: ruledBlocksOf(table.columns.values()), restoring: true });
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1547
1590
|
await app.rbac.audit(request, {
|
|
1548
1591
|
category: 'data',
|
|
1549
1592
|
action: 'record.undo',
|
|
@@ -1900,10 +1943,12 @@ export function dataRoutes(deps) {
|
|
|
1900
1943
|
context,
|
|
1901
1944
|
recheck: (final) => assertFileColumns(ctx, final),
|
|
1902
1945
|
mapError: (error) => mapDbError(error, ctx.table),
|
|
1903
|
-
announce: async (row,
|
|
1946
|
+
announce: async (row, written, posted) => {
|
|
1904
1947
|
told = postingAnswers(posted);
|
|
1905
1948
|
await afterMutation(request, ctx, 'create', recordRef(ctx, Object.fromEntries(ctx.table.primaryKey.map((c) => [c, row[c]]))), null, row);
|
|
1906
1949
|
await tellPostings(app, { connectionId: ctx.connectionId, view: ctx.view, postings: posted, origin: 'dashboard', request });
|
|
1950
|
+
// The parent a new row moved (`moveOnCreate`).
|
|
1951
|
+
await announceEffects(app, { connectionId: ctx.connectionId, view: ctx.view, effects: effectsOf(written), origin: 'bulk', request });
|
|
1907
1952
|
},
|
|
1908
1953
|
});
|
|
1909
1954
|
const key = ctx.table.primaryKey.length === 1 ? inserted[ctx.table.primaryKey[0]] : Object.fromEntries(ctx.table.primaryKey.map((c) => [c, inserted[c]]));
|
|
@@ -2118,9 +2163,24 @@ export function dataRoutes(deps) {
|
|
|
2118
2163
|
}
|
|
2119
2164
|
});
|
|
2120
2165
|
const okCount = results.filter((r) => r.ok).length;
|
|
2166
|
+
/*
|
|
2167
|
+
* Each row's files, as a row's own write moves them: a deleted row's go
|
|
2168
|
+
* to the bin (and come back with its undo), a changed row holds what it
|
|
2169
|
+
* names now and lets go of what it named.
|
|
2170
|
+
*/
|
|
2171
|
+
const trashedFileIds = [];
|
|
2172
|
+
if (deps.files !== undefined) {
|
|
2173
|
+
for (const event of events) {
|
|
2174
|
+
const entity = recordRef(ctx, event.pk);
|
|
2175
|
+
if (action === 'delete')
|
|
2176
|
+
trashedFileIds.push(...(await trashRecordFiles(ctx, entity, event.before)));
|
|
2177
|
+
else
|
|
2178
|
+
await deps.files.reconcile({ connectionId: ctx.connectionId, table: ctx.table.id, entity, before: event.before, after: event.after, ruled: ruledBlocksOf(ctx.table.columns.values()) });
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2121
2181
|
const undoToken = okCount === 0
|
|
2122
2182
|
? null
|
|
2123
|
-
: await issueUndo(request, ctx, action, beforeImages, afterImages, action === 'update' && values !== null ? changedColumns(values, readied) : [],
|
|
2183
|
+
: await issueUndo(request, ctx, action, beforeImages, afterImages, action === 'update' && values !== null ? changedColumns(values, readied) : [], trashedFileIds, [], [], effected);
|
|
2124
2184
|
await app.rbac.audit(request, {
|
|
2125
2185
|
category: 'data',
|
|
2126
2186
|
action: `record.bulk-${action}`,
|
|
@@ -2810,13 +2870,17 @@ export function dataRoutes(deps) {
|
|
|
2810
2870
|
}
|
|
2811
2871
|
return written;
|
|
2812
2872
|
});
|
|
2873
|
+
// The parents the new rows moved (`moveOnCreate`): such a save offers no Undo.
|
|
2874
|
+
const moved = prepared.flatMap((row) => effectsOf(row.values));
|
|
2813
2875
|
// One token over every row: the create-undo path already deletes
|
|
2814
2876
|
// each `after` it holds, in order.
|
|
2815
|
-
|
|
2877
|
+
if (moved.length === 0)
|
|
2878
|
+
undoToken = await issueUndo(request, ctx, 'create', [], rows);
|
|
2816
2879
|
for (const row of rows) {
|
|
2817
2880
|
const pk = Object.fromEntries(ctx.table.primaryKey.map((c) => [c, row[c]]));
|
|
2818
2881
|
await afterMutation(request, ctx, 'create', recordRef(ctx, pk), null, row);
|
|
2819
2882
|
}
|
|
2883
|
+
await announceEffects(app, { connectionId: ctx.connectionId, view: ctx.view, effects: moved, origin: 'dashboard', request });
|
|
2820
2884
|
await writes.afterEach('create', ctx.target, context, rows.map((record) => ({ record, before: null })));
|
|
2821
2885
|
// The reply is the row as stored, its own totals settled after the commit.
|
|
2822
2886
|
const [first] = (await writes.stored(ctx.target, rows.slice(0, 1)));
|
|
@@ -2838,10 +2902,12 @@ export function dataRoutes(deps) {
|
|
|
2838
2902
|
if (tree.outcome.replayed)
|
|
2839
2903
|
return reply.status(200).send({ data: staffRow(ctx.dialect, created, ctx.readTable, ctx.unmasked), undoToken: null, replayed: true });
|
|
2840
2904
|
const told = postingAnswers(tree.outcome.postings);
|
|
2841
|
-
// A save that posted is not undone by a token: the rule's own way back is.
|
|
2842
|
-
if (told === undefined && !pricedBy(tree.outcome.adjusted))
|
|
2905
|
+
// A save that posted is not undone by a token: the rule's own way back is. Nor one that moved its parent.
|
|
2906
|
+
if (told === undefined && !pricedBy(tree.outcome.adjusted) && tree.outcome.effects === undefined)
|
|
2843
2907
|
undoToken = await issueUndo(request, ctx, 'create', [], [created], [], [], [], []);
|
|
2844
2908
|
await tellPostings(app, { connectionId: ctx.connectionId, view: ctx.view, postings: tree.outcome.postings, origin: 'dashboard', request });
|
|
2909
|
+
// The parent the new row moved (`moveOnCreate`): announced as a change of its own, after the row's.
|
|
2910
|
+
await announceEffects(app, { connectionId: ctx.connectionId, view: ctx.view, effects: tree.outcome.effects, origin: 'dashboard', request });
|
|
2845
2911
|
const once = onceFor(ctx.connectionId, request.user?.id ?? null, tree.outcome.rows.map((made) => ({ table: made.node.target.table, row: made.record })));
|
|
2846
2912
|
return reply.status(201).send({ data: staffRow(ctx.dialect, created, ctx.readTable, ctx.unmasked), undoToken, ...(told === undefined ? {} : { postings: told }), ...(once === undefined ? {} : { once }), ...(await pricedAs(request, ctx, tree.outcome.adjusted, tree.outcome.rows)), ...(await paidAs(request, ctx, treeRows(tree.outcome), tree.outcome.postings)) });
|
|
2847
2913
|
}
|
|
@@ -2855,16 +2921,19 @@ export function dataRoutes(deps) {
|
|
|
2855
2921
|
context,
|
|
2856
2922
|
recheck: (final) => assertFileColumns(ctx, final),
|
|
2857
2923
|
mapError: (error) => mapDbError(error, ctx.table),
|
|
2858
|
-
announce: async (row,
|
|
2924
|
+
announce: async (row, written, posted, adjusted) => {
|
|
2859
2925
|
const pk = Object.fromEntries(ctx.table.primaryKey.map((c) => [c, row[c]]));
|
|
2860
2926
|
told = postingAnswers(posted);
|
|
2861
2927
|
asked = adjusted;
|
|
2862
2928
|
outcomes = posted;
|
|
2863
|
-
//
|
|
2864
|
-
|
|
2929
|
+
// The parent the new row moved (`moveOnCreate`): announced as a change of its own, after the row's.
|
|
2930
|
+
const moved = effectsOf(written);
|
|
2931
|
+
// A save that moved an order's price has no Undo: its way back is another save, priced in its turn. Nor one that moved its parent.
|
|
2932
|
+
if (told === undefined && !pricedBy(adjusted) && moved.length === 0)
|
|
2865
2933
|
undoToken = await issueUndo(request, ctx, 'create', [], [row]);
|
|
2866
2934
|
await afterMutation(request, ctx, 'create', recordRef(ctx, pk), null, row);
|
|
2867
2935
|
await tellPostings(app, { connectionId: ctx.connectionId, view: ctx.view, postings: posted, origin: 'dashboard', request });
|
|
2936
|
+
await announceEffects(app, { connectionId: ctx.connectionId, view: ctx.view, effects: moved, origin: 'dashboard', request });
|
|
2868
2937
|
},
|
|
2869
2938
|
});
|
|
2870
2939
|
const once = onceFor(ctx.connectionId, request.user?.id ?? null, [{ table: ctx.table, row: inserted }]);
|
|
@@ -2893,9 +2962,10 @@ export function dataRoutes(deps) {
|
|
|
2893
2962
|
return reply.status(200).send({ data: staffRow(ctx.dialect, created, ctx.readTable, ctx.unmasked), undoToken: null, replayed: true });
|
|
2894
2963
|
const pk = Object.fromEntries(ctx.table.primaryKey.map((c) => [c, created[c]]));
|
|
2895
2964
|
const told = postingAnswers(tree.outcome.postings);
|
|
2896
|
-
if (told === undefined && !pricedBy(tree.outcome.adjusted))
|
|
2965
|
+
if (told === undefined && !pricedBy(tree.outcome.adjusted) && tree.outcome.effects === undefined)
|
|
2897
2966
|
undoToken = await issueUndo(request, ctx, 'create', [], [created], [], [], tree.links, tree.children);
|
|
2898
2967
|
await tellPostings(app, { connectionId: ctx.connectionId, view: ctx.view, postings: tree.outcome.postings, origin: 'dashboard', request });
|
|
2968
|
+
await announceEffects(app, { connectionId: ctx.connectionId, view: ctx.view, effects: tree.outcome.effects, origin: 'dashboard', request });
|
|
2899
2969
|
for (const event of tree.events)
|
|
2900
2970
|
publishChildWrite(app, { connectionId: ctx.connectionId, ...event });
|
|
2901
2971
|
await tellChildMentions(request, ctx, tree.events);
|
|
@@ -2957,6 +3027,8 @@ export function dataRoutes(deps) {
|
|
|
2957
3027
|
const written = [];
|
|
2958
3028
|
const childWrites = [];
|
|
2959
3029
|
const childEvents = [];
|
|
3030
|
+
/** The parents the new rows moved (`moveOnCreate`): the record's own, and its children's. */
|
|
3031
|
+
const childEffects = [];
|
|
2960
3032
|
const numbered = children.map((requested) => ({ target: childTargetOf(ctx, requested.child, ctx.db), row: {} }));
|
|
2961
3033
|
const agrees = await recordAgrees(ctx);
|
|
2962
3034
|
let inserted = await writes.transaction(ctx.target, [prepared.values], async (trx) => {
|
|
@@ -2980,6 +3052,7 @@ export function dataRoutes(deps) {
|
|
|
2980
3052
|
childWrites.push(await applyChildren(ctx, tdb, requested, row[requested.child.parentKeyColumn], context, {
|
|
2981
3053
|
existing: [],
|
|
2982
3054
|
events: childEvents,
|
|
3055
|
+
effects: childEffects,
|
|
2983
3056
|
}));
|
|
2984
3057
|
}
|
|
2985
3058
|
// The record as its children left it: a total over them has moved,
|
|
@@ -2997,8 +3070,12 @@ export function dataRoutes(deps) {
|
|
|
2997
3070
|
return made;
|
|
2998
3071
|
}, numbered);
|
|
2999
3072
|
const pk = Object.fromEntries(ctx.table.primaryKey.map((c) => [c, inserted[c]]));
|
|
3000
|
-
|
|
3073
|
+
const moved = [...effectsOf(prepared.values), ...childEffects];
|
|
3074
|
+
// A save that moved a parent offers no Undo: taking the row back would leave the parent moved.
|
|
3075
|
+
if (moved.length === 0)
|
|
3076
|
+
undoToken = await issueUndo(request, ctx, 'create', [], [inserted], [], [], written, childWrites);
|
|
3001
3077
|
await afterMutation(request, ctx, 'create', recordRef(ctx, pk), null, inserted);
|
|
3078
|
+
await announceEffects(app, { connectionId: ctx.connectionId, view: ctx.view, effects: moved, origin: 'dashboard', request });
|
|
3002
3079
|
for (const event of childEvents)
|
|
3003
3080
|
publishChildWrite(app, { connectionId: ctx.connectionId, ...event });
|
|
3004
3081
|
await tellChildMentions(request, ctx, childEvents);
|
|
@@ -3452,6 +3529,8 @@ export function dataRoutes(deps) {
|
|
|
3452
3529
|
context,
|
|
3453
3530
|
mapError: (error) => mapDbError(error, ctx.table),
|
|
3454
3531
|
...withinReach(ctx, 'delete'),
|
|
3532
|
+
// A DELETE that matched nothing (somebody else's landed first) announces nothing: no file to the bin, no Undo.
|
|
3533
|
+
skipIfNone: true,
|
|
3455
3534
|
announce: async (_count, _before, adjusted) => {
|
|
3456
3535
|
asked = adjusted;
|
|
3457
3536
|
const entity = recordRef(ctx, pk);
|