pi-proactive 0.2.0-beta.2 → 0.2.0-beta.3
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 +29 -0
- package/README.md +32 -28
- package/build/cli.mjs +121 -0
- package/build/extensions/proactive.js +47 -6
- package/build/src/commands.js +78 -2
- package/build/src/config.js +511 -4
- package/build/src/daemon-config.js +221 -0
- package/build/src/daemon-contact.js +103 -0
- package/build/src/daemon-host.js +84 -0
- package/build/src/daemon.js +193 -3
- package/build/src/health.js +84 -0
- package/build/src/lineage.js +41 -2
- package/build/src/notify.js +183 -0
- package/build/src/progress-eta.js +134 -0
- package/build/src/trigger.js +43 -0
- package/build/src/trust-loop.js +321 -0
- package/build/src/trust-metrics.js +236 -0
- package/build/src/trust-notify.js +73 -0
- package/build/src/trust-policy.js +58 -0
- package/build/src/trust-registry.js +323 -0
- package/daemon/launchd.plist +48 -0
- package/daemon/pi-proactive-daemon.service +29 -0
- package/daemon/run-daemon.sh +84 -0
- package/node_modules/typebox/build/compile/code.mjs +2 -1
- package/node_modules/typebox/build/compile/validator.mjs +1 -5
- package/node_modules/typebox/build/format/date_time.d.mts +1 -2
- package/node_modules/typebox/build/format/date_time.mjs +3 -12
- package/node_modules/typebox/build/format/duration.d.mts +2 -2
- package/node_modules/typebox/build/format/duration.mjs +2 -2
- package/node_modules/typebox/build/format/idn_email.d.mts +0 -1
- package/node_modules/typebox/build/format/idn_email.mjs +0 -1
- package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -1
- package/node_modules/typebox/build/format/idn_hostname.mjs +1 -1
- package/node_modules/typebox/build/format/ipv4.d.mts +2 -2
- package/node_modules/typebox/build/format/ipv4.mjs +2 -2
- package/node_modules/typebox/build/format/ipv6.d.mts +1 -1
- package/node_modules/typebox/build/format/ipv6.mjs +1 -1
- package/node_modules/typebox/build/format/iri.mjs +9 -16
- package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
- package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
- package/node_modules/typebox/build/guard/emit.mjs +2 -2
- package/node_modules/typebox/build/guard/guard.d.mts +5 -7
- package/node_modules/typebox/build/guard/guard.mjs +9 -14
- package/node_modules/typebox/build/guard/index.mjs +0 -6
- package/node_modules/typebox/build/guard/{unicode/unicode_segment.mjs → string.mjs} +19 -16
- package/node_modules/typebox/build/schema/build.mjs +5 -5
- package/node_modules/typebox/build/schema/check.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/_context.d.mts +1 -5
- package/node_modules/typebox/build/schema/engine/_context.mjs +3 -16
- package/node_modules/typebox/build/schema/engine/_functions.d.mts +2 -2
- package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/_reducer.d.mts +3 -3
- package/node_modules/typebox/build/schema/engine/_refine.d.mts +5 -5
- package/node_modules/typebox/build/schema/engine/_refine.mjs +9 -14
- package/node_modules/typebox/build/schema/engine/_stack.d.mts +20 -34
- package/node_modules/typebox/build/schema/engine/_stack.mjs +202 -143
- package/node_modules/typebox/build/schema/engine/_unique.d.mts +2 -4
- package/node_modules/typebox/build/schema/engine/_unique.mjs +3 -7
- package/node_modules/typebox/build/schema/engine/additionalItems.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/additionalItems.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/additionalProperties.d.mts +8 -5
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +32 -27
- package/node_modules/typebox/build/schema/engine/allOf.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/allOf.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/anyOf.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/anyOf.mjs +9 -4
- package/node_modules/typebox/build/schema/engine/boolean.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/boolean.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/const.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/const.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/contains.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/contains.mjs +9 -5
- package/node_modules/typebox/build/schema/engine/dependencies.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/dependencies.mjs +7 -5
- package/node_modules/typebox/build/schema/engine/dependentRequired.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/dependentRequired.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/dependentSchemas.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +1 -2
- package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +8 -12
- package/node_modules/typebox/build/schema/engine/enum.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/enum.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/exclusiveMaximum.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/exclusiveMaximum.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/exclusiveMinimum.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/exclusiveMinimum.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/format.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/format.mjs +8 -11
- package/node_modules/typebox/build/schema/engine/if.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/if.mjs +13 -5
- package/node_modules/typebox/build/schema/engine/index.d.mts +0 -1
- package/node_modules/typebox/build/schema/engine/index.mjs +0 -1
- package/node_modules/typebox/build/schema/engine/items.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/items.mjs +5 -8
- package/node_modules/typebox/build/schema/engine/maxContains.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/maxContains.mjs +8 -4
- package/node_modules/typebox/build/schema/engine/maxItems.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/maxItems.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/maxLength.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/maxLength.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/maxProperties.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/maxProperties.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/maximum.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/maximum.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/minContains.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/minContains.mjs +9 -5
- package/node_modules/typebox/build/schema/engine/minItems.d.mts +5 -5
- package/node_modules/typebox/build/schema/engine/minItems.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/minLength.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/minLength.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/minProperties.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/minProperties.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/minimum.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/minimum.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/multipleOf.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/multipleOf.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/not.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/not.mjs +8 -4
- package/node_modules/typebox/build/schema/engine/oneOf.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/oneOf.mjs +11 -6
- package/node_modules/typebox/build/schema/engine/pattern.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/pattern.mjs +7 -3
- package/node_modules/typebox/build/schema/engine/patternProperties.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +5 -6
- package/node_modules/typebox/build/schema/engine/prefixItems.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/prefixItems.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/properties.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/properties.mjs +3 -4
- package/node_modules/typebox/build/schema/engine/propertyNames.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/propertyNames.mjs +10 -7
- package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +8 -12
- package/node_modules/typebox/build/schema/engine/ref.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/ref.mjs +14 -18
- package/node_modules/typebox/build/schema/engine/required.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/required.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/schema.d.mts +7 -7
- package/node_modules/typebox/build/schema/engine/schema.mjs +138 -136
- package/node_modules/typebox/build/schema/engine/type.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/type.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/unevaluatedItems.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/unevaluatedItems.mjs +9 -5
- package/node_modules/typebox/build/schema/engine/unevaluatedProperties.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/unevaluatedProperties.mjs +9 -5
- package/node_modules/typebox/build/schema/engine/uniqueItems.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/uniqueItems.mjs +6 -2
- package/node_modules/typebox/build/schema/errors.mjs +1 -1
- package/node_modules/typebox/build/schema/intern/intern.d.mts +9 -6
- package/node_modules/typebox/build/schema/intern/intern.mjs +56 -90
- package/node_modules/typebox/build/schema/parse.mjs +0 -3
- package/node_modules/typebox/build/schema/pointer/pointer.d.mts +6 -1
- package/node_modules/typebox/build/schema/pointer/pointer.mjs +64 -47
- package/node_modules/typebox/build/schema/resolve/resolve.d.mts +32 -6
- package/node_modules/typebox/build/schema/resolve/resolve.mjs +227 -231
- package/node_modules/typebox/build/schema/schema.d.mts +0 -1
- package/node_modules/typebox/build/schema/schema.mjs +0 -1
- package/node_modules/typebox/build/system/hashing/hash.mjs +34 -63
- package/node_modules/typebox/build/system/locale/en_US.mjs +1 -2
- package/node_modules/typebox/build/system/memory/assign.d.mts +8 -2
- package/node_modules/typebox/build/system/memory/assign.mjs +6 -13
- package/node_modules/typebox/build/system/memory/clone.d.mts +5 -4
- package/node_modules/typebox/build/system/memory/clone.mjs +96 -8
- package/node_modules/typebox/build/system/memory/create.d.mts +5 -1
- package/node_modules/typebox/build/system/memory/create.mjs +13 -18
- package/node_modules/typebox/build/system/memory/discard.d.mts +1 -1
- package/node_modules/typebox/build/system/memory/discard.mjs +8 -9
- package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
- package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
- package/node_modules/typebox/build/system/memory/update.d.mts +4 -1
- package/node_modules/typebox/build/system/memory/update.mjs +16 -43
- package/node_modules/typebox/build/system/settings/settings.d.mts +0 -11
- package/node_modules/typebox/build/system/settings/settings.mjs +0 -14
- package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +24 -2
- package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +29 -2
- package/node_modules/typebox/build/type/engine/evaluate/index.d.mts +0 -1
- package/node_modules/typebox/build/type/engine/evaluate/index.mjs +0 -1
- package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +1 -5
- package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +1 -6
- package/node_modules/typebox/build/type/engine/immutable/instantiate_add.d.mts +3 -1
- package/node_modules/typebox/build/type/engine/immutable/instantiate_add.mjs +4 -1
- package/node_modules/typebox/build/type/engine/object/from_intersect.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/object/from_intersect.mjs +2 -2
- package/node_modules/typebox/build/type/engine/object/from_union.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/object/from_union.mjs +2 -2
- package/node_modules/typebox/build/type/engine/optional/instantiate_add.d.mts +3 -1
- package/node_modules/typebox/build/type/engine/optional/instantiate_add.mjs +4 -1
- package/node_modules/typebox/build/type/engine/readonly/instantiate_add.d.mts +3 -1
- package/node_modules/typebox/build/type/engine/readonly/instantiate_add.mjs +4 -1
- package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
- package/node_modules/typebox/build/type/extends/inference.mjs +2 -15
- package/node_modules/typebox/build/type/extends/tuple.d.mts +1 -2
- package/node_modules/typebox/build/type/extends/tuple.mjs +1 -21
- package/node_modules/typebox/build/value/clean/from_object.mjs +1 -1
- package/node_modules/typebox/build/value/clone/clone.d.mts +3 -4
- package/node_modules/typebox/build/value/clone/clone.mjs +7 -5
- package/node_modules/typebox/build/value/parse/parse.mjs +4 -10
- package/node_modules/typebox/build/value/shared/union_priority_sort.mjs +14 -25
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +84 -52
- package/package.json +11 -3
- package/skills/pi-proactive/SKILL.md +27 -24
- package/tools/cli.mjs +121 -0
- package/tools/daemon-install.sh +397 -0
- package/tools/daemon-uninstall.sh +226 -0
- package/node_modules/typebox/build/guard/unicode/unicode.d.mts +0 -6
- package/node_modules/typebox/build/guard/unicode/unicode.mjs +0 -35
- package/node_modules/typebox/build/schema/engine/_pathing.d.mts +0 -1
- package/node_modules/typebox/build/schema/engine/_pathing.mjs +0 -11
- package/node_modules/typebox/build/schema/meta/draft_2019_09.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_2019_09.mjs +0 -288
- package/node_modules/typebox/build/schema/meta/draft_2020_12.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_2020_12.mjs +0 -300
- package/node_modules/typebox/build/schema/meta/draft_3.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_3.mjs +0 -143
- package/node_modules/typebox/build/schema/meta/draft_4.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_4.mjs +0 -149
- package/node_modules/typebox/build/schema/meta/draft_6.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_6.mjs +0 -155
- package/node_modules/typebox/build/schema/meta/draft_7.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_7.mjs +0 -172
- package/node_modules/typebox/build/schema/meta/index.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/index.mjs +0 -2
- package/node_modules/typebox/build/schema/meta/meta.d.mts +0 -9
- package/node_modules/typebox/build/schema/meta/meta.mjs +0 -15
- package/node_modules/typebox/build/schema/meta/schema.d.mts +0 -6
- package/node_modules/typebox/build/schema/meta/schema.mjs +0 -1
- package/node_modules/typebox/build/system/memory/deep.d.mts +0 -2
- package/node_modules/typebox/build/system/memory/deep.mjs +0 -108
- package/node_modules/typebox/build/system/memory/finalize.d.mts +0 -4
- package/node_modules/typebox/build/system/memory/finalize.mjs +0 -30
- package/node_modules/typebox/build/system/memory/keys.d.mts +0 -2
- package/node_modules/typebox/build/system/memory/keys.mjs +0 -8
- package/node_modules/typebox/build/system/settings/internal.d.mts +0 -2
- package/node_modules/typebox/build/system/settings/internal.mjs +0 -20
- package/node_modules/typebox/build/type/engine/call/index.d.mts +0 -1
- package/node_modules/typebox/build/type/engine/call/index.mjs +0 -1
- package/node_modules/typebox/build/type/engine/evaluate/property.d.mts +0 -30
- package/node_modules/typebox/build/type/engine/evaluate/property.mjs +0 -29
- package/node_modules/typebox/build/type/engine/this/index.d.mts +0 -1
- package/node_modules/typebox/build/type/engine/this/index.mjs +0 -1
- package/node_modules/typebox/build/value/repair/from_cyclic.d.mts +0 -2
- package/node_modules/typebox/build/value/repair/from_cyclic.mjs +0 -6
- /package/node_modules/typebox/build/guard/{unicode/unicode_segment.d.mts → string.d.mts} +0 -0
|
@@ -1,67 +1,49 @@
|
|
|
1
|
+
// deno-fmt-ignore-file
|
|
1
2
|
import { Guard } from '../../guard/index.mjs';
|
|
2
3
|
import { Pointer } from '../pointer/index.mjs';
|
|
3
4
|
import * as Schema from '../types/index.mjs';
|
|
4
|
-
|
|
5
|
+
export const DefaultBase = 'https://json-schema.org';
|
|
5
6
|
// ------------------------------------------------------------------
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// Utilities to compute schema base URIs, normalize absolute URLs,
|
|
9
|
-
// strip URL fragments for canonical hrefs, find target base URIs,
|
|
10
|
-
// resolve $ref root schemas, and identify JSON pointers vs anchors.
|
|
11
|
-
// ------------------------------------------------------------------
|
|
12
|
-
function RelativeBase(schema, base) {
|
|
13
|
-
return Schema.IsSchemaObject(schema) && Schema.IsId(schema) ? Stack.NextUri(schema.$id, base.href) : base;
|
|
14
|
-
}
|
|
15
|
-
function AbsoluteBase(base) {
|
|
16
|
-
return Stack.NextUri(base, Stack.DefaultUri);
|
|
17
|
-
}
|
|
18
|
-
function CanonicalHref(url) {
|
|
19
|
-
return url.href.split('#')[0];
|
|
20
|
-
}
|
|
21
|
-
function Base(schema, base, target) {
|
|
22
|
-
return SearchBase(schema, AbsoluteBase(base), target);
|
|
23
|
-
}
|
|
24
|
-
function RefRoot(stack, ref) {
|
|
25
|
-
return (ref.$ref.startsWith('#') || stack.enteredResource) ? stack.lexicalSchema : stack.schema;
|
|
26
|
-
}
|
|
27
|
-
function IsPointerFragment(fragment) {
|
|
28
|
-
return fragment.startsWith('#/');
|
|
29
|
-
}
|
|
30
|
-
// ------------------------------------------------------------------
|
|
31
|
-
// Search
|
|
32
|
-
//
|
|
33
|
-
// Recursive tree walks that locate things by identity, not URL.
|
|
34
|
-
// SearchDynamicAnchor finds a node with a matching $dynamicAnchor.
|
|
35
|
-
// SearchBase finds a specific target schema (by reference) and
|
|
36
|
-
// returns its base URI, tracking $id rebasing as it descends.
|
|
7
|
+
// Find: FindDynamicAnchor
|
|
37
8
|
// ------------------------------------------------------------------
|
|
38
|
-
function
|
|
9
|
+
function FindDynamicAnchor(schema, name) {
|
|
39
10
|
if (Guard.IsObject(schema) && Schema.IsDynamicAnchor(schema) && Guard.IsEqual(schema.$dynamicAnchor, name)) {
|
|
40
11
|
return schema;
|
|
41
12
|
}
|
|
42
13
|
if (Guard.IsObject(schema)) {
|
|
43
14
|
for (const key of Guard.Keys(schema)) {
|
|
44
|
-
const result =
|
|
15
|
+
const result = FindDynamicAnchor(schema[key], name);
|
|
45
16
|
if (result)
|
|
46
17
|
return result;
|
|
47
18
|
}
|
|
48
19
|
}
|
|
20
|
+
// (no-coverage) - is it even possible to search for an anchor
|
|
21
|
+
// with embedded logical schema like allOf, anyOf, etc?
|
|
22
|
+
// if (Guard.IsArray(schema)) { // (no-coverage)
|
|
23
|
+
// for (const item of schema) {
|
|
24
|
+
// const result = FindDynamicAnchor(item, name)
|
|
25
|
+
// if (result) return result
|
|
26
|
+
// }
|
|
27
|
+
// }
|
|
49
28
|
return undefined;
|
|
50
29
|
}
|
|
51
|
-
|
|
30
|
+
// ------------------------------------------------------------------
|
|
31
|
+
// Find: FindBase
|
|
32
|
+
// ------------------------------------------------------------------
|
|
33
|
+
function FindBase(schema, base, target) {
|
|
52
34
|
if (Guard.IsEqual(schema, target))
|
|
53
35
|
return base.href;
|
|
54
|
-
const nextBase =
|
|
36
|
+
const nextBase = Schema.IsSchemaObject(schema) && Schema.IsId(schema) ? new URL(schema.$id, base.href) : base;
|
|
55
37
|
if (Guard.IsArray(schema)) {
|
|
56
38
|
for (const item of schema) {
|
|
57
|
-
const result =
|
|
39
|
+
const result = FindBase(item, nextBase, target);
|
|
58
40
|
if (!Guard.IsUndefined(result))
|
|
59
41
|
return result;
|
|
60
42
|
}
|
|
61
43
|
}
|
|
62
44
|
else if (Guard.IsObject(schema)) {
|
|
63
45
|
for (const key of Guard.Keys(schema)) {
|
|
64
|
-
const result =
|
|
46
|
+
const result = FindBase(schema[key], nextBase, target);
|
|
65
47
|
if (!Guard.IsUndefined(result))
|
|
66
48
|
return result;
|
|
67
49
|
}
|
|
@@ -69,263 +51,277 @@ function SearchBase(schema, base, target) {
|
|
|
69
51
|
return undefined;
|
|
70
52
|
}
|
|
71
53
|
// ------------------------------------------------------------------
|
|
72
|
-
// Match
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
//
|
|
76
|
-
// $dynamicAnchor, then JSON pointer/hash. MatchFromArray,
|
|
77
|
-
// MatchFromObject, and Match recurse through the tree to try every
|
|
78
|
-
// node, skipping const and enum since their values are user data,
|
|
79
|
-
// not schema.
|
|
80
|
-
// ------------------------------------------------------------------
|
|
81
|
-
function MatchWithHash(schema, ref) {
|
|
82
|
-
if (ref.href.endsWith('#'))
|
|
83
|
-
return schema;
|
|
84
|
-
if (!ref.hash.startsWith('#'))
|
|
85
|
-
return undefined;
|
|
86
|
-
const fragment = decodeURIComponent(ref.hash.slice(1));
|
|
87
|
-
if (!fragment.startsWith('/'))
|
|
88
|
-
return undefined;
|
|
89
|
-
return Pointer.Get(schema, fragment);
|
|
90
|
-
}
|
|
91
|
-
function MatchWithId(schema, base, ref) {
|
|
92
|
-
if (!Schema.IsId(schema))
|
|
93
|
-
return undefined;
|
|
54
|
+
// Match: MatchId
|
|
55
|
+
// ------------------------------------------------------------------
|
|
56
|
+
function MatchId(schema, base, ref) {
|
|
57
|
+
// ref is a bare fragment naming this schema's $id directly
|
|
94
58
|
if (Guard.IsEqual(schema.$id, ref.hash))
|
|
95
59
|
return schema;
|
|
96
60
|
const absoluteRef = new URL(ref.href, base.href);
|
|
61
|
+
// ref shares this $id's document, so resolve the fragment within it
|
|
97
62
|
if (Guard.IsEqual(base.pathname, absoluteRef.pathname))
|
|
98
|
-
return ref.hash.startsWith('#') ?
|
|
63
|
+
return ref.hash.startsWith('#') ? MatchHash(schema, ref) : schema;
|
|
99
64
|
return undefined;
|
|
100
65
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
66
|
+
// ------------------------------------------------------------------
|
|
67
|
+
// Match: MatchAnchor
|
|
68
|
+
// ------------------------------------------------------------------
|
|
69
|
+
function MatchAnchor(schema, base, ref) {
|
|
104
70
|
const absoluteAnchor = new URL(`#${schema.$anchor}`, base.href);
|
|
105
71
|
const absoluteRef = new URL(ref.href, base.href);
|
|
106
72
|
return Guard.IsEqual(absoluteAnchor.href, absoluteRef.href) ? schema : undefined;
|
|
107
73
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
74
|
+
// ------------------------------------------------------------------
|
|
75
|
+
// Match: MatchDynamicAnchor
|
|
76
|
+
// ------------------------------------------------------------------
|
|
77
|
+
function MatchDynamicAnchor(schema, base, ref) {
|
|
111
78
|
const absoluteAnchor = new URL(`#${schema.$dynamicAnchor}`, base.href);
|
|
112
79
|
const absoluteRef = new URL(ref.href, base.href);
|
|
113
80
|
const isMatch = Guard.IsEqual(absoluteAnchor.href, absoluteRef.href);
|
|
114
81
|
return isMatch ? schema : undefined;
|
|
115
82
|
}
|
|
116
|
-
|
|
117
|
-
|
|
83
|
+
// ------------------------------------------------------------------
|
|
84
|
+
// Match: MatchHash
|
|
85
|
+
// ------------------------------------------------------------------
|
|
86
|
+
function MatchHash(schema, ref) {
|
|
87
|
+
if (ref.href.endsWith('#'))
|
|
88
|
+
return schema;
|
|
89
|
+
if (!ref.hash.startsWith('#'))
|
|
118
90
|
return undefined;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
MatchWithDynamicAnchor(schema, base, ref) ??
|
|
122
|
-
MatchWithHash(schema, ref);
|
|
123
|
-
}
|
|
124
|
-
function MatchFromArray(schema, base, ref) {
|
|
125
|
-
if (!Guard.IsArray(schema))
|
|
91
|
+
const fragment = decodeURIComponent(ref.hash.slice(1));
|
|
92
|
+
if (!fragment.startsWith('/'))
|
|
126
93
|
return undefined;
|
|
94
|
+
const result = Pointer.Get(schema, fragment);
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
// ------------------------------------------------------------------
|
|
98
|
+
// Match: Match
|
|
99
|
+
// ------------------------------------------------------------------
|
|
100
|
+
function Match(schema, base, ref) {
|
|
101
|
+
if (Schema.IsId(schema)) {
|
|
102
|
+
const result = MatchId(schema, base, ref);
|
|
103
|
+
if (!Guard.IsUndefined(result))
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
if (Schema.IsAnchor(schema)) {
|
|
107
|
+
const result = MatchAnchor(schema, base, ref);
|
|
108
|
+
if (!Guard.IsUndefined(result))
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
if (Schema.IsDynamicAnchor(schema)) {
|
|
112
|
+
const result = MatchDynamicAnchor(schema, base, ref);
|
|
113
|
+
if (!Guard.IsUndefined(result))
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
return MatchHash(schema, ref);
|
|
117
|
+
}
|
|
118
|
+
// ------------------------------------------------------------------
|
|
119
|
+
// FromArray
|
|
120
|
+
// ------------------------------------------------------------------
|
|
121
|
+
function FromArray(schema, base, ref) {
|
|
127
122
|
return schema.reduce((result, item) => {
|
|
128
|
-
const match =
|
|
123
|
+
const match = FromValue(item, base, ref);
|
|
129
124
|
return !Guard.IsUndefined(match) ? match : result;
|
|
130
125
|
}, undefined);
|
|
131
126
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
127
|
+
// ------------------------------------------------------------------
|
|
128
|
+
// FromObject
|
|
129
|
+
// ------------------------------------------------------------------
|
|
130
|
+
function SkipProperty(key) {
|
|
131
|
+
return Guard.IsEqual(key, 'const') || Guard.IsEqual(key, 'enum');
|
|
132
|
+
}
|
|
133
|
+
function FromObject(schema, base, ref) {
|
|
135
134
|
return Guard.Keys(schema).reduce((result, key) => {
|
|
136
|
-
if (
|
|
135
|
+
if (SkipProperty(key))
|
|
137
136
|
return result;
|
|
138
|
-
const match =
|
|
137
|
+
const match = FromValue(schema[key], base, ref);
|
|
139
138
|
return !Guard.IsUndefined(match) ? match : result;
|
|
140
139
|
}, undefined);
|
|
141
140
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
// ------------------------------------------------------------------
|
|
142
|
+
// FromValue
|
|
143
|
+
// ------------------------------------------------------------------
|
|
144
|
+
function FromValue(schema, base, ref) {
|
|
145
|
+
const nextBase = Schema.IsSchemaObject(schema) && Schema.IsId(schema) ? new URL(schema.$id, base.href) : base;
|
|
146
|
+
if (Schema.IsSchemaObject(schema)) {
|
|
147
|
+
const result = Match(schema, nextBase, ref);
|
|
148
|
+
if (!Guard.IsUndefined(result))
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
if (Guard.IsArray(schema))
|
|
152
|
+
return FromArray(schema, nextBase, ref);
|
|
153
|
+
if (Guard.IsObject(schema))
|
|
154
|
+
return FromObject(schema, nextBase, ref);
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
// ------------------------------------------------------------------
|
|
158
|
+
// Base
|
|
159
|
+
// ------------------------------------------------------------------
|
|
160
|
+
export function Base(schema, base, target) {
|
|
161
|
+
return FindBase(schema, new URL(base || '.', DefaultBase), target);
|
|
147
162
|
}
|
|
148
163
|
// ------------------------------------------------------------------
|
|
149
164
|
// Resource
|
|
150
|
-
//
|
|
151
|
-
// Wraps RefInternal to check whether the resolved schema is itself
|
|
152
|
-
// a resource root (carries its own $id). Used by FindResolvedResource
|
|
153
|
-
// to tell a boundary hit from a landing inside a resource.
|
|
154
165
|
// ------------------------------------------------------------------
|
|
155
|
-
function Resource(context, schema, base, ref) {
|
|
156
|
-
const result =
|
|
166
|
+
export function Resource(context, schema, base, ref) {
|
|
167
|
+
const result = Ref(context, schema, base, ref, false);
|
|
157
168
|
return Schema.IsSchemaObject(result) && Schema.IsId(result) ? result : undefined;
|
|
158
169
|
}
|
|
159
170
|
// ------------------------------------------------------------------
|
|
160
|
-
//
|
|
171
|
+
// CanonicalHref
|
|
172
|
+
// ------------------------------------------------------------------
|
|
173
|
+
function CanonicalHref(url) {
|
|
174
|
+
return url.href.split('#')[0];
|
|
175
|
+
}
|
|
176
|
+
// ------------------------------------------------------------------
|
|
177
|
+
// Ref: RefRemote (Phase 1)
|
|
178
|
+
// ------------------------------------------------------------------
|
|
179
|
+
function RefContext(context, ref) {
|
|
180
|
+
return Guard.HasPropertyKey(context, ref) ? context[ref] : undefined;
|
|
181
|
+
}
|
|
182
|
+
// ------------------------------------------------------------------
|
|
183
|
+
// Ref: RefRemote (Phase 2)
|
|
184
|
+
// ------------------------------------------------------------------
|
|
185
|
+
function RefLocal(schema, base, ref) {
|
|
186
|
+
return FromValue(schema, base, ref);
|
|
187
|
+
}
|
|
188
|
+
// ------------------------------------------------------------------
|
|
189
|
+
// Ref: RefRemote (Phase 3)
|
|
190
|
+
// ------------------------------------------------------------------
|
|
191
|
+
function RefRemote(context, base, ref) {
|
|
192
|
+
const canonicalHref = CanonicalHref(ref);
|
|
193
|
+
if (Guard.IsEqual(canonicalHref, CanonicalHref(base)))
|
|
194
|
+
return undefined;
|
|
195
|
+
if (!Guard.HasPropertyKey(context, canonicalHref))
|
|
196
|
+
return undefined;
|
|
197
|
+
const remoteSchema = context[canonicalHref];
|
|
198
|
+
const remoteBase = (Schema.IsSchemaObject(remoteSchema) && Schema.IsId(remoteSchema)) ? new URL(remoteSchema.$id, canonicalHref) : new URL(canonicalHref);
|
|
199
|
+
const result = Guard.IsEqual(ref.hash, '') ? remoteSchema : FromValue(remoteSchema, remoteBase, ref);
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
// ------------------------------------------------------------------
|
|
203
|
+
// RetrievedResource: LegacyRetrievedResource
|
|
161
204
|
//
|
|
162
|
-
//
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
//
|
|
205
|
+
// Draft-4 style schemas (no $schema keyword) treat a nested $id as an
|
|
206
|
+
// in-place base URI change rather than a new resource boundary. A
|
|
207
|
+
// local ('#...') ref that lands somewhere with a different base than
|
|
208
|
+
// the current reference base needs a frame so later anchor/pointer
|
|
209
|
+
// resolution is computed against the right base.
|
|
166
210
|
// ------------------------------------------------------------------
|
|
167
|
-
function
|
|
211
|
+
function LegacyRetrievedResource(root, lexicalSchema, referenceBase, ref, schema) {
|
|
168
212
|
if (!ref.$ref.startsWith('#'))
|
|
169
213
|
return undefined;
|
|
170
|
-
if (
|
|
214
|
+
if (Guard.HasPropertyKey(root, '$schema'))
|
|
171
215
|
return undefined;
|
|
172
|
-
const targetBase = Base(
|
|
173
|
-
if (Guard.IsUndefined(targetBase) || Guard.IsEqual(targetBase,
|
|
216
|
+
const targetBase = Base(lexicalSchema, referenceBase, schema);
|
|
217
|
+
if (Guard.IsUndefined(targetBase) || Guard.IsEqual(targetBase, referenceBase))
|
|
174
218
|
return undefined;
|
|
175
|
-
return { target: schema, base: targetBase, root:
|
|
219
|
+
return { target: schema, base: targetBase, root: lexicalSchema };
|
|
176
220
|
}
|
|
177
|
-
|
|
178
|
-
|
|
221
|
+
// ------------------------------------------------------------------
|
|
222
|
+
// RetrievedResource: RemoteRetrievedResource
|
|
223
|
+
//
|
|
224
|
+
// The ref's canonical URL names a document already loaded into
|
|
225
|
+
// context. That document becomes the frame's root going forward.
|
|
226
|
+
// ------------------------------------------------------------------
|
|
227
|
+
function RemoteRetrievedResource(context, canonical, schema) {
|
|
228
|
+
const remoteRoot = context[canonical];
|
|
179
229
|
if (!Schema.IsSchemaObject(remoteRoot))
|
|
180
230
|
return undefined;
|
|
181
231
|
return { target: schema, base: canonical, root: remoteRoot };
|
|
182
232
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
233
|
+
// ------------------------------------------------------------------
|
|
234
|
+
// RetrievedResource
|
|
235
|
+
//
|
|
236
|
+
// A genuinely remote document frame always wins over a same-document
|
|
237
|
+
// legacy one: only one frame is ever entered per ref.
|
|
238
|
+
// ------------------------------------------------------------------
|
|
239
|
+
function FindRetrievedResource(stackframe, ref, schema, canonical, isRemote) {
|
|
240
|
+
const remote = isRemote ? RemoteRetrievedResource(stackframe.context, canonical, schema) : undefined;
|
|
241
|
+
if (!Guard.IsUndefined(remote))
|
|
242
|
+
return remote;
|
|
243
|
+
return LegacyRetrievedResource(stackframe.root, stackframe.lexicalSchema, stackframe.referenceBase, ref, schema);
|
|
186
244
|
}
|
|
187
245
|
// ------------------------------------------------------------------
|
|
188
|
-
// FindResolvedResource
|
|
246
|
+
// ResolvedResource: FindResolvedResource
|
|
189
247
|
//
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
// middle of a remote document).
|
|
193
|
-
// lexical/base lookups behave as if traversal
|
|
248
|
+
// The ref crossed into a different resource but landed on a schema
|
|
249
|
+
// that doesn't itself carry that resource's $id (e.g. a pointer into
|
|
250
|
+
// the middle of a remote document). The enclosing resource still
|
|
251
|
+
// needs to be entered so lexical/base lookups behave as if traversal
|
|
252
|
+
// had walked in from its top.
|
|
194
253
|
// ------------------------------------------------------------------
|
|
195
|
-
function FindResolvedResource(
|
|
254
|
+
function FindResolvedResource(context, root, referenceBase, canonical, schema, ids) {
|
|
196
255
|
if (Schema.IsId(schema))
|
|
197
256
|
return undefined;
|
|
198
|
-
const resource = Resource(
|
|
199
|
-
if (!resource ||
|
|
257
|
+
const resource = Resource(context, root, referenceBase, canonical);
|
|
258
|
+
if (!resource || ids.includes(resource))
|
|
200
259
|
return undefined;
|
|
201
|
-
return { resource };
|
|
260
|
+
return { target: schema, resource };
|
|
202
261
|
}
|
|
203
262
|
// ------------------------------------------------------------------
|
|
204
|
-
//
|
|
205
|
-
//
|
|
206
|
-
// Shared lookup used by Ref, RecursiveRef, and DynamicRef. Tries,
|
|
207
|
-
// in order: exact match in the pre-registered context, then a local
|
|
208
|
-
// search within the given schema, then a search in a remote
|
|
209
|
-
// document. Returns just the schema; caller-specific bookkeeping
|
|
210
|
-
// (deferred/resolved resources) happens one level up.
|
|
263
|
+
// Ref
|
|
211
264
|
// ------------------------------------------------------------------
|
|
212
|
-
function
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return
|
|
217
|
-
}
|
|
218
|
-
function RefInternalWithRemote(context, base, ref) {
|
|
219
|
-
const canonicalHref = CanonicalHref(ref);
|
|
220
|
-
if (!Guard.HasPropertyKey(context, canonicalHref) || Guard.IsEqual(canonicalHref, CanonicalHref(base)))
|
|
221
|
-
return undefined;
|
|
222
|
-
const remoteSchema = context[canonicalHref];
|
|
223
|
-
const remoteBase = RelativeBase(remoteSchema, new URL(canonicalHref));
|
|
224
|
-
return Guard.IsEqual(ref.hash, '') ? remoteSchema : Match(remoteSchema, remoteBase, ref);
|
|
225
|
-
}
|
|
226
|
-
function RefInternal(context, schema, base, ref) {
|
|
227
|
-
const absoluteBase = AbsoluteBase(base);
|
|
228
|
-
const target = Stack.NextUri(ref, absoluteBase.href);
|
|
229
|
-
return RefInternalWithContext(context, ref) ??
|
|
230
|
-
RefInternalWithLocal(schema, absoluteBase, target) ??
|
|
231
|
-
RefInternalWithRemote(context, absoluteBase, target);
|
|
265
|
+
export function Ref(remotes, schema, base, ref, applySchemaId = true) {
|
|
266
|
+
const initialBase = new URL(base || '.', DefaultBase);
|
|
267
|
+
const resolvedBase = applySchemaId && Schema.IsId(schema) ? new URL(schema.$id, initialBase) : initialBase;
|
|
268
|
+
const initialRef = new URL(ref, resolvedBase.href);
|
|
269
|
+
return RefContext(remotes, ref) ?? RefLocal(schema, resolvedBase, initialRef) ?? RefRemote(remotes, resolvedBase, initialRef);
|
|
232
270
|
}
|
|
233
271
|
// ------------------------------------------------------------------
|
|
234
|
-
//
|
|
235
|
-
//
|
|
236
|
-
// Computes the next stack state from any deferred or resolved
|
|
237
|
-
// resource found while following a $ref, carrying existing stack
|
|
238
|
-
// state forward rather than rebuilding it.
|
|
239
|
-
// ------------------------------------------------------------------
|
|
240
|
-
function RefNextStackDeferred(stack, deferredResource) {
|
|
241
|
-
if (!deferredResource)
|
|
242
|
-
return stack;
|
|
243
|
-
const resourceEntries = new Map(stack.resourceEntries);
|
|
244
|
-
resourceEntries.set(deferredResource.target, { base: deferredResource.base, root: deferredResource.root });
|
|
245
|
-
return { ...stack, resourceEntries };
|
|
246
|
-
}
|
|
247
|
-
function RefNextStackResolved(stack, resolvedResource) {
|
|
248
|
-
return resolvedResource ? Stack.NextStack(stack, resolvedResource.resource) : stack;
|
|
249
|
-
}
|
|
250
|
-
function RefNextStack(stack, pendingResource, deferredResource, resolvedResource) {
|
|
251
|
-
const withDeferred = RefNextStackDeferred({ ...stack, pendingResource }, deferredResource);
|
|
252
|
-
const withResolved = RefNextStackResolved(withDeferred, resolvedResource);
|
|
253
|
-
return withResolved;
|
|
254
|
-
}
|
|
272
|
+
// DynamicRef
|
|
255
273
|
// ------------------------------------------------------------------
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
274
|
+
export function DynamicRef(context, root, base, schema, dynamicRef, dynamicAnchors) {
|
|
275
|
+
const initialBase = new URL(base || '.', DefaultBase);
|
|
276
|
+
const fragmentRoot = dynamicRef.$dynamicRef.startsWith('#') ? schema : root;
|
|
277
|
+
const fragmentTarget = Ref(context, fragmentRoot, base, dynamicRef.$dynamicRef, false);
|
|
278
|
+
if (Guard.IsUndefined(fragmentTarget)) {
|
|
279
|
+
const fragment = new URL(dynamicRef.$dynamicRef, initialBase).hash;
|
|
280
|
+
if (!fragment.startsWith('#/') && fragment.startsWith('#')) {
|
|
281
|
+
const name = decodeURIComponent(fragment.slice(1));
|
|
282
|
+
const anchorTarget = dynamicAnchors.find((anchor) => Guard.IsEqual(anchor.$dynamicAnchor, name)) ?? FindDynamicAnchor(root, name);
|
|
283
|
+
return anchorTarget;
|
|
284
|
+
}
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
if (!Schema.IsSchemaObject(fragmentTarget) || !Schema.IsDynamicAnchor(fragmentTarget))
|
|
288
|
+
return fragmentTarget;
|
|
289
|
+
const fragment = new URL(dynamicRef.$dynamicRef, initialBase).hash;
|
|
290
|
+
if (fragment.startsWith('#/'))
|
|
291
|
+
return fragmentTarget;
|
|
292
|
+
const anchorTarget = dynamicAnchors.find((anchor) => Guard.IsEqual(anchor.$dynamicAnchor, fragmentTarget.$dynamicAnchor));
|
|
293
|
+
return anchorTarget ?? fragmentTarget;
|
|
273
294
|
}
|
|
274
295
|
// ------------------------------------------------------------------
|
|
275
|
-
//
|
|
296
|
+
// ResolveRef
|
|
276
297
|
//
|
|
277
|
-
//
|
|
278
|
-
//
|
|
279
|
-
//
|
|
298
|
+
// Resolves the schema a $ref points to, and describes whether that
|
|
299
|
+
// crossing implies a "retrieved resource" frame or entering a
|
|
300
|
+
// resource the target doesn't itself carry the $id for. The caller
|
|
301
|
+
// decides whether and how to record these.
|
|
280
302
|
// ------------------------------------------------------------------
|
|
281
|
-
export function
|
|
282
|
-
const
|
|
283
|
-
|
|
303
|
+
export function ResolveRef(stackframe, ref) {
|
|
304
|
+
const source = stackframe.inRetrievedFrame ? stackframe.lexicalSchema : stackframe.root;
|
|
305
|
+
const refRoot = ref.$ref.startsWith('#') ? stackframe.lexicalSchema : source;
|
|
306
|
+
const schema = Ref(stackframe.context, refRoot, stackframe.referenceBase, ref.$ref, false);
|
|
307
|
+
if (!schema || !Schema.IsSchemaObject(schema))
|
|
308
|
+
return { schema };
|
|
309
|
+
const canonical = new URL(ref.$ref, stackframe.referenceBase).href.split('#')[0];
|
|
310
|
+
const isRemote = !Guard.IsEqual(canonical, stackframe.resourceBase);
|
|
311
|
+
const retrievedResource = FindRetrievedResource(stackframe, ref, schema, canonical, isRemote);
|
|
312
|
+
const resolvedResource = isRemote ? FindResolvedResource(stackframe.context, stackframe.root, stackframe.referenceBase, canonical, schema, stackframe.ids) : undefined;
|
|
313
|
+
return { schema, retrievedResource, resolvedResource };
|
|
284
314
|
}
|
|
285
315
|
// ------------------------------------------------------------------
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
// If a $recursiveAnchor is active in scope, it's used as the root
|
|
289
|
-
// instead of the lexical schema, letting the ref bind to the
|
|
290
|
-
// outermost applicable schema rather than the innermost.
|
|
316
|
+
// ResolveRecursiveRef
|
|
291
317
|
// ------------------------------------------------------------------
|
|
292
|
-
function
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
export function RecursiveRef(stack, recursiveRef) {
|
|
296
|
-
const schema = IsRecursiveAnchorInScope(stack) ? stack.recursiveAnchor : stack.lexicalSchema;
|
|
297
|
-
return RefInternal(stack.context, schema, stack.lexicalBase, recursiveRef.$recursiveRef);
|
|
318
|
+
export function ResolveRecursiveRef(stackframe, recursiveRef) {
|
|
319
|
+
const refRoot = Schema.IsRecursiveAnchorTrue(stackframe.lexicalSchema) ? stackframe.recursiveAnchors[0] : stackframe.lexicalSchema;
|
|
320
|
+
return Ref(stackframe.context, refRoot, stackframe.lexicalBase, recursiveRef.$recursiveRef, false);
|
|
298
321
|
}
|
|
299
322
|
// ------------------------------------------------------------------
|
|
300
|
-
//
|
|
301
|
-
//
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
// directly, DynamicRefWhenFound only continues the scoped search when
|
|
305
|
-
// that target itself has a $dynamicAnchor. If RefInternal finds nothing,
|
|
306
|
-
// DynamicRefWhenNotFound goes straight to a scoped anchor search
|
|
307
|
-
// by name.
|
|
308
|
-
// ------------------------------------------------------------------
|
|
309
|
-
function DynamicRefFragment(stack, dynamicRef) {
|
|
310
|
-
return Stack.NextUri(dynamicRef.$dynamicRef, AbsoluteBase(stack.lexicalBase).href).hash;
|
|
311
|
-
}
|
|
312
|
-
function FindScopedDynamicAnchor(stack, name) {
|
|
313
|
-
return stack.dynamicAnchors.find((anchor) => Guard.IsEqual(anchor.$dynamicAnchor, name)) ?? SearchDynamicAnchor(stack.schema, name);
|
|
314
|
-
}
|
|
315
|
-
function DynamicRefWhenFound(stack, dynamicRef, fragmentTarget) {
|
|
316
|
-
if (!Schema.IsSchemaObject(fragmentTarget) || !Schema.IsDynamicAnchor(fragmentTarget))
|
|
317
|
-
return fragmentTarget;
|
|
318
|
-
const fragment = DynamicRefFragment(stack, dynamicRef);
|
|
319
|
-
return IsPointerFragment(fragment) ? fragmentTarget : FindScopedDynamicAnchor(stack, fragmentTarget.$dynamicAnchor);
|
|
320
|
-
}
|
|
321
|
-
function DynamicRefWhenNotFound(stack, dynamicRef) {
|
|
322
|
-
const fragment = DynamicRefFragment(stack, dynamicRef);
|
|
323
|
-
// (review): We never observe this condition, but should be able to reach here in coverage.
|
|
324
|
-
// if (IsPointerFragment(fragment) || !fragment.startsWith('#')) return undefined
|
|
325
|
-
return FindScopedDynamicAnchor(stack, decodeURIComponent(fragment.slice(1)));
|
|
326
|
-
}
|
|
327
|
-
export function DynamicRef(stack, dynamicRef) {
|
|
328
|
-
const fragmentRoot = dynamicRef.$dynamicRef.startsWith('#') ? stack.lexicalSchema : stack.schema;
|
|
329
|
-
const fragmentTarget = RefInternal(stack.context, fragmentRoot, stack.lexicalBase, dynamicRef.$dynamicRef);
|
|
330
|
-
return Guard.IsUndefined(fragmentTarget) ? DynamicRefWhenNotFound(stack, dynamicRef) : DynamicRefWhenFound(stack, dynamicRef, fragmentTarget);
|
|
323
|
+
// ResolveDynamicRef
|
|
324
|
+
// ------------------------------------------------------------------
|
|
325
|
+
export function ResolveDynamicRef(stackframe, dynamicRef) {
|
|
326
|
+
return DynamicRef(stackframe.context, stackframe.root, stackframe.lexicalBase, stackframe.lexicalSchema, dynamicRef, stackframe.dynamicAnchors);
|
|
331
327
|
}
|