@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,31 @@
1
+ import type { Asset } from "./index.js";
2
+ export declare function sanitizeName(name: string): string;
3
+ /** Image/font/sound assets have no uploaded file name, so the file name is the asset name plus a mediaType extension. */
4
+ export declare function imageFileName(asset: {
5
+ name: string;
6
+ source: {
7
+ mediaType: string;
8
+ };
9
+ }): string;
10
+ export declare function fontFileName(asset: {
11
+ name: string;
12
+ source: {
13
+ mediaType: string;
14
+ };
15
+ }): string;
16
+ export declare function soundFileName(asset: {
17
+ name: string;
18
+ source: {
19
+ mediaType: string;
20
+ };
21
+ }): string;
22
+ /** Package-relative path for one asset file, per the fixed folder layout (`assets/<assetId>/<fileName>`). */
23
+ export declare function assetFilePath(assetId: string, fileName: string): string;
24
+ export type AssetFileEntry = {
25
+ path: string;
26
+ fileName: string;
27
+ mediaType: string;
28
+ };
29
+ /** Every relative-path file entry an asset owns: multi-file assets (atlas/Spine) keep their original uploaded file names. */
30
+ export declare function collectAssetFileEntries(asset: Asset): AssetFileEntry[];
31
+ //# sourceMappingURL=assetPaths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetPaths.d.ts","sourceRoot":"","sources":["../src/assetPaths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAyBxC,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED,yHAAyH;AACzH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,MAAM,CAG5F;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,MAAM,CAG3F;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,MAAM,CAG5F;AAED,6GAA6G;AAC7G,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,6HAA6H;AAC7H,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,EAAE,CAetE"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Single source of truth for `Asset -> project folder relative path` naming, shared by the exported ZIP
3
+ * package (`apps/editor-web/src/shared/exportPackage.ts`) and the IndexedDB working copy (`projectStore`):
4
+ * both must resolve the same asset to the same `assets/<assetId>/<fileName>` path.
5
+ */
6
+ const IMAGE_EXTENSIONS = {
7
+ "image/png": ".png",
8
+ "image/jpeg": ".jpg",
9
+ "image/webp": ".webp",
10
+ "image/gif": ".gif",
11
+ "image/svg+xml": ".svg",
12
+ "image/avif": ".avif",
13
+ };
14
+ const SOUND_EXTENSIONS = {
15
+ "audio/wav": ".wav",
16
+ "audio/mpeg": ".mp3",
17
+ "audio/ogg": ".ogg",
18
+ "audio/aac": ".aac",
19
+ "audio/mp4": ".m4a",
20
+ };
21
+ export function sanitizeName(name) {
22
+ const safe = name.replace(/[^\p{L}\p{N}._-]+/gu, "-").replace(/^-+|-+$/g, "");
23
+ return safe === "" ? "file" : safe;
24
+ }
25
+ /** Image/font/sound assets have no uploaded file name, so the file name is the asset name plus a mediaType extension. */
26
+ export function imageFileName(asset) {
27
+ const extension = IMAGE_EXTENSIONS[asset.source.mediaType] ?? `.${sanitizeName(asset.source.mediaType.split("/")[1] ?? "bin")}`;
28
+ return `${sanitizeName(asset.name)}${extension}`;
29
+ }
30
+ export function fontFileName(asset) {
31
+ const extension = asset.source.mediaType.split("/")[1] ?? "font";
32
+ return `${sanitizeName(asset.name)}.${sanitizeName(extension)}`;
33
+ }
34
+ export function soundFileName(asset) {
35
+ const extension = SOUND_EXTENSIONS[asset.source.mediaType] ?? `.${sanitizeName(asset.source.mediaType.split("/")[1] ?? "bin")}`;
36
+ return `${sanitizeName(asset.name)}${extension}`;
37
+ }
38
+ /** Package-relative path for one asset file, per the fixed folder layout (`assets/<assetId>/<fileName>`). */
39
+ export function assetFilePath(assetId, fileName) {
40
+ return `assets/${assetId}/${fileName}`;
41
+ }
42
+ /** Every relative-path file entry an asset owns: multi-file assets (atlas/Spine) keep their original uploaded file names. */
43
+ export function collectAssetFileEntries(asset) {
44
+ if (asset.type === "image") {
45
+ const fileName = imageFileName(asset);
46
+ return [{ path: assetFilePath(asset.id, fileName), fileName, mediaType: asset.source.mediaType }];
47
+ }
48
+ if (asset.type === "font") {
49
+ const fileName = fontFileName(asset);
50
+ return [{ path: assetFilePath(asset.id, fileName), fileName, mediaType: asset.source.mediaType }];
51
+ }
52
+ if (asset.type === "sound") {
53
+ const fileName = soundFileName(asset);
54
+ return [{ path: assetFilePath(asset.id, fileName), fileName, mediaType: asset.source.mediaType }];
55
+ }
56
+ if (asset.type === "atlas") {
57
+ return [
58
+ { path: assetFilePath(asset.id, asset.files.json.name), fileName: asset.files.json.name, mediaType: asset.files.json.mediaType },
59
+ { path: assetFilePath(asset.id, asset.files.texture.name), fileName: asset.files.texture.name, mediaType: asset.files.texture.mediaType },
60
+ ];
61
+ }
62
+ return [
63
+ { path: assetFilePath(asset.id, asset.files.skeleton.name), fileName: asset.files.skeleton.name, mediaType: asset.files.skeleton.mediaType },
64
+ { path: assetFilePath(asset.id, asset.files.atlas.name), fileName: asset.files.atlas.name, mediaType: asset.files.atlas.mediaType },
65
+ ...asset.files.textures.map((texture) => ({ path: assetFilePath(asset.id, texture.name), fileName: texture.name, mediaType: texture.mediaType })),
66
+ ];
67
+ }
68
+ //# sourceMappingURL=assetPaths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetPaths.js","sourceRoot":"","sources":["../src/assetPaths.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,MAAM,gBAAgB,GAA2B;IAC/C,WAAW,EAAE,MAAM;IACnB,YAAY,EAAE,MAAM;IACpB,YAAY,EAAE,OAAO;IACrB,WAAW,EAAE,MAAM;IACnB,eAAe,EAAE,MAAM;IACvB,YAAY,EAAE,OAAO;CACtB,CAAC;AAEF,MAAM,gBAAgB,GAA2B;IAC/C,WAAW,EAAE,MAAM;IACnB,YAAY,EAAE,MAAM;IACpB,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,MAAM;CACpB,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC9E,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,CAAC;AAED,yHAAyH;AACzH,MAAM,UAAU,aAAa,CAAC,KAAsD;IAClF,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;IAChI,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAsD;IACjF,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IACjE,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAsD;IAClF,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;IAChI,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC;AACnD,CAAC;AAED,6GAA6G;AAC7G,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,QAAgB;IAC7D,OAAO,UAAU,OAAO,IAAI,QAAQ,EAAE,CAAC;AACzC,CAAC;AAID,6HAA6H;AAC7H,MAAM,UAAU,uBAAuB,CAAC,KAAY;IAClD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAAC,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAAC,CAAC;IACzK,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAAC,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAAC,CAAC;IACvK,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAAC,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAAC,CAAC;IACzK,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO;YACL,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE;YAChI,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE;SAC1I,CAAC;IACJ,CAAC;IACD,OAAO;QACL,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE;QAC5I,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE;QACnI,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;KAClJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=assetPaths.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetPaths.test.d.ts","sourceRoot":"","sources":["../src/assetPaths.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { assetFilePath, collectAssetFileEntries, imageFileName } from "./assetPaths.js";
3
+ const assetId = "30000000-0000-4000-8000-000000000001";
4
+ describe("asset file naming", () => {
5
+ it("derives an image file name from the sanitized asset name and its mediaType extension", () => {
6
+ expect(imageFileName({ name: "Hero Icon", source: { mediaType: "image/jpeg" } })).toBe("Hero-Icon.jpg");
7
+ expect(assetFilePath(assetId, imageFileName({ name: "Hero Icon", source: { mediaType: "image/jpeg" } }))).toBe(`assets/${assetId}/Hero-Icon.jpg`);
8
+ });
9
+ it("keeps atlas/Spine file names as uploaded when composing their relative path, matching export output", () => {
10
+ const atlas = {
11
+ id: assetId,
12
+ name: "Sparkle Sheet",
13
+ type: "atlas",
14
+ files: {
15
+ json: { name: "sparkles.json", uri: "assets/sparkles.json", mediaType: "application/json" },
16
+ texture: { name: "sparkles.png", uri: "assets/sparkles.png", mediaType: "image/png" },
17
+ },
18
+ frames: {},
19
+ };
20
+ expect(collectAssetFileEntries(atlas)).toEqual([
21
+ { path: `assets/${assetId}/sparkles.json`, fileName: "sparkles.json", mediaType: "application/json" },
22
+ { path: `assets/${assetId}/sparkles.png`, fileName: "sparkles.png", mediaType: "image/png" },
23
+ ]);
24
+ });
25
+ });
26
+ //# sourceMappingURL=assetPaths.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetPaths.test.js","sourceRoot":"","sources":["../src/assetPaths.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGxF,MAAM,OAAO,GAAG,sCAAsC,CAAC;AAEvD,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,sFAAsF,EAAE,GAAG,EAAE;QAC9F,MAAM,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACxG,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,OAAO,gBAAgB,CAAC,CAAC;IACpJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qGAAqG,EAAE,GAAG,EAAE;QAC7G,MAAM,KAAK,GAAU;YACnB,EAAE,EAAE,OAAO;YACX,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,sBAAsB,EAAE,SAAS,EAAE,kBAAkB,EAAE;gBAC3F,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,qBAAqB,EAAE,SAAS,EAAE,WAAW,EAAE;aACtF;YACD,MAAM,EAAE,EAAE;SACX,CAAC;QACF,MAAM,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;YAC7C,EAAE,IAAI,EAAE,UAAU,OAAO,gBAAgB,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,kBAAkB,EAAE;YACrG,EAAE,IAAI,EAAE,UAAU,OAAO,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE;SAC7F,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}