@hyprune/schema 0.9.0 → 0.11.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +31 -1
  3. package/bin/validate.mjs +11 -5
  4. package/examples/registry/entry.json +106 -0
  5. package/examples/registry/index.json +137 -0
  6. package/examples/registry/invalid/registry-entry--bad-spdx.json +106 -0
  7. package/examples/registry/invalid/registry-entry--build-metadata.json +106 -0
  8. package/examples/registry/invalid/registry-entry--control-characters.json +106 -0
  9. package/examples/registry/invalid/registry-entry--duplicate-version.json +136 -0
  10. package/examples/registry/invalid/registry-entry--five-thumbnails.json +130 -0
  11. package/examples/registry/invalid/registry-entry--library-over-limit.json +22 -0
  12. package/examples/registry/invalid/registry-entry--name-too-long.json +106 -0
  13. package/examples/registry/invalid/registry-entry--tag-mismatch.json +106 -0
  14. package/examples/registry/invalid/registry-entry--uppercase-hash.json +106 -0
  15. package/examples/registry/invalid/registry-entry--versions-oldest-first.json +106 -0
  16. package/examples/registry/invalid/registry-index--duplicate-id.json +159 -0
  17. package/examples/registry/invalid/registry-index--entry-schema-pointer.json +138 -0
  18. package/examples/registry/invalid/registry-index--http-url.json +137 -0
  19. package/examples/registry/invalid/registry-index--newer-index-version.json +137 -0
  20. package/examples/registry/invalid/registry-index--zero-serial.json +137 -0
  21. package/examples/registry/invalid/release-record--archive-name.json +42 -0
  22. package/examples/registry/invalid/release-record--library-requires.json +42 -0
  23. package/examples/registry/invalid/release-record--short-commit.json +42 -0
  24. package/examples/registry/invalid/release-record--tag-mismatch.json +42 -0
  25. package/examples/registry/invalid/release-record--thumbnail-name.json +42 -0
  26. package/examples/registry/invalid/sources--archive-without-hash.json +50 -0
  27. package/examples/registry/invalid/sources--duplicate-id.json +59 -0
  28. package/examples/registry/invalid/sources--github-without-repo.json +50 -0
  29. package/examples/registry/invalid/sources--index-with-repo.json +52 -0
  30. package/examples/registry/invalid/sources--label-too-long.json +51 -0
  31. package/examples/registry/invalid/sources--reserved-id.json +51 -0
  32. package/examples/registry/invalid/sources--too-many.json +277 -0
  33. package/examples/registry/release-record.json +42 -0
  34. package/examples/registry/sources.json +51 -0
  35. package/lib/validate.d.mts +24 -0
  36. package/lib/validate.mjs +147 -0
  37. package/package.json +2 -1
  38. package/registry/v0.1/index.schema.json +309 -0
  39. package/registry/v0.1/release-record.schema.json +181 -0
  40. package/registry/v0.1/sources.schema.json +129 -0
  41. package/v0.10/object.schema.json +39 -0
  42. package/v0.25/ipc.schema.json +20085 -0
