@aura3d/cli 2.0.2 → 2.0.4

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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +20 -0
  3. package/dist/asset-core-types.d.ts +19 -0
  4. package/dist/asset-core-types.d.ts.map +1 -1
  5. package/dist/asset-manifest.d.ts.map +1 -1
  6. package/dist/asset-manifest.js +2 -1
  7. package/dist/asset-manifest.js.map +1 -1
  8. package/dist/cli-help.d.ts.map +1 -1
  9. package/dist/cli-help.js +2 -0
  10. package/dist/cli-help.js.map +1 -1
  11. package/dist/cli.js +24 -1
  12. package/dist/cli.js.map +1 -1
  13. package/dist/index.d.ts +5 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +5 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/meshy/admission.d.ts +40 -0
  18. package/dist/meshy/admission.d.ts.map +1 -0
  19. package/dist/meshy/admission.js +126 -0
  20. package/dist/meshy/admission.js.map +1 -0
  21. package/dist/meshy/evidence.d.ts +12 -0
  22. package/dist/meshy/evidence.d.ts.map +1 -0
  23. package/dist/meshy/evidence.js +37 -0
  24. package/dist/meshy/evidence.js.map +1 -0
  25. package/dist/meshy/import.d.ts +25 -0
  26. package/dist/meshy/import.d.ts.map +1 -0
  27. package/dist/meshy/import.js +104 -0
  28. package/dist/meshy/import.js.map +1 -0
  29. package/dist/meshy/index.d.ts +10 -0
  30. package/dist/meshy/index.d.ts.map +1 -0
  31. package/dist/meshy/index.js +6 -0
  32. package/dist/meshy/index.js.map +1 -0
  33. package/dist/meshy/metadata.d.ts +22 -0
  34. package/dist/meshy/metadata.d.ts.map +1 -0
  35. package/dist/meshy/metadata.js +176 -0
  36. package/dist/meshy/metadata.js.map +1 -0
  37. package/dist/meshy/provenance.d.ts +4 -0
  38. package/dist/meshy/provenance.d.ts.map +1 -0
  39. package/dist/meshy/provenance.js +21 -0
  40. package/dist/meshy/provenance.js.map +1 -0
  41. package/dist/meshy/thumbnail.d.ts +19 -0
  42. package/dist/meshy/thumbnail.d.ts.map +1 -0
  43. package/dist/meshy/thumbnail.js +59 -0
  44. package/dist/meshy/thumbnail.js.map +1 -0
  45. package/dist/meshy/validation.d.ts +5 -0
  46. package/dist/meshy/validation.d.ts.map +1 -0
  47. package/dist/meshy/validation.js +64 -0
  48. package/dist/meshy/validation.js.map +1 -0
  49. package/package.json +4 -3
