@pixi-ui-editor/schema 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,132 @@
1
+ import { BUTTON_STATE_KEYS, CURRENT_SCHEMA_VERSION, validateProjectDocument, } from "./index.js";
2
+ /** Appends a button whose four states each reference their own image asset, wired into the fixture's scene root. */
3
+ export function addButtonNode(document) {
4
+ const scene = document.scenes[0];
5
+ const root = scene.nodes[0];
6
+ const assetIds = BUTTON_STATE_KEYS.map((state, index) => {
7
+ const id = stableId(10 + index);
8
+ document.assets.push({ id, name: `Button ${state}`, type: "image", source: { uri: `assets/button-${state}.png`, mediaType: "image/png" } });
9
+ return id;
10
+ });
11
+ const button = {
12
+ id: stableId(20),
13
+ name: "Play",
14
+ type: "button",
15
+ parentId: root.id,
16
+ children: [],
17
+ visible: true,
18
+ enabled: true,
19
+ states: { normalAssetId: assetIds[0], hoverAssetId: assetIds[1], pressedAssetId: assetIds[2], disabledAssetId: assetIds[3] },
20
+ transform: { x: 0, y: 0, width: 120, height: 40, scaleX: 1, scaleY: 1, rotation: 0 },
21
+ };
22
+ root.children.push(button.id);
23
+ scene.nodes.push(button);
24
+ return button;
25
+ }
26
+ export const stableId = (value) => `00000000-0000-4000-8000-${String(value).padStart(12, "0")}`;
27
+ /** Appends an atlas asset with one named frame and points an existing image node at that frame id. */
28
+ export function addAtlasAssetWithFrame(document) {
29
+ const atlasId = stableId(40);
30
+ const frameId = stableId(41);
31
+ document.assets.push({
32
+ id: atlasId,
33
+ name: "Atlas",
34
+ type: "atlas",
35
+ files: {
36
+ json: { name: "atlas.json", uri: "assets/atlas.json", mediaType: "application/json" },
37
+ texture: { name: "atlas.png", uri: "assets/atlas.png", mediaType: "image/png" },
38
+ },
39
+ frames: { "icon.png": frameId },
40
+ });
41
+ document.scenes[0].nodes[1].assetId = frameId;
42
+ return { atlasId, frameId };
43
+ }
44
+ export function createProjectDocumentFixture() {
45
+ const project = stableId(1);
46
+ const scene = stableId(2);
47
+ const root = stableId(3);
48
+ const image = stableId(4);
49
+ const asset = stableId(5);
50
+ const prefab = stableId(6);
51
+ return {
52
+ schemaVersion: CURRENT_SCHEMA_VERSION,
53
+ project: { id: project, name: "Project" },
54
+ settings: {
55
+ layoutProfileSelection: { mode: "aspect-ratio", mobileMaxAspectRatio: 1 },
56
+ },
57
+ assets: [
58
+ {
59
+ id: asset,
60
+ name: "Logo",
61
+ type: "image",
62
+ source: { uri: "assets/logo.png", mediaType: "image/png" },
63
+ },
64
+ ],
65
+ effects: [],
66
+ prefabs: [
67
+ {
68
+ id: prefab,
69
+ name: "Badge",
70
+ rootNodeIds: [],
71
+ nodes: [],
72
+ exposedProperties: [],
73
+ },
74
+ ],
75
+ scenes: [
76
+ {
77
+ id: scene,
78
+ name: "Main",
79
+ rootNodeIds: [root],
80
+ layout: {
81
+ referenceViewports: {
82
+ desktop: { width: 1920, height: 1080 },
83
+ mobile: { width: 390, height: 844 },
84
+ },
85
+ },
86
+ nodes: [
87
+ {
88
+ id: root,
89
+ name: "Root",
90
+ type: "container",
91
+ parentId: null,
92
+ children: [image],
93
+ visible: true,
94
+ transform: {
95
+ x: 0,
96
+ y: 0,
97
+ width: 100,
98
+ height: 100,
99
+ scaleX: 1,
100
+ scaleY: 1,
101
+ rotation: 0,
102
+ },
103
+ },
104
+ {
105
+ id: image,
106
+ name: "Logo",
107
+ type: "image",
108
+ assetId: asset,
109
+ parentId: root,
110
+ children: [],
111
+ visible: true,
112
+ transform: {
113
+ x: 0,
114
+ y: 0,
115
+ width: 10,
116
+ height: 10,
117
+ scaleX: 1,
118
+ scaleY: 1,
119
+ rotation: 0,
120
+ },
121
+ },
122
+ ],
123
+ },
124
+ ],
125
+ };
126
+ }
127
+ export function validateFixtureMutation(mutate) {
128
+ const document = createProjectDocumentFixture();
129
+ mutate(document);
130
+ return validateProjectDocument(document);
131
+ }
132
+ //# sourceMappingURL=index.test-fixtures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test-fixtures.js","sourceRoot":"","sources":["../src/index.test-fixtures.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,239 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { CURRENT_SCHEMA_VERSION, createStableId, migrateProjectDocument, serializeProjectDocument, validateProjectDocument, } from "./index.js";
3
+ import { addAtlasAssetWithFrame, addButtonNode, createProjectDocumentFixture, stableId, validateFixtureMutation, } from "./index.test-fixtures.js";
4
+ describe("schema v1", () => {
5
+ it("generates independent UUID stable IDs", () => {
6
+ const first = createStableId();
7
+ const second = createStableId();
8
+ expect(first).toMatch(/^[0-9a-f]{8}-/i);
9
+ expect(first).not.toBe(second);
10
+ });
11
+ it("accepts a minimal valid document", () => {
12
+ expect(validateProjectDocument(createProjectDocumentFixture())).toEqual({ valid: true, issues: [] });
13
+ });
14
+ it("accepts normalized anchors and rejects values outside the parent rectangle", () => {
15
+ const document = createProjectDocumentFixture();
16
+ document.scenes[0].nodes[1].transform.anchorMinX = 0.5;
17
+ document.scenes[0].nodes[1].transform.anchorMinY = 1;
18
+ expect(validateProjectDocument(document).valid).toBe(true);
19
+ document.scenes[0].nodes[1].transform.anchorMinX = 1.1;
20
+ expect(validateProjectDocument(document).issues[0].code).toBe("STRUCTURAL_SCHEMA");
21
+ });
22
+ it("allows non-positive width only on a stretched axis", () => {
23
+ const document = createProjectDocumentFixture();
24
+ const transform = document.scenes[0].nodes[1].transform;
25
+ transform.width = -20;
26
+ expect(validateProjectDocument(document).issues[0].code).toBe("NON_POSITIVE_SIZE");
27
+ transform.anchorMinX = 0;
28
+ transform.anchorMaxX = 1;
29
+ expect(validateProjectDocument(document).valid).toBe(true);
30
+ });
31
+ it("migrates v1 point anchors to v2 anchorMin/anchorMax pairs", () => {
32
+ const document = createProjectDocumentFixture();
33
+ document.schemaVersion = 1;
34
+ const v1Document = document;
35
+ const transform = v1Document.scenes[0].nodes[1].transform;
36
+ transform.anchorX = 0.5;
37
+ transform.anchorY = 1;
38
+ v1Document.scenes[0].nodes[1].layoutOverrides = { mobile: { transform: { anchorX: 0.25 } } };
39
+ const migrated = migrateProjectDocument(document);
40
+ expect(migrated.schemaVersion).toBe(CURRENT_SCHEMA_VERSION);
41
+ expect(migrated.scenes[0].nodes[1].transform).toMatchObject({ anchorMinX: 0.5, anchorMaxX: 0.5, anchorMinY: 1, anchorMaxY: 1 });
42
+ expect(migrated.scenes[0].nodes[1].transform).not.toHaveProperty("anchorX");
43
+ expect(migrated.scenes[0].nodes[1].layoutOverrides?.mobile?.transform).toEqual({ anchorMinX: 0.25, anchorMaxX: 0.25 });
44
+ });
45
+ it("accepts a button whose four states reference image assets", () => {
46
+ const document = createProjectDocumentFixture();
47
+ addButtonNode(document);
48
+ expect(validateProjectDocument(document)).toEqual({ valid: true, issues: [] });
49
+ });
50
+ it("reports the offending state field when a button state references a non-image asset", () => {
51
+ const document = createProjectDocumentFixture();
52
+ const button = addButtonNode(document);
53
+ const spineAsset = stableId(30);
54
+ document.assets.push({
55
+ id: spineAsset,
56
+ name: "Hero",
57
+ type: "spine",
58
+ files: {
59
+ skeleton: { name: "hero.json", uri: "assets/hero.json", mediaType: "application/json" },
60
+ atlas: { name: "hero.atlas", uri: "assets/hero.atlas", mediaType: "text/plain" },
61
+ textures: [{ name: "hero.png", uri: "assets/hero.png", mediaType: "image/png" }],
62
+ },
63
+ });
64
+ button.states.pressedAssetId = spineAsset;
65
+ const result = validateProjectDocument(document);
66
+ expect(result.issues).toMatchObject([{ code: "INCOMPATIBLE_ASSET_REFERENCE", path: "/scenes/0/nodes/2/states/pressedAssetId" }]);
67
+ });
68
+ it("migrates a v2 document to v3 without changing its existing nodes", () => {
69
+ const document = createProjectDocumentFixture();
70
+ const v2Nodes = structuredClone(document.scenes[0].nodes);
71
+ document.schemaVersion = 2;
72
+ const migrated = migrateProjectDocument(document);
73
+ expect(migrated.schemaVersion).toBe(CURRENT_SCHEMA_VERSION);
74
+ expect(migrated.scenes[0].nodes).toEqual(v2Nodes);
75
+ });
76
+ it("migrates a v3 document to v4 without changing its existing assets or nodes", () => {
77
+ const document = createProjectDocumentFixture();
78
+ const v3Assets = structuredClone(document.assets);
79
+ const v3Nodes = structuredClone(document.scenes[0].nodes);
80
+ document.schemaVersion = 3;
81
+ const migrated = migrateProjectDocument(document);
82
+ expect(migrated.schemaVersion).toBe(CURRENT_SCHEMA_VERSION);
83
+ expect(migrated.assets).toEqual(v3Assets);
84
+ expect(migrated.scenes[0].nodes).toEqual(v3Nodes);
85
+ });
86
+ it("migrates a v4 document to v5 without changing its existing assets or nodes", () => {
87
+ const document = createProjectDocumentFixture();
88
+ const v4Assets = structuredClone(document.assets);
89
+ const v4Nodes = structuredClone(document.scenes[0].nodes);
90
+ document.schemaVersion = 4;
91
+ const migrated = migrateProjectDocument(document);
92
+ expect(migrated.schemaVersion).toBe(CURRENT_SCHEMA_VERSION);
93
+ expect(migrated.assets).toEqual(v4Assets);
94
+ expect(migrated.scenes[0].nodes).toEqual(v4Nodes);
95
+ });
96
+ it("rejects a sound asset with an empty source uri", () => {
97
+ const result = validateFixtureMutation((document) => {
98
+ document.assets.push({
99
+ id: stableId(45),
100
+ name: "Click",
101
+ type: "sound",
102
+ source: { uri: "", mediaType: "audio/wav" },
103
+ });
104
+ });
105
+ expect(result.issues.some((issue) => issue.code === "STRUCTURAL_SCHEMA")).toBe(true);
106
+ });
107
+ it("rejects a button press sound that references an image asset", () => {
108
+ const document = createProjectDocumentFixture();
109
+ const button = addButtonNode(document);
110
+ button.sounds = { pressAssetId: button.states.normalAssetId };
111
+ const result = validateProjectDocument(document);
112
+ expect(result.issues).toMatchObject([{ code: "INCOMPATIBLE_ASSET_REFERENCE", path: "/scenes/0/nodes/2/sounds/pressAssetId" }]);
113
+ });
114
+ it("accepts an image node whose assetId is an atlas frame id", () => {
115
+ const document = createProjectDocumentFixture();
116
+ addAtlasAssetWithFrame(document);
117
+ expect(validateProjectDocument(document)).toEqual({ valid: true, issues: [] });
118
+ });
119
+ it("rejects an atlas asset with an incomplete files object", () => {
120
+ const result = validateFixtureMutation((document) => {
121
+ document.assets.push({
122
+ id: stableId(42),
123
+ name: "Broken atlas",
124
+ type: "atlas",
125
+ files: { json: { name: "atlas.json", uri: "assets/atlas.json", mediaType: "application/json" } },
126
+ frames: { "icon.png": stableId(43) },
127
+ });
128
+ });
129
+ expect(result.issues.some((issue) => issue.code === "STRUCTURAL_SCHEMA")).toBe(true);
130
+ });
131
+ it("rejects an atlas asset without a frames map", () => {
132
+ const result = validateFixtureMutation((document) => {
133
+ document.assets.push({
134
+ id: stableId(44),
135
+ name: "Broken atlas",
136
+ type: "atlas",
137
+ files: {
138
+ json: { name: "atlas.json", uri: "assets/atlas.json", mediaType: "application/json" },
139
+ texture: { name: "atlas.png", uri: "assets/atlas.png", mediaType: "image/png" },
140
+ },
141
+ });
142
+ });
143
+ expect(result.issues.some((issue) => issue.code === "STRUCTURAL_SCHEMA")).toBe(true);
144
+ });
145
+ it.each(["desktop", "mobile"])("rejects missing %s viewport", (profile) => {
146
+ const result = validateFixtureMutation((document) => {
147
+ delete document.scenes[0].layout.referenceViewports[profile];
148
+ });
149
+ expect(result.issues[0].code).toBe("STRUCTURAL_SCHEMA");
150
+ });
151
+ it("reports duplicate IDs", () => {
152
+ const result = validateFixtureMutation((document) => {
153
+ document.scenes[0].nodes[1].id = document.scenes[0].nodes[0].id;
154
+ });
155
+ expect(result.issues.some((issue) => issue.code === "DUPLICATE_ID")).toBe(true);
156
+ });
157
+ it("reports missing child and asset references", () => {
158
+ const result = validateFixtureMutation((document) => {
159
+ document.scenes[0].nodes[0].children = [stableId(99)];
160
+ document.scenes[0].nodes[1].assetId = stableId(98);
161
+ });
162
+ expect(result.issues.map((issue) => issue.code)).toEqual(expect.arrayContaining(["MISSING_CHILD_REFERENCE", "MISSING_ASSET_REFERENCE"]));
163
+ });
164
+ it("reports missing prefab references", () => {
165
+ const result = validateFixtureMutation((document) => {
166
+ document.scenes[0].nodes[1] = {
167
+ ...document.scenes[0].nodes[1],
168
+ type: "prefab-instance",
169
+ prefabId: stableId(99),
170
+ };
171
+ });
172
+ expect(result.issues.some((issue) => issue.code === "MISSING_PREFAB_REFERENCE")).toBe(true);
173
+ });
174
+ it("reports inconsistent parent and children", () => {
175
+ const result = validateFixtureMutation((document) => {
176
+ document.scenes[0].nodes[1].parentId = null;
177
+ });
178
+ expect(result.issues.some((issue) => issue.code === "HIERARCHY_PARENT_MISMATCH")).toBe(true);
179
+ });
180
+ it("reports cycles", () => {
181
+ const result = validateFixtureMutation((document) => {
182
+ const nodes = document.scenes[0].nodes;
183
+ nodes[0].parentId = nodes[1].id;
184
+ nodes[1].children = [nodes[0].id];
185
+ });
186
+ expect(result.issues.some((issue) => issue.code === "HIERARCHY_CYCLE")).toBe(true);
187
+ });
188
+ it("reports duplicate bindings", () => {
189
+ const result = validateFixtureMutation((document) => {
190
+ document.scenes[0].nodes[0].binding = "target";
191
+ document.scenes[0].nodes[1].binding = "target";
192
+ });
193
+ expect(result.issues.some((issue) => issue.code === "DUPLICATE_BINDING")).toBe(true);
194
+ });
195
+ it("rejects an incomplete spine asset", () => {
196
+ const result = validateFixtureMutation((document) => {
197
+ document.assets[0] = {
198
+ id: stableId(5),
199
+ name: "Hero",
200
+ type: "spine",
201
+ files: {
202
+ skeleton: { name: "hero.json", uri: "hero.json", mediaType: "application/json" },
203
+ textures: [{ name: "hero.png", uri: "hero.png", mediaType: "image/png" }],
204
+ },
205
+ };
206
+ });
207
+ expect(result.issues.some((issue) => issue.code === "STRUCTURAL_SCHEMA")).toBe(true);
208
+ });
209
+ it("rejects unknown profile keys and schema versions", () => {
210
+ const result = validateFixtureMutation((document) => {
211
+ document.scenes[0].nodes[0].layoutOverrides = { tablet: {} };
212
+ document.schemaVersion = 0;
213
+ });
214
+ expect(result.issues.some((issue) => issue.code === "STRUCTURAL_SCHEMA")).toBe(true);
215
+ });
216
+ it("clones and validates the current version without mutating input", () => {
217
+ const input = createProjectDocumentFixture();
218
+ const output = migrateProjectDocument(input);
219
+ expect(output).toEqual(input);
220
+ expect(output).not.toBe(input);
221
+ output.project.name = "Changed";
222
+ expect(input.project.name).toBe("Project");
223
+ });
224
+ it("rejects non-finite numbers", () => {
225
+ const result = validateFixtureMutation((document) => {
226
+ document.scenes[0].nodes[0].transform.x = Number.NaN;
227
+ });
228
+ expect(result.issues.some((issue) => issue.code === "NON_FINITE_NUMBER")).toBe(true);
229
+ });
230
+ it("serializes deterministically without mutating the document", () => {
231
+ const input = createProjectDocumentFixture();
232
+ const before = structuredClone(input);
233
+ const reordered = Object.fromEntries(Object.entries(input).reverse());
234
+ expect(serializeProjectDocument(input)).toBe(serializeProjectDocument(reordered));
235
+ expect(serializeProjectDocument(input).endsWith("\n")).toBe(true);
236
+ expect(input).toEqual(before);
237
+ });
238
+ });
239
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type Static } from "@sinclair/typebox";
2
+ /**
3
+ * `manifest.json`: the project folder's own identity, separate from `project.json`'s `ProjectDocument`.
4
+ * No save timestamp is stored on purpose (git-diff-friendly: `manifest.json` only changes when the
5
+ * project identity, name, or editor version actually changes, not on every save).
6
+ */
7
+ export declare const PROJECT_MANIFEST_FORMAT_VERSION: 1;
8
+ declare const ProjectManifestSchema: import("@sinclair/typebox").TObject<{
9
+ formatVersion: import("@sinclair/typebox").TLiteral<1>;
10
+ projectId: import("@sinclair/typebox").TString;
11
+ name: import("@sinclair/typebox").TString;
12
+ createdAt: import("@sinclair/typebox").TString;
13
+ editorVersion: import("@sinclair/typebox").TString;
14
+ }>;
15
+ export type ProjectManifest = Static<typeof ProjectManifestSchema>;
16
+ export type ProjectManifestErrorCode = "INVALID_MANIFEST_SHAPE" | "UNSUPPORTED_MANIFEST_VERSION";
17
+ export declare class ProjectManifestError extends Error {
18
+ readonly code: ProjectManifestErrorCode;
19
+ constructor(code: ProjectManifestErrorCode, message: string);
20
+ }
21
+ /** Parses/validates an already-`JSON.parse`d manifest value (mirrors `assertProjectDocument`'s `unknown`-in contract). */
22
+ export declare function parseProjectManifest(input: unknown): ProjectManifest;
23
+ /** Deterministic, human-diffable form for `manifest.json`: sorted keys, 2-space indent, trailing newline. */
24
+ export declare function serializeProjectManifest(manifest: ProjectManifest): string;
25
+ export {};
26
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAItD;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,EAAG,CAAU,CAAC;AAE1D,QAAA,MAAM,qBAAqB;;;;;;EAMzB,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEnE,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,GAAG,8BAA8B,CAAC;AAEjG,qBAAa,oBAAqB,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,wBAAwB;gBAA9B,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,MAAM;CAIrE;AAQD,0HAA0H;AAC1H,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAWpE;AAQD,6GAA6G;AAC7G,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAG1E"}
@@ -0,0 +1,56 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import Ajv from "ajv";
3
+ import addFormats from "ajv-formats";
4
+ /**
5
+ * `manifest.json`: the project folder's own identity, separate from `project.json`'s `ProjectDocument`.
6
+ * No save timestamp is stored on purpose (git-diff-friendly: `manifest.json` only changes when the
7
+ * project identity, name, or editor version actually changes, not on every save).
8
+ */
9
+ export const PROJECT_MANIFEST_FORMAT_VERSION = 1;
10
+ const ProjectManifestSchema = Type.Object({
11
+ formatVersion: Type.Literal(PROJECT_MANIFEST_FORMAT_VERSION),
12
+ projectId: Type.String({ format: "uuid" }),
13
+ name: Type.String({ minLength: 1 }),
14
+ createdAt: Type.String({ format: "date-time" }),
15
+ editorVersion: Type.String({ minLength: 1 }),
16
+ });
17
+ export class ProjectManifestError extends Error {
18
+ code;
19
+ constructor(code, message) {
20
+ super(message);
21
+ this.code = code;
22
+ this.name = "ProjectManifestError";
23
+ }
24
+ }
25
+ const AjvConstructor = Ajv;
26
+ const addAjvFormats = addFormats;
27
+ const manifestAjv = new AjvConstructor({ allErrors: true, strict: false });
28
+ addAjvFormats(manifestAjv);
29
+ const structuralManifest = manifestAjv.compile(ProjectManifestSchema);
30
+ /** Parses/validates an already-`JSON.parse`d manifest value (mirrors `assertProjectDocument`'s `unknown`-in contract). */
31
+ export function parseProjectManifest(input) {
32
+ if (typeof input !== "object" || input === null)
33
+ throw new ProjectManifestError("INVALID_MANIFEST_SHAPE", "A project manifest must be an object.");
34
+ const formatVersion = input.formatVersion;
35
+ if (typeof formatVersion === "number" && formatVersion > PROJECT_MANIFEST_FORMAT_VERSION) {
36
+ throw new ProjectManifestError("UNSUPPORTED_MANIFEST_VERSION", `Unsupported manifest formatVersion '${formatVersion}'. This editor supports up to ${PROJECT_MANIFEST_FORMAT_VERSION}.`);
37
+ }
38
+ if (!structuralManifest(input)) {
39
+ const detail = (structuralManifest.errors ?? []).map((error) => `${error.instancePath || "/"} ${error.message ?? ""}`).join(", ");
40
+ throw new ProjectManifestError("INVALID_MANIFEST_SHAPE", `Invalid project manifest: ${detail || "does not match the expected shape."}`);
41
+ }
42
+ return input;
43
+ }
44
+ function canonicalizeJson(value) {
45
+ if (Array.isArray(value))
46
+ return value.map(canonicalizeJson);
47
+ if (typeof value === "object" && value !== null)
48
+ return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalizeJson(value[key])]));
49
+ return value;
50
+ }
51
+ /** Deterministic, human-diffable form for `manifest.json`: sorted keys, 2-space indent, trailing newline. */
52
+ export function serializeProjectManifest(manifest) {
53
+ const validated = parseProjectManifest(manifest);
54
+ return `${JSON.stringify(canonicalizeJson(validated), null, 2)}\n`;
55
+ }
56
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=manifest.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.test.d.ts","sourceRoot":"","sources":["../src/manifest.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { parseProjectManifest, ProjectManifestError, serializeProjectManifest } from "./manifest.js";
3
+ const validManifest = {
4
+ formatVersion: 1,
5
+ projectId: "40000000-0000-4000-8000-000000000001",
6
+ name: "Demo Project",
7
+ createdAt: "2026-01-01T00:00:00.000Z",
8
+ editorVersion: "0.0.0",
9
+ };
10
+ describe("project manifest", () => {
11
+ it("round-trips a valid manifest deterministically regardless of key order", () => {
12
+ const reordered = Object.fromEntries(Object.entries(validManifest).reverse());
13
+ const serialized = serializeProjectManifest(validManifest);
14
+ expect(serialized).toBe(serializeProjectManifest(reordered));
15
+ expect(serialized.endsWith("\n")).toBe(true);
16
+ expect(serialized).toContain("\n \"createdAt\"");
17
+ expect(parseProjectManifest(JSON.parse(serialized))).toEqual(validManifest);
18
+ });
19
+ it.each([
20
+ ["INVALID_MANIFEST_SHAPE", { ...validManifest, projectId: "not-a-uuid" }],
21
+ ["INVALID_MANIFEST_SHAPE", { ...validManifest, name: "" }],
22
+ ["UNSUPPORTED_MANIFEST_VERSION", { ...validManifest, formatVersion: 2 }],
23
+ ])("rejects an invalid manifest with code %s", (code, invalid) => {
24
+ expect(() => parseProjectManifest(invalid)).toThrow(ProjectManifestError);
25
+ try {
26
+ parseProjectManifest(invalid);
27
+ expect.unreachable();
28
+ }
29
+ catch (error) {
30
+ expect(error).toBeInstanceOf(ProjectManifestError);
31
+ expect(error.code).toBe(code);
32
+ }
33
+ });
34
+ });
35
+ //# sourceMappingURL=manifest.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.test.js","sourceRoot":"","sources":["../src/manifest.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,wBAAwB,EAAwB,MAAM,eAAe,CAAC;AAE3H,MAAM,aAAa,GAAoB;IACrC,aAAa,EAAE,CAAC;IAChB,SAAS,EAAE,sCAAsC;IACjD,IAAI,EAAE,cAAc;IACpB,SAAS,EAAE,0BAA0B;IACrC,aAAa,EAAE,OAAO;CACvB,CAAC;AAEF,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAoB,CAAC;QAEjG,MAAM,UAAU,GAAG,wBAAwB,CAAC,aAAa,CAAC,CAAC;QAC3D,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC,CAAC;QAC7D,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAElD,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC;QACN,CAAC,wBAAwB,EAAE,EAAE,GAAG,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;QACzE,CAAC,wBAAwB,EAAE,EAAE,GAAG,aAAa,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAC1D,CAAC,8BAA8B,EAAE,EAAE,GAAG,aAAa,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;KAChE,CAAC,CAAC,0CAA0C,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;QACxE,MAAM,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC1E,IAAI,CAAC;YACH,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC9B,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC;YACnD,MAAM,CAAE,KAA8B,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@pixi-ui-editor/schema",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/AlexMariacho/pixi-ui-editor.git",
8
+ "directory": "packages/schema"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ }
21
+ },
22
+ "dependencies": {
23
+ "@sinclair/typebox": "^0.34.52",
24
+ "ajv": "^8.20.0",
25
+ "ajv-formats": "^3.0.1"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^26.1.1"
29
+ },
30
+ "scripts": {
31
+ "build": "tsc -p tsconfig.json",
32
+ "typecheck": "tsc --noEmit -p tsconfig.json",
33
+ "test": "vitest run"
34
+ }
35
+ }