@astrale-os/kernel-core 0.9.0-beta.62 → 0.9.0-beta.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/authority/admission/admission.d.ts +2 -2
- package/dist/auth/authority/admission/admission.js +10 -8
- package/dist/auth/authority/admission/index.d.ts +1 -1
- package/dist/auth/authority/admission/index.js +1 -1
- package/dist/auth/authority/index.d.ts +7 -3
- package/dist/auth/authority/index.js +4 -2
- package/dist/auth/authority/language/index.d.ts +2 -0
- package/dist/auth/authority/language/index.js +1 -0
- package/dist/auth/authority/language/predicate.d.ts +10 -5
- package/dist/auth/authority/language/predicate.js +1 -1
- package/dist/auth/authority/language/program.d.ts +21 -0
- package/dist/auth/authority/language/program.js +2 -0
- package/dist/auth/authority/normalization/index.d.ts +1 -1
- package/dist/auth/authority/normalization/index.js +1 -1
- package/dist/auth/authority/normalization/normalize.d.ts +1 -1
- package/dist/auth/authority/normalization/normalize.js +4 -5
- package/dist/auth/authority/ownership.optimization.js +2 -2
- package/dist/auth/authority/prepare-binder-body.d.ts +4 -0
- package/dist/auth/authority/prepare-binder-body.js +31 -0
- package/dist/auth/authority/program.d.ts +28 -0
- package/dist/auth/authority/program.js +191 -0
- package/dist/auth/authority/semantics/class-authority.d.ts +8 -0
- package/dist/auth/authority/semantics/class-authority.js +26 -0
- package/dist/auth/authority/semantics/composition.d.ts +39 -0
- package/dist/auth/authority/semantics/composition.js +112 -0
- package/dist/auth/authority/semantics/failure.d.ts +21 -0
- package/dist/auth/authority/semantics/failure.js +10 -0
- package/dist/auth/authority/semantics/index.d.ts +11 -0
- package/dist/auth/authority/semantics/index.js +5 -0
- package/dist/auth/authority/semantics/interpret.d.ts +35 -0
- package/dist/auth/authority/semantics/interpret.js +215 -0
- package/dist/auth/authority/semantics/snapshot.d.ts +34 -0
- package/dist/auth/authority/semantics/terms.d.ts +20 -0
- package/dist/auth/authority/semantics/terms.js +96 -0
- package/dist/auth/authority/semantics/vocabulary.d.ts +19 -0
- package/dist/auth/authority/semantics/vocabulary.js +1 -0
- package/dist/auth/context/context.d.ts +4 -3
- package/dist/auth/expression/authoring/builder.d.ts +2 -11
- package/dist/auth/expression/authoring/builder.js +1 -45
- package/dist/auth/expression/authoring/index.d.ts +1 -1
- package/dist/auth/expression/authoring/index.js +1 -1
- package/dist/auth/expression/index.d.ts +1 -2
- package/dist/auth/expression/index.js +1 -2
- package/dist/auth/expression/language/identity-expression.d.ts +2 -22
- package/dist/auth/grant/index.d.ts +1 -1
- package/dist/auth/grant/index.js +1 -1
- package/dist/auth/grant/resolved/admission.d.ts +4 -3
- package/dist/auth/grant/resolved/admission.js +23 -13
- package/dist/auth/grant/resolved/grant.d.ts +1 -1
- package/dist/auth/grant/resolved/index.d.ts +1 -1
- package/dist/auth/grant/resolved/index.js +1 -1
- package/dist/auth/grant/unresolved/admission.d.ts +4 -1
- package/dist/auth/grant/unresolved/admission.js +27 -67
- package/dist/auth/grant/unresolved/limits.d.ts +2 -4
- package/dist/auth/grant/unresolved/limits.js +1 -5
- package/dist/auth/index.d.ts +1 -1
- package/dist/graph/graph/graph.d.ts +1 -5
- package/dist/graph/graph/graph.js +3 -27
- package/dist/graph/graph/index.d.ts +1 -3
- package/dist/graph/graph/index.js +1 -2
- package/dist/graph/query/index.d.ts +2 -0
- package/dist/graph/query/index.js +1 -0
- package/dist/graph/query/order/index.d.ts +46 -0
- package/dist/graph/query/order/index.js +59 -0
- package/dist/graph/query/reference/evaluate.js +24 -50
- package/dist/graph/reconcile/planning/canonical.d.ts +6 -0
- package/dist/graph/reconcile/planning/canonical.js +28 -0
- package/dist/graph/reconcile/planning/model.d.ts +4 -0
- package/dist/graph/reconcile/planning/plan.js +2 -1
- package/dist/schema/authority/vocabulary.d.ts +3 -0
- package/dist/schema/authority/vocabulary.js +25 -0
- package/dist/schema/identity/composition.d.ts +5 -0
- package/dist/schema/identity/composition.js +5 -0
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +1 -0
- package/dist/schema/introspection/language.d.ts +2 -0
- package/dist/schema/kernel/schema.d.ts +125 -79
- package/dist/schema/kernel/syscalls/contracts/install.d.ts +86 -7
- package/dist/schema/kernel/syscalls/contracts/install.js +6 -3
- package/dist/schema/kernel/syscalls/contracts/installation.d.ts +30 -0
- package/dist/schema/kernel/syscalls/contracts/installation.js +9 -0
- package/dist/schema/kernel/syscalls/contracts/introspect.d.ts +5 -2
- package/dist/schema/kernel/syscalls/contracts/introspect.js +9 -5
- package/dist/schema/kernel/syscalls/contracts/legacy/install.d.ts +22 -0
- package/dist/schema/kernel/syscalls/contracts/legacy/install.js +31 -0
- package/dist/schema/kernel/syscalls/contracts/uninstall.d.ts +10 -0
- package/dist/schema/kernel/syscalls/declarations/index.d.ts +49 -25
- package/dist/schema/kernel/syscalls/declarations/install.d.ts +17 -2
- package/dist/schema/kernel/syscalls/declarations/introspect.d.ts +2 -0
- package/dist/schema/kernel/syscalls/declarations/mutate.d.ts +23 -23
- package/dist/schema/kernel/syscalls/declarations/uninstall.d.ts +7 -0
- package/dist/schema/kernel/syscalls/descriptors/results/view-resolution.d.ts +7 -0
- package/package.json +2 -2
- package/dist/auth/authority/prepare-grant-body.d.ts +0 -4
- package/dist/auth/authority/prepare-grant-body.js +0 -27
- package/dist/auth/expression/normalization/canonicalize.d.ts +0 -7
- package/dist/auth/expression/normalization/canonicalize.js +0 -102
- package/dist/auth/expression/normalization/index.d.ts +0 -2
- package/dist/auth/expression/normalization/index.js +0 -2
- package/dist/auth/expression/normalization/raise-denials.d.ts +0 -3
- package/dist/auth/expression/normalization/raise-denials.js +0 -59
- package/dist/graph/graph/navigation/error.d.ts +0 -12
- package/dist/graph/graph/navigation/error.js +0 -20
- package/dist/graph/graph/navigation/index.d.ts +0 -2
- package/dist/graph/graph/navigation/index.js +0 -1
- package/dist/graph/graph/navigation/model.d.ts +0 -15
- package/dist/schema/kernel/projection/path.d.ts +0 -2
- package/dist/schema/kernel/projection/path.js +0 -113
- /package/dist/{graph/graph/navigation/model.js → auth/authority/semantics/snapshot.js} +0 -0
|
@@ -13,27 +13,6 @@ class Expression {
|
|
|
13
13
|
build() {
|
|
14
14
|
return this.value;
|
|
15
15
|
}
|
|
16
|
-
union(other) {
|
|
17
|
-
return compose('union', this, other);
|
|
18
|
-
}
|
|
19
|
-
intersect(other) {
|
|
20
|
-
return compose('intersect', this, other);
|
|
21
|
-
}
|
|
22
|
-
exclude(other) {
|
|
23
|
-
const current = this.value;
|
|
24
|
-
if (current.kind === 'exclude') {
|
|
25
|
-
return expression({
|
|
26
|
-
kind: 'exclude',
|
|
27
|
-
base: current.base,
|
|
28
|
-
excluded: [...current.excluded, other.build()],
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
return expression({
|
|
32
|
-
kind: 'exclude',
|
|
33
|
-
base: current,
|
|
34
|
-
excluded: [other.build()],
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
16
|
}
|
|
38
17
|
/** Build one resolved Identity leaf. */
|
|
39
18
|
export function identity(id) {
|
|
@@ -55,33 +34,10 @@ export function cred(credential) {
|
|
|
55
34
|
}
|
|
56
35
|
return expression(Object.freeze({ kind: 'identity', credential: credential.slice() }));
|
|
57
36
|
}
|
|
58
|
-
/** Re-enter
|
|
37
|
+
/** Re-enter from an already trusted or separately admitted Identity leaf. */
|
|
59
38
|
export function raw(expr) {
|
|
60
39
|
return expression(expr);
|
|
61
40
|
}
|
|
62
|
-
/** Compose at least two expressions of the same resolved or unresolved phase. */
|
|
63
|
-
export function union(first, second, ...rest) {
|
|
64
|
-
return compose('union', first, second, ...rest);
|
|
65
|
-
}
|
|
66
|
-
/** Intersect at least two expressions of the same resolved or unresolved phase. */
|
|
67
|
-
export function intersect(first, second, ...rest) {
|
|
68
|
-
return compose('intersect', first, second, ...rest);
|
|
69
|
-
}
|
|
70
|
-
/** Exclude one expression from another expression of the same phase. */
|
|
71
|
-
export function exclude(base, excluded) {
|
|
72
|
-
return base.exclude(excluded);
|
|
73
|
-
}
|
|
74
|
-
function compose(kind, first, second, ...rest) {
|
|
75
|
-
const operands = [];
|
|
76
|
-
for (const builder of [first, second, ...rest]) {
|
|
77
|
-
const value = builder.build();
|
|
78
|
-
if (value.kind === kind)
|
|
79
|
-
operands.push(...value.operands);
|
|
80
|
-
else
|
|
81
|
-
operands.push(value);
|
|
82
|
-
}
|
|
83
|
-
return expression({ kind, operands });
|
|
84
|
-
}
|
|
85
41
|
function expression(value) {
|
|
86
42
|
return Object.freeze(new Expression(value));
|
|
87
43
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export type { BuiltExpr, Expr, ExprBuilder } from './builder.js';
|
|
2
|
-
export { cred,
|
|
2
|
+
export { cred, identity, isExprBuilder, raw, self } from './builder.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { cred,
|
|
1
|
+
export { cred, identity, isExprBuilder, raw, self } from './builder.js';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export type { BuiltExpr, Expr, ExprBuilder } from './authoring/index.js';
|
|
2
|
-
export { cred,
|
|
2
|
+
export { cred, identity, isExprBuilder, raw, self } from './authoring/index.js';
|
|
3
3
|
export type { IdentityExpr, SelfIdentityExpr, UnresolvedIdentityExpr } from './language/index.js';
|
|
4
|
-
export { canonicalize, raiseDenials } from './normalization/index.js';
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export { cred,
|
|
2
|
-
export { canonicalize, raiseDenials } from './normalization/index.js';
|
|
1
|
+
export { cred, identity, isExprBuilder, raw, self } from './authoring/index.js';
|
|
@@ -5,33 +5,13 @@ export type SelfIdentityExpr = {
|
|
|
5
5
|
readonly kind: 'identity';
|
|
6
6
|
readonly self: true;
|
|
7
7
|
};
|
|
8
|
-
/**
|
|
8
|
+
/** The one resolved Identity leaf carried by Kernel bearer and delegation proof claims. */
|
|
9
9
|
export type IdentityExpr = {
|
|
10
10
|
readonly kind: 'identity';
|
|
11
11
|
readonly id: IdentityId;
|
|
12
|
-
} | {
|
|
13
|
-
readonly kind: 'union';
|
|
14
|
-
readonly operands: readonly IdentityExpr[];
|
|
15
|
-
} | {
|
|
16
|
-
readonly kind: 'intersect';
|
|
17
|
-
readonly operands: readonly IdentityExpr[];
|
|
18
|
-
} | {
|
|
19
|
-
readonly kind: 'exclude';
|
|
20
|
-
readonly base: IdentityExpr;
|
|
21
|
-
readonly excluded: readonly IdentityExpr[];
|
|
22
12
|
};
|
|
23
|
-
/** Caller-authored
|
|
13
|
+
/** Caller-authored single leaf accepted only inside a versioned credential claim. */
|
|
24
14
|
export type UnresolvedIdentityExpr = SelfIdentityExpr | {
|
|
25
15
|
readonly kind: 'identity';
|
|
26
16
|
readonly credential: CredentialInput;
|
|
27
|
-
} | {
|
|
28
|
-
readonly kind: 'union';
|
|
29
|
-
readonly operands: readonly UnresolvedIdentityExpr[];
|
|
30
|
-
} | {
|
|
31
|
-
readonly kind: 'intersect';
|
|
32
|
-
readonly operands: readonly UnresolvedIdentityExpr[];
|
|
33
|
-
} | {
|
|
34
|
-
readonly kind: 'exclude';
|
|
35
|
-
readonly base: UnresolvedIdentityExpr;
|
|
36
|
-
readonly excluded: readonly UnresolvedIdentityExpr[];
|
|
37
17
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { accept,
|
|
1
|
+
export { accept, self } from './resolved/index.js';
|
|
2
2
|
export type { Grant } from './resolved/index.js';
|
|
3
3
|
export { acceptUnresolved, limits } from './unresolved/index.js';
|
|
4
4
|
export type { UnresolvedGrant } from './unresolved/index.js';
|
package/dist/auth/grant/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { accept,
|
|
1
|
+
export { accept, self } from './resolved/index.js';
|
|
2
2
|
export { acceptUnresolved, limits } from './unresolved/index.js';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Grant } from './grant.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Admit one exact resolved claim value `{ expr: { kind: 'identity', id } }`. Compound structure
|
|
4
|
+
* keeps the unresolved claim's stable code, AUTH_GRANT_COMPOUND.
|
|
5
|
+
*/
|
|
3
6
|
export declare function accept(input: unknown): Grant;
|
|
4
|
-
/** Re-canonicalize a trusted Grant value. */
|
|
5
|
-
export declare function canonicalize(input: Grant): Grant;
|
|
@@ -1,30 +1,40 @@
|
|
|
1
1
|
import * as portable from '@astrale-os/kernel-dsl/value';
|
|
2
|
+
import { isNodeId, NodeId } from '../../../graph/node/index.js';
|
|
2
3
|
import { AuthValueError } from '../../error.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
4
|
+
const COMPOUND = new Set(['union', 'intersect', 'exclude']);
|
|
5
|
+
/**
|
|
6
|
+
* Admit one exact resolved claim value `{ expr: { kind: 'identity', id } }`. Compound structure
|
|
7
|
+
* keeps the unresolved claim's stable code, AUTH_GRANT_COMPOUND.
|
|
8
|
+
*/
|
|
5
9
|
export function accept(input) {
|
|
6
10
|
try {
|
|
7
11
|
const value = portable.accept(input);
|
|
8
|
-
|
|
9
|
-
invalid('', 'Expected a Grant object');
|
|
10
|
-
}
|
|
11
|
-
const grant = value;
|
|
12
|
+
const grant = record(value, '', 'Expected a Grant object');
|
|
12
13
|
exact(grant, ['expr'], '');
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const expr = record(grant.expr, '/expr', 'Expected one resolved Identity leaf');
|
|
15
|
+
if (typeof expr.kind === 'string' && COMPOUND.has(expr.kind)) {
|
|
16
|
+
throw new AuthValueError('AUTH_GRANT_COMPOUND', 'Resolved Grant must name exactly one Identity', '/expr');
|
|
17
|
+
}
|
|
18
|
+
exact(expr, ['id', 'kind'], '/expr');
|
|
19
|
+
if (expr.kind !== 'identity')
|
|
20
|
+
invalid('/expr/kind', 'Expected one resolved Identity leaf');
|
|
21
|
+
if (typeof expr.id !== 'string' || !isNodeId(expr.id)) {
|
|
22
|
+
invalid('/expr/id', 'Expected one canonical IdentityId');
|
|
23
|
+
}
|
|
24
|
+
return Object.freeze({ expr: Object.freeze({ kind: 'identity', id: NodeId(expr.id) }) });
|
|
16
25
|
}
|
|
17
26
|
catch (cause) {
|
|
18
27
|
if (cause instanceof AuthValueError)
|
|
19
28
|
throw cause;
|
|
20
|
-
throw new AuthValueError('AUTH_GRANT_INVALID', 'Expected a
|
|
29
|
+
throw new AuthValueError('AUTH_GRANT_INVALID', 'Expected a resolved single-Identity Grant', '', {
|
|
21
30
|
cause,
|
|
22
31
|
});
|
|
23
32
|
}
|
|
24
33
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
function record(value, path, message) {
|
|
35
|
+
if (value === null || Array.isArray(value) || typeof value !== 'object')
|
|
36
|
+
invalid(path, message);
|
|
37
|
+
return value;
|
|
28
38
|
}
|
|
29
39
|
function exact(value, expected, path) {
|
|
30
40
|
const actual = Object.keys(value).sort(compare);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IdentityExpr } from '../../expression/language/index.js';
|
|
2
|
-
/**
|
|
2
|
+
/** The resolved single-identity claim value carried by Kernel bearers and delegation proofs. */
|
|
3
3
|
export interface Grant {
|
|
4
4
|
readonly expr: IdentityExpr;
|
|
5
5
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { accept
|
|
1
|
+
export { accept } from './admission.js';
|
|
2
2
|
export { self } from './self.js';
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import type { UnresolvedGrant } from './grant.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Admit the exact version-1 unresolved Grant claim: exactly one `self` or one credential leaf.
|
|
4
|
+
* Compound structure is refused before any nested credential could be verified.
|
|
5
|
+
*/
|
|
3
6
|
export declare function acceptUnresolved(input: unknown): UnresolvedGrant;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { AuthValueError } from '../../error.js';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
/**
|
|
2
|
+
import { CREDENTIAL_BYTES_LIMIT } from './limits.js';
|
|
3
|
+
const COMPOUND = new Set(['union', 'intersect', 'exclude']);
|
|
4
|
+
/**
|
|
5
|
+
* Admit the exact version-1 unresolved Grant claim: exactly one `self` or one credential leaf.
|
|
6
|
+
* Compound structure is refused before any nested credential could be verified.
|
|
7
|
+
*/
|
|
5
8
|
export function acceptUnresolved(input) {
|
|
6
9
|
try {
|
|
7
10
|
const value = record(input, '');
|
|
8
11
|
exact(value, ['expr', 'v'], '');
|
|
9
12
|
if (data(value, 'v', '/v') !== 1)
|
|
10
13
|
invalid('/v', 'Unsupported unresolved Grant version');
|
|
11
|
-
return Object.freeze({
|
|
12
|
-
v: 1,
|
|
13
|
-
expr: expression(data(value, 'expr', '/expr'), '/expr', 0, 0, new WeakSet()),
|
|
14
|
-
});
|
|
14
|
+
return Object.freeze({ v: 1, expr: leaf(data(value, 'expr', '/expr'), '/expr') });
|
|
15
15
|
}
|
|
16
16
|
catch (cause) {
|
|
17
17
|
if (cause instanceof AuthValueError)
|
|
@@ -21,61 +21,29 @@ export function acceptUnresolved(input) {
|
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
if (depth > EXPRESSION_DEPTH_LIMIT)
|
|
26
|
-
invalid(path, 'Identity expression exceeds its depth limit');
|
|
24
|
+
function leaf(input, path) {
|
|
27
25
|
const value = record(input, path);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (hasSelf === hasCredential)
|
|
38
|
-
invalid(path, 'Expected exactly one unresolved Identity leaf');
|
|
39
|
-
if (hasSelf) {
|
|
40
|
-
exact(value, ['kind', 'self'], path);
|
|
41
|
-
if (data(value, 'self', `${path}/self`) !== true)
|
|
42
|
-
invalid(`${path}/self`, 'Expected true');
|
|
43
|
-
return Object.freeze({ kind: 'identity', self: true });
|
|
44
|
-
}
|
|
45
|
-
exact(value, ['credential', 'kind'], path);
|
|
46
|
-
if (credentialDepth >= CREDENTIAL_NESTING_DEPTH_LIMIT) {
|
|
47
|
-
invalid(`${path}/credential`, 'Credential nesting exceeds its limit');
|
|
48
|
-
}
|
|
49
|
-
return Object.freeze({
|
|
50
|
-
kind: 'identity',
|
|
51
|
-
credential: credential(data(value, 'credential', `${path}/credential`), `${path}/credential`),
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
case 'union':
|
|
55
|
-
case 'intersect': {
|
|
56
|
-
exact(value, ['kind', 'operands'], path);
|
|
57
|
-
const operands = list(data(value, 'operands', `${path}/operands`), `${path}/operands`, 2);
|
|
58
|
-
return Object.freeze({
|
|
59
|
-
kind,
|
|
60
|
-
operands: Object.freeze(operands.map((operand, index) => expression(operand, `${path}/operands/${index}`, depth + 1, credentialDepth, active))),
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
case 'exclude': {
|
|
64
|
-
exact(value, ['base', 'excluded', 'kind'], path);
|
|
65
|
-
const excluded = list(data(value, 'excluded', `${path}/excluded`), `${path}/excluded`, 1);
|
|
66
|
-
return Object.freeze({
|
|
67
|
-
kind: 'exclude',
|
|
68
|
-
base: expression(data(value, 'base', `${path}/base`), `${path}/base`, depth + 1, credentialDepth, active),
|
|
69
|
-
excluded: Object.freeze(excluded.map((operand, index) => expression(operand, `${path}/excluded/${index}`, depth + 1, credentialDepth, active))),
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
default:
|
|
73
|
-
invalid(`${path}/kind`, 'Expected identity, union, intersect, or exclude');
|
|
74
|
-
}
|
|
26
|
+
const kind = data(value, 'kind', `${path}/kind`);
|
|
27
|
+
if (typeof kind === 'string' && COMPOUND.has(kind)) {
|
|
28
|
+
throw new AuthValueError('AUTH_GRANT_COMPOUND', 'Unresolved Grant must name exactly one Identity', path);
|
|
29
|
+
}
|
|
30
|
+
if (kind !== 'identity')
|
|
31
|
+
invalid(`${path}/kind`, 'Expected identity');
|
|
32
|
+
const hasSelf = own(value, 'self');
|
|
33
|
+
if (hasSelf === own(value, 'credential')) {
|
|
34
|
+
invalid(path, 'Expected exactly one unresolved Identity leaf');
|
|
75
35
|
}
|
|
76
|
-
|
|
77
|
-
|
|
36
|
+
if (hasSelf) {
|
|
37
|
+
exact(value, ['kind', 'self'], path);
|
|
38
|
+
if (data(value, 'self', `${path}/self`) !== true)
|
|
39
|
+
invalid(`${path}/self`, 'Expected true');
|
|
40
|
+
return Object.freeze({ kind: 'identity', self: true });
|
|
78
41
|
}
|
|
42
|
+
exact(value, ['credential', 'kind'], path);
|
|
43
|
+
return Object.freeze({
|
|
44
|
+
kind: 'identity',
|
|
45
|
+
credential: credential(data(value, 'credential', `${path}/credential`), `${path}/credential`),
|
|
46
|
+
});
|
|
79
47
|
}
|
|
80
48
|
function credential(input, path) {
|
|
81
49
|
if (typeof input === 'string') {
|
|
@@ -120,14 +88,6 @@ function exact(input, expected, path) {
|
|
|
120
88
|
invalid(path, `Expected exactly ${expected.join(', ')}`);
|
|
121
89
|
}
|
|
122
90
|
}
|
|
123
|
-
function list(input, path, minimum) {
|
|
124
|
-
if (!Array.isArray(input) || input.length < minimum || input.length > EXPRESSION_OPERAND_LIMIT) {
|
|
125
|
-
invalid(path, `Expected ${minimum}-${EXPRESSION_OPERAND_LIMIT} operands`);
|
|
126
|
-
}
|
|
127
|
-
if (Object.keys(input).length !== input.length)
|
|
128
|
-
invalid(path, 'Expected a dense array');
|
|
129
|
-
return input;
|
|
130
|
-
}
|
|
131
91
|
function compare(left, right) {
|
|
132
92
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
133
93
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
export declare const CREDENTIAL_NESTING_DEPTH_LIMIT = 3;
|
|
2
1
|
export declare const CREDENTIAL_BYTES_LIMIT: number;
|
|
3
2
|
export declare const limits: {
|
|
4
|
-
|
|
5
|
-
readonly
|
|
6
|
-
readonly credentialNestingDepth: 3;
|
|
3
|
+
/** One nested Kernel delegation proof; proofs never nest further. */
|
|
4
|
+
readonly credentialNestingDepth: 1;
|
|
7
5
|
};
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import { EXPRESSION_DEPTH_LIMIT, EXPRESSION_OPERAND_LIMIT, } from '../../expression/normalization/index.js';
|
|
2
|
-
export const CREDENTIAL_NESTING_DEPTH_LIMIT = 3;
|
|
3
1
|
export const CREDENTIAL_BYTES_LIMIT = 64 * 1024;
|
|
4
2
|
export const limits = Object.freeze({
|
|
5
|
-
|
|
6
|
-
operandsPerExpression: EXPRESSION_OPERAND_LIMIT,
|
|
7
|
-
credentialNestingDepth: CREDENTIAL_NESTING_DEPTH_LIMIT,
|
|
3
|
+
credentialNestingDepth: 1,
|
|
8
4
|
});
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { AuthValueError } from './error.js';
|
|
2
2
|
export type { Attestation } from './attestation/index.js';
|
|
3
|
-
export type { AuthorityExpr, AuthorityPredicate, ClosedEdgeExtent, } from './authority/language/index.js';
|
|
3
|
+
export type { AuthorityExpr, AuthorityPredicate, AuthorityProgram, PredicateRef, ClosedEdgeExtent, } from './authority/language/index.js';
|
|
4
4
|
export type { ClaimConstraint } from './claims/index.js';
|
|
5
5
|
export type { AuthenticationEvidence, AuthenticationMethod, CredentialAudience, CredentialInput, MintedCredential, UnverifiedCredential, VerifiedCredential, } from './credential/index.js';
|
|
6
6
|
export type { AuthContext, Authenticated, CredentialContext } from './context/index.js';
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import type { Node } from '../node/index.js';
|
|
2
|
-
import type { PathLike } from '../path/index.js';
|
|
3
1
|
import type { GraphAdmissionContext } from './admission/index.js';
|
|
4
2
|
import type { Delta, DeltaResult } from './delta/index.js';
|
|
5
3
|
import type { GraphEdges, GraphNodes } from './indexes/index.js';
|
|
6
4
|
import type { MergeResult } from './merge/index.js';
|
|
7
5
|
import type { GraphData } from './model/index.js';
|
|
8
|
-
import type { GraphPathWalker } from './navigation/index.js';
|
|
9
6
|
/** Immutable indexed behavioral view over exactly one admitted GraphData value. */
|
|
10
7
|
export declare class Graph {
|
|
11
8
|
#private;
|
|
12
9
|
readonly nodes: GraphNodes;
|
|
13
10
|
readonly edges: GraphEdges;
|
|
14
11
|
private constructor();
|
|
15
|
-
static admit(data: GraphData, context: GraphAdmissionContext
|
|
12
|
+
static admit(data: GraphData, context: GraphAdmissionContext): Graph;
|
|
16
13
|
static empty(): Graph;
|
|
17
14
|
/** Compare reference-open observations without deriving deletion from absence. */
|
|
18
15
|
static delta(left: Graph, right: Graph): DeltaResult;
|
|
@@ -22,7 +19,6 @@ export declare class Graph {
|
|
|
22
19
|
static merge(base: Graph, current: Graph, target: Graph): MergeResult;
|
|
23
20
|
/** Apply the same exact merge rule to canonical finite values without schema re-admission. */
|
|
24
21
|
static mergeData(base: GraphData, current: GraphData, target: GraphData): MergeResult;
|
|
25
|
-
walk(path: PathLike): Node | undefined;
|
|
26
22
|
toData(): GraphData;
|
|
27
23
|
equals(other: Graph): boolean;
|
|
28
24
|
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { edgeKeyOf } from '../edge/index.js';
|
|
2
|
-
import { Path } from '../path/index.js';
|
|
3
2
|
import { equal as equalProperties } from '../properties/index.js';
|
|
4
3
|
import { admitGraphData } from './admission/index.js';
|
|
5
4
|
import { apply as applyDelta, delta as graphDelta } from './delta/index.js';
|
|
6
5
|
import { buildIndexes, createCollections } from './indexes/index.js';
|
|
7
6
|
import { mergeData as mergeGraphData } from './merge/index.js';
|
|
8
|
-
import { GraphPathWalkerRequiredError } from './navigation/index.js';
|
|
9
7
|
const EMPTY_DATA = Object.freeze({
|
|
10
8
|
nodes: Object.freeze([]),
|
|
11
9
|
edges: Object.freeze([]),
|
|
@@ -17,30 +15,17 @@ export class Graph {
|
|
|
17
15
|
nodes;
|
|
18
16
|
edges;
|
|
19
17
|
#data;
|
|
20
|
-
|
|
21
|
-
#walker;
|
|
22
|
-
#pathContext;
|
|
23
|
-
constructor(data, indexes, walker) {
|
|
18
|
+
constructor(data, indexes) {
|
|
24
19
|
this.#data = data;
|
|
25
|
-
this.#indexes = indexes;
|
|
26
|
-
this.#walker = walker;
|
|
27
20
|
const collections = createCollections(data.nodes, data.edges, indexes);
|
|
28
21
|
this.nodes = collections.nodes;
|
|
29
22
|
this.edges = collections.edges;
|
|
30
|
-
this.#pathContext = Object.freeze({
|
|
31
|
-
nodes: this.nodes,
|
|
32
|
-
edges: this.edges,
|
|
33
|
-
orientation: (classKey) => {
|
|
34
|
-
const info = this.#indexes.classes.byKey.get(classKey);
|
|
35
|
-
return info?.kind === 'edge' ? info.orientation : undefined;
|
|
36
|
-
},
|
|
37
|
-
});
|
|
38
23
|
Object.freeze(this);
|
|
39
24
|
}
|
|
40
|
-
static admit(data, context
|
|
25
|
+
static admit(data, context) {
|
|
41
26
|
const admitted = admitGraphData(data, context);
|
|
42
27
|
const indexes = buildIndexes(admitted.data.nodes, admitted.data.edges, admitted.classes);
|
|
43
|
-
return new Graph(admitted.data, indexes
|
|
28
|
+
return new Graph(admitted.data, indexes);
|
|
44
29
|
}
|
|
45
30
|
static empty() {
|
|
46
31
|
return Graph.#EMPTY;
|
|
@@ -61,15 +46,6 @@ export class Graph {
|
|
|
61
46
|
static mergeData(base, current, target) {
|
|
62
47
|
return mergeGraphData(base, current, target);
|
|
63
48
|
}
|
|
64
|
-
walk(path) {
|
|
65
|
-
const value = Path.from(path);
|
|
66
|
-
if (this.#walker !== undefined)
|
|
67
|
-
return this.#walker.walk(value, this.#pathContext);
|
|
68
|
-
if (value.ast.anchor.kind === 'id' && value.ast.steps.length === 0) {
|
|
69
|
-
return this.#indexes.nodes.byId.get(value.ast.anchor.id);
|
|
70
|
-
}
|
|
71
|
-
throw new GraphPathWalkerRequiredError(value.raw);
|
|
72
|
-
}
|
|
73
49
|
toData() {
|
|
74
50
|
return this.#data;
|
|
75
51
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Stable aggregate facade over Graph model, admission, indexes,
|
|
1
|
+
/** Stable aggregate facade over Graph model, admission, indexes, delta, and merge. */
|
|
2
2
|
export { Graph } from './graph.js';
|
|
3
3
|
export type { Delta, DeltaConflict, DeltaResult } from './delta/index.js';
|
|
4
4
|
export type { MergeConflict, MergeResult } from './merge/index.js';
|
|
@@ -8,5 +8,3 @@ export { LocalBinding, isLocalBinding } from './model/index.js';
|
|
|
8
8
|
export type { GraphAdmissionContext, GraphClassInfo, GraphDiagnostic } from './admission/index.js';
|
|
9
9
|
export { GraphAdmissionError } from './admission/index.js';
|
|
10
10
|
export type { GraphEdges, GraphNodes } from './indexes/index.js';
|
|
11
|
-
export type { GraphPathContext, GraphPathWalker } from './navigation/index.js';
|
|
12
|
-
export { GraphPathAmbiguousError, GraphPathWalkerRequiredError } from './navigation/index.js';
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
/** Stable aggregate facade over Graph model, admission, indexes,
|
|
1
|
+
/** Stable aggregate facade over Graph model, admission, indexes, delta, and merge. */
|
|
2
2
|
export { Graph } from './graph.js';
|
|
3
3
|
export { GraphData, GraphDataDecodeError, GraphSpec, GraphSpecDecodeError } from './model/index.js';
|
|
4
4
|
export { LocalBinding, isLocalBinding } from './model/index.js';
|
|
5
5
|
export { GraphAdmissionError } from './admission/index.js';
|
|
6
|
-
export { GraphPathAmbiguousError, GraphPathWalkerRequiredError } from './navigation/index.js';
|
|
@@ -5,5 +5,7 @@ export { QueryAST, QueryASTDecodeError } from './language/index.js';
|
|
|
5
5
|
export type { EdgeBinding, NodeBinding, QueryBinding, QueryClassFilter, QueryClassPredicate, QueryClassSourceTerm, QueryClassSatisfiesPredicate, QueryClassEqualPredicate, QueryDirection, QueryEdgeSource, QueryEdgeSourceTerm, QueryEdgeSelect, QueryEdgeAST, QueryEdgeIdentityPredicate, QueryEdgeProjection, QueryExpand, QueryFingerprint, QueryIdentityFilter, QueryIdentityPredicate, QueryGraphSelect, QueryNodeAST, QueryNodeIdentityPredicate, QueryNodeProjection, QueryNodeSelect, QueryNodeSource, QueryNodeSourceTerm, QueryNodeTerminalSelect, QueryEdgeTerminalSelect, QueryOrderDirection, QueryPathSourceTerm, QueryPredicate, QueryProjectionShape, QueryPropertyEqualPredicate, QueryPropertyFilter, QueryPropertyOrder, QueryPropertyPredicate, QueryPropertyPresentPredicate, QuerySelect, QuerySingleSourceClassOf, QuerySource, QuerySourceClassesOf, QuerySourceTerm, QueryStep, QueryStructuralLimits, QueryUnrankedPlacement, } from './language/index.js';
|
|
6
6
|
export { QueryResult, QueryResultDecodeError } from './result/index.js';
|
|
7
7
|
export type { QueryEdgeComponentFor, QueryEdgeGraphResult, QueryEdgeItemFor, QueryEdgeResult, QueryGraphResult, QueryNodeComponentFor, QueryNodeGraphResult, QueryNodeItemFor, QueryNodeReference, QueryNodeResult, QueryResultFor, QueryResultForSelect, QuerySelection, QuerySelectionFor, } from './result/index.js';
|
|
8
|
+
export { compareQueryIdentity, compareQueryRank, compareQueryText, compareQueryValue, } from './order/index.js';
|
|
9
|
+
export type { QueryRank, QueryRankIdentity, QueryRankOrder, QueryRankValue } from './order/index.js';
|
|
8
10
|
export { QueryReference, QueryReferenceError } from './reference/index.js';
|
|
9
11
|
export type { QueryReferenceContext, QueryReferenceClassClosure, QueryReferenceEvaluation, QueryReferenceFrontier, QueryReferenceIdentity, QueryReferenceOptions, QueryReferencePathWitness, QueryReferenceProperty, QueryReferenceTrace, } from './reference/index.js';
|
|
@@ -2,4 +2,5 @@
|
|
|
2
2
|
export { Property, Query } from './authoring/index.js';
|
|
3
3
|
export { QueryAST, QueryASTDecodeError } from './language/index.js';
|
|
4
4
|
export { QueryResult, QueryResultDecodeError } from './result/index.js';
|
|
5
|
+
export { compareQueryIdentity, compareQueryRank, compareQueryText, compareQueryValue, } from './order/index.js';
|
|
5
6
|
export { QueryReference, QueryReferenceError } from './reference/index.js';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { OrderingKind } from '@astrale-os/kernel-dsl/v1/language';
|
|
2
|
+
import type { EdgeKey } from '../../edge/index.js';
|
|
3
|
+
import type { NodeId } from '../../node/index.js';
|
|
4
|
+
import type { QueryOrderDirection, QueryUnrankedPlacement } from '../language/index.js';
|
|
5
|
+
/** The identity of one selected fact: a Node's NodeId or an Edge's complete EdgeKey. */
|
|
6
|
+
export type QueryRankIdentity = NodeId | EdgeKey;
|
|
7
|
+
/** A scalar ordering value of one proven kind; an instant is its canonical text. */
|
|
8
|
+
export type QueryRankValue = boolean | number | string;
|
|
9
|
+
/** One selected fact's position: its bucket, its ordering value when ranked, and its identity. */
|
|
10
|
+
export type QueryRank<Identity extends QueryRankIdentity = QueryRankIdentity> = {
|
|
11
|
+
readonly bucket: 'identity';
|
|
12
|
+
readonly identity: Identity;
|
|
13
|
+
} | {
|
|
14
|
+
readonly bucket: 'ranked';
|
|
15
|
+
readonly value: QueryRankValue;
|
|
16
|
+
readonly identity: Identity;
|
|
17
|
+
} | {
|
|
18
|
+
readonly bucket: 'unranked';
|
|
19
|
+
readonly identity: Identity;
|
|
20
|
+
};
|
|
21
|
+
/** The ordering of one Property order: its proven value kind, direction and unranked placement. */
|
|
22
|
+
export interface QueryRankOrder {
|
|
23
|
+
readonly kind: OrderingKind;
|
|
24
|
+
readonly direction: QueryOrderDirection;
|
|
25
|
+
readonly unranked: QueryUnrankedPlacement;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The one observable Query order. Without a Property order, facts follow identity order. With one,
|
|
29
|
+
* unranked facts sit first or last regardless of direction, ranked values compare by their kind in
|
|
30
|
+
* the requested direction, and identity breaks every tie: NodeId byte order, or EdgeKey order by
|
|
31
|
+
* source, target and ClassKey.
|
|
32
|
+
*/
|
|
33
|
+
export declare function compareQueryRank(left: QueryRank, right: QueryRank, order: QueryRankOrder | undefined): number;
|
|
34
|
+
/**
|
|
35
|
+
* Compare two ordering values of one kind: false before true, numeric order, and code-point order
|
|
36
|
+
* for strings and instants.
|
|
37
|
+
*/
|
|
38
|
+
export declare function compareQueryValue(left: QueryRankValue, right: QueryRankValue, kind: OrderingKind): number;
|
|
39
|
+
/**
|
|
40
|
+
* Unicode code-point order, which equals the byte order of the UTF-8 encodings. UTF-16 unit order
|
|
41
|
+
* differs from it only where a surrogate meets a unit at or above U+E000; the fixup reorders
|
|
42
|
+
* exactly that range.
|
|
43
|
+
*/
|
|
44
|
+
export declare function compareQueryText(left: string, right: string): number;
|
|
45
|
+
/** Identity order: NodeId byte order, or EdgeKey (source, target, ClassKey) tuple order. */
|
|
46
|
+
export declare function compareQueryIdentity(left: QueryRankIdentity, right: QueryRankIdentity): number;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { compareEdgeKeys } from '../../edge/index.js';
|
|
2
|
+
import { compareNodeIds } from '../../node/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* The one observable Query order. Without a Property order, facts follow identity order. With one,
|
|
5
|
+
* unranked facts sit first or last regardless of direction, ranked values compare by their kind in
|
|
6
|
+
* the requested direction, and identity breaks every tie: NodeId byte order, or EdgeKey order by
|
|
7
|
+
* source, target and ClassKey.
|
|
8
|
+
*/
|
|
9
|
+
export function compareQueryRank(left, right, order) {
|
|
10
|
+
if (order !== undefined && left.bucket !== right.bucket) {
|
|
11
|
+
const first = order.unranked === 'first' ? 'unranked' : 'ranked';
|
|
12
|
+
return left.bucket === first ? -1 : 1;
|
|
13
|
+
}
|
|
14
|
+
if (order !== undefined && left.bucket === 'ranked' && right.bucket === 'ranked') {
|
|
15
|
+
const compared = compareQueryValue(left.value, right.value, order.kind);
|
|
16
|
+
if (compared !== 0)
|
|
17
|
+
return order.direction === 'asc' ? compared : -compared;
|
|
18
|
+
}
|
|
19
|
+
return compareQueryIdentity(left.identity, right.identity);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Compare two ordering values of one kind: false before true, numeric order, and code-point order
|
|
23
|
+
* for strings and instants.
|
|
24
|
+
*/
|
|
25
|
+
export function compareQueryValue(left, right, kind) {
|
|
26
|
+
if (kind === 'boolean')
|
|
27
|
+
return Number(left) - Number(right);
|
|
28
|
+
if (kind === 'number')
|
|
29
|
+
return Math.sign(left - right);
|
|
30
|
+
return compareQueryText(left, right);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Unicode code-point order, which equals the byte order of the UTF-8 encodings. UTF-16 unit order
|
|
34
|
+
* differs from it only where a surrogate meets a unit at or above U+E000; the fixup reorders
|
|
35
|
+
* exactly that range.
|
|
36
|
+
*/
|
|
37
|
+
export function compareQueryText(left, right) {
|
|
38
|
+
const length = Math.min(left.length, right.length);
|
|
39
|
+
for (let index = 0; index < length; index++) {
|
|
40
|
+
let a = left.charCodeAt(index);
|
|
41
|
+
let b = right.charCodeAt(index);
|
|
42
|
+
if (a === b)
|
|
43
|
+
continue;
|
|
44
|
+
if (a >= 0xd800 && b >= 0xd800) {
|
|
45
|
+
a += a >= 0xe000 ? -0x800 : 0x2000;
|
|
46
|
+
b += b >= 0xe000 ? -0x800 : 0x2000;
|
|
47
|
+
}
|
|
48
|
+
return a < b ? -1 : 1;
|
|
49
|
+
}
|
|
50
|
+
return Math.sign(left.length - right.length);
|
|
51
|
+
}
|
|
52
|
+
/** Identity order: NodeId byte order, or EdgeKey (source, target, ClassKey) tuple order. */
|
|
53
|
+
export function compareQueryIdentity(left, right) {
|
|
54
|
+
if (typeof left === 'string' && typeof right === 'string')
|
|
55
|
+
return compareNodeIds(left, right);
|
|
56
|
+
if (typeof left !== 'string' && typeof right !== 'string')
|
|
57
|
+
return compareEdgeKeys(left, right);
|
|
58
|
+
throw new TypeError('Query rank identities of different kinds are not comparable.');
|
|
59
|
+
}
|