@astrale-os/kernel-dsl 0.2.0-beta.27 → 0.2.0-beta.28
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/v1/builder/callable/authoring.d.ts +1 -1
- package/dist/v1/builder/lowering/schema/context.js +28 -9
- package/dist/v1/builder/lowering/schema/ownership.d.ts +3 -3
- package/dist/v1/compiled/admission/semantics.js +2 -5
- package/dist/v1/schema/validation/policy/uses.js +14 -7
- package/package.json +1 -1
|
@@ -91,7 +91,7 @@ export type ProjectionOfCallable<Value extends Function | Method> = Value extend
|
|
|
91
91
|
/** Internal lowering access; Callable authoring handles expose no public configuration object. */
|
|
92
92
|
export declare function callableConfiguration(value: Function | Method): CallableInput;
|
|
93
93
|
export type PolicyObjectAuthoring = Class | Function | Policy | View | CoreNode;
|
|
94
|
-
export type PolicyObjectInput = Lazy<PolicyObjectAuthoring>;
|
|
94
|
+
export type PolicyObjectInput = Lazy<PolicyObjectAuthoring | PolicyObjectRef>;
|
|
95
95
|
export declare function func<const Config extends FunctionInput, Input = ValueInputOf<Config['input']>, Output = CallableOutputOf<Config['output']>, Auth extends FunctionAuth = Config['auth']>(config: Config): Function<CallableProjection<Input, Output, Auth, false, 'default'>>;
|
|
96
96
|
export declare function method<const Config extends MethodInput, Input = ValueInputOf<Config['input']>, Output = CallableOutputOf<Config['output']>, Auth extends FunctionAuth = Config['auth'], Static extends boolean = Config extends {
|
|
97
97
|
readonly static: true;
|
|
@@ -50,22 +50,22 @@ export class BuilderContext {
|
|
|
50
50
|
this.capturePolicyObject(value, ref);
|
|
51
51
|
}
|
|
52
52
|
capturePolicy(value, ref, pointer) {
|
|
53
|
-
this.ownership.
|
|
53
|
+
this.ownership.captureDefinition(value, ref, pointer);
|
|
54
54
|
this.policies.set(value, ref);
|
|
55
55
|
this.capturePolicyObject(value, ref);
|
|
56
56
|
}
|
|
57
57
|
captureCoreNode(value, slug, pointer) {
|
|
58
|
-
this.ownership.capture(value, `${this.origin}:core.${slug}`, pointer);
|
|
59
58
|
const ref = { origin: this.origin, kind: 'core', name: slug };
|
|
59
|
+
this.ownership.captureDefinition(value, ref, pointer);
|
|
60
60
|
this.coreNodes.set(value, ref);
|
|
61
61
|
this.capturePolicyObject(value, ref);
|
|
62
62
|
}
|
|
63
63
|
captureFunction(value, ref, pointer) {
|
|
64
|
-
this.ownership.
|
|
64
|
+
this.ownership.captureDefinition(value, ref, pointer);
|
|
65
65
|
this.capturePolicyObject(value, ref);
|
|
66
66
|
}
|
|
67
67
|
captureView(value, ref, pointer) {
|
|
68
|
-
this.ownership.
|
|
68
|
+
this.ownership.captureDefinition(value, ref, pointer);
|
|
69
69
|
this.capturePolicyObject(value, ref);
|
|
70
70
|
}
|
|
71
71
|
resolveClass(input, kind, pointer) {
|
|
@@ -112,13 +112,18 @@ export class BuilderContext {
|
|
|
112
112
|
const ref = isPolicyObjectRef(value)
|
|
113
113
|
? value
|
|
114
114
|
: typeof value === 'object' && value !== null
|
|
115
|
-
? this.policyObjects.get(value)
|
|
115
|
+
? (this.policyObjects.get(value) ?? this.ownership.definition(value))
|
|
116
116
|
: undefined;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
const dependency = ref === undefined ? undefined : this.#dependencies.get(ref.origin)?.schema;
|
|
118
|
+
const admitted = ref !== undefined &&
|
|
119
|
+
(ref.origin === this.origin
|
|
120
|
+
? this.policyObjectRefs.has(definitionRefIndex(ref))
|
|
121
|
+
: dependency !== undefined && hasPolicyObject(dependency, ref));
|
|
122
|
+
if (!admitted || ref === undefined) {
|
|
123
|
+
fail('BUILDER_POLICY_REF', pointer, 'Policy ref(...) must name one registered local or direct-dependency Definition, Function, Policy, View, or Core Node.');
|
|
121
124
|
}
|
|
125
|
+
if (ref.origin !== this.origin)
|
|
126
|
+
this.usedForeignOrigins.add(ref.origin);
|
|
122
127
|
return { ...ref };
|
|
123
128
|
}
|
|
124
129
|
resolveCoreEndpoint(value, pointer) {
|
|
@@ -245,3 +250,17 @@ function definitionRefsOf(schema) {
|
|
|
245
250
|
}
|
|
246
251
|
return refs.sort(compareDefinitionRefs);
|
|
247
252
|
}
|
|
253
|
+
function hasPolicyObject(schema, ref) {
|
|
254
|
+
switch (ref.kind) {
|
|
255
|
+
case 'class':
|
|
256
|
+
return Object.hasOwn(schema.classes, ref.name);
|
|
257
|
+
case 'function':
|
|
258
|
+
return Object.hasOwn(schema.functions, ref.name);
|
|
259
|
+
case 'policy':
|
|
260
|
+
return Object.hasOwn(schema.policies, ref.name);
|
|
261
|
+
case 'view':
|
|
262
|
+
return Object.hasOwn(schema.views, ref.name);
|
|
263
|
+
case 'core':
|
|
264
|
+
return Object.hasOwn(schema.core.nodes, ref.name);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PolicyObjectRef } from '../../../language/policy/model/policy.js';
|
|
2
2
|
export declare class OwnershipCapture {
|
|
3
3
|
#private;
|
|
4
|
-
captureDefinition(value: object, ref:
|
|
4
|
+
captureDefinition(value: object, ref: PolicyObjectRef, pointer: string): void;
|
|
5
5
|
capture(value: object, owner: string, pointer: string): void;
|
|
6
|
-
definition(value: object):
|
|
6
|
+
definition(value: object): PolicyObjectRef | undefined;
|
|
7
7
|
commit(): void;
|
|
8
8
|
}
|
|
@@ -438,11 +438,8 @@ function validateCallablePolicy(context, entry, expression, inputIndex, fields,
|
|
|
438
438
|
!isSingleNodePathField(context, entry, inputIndex, object.field))
|
|
439
439
|
fail(`${path}/object`, 'Callable Policy input target must be a direct required single-Node Path field.');
|
|
440
440
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
context.definitions.get(Key.of(object.ref)) === undefined)
|
|
444
|
-
fail(`${path}/object/ref`, 'Callable Policy object refs must name an exact local Definition.');
|
|
445
|
-
}
|
|
441
|
+
// validateClosure already establishes that object refs name existing local
|
|
442
|
+
// or exact direct-dependency Definitions. Named Policy execution stays local.
|
|
446
443
|
return;
|
|
447
444
|
}
|
|
448
445
|
const children = 'allOf' in expression ? expression.allOf : expression.anyOf;
|
|
@@ -122,7 +122,14 @@ function visitChecks(validation, typing, expression, context, pointer) {
|
|
|
122
122
|
}
|
|
123
123
|
function referenceContracts(validation, ref, pointer) {
|
|
124
124
|
const candidate = validation.environment.candidate;
|
|
125
|
-
|
|
125
|
+
const local = ref.origin === candidate.origin;
|
|
126
|
+
const direct = Object.values(candidate.dependencies).some((entry) => entry.origin === ref.origin);
|
|
127
|
+
const owner = local
|
|
128
|
+
? candidate
|
|
129
|
+
: direct
|
|
130
|
+
? validation.environment.dependencies.get(ref.origin)
|
|
131
|
+
: undefined;
|
|
132
|
+
if (owner === undefined)
|
|
126
133
|
return invalidPolicyObjectRef(validation, ref, pointer);
|
|
127
134
|
switch (ref.kind) {
|
|
128
135
|
case 'class': {
|
|
@@ -132,26 +139,26 @@ function referenceContracts(validation, ref, pointer) {
|
|
|
132
139
|
: invalidPolicyObjectRef(validation, ref, pointer);
|
|
133
140
|
}
|
|
134
141
|
case 'function':
|
|
135
|
-
return
|
|
142
|
+
return owner.functions[ref.name] === undefined
|
|
136
143
|
? invalidPolicyObjectRef(validation, ref, pointer)
|
|
137
144
|
: [{ kind: 'exact', ref: PROJECTION_FUNCTION }];
|
|
138
145
|
case 'policy':
|
|
139
|
-
return
|
|
146
|
+
return owner.policies[ref.name] === undefined
|
|
140
147
|
? invalidPolicyObjectRef(validation, ref, pointer)
|
|
141
148
|
: [{ kind: 'exact', ref: PROJECTION_POLICY }];
|
|
142
149
|
case 'view':
|
|
143
|
-
return
|
|
150
|
+
return owner.views[ref.name] === undefined
|
|
144
151
|
? invalidPolicyObjectRef(validation, ref, pointer)
|
|
145
152
|
: [{ kind: 'exact', ref: PROJECTION_VIEW }];
|
|
146
153
|
case 'core': {
|
|
147
|
-
const node =
|
|
154
|
+
const node = owner.core.nodes[ref.name];
|
|
148
155
|
if (node === undefined)
|
|
149
156
|
return invalidPolicyObjectRef(validation, ref, pointer);
|
|
150
157
|
const resolved = validation.environment.resolve(node.class);
|
|
151
158
|
const analyzed = validation.analysis.definitions.get(definitionRefIndex(node.class));
|
|
152
159
|
// Core validation owns invalid Core Class diagnostics. Avoid adding Policy noise for
|
|
153
160
|
// a Node that cannot materialize in the first place.
|
|
154
|
-
if (node.class.origin !==
|
|
161
|
+
if (node.class.origin !== owner.origin ||
|
|
155
162
|
resolved?.ref.kind !== 'class' ||
|
|
156
163
|
resolved.kind !== 'node' ||
|
|
157
164
|
analyzed === undefined) {
|
|
@@ -163,7 +170,7 @@ function referenceContracts(validation, ref, pointer) {
|
|
|
163
170
|
return invalidPolicyObjectRef(validation, ref, pointer);
|
|
164
171
|
}
|
|
165
172
|
function invalidPolicyObjectRef(validation, ref, pointer) {
|
|
166
|
-
validation.add('PL_REF', `${pointer}/ref`, `${formatDefinitionRef(ref)} is not an exact local projected Policy object.`, formatDefinitionRef(ref));
|
|
173
|
+
validation.add('PL_REF', `${pointer}/ref`, `${formatDefinitionRef(ref)} is not an exact local or direct-dependency projected Policy object.`, formatDefinitionRef(ref));
|
|
167
174
|
return undefined;
|
|
168
175
|
}
|
|
169
176
|
function selfContracts(validation, context, pointer) {
|