attenu-guard 0.13.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/dist/cjs/authority.d.ts +12 -6
- package/dist/cjs/authority.d.ts.map +1 -1
- package/dist/cjs/authority.js +51 -15
- package/dist/cjs/authority.js.map +1 -1
- package/dist/cjs/ceilings.d.ts +58 -13
- package/dist/cjs/ceilings.d.ts.map +1 -1
- package/dist/cjs/ceilings.js +392 -70
- package/dist/cjs/ceilings.js.map +1 -1
- package/dist/cjs/display.d.ts +3 -2
- package/dist/cjs/display.d.ts.map +1 -1
- package/dist/cjs/display.js +4 -3
- package/dist/cjs/display.js.map +1 -1
- package/dist/cjs/evidence.js +1 -1
- package/dist/cjs/evidence.js.map +1 -1
- package/dist/cjs/guard.d.ts.map +1 -1
- package/dist/cjs/guard.js +7 -3
- package/dist/cjs/guard.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wire.d.ts.map +1 -1
- package/dist/cjs/wire.js +3 -2
- package/dist/cjs/wire.js.map +1 -1
- package/dist/esm/authority.d.ts +12 -6
- package/dist/esm/authority.d.ts.map +1 -1
- package/dist/esm/authority.js +51 -15
- package/dist/esm/authority.js.map +1 -1
- package/dist/esm/ceilings.d.ts +58 -13
- package/dist/esm/ceilings.d.ts.map +1 -1
- package/dist/esm/ceilings.js +390 -70
- package/dist/esm/ceilings.js.map +1 -1
- package/dist/esm/display.d.ts +3 -2
- package/dist/esm/display.d.ts.map +1 -1
- package/dist/esm/display.js +4 -3
- package/dist/esm/display.js.map +1 -1
- package/dist/esm/evidence.js +2 -2
- package/dist/esm/evidence.js.map +1 -1
- package/dist/esm/guard.d.ts.map +1 -1
- package/dist/esm/guard.js +8 -4
- package/dist/esm/guard.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/wire.d.ts.map +1 -1
- package/dist/esm/wire.js +3 -2
- package/dist/esm/wire.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,45 @@ Versions follow semantic versioning.
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.13.1] - 2026-10-05
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- **A constraint bound of the wrong type is malformed, so a token that carried one and verified before is now refused.** A `max` that is not a number (a boolean, a string, null, an array, an object, or no `max` at all), a `prefix` that is not a string, an egress `rank` other than `none`, `internal` or `any`, and a `field` or `applies_to` that is not a string are refused when the ceiling is built, with a TypeError `<member> of constraint <key> is <kind>, not <expected>`: `max of constraint 'max_rows' is a boolean, not a number`, `prefix of constraint 'path' is a number, not a string`, `rank of constraint 'egress' is 'everywhere', not 'none', 'internal' or 'any'`, `field of constraint 'region' is a number, not a string`. null leaves `field` and `applies_to` unset in-process and `field` unset on the wire; a wire `applies_to: null` is refused, as before, as a member this build does not read. So a token carrying one is refused as `malformed`, a bundle reports `unreadable_authority` or `unreadable_granted` with that text, and `new RowLimit("5")` or `new EgressRank("external")` throws. Every release from 0.1.0 through 0.13.0 accepted them: `max: true` read as 1, `max: "5"` was coerced, an unknown rank ranked above `any` and so admitted every request, `prefix: 5` matched as the text `5`, and `field: 5` read `ctx["5"]`. The draft defines `max` as a number and `prefix` as a string. The Python implementation raises ValueError with the same text
|
|
13
|
+
- **A constraint's `key` must be a string, so a token whose constraint had none, or a key of another type, is now refused.** A constraint of any type, an unknown type included, is refused when it is read, with a TypeError `key of a constraint is <absent|null|a number|a boolean|an array|an object>, not a string`, so a token is refused as `malformed` and a bundle reports `unreadable_authority` or `unreadable_granted`; `Allow`, `Deny` and `Prefix` throw it in-process too. Through 0.13.0, an allow-list, a deny-list or a prefix with no key loaded and read the context field `"undefined"`, so it bounded nothing; a key of 5, null or `true` was read as `String(key)`, so 5 and `"5"` were one dimension and one of two such constraints was dropped, where the Python implementation read a field no JSON context carries. Measured on the 0.13.0 package; the code is the same at every tag from 0.1.1. The draft makes `key` REQUIRED. The Python implementation raises ValueError with the same text
|
|
14
|
+
- **A constraint must be a JSON object, and its `type`, when present, a string, so a token carrying another value is now refused.** A constraint that is not an object is refused with a TypeError `a constraint is <a string|a number|a boolean|null|an array>, not an object`, and a `type` that is not a string with `type of constraint 'max_rows' is <null|a number|a boolean|an array|an object>, not a string`, the Python implementation's words; a token is refused as `malformed`, and a bundle reports `unreadable_authority` or `unreadable_granted`. Through 0.13.0, a constraint that is not an object loaded as an unknown constraint, which denies every action, except null, which threw a TypeError in JavaScript's words; a `type` that is a number, a boolean, a list or an object loaded as an unknown constraint; and a null `type` was read as absent, so the constraint was routed by its key: `{"key": "allow", "type": null, "one_of": ["us"]}` loaded as an allow-list, where the Python implementation loaded an unknown constraint, and `{"key": "max_rows", "type": null, "max": 5}` was refused as a member this build does not read. Measured on the 0.13.0 package; the code is the same at every tag from 0.1.1
|
|
15
|
+
- **An absent `one_of` or `not_one_of` is malformed.** Through 0.13.0, `{"key": "tool", "type": "deny"}` read as an empty deny-list and bounded nothing (measured on the 0.13.0 package; the code is the same at every tag from 0.1.1). It is now refused like a list of the wrong type, `not_one_of of constraint 'tool' is absent, not an array`. A constraint this build writes always carries its list
|
|
16
|
+
- **A scoped call limit's `applies_to` must be a scope.** It follows the scope grammar, an exact scope or a terminal `.*` wildcard, and any other string is refused: `applies_to of constraint 'max_calls' is '*', not a scope`. Through 0.13.0, `new CallLimit(1, "*")`, `"crm"` or `"CRM.READ"` applied to no call, so the limit bounded nothing (measured on the 0.13.0 package; the code is the same at every tag from 0.1.1)
|
|
17
|
+
- **A verifier finding prints every string member of an allow-list or a deny-list in its escaped JSON form, quoted.** `ceiling t in [1] looser than parent t in ["1"]`, where both lists printed `[1]`. That is the display rule 0.13.0 applied to a member that needs escapes, applied to every string member, so the text is ASCII and the same as the Python implementation's on every Python version: `["S\u00e3o\u0020Paulo", "us"]` where 0.13.0 printed `["S\u00e3o\u0020Paulo", us]`. A number, a boolean and null print bare, as before. `describe()` is unchanged
|
|
18
|
+
- **Two constraints under one key in one authority are malformed.** `Authority` throws a TypeError `two constraints share the key 'region'; an authority holds one per key`, in-process and on the wire, so a token carrying two is refused as `malformed` and a bundle reports `unreadable_authority` or `unreadable_granted`. Through 0.13.0 the last one won, silently: `[allow region in [us], deny region not in [rm]]` kept only the deny-list and permitted `region: eu` (measured on the 0.13.0 package). The Python implementation raises ValueError with the same text
|
|
19
|
+
- **`Allow.oneOf` and `Deny.notOneOf` are read-only at runtime.** Both were typed `ReadonlySet` and held a `Set`; each is now a read-only set whose `add`, `delete` and `clear` throw a TypeError, and which is not an `instanceof Set`, as the Python implementation's member set has no mutators. `has`, `size`, iteration, `forEach`, `keys`, `values` and `entries` work as before. The wire order of a member set is computed once, so a member added through a cast after the first `toWire()` would have been checked by `permits()` and missing from the wire
|
|
20
|
+
- **A token refused for a malformed constraint carries the error's text alone.** `invalid authorization_details: TypeError: max of constraint 'max_rows' is a boolean, not a number` is now `invalid authorization_details: max of constraint 'max_rows' is a boolean, not a number`, the Python implementation's message, and the same for an `AuthorityError`
|
|
21
|
+
- **`Ceiling.permits`, called directly, reads only the context's own fields.** `new RowLimit(5).permits(Object.create({ rows: 500 }))`, or a context whose `rows` is a getter on its prototype, was refused by 0.13.0 and is permitted now: an inherited field is not the context's, so it asserts nothing. `Authority.permits`, `Guard.check`, `VerifiedChain.permits` and `verifyBundle` already read only own fields in 0.13.0, through `{...context}`, so they are unchanged
|
|
22
|
+
- **A bundle that verified under an earlier release can now fail re-verification.** Evidence recorded by 0.1.0 through 0.13.0 fails where the earlier check was wrong: an allow whose context held a value a ceiling coerced, such as `rows: "50"` under a row cap, `tool: ["rm"]` under a deny-list, or `path: ["/tmp/x"]` or `flag: true` under a prefix, fails containment, and so does an allow whose context carried a `_scope` that moved the call off its meter. A bundle the Python implementation recorded through 0.19.0 fails the same way, with `rows: true` under a row cap or `tier: true` under `one_of: [1]`. A Python delegation whose meet widened across `true` and 1, in either direction, failed monotonicity here already, and now fails it there too
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- **A deny-list let through a request value it could not compare.** `not_one_of: ["rm"]` permitted `tool: ["rm"]`, and any other array or object, in every release from 0.1.0 through 0.13.0: measured on the 0.1.0, 0.1.1, 0.5.0, 0.6.0, 0.7.0, 0.9.0, 0.12.0 and 0.13.0 packages, and the `Allow` and `Deny` checks are the same at every tag in between. A Set compares an array or an object by identity, so no request value ever equals a member: an allow-list refused one as a non-member, and a deny-list waved it through. Both lists now refuse a request value that is not a string, a number, a boolean or null, as `ceiling_exceeded` with the message `an array cannot be compared with not_one_of members; refused` (or `an object`, or `a value that is not JSON`; `one_of` for an allow-list). The rule is in `permits`, so it holds in `Guard.check`, in `VerifiedChain.permits` after `load()`, and in `verifyBundle`'s containment check. The Python implementation's change for attenu-ops#110 has the same rule, reason and message
|
|
26
|
+
- **A number read with this library's `parseJson` passed a deny-list.** `parseJson` returns every number as a `RawNumber`, which no Set member equals, so `not_one_of: [1]` permitted a context `{"tier": 1}` read with `parseJson`, in `Ceiling.permits` and in `Guard.check`, and `one_of: [1]` refused it. Measured on the 0.13.0 package; the check is the same at every tag from 0.1.1. A `RawNumber` now counts as the number it holds in every ceiling's type check, in a context, a bound or a member
|
|
27
|
+
- **`Allow` and `Deny` read a context field named like an `Object.prototype` member from the prototype.** On a plain object `ctx["constructor"]` is Object's constructor, so `Allow("constructor", …)` refused a context that did not hold that field, where the Python implementation reads the field as absent and permits. Both now read only the context's own fields, so an absent field asserts nothing, whatever its name
|
|
28
|
+
- **Different ceiling types under one key threw a TypeError, or delegated by a guess.** A child whose ceiling under a key is of another class than its parent's, such as a deny-list where the parent holds an allow-list, threw a TypeError (`undefined is not iterable`) out of `isNarrowerThan`, so out of `load()` and out of `verifyBundle`; a delegation across the two threw out of `meet` with nothing on the ledger; one that asked for a prefix under a parent's egress rank was granted the parent's rank, the request dropped; and one that asked for a constraint this build does not define under a parent's row cap failed the chain's own check, `attenuation invariant violated`. Measured on the 0.13.0 package; the `subsumes` and `narrow` code is the same at every tag from 0.1.1. Two different known types under one key are not comparable now: such a child is not narrower, so `load()` reports `not_narrower` and a bundle a monotonicity finding, and `Authority.meet` throws an AuthorityError `constraint 'region' has a different ceiling type on each side; neither narrows the other` with the reason `not_narrower`, so `Guard.delegate` records the refused delegation as `spawn_denied`, with that reason and the detail `{"constraint": "region"}`, and throws it. A constraint this build does not define is the one exception, in one direction: from a parent holding one, the child inherits it, as 0.13.0 did, since it denies every action. A request carrying one under a parent's other ceiling is refused like any other pair, as not narrower with a `spawn_denied` entry. 0.13.0 did one of three things there, by the parent's ceiling: under an allow-list, a deny-list or a prefix it threw a TypeError with nothing on the ledger; under an egress rank it delegated, granting the parent's rank and dropping the requested constraint; and under a numeric cap it recorded `spawn_denied` with the reason `integrity`; and a child holding one under a parent's other ceiling is not narrower, in `isNarrowerThan`, `load()` and a bundle's monotonicity check, as 0.13.0 found for a numeric cap, where an allow-list threw. The same in the Python implementation, whose `meet` raises the same AuthorityError
|
|
29
|
+
- **A custom ceiling could let a wider child of another class pass as narrower.** `isNarrowerThan` handed the parent's ceiling the child's ceiling under the same key whatever its class, so a custom ceiling whose `subsumes()` accepts any ceiling, as one written for its own class may, let a child holding a wider allow-list pass as narrower: in-process, and for a registered type in `load()` and in a bundle's monotonicity check. Measured on the 0.13.0 package. The relation checks the class first now, so such a child is not narrower
|
|
30
|
+
- **A custom ceiling's denial without a reason let the call through.** `Authority.permits` allowed a call whenever it had collected no reason, so a custom ceiling returning `Decision.deny([])` was allowed by `Guard.check` and by `VerifiedChain.permits`, and passed `verifyBundle`'s containment check (measured on the 0.13.0 package). Such a denial denies now in all three, with the reason `ceiling_exceeded`, the ceiling's key and the message `denied without a reason`, the same in the Python implementation. An archived bundle that recorded allows under such a ceiling, and verified before with the ceiling registered, now fails containment
|
|
31
|
+
- **A constraint member named like an `Object.prototype` member was ignored.** The check that refuses a constraint carrying a member this build does not read asked `k in emitted`, which is true for `constructor`, `toString`, `valueOf`, `__proto__` and the rest on every plain object, so `{"key": "max_rows", "max": 5, "constructor": 1}` loaded as `max_rows<=5` (measured on the 0.13.0 package), where the Python implementation refuses it. It reads the emitted constraint's own members now, so the token is refused as `malformed`, in the Python implementation's words
|
|
32
|
+
- **A null quantity passed a metered call.** Under strict metering, `{rows: null}` counted as a declared quantity, though every ceiling reads null as absent; and a context's `calls: null` replaced the guard's own call count, so it passed `new CallLimit(1)` any number of times. Measured on the 0.13.0 package; the check is the same at every tag from 0.1.1. A null quantity is now undeclared: strict metering refuses the call as `unmetered`, and the guard counts a call whose `calls` is null itself. Strict metering reads only the context's own fields, as the ceilings do. An explicit numeric count still wins: the declared-quantity limit the Python implementation's `docs/RED-TEAM.md` describes
|
|
33
|
+
- **Equal member sets re-emitted different bytes.** Members that print alike, such as `"1"` and 1, `"True"` and `true`, or `"None"` and null, kept the order they arrived in, so `one_of: ["1", 1]` re-emitted `["1",1]` and `one_of: [1, "1"]` re-emitted `[1,"1"]`. Measured on the 0.13.0 package; the sort is the same at every tag from 0.1.1. They are ordered by JSON type now, null, boolean, number, then string, the same in the Python implementation
|
|
34
|
+
- **A `one_of` or `not_one_of` that is not an array was read anyway.** null became the empty list and a string its characters, so `not_one_of: null` was an empty deny-list and `one_of: "us"` the allow-list `["s", "u"]`, and a token or a bundle carrying one verified; an object, a number or a boolean threw a TypeError in its own words. Measured on the 0.1.0, 0.1.1, 0.5.0, 0.6.0, 0.7.0, 0.9.0, 0.12.0 and 0.13.0 packages. Each is now malformed, as the draft defines both as an array: `Allow` and `Deny` throw a TypeError naming the list and the key, such as `one_of of constraint 'region' is an object, not an array` (or `null`, `a string`, `a number`, `a boolean`), so a token carrying one is refused as `malformed` and a bundle reports `unreadable_authority` or `unreadable_granted` with that text. The Python implementation raises ValueError with the same text
|
|
35
|
+
- **Unknown constraints were compared as JSON text with only the top-level keys sorted.** Two constraints equal as JSON differed when a nested object listed its keys in another order, so a bundle whose child repeated its parent's unknown constraint with a nested object's keys reordered failed monotonicity, in every release from 0.1.0 through 0.13.0. (A token cannot carry such a reorder: its RFC 8785 bytes sort every level.) An unknown constraint now subsumes only one with the same RFC 8785 bytes: `true` is not 1, `1.0` is 1, and key order is no difference at any depth. A value this build cannot write in RFC 8785, such as an integer past 2^53, is identical to nothing. The Python implementation compares the same way, except for an integral float past 2^53 (see Known differences)
|
|
36
|
+
- **A ceiling coerced a request value of the wrong JSON type.** `<=` let `"50"`, `[50]` and `true` pass a row cap, and every other numeric cap, and `String()` let `["/tmp/x"]` pass the prefix `"/tmp/"` as the text `/tmp/x` and `true` pass the prefix `"t"` as `true`, in every release from 0.1.0 through 0.13.0: measured on the 0.1.0, 0.1.1, 0.5.0, 0.6.0, 0.7.0, 0.9.0, 0.12.0 and 0.13.0 packages, and the five checks are the same at every tag in between. Every built-in ceiling now refuses a request value of the wrong type as `ceiling_exceeded` and never coerces it: a numeric cap takes a number, a prefix and an egress rank take a string, and an allow-list or a deny-list takes a string, a number or a boolean. The message names the value's JSON type and what it could not be compared with: `a string cannot be compared with a maximum; refused`, `an array cannot be compared with a prefix; refused`, `a boolean cannot be compared with an egress rank; refused`, and the membership messages above, in the Python implementation's words. null and an absent field still assert nothing, and every ceiling reads only the context's own fields, so a prefix on a field named `constructor` no longer refuses a context that does not hold one. The Python implementation now refuses such a value too, where it raised, so an allow whose context holds `{"rows": "many"}` fails containment in both
|
|
37
|
+
- **A request context could choose which scoped call limit applied.** `Authority.permits` set the reserved `_scope` only when the context did not carry one, so a context's own `_scope` decided which scoped `CallLimit` applied: after `new CallLimit(1, "crm.read")` had refused a second call, a third carrying `_scope: "other.x"` was allowed, and a call could be charged to another scope's limit instead, in every release from 0.1.0 through 0.13.0. `_scope` is now always the scope being checked, and a context's value is ignored, in `Guard.check`, `VerifiedChain.permits` and `verifyBundle`'s containment check. A `calls` count supplied in the context still wins over the guard's own count: the declared-quantity limit the Python implementation's `docs/RED-TEAM.md` describes
|
|
38
|
+
- **An unknown constraint described itself and denied in other words than the Python implementation.** `describe()` printed it as JSON text, `quota={"key":"quota","type":"x-unknown","max":1}`, and its denial read `unrecognised constraint type for key="quota"; fail-closed`, in every release from 0.1.0 through 0.13.0, so the deny entry a Guard writes for the same call was different bytes from the two implementations. Both now print it as the Python implementation does, `quota={'key': 'quota', 'type': 'x-unknown', 'max': 1}` and `unrecognised constraint type for key='quota'; fail-closed`, except where Known differences says otherwise. A key that is not a string, which the reason's `constraint` recorded as text, is now malformed (see Changed)
|
|
39
|
+
- **A number with a fraction printed in JavaScript's form where the Python implementation prints its repr.** A message quoting a constraint this build refuses read `'min': 0.00001` in 0.13.0, where the Python implementation reads `'min': 1e-05`. A number that has lost its literal now prints as Python's repr of the float, there and in an unknown constraint's `describe()`; an integral one still prints as an integer (see Known differences)
|
|
40
|
+
|
|
41
|
+
### Known differences
|
|
42
|
+
- A ceiling bound or an unknown constraint value written as an integral number with a fraction or an exponent, such as `100.0` or `1e5`, prints as an integer here, in `describe()` and in a verifier finding (`max_rows<=100`, `100000`), and as a float in the Python implementation (`100.0`, `100000.0`). This build reads the number before it prints it. A bound written as `-0` prints as `-0.0` here and as `0` there. Verdicts and hashes are the same: RFC 8785 writes both as `100`, and both as `0`
|
|
43
|
+
- A list or an object as a `one_of` or `not_one_of` member is accepted here and compared by object identity, so no request value matches it, and a child that repeats it is not narrower than the parent holding it; a lone root token carrying one verifies. The Python implementation refuses it: as `malformed` in a token, and as `unreadable_authority` or `unreadable_granted` in a bundle
|
|
44
|
+
- An unknown constraint holding an integral float at or past 2^53, such as `v: 1e16`, is identical to nothing here, since this build cannot write that number in RFC 8785, so a child that repeats its parent's constraint is not narrower. The Python implementation writes such a float, and there the two subsume each other
|
|
45
|
+
- An unknown constraint whose object has member names that look like integers, such as `"10"` and `"2"`, prints with those members first, in ascending numeric order, in `describe()` and in a verifier finding, since a JavaScript object orders such names that way. The Python implementation prints its members in wire order
|
|
46
|
+
- Whether a character prints as itself or as an escape in a Python-style `repr` follows each runtime's Unicode tables, and the Python implementation's varies across Python versions too. That reaches a message that quotes a key or a constraint through `repr`, such as `type of constraint '<key>' is null, not a string`, and an unknown constraint's `describe()`. A character only the newer table defines prints as itself in one and escaped in the other: U+1CCFA, which Unicode 17 assigns, prints as itself here on Node 22.22 (Unicode 17) and as `\U0001ccfa` in the Python implementation on Python 3.14 (Unicode 16). The members of an allow-list or a deny-list in a finding are ASCII, so they do not vary
|
|
47
|
+
|
|
9
48
|
## [0.13.0] - 2026-10-05
|
|
10
49
|
|
|
11
50
|
### Added
|
package/dist/cjs/authority.d.ts
CHANGED
|
@@ -58,10 +58,10 @@ export declare class Authority {
|
|
|
58
58
|
*/
|
|
59
59
|
readonly scopes: ReadonlySet<string>;
|
|
60
60
|
/**
|
|
61
|
-
*
|
|
62
|
-
* deterministic wire form and integrity seal. A dimension
|
|
63
|
-
* unbounded on that dimension unless a parent in the chain
|
|
64
|
-
* attenuation can only add or tighten bounds, never remove one.
|
|
61
|
+
* One ceiling per `key` (a second one under the same key throws a TypeError),
|
|
62
|
+
* sorted by key for a deterministic wire form and integrity seal. A dimension
|
|
63
|
+
* with no ceiling is unbounded on that dimension unless a parent in the chain
|
|
64
|
+
* bounds it — attenuation can only add or tighten bounds, never remove one.
|
|
65
65
|
*/
|
|
66
66
|
readonly ceilings: readonly Ceiling[];
|
|
67
67
|
/** Seconds from issuance. `null` is unbounded (discouraged). */
|
|
@@ -75,8 +75,14 @@ export declare class Authority {
|
|
|
75
75
|
coversScope(requested: string): boolean;
|
|
76
76
|
/**
|
|
77
77
|
* The greatest authority within BOTH `this` and `other` — the attenuation.
|
|
78
|
-
* This is the only way a child authority is constructed
|
|
79
|
-
* and can only ever shrink
|
|
78
|
+
* This is the only way a child authority is constructed, with `this` the
|
|
79
|
+
* parent and `other` the request. It is commutative and can only ever shrink
|
|
80
|
+
* relative to either input, except in one case, by design (attenu-ops#110):
|
|
81
|
+
* a constraint this build does not define on the parent's side passes down,
|
|
82
|
+
* so the child inherits it, and it denies every action; one in the request
|
|
83
|
+
* under a parent's ceiling of another type is refused with an AuthorityError
|
|
84
|
+
* (reason `not_narrower`), as two different ceiling types under one key are.
|
|
85
|
+
* So `parent.meet(request)` and `request.meet(parent)` differ there.
|
|
80
86
|
*/
|
|
81
87
|
meet(other: Authority): Authority;
|
|
82
88
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authority.d.ts","sourceRoot":"","sources":["../../src/authority.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAA6C,KAAK,KAAK,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAElG,OAAO,
|
|
1
|
+
{"version":3,"file":"authority.d.ts","sourceRoot":"","sources":["../../src/authority.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAA6C,KAAK,KAAK,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAElG,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,OAAO,EACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAsB,MAAM,cAAc,CAAC;AAE5D;;;;;;;GAOG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAM;CAM/E;AAqFD,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7B,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;IACpC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAGnB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;CACtB;AAWD,qBAAa,SAAS;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAErC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAEtC,gEAAgE;IAChE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;gBAEhB,IAAI,GAAE,aAAkB;IAmBpC,OAAO,CAAC,KAAK;IAMb,kDAAkD;IAClD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAMzC,4EAA4E;IAC5E,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAM5D,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IASvC;;;;;;;;;;OAUG;IACH,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS;IAuDjC;;;;;;;;;;;;;;;OAeG;IACH,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;IAoBzC;;;;;;;;OAQG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,OAAO,GAAG,IAAW,GAAG,QAAQ;IAgC5D,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS;IAM/B,MAAM,IAAI,aAAa;IAQvB,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS;IAiCvC,0CAA0C;IAC1C,QAAQ,IAAI,MAAM;IAMlB,QAAQ,IAAI,MAAM;CAGnB"}
|
package/dist/cjs/authority.js
CHANGED
|
@@ -100,7 +100,10 @@ function ceilingFromWireWhole(c) {
|
|
|
100
100
|
"than silently changing which dimension is bounded", "malformed_constraint");
|
|
101
101
|
}
|
|
102
102
|
const dropped = Object.keys(input)
|
|
103
|
-
|
|
103
|
+
// The emission's OWN members: `k in emitted` found `constructor`, `toString` and the rest of
|
|
104
|
+
// Object.prototype on every plain object, so a member named like one was ignored, where the
|
|
105
|
+
// Python implementation refuses it (attenu-ops#110).
|
|
106
|
+
.filter((k) => !Object.prototype.hasOwnProperty.call(emitted, k))
|
|
104
107
|
// `field` is read and then not re-emitted when it equals `key`, because at
|
|
105
108
|
// that point it is redundant. Absent from the emission does not mean
|
|
106
109
|
// unread, so exempt it only on EVIDENCE that this ceiling parsed it: the
|
|
@@ -118,9 +121,8 @@ function ceilingFromWireWhole(c) {
|
|
|
118
121
|
}
|
|
119
122
|
return ceiling;
|
|
120
123
|
}
|
|
121
|
-
const SCOPE_RE = /^[a-z][a-z0-9_-]*(?:\.[a-z][a-z0-9_-]*)*\.(?:[a-z][a-z0-9_-]*|\*)$/;
|
|
122
124
|
function validateScope(scope) {
|
|
123
|
-
if (typeof scope !== "string" || !SCOPE_RE.test(scope)) {
|
|
125
|
+
if (typeof scope !== "string" || !ceilings_js_1.SCOPE_RE.test(scope)) {
|
|
124
126
|
throw new TypeError(`invalid scope ${(0, display_js_1.pyRepr)((scope ?? null))}: expected lowercase dot-separated segments; ` +
|
|
125
127
|
"'*' is permitted only as the complete final segment after a dot");
|
|
126
128
|
}
|
|
@@ -135,10 +137,10 @@ class Authority {
|
|
|
135
137
|
*/
|
|
136
138
|
scopes;
|
|
137
139
|
/**
|
|
138
|
-
*
|
|
139
|
-
* deterministic wire form and integrity seal. A dimension
|
|
140
|
-
* unbounded on that dimension unless a parent in the chain
|
|
141
|
-
* attenuation can only add or tighten bounds, never remove one.
|
|
140
|
+
* One ceiling per `key` (a second one under the same key throws a TypeError),
|
|
141
|
+
* sorted by key for a deterministic wire form and integrity seal. A dimension
|
|
142
|
+
* with no ceiling is unbounded on that dimension unless a parent in the chain
|
|
143
|
+
* bounds it — attenuation can only add or tighten bounds, never remove one.
|
|
142
144
|
*/
|
|
143
145
|
ceilings;
|
|
144
146
|
/** Seconds from issuance. `null` is unbounded (discouraged). */
|
|
@@ -149,8 +151,14 @@ class Authority {
|
|
|
149
151
|
validateScope(scope);
|
|
150
152
|
this.scopes = scopes;
|
|
151
153
|
const byKey = new Map();
|
|
152
|
-
for (const c of init.ceilings ?? [])
|
|
154
|
+
for (const c of init.ceilings ?? []) {
|
|
155
|
+
// One constraint per key, on every path (attenu-ops#110): the last one won, silently, so
|
|
156
|
+
// [allow region in [us], deny region not in [rm]] kept only the deny-list.
|
|
157
|
+
if (byKey.has(String(c.key))) {
|
|
158
|
+
throw new TypeError(`two constraints share the key ${(0, display_js_1.pyRepr)(c.key)}; an authority holds one per key`);
|
|
159
|
+
}
|
|
153
160
|
byKey.set(String(c.key), c);
|
|
161
|
+
}
|
|
154
162
|
this.ceilings = Array.from(byKey.keys())
|
|
155
163
|
.sort(canonical_js_1.compareCodePoints)
|
|
156
164
|
.map((k) => byKey.get(k));
|
|
@@ -185,8 +193,14 @@ class Authority {
|
|
|
185
193
|
// ---- the lattice ------------------------------------------------------
|
|
186
194
|
/**
|
|
187
195
|
* The greatest authority within BOTH `this` and `other` — the attenuation.
|
|
188
|
-
* This is the only way a child authority is constructed
|
|
189
|
-
* and can only ever shrink
|
|
196
|
+
* This is the only way a child authority is constructed, with `this` the
|
|
197
|
+
* parent and `other` the request. It is commutative and can only ever shrink
|
|
198
|
+
* relative to either input, except in one case, by design (attenu-ops#110):
|
|
199
|
+
* a constraint this build does not define on the parent's side passes down,
|
|
200
|
+
* so the child inherits it, and it denies every action; one in the request
|
|
201
|
+
* under a parent's ceiling of another type is refused with an AuthorityError
|
|
202
|
+
* (reason `not_narrower`), as two different ceiling types under one key are.
|
|
203
|
+
* So `parent.meet(request)` and `request.meet(parent)` differ there.
|
|
190
204
|
*/
|
|
191
205
|
meet(other) {
|
|
192
206
|
// Scopes: keep a requested scope only if this side covers it, and keep this
|
|
@@ -215,6 +229,19 @@ class Authority {
|
|
|
215
229
|
for (const k of keys) {
|
|
216
230
|
const a = mine.get(k);
|
|
217
231
|
const b = theirs.get(k);
|
|
232
|
+
if (a !== undefined && b !== undefined && !(0, ceilings_js_1.sameType)(a, b)) {
|
|
233
|
+
// Two ceiling types under one key have no common narrowing, so the delegation is refused
|
|
234
|
+
// as not narrower, and `Guard.delegate` records it as `spawn_denied` (attenu-ops#110). One
|
|
235
|
+
// exception: this side's constraint this build does not define, which denies every action,
|
|
236
|
+
// is kept, so the child inherits it, as 0.13.0 delegated from a parent holding one. A
|
|
237
|
+
// request carrying one under this side's other ceiling is refused: the child would not be
|
|
238
|
+
// narrower (`isNarrowerThan`).
|
|
239
|
+
if (a instanceof ceilings_js_1.UnknownCeiling) {
|
|
240
|
+
ceilings.push(a);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
throw new AuthorityError(`constraint ${(0, display_js_1.pyRepr)(k)} has a different ceiling type on each side; neither narrows the other`, "not_narrower", { constraint: k });
|
|
244
|
+
}
|
|
218
245
|
ceilings.push(a !== undefined && b !== undefined ? a.narrow(b) : (a ?? b));
|
|
219
246
|
}
|
|
220
247
|
const ttls = [this.ttl, other.ttl].filter((t) => t !== null);
|
|
@@ -247,7 +274,9 @@ class Authority {
|
|
|
247
274
|
const selfCeiling = mine.get(k);
|
|
248
275
|
if (selfCeiling === undefined)
|
|
249
276
|
return false; // unbounded here where other bounds
|
|
250
|
-
|
|
277
|
+
// Two ceiling types under one key are not comparable, so not narrower (a custom ceiling's
|
|
278
|
+
// subsumes() need not handle another type).
|
|
279
|
+
if (!(0, ceilings_js_1.sameType)(selfCeiling, otherCeiling) || !otherCeiling.subsumes(selfCeiling))
|
|
251
280
|
return false;
|
|
252
281
|
}
|
|
253
282
|
if (other.ttl !== null) {
|
|
@@ -277,14 +306,21 @@ class Authority {
|
|
|
277
306
|
.join(", ")}]`,
|
|
278
307
|
}));
|
|
279
308
|
}
|
|
280
|
-
// Reserved key so scoped ceilings can tell whether they apply.
|
|
309
|
+
// Reserved key so scoped ceilings can tell whether they apply. Always the scope being checked: a
|
|
310
|
+
// `_scope` in the caller's context is ignored, so it can move no call off its own meter or onto
|
|
311
|
+
// another (attenu-ops#110).
|
|
281
312
|
const cctx = { ...context };
|
|
282
|
-
|
|
283
|
-
cctx["_scope"] = scope;
|
|
313
|
+
cctx["_scope"] = scope;
|
|
284
314
|
for (const c of this.ceilings) {
|
|
285
315
|
const decision = c.permits(cctx);
|
|
286
|
-
if (
|
|
316
|
+
if (decision.allowed)
|
|
317
|
+
continue;
|
|
318
|
+
// A denial with no reason still denies: an empty list read as an allow, so a custom ceiling's
|
|
319
|
+
// bare `Decision.deny([])` let every call through (attenu-ops#110).
|
|
320
|
+
if (decision.reasons.length > 0)
|
|
287
321
|
reasons.push(...decision.reasons);
|
|
322
|
+
else
|
|
323
|
+
reasons.push(new reasons_js_1.Reason(reasons_js_1.ReasonCode.CEILING_EXCEEDED, { constraint: c.key, message: "denied without a reason" }));
|
|
288
324
|
}
|
|
289
325
|
return reasons.length > 0 ? reasons_js_1.Decision.deny(reasons) : reasons_js_1.Decision.allow();
|
|
290
326
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authority.js","sourceRoot":"","sources":["../../src/authority.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAEH,iDAAkG;AAClG,6CAAiD;AACjD,+
|
|
1
|
+
{"version":3,"file":"authority.js","sourceRoot":"","sources":["../../src/authority.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/ceilings.d.ts
CHANGED
|
@@ -16,6 +16,12 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { type CJson, type Json } from "./canonical.js";
|
|
18
18
|
import { Decision } from "./reasons.js";
|
|
19
|
+
/**
|
|
20
|
+
* The scope grammar the draft defines: lowercase dot-separated segments, `*` only as the whole last
|
|
21
|
+
* segment. `Authority` validates its scopes against it, and a scoped `CallLimit`'s `appliesTo`
|
|
22
|
+
* follows it too.
|
|
23
|
+
*/
|
|
24
|
+
export declare const SCOPE_RE: RegExp;
|
|
19
25
|
/** A request context: the quantities and attributes a call declares. */
|
|
20
26
|
export type Context = Record<string, Json>;
|
|
21
27
|
/** The shape every ceiling — built-in or custom — must implement. */
|
|
@@ -56,7 +62,17 @@ export interface Ceiling {
|
|
|
56
62
|
* then the caller-keyed `field`, then the ceiling's own `key`.
|
|
57
63
|
*/
|
|
58
64
|
export declare function ctxFieldOf(ceiling: Ceiling): string;
|
|
59
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Python's `type(a) is type(b)`: whether two ceilings are of one class. Ceilings pair by key, and
|
|
67
|
+
* two of different classes under one key are not comparable: neither narrows the other, so an
|
|
68
|
+
* authority holding one is not narrower than an authority holding the other (attenu-ops#110).
|
|
69
|
+
*/
|
|
70
|
+
export declare function sameType(a: Ceiling, b: Ceiling): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Uniform human-readable rendering of any ceiling. Never parsed back. A ceiling without its own
|
|
73
|
+
* `describe`, such as one this build does not define, prints as the Python implementation prints
|
|
74
|
+
* it: its key as the wire carried it, `=`, and its wire form as Python prints a dict.
|
|
75
|
+
*/
|
|
60
76
|
export declare function describe(ceiling: Ceiling): string;
|
|
61
77
|
/**
|
|
62
78
|
* A ceiling's key as the wire carried it, which is what a finding names. A ceiling this build does
|
|
@@ -69,10 +85,12 @@ export declare function wireKeyOf(ceiling: Ceiling): CJson;
|
|
|
69
85
|
* printed through `shown` (display.ts), so the finding stays on one line.
|
|
70
86
|
*
|
|
71
87
|
* `describe` itself is left alone, so dashboards and `Authority.describe()` print a region called
|
|
72
|
-
* "São Paulo" as it is, and for values in the bare set the two agree character for character
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
88
|
+
* "São Paulo" as it is, and for values in the bare set the two agree character for character, except
|
|
89
|
+
* that an allow-list's or a deny-list's string members are printed in their escaped JSON form, quoted,
|
|
90
|
+
* so the string "1" and the number 1 read differently. A ceiling this build does not define prints the
|
|
91
|
+
* Python implementation's description of it — its key, `=`, and the wire object as Python prints a
|
|
92
|
+
* dict — as it is when that is printable ASCII, spaces included, and as escaped JSON otherwise. Same
|
|
93
|
+
* text as the Python implementation's finding.
|
|
76
94
|
*/
|
|
77
95
|
export declare function describeInFinding(ceiling: Ceiling): string;
|
|
78
96
|
/**
|
|
@@ -82,11 +100,17 @@ export declare function describeInFinding(ceiling: Ceiling): string;
|
|
|
82
100
|
* asserting anything here", not "consuming an undeclared amount".
|
|
83
101
|
*/
|
|
84
102
|
export declare function isMetered(ceiling: Ceiling): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* The context's own value for `field`, or `undefined`. A plain object inherits `constructor`,
|
|
105
|
+
* `toString` and the rest from Object.prototype, and a field named like one of them is absent unless
|
|
106
|
+
* the context holds it, as `ctx.get(field)` reads it in the Python implementation.
|
|
107
|
+
*/
|
|
108
|
+
export declare function ownValue(ctx: Context, field: string): Json | undefined;
|
|
85
109
|
/** Per-call cap on rows read or returned. Context field: "rows". */
|
|
86
110
|
export declare class RowLimit implements Ceiling {
|
|
87
|
-
readonly maxRows: number;
|
|
88
111
|
readonly key = "max_rows";
|
|
89
112
|
readonly ctxField = "rows";
|
|
113
|
+
readonly maxRows: number;
|
|
90
114
|
constructor(maxRows: number);
|
|
91
115
|
permits(ctx: Context): Decision;
|
|
92
116
|
describe(): string;
|
|
@@ -97,9 +121,9 @@ export declare class RowLimit implements Ceiling {
|
|
|
97
121
|
}
|
|
98
122
|
/** Per-call cap on spend, currency-agnostic. Context field: "spend". */
|
|
99
123
|
export declare class SpendCap implements Ceiling {
|
|
100
|
-
readonly maxSpend: number;
|
|
101
124
|
readonly key = "max_spend";
|
|
102
125
|
readonly ctxField = "spend";
|
|
126
|
+
readonly maxSpend: number;
|
|
103
127
|
constructor(maxSpend: number);
|
|
104
128
|
permits(ctx: Context): Decision;
|
|
105
129
|
describe(): string;
|
|
@@ -121,10 +145,10 @@ export declare class SpendCap implements Ceiling {
|
|
|
121
145
|
* does not; an explicit `calls` in the context still wins.
|
|
122
146
|
*/
|
|
123
147
|
export declare class CallLimit implements Ceiling {
|
|
124
|
-
readonly maxCalls: number;
|
|
125
148
|
readonly appliesTo: string | null;
|
|
126
149
|
readonly key: string;
|
|
127
150
|
readonly ctxField: string;
|
|
151
|
+
readonly maxCalls: number;
|
|
128
152
|
constructor(maxCalls: number, appliesTo?: string | null);
|
|
129
153
|
/** What this ceiling counts: the pattern it applies to, or every call. */
|
|
130
154
|
get meterKey(): string;
|
|
@@ -149,7 +173,11 @@ export declare class EgressRank implements Ceiling {
|
|
|
149
173
|
toWire(): Record<string, Json>;
|
|
150
174
|
static fromWire(d: Record<string, Json>): EgressRank;
|
|
151
175
|
}
|
|
152
|
-
/**
|
|
176
|
+
/**
|
|
177
|
+
* Membership allow-list: the context value MUST be one of `oneOf`. A member is its JSON type plus
|
|
178
|
+
* its value, as a Set holds it: `[1]` admits 1 and refuses `true` and `"1"`. A context value that
|
|
179
|
+
* is not a JSON scalar is refused (`wrongKind`).
|
|
180
|
+
*/
|
|
153
181
|
export declare class Allow implements Ceiling {
|
|
154
182
|
readonly key: string;
|
|
155
183
|
readonly field: string | null;
|
|
@@ -163,7 +191,12 @@ export declare class Allow implements Ceiling {
|
|
|
163
191
|
toWire(): Record<string, Json>;
|
|
164
192
|
static fromWire(d: Record<string, Json>): Allow;
|
|
165
193
|
}
|
|
166
|
-
/**
|
|
194
|
+
/**
|
|
195
|
+
* Membership deny-list: the context value MUST NOT be one of `notOneOf`. A member is its JSON type
|
|
196
|
+
* plus its value, as a Set holds it: `[1]` refuses 1 and not `true` or `"1"`. A context value that
|
|
197
|
+
* is not a JSON scalar is refused as well (`wrongKind`): a deny-list never waves through a value it
|
|
198
|
+
* cannot compare, since waving `["rm"]` through because it is not the string "rm" would fail open.
|
|
199
|
+
*/
|
|
167
200
|
export declare class Deny implements Ceiling {
|
|
168
201
|
readonly key: string;
|
|
169
202
|
readonly field: string | null;
|
|
@@ -204,10 +237,15 @@ export declare function registerCeiling(key: string, cls: CeilingClass): void;
|
|
|
204
237
|
* Fail-closed placeholder for a wire constraint this build does not recognise.
|
|
205
238
|
*
|
|
206
239
|
* `permits` always denies. `narrow` stays an unknown ceiling, so it can never
|
|
207
|
-
* resolve to something more permissive than "deny everything"
|
|
240
|
+
* resolve to something more permissive than "deny everything"; `Authority.meet`
|
|
241
|
+
* keeps a parent's against a request of any other type, so the child inherits
|
|
242
|
+
* it. `subsumes` is
|
|
208
243
|
* true only against an identical unknown ceiling — just enough reflexivity for
|
|
209
|
-
* `isNarrowerThan(self)`.
|
|
210
|
-
*
|
|
244
|
+
* `isNarrowerThan(self)`. Identical means the same RFC 8785 bytes, which is
|
|
245
|
+
* equality as JSON: `true` is not 1, `1.0` is 1, and key order is no difference
|
|
246
|
+
* at any depth; a value RFC 8785 cannot write is identical to nothing. `toWire`
|
|
247
|
+
* preserves the original bytes losslessly, so a chain that merely forwards
|
|
248
|
+
* constraints can still do so.
|
|
211
249
|
*/
|
|
212
250
|
export declare class UnknownCeiling implements Ceiling {
|
|
213
251
|
readonly raw: Record<string, Json>;
|
|
@@ -223,6 +261,13 @@ export declare class UnknownCeiling implements Ceiling {
|
|
|
223
261
|
* Reconstruct a Ceiling from its wire form. Routes on "type" when present (it
|
|
224
262
|
* disambiguates the generic ceilings), else on "key". An unrecognised
|
|
225
263
|
* discriminator fails closed via `UnknownCeiling`.
|
|
264
|
+
*
|
|
265
|
+
* A constraint is a JSON object with a string `key`, and a `type` that, when present, is a string;
|
|
266
|
+
* anything else is malformed (attenu-ops#110), in the Python implementation's words too: `a
|
|
267
|
+
* constraint is a string, not an object`, `type of constraint 'max_rows' is null, not a string`.
|
|
268
|
+
* A constraint that is not an object loaded as an unknown constraint here, null aside, and a null
|
|
269
|
+
* `type` was read as absent, so the constraint was routed by its key: `{"key": "allow", "type":
|
|
270
|
+
* null, ...}` loaded as an allow-list, where the Python implementation loaded an unknown constraint.
|
|
226
271
|
*/
|
|
227
272
|
export declare function ceilingFromWire(wire: CJson): Ceiling;
|
|
228
273
|
//# sourceMappingURL=ceilings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ceilings.d.ts","sourceRoot":"","sources":["../../src/ceilings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"ceilings.d.ts","sourceRoot":"","sources":["../../src/ceilings.ts"],"names":[],"mappings":"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"}
|