@nxgt/janus 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +102 -17
  2. package/dist/auth/email-flows/prove-first.d.ts +23 -1
  3. package/dist/auth/email-flows/prove-first.d.ts.map +1 -1
  4. package/dist/auth/index.d.ts +1 -1
  5. package/dist/auth/index.d.ts.map +1 -1
  6. package/dist/auth/outage.d.ts +15 -4
  7. package/dist/auth/outage.d.ts.map +1 -1
  8. package/dist/auth/types/email-flows.d.ts +13 -2
  9. package/dist/auth/types/email-flows.d.ts.map +1 -1
  10. package/dist/auth/types/find-or-create.d.ts +59 -0
  11. package/dist/auth/types/find-or-create.d.ts.map +1 -0
  12. package/dist/auth/types/index.d.ts +1 -0
  13. package/dist/auth/types/index.d.ts.map +1 -1
  14. package/dist/auth/types/janus.d.ts +2 -1
  15. package/dist/auth/types/janus.d.ts.map +1 -1
  16. package/dist/auth/users/any-type-api.d.ts +2 -2
  17. package/dist/auth/users/any-type-api.d.ts.map +1 -1
  18. package/dist/auth/users/find-or-create.d.ts +12 -0
  19. package/dist/auth/users/find-or-create.d.ts.map +1 -0
  20. package/dist/auth/users/insert.d.ts +8 -3
  21. package/dist/auth/users/insert.d.ts.map +1 -1
  22. package/dist/auth/users/type-api.d.ts +1 -1
  23. package/dist/auth/users/type-api.d.ts.map +1 -1
  24. package/dist/index.js +149 -36
  25. package/dist/index.js.map +8 -7
  26. package/dist/permissions/engine.d.ts.map +1 -1
  27. package/dist/permissions/index.d.ts +1 -1
  28. package/dist/permissions/index.d.ts.map +1 -1
  29. package/dist/permissions/index.js +49 -16
  30. package/dist/permissions/index.js.map +6 -5
  31. package/dist/permissions/input.d.ts +13 -1
  32. package/dist/permissions/input.d.ts.map +1 -1
  33. package/dist/permissions/model/grant.d.ts +14 -1
  34. package/dist/permissions/model/grant.d.ts.map +1 -1
  35. package/dist/permissions/model/permissions.d.ts +13 -1
  36. package/dist/permissions/model/permissions.d.ts.map +1 -1
  37. package/dist/permissions/port/types.d.ts +8 -2
  38. package/dist/permissions/port/types.d.ts.map +1 -1
  39. package/dist/permissions/replace.d.ts +25 -0
  40. package/dist/permissions/replace.d.ts.map +1 -0
  41. package/docs/README.md +2 -2
  42. package/docs/guide/email-flows.md +47 -11
  43. package/docs/guide/errors.md +1 -1
  44. package/docs/guide/permissions.md +42 -1
  45. package/docs/guide/sessions.md +6 -0
  46. package/docs/guide/users.md +44 -0
  47. package/docs/guide/vocabulary.md +2 -2
  48. package/docs/roadmap.md +25 -30
  49. package/docs/troubleshooting.md +44 -15
  50. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/permissions/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,KAAK,eAAe,EAAc,MAAM,gBAAgB,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAclD,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,WAAW;IACxD,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IACnC,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAChD,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC5B,WAAW,CAAC,CAAC,CAAC,CAsChB"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/permissions/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,KAAK,eAAe,EAAc,MAAM,gBAAgB,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAelD,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,WAAW;IACxD,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IACnC,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAChD,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC5B,WAAW,CAAC,CAAC,CAAC,CA8ChB"}
@@ -24,7 +24,7 @@ export type { ModelTypesOf } from './model/constraint';
24
24
  export type { CtxOf } from './model/ctx';
25
25
  export { type ConfigOf, defineModel, type PermissionModel, } from './model/define';
26
26
  export { type FromField, fromField, type Lookup, type ReversibleFromField, } from './model/from-field';
27
- export type { Grant, GrantableOf, HolderOf } from './model/grant';
27
+ export type { Grant, GrantableOf, HolderOf, Replace } from './model/grant';
28
28
  export type { List, ListPage, LookupGap } from './model/list';
29
29
  export type { ObjectTypeOf, UserTypeOf } from './model/names';
30
30
  export type { Permissions } from './model/permissions';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/permissions/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAChE,YAAY,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EACX,WAAW,EACX,aAAa,EACb,WAAW,EACX,OAAO,GACP,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,YAAY,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACN,KAAK,QAAQ,EACb,WAAW,EACX,KAAK,eAAe,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EACT,KAAK,MAAM,EACX,KAAK,mBAAmB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9D,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9D,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EACX,WAAW,EACX,QAAQ,EACR,SAAS,EACT,UAAU,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,IAAI,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EACX,iBAAiB,EACjB,eAAe,EACf,aAAa,GACb,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/permissions/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAChE,YAAY,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EACX,WAAW,EACX,aAAa,EACb,WAAW,EACX,OAAO,GACP,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,YAAY,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACN,KAAK,QAAQ,EACb,WAAW,EACX,KAAK,eAAe,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EACT,KAAK,MAAM,EACX,KAAK,mBAAmB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC3E,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9D,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9D,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EACX,WAAW,EACX,QAAQ,EACR,SAAS,EACT,UAAU,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,IAAI,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EACX,iBAAiB,EACjB,eAAe,EACf,aAAa,GACb,MAAM,cAAc,CAAC"}
@@ -7,6 +7,7 @@ import {
7
7
  } from "../chunks/index-4khsm7mw.js";
8
8
  import {
9
9
  PermissionDepthError2,
10
+ isSubjectSet2,
10
11
  isSetOf2,
11
12
  formatEntity2
12
13
  } from "../chunks/index-kppkcbn5.js";
@@ -66,7 +67,7 @@ function subjectOf(model, value, where) {
66
67
  }
67
68
  return { type: type.name, id, relation: value["relation"] };
68
69
  }