@@ -0,0 +1,52 @@
1
+ {
2
+ "version": 1,
3
+ "builtin": {
4
+ "official": {
5
+ "enabled": true
6
+ },
7
+ "community": {
8
+ "enabled": false
9
+ }
10
+ },
11
+ "custom": [
12
+ {
13
+ "id": "example-index",
14
+ "label": "Example worlds",
15
+ "kind": "index",
16
+ "url": "https://example.org/hyprune/v0.1/index.json",
17
+ "enabled": true,
18
+ "added": "2026-11-01",
19
+ "repo": "example-creator/tidepool-world"
20
+ },
21
+ {
22
+ "id": "tidepool",
23
+ "label": "Tidepool",
24
+ "kind": "github",
25
+ "repo": "example-creator/tidepool-world",
26
+ "enabled": true,
27
+ "added": "2026-11-02"
28
+ },
29
+ {
30
+ "id": "street",
31
+ "label": "Street kit",
32
+ "kind": "github",
33
+ "repo": "example-org/hyprune-objects/street",
34
+ "enabled": false
35
+ },
36
+ {
37
+ "id": "one-archive",
38
+ "label": "example.org",
39
+ "kind": "url",
40
+ "url": "https://example.org/files/com.example.street-1.2.0.tar.zst",
41
+ "sha256": "5d2f0c6e3b9a41d8e7c2b0f4a6d9e1c3b5a7f9e2d4c6b8a0f1e3d5c7b9a2e4f6",
42
+ "enabled": true
43
+ },
44
+ {
45
+ "id": "one-record",
46
+ "label": "A record",
47
+ "kind": "url",
48
+ "url": "https://example.org/files/com.example.street-1.2.0.release.json",
49
+ "enabled": true
50
+ }
51
+ ]
52
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "version": 1,
3
+ "builtin": {
4
+ "official": {
5
+ "enabled": true
6
+ },
7
+ "community": {
8
+ "enabled": false
9
+ }
10
+ },
11
+ "custom": [
12
+ {
13
+ "id": "example-index",
14
+ "label": "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL",
15
+ "kind": "index",
16
+ "url": "https://example.org/hyprune/v0.1/index.json",
17
+ "enabled": true,
18
+ "added": "2026-11-01"
19
+ },
20
+ {
21
+ "id": "tidepool",
22
+ "label": "Tidepool",
23
+ "kind": "github",
24
+ "repo": "example-creator/tidepool-world",
25
+ "enabled": true,
26
+ "added": "2026-11-02"
27
+ },
28
+ {
29
+ "id": "street",
30
+ "label": "Street kit",
31
+ "kind": "github",
32
+ "repo": "example-org/hyprune-objects/street",
33
+ "enabled": false
34
+ },
35
+ {
36
+ "id": "one-archive",
37
+ "label": "example.org",
38
+ "kind": "url",
39
+ "url": "https://example.org/files/com.example.street-1.2.0.tar.zst",
40
+ "sha256": "5d2f0c6e3b9a41d8e7c2b0f4a6d9e1c3b5a7f9e2d4c6b8a0f1e3d5c7b9a2e4f6",
41
+ "enabled": true
42
+ },
43
+ {
44
+ "id": "one-record",
45
+ "label": "A record",
46
+ "kind": "url",
47
+ "url": "https://example.org/files/com.example.street-1.2.0.release.json",
48
+ "enabled": true
49
+ }
50
+ ]
51
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "version": 1,
3
+ "builtin": {
4
+ "official": {
5
+ "enabled": true
6
+ },
7
+ "community": {
8
+ "enabled": false
9
+ }
10
+ },
11
+ "custom": [
12
+ {
13
+ "id": "official",
14
+ "label": "Example worlds",
15
+ "kind": "index",
16
+ "url": "https://example.org/hyprune/v0.1/index.json",
17
+ "enabled": true,
18
+ "added": "2026-11-01"
19
+ },
20
+ {
21
+ "id": "tidepool",
22
+ "label": "Tidepool",
23
+ "kind": "github",
24
+ "repo": "example-creator/tidepool-world",
25
+ "enabled": true,
26
+ "added": "2026-11-02"
27
+ },
28
+ {
29
+ "id": "street",
30
+ "label": "Street kit",
31
+ "kind": "github",
32
+ "repo": "example-org/hyprune-objects/street",
33
+ "enabled": false
34
+ },
35
+ {
36
+ "id": "one-archive",
37
+ "label": "example.org",
38
+ "kind": "url",
39
+ "url": "https://example.org/files/com.example.street-1.2.0.tar.zst",
40
+ "sha256": "5d2f0c6e3b9a41d8e7c2b0f4a6d9e1c3b5a7f9e2d4c6b8a0f1e3d5c7b9a2e4f6",
41
+ "enabled": true
42
+ },
43
+ {
44
+ "id": "one-record",
45
+ "label": "A record",
46
+ "kind": "url",
47
+ "url": "https://example.org/files/com.example.street-1.2.0.release.json",
48
+ "enabled": true
49
+ }
50
+ ]
51
+ }
@@ -0,0 +1,277 @@
1
+ {
2
+ "version": 1,
3
+ "builtin": {
4
+ "official": {
5
+ "enabled": true
6
+ },
7
+ "community": {
8
+ "enabled": false
9
+ }
10
+ },
11
+ "custom": [
12
+ {
13
+ "id": "s0",
14
+ "label": "Example worlds",
15
+ "kind": "index",
16
+ "url": "https://example.org/hyprune/v0.1/index.json",
17
+ "enabled": true,
18
+ "added": "2026-11-01"
19
+ },
20
+ {
21
+ "id": "s1",
22
+ "label": "Example worlds",
23
+ "kind": "index",
24
+ "url": "https://example.org/hyprune/v0.1/index.json",
25
+ "enabled": true,
26
+ "added": "2026-11-01"
27
+ },
28
+ {
29
+ "id": "s2",
30
+ "label": "Example worlds",
31
+ "kind": "index",
32
+ "url": "https://example.org/hyprune/v0.1/index.json",
33
+ "enabled": true,
34
+ "added": "2026-11-01"
35
+ },
36
+ {
37
+ "id": "s3",
38
+ "label": "Example worlds",
39
+ "kind": "index",
40
+ "url": "https://example.org/hyprune/v0.1/index.json",
41
+ "enabled": true,
42
+ "added": "2026-11-01"
43
+ },
44
+ {
45
+ "id": "s4",
46
+ "label": "Example worlds",
47
+ "kind": "index",
48
+ "url": "https://example.org/hyprune/v0.1/index.json",
49
+ "enabled": true,
50
+ "added": "2026-11-01"
51
+ },
52
+ {
53
+ "id": "s5",
54
+ "label": "Example worlds",
55
+ "kind": "index",
56
+ "url": "https://example.org/hyprune/v0.1/index.json",
57
+ "enabled": true,
58
+ "added": "2026-11-01"
59
+ },
60
+ {
61
+ "id": "s6",
62
+ "label": "Example worlds",
63
+ "kind": "index",
64
+ "url": "https://example.org/hyprune/v0.1/index.json",
65
+ "enabled": true,
66
+ "added": "2026-11-01"
67
+ },
68
+ {
69
+ "id": "s7",
70
+ "label": "Example worlds",
71
+ "kind": "index",
72
+ "url": "https://example.org/hyprune/v0.1/index.json",
73
+ "enabled": true,
74
+ "added": "2026-11-01"
75
+ },
76
+ {
77
+ "id": "s8",
78
+ "label": "Example worlds",
79
+ "kind": "index",
80
+ "url": "https://example.org/hyprune/v0.1/index.json",
81
+ "enabled": true,
82
+ "added": "2026-11-01"
83
+ },
84
+ {
85
+ "id": "s9",
86
+ "label": "Example worlds",
87
+ "kind": "index",
88
+ "url": "https://example.org/hyprune/v0.1/index.json",
89
+ "enabled": true,
90
+ "added": "2026-11-01"
91
+ },
92
+ {
93
+ "id": "s10",
94
+ "label": "Example worlds",
95
+ "kind": "index",
96
+ "url": "https://example.org/hyprune/v0.1/index.json",
97
+ "enabled": true,
98
+ "added": "2026-11-01"
99
+ },
100
+ {
101
+ "id": "s11",
102
+ "label": "Example worlds",
103
+ "kind": "index",
104
+ "url": "https://example.org/hyprune/v0.1/index.json",
105
+ "enabled": true,
106
+ "added": "2026-11-01"
107
+ },
108
+ {
109
+ "id": "s12",
110
+ "label": "Example worlds",
111
+ "kind": "index",
112
+ "url": "https://example.org/hyprune/v0.1/index.json",
113
+ "enabled": true,
114
+ "added": "2026-11-01"
115
+ },
116
+ {
117
+ "id": "s13",
118
+ "label": "Example worlds",
119
+ "kind": "index",
120
+ "url": "https://example.org/hyprune/v0.1/index.json",
121
+ "enabled": true,
122
+ "added": "2026-11-01"
123
+ },
124
+ {
125
+ "id": "s14",
126
+ "label": "Example worlds",
127
+ "kind": "index",
128
+ "url": "https://example.org/hyprune/v0.1/index.json",
129
+ "enabled": true,
130
+ "added": "2026-11-01"
131
+ },
132
+ {
133
+ "id": "s15",
134
+ "label": "Example worlds",
135
+ "kind": "index",
136
+ "url": "https://example.org/hyprune/v0.1/index.json",
137
+ "enabled": true,
138
+ "added": "2026-11-01"
139
+ },
140
+ {
141
+ "id": "s16",
142
+ "label": "Example worlds",
143
+ "kind": "index",
144
+ "url": "https://example.org/hyprune/v0.1/index.json",
145
+ "enabled": true,
146
+ "added": "2026-11-01"
147
+ },
148
+ {
149
+ "id": "s17",
150
+ "label": "Example worlds",
151
+ "kind": "index",
152
+ "url": "https://example.org/hyprune/v0.1/index.json",
153
+ "enabled": true,
154
+ "added": "2026-11-01"
155
+ },
156
+ {
157
+ "id": "s18",
158
+ "label": "Example worlds",
159
+ "kind": "index",
160
+ "url": "https://example.org/hyprune/v0.1/index.json",
161
+ "enabled": true,
162
+ "added": "2026-11-01"
163
+ },
164
+ {
165
+ "id": "s19",
166
+ "label": "Example worlds",
167
+ "kind": "index",
168
+ "url": "https://example.org/hyprune/v0.1/index.json",
169
+ "enabled": true,
170
+ "added": "2026-11-01"
171
+ },
172
+ {
173
+ "id": "s20",
174
+ "label": "Example worlds",
175
+ "kind": "index",
176
+ "url": "https://example.org/hyprune/v0.1/index.json",
177
+ "enabled": true,
178
+ "added": "2026-11-01"
179
+ },
180
+ {
181
+ "id": "s21",
182
+ "label": "Example worlds",
183
+ "kind": "index",
184
+ "url": "https://example.org/hyprune/v0.1/index.json",
185
+ "enabled": true,
186
+ "added": "2026-11-01"
187
+ },
188
+ {
189
+ "id": "s22",
190
+ "label": "Example worlds",
191
+ "kind": "index",
192
+ "url": "https://example.org/hyprune/v0.1/index.json",
193
+ "enabled": true,
194
+ "added": "2026-11-01"
195
+ },
196
+ {
197
+ "id": "s23",
198
+ "label": "Example worlds",
199
+ "kind": "index",
200
+ "url": "https://example.org/hyprune/v0.1/index.json",
201
+ "enabled": true,
202
+ "added": "2026-11-01"
203
+ },
204
+ {
205
+ "id": "s24",
206
+ "label": "Example worlds",
207
+ "kind": "index",
208
+ "url": "https://example.org/hyprune/v0.1/index.json",
209
+ "enabled": true,
210
+ "added": "2026-11-01"
211
+ },
212
+ {
213
+ "id": "s25",
214
+ "label": "Example worlds",
215
+ "kind": "index",
216
+ "url": "https://example.org/hyprune/v0.1/index.json",
217
+ "enabled": true,
218
+ "added": "2026-11-01"
219
+ },
220
+ {
221
+ "id": "s26",
222
+ "label": "Example worlds",
223
+ "kind": "index",
224
+ "url": "https://example.org/hyprune/v0.1/index.json",
225
+ "enabled": true,
226
+ "added": "2026-11-01"
227
+ },
228
+ {
229
+ "id": "s27",
230
+ "label": "Example worlds",
231
+ "kind": "index",
232
+ "url": "https://example.org/hyprune/v0.1/index.json",
233
+ "enabled": true,
234
+ "added": "2026-11-01"
235
+ },
236
+ {
237
+ "id": "s28",
238
+ "label": "Example worlds",
239
+ "kind": "index",
240
+ "url": "https://example.org/hyprune/v0.1/index.json",
241
+ "enabled": true,
242
+ "added": "2026-11-01"
243
+ },
244
+ {
245
+ "id": "s29",
246
+ "label": "Example worlds",
247
+ "kind": "index",
248
+ "url": "https://example.org/hyprune/v0.1/index.json",
249
+ "enabled": true,
250
+ "added": "2026-11-01"
251
+ },
252
+ {
253
+ "id": "s30",
254
+ "label": "Example worlds",
255
+ "kind": "index",
256
+ "url": "https://example.org/hyprune/v0.1/index.json",
257
+ "enabled": true,
258
+ "added": "2026-11-01"
259
+ },
260
+ {
261
+ "id": "s31",
262
+ "label": "Example worlds",
263
+ "kind": "index",
264
+ "url": "https://example.org/hyprune/v0.1/index.json",
265
+ "enabled": true,
266
+ "added": "2026-11-01"
267
+ },
268
+ {
269
+ "id": "s32",
270
+ "label": "Example worlds",
271
+ "kind": "index",
272
+ "url": "https://example.org/hyprune/v0.1/index.json",
273
+ "enabled": true,
274
+ "added": "2026-11-01"
275
+ }
276
+ ]
277
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "recordVersion": "0.1",
3
+ "type": "world",
4
+ "id": "io.github.example-creator.tidepool",
5
+ "version": "1.2.0",
6
+ "formatVersion": "0.9",
7
+ "name": "Tidepool Station",
8
+ "license": "CC-BY-SA-4.0",
9
+ "archive": {
10
+ "name": "io.github.example-creator.tidepool-1.2.0.tar.zst",
11
+ "sha256": "5d2f0c6e3b9a41d8e7c2b0f4a6d9e1c3b5a7f9e2d4c6b8a0f1e3d5c7b9a2e4f6",
12
+ "bytes": 48213004,
13
+ "expandedBytes": 96424960,
14
+ "files": 212
15
+ },
16
+ "requires": {
17
+ "libraries": [
18
+ "com.example.street@1.2.0"
19
+ ]
20
+ },
21
+ "thumbnails": [
22
+ {
23
+ "name": "io.github.example-creator.tidepool-1.2.0.thumb-1.png",
24
+ "sha256": "0b8e4c2a6f1d3e5b7a9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e8f1a3b5c7d9e0f2a",
25
+ "width": 1280,
26
+ "height": 720
27
+ }
28
+ ],
29
+ "source": {
30
+ "repo": "https://github.com/example-creator/tidepool-world",
31
+ "tag": "v1.2.0",
32
+ "commit": "3f2a9c4e1b7d5a8c0e2f4b6d8a1c3e5f7b9d0a2c"
33
+ },
34
+ "tool": {
35
+ "name": "hyprune",
36
+ "version": "0.7.0"
37
+ },
38
+ "checks": {
39
+ "schema": "pass",
40
+ "worldCheck": "pass"
41
+ }
42
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "version": 1,
3
+ "builtin": {
4
+ "official": {
5
+ "enabled": true
6
+ },
7
+ "community": {
8
+ "enabled": false
9
+ }
10
+ },
11
+ "custom": [
12
+ {
13
+ "id": "example-index",
14
+ "label": "Example worlds",
15
+ "kind": "index",
16
+ "url": "https://example.org/hyprune/v0.1/index.json",
17
+ "enabled": true,
18
+ "added": "2026-11-01"
19
+ },
20
+ {
21
+ "id": "tidepool",
22
+ "label": "Tidepool",
23
+ "kind": "github",
24
+ "repo": "example-creator/tidepool-world",
25
+ "enabled": true,
26
+ "added": "2026-11-02"
27
+ },
28
+ {
29
+ "id": "street",
30
+ "label": "Street kit",
31
+ "kind": "github",
32
+ "repo": "example-org/hyprune-objects/street",
33
+ "enabled": false
34
+ },
35
+ {
36
+ "id": "one-archive",
37
+ "label": "example.org",
38
+ "kind": "url",
39
+ "url": "https://example.org/files/com.example.street-1.2.0.tar.zst",
40
+ "sha256": "5d2f0c6e3b9a41d8e7c2b0f4a6d9e1c3b5a7f9e2d4c6b8a0f1e3d5c7b9a2e4f6",
41
+ "enabled": true
42
+ },
43
+ {
44
+ "id": "one-record",
45
+ "label": "A record",
46
+ "kind": "url",
47
+ "url": "https://example.org/files/com.example.street-1.2.0.release.json",
48
+ "enabled": true
49
+ }
50
+ ]
51
+ }
@@ -72,3 +72,27 @@ export const objectLimits: Readonly<Record<string, number>>;
72
72
  export const worldLimits: Readonly<{ characters: number; charactersPerPath: number; pathPoints: number; arcChord: number }>;
