@entelekheia/ref-id 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,87 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ //
3
+ // The one registry that maps a NAME the spec uses to behaviour: the owning validators (by
4
+ // `dispatch.<type>.validator`), the ways a delegated string is formed (by `dispatch.<type>.delegate`),
5
+ // the refinement range constraints (by `refinements.<key>.range`), and the policies this package
6
+ // implements (`unknownKey`, `repeatedKey`). A validator or delegate name the spec uses and this file
7
+ // does not know degrades to `uncovered`; a range or policy name it does not know is a version
8
+ // mismatch and is refused loudly, because silently skipping a constraint is the drift the guardrail
9
+ // forbids.
10
+ import { PackageURL } from "packageurl-js";
11
+ import { FIELD, pattern } from "./grammar.js";
12
+ import { SpecVersionError } from "./spec.js";
13
+ const validators = {
14
+ "package-url": (_spec, _entry, delegated) => {
15
+ try {
16
+ return { ok: true, canonical: PackageURL.fromString(delegated).toString() };
17
+ }
18
+ catch {
19
+ return { ok: false };
20
+ }
21
+ },
22
+ "declared-name": (spec, entry, delegated) => ({ ok: pattern(spec, entry.pattern ?? "").test(delegated) }),
23
+ };
24
+ /** How `dispatch.<type>.delegate` forms the delegated string, and whether a producer may pass the format's own scheme back in. */
25
+ const delegators = {
26
+ "type-prefixed": { form: (type, locator) => `${type}${FIELD}${locator}`, foldsType: true },
27
+ verbatim: { form: (_type, locator) => locator, foldsType: false },
28
+ };
29
+ /** The constraints a refinement may declare beyond its pattern, by the name `refinements.<key>.range` uses. */
30
+ const ranges = {
31
+ ascending: (value, boundSeparator) => {
32
+ const bounds = value.split(boundSeparator).map(Number);
33
+ return bounds.length < 2 || (bounds[0] ?? 0) <= (bounds[1] ?? 0);
34
+ },
35
+ };
36
+ /** The policies this package implements, by the name the spec declares them under. */
37
+ const policies = { unknownKey: "carry-through", repeatedKey: "malformed" };
38
+ const policiesChecked = new WeakSet();
39
+ /** Refuses a spec whose declared policies or range names are ones this package does not implement. */
40
+ export function assertImplemented(spec) {
41
+ if (policiesChecked.has(spec)) {
42
+ return;
43
+ }
44
+ const declared = [
45
+ ["grammar.state.unknownKey", spec.grammar.state.unknownKey],
46
+ ["unknownRefinement", spec.unknownRefinement],
47
+ ["grammar.state.repeatedKey", spec.grammar.state.repeatedKey],
48
+ ["grammar.fragment.repeatedKey", spec.grammar.fragment.repeatedKey],
49
+ ];
50
+ for (const [field, value] of declared) {
51
+ const implemented = field.endsWith("repeatedKey") ? policies.repeatedKey : policies.unknownKey;
52
+ if (value !== implemented) {
53
+ throw new SpecVersionError(`spec.${field} declares ${JSON.stringify(value)}; this package implements only ${JSON.stringify(implemented)}`);
54
+ }
55
+ }
56
+ for (const [key, refinement] of Object.entries(spec.refinements)) {
57
+ if (refinement.range !== undefined && !Object.hasOwn(ranges, refinement.range)) {
58
+ throw new SpecVersionError(`spec.refinements.${key}.range declares ${JSON.stringify(refinement.range)}, which this package does not implement`);
59
+ }
60
+ }
61
+ policiesChecked.add(spec);
62
+ }
63
+ /** The string handed to the validator, or undefined when the type is not dispatched or its delegate mode is unknown here. */
64
+ export function delegatedString(spec, type, locator) {
65
+ const entry = spec.dispatch[type];
66
+ const delegator = entry ? delegators[entry.delegate] : undefined;
67
+ return delegator ? delegator.form(type, locator) : undefined;
68
+ }
69
+ /** True when a producer may pass the intact format string (`pkg:npm/x`) as the locator of this type. */
70
+ export function foldsType(spec, type) {
71
+ const entry = spec.dispatch[type];
72
+ return entry ? (delegators[entry.delegate]?.foldsType ?? false) : false;
73
+ }
74
+ /** Runs the owning validator, or undefined when the spec names one this package does not implement. */
75
+ export function validateLocator(spec, entry, delegated) {
76
+ const validator = validators[entry.validator];
77
+ return validator ? validator(spec, entry, delegated) : undefined;
78
+ }
79
+ /** True when the value satisfies the refinement's declared range constraint (or it declares none). */
80
+ export function rangeHolds(refinement, value) {
81
+ if (refinement.range === undefined) {
82
+ return true;
83
+ }
84
+ const check = ranges[refinement.range];
85
+ return check ? check(value, refinement.boundSeparator ?? "") : true;
86
+ }
87
+ //# sourceMappingURL=validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@entelekheia/ref-id",
3
+ "version": "0.1.0",
4
+ "description": "The ref: identifier scheme \u2014 a specification published as data with conformance vectors, and the package that consumes it.",
5
+ "type": "module",
6
+ "license": "Apache-2.0",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "spec"
16
+ ],
17
+ "scripts": {
18
+ "prebuild": "mkdir -p spec && cp ../../spec/ref-id.json ../../spec/ref-id.json.sha256 spec/",
19
+ "build": "tsc -p tsconfig.build.json",
20
+ "pretest": "mkdir -p spec && cp ../../spec/ref-id.json ../../spec/ref-id.json.sha256 spec/",
21
+ "typecheck": "tsc --noEmit",
22
+ "test": "node --test test/*.test.ts",
23
+ "prepublishOnly": "npm run build && npm test"
24
+ },
25
+ "engines": {
26
+ "node": ">=22"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^25.2.3",
30
+ "typescript": "^7.0.2"
31
+ },
32
+ "publishConfig": {
33
+ "access": "public",
34
+ "registry": "https://registry.npmjs.org",
35
+ "provenance": false
36
+ },
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/entelekheia-ai/ref-id.git",
40
+ "directory": "packages/ref-id"
41
+ },
42
+ "dependencies": {
43
+ "packageurl-js": "^2.0.1"
44
+ }
45
+ }