@@ -0,0 +1,176 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFileSync, statSync } from "node:fs";
3
+ export const MAX_MESHY_METADATA_BYTES = 1024 * 1024;
4
+ const SECRET_KEY = /(?:^|_)(?:api_?key|access_?token|refresh_?token|authorization|bearer|client_?secret|password|credentials?|cookie|private_?key|environment|env)(?:$|_)/i;
5
+ const SIGNED_QUERY_KEY = /^(?:x-amz-|x-goog-|signature$|sig$|token$|expires$|credential$|policy$|key-pair-id$)/i;
6
+ export function readMeshyMetadata(path) {
7
+ const size = statSync(path).size;
8
+ if (size > MAX_MESHY_METADATA_BYTES) {
9
+ throw new Error(`Meshy metadata exceeds ${MAX_MESHY_METADATA_BYTES} bytes: ${path}`);
10
+ }
11
+ let parsed;
12
+ try {
13
+ parsed = JSON.parse(readFileSync(path, "utf8"));
14
+ }
15
+ catch {
16
+ throw new Error(`Meshy metadata is not valid JSON: ${path}`);
17
+ }
18
+ const root = record(parsed, "Meshy metadata");
19
+ rejectCredentialFields(root, "metadata");
20
+ const task = optionalRecord(root.task, "metadata.task") ?? root;
21
+ const prompt = optionalString(first(task.prompt, root.prompt), "prompt");
22
+ const settingsValue = first(task.settings, task.parameters, root.settings, root.parameters);
23
+ const settings = settingsValue === undefined ? undefined : sanitizeRecord(record(settingsValue, "settings"), 0);
24
+ return compact({
25
+ providerCli: optionalString(first(root.providerCli, root.provider_cli, root.cliVersion, root.cli_version), "providerCli"),
26
+ taskId: optionalString(first(task.taskId, task.task_id, task.id, root.taskId, root.task_id), "taskId"),
27
+ parentTaskIds: stringList(first(task.parentTaskIds, task.parent_task_ids, task.parentTaskId, task.parent_task_id), "parentTaskIds"),
28
+ operation: optionalString(first(task.operation, task.type, root.operation, root.type), "operation"),
29
+ promptHash: prompt ? `sha256-${createHash("sha256").update(prompt).digest("hex")}` : undefined,
30
+ model: optionalString(first(task.model, task.modelVersion, task.model_version, root.model), "model"),
31
+ settings,
32
+ createdAt: isoString(first(task.createdAt, task.created_at, root.createdAt, root.created_at), "createdAt"),
33
+ finishedAt: isoString(first(task.finishedAt, task.finished_at, task.completedAt, task.completed_at, root.finishedAt, root.finished_at), "finishedAt"),
34
+ consumedCredits: nonNegativeNumber(first(task.consumedCredits, task.consumed_credits, task.credits, root.consumedCredits, root.consumed_credits), "consumedCredits")
35
+ });
36
+ }
37
+ export function validateMeshyEvidenceJson(path) {
38
+ const size = statSync(path).size;
39
+ if (size > MAX_MESHY_METADATA_BYTES)
40
+ throw new Error(`Meshy rights evidence exceeds ${MAX_MESHY_METADATA_BYTES} bytes: ${path}`);
41
+ let parsed;
42
+ try {
43
+ parsed = JSON.parse(readFileSync(path, "utf8"));
44
+ }
45
+ catch {
46
+ throw new Error(`Meshy rights evidence is not valid JSON: ${path}`);
47
+ }
48
+ const value = record(parsed, "Meshy rights evidence");
49
+ if (Object.keys(value).length === 0)
50
+ throw new Error("Meshy rights evidence must be a non-empty JSON object.");
51
+ rejectCredentialFields(value, "rights evidence");
52
+ const licenseName = boundedRightsString(value.licenseName, "licenseName", 512);
53
+ const licenseUrl = rightsHttpsUrl(first(value.termsUrl, value.licenseUrl), "termsUrl/licenseUrl");
54
+ const licenseRaw = boundedRightsString(first(value.rightsBasis, value.licenseRaw), "rightsBasis/licenseRaw", 4096);
55
+ return compact({ licenseName, licenseUrl, licenseRaw });
56
+ }
57
+ export function stripSignedUrl(value) {
58
+ try {
59
+ const url = new URL(value);
60
+ if ([...url.searchParams.keys()].some((key) => SIGNED_QUERY_KEY.test(key)))
61
+ url.search = "";
62
+ return url.toString();
63
+ }
64
+ catch {
65
+ return value;
66
+ }
67
+ }
68
+ function rejectCredentialFields(value, path) {
69
+ if (Array.isArray(value)) {
70
+ value.forEach((item, index) => rejectCredentialFields(item, `${path}[${index}]`));
71
+ return;
72
+ }
73
+ if (!value || typeof value !== "object")
74
+ return;
75
+ for (const [key, child] of Object.entries(value)) {
76
+ const normalized = key.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[- ]/g, "_");
77
+ if (SECRET_KEY.test(normalized))
78
+ throw new Error(`Meshy input contains forbidden credential field at ${path}.${key}.`);
79
+ rejectCredentialFields(child, `${path}.${key}`);
80
+ }
81
+ }
82
+ function sanitizeRecord(value, depth) {
83
+ if (depth > 4)
84
+ throw new Error("Meshy settings exceed the maximum nesting depth.");
85
+ if (Object.keys(value).length > 100)
86
+ throw new Error("Meshy settings contain too many fields.");
87
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, sanitizeValue(child, depth + 1)]));
88
+ }
89
+ function sanitizeValue(value, depth) {
90
+ if (value === null || typeof value === "boolean" || typeof value === "number")
91
+ return value;
92
+ if (typeof value === "string") {
93
+ if (value.length > 4096)
94
+ throw new Error("Meshy metadata contains an unexpectedly long string.");
95
+ return stripSignedUrl(value);
96
+ }
97
+ if (Array.isArray(value)) {
98
+ if (value.length > 100)
99
+ throw new Error("Meshy metadata contains an unexpectedly large array.");
100
+ return value.map((entry) => sanitizeValue(entry, depth));
101
+ }
102
+ return sanitizeRecord(record(value, "settings value"), depth);
103
+ }
104
+ function record(value, label) {
105
+ if (!value || typeof value !== "object" || Array.isArray(value))
106
+ throw new Error(`${label} must be a JSON object.`);
107
+ return value;
108
+ }
109
+ function optionalRecord(value, label) { return value === undefined ? undefined : record(value, label); }
110
+ function first(...values) { return values.find((value) => value !== undefined && value !== null); }
111
+ function optionalString(value, label) {
112
+ if (value === undefined)
113
+ return undefined;
114
+ if (typeof value !== "string" || value.trim() === "" || value.length > 4096)
115
+ throw new Error(`Meshy metadata field ${label} must be a non-empty bounded string.`);
116
+ return stripSignedUrl(value.trim());
117
+ }
118
+ function boundedRightsString(value, label, maximumLength) {
119
+ if (value === undefined || value === null)
120
+ return undefined;
121
+ if (typeof value !== "string" || value.trim() === "" || value.length > maximumLength) {
122
+ throw new Error(`Meshy rights evidence field ${label} must be a non-empty string of at most ${maximumLength} characters.`);
123
+ }
124
+ return value.trim();
125
+ }
126
+ function rightsHttpsUrl(value, label) {
127
+ const text = boundedRightsString(value, label, 2048);
128
+ if (!text)
129
+ return undefined;
130
+ let url;
131
+ try {
132
+ url = new URL(text);
133
+ }
134
+ catch {
135
+ throw new Error(`Meshy rights evidence field ${label} must be an HTTPS URL.`);
136
+ }
137
+ if (url.protocol !== "https:" || url.username || url.password) {
138
+ throw new Error(`Meshy rights evidence field ${label} must be an HTTPS URL without embedded credentials.`);
139
+ }
140
+ return stripSignedUrl(url.toString());
141
+ }
142
+ function isoString(value, label) {
143
+ if (value === undefined)
144
+ return undefined;
145
+ if (typeof value === "number") {
146
+ if (!Number.isFinite(value) || value < 0)
147
+ throw new Error(`Meshy metadata field ${label} must be an ISO-8601 timestamp or non-negative epoch milliseconds.`);
148
+ const timestamp = new Date(value);
149
+ if (Number.isNaN(timestamp.getTime()))
150
+ throw new Error(`Meshy metadata field ${label} must be an ISO-8601 timestamp or non-negative epoch milliseconds.`);
151
+ return timestamp.toISOString();
152
+ }
153
+ const text = optionalString(value, label);
154
+ if (!text)
155
+ return undefined;
156
+ if (Number.isNaN(Date.parse(text)))
157
+ throw new Error(`Meshy metadata field ${label} must be an ISO-8601 timestamp or non-negative epoch milliseconds.`);
158
+ return text;
159
+ }
160
+ function nonNegativeNumber(value, label) {
161
+ if (value === undefined)
162
+ return undefined;
163
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0)
164
+ throw new Error(`Meshy metadata field ${label} must be a non-negative number.`);
165
+ return value;
166
+ }
167
+ function stringList(value, label) {
168
+ if (value === undefined)
169
+ return undefined;
170
+ const values = Array.isArray(value) ? value : [value];
171
+ if (values.length > 100)
172
+ throw new Error(`Meshy metadata field ${label} contains too many values.`);
173
+ return values.map((entry) => optionalString(entry, label));
174
+ }
175
+ function compact(value) { return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined)); }
176
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../../../packages/aura3d-cli/src/meshy/metadata.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { AuraCliGeneratedAssetProvenance } from "../asset-core-types.js";
2
+ import type { SanitizedMeshyMetadata } from "./metadata.js";
3
+ export declare function createMeshyProvenance(projectDir: string, metadataPath: string, rightsPath: string, metadata: SanitizedMeshyMetadata): AuraCliGeneratedAssetProvenance;
4
+ //# sourceMappingURL=provenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../../../../packages/aura3d-cli/src/meshy/provenance.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE5D,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,GAAG,+BAA+B,CAgBrK"}
@@ -0,0 +1,21 @@
1
+ import { realpathSync } from "node:fs";
2
+ import { relative } from "node:path";
3
+ export function createMeshyProvenance(projectDir, metadataPath, rightsPath, metadata) {
4
+ return {
5
+ provider: "meshy",
6
+ providerCli: metadata.providerCli ?? "@meshy-ai/cli@0.2.0",
7
+ ...(metadata.taskId ? { taskId: metadata.taskId } : {}),
8
+ ...(metadata.parentTaskIds?.length ? { parentTaskIds: metadata.parentTaskIds } : {}),
9
+ ...(metadata.operation ? { operation: metadata.operation } : {}),
10
+ ...(metadata.promptHash ? { promptHash: metadata.promptHash } : {}),
11
+ ...(metadata.model ? { model: metadata.model } : {}),
12
+ ...(metadata.settings ? { settings: metadata.settings } : {}),
13
+ ...(metadata.createdAt ? { createdAt: metadata.createdAt } : {}),
14
+ ...(metadata.finishedAt ? { finishedAt: metadata.finishedAt } : {}),
15
+ ...(metadata.consumedCredits !== undefined ? { consumedCredits: metadata.consumedCredits } : {}),
16
+ localMetadata: normalized(relative(realpathSync(projectDir), metadataPath)),
17
+ rightsEvidence: normalized(relative(realpathSync(projectDir), rightsPath))
18
+ };
19
+ }
20
+ function normalized(path) { return path.replaceAll("\\", "/"); }
21
+ //# sourceMappingURL=provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../../../../packages/aura3d-cli/src/meshy/provenance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAIrC,MAAM,UAAU,qBAAqB,CAAC,UAAkB,EAAE,YAAoB,EAAE,UAAkB,EAAE,QAAgC;IAClI,OAAO;QACL,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,qBAAqB;QAC1D,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,GAAG,CAAC,QAAQ,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,QAAQ,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChG,aAAa,EAAE,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;QAC3E,cAAc,EAAE,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC;KAC3E,CAAC;AACJ,CAAC;AACD,SAAS,UAAU,CAAC,IAAY,IAAY,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { AuraCliRenderedProbe } from "../asset-core-types.js";
2
+ export declare const MAX_MESHY_THUMBNAIL_BYTES: number;
3
+ export interface RetainedMeshyThumbnail {
4
+ readonly sourceFile: string;
5
+ readonly outputPath: string;
6
+ readonly url: string;
7
+ readonly sha256: string;
8
+ readonly renderedProbe: AuraCliRenderedProbe;
9
+ }
10
+ export declare function findMeshyThumbnail(inputDir: string, requested: string | undefined): string | undefined;
11
+ export declare function retainMeshyThumbnail(options: {
12
+ readonly projectDir: string;
13
+ readonly inputDir: string;
14
+ readonly requested?: string;
15
+ readonly assetName: string;
16
+ readonly outputDir: string;
17
+ readonly publicPath: string;
18
+ }): RetainedMeshyThumbnail | undefined;
19
+ //# sourceMappingURL=thumbnail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail.d.ts","sourceRoot":"","sources":["../../../../../packages/aura3d-cli/src/meshy/thumbnail.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAKnE,eAAO,MAAM,yBAAyB,QAAmB,CAAC;AAE1D,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,oBAAoB,CAAC;CAC9C;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOtG;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,GAAG,sBAAsB,GAAG,SAAS,CA4BrC"}
@@ -0,0 +1,59 @@
1
+ import { createHash } from "node:crypto";
2
+ import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync } from "node:fs";
3
+ import { extname, join, resolve } from "node:path";
4
+ import { resolveConfinedPath } from "./validation.js";
5
+ const THUMBNAIL_NAMES = ["thumbnail", "thumb", "preview", "render"];
6
+ const THUMBNAIL_EXTENSIONS = new Set([".png", ".jpg", ".jpeg", ".webp"]);
7
+ export const MAX_MESHY_THUMBNAIL_BYTES = 20 * 1024 * 1024;
8
+ export function findMeshyThumbnail(inputDir, requested) {
9
+ if (requested)
10
+ return resolveConfinedPath(inputDir, requested, "thumbnail");
11
+ const matches = readdirSync(inputDir, { withFileTypes: true })
12
+ .filter((entry) => entry.isFile() && THUMBNAIL_EXTENSIONS.has(extname(entry.name).toLowerCase()) && THUMBNAIL_NAMES.includes(entry.name.replace(/\.[^.]+$/, "").toLowerCase()))
13
+ .map((entry) => resolve(inputDir, entry.name));
14
+ if (matches.length > 1)
15
+ throw new Error("Meshy output contains multiple candidate thumbnails. Select exactly one with --thumbnail <relative-image>.");
16
+ return matches[0];
17
+ }
18
+ export function retainMeshyThumbnail(options) {
19
+ const source = findMeshyThumbnail(options.inputDir, options.requested);
20
+ if (!source)
21
+ return undefined;
22
+ const stat = statSync(source);
23
+ const extension = extname(source).toLowerCase();
24
+ if (!stat.isFile() || !THUMBNAIL_EXTENSIONS.has(extension))
25
+ throw new Error("Meshy thumbnail must be a PNG, JPEG, or WebP regular file.");
26
+ if (stat.size === 0 || stat.size > MAX_MESHY_THUMBNAIL_BYTES)
27
+ throw new Error("Meshy thumbnail must be non-empty and no larger than " + MAX_MESHY_THUMBNAIL_BYTES + " bytes.");
28
+ const bytes = readFileSync(source);
29
+ validateImageSignature(bytes, extension);
30
+ const hash = createHash("sha256").update(bytes).digest("hex");
31
+ const fileName = options.assetName + ".meshy-candidate." + hash.slice(0, 8) + extension;
32
+ const outputPath = join(options.outputDir, fileName).replaceAll("\\", "/");
33
+ const destination = resolve(options.projectDir, outputPath);
34
+ mkdirSync(resolve(options.projectDir, options.outputDir), { recursive: true });
35
+ if (!existsSync(destination))
36
+ copyFileSync(source, destination);
37
+ const url = options.publicPath.replace(/\/?$/, "/") + fileName;
38
+ return {
39
+ sourceFile: source,
40
+ outputPath,
41
+ url,
42
+ sha256: "sha256-" + hash,
43
+ renderedProbe: {
44
+ url,
45
+ kind: "manual-inspection",
46
+ sha256: "sha256-" + hash,
47
+ checkedAt: new Date().toISOString()
48
+ }
49
+ };
50
+ }
51
+ function validateImageSignature(bytes, extension) {
52
+ const png = bytes.length >= 8 && bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]));
53
+ const jpeg = bytes.length >= 3 && bytes[0] === 0xff && bytes[1] === 0xd8 && bytes[2] === 0xff;
54
+ const webp = bytes.length >= 12 && bytes.toString("ascii", 0, 4) === "RIFF" && bytes.toString("ascii", 8, 12) === "WEBP";
55
+ const valid = extension === ".png" ? png : extension === ".webp" ? webp : jpeg;
56
+ if (!valid)
57
+ throw new Error("Meshy thumbnail content does not match its image extension.");
58
+ }
59
+ //# sourceMappingURL=thumbnail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail.js","sourceRoot":"","sources":["../../../../../packages/aura3d-cli/src/meshy/thumbnail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,eAAe,GAAG,CAAC,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AACpE,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AACzE,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAU1D,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,SAA6B;IAChF,IAAI,SAAS;QAAE,OAAO,mBAAmB,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SAC3D,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;SAC9K,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACjD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4GAA4G,CAAC,CAAC;IACtJ,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAOpC;IACC,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACvE,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IAChD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAC1I,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,yBAAyB;QAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,GAAG,yBAAyB,GAAG,SAAS,CAAC,CAAC;IAC/K,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACnC,sBAAsB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC;IACxF,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC3E,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC5D,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAChE,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC;IAC/D,OAAO;QACL,UAAU,EAAE,MAAM;QAClB,UAAU;QACV,GAAG;QACH,MAAM,EAAE,SAAS,GAAG,IAAI;QACxB,aAAa,EAAE;YACb,GAAG;YACH,IAAI,EAAE,mBAAmB;YACzB,MAAM,EAAE,SAAS,GAAG,IAAI;YACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAa,EAAE,SAAiB;IAC9D,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7G,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAC9F,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC;IACzH,MAAM,KAAK,GAAG,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/E,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;AAC7F,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const MAX_MESHY_GLB_BYTES: number;
2
+ export declare function resolveConfinedPath(allowedRoot: string, candidate: string, label: string): string;
3
+ export declare function selectMeshyGlb(inputDir: string, file: string | undefined): string;
4
+ export declare function validateMeshyGlb(path: string): void;
5
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../../../packages/aura3d-cli/src/meshy/validation.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,QAAoB,CAAC;AAErD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBjG;AACD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAcjF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAWnD"}
@@ -0,0 +1,64 @@
1
+ import { closeSync, existsSync, openSync, readSync, realpathSync, readdirSync, statSync } from "node:fs";
2
+ import { extname, isAbsolute, relative, resolve } from "node:path";
3
+ export const MAX_MESHY_GLB_BYTES = 100 * 1024 * 1024;
4
+ export function resolveConfinedPath(allowedRoot, candidate, label) {
5
+ if (!existsSync(allowedRoot))
6
+ throw new Error(`Meshy allowed root does not exist: ${allowedRoot}`);
7
+ const lexicalRoot = resolve(allowedRoot);
8
+ const target = resolve(isAbsolute(candidate) ? candidate : resolve(lexicalRoot, candidate));
9
+ const lexicalRelative = relative(lexicalRoot, target);
10
+ if (lexicalRelative === ".." || lexicalRelative.startsWith("../") || isAbsolute(lexicalRelative)) {
11
+ throw new Error(`Meshy ${label} escapes the allowed root: ${candidate}`);
12
+ }
13
+ if (!existsSync(target))
14
+ throw new Error(`Meshy ${label} does not exist: ${candidate}`);
15
+ const root = realpathSync(lexicalRoot);
16
+ const realTarget = realpathSync(target);
17
+ const realRelative = relative(root, realTarget);
18
+ if (realRelative === ".." || realRelative.startsWith("../") || isAbsolute(realRelative)) {
19
+ throw new Error(`Meshy ${label} escapes the allowed root through a symbolic link: ${candidate}`);
20
+ }
21
+ return realTarget;
22
+ }
23
+ export function selectMeshyGlb(inputDir, file) {
24
+ if (!statSync(inputDir).isDirectory())
25
+ throw new Error(`Meshy input must be a directory: ${inputDir}`);
26
+ if (file) {
27
+ const selected = resolveConfinedPath(inputDir, file, "selected GLB");
28
+ validateMeshyGlb(selected);
29
+ return selected;
30
+ }
31
+ const glbs = readdirSync(inputDir, { withFileTypes: true })
32
+ .filter((entry) => entry.isFile() && extname(entry.name).toLowerCase() === ".glb")
33
+ .map((entry) => resolve(inputDir, entry.name));
34
+ if (glbs.length === 0)
35
+ throw new Error("Meshy output contains no GLB. Supply a completed local output directory.");
36
+ if (glbs.length > 1)
37
+ throw new Error("Meshy output contains multiple GLBs. Select exactly one with --file <relative.glb>.");
38
+ validateMeshyGlb(glbs[0]);
39
+ return glbs[0];
40
+ }
41
+ export function validateMeshyGlb(path) {
42
+ const stat = statSync(path);
43
+ if (!stat.isFile())
44
+ throw new Error(`Meshy GLB is not a regular file: ${path}`);
45
+ if (extname(path).toLowerCase() !== ".glb")
46
+ throw new Error(`Meshy selected file must use the .glb extension: ${path}`);
47
+ if (stat.size < 20)
48
+ throw new Error(`Meshy GLB is too small to be valid: ${path}`);
49
+ if (stat.size > MAX_MESHY_GLB_BYTES)
50
+ throw new Error(`Meshy GLB exceeds ${MAX_MESHY_GLB_BYTES} bytes: ${path}`);
51
+ const bytes = Buffer.alloc(12);
52
+ const handle = openSync(path, "r");
53
+ try {
54
+ readSync(handle, bytes, 0, 12, 0);
55
+ }
56
+ finally {
57
+ closeSync(handle);
58
+ }
59
+ if (bytes.toString("utf8", 0, 4) !== "glTF")
60
+ throw new Error(`Meshy GLB has invalid magic bytes: ${path}`);
61
+ if (bytes.readUInt32LE(8) !== stat.size)
62
+ throw new Error(`Meshy GLB declared length does not match its file size: ${path}`);
63
+ }
64
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../../../packages/aura3d-cli/src/meshy/validation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aura3d/cli",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "aura3d": "dist/cli.js",
@@ -9,6 +9,7 @@
9
9
  },
10
10
  "files": [
11
11
  "README.md",
12
+ "LICENSE",
12
13
  "dist"
13
14
  ],
14
15
  "publishConfig": {
@@ -24,8 +25,8 @@
24
25
  "types": "./dist/index.d.ts",
25
26
  "dependencies": {
26
27
  "typescript": "^5.8.3",
27
- "@aura3d/asset-index": "2.0.2",
28
- "create-aura3d": "2.0.2"
28
+ "create-aura3d": "2.0.4",
29
+ "@aura3d/asset-index": "2.0.4"
29
30
  },
30
31
  "description": "Bring real GLB/glTF assets into Aura3D browser apps with typed references, provenance, catalog search, validation, screenshots, and deploy checks.",
31
32
  "keywords": [