73
73
  /** glTF extensions a scene may list in extensionsRequired for a world format. */
74
74
  export function sceneExtensions(version: string): string[];
75
+
76
+ /** Registry document kinds (RFC-0015). `registry-entry` is one index entry (a registry entry file may add `$schema`). */
77
+ export type RegistryKind = 'registry-index' | 'registry-entry' | 'release-record' | 'sources';
78
+ /**
79
+ * Validate a registry document against `registry/v<version>/` (default: the newest) plus the
80
+ * semantic rules: unique ids, versions unique and newest first (SemVer), tags naming their
81
+ * version (`v<version>` or `<name>-v<version>`), SPDX expressions, per-type archive limits.
82
+ * @throws on an unknown kind or version
83
+ */
84
+ export function validateRegistry(kind: RegistryKind, value: unknown, version?: string): ValidationResult;
85
+ /** Registry format versions with published schemas (registry/v0.N), oldest first. */
86
+ export const registryVersions: readonly string[];
87
+ /** RFC-0015 archive limits per package type and index limits. */
88
+ export const registryLimits: Readonly<{
89
+ world: Readonly<{ bytes: number; expandedBytes: number; files: number; fileBytes: number }>;
90
+ library: Readonly<{ bytes: number; expandedBytes: number; files: number; fileBytes: number }>;
91
+ index: Readonly<{ bytes: number; entries: number; versions: number; thumbnails: number; custom: number }>;
92
+ }>;
93
+ /** A parsed SemVer 2.0 version, or undefined when invalid. */
94
+ export function parseSemver(text: unknown): { major: number; minor: number; patch: number; prerelease: string[]; build: string | null } | undefined;
95
+ /** SemVer precedence (-1, 0, 1; build metadata ignored). Throws on invalid input. */
96
+ export function compareSemver(a: string, b: string): -1 | 0 | 1;
97
+ /** The version a tag names (`v<version>` or `<name>-v<version>`), or undefined. */
98
+ export function tagVersion(tag: unknown): { name: string | null; version: string } | undefined;