@haverstack/core 0.33.0 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/access.d.ts +39 -34
- package/dist/access.d.ts.map +1 -1
- package/dist/access.js +94 -68
- package/dist/access.js.map +1 -1
- package/dist/changes.d.ts +74 -58
- package/dist/changes.d.ts.map +1 -1
- package/dist/changes.js +115 -101
- package/dist/changes.js.map +1 -1
- package/dist/combine.d.ts.map +1 -1
- package/dist/combine.js +7 -0
- package/dist/combine.js.map +1 -1
- package/dist/grants.d.ts +78 -33
- package/dist/grants.d.ts.map +1 -1
- package/dist/grants.js +164 -72
- package/dist/grants.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/query-validation.d.ts +30 -1
- package/dist/query-validation.d.ts.map +1 -1
- package/dist/query-validation.js +128 -2
- package/dist/query-validation.js.map +1 -1
- package/dist/record-changes.d.ts +77 -57
- package/dist/record-changes.d.ts.map +1 -1
- package/dist/record-changes.js +153 -89
- package/dist/record-changes.js.map +1 -1
- package/dist/scoped-stack.d.ts +120 -120
- package/dist/scoped-stack.d.ts.map +1 -1
- package/dist/scoped-stack.js +210 -190
- package/dist/scoped-stack.js.map +1 -1
- package/dist/stack.d.ts +178 -168
- package/dist/stack.d.ts.map +1 -1
- package/dist/stack.js +346 -277
- package/dist/stack.js.map +1 -1
- package/dist/testing.d.ts +16 -5
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +124 -52
- package/dist/testing.js.map +1 -1
- package/dist/types.d.ts +155 -113
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +0 -2
- package/dist/validate.js.map +1 -1
- package/dist/wire-record.d.ts.map +1 -1
- package/dist/wire-record.js.map +1 -1
- package/package.json +1 -1
package/dist/changes.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* to remember. See docs/spec/events.md.
|
|
15
15
|
*/
|
|
16
16
|
import { StackQueryError } from './errors.js';
|
|
17
|
-
import { bumpsVersion } from './record-changes.js';
|
|
17
|
+
import { bumpsVersion, feedAssociationDelta, movesAuthority } from './record-changes.js';
|
|
18
18
|
/** The `baseId@version` split, as grants and query filters read it. */
|
|
19
19
|
const baseIdOf = (typeId) => typeId.split('@')[0];
|
|
20
20
|
/**
|
|
@@ -51,15 +51,10 @@ export function matchesFilter(emitted, filter) {
|
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
53
|
* Whether an emission passes the unlisted-enumeration boundary for one
|
|
54
|
-
* subscription.
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* otherwise failing this very check. Without that exception a subscriber
|
|
59
|
-
* who already knows the record would never be told to drop it. Every other
|
|
60
|
-
* transition (create-unlisted, an edit while already unlisted, a purge of
|
|
61
|
-
* a record that was never listed, the `list` transition itself) needs no
|
|
62
|
-
* special-casing: it falls out of checking the record's current state.
|
|
54
|
+
* subscription. The `unlist` transition is the one exception to the
|
|
55
|
+
* default exclusion: without it a subscriber who already knows the record
|
|
56
|
+
* would never be told to drop it. Every other transition falls out of
|
|
57
|
+
* checking the record's current state.
|
|
63
58
|
* See docs/spec/events.md § The unlisted transition.
|
|
64
59
|
*/
|
|
65
60
|
export function passesUnlistedBoundary(emitted, includeUnlisted) {
|
|
@@ -78,9 +73,7 @@ export function passesUnlistedBoundary(emitted, includeUnlisted) {
|
|
|
78
73
|
* nothing.
|
|
79
74
|
*
|
|
80
75
|
* The record rides by reference, shared across every frame projected from
|
|
81
|
-
* one emission: handlers are contractually read-only over it
|
|
82
|
-
* per subscriber would charge every consumer for a defect none of them
|
|
83
|
-
* have. See docs/spec/events.md § The event shape.
|
|
76
|
+
* one emission: handlers are contractually read-only over it.
|
|
84
77
|
*/
|
|
85
78
|
export function emitted(emission, includeRecords) {
|
|
86
79
|
const { change, record } = emission;
|
|
@@ -108,12 +101,7 @@ export class Subscription {
|
|
|
108
101
|
close() {
|
|
109
102
|
this.closed = true;
|
|
110
103
|
}
|
|
111
|
-
/**
|
|
112
|
-
* Hand a frame to the handler. A handler that throws cannot fail the
|
|
113
|
-
* write it is being told about — the write is already durable — so the
|
|
114
|
-
* error goes to onError, or is rethrown asynchronously so that it
|
|
115
|
-
* surfaces as an unhandled error rather than vanishing.
|
|
116
|
-
*/
|
|
104
|
+
/** Hand a frame to the handler; anything it throws goes to reportError(). */
|
|
117
105
|
deliver(emission) {
|
|
118
106
|
if (this.closed)
|
|
119
107
|
return;
|
|
@@ -129,10 +117,11 @@ export class Subscription {
|
|
|
129
117
|
}
|
|
130
118
|
}
|
|
131
119
|
/**
|
|
132
|
-
* Where a handler's error goes.
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
120
|
+
* Where a handler's error goes. Never into the call stack of the mutation
|
|
121
|
+
* that produced the event — that write is already durable, so a handler
|
|
122
|
+
* cannot fail it. Without an onError the error is rethrown asynchronously,
|
|
123
|
+
* surfacing as an unhandled error rather than vanishing.
|
|
124
|
+
* See docs/spec/events.md § Handlers.
|
|
136
125
|
*/
|
|
137
126
|
function reportError(err, opts) {
|
|
138
127
|
if (opts.onError) {
|
|
@@ -140,8 +129,7 @@ function reportError(err, opts) {
|
|
|
140
129
|
opts.onError(err);
|
|
141
130
|
}
|
|
142
131
|
catch {
|
|
143
|
-
// An onError that throws has nowhere left to report to.
|
|
144
|
-
// better than letting it escape into a mutation's call stack.
|
|
132
|
+
// An onError that throws has nowhere left to report to.
|
|
145
133
|
}
|
|
146
134
|
return;
|
|
147
135
|
}
|
|
@@ -197,83 +185,112 @@ class UnscopedSubscription extends Subscription {
|
|
|
197
185
|
}
|
|
198
186
|
}
|
|
199
187
|
/**
|
|
200
|
-
*
|
|
188
|
+
* One change, held between the two halves it is written in.
|
|
201
189
|
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
* purge also drops `parentId` and the create-time `appId`: the frame says
|
|
211
|
-
* that a record of some type was destroyed, and nothing further about
|
|
212
|
-
* whose it was. See docs/spec/events.md § Purged records carry nothing.
|
|
190
|
+
* A change lands twice: the durable half travels into the adapter's
|
|
191
|
+
* transaction ahead of the write, and the live half is built from the
|
|
192
|
+
* record that write produced. Naming the change once — its ops, its kind,
|
|
193
|
+
* its actor, what it moved — is what makes "the entry set is the event
|
|
194
|
+
* set" true by construction rather than by convention. No verb can journal
|
|
195
|
+
* one thing and announce another, and a verb that writes only one half has
|
|
196
|
+
* to say so where it does it. See docs/spec/journal.md § The entry set is
|
|
197
|
+
* the event set.
|
|
213
198
|
*/
|
|
214
|
-
export
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
199
|
+
export class PendingChange {
|
|
200
|
+
moved;
|
|
201
|
+
ops;
|
|
202
|
+
kind;
|
|
203
|
+
constructor(ops, moved = {}) {
|
|
204
|
+
this.moved = moved;
|
|
205
|
+
const list = Array.isArray(ops) ? ops : [ops];
|
|
206
|
+
if (list.length === 0) {
|
|
207
|
+
throw new Error('PendingChange: a change reports at least one op');
|
|
208
|
+
}
|
|
209
|
+
this.ops = list;
|
|
210
|
+
this.kind = resolveKind(list);
|
|
218
211
|
}
|
|
219
|
-
|
|
220
|
-
|
|
212
|
+
/**
|
|
213
|
+
* The durable half, handed to the adapter as `journal` so that it lands
|
|
214
|
+
* in the same write as the mutation it describes.
|
|
215
|
+
*
|
|
216
|
+
* Absent for a purge, which destroys the log an entry would be appended
|
|
217
|
+
* to. The rule lives here rather than at each call site that would
|
|
218
|
+
* otherwise have to remember it. See docs/spec/journal.md § A hard
|
|
219
|
+
* delete destroys the journal.
|
|
220
|
+
*/
|
|
221
|
+
get journal() {
|
|
222
|
+
if (this.kind === 'purged')
|
|
223
|
+
return undefined;
|
|
224
|
+
const { actor, previousParentId, associations } = this.moved;
|
|
225
|
+
return {
|
|
226
|
+
ops: this.ops,
|
|
227
|
+
kind: this.kind,
|
|
228
|
+
...(actor && { actor }),
|
|
229
|
+
...(previousParentId !== undefined && { previousParentId }),
|
|
230
|
+
...(associations?.length && { associations }),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* The live half, built from the record the write produced — for a purge,
|
|
235
|
+
* from the record as it stood immediately before destruction.
|
|
236
|
+
*
|
|
237
|
+
* The actor is read off the record for every version-bumping op, so it
|
|
238
|
+
* agrees with what was persisted by construction. A no-bump op stamps
|
|
239
|
+
* nothing, so the requester travels here instead — reading the record
|
|
240
|
+
* would report whoever's last version-bumping write this is. A purged
|
|
241
|
+
* frame drops `parentId` and the create-time `appId` too: it says a
|
|
242
|
+
* record of some type was destroyed and nothing about whose it was.
|
|
243
|
+
*/
|
|
244
|
+
emission(record, at) {
|
|
245
|
+
if (this.kind === 'purged') {
|
|
246
|
+
return {
|
|
247
|
+
record,
|
|
248
|
+
change: {
|
|
249
|
+
kind: this.kind,
|
|
250
|
+
ops: this.ops,
|
|
251
|
+
recordId: record.id,
|
|
252
|
+
typeId: record.typeId,
|
|
253
|
+
version: record.version,
|
|
254
|
+
updatedAt: at ?? new Date(),
|
|
255
|
+
...(this.moved.actor && { actor: this.moved.actor }),
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
const actor = bumpsVersion(this.ops) ? actorOf(record, this.kind) : this.moved.actor;
|
|
221
260
|
return {
|
|
222
261
|
record,
|
|
262
|
+
...(this.moved.previousParentId !== undefined && {
|
|
263
|
+
previousParentId: this.moved.previousParentId,
|
|
264
|
+
}),
|
|
223
265
|
change: {
|
|
224
|
-
kind,
|
|
225
|
-
ops:
|
|
266
|
+
kind: this.kind,
|
|
267
|
+
ops: this.ops,
|
|
226
268
|
recordId: record.id,
|
|
227
269
|
typeId: record.typeId,
|
|
228
270
|
version: record.version,
|
|
229
|
-
updatedAt:
|
|
230
|
-
...(
|
|
271
|
+
updatedAt: record.updatedAt,
|
|
272
|
+
...(record.parentId !== undefined && { parentId: record.parentId }),
|
|
273
|
+
...(actor && { actor }),
|
|
274
|
+
...this.associationDeltas(),
|
|
231
275
|
},
|
|
232
276
|
};
|
|
233
277
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
...(actor && { actor }),
|
|
250
|
-
...(opts.associationsAdded?.length && { associationsAdded: opts.associationsAdded }),
|
|
251
|
-
...(opts.associationsRemoved?.length && { associationsRemoved: opts.associationsRemoved }),
|
|
252
|
-
},
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* The durable half of a change, built before the write that it describes
|
|
257
|
-
* — where an emission is built after one. The two carry the same facts
|
|
258
|
-
* about what moved and who moved it; they differ in what they can read
|
|
259
|
-
* off the record, which at this point has not been written yet. So the
|
|
260
|
-
* adapter stamps the record-derived fields and this names the rest.
|
|
261
|
-
* See docs/spec/versioning.md § The change journal.
|
|
262
|
-
*/
|
|
263
|
-
export function buildJournalEntry(ops, opts = {}) {
|
|
264
|
-
const list = Array.isArray(ops) ? ops : [ops];
|
|
265
|
-
if (list.length === 0) {
|
|
266
|
-
throw new Error('buildJournalEntry: a change reports at least one op');
|
|
278
|
+
/**
|
|
279
|
+
* The frame's two flat lists, flattened out of the one the journal
|
|
280
|
+
* takes. Present only where non-empty.
|
|
281
|
+
*
|
|
282
|
+
* The data half alone: the `permissions` op is what announces an ACL
|
|
283
|
+
* move, so a subscriber watching tags is never handed the sharing graph
|
|
284
|
+
* as a side effect of the partition sharing one delta.
|
|
285
|
+
* See docs/spec/events.md § The event shape.
|
|
286
|
+
*/
|
|
287
|
+
associationDeltas() {
|
|
288
|
+
const { added, removed } = feedAssociationDelta((this.moved.associations ?? []).filter((c) => !movesAuthority(c)));
|
|
289
|
+
return {
|
|
290
|
+
...(added.length && { associationsAdded: added }),
|
|
291
|
+
...(removed.length && { associationsRemoved: removed }),
|
|
292
|
+
};
|
|
267
293
|
}
|
|
268
|
-
return {
|
|
269
|
-
ops: list,
|
|
270
|
-
kind: resolveKind(list),
|
|
271
|
-
...(opts.actor && { actor: opts.actor }),
|
|
272
|
-
...(opts.previousParentId !== undefined && { previousParentId: opts.previousParentId }),
|
|
273
|
-
...(opts.associationsAdded?.length && { associationsAdded: opts.associationsAdded }),
|
|
274
|
-
...(opts.associationsRemoved?.length && { associationsRemoved: opts.associationsRemoved }),
|
|
275
|
-
...(opts.associationsReplaced?.length && { associationsReplaced: opts.associationsReplaced }),
|
|
276
|
-
};
|
|
277
294
|
}
|
|
278
295
|
/**
|
|
279
296
|
* The acting identity a stored record reports. `appId` rides along only on
|
|
@@ -322,16 +339,13 @@ export class ChangeEmitter {
|
|
|
322
339
|
this.subscriptions.clear();
|
|
323
340
|
}
|
|
324
341
|
}
|
|
325
|
-
/** The kind each op produces. See docs/spec/events.md § The event shape. */
|
|
326
342
|
/**
|
|
327
343
|
* The kind a set of ops resolves to: the most conservative entry wins.
|
|
328
344
|
* `unlist` beats everything a change set can carry beside it, because a
|
|
329
|
-
* subscriber holding the record still has to drop it — announcing an
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
* transitions that are always emitted alone
|
|
333
|
-
* `changed` unless it unlists.
|
|
334
|
-
* See docs/spec/events.md § The event shape.
|
|
345
|
+
* subscriber holding the record still has to drop it — announcing an edit
|
|
346
|
+
* bundled with an unlist as an upsert would leave a stale copy behind.
|
|
347
|
+
* Nothing else competes: `created` and `purged` name whole-record
|
|
348
|
+
* transitions that are always emitted alone.
|
|
335
349
|
*/
|
|
336
350
|
function resolveKind(ops) {
|
|
337
351
|
if (ops.includes('unlist'))
|
|
@@ -340,6 +354,7 @@ function resolveKind(ops) {
|
|
|
340
354
|
return CHANGE_KINDS[ops[0]];
|
|
341
355
|
return 'changed';
|
|
342
356
|
}
|
|
357
|
+
/** The kind each op produces. See docs/spec/events.md § The event shape. */
|
|
343
358
|
export const CHANGE_KINDS = {
|
|
344
359
|
create: 'created',
|
|
345
360
|
patch: 'changed',
|
|
@@ -369,11 +384,10 @@ const SEQ_FORMAT = /^[A-Za-z0-9_-]+$/;
|
|
|
369
384
|
* caller believe it resumed when it did not, so a stack that cannot honor
|
|
370
385
|
* `since` refuses it rather than ignoring it.
|
|
371
386
|
*
|
|
372
|
-
* Its shape is checked here rather than left to the adapter, so
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
* docs/spec/events.md § Subscribing.
|
|
387
|
+
* Its shape is checked here rather than left to the adapter, so a malformed
|
|
388
|
+
* cursor is the same error whoever is underneath. The value stays opaque:
|
|
389
|
+
* this asks whether it is framable, never what it means.
|
|
390
|
+
* See docs/spec/events.md § Subscribing.
|
|
377
391
|
*/
|
|
378
392
|
export function assertSinceUsable(since, relaysChanges) {
|
|
379
393
|
if (since === undefined)
|
package/dist/changes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changes.js","sourceRoot":"","sources":["../src/changes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAcH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"changes.js","sourceRoot":"","sources":["../src/changes.ts"],"names":[],"mappings":"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"}
|
package/dist/combine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combine.d.ts","sourceRoot":"","sources":["../src/combine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"combine.d.ts","sourceRoot":"","sources":["../src/combine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,gBAAgB,CAAC;CACxB,GAAG,YAAY,CAuEf"}
|
package/dist/combine.js
CHANGED
|
@@ -39,6 +39,13 @@ export function combineAdapters(parts) {
|
|
|
39
39
|
...(parts.record.deleteUnreferencedAttachmentRecords && {
|
|
40
40
|
deleteUnreferencedAttachmentRecords: (fileId, metadataTypeIds) => parts.record.deleteUnreferencedAttachmentRecords(fileId, metadataTypeIds),
|
|
41
41
|
}),
|
|
42
|
+
// Forwarded on the same terms, and it decides more than it looks:
|
|
43
|
+
// Stack.relaysChanges reads its presence, so dropping it here would
|
|
44
|
+
// leave a combined stack quietly emitting only its own writes while a
|
|
45
|
+
// remote record backend's feed went unread.
|
|
46
|
+
...(parts.record.subscribeChanges && {
|
|
47
|
+
subscribeChanges: (opts, handler) => parts.record.subscribeChanges(opts, handler),
|
|
48
|
+
}),
|
|
42
49
|
// StackAdapter.putAttachmentWithMetadata is deliberately never
|
|
43
50
|
// synthesized here: glued backends have no shared transaction to honor
|
|
44
51
|
// its atomicity promise (docs/spec/adapters.md § Interface split).
|
package/dist/combine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combine.js","sourceRoot":"","sources":["../src/combine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"combine.js","sourceRoot":"","sources":["../src/combine.ts"],"names":[],"mappings":"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"}
|
package/dist/grants.d.ts
CHANGED
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
* See docs/spec/access-control.md § Type-level grants.
|
|
10
10
|
*/
|
|
11
11
|
import type { GroupRole } from './access.js';
|
|
12
|
-
import type { EntityId, GrantAction, GrantContent, QueryResult, RecordId, StackQuery, StackRecord } from './types.js';
|
|
12
|
+
import type { EntityId, GrantAction, GrantContent, GrantGrantee, QueryResult, RecordId, StackQuery, StackRecord, TypeId } from './types.js';
|
|
13
|
+
import type { ValidationError } from './validate.js';
|
|
13
14
|
/**
|
|
14
|
-
* Valid GrantAction values, for runtime validation in Stack.grant().
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* Valid GrantAction values, for runtime validation in Stack.grant(). Built
|
|
16
|
+
* from GRANT_ACTIONS, which GrantAction itself derives from, so the set and
|
|
17
|
+
* the type cannot drift.
|
|
17
18
|
*/
|
|
18
19
|
export declare const GRANT_ACTION_SET: ReadonlySet<GrantAction>;
|
|
19
20
|
/**
|
|
@@ -27,37 +28,79 @@ export declare const GRANT_ACTION_SET: ReadonlySet<GrantAction>;
|
|
|
27
28
|
export declare const READ_COMPANIONS: ReadonlyMap<GrantAction, readonly GrantAction[]>;
|
|
28
29
|
/**
|
|
29
30
|
* Whether one grant's action list conveys `action`. The companion has to
|
|
30
|
-
* sit in the same `_grant` Record
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
31
|
+
* sit in the same `_grant` Record: a grant is revoked whole, so a rule
|
|
32
|
+
* satisfied across two records would let revoking the read one leave a
|
|
33
|
+
* mutate-without-read grant standing.
|
|
34
|
+
*
|
|
35
|
+
* Takes the list grantReach() produced, never a stored field: `includes()`
|
|
36
|
+
* over a string is substring matching, so one would answer for every verb
|
|
37
|
+
* spelled inside it.
|
|
35
38
|
*/
|
|
36
|
-
export declare function grantConveys(actions: readonly
|
|
39
|
+
export declare function grantConveys(actions: readonly GrantAction[], action: GrantAction): boolean;
|
|
37
40
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
41
|
+
* What a stored `_grant` reaches, or null where it names nothing the
|
|
42
|
+
* evaluator recognizes. Read as data, like the grantee beside it: a grant
|
|
43
|
+
* Record can arrive from an import, a direct adapter write or a foreign
|
|
44
|
+
* server, where no schema saw it, so both fields are asked for their shape
|
|
45
|
+
* rather than taken from the type. An unknown action is dropped from the
|
|
46
|
+
* list, on the same terms an unknown grantee `kind` confers nothing.
|
|
47
|
+
* See docs/spec/access-control.md § Refused at the write, and again at evaluation.
|
|
42
48
|
*/
|
|
43
|
-
export
|
|
44
|
-
|
|
49
|
+
export declare function grantReach(content: unknown): {
|
|
50
|
+
familyId: string;
|
|
51
|
+
actions: GrantAction[];
|
|
45
52
|
} | null;
|
|
46
|
-
/** Direct (non-roster) match between a stored _grant's content and a GrantTarget. */
|
|
47
|
-
export declare function matchesGrantTarget(content: GrantContent, target: GrantTarget): boolean;
|
|
48
53
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
54
|
+
* Who a grant() / revoke() / listGrants() call targets — the same union a
|
|
55
|
+
* stored grant carries, so a target is the grantee it writes.
|
|
56
|
+
* `{ kind: 'authenticated' }` is the default grant, and the default-only
|
|
57
|
+
* listing.
|
|
58
|
+
*/
|
|
59
|
+
export type GrantTarget = GrantGrantee;
|
|
60
|
+
/**
|
|
61
|
+
* What listGrants() accepts: a GrantTarget, widened so a group listing can
|
|
62
|
+
* ask for every role at once. `role: 'any'` is not a role an entity can
|
|
63
|
+
* hold and never reaches storage — a query can say it, a grantee cannot.
|
|
64
|
+
*/
|
|
65
|
+
export type GrantQuery = {
|
|
66
|
+
kind: 'entity';
|
|
67
|
+
entityId: EntityId;
|
|
68
|
+
} | {
|
|
69
|
+
kind: 'group';
|
|
70
|
+
groupId: RecordId;
|
|
71
|
+
role: 'member' | 'admin' | 'any';
|
|
72
|
+
} | {
|
|
73
|
+
kind: 'authenticated';
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Direct (non-roster) match between a stored _grant's content and a target:
|
|
77
|
+
* the whole grantee, `role` included. A target is the identity grant()
|
|
78
|
+
* wrote, so a revoke aimed at a group's admins leaves the members' grant
|
|
79
|
+
* standing. A query's `role: 'any'` is the one widening, and it is spelled.
|
|
53
80
|
*/
|
|
54
|
-
export declare function
|
|
81
|
+
export declare function matchesGrantTarget(content: GrantContent, target: GrantQuery): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Reject a grant target that names no tier, or whose tier names nobody. An
|
|
84
|
+
* empty groupId or entityId reaches no one, so storing it would leave a
|
|
85
|
+
* grant that can only ever deny while looking like a share that worked.
|
|
86
|
+
* Read as data, not as the type: a target reaching Stack from a request
|
|
87
|
+
* body or an import has whatever shape it arrived with. `allowAny` admits
|
|
88
|
+
* the listing-only `role: 'any'`, which grant() and revoke() refuse.
|
|
89
|
+
*/
|
|
90
|
+
export declare function validateGrantTarget(target: GrantQuery, allowAny?: boolean): void;
|
|
91
|
+
/**
|
|
92
|
+
* The fields each grantee arm must carry, asked of a `_grant`'s content on
|
|
93
|
+
* every write. The schema cannot ask it — a closed `object` field holds one
|
|
94
|
+
* `properties` set, so only `kind` is required there — and an arm missing
|
|
95
|
+
* its own field would otherwise store, answer 200, then deny forever.
|
|
96
|
+
*/
|
|
97
|
+
export declare function validateGrantee(typeId: TypeId, content: unknown): ValidationError[];
|
|
55
98
|
/**
|
|
56
99
|
* Whether a stored _grant covers `grantee`: a direct DID match, roster
|
|
57
|
-
* membership when `allowGroup`, or
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
100
|
+
* membership when `allowGroup`, or the authenticated tier when
|
|
101
|
+
* `allowDefault`. The grantee's own `kind` decides which question is asked
|
|
102
|
+
* — every tier is affirmative, and none is reachable by omission, so a
|
|
103
|
+
* grant carrying nothing recognizable confers nothing.
|
|
61
104
|
*/
|
|
62
105
|
export declare function grantCoversGrantee(c: GrantContent, grantee: EntityId, opts: {
|
|
63
106
|
allowDefault: boolean;
|
|
@@ -68,17 +111,19 @@ export declare function grantCoversGrantee(c: GrantContent, grantee: EntityId, o
|
|
|
68
111
|
/**
|
|
69
112
|
* System type families grant() refuses to target: a grant on any of them
|
|
70
113
|
* would let the grantee mint their own grants, touch stack config, or
|
|
71
|
-
* register an app card claiming a DID that isn't theirs — the last of
|
|
72
|
-
*
|
|
73
|
-
* docs/spec/access-control.md § Type-level grants.
|
|
114
|
+
* register an app card claiming a DID that isn't theirs — the last of which
|
|
115
|
+
* is what verified app attribution rests on.
|
|
74
116
|
*/
|
|
75
117
|
export declare const UNGRANTABLE_SYSTEM_TYPES: ReadonlySet<string>;
|
|
76
118
|
/**
|
|
77
119
|
* Every `_grant` Record, cursor-walked. Read through an unscoped query at
|
|
78
120
|
* every call site: a grant is what decides who may read, so it can never
|
|
79
|
-
* itself sit behind a read check.
|
|
80
|
-
*
|
|
81
|
-
*
|
|
121
|
+
* itself sit behind a read check.
|
|
122
|
+
*
|
|
123
|
+
* `includeUnlisted`, because withholding a Record from enumeration decides
|
|
124
|
+
* nothing about what it confers. Deleted grants are excluded on the
|
|
125
|
+
* opposite grounds — a soft delete is how revoke() withdraws one.
|
|
126
|
+
* See docs/spec/unlisted.md.
|
|
82
127
|
*/
|
|
83
128
|
export declare function loadGrantRecords(query: (q: StackQuery) => Promise<QueryResult>): Promise<StackRecord[]>;
|
|
84
129
|
//# sourceMappingURL=grants.d.ts.map
|
package/dist/grants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grants.d.ts","sourceRoot":"","sources":["../src/grants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,UAAU,EACV,WAAW,
|
|
1
|
+
{"version":3,"file":"grants.d.ts","sourceRoot":"","sources":["../src/grants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,UAAU,EACV,WAAW,EACX,MAAM,EACP,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,WAAW,CAA0B,CAAC;AAEjF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,WAAW,EAAE,SAAS,WAAW,EAAE,CAK3E,CAAC;AAEH;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAI1F;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,EAAE,CAAA;CAAE,GAAG,IAAI,CAShG;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC;AAEvC;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC;AAE9B;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CASrF;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,UAAQ,GAAG,IAAI,CA6B9E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe,EAAE,CA0CnF;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,CAAC,EAAE,YAAY,EACf,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE;IACJ,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC;IAC1C,aAAa,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC9D,GACA,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAwBD;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,CAIvD,CAAC;AAEH;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,CAAC,GAC7C,OAAO,CAAC,WAAW,EAAE,CAAC,CAIxB"}
|