69
- function tupleOf(model, object, relation, subject, where) {
70
+ function targetOf(model, object, relation, where) {
70
71
  const target = objectOf(model, object, where);
71
72
  const type = typeOf(model, target.type, where);
72
73
  const def = type.relations.get(relation);
@@ -76,23 +77,26 @@ function tupleOf(model, object, relation, subject, where) {
76
77
  if (def.kind === "fromField") {
77
78
  throw new TypeError(`${where}: ${type.name}.${relation} is read from ${def.field}; there is nothing to store — change the ${type.name} instead`);
78
79
  }
79
- const who = subjectOf(model, subject, where);
80
- for (const [what, id] of [
81
- ["the object id", target.id],
82
- ["the subject id", who.id]
83
- ]) {
84
- if (!isStorable(id))
85
- throw new TypeError(`${where}: ${what} ${UNSTORABLE}`);
86
- }
87
- if (!admits(def.holders, who)) {
88
- throw new TypeError(`${where}: ${type.name}.${relation} is not held by ${"relation" in who ? `${who.type}#${who.relation}` : who.type}`);
80
+ if (!isStorable(target.id)) {
81
+ throw new TypeError(`${where}: the object id ${UNSTORABLE}`);
89
82
  }
90
83
  return {
91
- object: { type: target.type, id: target.id },
92
- relation,
93
- subject: who
84
+ entity: { type: target.type, id: target.id },
85
+ type,
86
+ holders: def.holders
94
87
  };
95
88
  }
89
+ function tupleOf(model, object, relation, subject, where) {
90
+ const target = targetOf(model, object, relation, where);
91
+ const who = subjectOf(model, subject, where);
92
+ if (!isStorable(who.id)) {
93
+ throw new TypeError(`${where}: the subject id ${UNSTORABLE}`);
94
+ }
95
+ if (!admits(target.holders, who)) {
96
+ throw new TypeError(`${where}: ${target.type.name}.${relation} is not held by ${"relation" in who ? `${who.type}#${who.relation}` : who.type}`);
97
+ }
98
+ return { object: target.entity, relation, subject: who };
99
+ }
96
100
 
97
101
  // src/permissions/walk.ts
98
102
  class Walk {
@@ -710,6 +714,34 @@ function resolvedOf(model) {
710
714
  return resolved;
711
715
  }
712
716
 
717
+ // src/permissions/replace.ts
718
+ var keyOf = (subject) => isSubjectSet2(subject) ? `set\x00${subject.type}\x00${subject.id}\x00${subject.relation}` : `entity\x00${subject.type}\x00${subject.id}`;
719
+ async function replace(model, store, object, relation, subjects) {
720
+ const where = "replace";
721
+ if (!Array.isArray(subjects)) {
722
+ throw new TypeError(`${where}: the subjects must be an array`);
723
+ }
724
+ const { entity } = targetOf(model, object, relation, where);
725
+ const wanted = new Map;
726
+ for (const subject of subjects) {
727
+ const tuple = tupleOf(model, object, relation, subject, where);
728
+ wanted.set(keyOf(tuple.subject), tuple);
729
+ }
730
+ const [entities, sets] = await Promise.all([
731
+ store.findEntities(entity, relation),
732
+ store.findSubjectSets(entity, relation)
733
+ ]);
734
+ const held = new Map;
735
+ for (const subject of [...entities, ...sets]) {
736
+ held.set(keyOf(subject), subject);
737
+ }
738
+ const add = [...wanted].filter(([key]) => !held.has(key)).map(([, t]) => t);
739
+ const remove = [...held].filter(([key]) => !wanted.has(key)).map(([, subject]) => ({ object: entity, relation, subject }));
740
+ if (add.length > 0 || remove.length > 0)
741
+ await store.write({ remove, add });
742
+ return { added: add, removed: remove };
743
+ }
744
+
713
745
  // src/permissions/engine.ts
714
746
  var DEFAULT_MAX_DEPTH = 25;
715
747
  var REQUIRED = [
@@ -745,7 +777,8 @@ function permissions(options) {
745
777
  can: withBoundModel(can),
746
778
  list: withBoundModel(list),
747
779
  grant: change("grant"),
748
- revoke: change("revoke")
780
+ revoke: change("revoke"),
781
+ replace: (object, relation, subjects) => replace(model, store, object, relation, subjects)
749
782
  });
750
783
  }
751
784
  // src/permissions/model/from-field.ts
@@ -764,5 +797,5 @@ export {
764
797
  when
765
798
  };
766
799
 
767
- //# debugId=1EF03665D47E58A564756E2164756E21
800
+ //# debugId=ED4DFF0CF169883A64756E2164756E21
768
801
  //# sourceMappingURL=index.js.map
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/permissions/resolve/resolved.ts", "../src/permissions/input.ts", "../src/permissions/walk.ts", "../src/permissions/can.ts", "../src/permissions/reverse.ts", "../src/permissions/list.ts", "../src/permissions/resolve/step.ts", "../src/permissions/resolve/declared-names.ts", "../src/permissions/resolve/refuse-data-beyond-root.ts", "../src/permissions/resolve/refuse-loops.ts", "../src/permissions/resolve/resolve-relation.ts", "../src/permissions/resolve/resolve-rule.ts", "../src/permissions/resolve/resolve-model.ts", "../src/permissions/model/define.ts", "../src/permissions/engine.ts", "../src/permissions/model/from-field.ts", "../src/permissions/model/when.ts"],
3
+ "sources": ["../src/permissions/resolve/resolved.ts", "../src/permissions/input.ts", "../src/permissions/walk.ts", "../src/permissions/can.ts", "../src/permissions/reverse.ts", "../src/permissions/list.ts", "../src/permissions/resolve/step.ts", "../src/permissions/resolve/declared-names.ts", "../src/permissions/resolve/refuse-data-beyond-root.ts", "../src/permissions/resolve/refuse-loops.ts", "../src/permissions/resolve/resolve-relation.ts", "../src/permissions/resolve/resolve-rule.ts", "../src/permissions/resolve/resolve-model.ts", "../src/permissions/model/define.ts", "../src/permissions/replace.ts", "../src/permissions/engine.ts", "../src/permissions/model/from-field.ts", "../src/permissions/model/when.ts"],
4
4
  "sourcesContent": [
5
5
  "/**\n * A model, resolved: what `can()`, `list()` and `grant()` read — every string\n * already parsed, every reference already checked.\n */\n\nimport type { Subject } from '../../subjects/subject';\n\n/** Who may hold a stored relation: a subject type, or a subject set. */\nexport type Holder =\n\t| { readonly kind: 'type'; readonly type: string }\n\t| { readonly kind: 'set'; readonly type: string; readonly relation: string };\n\n/**\n * Whether a stored relation admits `subject` as a holder: an entity of a\n * declared type, or a set of a declared `type#relation`. One rule for what\n * `grant()` writes and what `can()` and `list()` follow — a tuple the model\n * does not admit grants nothing, however it was stored.\n */\nexport function admits(holders: readonly Holder[], subject: Subject): boolean {\n\treturn holders.some((holder) =>\n\t\tholder.kind === 'type'\n\t\t\t? !('relation' in subject) && holder.type === subject.type\n\t\t\t: 'relation' in subject &&\n\t\t\t\tholder.type === subject.type &&\n\t\t\t\tholder.relation === subject.relation,\n\t);\n}\n\nexport type ResolvedRelation =\n\t| { readonly kind: 'stored'; readonly holders: readonly Holder[] }\n\t| {\n\t\t\treadonly kind: 'fromField';\n\t\t\treadonly field: string;\n\t\t\treadonly subject: string;\n\t\t\t/** What `list()` reverses it with. Absent: `list()` cannot reach through it. */\n\t\t\treadonly lookup?: (subjectId: string) => Promise<readonly string[]>;\n\t };\n\n/** One rule of a permission. `test`, when present, must pass for it to grant. */\nexport type ResolvedRule = (\n\t| { readonly kind: 'name'; readonly name: string }\n\t| {\n\t\t\treadonly kind: 'arrow';\n\t\t\treadonly relation: string;\n\t\t\treadonly target: string;\n\t }\n) & { readonly test?: (ctx: never) => boolean };\n\nexport interface ResolvedObjectType {\n\treadonly name: string;\n\treadonly relations: ReadonlyMap<string, ResolvedRelation>;\n\treadonly permissions: ReadonlyMap<string, readonly ResolvedRule[]>;\n}\n\nexport interface ResolvedModel {\n\treadonly subjects: ReadonlySet<string>;\n\treadonly types: ReadonlyMap<string, ResolvedObjectType>;\n}\n",
6
- "/** Reading what a caller passed to `can()`, `list()`, `grant()` and `revoke()`. */\n\nimport { isStorable, UNSTORABLE } from '../stores/storable';\nimport { isSetOf, type Subject } from '../subjects/subject';\nimport {\n\tadmits,\n\ttype ResolvedModel,\n\ttype ResolvedObjectType,\n} from './resolve/resolved';\n\n/** What no part of an id may hold: the notation would read it two ways. */\nconst RESERVED = /[@#()]/;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n\ttypeof value === 'object' && value !== null;\n\nexport function idOf(value: unknown, what: string, where: string): string {\n\tif (typeof value !== 'string' || value === '' || RESERVED.test(value)) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: ${what} must be a non-empty string without @, # or parentheses`,\n\t\t);\n\t}\n\treturn value;\n}\n\nexport function typeOf(\n\tmodel: ResolvedModel,\n\tname: string,\n\twhere: string,\n): ResolvedObjectType {\n\tconst type = model.types.get(name);\n\tif (type === undefined) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: \"${name}\" is not an object type of the model`,\n\t\t);\n\t}\n\treturn type;\n}\n\nexport function objectOf(\n\tmodel: ResolvedModel,\n\tvalue: unknown,\n\twhere: string,\n): {\n\treadonly type: string;\n\treadonly id: string;\n\treadonly data: Readonly<Record<string, unknown>>;\n} {\n\tif (!isRecord(value) || typeof value['type'] !== 'string') {\n\t\tthrow new TypeError(\n\t\t\t`${where}: the object must be { type, id, …its fields }`,\n\t\t);\n\t}\n\ttypeOf(model, value['type'], where);\n\treturn {\n\t\ttype: value['type'],\n\t\tid: idOf(value['id'], 'the object id', where),\n\t\tdata: value,\n\t};\n}\n\n/**\n * The subject as the store compares it: `{ type, id }` for a user or an\n * object, and `{ type, id, relation }` for a subject set.\n *\n * Decided by the type, not the shape: a user's fields are flat on it, and one\n * named `relation` must not make a user read as a set. A value of a user type\n * is that user — unless `setOf()` made it, the one way to write a set on a user\n * type the model also declares as an object type. A value of an object type is\n * a set when `relation` is given.\n */\nexport function subjectOf(\n\tmodel: ResolvedModel,\n\tvalue: unknown,\n\twhere: string,\n): Subject {\n\tif (!isRecord(value) || typeof value['type'] !== 'string') {\n\t\tthrow new TypeError(\n\t\t\t`${where}: the subject must be a user, or { type, id }`,\n\t\t);\n\t}\n\tconst id = idOf(value['id'], 'the subject id', where);\n\tconst isUserType = model.subjects.has(value['type']);\n\tconst isSet = isSetOf(value);\n\tif (isUserType && !isSet) return { type: value['type'], id };\n\tif (isUserType && isSet && !model.types.has(value.type)) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: ${value.type} is a user type the model does not declare as an object type, so ${value.type}#${String(value.relation)} is no subject set`,\n\t\t);\n\t}\n\n\tconst type = typeOf(model, value['type'], where);\n\tif (typeof value['relation'] !== 'string') return { type: type.name, id };\n\tif (!type.relations.has(value['relation'])) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: \"${value['relation']}\" is not a relation of ${type.name}, so ${type.name}#${value['relation']} is no subject set`,\n\t\t);\n\t}\n\treturn { type: type.name, id, relation: value['relation'] };\n}\n\n/** A tuple `grant` or `revoke` may write: a stored relation, and a holder it admits. */\nexport function tupleOf(\n\tmodel: ResolvedModel,\n\tobject: unknown,\n\trelation: string,\n\tsubject: unknown,\n\twhere: string,\n) {\n\tconst target = objectOf(model, object, where);\n\tconst type = typeOf(model, target.type, where);\n\tconst def = type.relations.get(relation);\n\tif (def === undefined) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: \"${relation}\" is not a relation of ${type.name}`,\n\t\t);\n\t}\n\tif (def.kind === 'fromField') {\n\t\tthrow new TypeError(\n\t\t\t`${where}: ${type.name}.${relation} is read from ${def.field}; there is nothing to store — change the ${type.name} instead`,\n\t\t);\n\t}\n\n\tconst who = subjectOf(model, subject, where);\n\t// A tuple no store can keep is refused before one is asked: the same\n\t// answer on every adapter, not STORE_FAILED on PostgreSQL alone.\n\tfor (const [what, id] of [\n\t\t['the object id', target.id],\n\t\t['the subject id', who.id],\n\t] as const) {\n\t\tif (!isStorable(id)) throw new TypeError(`${where}: ${what} ${UNSTORABLE}`);\n\t}\n\tif (!admits(def.holders, who)) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: ${type.name}.${relation} is not held by ${'relation' in who ? `${who.type}#${who.relation}` : who.type}`,\n\t\t);\n\t}\n\n\treturn {\n\t\tobject: { type: target.type, id: target.id },\n\t\trelation,\n\t\tsubject: who,\n\t};\n}\n",
6
+ "/** Reading what a caller passed to `can()`, `list()`, `grant()` and `revoke()`. */\n\nimport { isStorable, UNSTORABLE } from '../stores/storable';\nimport { isSetOf, type Subject } from '../subjects/subject';\nimport {\n\tadmits,\n\ttype ResolvedModel,\n\ttype ResolvedObjectType,\n} from './resolve/resolved';\n\n/** What no part of an id may hold: the notation would read it two ways. */\nconst RESERVED = /[@#()]/;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n\ttypeof value === 'object' && value !== null;\n\nexport function idOf(value: unknown, what: string, where: string): string {\n\tif (typeof value !== 'string' || value === '' || RESERVED.test(value)) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: ${what} must be a non-empty string without @, # or parentheses`,\n\t\t);\n\t}\n\treturn value;\n}\n\nexport function typeOf(\n\tmodel: ResolvedModel,\n\tname: string,\n\twhere: string,\n): ResolvedObjectType {\n\tconst type = model.types.get(name);\n\tif (type === undefined) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: \"${name}\" is not an object type of the model`,\n\t\t);\n\t}\n\treturn type;\n}\n\nexport function objectOf(\n\tmodel: ResolvedModel,\n\tvalue: unknown,\n\twhere: string,\n): {\n\treadonly type: string;\n\treadonly id: string;\n\treadonly data: Readonly<Record<string, unknown>>;\n} {\n\tif (!isRecord(value) || typeof value['type'] !== 'string') {\n\t\tthrow new TypeError(\n\t\t\t`${where}: the object must be { type, id, …its fields }`,\n\t\t);\n\t}\n\ttypeOf(model, value['type'], where);\n\treturn {\n\t\ttype: value['type'],\n\t\tid: idOf(value['id'], 'the object id', where),\n\t\tdata: value,\n\t};\n}\n\n/**\n * The subject as the store compares it: `{ type, id }` for a user or an\n * object, and `{ type, id, relation }` for a subject set.\n *\n * Decided by the type, not the shape: a user's fields are flat on it, and one\n * named `relation` must not make a user read as a set. A value of a user type\n * is that user — unless `setOf()` made it, the one way to write a set on a user\n * type the model also declares as an object type. A value of an object type is\n * a set when `relation` is given.\n */\nexport function subjectOf(\n\tmodel: ResolvedModel,\n\tvalue: unknown,\n\twhere: string,\n): Subject {\n\tif (!isRecord(value) || typeof value['type'] !== 'string') {\n\t\tthrow new TypeError(\n\t\t\t`${where}: the subject must be a user, or { type, id }`,\n\t\t);\n\t}\n\tconst id = idOf(value['id'], 'the subject id', where);\n\tconst isUserType = model.subjects.has(value['type']);\n\tconst isSet = isSetOf(value);\n\tif (isUserType && !isSet) return { type: value['type'], id };\n\tif (isUserType && isSet && !model.types.has(value.type)) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: ${value.type} is a user type the model does not declare as an object type, so ${value.type}#${String(value.relation)} is no subject set`,\n\t\t);\n\t}\n\n\tconst type = typeOf(model, value['type'], where);\n\tif (typeof value['relation'] !== 'string') return { type: type.name, id };\n\tif (!type.relations.has(value['relation'])) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: \"${value['relation']}\" is not a relation of ${type.name}, so ${type.name}#${value['relation']} is no subject set`,\n\t\t);\n\t}\n\treturn { type: type.name, id, relation: value['relation'] };\n}\n\n/**\n * The object and stored relation a write is about: the entity as the store\n * keeps it, and what its relation admits. Refuses a relation read from a field.\n */\nexport function targetOf(\n\tmodel: ResolvedModel,\n\tobject: unknown,\n\trelation: string,\n\twhere: string,\n) {\n\tconst target = objectOf(model, object, where);\n\tconst type = typeOf(model, target.type, where);\n\tconst def = type.relations.get(relation);\n\tif (def === undefined) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: \"${relation}\" is not a relation of ${type.name}`,\n\t\t);\n\t}\n\tif (def.kind === 'fromField') {\n\t\tthrow new TypeError(\n\t\t\t`${where}: ${type.name}.${relation} is read from ${def.field}; there is nothing to store — change the ${type.name} instead`,\n\t\t);\n\t}\n\t// A tuple no store can keep is refused before one is asked: the same\n\t// answer on every adapter, not STORE_FAILED on PostgreSQL alone.\n\tif (!isStorable(target.id)) {\n\t\tthrow new TypeError(`${where}: the object id ${UNSTORABLE}`);\n\t}\n\treturn {\n\t\tentity: { type: target.type, id: target.id },\n\t\ttype,\n\t\tholders: def.holders,\n\t};\n}\n\n/** A tuple `grant`, `revoke` or `replace` may write: a stored relation, and a holder it admits. */\nexport function tupleOf(\n\tmodel: ResolvedModel,\n\tobject: unknown,\n\trelation: string,\n\tsubject: unknown,\n\twhere: string,\n) {\n\tconst target = targetOf(model, object, relation, where);\n\tconst who = subjectOf(model, subject, where);\n\tif (!isStorable(who.id)) {\n\t\tthrow new TypeError(`${where}: the subject id ${UNSTORABLE}`);\n\t}\n\tif (!admits(target.holders, who)) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: ${target.type.name}.${relation} is not held by ${'relation' in who ? `${who.type}#${who.relation}` : who.type}`,\n\t\t);\n\t}\n\n\treturn { object: target.entity, relation, subject: who };\n}\n",
7
7
  "/** The walk behind `can()`: from an object, through its rules, to a subject. */\n\nimport { PermissionDepthError } from '../errors/janus-error';\nimport { isStorable } from '../stores/storable';\nimport { formatEntity } from '../subjects/notation';\nimport type { Entity, Subject } from '../subjects/subject';\nimport type { RelationStore } from './port/types';\nimport {\n\tadmits,\n\ttype ResolvedModel,\n\ttype ResolvedObjectType,\n\ttype ResolvedRule,\n} from './resolve/resolved';\n\n/** An object on the walk: its entity, and its data when the caller passed it. */\nexport interface Node {\n\treadonly entity: Entity;\n\treadonly data: Readonly<Record<string, unknown>> | null;\n}\n\n/** One check: its context, its path, and the depth it may reach. */\nexport class Walk {\n\t/** The nodes on the current path. The walk is sequential, so one set is the stack. */\n\tprivate readonly path = new Set<string>();\n\n\tconstructor(\n\t\tprivate readonly model: ResolvedModel,\n\t\tprivate readonly store: RelationStore,\n\t\tprivate readonly maxDepth: number,\n\t\tprivate readonly ctx: unknown,\n\t\tprivate readonly question: string,\n\t) {}\n\n\t/** Whether `subject` holds `name` — a relation or a permission — on `node`. */\n\tasync holds(\n\t\tsubject: Subject,\n\t\tnode: Node,\n\t\tname: string,\n\t\tdepth: number,\n\t): Promise<boolean> {\n\t\tif (depth > this.maxDepth) {\n\t\t\tthrow new PermissionDepthError(\n\t\t\t\t`can: checking ${this.question} crossed more than ${this.maxDepth} relations without an answer`,\n\t\t\t\t{ permission: this.question, maxDepth: this.maxDepth },\n\t\t\t);\n\t\t}\n\n\t\tconst key = `${formatEntity(node.entity)}#${name}`;\n\t\t// A cycle in the data: this branch grants nothing, and it is not an error.\n\t\tif (this.path.has(key)) return false;\n\n\t\tconst type = this.model.types.get(node.entity.type);\n\t\t// A stored tuple naming a type the model no longer declares grants nothing.\n\t\tif (type === undefined) return false;\n\n\t\tthis.path.add(key);\n\t\ttry {\n\t\t\treturn type.permissions.has(name)\n\t\t\t\t? await this.permission(subject, type, node, name, depth)\n\t\t\t\t: await this.relation(subject, type, node, name, depth);\n\t\t} finally {\n\t\t\tthis.path.delete(key);\n\t\t}\n\t}\n\n\tprivate async relation(\n\t\tsubject: Subject,\n\t\ttype: ResolvedObjectType,\n\t\tnode: Node,\n\t\tname: string,\n\t\tdepth: number,\n\t): Promise<boolean> {\n\t\tconst relation = type.relations.get(name);\n\t\tif (relation === undefined) return false;\n\n\t\tif (relation.kind === 'fromField') {\n\t\t\tconst id = fieldOf(node, relation.field, `${type.name}.${name}`);\n\t\t\treturn (\n\t\t\t\tid !== null &&\n\t\t\t\t!('relation' in subject) &&\n\t\t\t\tsubject.type === relation.subject &&\n\t\t\t\tsubject.id === id\n\t\t\t);\n\t\t}\n\n\t\t// What the model does not admit here grants nothing, however it was stored.\n\t\tif (\n\t\t\tadmits(relation.holders, subject) &&\n\t\t\t(await this.store.has({ object: node.entity, relation: name, subject }))\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\tfor (const set of await this.store.findSubjectSets(node.entity, name)) {\n\t\t\tif (!admits(relation.holders, set)) continue;\n\t\t\tconst through = { entity: { type: set.type, id: set.id }, data: null };\n\t\t\tif (await this.holds(subject, through, set.relation, depth + 1)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate async permission(\n\t\tsubject: Subject,\n\t\ttype: ResolvedObjectType,\n\t\tnode: Node,\n\t\tname: string,\n\t\tdepth: number,\n\t): Promise<boolean> {\n\t\tfor (const rule of type.permissions.get(name) ?? []) {\n\t\t\tif (rule.test !== undefined && !this.passes(rule, type, name)) continue;\n\n\t\t\tif (rule.kind === 'name') {\n\t\t\t\tif (await this.holds(subject, node, rule.name, depth)) return true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (const target of await this.targets(type, node, rule.relation)) {\n\t\t\t\tif (await this.holds(subject, target, rule.target, depth + 1)) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/** The condition, run on the caller's `ctx`. Its absence is a caller's bug, not a denial. */\n\tprivate passes(\n\t\trule: ResolvedRule,\n\t\ttype: ResolvedObjectType,\n\t\tname: string,\n\t): boolean {\n\t\tif (this.ctx === undefined) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`can: ${type.name}.${name} reaches a condition, and no ctx was passed — pass { ctx }`,\n\t\t\t);\n\t\t}\n\t\treturn (rule.test as (ctx: unknown) => boolean)(this.ctx) === true;\n\t}\n\n\t/** The objects an arrow through `relation` reaches from `node`. */\n\tprivate async targets(\n\t\ttype: ResolvedObjectType,\n\t\tnode: Node,\n\t\trelation: string,\n\t): Promise<Node[]> {\n\t\tconst through = type.relations.get(relation);\n\t\tif (through === undefined) return [];\n\n\t\tif (through.kind === 'fromField') {\n\t\t\tconst id = fieldOf(node, through.field, `${type.name}.${relation}`);\n\t\t\treturn id === null\n\t\t\t\t? []\n\t\t\t\t: [{ entity: { type: through.subject, id }, data: null }];\n\t\t}\n\t\t// An entity of a type the model does not admit here is no target.\n\t\treturn (await this.store.findEntities(node.entity, relation))\n\t\t\t.filter((entity) => admits(through.holders, entity))\n\t\t\t.map((entity) => ({\n\t\t\t\tentity: { type: entity.type, id: entity.id },\n\t\t\t\tdata: null,\n\t\t\t}));\n\t}\n}\n\n/**\n * The id a `fromField` reads, or `null` for nobody — an id no store can keep\n * included, so none is asked about it. A missing field is the caller's bug.\n */\nfunction fieldOf(node: Node, field: string, what: string): string | null {\n\tif (node.data === null) {\n\t\t// resolveModel refuses a model that could get here.\n\t\tthrow new TypeError(\n\t\t\t`can: ${what} reads ${field} from an object nobody passed`,\n\t\t);\n\t}\n\tconst value = node.data[field];\n\tif (value === null) return null;\n\tif (typeof value !== 'string') {\n\t\tthrow new TypeError(\n\t\t\t`can: ${what} reads ${field}, which the object ${value === undefined ? 'does not carry — pass the loaded object, spread' : 'holds as something other than a string id'}`,\n\t\t);\n\t}\n\treturn isStorable(value) ? value : null;\n}\n",
8
8
  "/**\n * `can()`: whether a subject holds a permission on an object — the walk of\n * `walk.ts`, after the refusals of what a caller passed.\n */\n\nimport { isStorable } from '../stores/storable';\nimport type { BoundModel } from './bound-model';\nimport { objectOf, subjectOf, typeOf } from './input';\nimport { Walk } from './walk';\n\n/**\n * Whether `subject` holds `permission` on `object`: `false` for anonymous or\n * an id no store can keep, before any store call; a failure throws.\n */\nexport async function can(\n\t{ model, store, maxDepth }: BoundModel,\n\tsubject: unknown,\n\tpermission: string,\n\tobject: unknown,\n\toptions?: { readonly ctx?: unknown },\n): Promise<boolean> {\n\t// Anonymous, before anything else — and before the store.\n\tif (subject === null || subject === undefined) return false;\n\n\tconst root = objectOf(model, object, 'can');\n\tconst type = typeOf(model, root.type, 'can');\n\tif (!type.relations.has(permission) && !type.permissions.has(permission)) {\n\t\tthrow new TypeError(\n\t\t\t`can: \"${permission}\" is not a relation or a permission of ${type.name}`,\n\t\t);\n\t}\n\n\tconst who = subjectOf(model, subject, 'can');\n\t// An id no store can keep is held by nobody, and no store is asked:\n\t// the same answer on every adapter, as for an anonymous subject.\n\tif (!isStorable(root.id) || !isStorable(who.id)) return false;\n\n\treturn new Walk(\n\t\tmodel,\n\t\tstore,\n\t\tmaxDepth,\n\t\toptions?.ctx,\n\t\t`${type.name}#${permission}`,\n\t).holds(\n\t\twho,\n\t\t{ entity: { type: root.type, id: root.id }, data: root.data },\n\t\tpermission,\n\t\t0,\n\t);\n}\n",
9
9
  "import { PermissionDepthError } from '../errors/janus-error';\nimport type { CursorPage } from '../pagination/cursor-page';\nimport { MAX_PAGE_SIZE } from '../pagination/cursor-page';\nimport { isStorable } from '../stores/storable';\nimport type { Subject } from '../subjects/subject';\nimport type { RelationStore } from './port/types';\nimport {\n\tadmits,\n\ttype ResolvedModel,\n\ttype ResolvedObjectType,\n\ttype ResolvedRule,\n} from './resolve/resolved';\n\n/**\n * One `list()`: the objects a subject holds a name on, found backwards —\n * from the subject to the tuples naming it, through the sets and arrows the\n * model declares, to the objects.\n *\n * **A least fixpoint.** `objects(type, name)` is a union of what its rules\n * reach, and a rule can reach its own name again — a folder viewable through\n * its parent, a team member through a team. Such a name, met again on the\n * current path, answers what the previous round found; rounds repeat until\n * none adds an id. That is exactly the set of objects with a derivation that\n * does not loop — what `can()`'s cut finds, one object at a time. A round\n * that met no loop is final.\n *\n * **Depth.** Each round past the first follows the loops one relation\n * further; more than `maxDepth` rounds is `PERMISSION_DEPTH`, as crossing more\n * than `maxDepth` relations is for `can()`.\n *\n * **Cost.** Every page of `findObjects` for every id each step reaches, every\n * round. Linear in what the subject can reach — fine for the objects of one\n * user, not for a subject set holding most of the database.\n */\nexport class Reverse {\n\tprivate previous = new Map<string, ReadonlySet<string>>();\n\tprivate current = new Map<string, ReadonlySet<string>>();\n\tprivate readonly path = new Set<string>();\n\tprivate looped = false;\n\n\tconstructor(\n\t\tprivate readonly model: ResolvedModel,\n\t\tprivate readonly store: RelationStore,\n\t\tprivate readonly maxDepth: number,\n\t\tprivate readonly ctx: unknown,\n\t\tprivate readonly subject: Subject,\n\t\tprivate readonly question: string,\n\t) {}\n\n\tasync objects(type: string, name: string): Promise<ReadonlySet<string>> {\n\t\tfor (let round = 0; round <= this.maxDepth; round += 1) {\n\t\t\tthis.current = new Map();\n\t\t\tthis.looped = false;\n\t\t\tconst found = await this.reach(type, name);\n\t\t\tif (!this.looped || this.same()) return found;\n\t\t\tthis.previous = this.current;\n\t\t}\n\t\tthrow new PermissionDepthError(\n\t\t\t`list: listing ${this.question} crossed more than ${this.maxDepth} relations without an answer`,\n\t\t\t{ permission: this.question, maxDepth: this.maxDepth },\n\t\t);\n\t}\n\n\t/** Whether this round found what the previous one did: nothing more to find. */\n\tprivate same(): boolean {\n\t\tfor (const [key, ids] of this.current) {\n\t\t\tif ((this.previous.get(key)?.size ?? 0) !== ids.size) return false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** The ids of the objects of `typeName` on which the subject holds `name`. */\n\tprivate async reach(\n\t\ttypeName: string,\n\t\tname: string,\n\t): Promise<ReadonlySet<string>> {\n\t\tconst key = `${typeName}#${name}`;\n\t\tconst done = this.current.get(key);\n\t\tif (done !== undefined) return done;\n\t\tif (this.path.has(key)) {\n\t\t\tthis.looped = true;\n\t\t\treturn this.previous.get(key) ?? new Set();\n\t\t}\n\n\t\tconst type = this.model.types.get(typeName);\n\t\tif (type === undefined) return new Set();\n\n\t\tthis.path.add(key);\n\t\ttry {\n\t\t\tconst found = type.permissions.has(name)\n\t\t\t\t? await this.permission(type, name)\n\t\t\t\t: await this.relation(type, name);\n\t\t\tthis.current.set(key, found);\n\t\t\treturn found;\n\t\t} finally {\n\t\t\tthis.path.delete(key);\n\t\t}\n\t}\n\n\tprivate async relation(\n\t\ttype: ResolvedObjectType,\n\t\tname: string,\n\t): Promise<Set<string>> {\n\t\tconst relation = type.relations.get(name);\n\t\tif (relation === undefined) return new Set();\n\n\t\tif (relation.kind === 'fromField') {\n\t\t\tconst subject = this.subject;\n\t\t\treturn 'relation' in subject || subject.type !== relation.subject\n\t\t\t\t? new Set()\n\t\t\t\t: new Set(await this.lookup(type, name, subject.id));\n\t\t}\n\n\t\t// A direct tuple counts only when the model admits the subject here.\n\t\tconst found = new Set(\n\t\t\tadmits(relation.holders, this.subject)\n\t\t\t\t? await this.holding(type.name, name, this.subject)\n\t\t\t\t: [],\n\t\t);\n\t\tfor (const holder of relation.holders) {\n\t\t\tif (holder.kind !== 'set') continue;\n\t\t\tfor (const id of await this.reach(holder.type, holder.relation)) {\n\t\t\t\tconst set = { type: holder.type, id, relation: holder.relation };\n\t\t\t\tfor (const object of await this.holding(type.name, name, set)) {\n\t\t\t\t\tfound.add(object);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn found;\n\t}\n\n\tprivate async permission(\n\t\ttype: ResolvedObjectType,\n\t\tname: string,\n\t): Promise<Set<string>> {\n\t\tconst found = new Set<string>();\n\t\tfor (const rule of type.permissions.get(name) ?? []) {\n\t\t\tif (rule.test !== undefined && !this.passes(rule, type, name)) continue;\n\n\t\t\tif (rule.kind === 'name') {\n\t\t\t\tfor (const id of await this.reach(type.name, rule.name)) found.add(id);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (const id of await this.arrow(type, rule.relation, rule.target)) {\n\t\t\t\tfound.add(id);\n\t\t\t}\n\t\t}\n\t\treturn found;\n\t}\n\n\t/** The objects of `type` whose `relation` reaches an object on which the subject holds `target`. */\n\tprivate async arrow(\n\t\ttype: ResolvedObjectType,\n\t\trelation: string,\n\t\ttarget: string,\n\t): Promise<Set<string>> {\n\t\tconst through = type.relations.get(relation);\n\t\tconst found = new Set<string>();\n\t\tif (through === undefined) return found;\n\n\t\tif (through.kind === 'fromField') {\n\t\t\tfor (const id of await this.reach(through.subject, target)) {\n\t\t\t\tfor (const object of await this.lookup(type, relation, id)) {\n\t\t\t\t\tfound.add(object);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn found;\n\t\t}\n\t\tfor (const holder of through.holders) {\n\t\t\t// An arrow follows entities of an object type — a user type too, when\n\t\t\t// the model also declares it under types.\n\t\t\tif (holder.kind !== 'type' || !this.model.types.has(holder.type)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (const id of await this.reach(holder.type, target)) {\n\t\t\t\tconst entity = { type: holder.type, id };\n\t\t\t\tfor (const object of await this.holding(type.name, relation, entity)) {\n\t\t\t\t\tfound.add(object);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn found;\n\t}\n\n\t/** Every id of every page of `findObjects`. */\n\tprivate async holding(\n\t\ttype: string,\n\t\trelation: string,\n\t\tsubject: Subject,\n\t): Promise<string[]> {\n\t\tconst ids: string[] = [];\n\t\tlet after: string | null = null;\n\t\tdo {\n\t\t\tconst page: CursorPage<string> = await this.store.findObjects({\n\t\t\t\ttype,\n\t\t\t\trelation,\n\t\t\t\tsubject,\n\t\t\t\tafter,\n\t\t\t\tlimit: MAX_PAGE_SIZE,\n\t\t\t});\n\t\t\tids.push(...page.items);\n\t\t\tafter = page.nextCursor;\n\t\t} while (after !== null);\n\t\treturn ids;\n\t}\n\n\t/** The objects whose field names `id`, from the `fromField`'s lookup. */\n\tprivate async lookup(\n\t\ttype: ResolvedObjectType,\n\t\trelation: string,\n\t\tid: string,\n\t): Promise<readonly string[]> {\n\t\tconst def = type.relations.get(relation);\n\t\tif (def?.kind !== 'fromField' || def.lookup === undefined) {\n\t\t\tconst field = def?.kind === 'fromField' ? def.field : relation;\n\t\t\tconst subject = def?.kind === 'fromField' ? def.subject : 'subject';\n\t\t\t// The subject's type, never its id: a message reports a shape.\n\t\t\tthrow new TypeError(\n\t\t\t\t`list: ${type.name}.${relation} is read from a field, and has no lookup to find the ${type.name}s naming a subject of type '${subject}' — fromField('${field}', '${subject}', { lookup })`,\n\t\t\t);\n\t\t}\n\t\tconst ids = await def.lookup(id);\n\t\tif (!Array.isArray(ids) || ids.some((each) => typeof each !== 'string')) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`list: the lookup of ${type.name}.${relation} must answer an array of ids`,\n\t\t\t);\n\t\t}\n\t\t// An id no store can keep is held by nobody, as can() answers it.\n\t\treturn ids.filter(isStorable);\n\t}\n\n\t/** The condition, run on the caller's `ctx`, as for `can()`. */\n\tprivate passes(\n\t\trule: ResolvedRule,\n\t\ttype: ResolvedObjectType,\n\t\tname: string,\n\t): boolean {\n\t\tif (this.ctx === undefined) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`list: ${type.name}.${name} reaches a condition, and no ctx was passed — pass { ctx }`,\n\t\t\t);\n\t\t}\n\t\treturn (rule.test as (ctx: unknown) => boolean)(this.ctx) === true;\n\t}\n}\n",
@@ -16,11 +16,12 @@
16
16
  "/** One rule of a permission: a name, an arrow, or either under `when()`. */\n\nimport type { ResolvedRelation, ResolvedRule } from './resolved';\nimport { isRecord, type Refuse } from './step';\n\nexport function resolveRule(\n\tvalue: unknown,\n\there: string,\n\tcontext: {\n\t\trefuse: Refuse;\n\t\town: ReadonlySet<string>;\n\t\trelations: ReadonlyMap<string, ResolvedRelation>;\n\t\ttypeNames: ReadonlySet<string>;\n\t\tnamesOf: (type: string) => ReadonlySet<string>;\n\t\tself: string;\n\t},\n): ResolvedRule {\n\tconst { refuse } = context;\n\n\tif (isRecord(value) && value['kind'] === 'when') {\n\t\tif (typeof value['test'] !== 'function') {\n\t\t\tthrow refuse(`${here}: when() takes a function as its test`);\n\t\t}\n\t\tconst inner = resolveRule(value['rule'], here, context);\n\t\treturn { ...inner, test: value['test'] as (ctx: never) => boolean };\n\t}\n\tif (typeof value !== 'string') {\n\t\tthrow refuse(`${here}: a rule is a name, an arrow, or when()`);\n\t}\n\n\tconst arrow = value.indexOf('->');\n\tif (arrow < 0) {\n\t\tif (!context.own.has(value)) {\n\t\t\tthrow refuse(\n\t\t\t\t`${here}: \"${value}\" is not a relation or a permission of ${context.self}`,\n\t\t\t);\n\t\t}\n\t\treturn { kind: 'name', name: value };\n\t}\n\n\tconst relation = value.slice(0, arrow);\n\tconst target = value.slice(arrow + 2);\n\tconst through = context.relations.get(relation);\n\tif (through === undefined) {\n\t\tthrow refuse(\n\t\t\t`${here}: \"${value}\" goes through \"${relation}\", which is not a relation of ${context.self}`,\n\t\t);\n\t}\n\tconst targets =\n\t\tthrough.kind === 'fromField'\n\t\t\t? [through.subject]\n\t\t\t: through.holders.map((holder) =>\n\t\t\t\t\tholder.kind === 'type' ? holder.type : null,\n\t\t\t\t);\n\tfor (const type of targets) {\n\t\t// A subject set, or a user type, has no permissions to follow.\n\t\tif (type === null || !context.typeNames.has(type)) {\n\t\t\tthrow refuse(\n\t\t\t\t`${here}: \"${value}\" goes through \"${relation}\", which can hold ${type === null ? 'a subject set' : `a ${type}`}; an arrow follows object types only`,\n\t\t\t);\n\t\t}\n\t\tif (!context.namesOf(type).has(target)) {\n\t\t\tthrow refuse(\n\t\t\t\t`${here}: \"${value}\" names \"${target}\", which ${type} does not declare`,\n\t\t\t);\n\t\t}\n\t}\n\treturn { kind: 'arrow', relation, target };\n}\n",
17
17
  "/**\n * Resolves a model: parses every string once, checks every reference, and\n * refuses with a `TypeError` naming where it is.\n *\n * The types refuse most of these first. This is what refuses them for a model\n * built at run time or written in JavaScript, and what refuses what the types\n * cannot see: names, and a permission that reaches itself without crossing a\n * relation.\n */\n\nimport type { ModelConfig } from '../model/config';\nimport {\n\tcollectNames,\n\ttype DeclaredNames,\n\tobjectTypeNamesOf,\n\tsubjectTypesOf,\n} from './declared-names';\nimport { refuseDataBeyondRoot } from './refuse-data-beyond-root';\nimport { refuseLoops } from './refuse-loops';\nimport { resolveRelation } from './resolve-relation';\nimport { resolveRule } from './resolve-rule';\nimport type {\n\tResolvedModel,\n\tResolvedObjectType,\n\tResolvedRelation,\n\tResolvedRule,\n} from './resolved';\nimport { isRecord, type Refuse } from './step';\n\nexport function resolveModel(\n\tconfig: ModelConfig,\n\twhere: string,\n): ResolvedModel {\n\tconst refuse: Refuse = (message) => new TypeError(`${where}: ${message}`);\n\n\tif (!isRecord(config)) throw refuse('pass { subjects, types }');\n\tconst subjects = subjectTypesOf(config.subjects, refuse);\n\tconst typeNames = objectTypeNamesOf(config.types, refuse);\n\tconst declared = collectNames(config.types, refuse);\n\tconst types = resolveTypes(config.types, {\n\t\trefuse,\n\t\tsubjects,\n\t\ttypeNames,\n\t\tdeclared,\n\t});\n\n\trefuseLoops(types, refuse);\n\trefuseDataBeyondRoot(types, refuse);\n\n\treturn { subjects, types };\n}\n\n/** Each object type's relations and permissions, every rule parsed once. */\nfunction resolveTypes(\n\tdefs: ModelConfig['types'],\n\tcontext: {\n\t\treadonly refuse: Refuse;\n\t\treadonly subjects: ReadonlySet<string>;\n\t\treadonly typeNames: ReadonlySet<string>;\n\t\treadonly declared: DeclaredNames;\n\t},\n): Map<string, ResolvedObjectType> {\n\tconst { refuse, subjects, typeNames } = context;\n\tconst { relationNames, permissionNames } = context.declared;\n\tconst isSubjectType = (type: string) =>\n\t\tsubjects.has(type) || typeNames.has(type);\n\tconst namesOf = (type: string) =>\n\t\tnew Set([\n\t\t\t...(relationNames.get(type) ?? []),\n\t\t\t...(permissionNames.get(type) ?? []),\n\t\t]);\n\n\tconst types = new Map<string, ResolvedObjectType>();\n\tfor (const [name, def] of Object.entries(defs)) {\n\t\tconst at = `types.${name}`;\n\t\tconst relations = new Map<string, ResolvedRelation>();\n\n\t\tfor (const [relation, holders] of Object.entries(def.related ?? {})) {\n\t\t\tconst here = `${at}.related.${relation}`;\n\t\t\trelations.set(\n\t\t\t\trelation,\n\t\t\t\tresolveRelation(holders, here, {\n\t\t\t\t\trefuse,\n\t\t\t\t\tisSubjectType,\n\t\t\t\t\trelationNames,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst permissions = new Map<string, readonly ResolvedRule[]>();\n\t\tfor (const [permission, rules] of Object.entries(def.permits ?? {})) {\n\t\t\tconst here = `${at}.permits.${permission}`;\n\t\t\tif (!Array.isArray(rules) || rules.length === 0) {\n\t\t\t\tthrow refuse(`${here} must be a non-empty array of rules`);\n\t\t\t}\n\t\t\tpermissions.set(\n\t\t\t\tpermission,\n\t\t\t\trules.map((rule: unknown, index: number) =>\n\t\t\t\t\tresolveRule(rule, `${here}[${index}]`, {\n\t\t\t\t\t\trefuse,\n\t\t\t\t\t\town: namesOf(name),\n\t\t\t\t\t\trelations,\n\t\t\t\t\t\ttypeNames,\n\t\t\t\t\t\tnamesOf,\n\t\t\t\t\t\tself: name,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\ttypes.set(name, { name, relations, permissions });\n\t}\n\treturn types;\n}\n",
18
18
  "/**\n * The permission model: which object types exist, which relations they hold,\n * and which permissions those relations grant — written in TypeScript, and\n * typed from itself.\n *\n * **ReBAC, embedded.** Zanzibar's data model — relations between objects and\n * subjects, permissions computed from them — without its infrastructure: the\n * database is the application's own, so reads follow writes and there is\n * nothing to cache or sequence. Two things go beyond Zanzibar's descendants:\n *\n * - **`fromField`**, a relation read from the object's own data — a record's\n * `doctorId` — rather than a tuple to keep in sync with it. Two sources of\n * truth for one fact is the first trap of a Zanzibar deployment;\n * - **`when`**, a condition written in TypeScript and typed: its `ctx` is what\n * `can()` then requires, and only for the permissions whose rules reach it.\n *\n * The model is a flat `const` literal, and everything the compiler can check\n * about it is checked by `ModelTypesOf`, in `./constraint`: a relation naming\n * a subject type that does not exist, a permission naming a relation that does\n * not exist, an arrow to a permission its target does not have. What only\n * running it can check —\n * names, cycles — is refused by {@link defineModel} with a `TypeError`.\n */\n\nimport { resolveModel } from '../resolve/resolve-model';\nimport type { ResolvedModel } from '../resolve/resolved';\nimport type { ModelConfig } from './config';\nimport type { ModelTypesOf } from './constraint';\nimport type { ObjectTypeOf, UserTypeOf } from './names';\n\n/** A model, checked and resolved. What `permissions()` will take. */\nexport interface PermissionModel<C extends ModelConfig = ModelConfig> {\n\t/** The user types it accepts as subjects. */\n\treadonly subjects: readonly UserTypeOf<C>[];\n\t/** The object types it declares. */\n\treadonly types: readonly ObjectTypeOf<C>[];\n\t/** The definition, as written — the very object passed to defineModel. */\n\treadonly definition: C;\n}\n\n/** The configuration a model was defined from. */\nexport type ConfigOf<M> = M extends PermissionModel<infer C> ? C : never;\n\n// Keyed by the frozen model itself: nothing outside this module can reach it.\nconst RESOLVED = new WeakMap<object, ResolvedModel>();\n\n/**\n * Checks a model and resolves it. Connects to nothing.\n *\n * ```ts\n * export const model = defineModel({\n * subjects: auth.types,\n * types: {\n * team: {\n * related: { members: ['staff', 'team#members'], leads: ['staff'] },\n * permits: { manage: ['leads'], view: ['members', 'manage'] },\n * },\n * record: {\n * related: {\n * doctors: fromField('doctorId', 'staff'),\n * teams: ['team'],\n * },\n * permits: {\n * view: ['doctors', 'teams->view'],\n * edit: [when('doctors', (ctx: { onShift: boolean }) => ctx.onShift)],\n * },\n * },\n * },\n * });\n * ```\n *\n * Refuses with a `TypeError` what only running it can see: a name that is not\n * camelCase, a permission that reaches itself without crossing a relation —\n * which no data could ever end. A user type may also be an object type: its\n * users are then objects too, and a set on it is written with `setOf()`.\n */\nexport function defineModel<\n\tconst Subjects extends readonly string[],\n\tconst Ts extends ModelConfig['types'] & ModelTypesOf<Subjects[number], Ts>,\n>(config: {\n\treadonly subjects: Subjects;\n\treadonly types: Ts;\n}): PermissionModel<{ readonly subjects: Subjects; readonly types: Ts }>;\nexport function defineModel<const C extends ModelConfig>(\n\tconfig: C,\n): PermissionModel<C> {\n\tconst resolved = resolveModel(config, 'defineModel');\n\tconst model: PermissionModel<C> = Object.freeze({\n\t\tsubjects: [...resolved.subjects] as UserTypeOf<C>[],\n\t\ttypes: [...resolved.types.keys()] as ObjectTypeOf<C>[],\n\t\tdefinition: config,\n\t});\n\tRESOLVED.set(model, resolved);\n\treturn model;\n}\n\n/** The resolved form of a model this module defined. Internal. */\nexport function resolvedOf(model: object): ResolvedModel {\n\tconst resolved = RESOLVED.get(model);\n\tif (resolved === undefined) {\n\t\tthrow new TypeError(\n\t\t\t'permissions: this model was not made by defineModel() — pass what defineModel() answered',\n\t\t);\n\t}\n\treturn resolved;\n}\n",
19
- "/**\n * The engine: `permissions({ model, store })`, the traversal behind `can()`,\n * and the same traversal run backwards behind `list()` — `can.ts` over\n * `walk.ts`, `list.ts` over `reverse.ts`; what a caller passes is read in\n * `input.ts`.\n *\n * **The invariant, permission side.** A denial is `false` — never a thrown\n * error, which is how Keto's historical endpoint answers and why a denial and\n * an outage look alike there. A failure throws — never `false`, which would\n * deny everybody everything during an outage and say nothing. The store is\n * reached only through `guardRelations`, and `outage.scan.spec.ts` refuses a `catch`\n * anywhere in this directory.\n *\n * **What is walked.** A relation holds when the tuple is stored, or through a\n * subject set holding it (`team:t1#member`), or — for a `fromField` — when the\n * object's field names the subject. A permission holds when any of its rules\n * does: a name of the same object, an arrow to a related object's permission,\n * either under a condition. The walk is sequential and stops at the first\n * grant, so a check reads no more than it needs.\n *\n * **Cycles and depth.** A node already on the current path — a team member of\n * a team member of itself — is cut: that branch grants nothing, and it is not\n * an error, because it is data. Crossing more than `maxDepth` relations *is*\n * an error, `PERMISSION_DEPTH`: an evaluation that stopped half-way decided\n * nothing, and `false` would hide it.\n */\n\nimport { guardRelations } from '../stores/guard';\nimport type { BoundModel } from './bound-model';\nimport { can } from './can';\nimport { tupleOf } from './input';\nimport { list } from './list';\nimport type { ModelConfig } from './model/config';\nimport { type PermissionModel, resolvedOf } from './model/define';\nimport type { Permissions } from './model/permissions';\nimport type { RelationStore } from './port/types';\n\n/** Deep enough for any hierarchy a person draws; OpenFGA's default too. */\nconst DEFAULT_MAX_DEPTH = 25;\n\nconst REQUIRED = [\n\t'write',\n\t'has',\n\t'findSubjectSets',\n\t'findEntities',\n\t'findObjects',\n\t'deleteEntity',\n] as const;\n\nexport interface PermissionsOptions<C extends ModelConfig> {\n\t/** What `defineModel()` answered. */\n\treadonly model: PermissionModel<C>;\n\t/** Where tuples live. `createMemoryRelations()` in tests. */\n\treadonly store: RelationStore;\n\t/** How many relations a check may cross. `25` when absent. */\n\treadonly maxDepth?: number;\n}\n\n/**\n * Binds a model to a relation store. Connects to nothing.\n *\n * ```ts\n * const access = permissions({ model, store: createMemoryRelations() });\n * await access.grant({ type: 'team', id: 't1' }, 'members', staff);\n * await access.can(staff, 'view', { type: 'record', ...record }, { ctx: { onShift } });\n * ```\n */\nexport function permissions<C extends ModelConfig>(\n\toptions: PermissionsOptions<C>,\n): Permissions<C> {\n\tconst where = 'permissions';\n\tconst model = resolvedOf(options.model);\n\tconst maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;\n\tif (!Number.isInteger(maxDepth) || maxDepth < 1) {\n\t\tthrow new TypeError(`${where}: maxDepth must be a positive integer`);\n\t}\n\tconst raw = options.store as unknown as Record<string, unknown> | undefined;\n\tfor (const method of REQUIRED) {\n\t\tif (typeof raw?.[method] !== 'function') {\n\t\t\tthrow new TypeError(`${where}: store.${method} is missing`);\n\t\t}\n\t}\n\tconst store = guardRelations(options.store);\n\n\tconst bound: BoundModel = { model, store, maxDepth };\n\t// `can` and `list` over what this call bound, as the API takes them.\n\tconst withBoundModel =\n\t\t<A extends unknown[], R>(call: (bound: BoundModel, ...rest: A) => R) =>\n\t\t(...rest: A): R =>\n\t\t\tcall(bound, ...rest);\n\n\tconst change =\n\t\t(operation: 'grant' | 'revoke') =>\n\t\tasync (object: unknown, relation: string, subject: unknown) => {\n\t\t\tconst tuple = tupleOf(model, object, relation, subject, operation);\n\t\t\tawait store.write(\n\t\t\t\toperation === 'grant' ? { add: [tuple] } : { remove: [tuple] },\n\t\t\t);\n\t\t};\n\n\treturn Object.freeze({\n\t\tmodel: options.model,\n\t\tcan: withBoundModel(can) as Permissions<C>['can'],\n\t\tlist: withBoundModel(list) as Permissions<C>['list'],\n\t\tgrant: change('grant') as Permissions<C>['grant'],\n\t\trevoke: change('revoke') as Permissions<C>['revoke'],\n\t});\n}\n",
19
+ "/** `replace()`: make the holders of one relation exactly a wanted list. */\n\nimport {\n\tisSubjectSet,\n\ttype RelationTuple,\n\ttype Subject,\n} from '../subjects/subject';\nimport { targetOf, tupleOf } from './input';\nimport type { RelationStore } from './port/types';\nimport type { ResolvedModel } from './resolve/resolved';\n\n/** A subject as an identity: an entity is not the set `type:id#relation`. */\nconst keyOf = (subject: Subject): string =>\n\tisSubjectSet(subject)\n\t\t? `set\\0${subject.type}\\0${subject.id}\\0${subject.relation}`\n\t\t: `entity\\0${subject.type}\\0${subject.id}`;\n\n/**\n * Makes `subjects` the only holders of `relation` on `object`: the missing\n * ones are added, the others removed, and what is already right is left alone.\n * Answers the tuples added and the tuples removed, as the single `write` held\n * them.\n *\n * Every subject is read first, as `grant` reads it, so a refusal writes\n * nothing. `[]` removes every holder. Duplicates count once, and a subject set\n * is not its entity. The current holders are read, then **one** `write` holds\n * the removals and the additions — all or nothing — and none when both are\n * empty.\n *\n * **Not serialised.** Two concurrent `replace` calls on the same object and\n * relation each read, then write their own diff, so the result can hold the\n * union of both adds. A caller that needs one winner serialises them itself.\n */\nexport async function replace(\n\tmodel: ResolvedModel,\n\tstore: RelationStore,\n\tobject: unknown,\n\trelation: string,\n\tsubjects: unknown,\n): Promise<{\n\tadded: RelationTuple[];\n\tremoved: RelationTuple[];\n}> {\n\tconst where = 'replace';\n\tif (!Array.isArray(subjects)) {\n\t\tthrow new TypeError(`${where}: the subjects must be an array`);\n\t}\n\t// An empty list still names an object and a relation: refuse a wrong one.\n\tconst { entity } = targetOf(model, object, relation, where);\n\tconst wanted = new Map<string, RelationTuple>();\n\tfor (const subject of subjects) {\n\t\tconst tuple = tupleOf(model, object, relation, subject, where);\n\t\twanted.set(keyOf(tuple.subject), tuple);\n\t}\n\n\tconst [entities, sets] = await Promise.all([\n\t\tstore.findEntities(entity, relation),\n\t\tstore.findSubjectSets(entity, relation),\n\t]);\n\tconst held = new Map<string, Subject>();\n\tfor (const subject of [...entities, ...sets]) {\n\t\theld.set(keyOf(subject), subject);\n\t}\n\n\tconst add = [...wanted].filter(([key]) => !held.has(key)).map(([, t]) => t);\n\tconst remove = [...held]\n\t\t.filter(([key]) => !wanted.has(key))\n\t\t.map(([, subject]) => ({ object: entity, relation, subject }));\n\tif (add.length > 0 || remove.length > 0) await store.write({ remove, add });\n\treturn { added: add, removed: remove };\n}\n",
20
+ "/**\n * The engine: `permissions({ model, store })`, the traversal behind `can()`,\n * and the same traversal run backwards behind `list()` — `can.ts` over\n * `walk.ts`, `list.ts` over `reverse.ts`; what a caller passes is read in\n * `input.ts`.\n *\n * **The invariant, permission side.** A denial is `false` — never a thrown\n * error, which is how Keto's historical endpoint answers and why a denial and\n * an outage look alike there. A failure throws — never `false`, which would\n * deny everybody everything during an outage and say nothing. The store is\n * reached only through `guardRelations`, and `outage.scan.spec.ts` refuses a `catch`\n * anywhere in this directory.\n *\n * **What is walked.** A relation holds when the tuple is stored, or through a\n * subject set holding it (`team:t1#member`), or — for a `fromField` — when the\n * object's field names the subject. A permission holds when any of its rules\n * does: a name of the same object, an arrow to a related object's permission,\n * either under a condition. The walk is sequential and stops at the first\n * grant, so a check reads no more than it needs.\n *\n * **Cycles and depth.** A node already on the current path — a team member of\n * a team member of itself — is cut: that branch grants nothing, and it is not\n * an error, because it is data. Crossing more than `maxDepth` relations *is*\n * an error, `PERMISSION_DEPTH`: an evaluation that stopped half-way decided\n * nothing, and `false` would hide it.\n */\n\nimport { guardRelations } from '../stores/guard';\nimport type { BoundModel } from './bound-model';\nimport { can } from './can';\nimport { tupleOf } from './input';\nimport { list } from './list';\nimport type { ModelConfig } from './model/config';\nimport { type PermissionModel, resolvedOf } from './model/define';\nimport type { Permissions } from './model/permissions';\nimport type { RelationStore } from './port/types';\nimport { replace } from './replace';\n\n/** Deep enough for any hierarchy a person draws; OpenFGA's default too. */\nconst DEFAULT_MAX_DEPTH = 25;\n\nconst REQUIRED = [\n\t'write',\n\t'has',\n\t'findSubjectSets',\n\t'findEntities',\n\t'findObjects',\n\t'deleteEntity',\n] as const;\n\nexport interface PermissionsOptions<C extends ModelConfig> {\n\t/** What `defineModel()` answered. */\n\treadonly model: PermissionModel<C>;\n\t/** Where tuples live. `createMemoryRelations()` in tests. */\n\treadonly store: RelationStore;\n\t/** How many relations a check may cross. `25` when absent. */\n\treadonly maxDepth?: number;\n}\n\n/**\n * Binds a model to a relation store. Connects to nothing.\n *\n * ```ts\n * const access = permissions({ model, store: createMemoryRelations() });\n * await access.grant({ type: 'team', id: 't1' }, 'members', staff);\n * await access.can(staff, 'view', { type: 'record', ...record }, { ctx: { onShift } });\n * ```\n */\nexport function permissions<C extends ModelConfig>(\n\toptions: PermissionsOptions<C>,\n): Permissions<C> {\n\tconst where = 'permissions';\n\tconst model = resolvedOf(options.model);\n\tconst maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;\n\tif (!Number.isInteger(maxDepth) || maxDepth < 1) {\n\t\tthrow new TypeError(`${where}: maxDepth must be a positive integer`);\n\t}\n\tconst raw = options.store as unknown as Record<string, unknown> | undefined;\n\tfor (const method of REQUIRED) {\n\t\tif (typeof raw?.[method] !== 'function') {\n\t\t\tthrow new TypeError(`${where}: store.${method} is missing`);\n\t\t}\n\t}\n\tconst store = guardRelations(options.store);\n\n\tconst bound: BoundModel = { model, store, maxDepth };\n\t// `can` and `list` over what this call bound, as the API takes them.\n\tconst withBoundModel =\n\t\t<A extends unknown[], R>(call: (bound: BoundModel, ...rest: A) => R) =>\n\t\t(...rest: A): R =>\n\t\t\tcall(bound, ...rest);\n\n\tconst change =\n\t\t(operation: 'grant' | 'revoke') =>\n\t\tasync (object: unknown, relation: string, subject: unknown) => {\n\t\t\tconst tuple = tupleOf(model, object, relation, subject, operation);\n\t\t\tawait store.write(\n\t\t\t\toperation === 'grant' ? { add: [tuple] } : { remove: [tuple] },\n\t\t\t);\n\t\t};\n\n\treturn Object.freeze({\n\t\tmodel: options.model,\n\t\tcan: withBoundModel(can) as Permissions<C>['can'],\n\t\tlist: withBoundModel(list) as Permissions<C>['list'],\n\t\tgrant: change('grant') as Permissions<C>['grant'],\n\t\trevoke: change('revoke') as Permissions<C>['revoke'],\n\t\treplace: ((object, relation, subjects) =>\n\t\t\treplace(\n\t\t\t\tmodel,\n\t\t\t\tstore,\n\t\t\t\tobject,\n\t\t\t\trelation as string,\n\t\t\t\tsubjects,\n\t\t\t)) as Permissions<C>['replace'],\n\t});\n}\n",
20
21
  "/** `fromField`: a relation read from the object's own data, and the lookup that reverses it. */\n\n/**\n * The ids of the objects whose field names this subject id — what `list()`\n * needs to reverse a `fromField`: `(doctorId) => db.records.ids({ doctorId })`.\n * Unpaged; a failure throws, as a store's does.\n */\nexport type Lookup = (subjectId: string) => Promise<readonly string[]>;\n\n/**\n * A relation read from the object's own data: `fromField('doctorId', 'staff')`\n * holds for the subject of type `staff` whose id is `object.doctorId`.\n *\n * Nothing is stored. `can()` receives the object — the route has already\n * loaded it — and the compiler requires the field on it. `list()` cannot read\n * a field of objects it has not found yet, so it asks `lookup` instead; a\n * `list()` that would need one it was not given is a compile error.\n */\nexport interface FromField<\n\tField extends string = string,\n\tSubject extends string = string,\n> {\n\treadonly kind: 'fromField';\n\treadonly field: Field;\n\treadonly subject: Subject;\n\treadonly lookup?: Lookup;\n}\n\n/** A `fromField` `list()` can reverse. */\nexport interface ReversibleFromField<\n\tField extends string = string,\n\tSubject extends string = string,\n> extends FromField<Field, Subject> {\n\treadonly lookup: Lookup;\n}\n\nexport function fromField<\n\tconst Field extends string,\n\tconst Subject extends string,\n>(field: Field, subject: Subject): FromField<Field, Subject>;\nexport function fromField<\n\tconst Field extends string,\n\tconst Subject extends string,\n>(\n\tfield: Field,\n\tsubject: Subject,\n\toptions: { readonly lookup: Lookup },\n): ReversibleFromField<Field, Subject>;\nexport function fromField(\n\tfield: string,\n\tsubject: string,\n\toptions?: { readonly lookup: Lookup },\n): FromField {\n\treturn Object.freeze(\n\t\toptions === undefined\n\t\t\t? { kind: 'fromField' as const, field, subject }\n\t\t\t: { kind: 'fromField' as const, field, subject, lookup: options.lookup },\n\t);\n}\n",
21
22
  "/** `when`: a rule under a condition, typed by the `ctx` it tests. */\n\n/**\n * A rule that grants only when `test(ctx)` is true: `when('doctors', (ctx:\n * { onShift: boolean }) => ctx.onShift)`.\n *\n * `rule` is any rule of the same object type — a relation, a permission, an\n * arrow. The test is synchronous and pure: it decides on what the caller\n * passes, and reads nothing, so it can never fail the way a store can.\n */\nexport interface When<Rule extends string = string, Ctx = never> {\n\treadonly kind: 'when';\n\treadonly rule: Rule;\n\treadonly test: (ctx: Ctx) => boolean;\n}\n\nexport function when<const Rule extends string, Ctx>(\n\trule: Rule,\n\ttest: (ctx: Ctx) => boolean,\n): When<Rule, Ctx> {\n\treturn Object.freeze({ kind: 'when', rule, test });\n}\n"
22
23
  ],
23
- "mappings": "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",
24
- "debugId": "1EF03665D47E58A564756E2164756E21",
24
+ "mappings": "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",
25
+ "debugId": "ED4DFF0CF169883A64756E2164756E21",
25
26
  "names": []
26
27
  }
@@ -19,7 +19,19 @@ export declare function objectOf(model: ResolvedModel, value: unknown, where: st
19
19
  * a set when `relation` is given.
20
20
  */
21
21
  export declare function subjectOf(model: ResolvedModel, value: unknown, where: string): Subject;
22
- /** A tuple `grant` or `revoke` may write: a stored relation, and a holder it admits. */
22
+ /**
23
+ * The object and stored relation a write is about: the entity as the store
24
+ * keeps it, and what its relation admits. Refuses a relation read from a field.
25
+ */
26
+ export declare function targetOf(model: ResolvedModel, object: unknown, relation: string, where: string): {
27
+ entity: {
28
+ type: string;
29
+ id: string;
30
+ };
31
+ type: ResolvedObjectType;
32
+ holders: readonly import("./resolve/resolved").Holder[];
33
+ };
34
+ /** A tuple `grant`, `revoke` or `replace` may write: a stored relation, and a holder it admits. */
23
35
  export declare function tupleOf(model: ResolvedModel, object: unknown, relation: string, subject: unknown, where: string): {
24
36
  object: {
25
37
  type: string;
@@ -1 +1 @@
1
- {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/permissions/input.ts"],"names":[],"mappings":"AAAA,mFAAmF;AAGnF,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAEN,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,MAAM,oBAAoB,CAAC;AAQ5B,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOxE;AAED,wBAAgB,MAAM,CACrB,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACX,kBAAkB,CAQpB;AAED,wBAAgB,QAAQ,CACvB,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,GACX;IACF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACjD,CAYA;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACxB,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,GACX,OAAO,CAwBT;AAED,wFAAwF;AACxF,wBAAgB,OAAO,CACtB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM;;;;;;;EAoCb"}
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/permissions/input.ts"],"names":[],"mappings":"AAAA,mFAAmF;AAGnF,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAEN,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,MAAM,oBAAoB,CAAC;AAQ5B,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOxE;AAED,wBAAgB,MAAM,CACrB,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACX,kBAAkB,CAQpB;AAED,wBAAgB,QAAQ,CACvB,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,GACX;IACF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACjD,CAYA;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACxB,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,GACX,OAAO,CAwBT;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CACvB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM;;;;;;;EAyBb;AAED,mGAAmG;AACnG,wBAAgB,OAAO,CACtB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM;;;;;;;EAcb"}
@@ -1,5 +1,5 @@
1
1
  /** What `grant()` and `revoke()` write: the stored relations, and who may hold them. */
2
- import type { NotASet, SetOf } from '../../subjects/subject';
2
+ import type { NotASet, RelationTuple, SetOf } from '../../subjects/subject';
3
3
  import type { ModelConfig } from './config';
4
4
  import type { ObjectTypeOf, RelationDefOf, StoredRelationsOf, TypesOf, UserTypeOf } from './names';
5
5
  /** The relations of an object type that `grant` can write: not its `fromField`s. */
@@ -23,4 +23,17 @@ export type Grant<C extends ModelConfig> = <T extends ObjectTypeOf<C>, R extends
23
23
  readonly type: T;
24
24
  readonly id: string;
25
25
  }, relation: R, subject: HolderOf<C, T, R>) => Promise<void>;
26
+ /**
27
+ * Makes `subjects` the only holders of `relation` on `object`, in one write:
28
+ * typed as {@link Grant}'s `subject`, as an array. Answers the tuples added
29
+ * and removed. Two concurrent calls on the same object and relation are not
30
+ * serialised: the result can hold the union of both adds.
31
+ */
32
+ export type Replace<C extends ModelConfig> = <T extends ObjectTypeOf<C>, R extends GrantableOf<C, T>>(object: {
33
+ readonly type: T;
34
+ readonly id: string;
35
+ }, relation: R, subjects: readonly HolderOf<C, T, R>[]) => Promise<{
36
+ added: RelationTuple[];
37
+ removed: RelationTuple[];
38
+ }>;
26
39
  //# sourceMappingURL=grant.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../../src/permissions/model/grant.ts"],"names":[],"mappings":"AAAA,wFAAwF;AAExF,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EACX,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,OAAO,EACP,UAAU,EACV,MAAM,SAAS,CAAC;AAEjB,oFAAoF;AACpF,MAAM,MAAM,WAAW,CACtB,CAAC,SAAS,WAAW,EACrB,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,IACtB,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAErC;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,IACvE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GACzD,CAAC,SAAS,GAAG,MAAM,OAAO,IAAI,MAAM,WAAW,EAAE,GAChD,OAAO,SAAS,UAAU,CAAC,CAAC,CAAC,GAC5B,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,GAC3B;IACA,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;CAC/B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,GACpD,KAAK,CAAC;AAEV,2DAA2D;AAC3D,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,WAAW,IAAI,CAC1C,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EACzB,CAAC,SAAS,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAE3B,MAAM,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EACjD,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KACtB,OAAO,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../../src/permissions/model/grant.ts"],"names":[],"mappings":"AAAA,wFAAwF;AAExF,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EACX,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,OAAO,EACP,UAAU,EACV,MAAM,SAAS,CAAC;AAEjB,oFAAoF;AACpF,MAAM,MAAM,WAAW,CACtB,CAAC,SAAS,WAAW,EACrB,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,IACtB,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAErC;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,IACvE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GACzD,CAAC,SAAS,GAAG,MAAM,OAAO,IAAI,MAAM,WAAW,EAAE,GAChD,OAAO,SAAS,UAAU,CAAC,CAAC,CAAC,GAC5B,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,GAC3B;IACA,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;CAC/B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,GACpD,KAAK,CAAC;AAEV,2DAA2D;AAC3D,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,WAAW,IAAI,CAC1C,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EACzB,CAAC,SAAS,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAE3B,MAAM,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EACjD,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KACtB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB;;;;;GAKG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,SAAS,WAAW,IAAI,CAC5C,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EACzB,CAAC,SAAS,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAE3B,MAAM,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EACjD,QAAQ,EAAE,CAAC,EACX,QAAQ,EAAE,SAAS,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAClC,OAAO,CAAC;IAAE,KAAK,EAAE,aAAa,EAAE,CAAC;IAAC,OAAO,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC,CAAC"}
@@ -2,7 +2,7 @@
2
2
  import type { Can } from './can';
3
3
  import type { ModelConfig } from './config';
4
4
  import type { PermissionModel } from './define';
5
- import type { Grant } from './grant';
5
+ import type { Grant, Replace } from './grant';
6
6
  import type { List } from './list';
7
7
  /** What `permissions()` answers. */
8
8
  export interface Permissions<C extends ModelConfig> {
@@ -24,5 +24,17 @@ export interface Permissions<C extends ModelConfig> {
24
24
  readonly grant: Grant<C>;
25
25
  /** Removes it. Idempotent: revoking what is not held is not an error. */
26
26
  readonly revoke: Grant<C>;
27
+ /**
28
+ * Makes `subjects` the only holders of `relation` on `object`: adds the
29
+ * missing, removes the others, in one write (none when nothing changes), and
30
+ * answers `{ added, removed }`. `[]` removes every holder; duplicates count
31
+ * once; a subject set is not its entity. Every subject is checked first, as
32
+ * `grant()` checks it, so a refusal writes nothing.
33
+ *
34
+ * **Not serialised**: two concurrent calls on the same object and relation
35
+ * each read, then write their diff, so the result can hold the union of both
36
+ * adds. A caller that needs one winner serialises them itself.
37
+ */
38
+ readonly replace: Replace<C>;
27
39
  }
28
40
  //# sourceMappingURL=permissions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../../src/permissions/model/permissions.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,oCAAoC;AACpC,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,WAAW;IACjD,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;CAC1B"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../../src/permissions/model/permissions.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,oCAAoC;AACpC,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,WAAW;IACjD,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC7B"}
@@ -59,13 +59,19 @@ export interface RelationStore {
59
59
  * The subject sets holding `relation` on `object` — `team:t1#member` — and
60
60
  * no single entity. What the traversal follows to reach members of a group.
61
61
  * `[]` when none; unordered; unpaged, because a relation is held by few sets.
62
+ *
63
+ * **Answer every holder, never cap.** `replace` reads every holder of any
64
+ * relation through this method and `findEntities`, and removes whatever it
65
+ * does not see as wanted: a truncated answer leaves holders it never saw.
62
66
  */
63
67
  findSubjectSets(object: Entity, relation: string): Promise<readonly SubjectSet[]>;
64
68
  /**
65
69
  * The single entities holding `relation` on `object`, and no subject set.
66
70
  * What an arrow follows — a record's team, a folder's parent — which is why
67
- * it is unpaged: an arrow relation holds a handful of objects. `[]` when
68
- * none; unordered.
71
+ * it is unpaged: an arrow relation usually holds a handful of objects, but
72
+ * `replace` reads every holder of any relation through this method and
73
+ * `findSubjectSets`, so an adapter must answer every holder and never cap.
74
+ * `[]` when none; unordered.
69
75
  */
70
76
  findEntities(object: Entity, relation: string): Promise<readonly Entity[]>;
71
77
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/permissions/port/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EACX,MAAM,EACN,aAAa,EACb,OAAO,EACP,UAAU,EACV,MAAM,wBAAwB,CAAC;AAEhC,oDAAoD;AACpD,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C;AAED,sFAAsF;AACtF,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC7B;;;;;;OAMG;IACH,KAAK,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C,4CAA4C;IAC5C,GAAG,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE5C;;;;OAIG;IACH,eAAe,CACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;IAElC;;;;;OAKG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAE3E;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAElE;;;;OAIG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/permissions/port/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EACX,MAAM,EACN,aAAa,EACb,OAAO,EACP,UAAU,EACV,MAAM,wBAAwB,CAAC;AAEhC,oDAAoD;AACpD,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C;AAED,sFAAsF;AACtF,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC7B;;;;;;OAMG;IACH,KAAK,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C,4CAA4C;IAC5C,GAAG,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE5C;;;;;;;;OAQG;IACH,eAAe,CACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;IAElC;;;;;;;OAOG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAE3E;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAElE;;;;OAIG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9C"}
@@ -0,0 +1,25 @@
1
+ /** `replace()`: make the holders of one relation exactly a wanted list. */
2
+ import { type RelationTuple } from '../subjects/subject';
3
+ import type { RelationStore } from './port/types';
4
+ import type { ResolvedModel } from './resolve/resolved';
5
+ /**
6
+ * Makes `subjects` the only holders of `relation` on `object`: the missing
7
+ * ones are added, the others removed, and what is already right is left alone.
8
+ * Answers the tuples added and the tuples removed, as the single `write` held
9
+ * them.
10
+ *
11
+ * Every subject is read first, as `grant` reads it, so a refusal writes
12
+ * nothing. `[]` removes every holder. Duplicates count once, and a subject set
13
+ * is not its entity. The current holders are read, then **one** `write` holds
14
+ * the removals and the additions — all or nothing — and none when both are
15
+ * empty.
16
+ *
17
+ * **Not serialised.** Two concurrent `replace` calls on the same object and
18
+ * relation each read, then write their own diff, so the result can hold the
19
+ * union of both adds. A caller that needs one winner serialises them itself.
20
+ */
21
+ export declare function replace(model: ResolvedModel, store: RelationStore, object: unknown, relation: string, subjects: unknown): Promise<{
22
+ added: RelationTuple[];
23
+ removed: RelationTuple[];
24
+ }>;
25
+ //# sourceMappingURL=replace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replace.d.ts","sourceRoot":"","sources":["../../src/permissions/replace.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAE3E,OAAO,EAEN,KAAK,aAAa,EAElB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAQxD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,OAAO,CAC5B,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC;IACV,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,EAAE,aAAa,EAAE,CAAC;CACzB,CAAC,CA4BD"}
package/docs/README.md CHANGED
@@ -11,7 +11,7 @@ below are defined once, in [Words](guide/vocabulary.md#words).
11
11
 
12
12
  | Page | Read it when |
13
13
  | --- | --- |
14
- | [Users](guide/users.md) | You are wiring `janus()`, declaring one or several user types, or calling `create`, `update`, `list`, `delete` — or finding a user by e-mail on a type with no password (`findByEmail`) |
14
+ | [Users](guide/users.md) | You are wiring `janus()`, declaring one or several user types, or calling `create`, `update`, `list`, `delete` — or finding a user by e-mail on a type with no password (`findByEmail`), or finding or creating one in a single call (`findOrCreate`) |
15
15
  | [Sessions](guide/sessions.md) | You need to know who a request belongs to, set or clear the cookie, renew, sign out, or test expiry — or sign in a user your application proved itself, such as on accepting an invitation (`signInProven`) |
16
16
  | [E-mail verification, password reset and changing an e-mail](guide/email-flows.md) | You are sending a verification, reset or e-mail-change link (`changeEmail`), and handling what comes back — or proving an address on your own proof, such as an invitation (`verifyEmail.proveFirst`) — and how requests that send e-mail are throttled per address or user |
17
17
  | [Signing in with an e-mailed link](guide/magic-link.md) | You are signing users in with a link sent by e-mail — a magic link: the page that confirms it from a `POST` so mail scanners spend nothing, the lifetime, the errors, and what ends a link |
@@ -26,7 +26,7 @@ below are defined once, in [Words](guide/vocabulary.md#words).
26
26
 
27
27
  | Page | Read it when |
28
28
  | --- | --- |
29
- | [Permissions](guide/permissions.md) | You are modelling access with `defineModel`, `fromField` and `when`, and calling `can`, `list`, `grant`, `revoke` |
29
+ | [Permissions](guide/permissions.md) | You are modelling access with `defineModel`, `fromField` and `when`, and calling `can`, `list`, `grant`, `revoke`, `replace` |
30
30
 
31
31
  ### Shared by both sides
32
32