@dcl/sdk-commands 7.12.0 → 7.12.1-18976734253.commit-271785b

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 (36) hide show
  1. package/dist/commands/code-to-composite/asset-migrator.d.ts +25 -0
  2. package/dist/commands/code-to-composite/asset-migrator.js +239 -0
  3. package/dist/commands/code-to-composite/asset-migrator.js.map +1 -0
  4. package/dist/commands/code-to-composite/code-commenter.d.ts +11 -0
  5. package/dist/commands/code-to-composite/code-commenter.js +88 -0
  6. package/dist/commands/code-to-composite/code-commenter.js.map +1 -0
  7. package/dist/commands/code-to-composite/composite-generator.d.ts +6 -0
  8. package/dist/commands/code-to-composite/composite-generator.js +56 -0
  9. package/dist/commands/code-to-composite/composite-generator.js.map +1 -0
  10. package/dist/commands/code-to-composite/index.d.ts +16 -0
  11. package/dist/commands/code-to-composite/index.js +130 -0
  12. package/dist/commands/code-to-composite/index.js.map +1 -0
  13. package/dist/commands/code-to-composite/name-generator.d.ts +9 -0
  14. package/dist/commands/code-to-composite/name-generator.js +140 -0
  15. package/dist/commands/code-to-composite/name-generator.js.map +1 -0
  16. package/dist/commands/code-to-composite/scene-executor.d.ts +15 -0
  17. package/dist/commands/code-to-composite/scene-executor.js +405 -0
  18. package/dist/commands/code-to-composite/scene-executor.js.map +1 -0
  19. package/dist/commands/start/data-layer/fs.d.ts +1 -1
  20. package/dist/commands/start/data-layer/fs.js +12 -8
  21. package/dist/commands/start/data-layer/fs.js.map +1 -1
  22. package/dist/commands/start/data-layer/rpc.d.ts +1 -1
  23. package/dist/commands/start/data-layer/rpc.js +2 -2
  24. package/dist/commands/start/data-layer/rpc.js.map +1 -1
  25. package/dist/commands/start/index.js +2 -1
  26. package/dist/commands/start/index.js.map +1 -1
  27. package/dist/components/fs.d.ts +1 -1
  28. package/dist/components/fs.js +1 -0
  29. package/dist/components/fs.js.map +1 -1
  30. package/dist/locales/en.json +5 -0
  31. package/dist/locales/es.json +5 -0
  32. package/dist/locales/zh.json +5 -0
  33. package/dist/logic/bundle.js +1 -1
  34. package/dist/logic/error.d.ts +1 -1
  35. package/dist/logic/error.js.map +1 -1
  36. package/package.json +4 -3
@@ -0,0 +1,25 @@
1
+ import { IEngine } from '@dcl/ecs/dist-cjs';
2
+ import { CliComponents } from '../../components';
3
+ import { SceneProject } from '../../logic/project-validations';
4
+ /**
5
+ * Asset Migrator for code-to-composite command
6
+ *
7
+ * This module handles migrating asset files to the Creator Hub directory structure:
8
+ * - Models: assets/scene/Models/{modelName}/*.{gltf,glb} (with dependencies)
9
+ * - Images: assets/scene/Images/*.{png,jpg,jpeg,bmp}
10
+ * - Audio: assets/scene/Audio/*.{mp3,wav,ogg}
11
+ * - Video: assets/scene/Video/*.{mp4}
12
+ *
13
+ * Models are treated specially: each model gets its own folder with all dependencies
14
+ * (textures, .bin files) copied into it, even if originally shared between models.
15
+ */
16
+ export type AssetType = 'Models' | 'Images' | 'Audio' | 'Video' | 'Other';
17
+ /**
18
+ * Main asset migration function
19
+ *
20
+ * Process:
21
+ * 1. Scan all components to find asset references
22
+ * 2. Copy asset files to new Creator Hub structure
23
+ * 3. Update all components with new asset paths
24
+ */
25
+ export declare function migrateAssets(components: Pick<CliComponents, 'fs' | 'logger'>, project: SceneProject, engine: IEngine): Promise<number>;
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.migrateAssets = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const gltf_validator_ts_1 = require("@dcl/gltf-validator-ts");
9
+ /**
10
+ * Determines the asset type based on file extension
11
+ */
12
+ function getAssetType(extension) {
13
+ const ext = extension.toLowerCase().replace(/^\./, '');
14
+ switch (ext) {
15
+ case 'gltf':
16
+ case 'glb':
17
+ return 'Models';
18
+ case 'png':
19
+ case 'jpg':
20
+ case 'jpeg':
21
+ case 'bmp':
22
+ return 'Images';
23
+ case 'mp3':
24
+ case 'wav':
25
+ case 'ogg':
26
+ return 'Audio';
27
+ case 'mp4':
28
+ return 'Video';
29
+ default:
30
+ return 'Other';
31
+ }
32
+ }
33
+ /**
34
+ * Checks if a string value looks like an asset path
35
+ */
36
+ function looksLikeAssetPath(value) {
37
+ if (typeof value !== 'string' || value.length === 0) {
38
+ return false;
39
+ }
40
+ const ext = path_1.default.extname(value);
41
+ if (!ext) {
42
+ return false;
43
+ }
44
+ return getAssetType(ext) !== 'Other';
45
+ }
46
+ /**
47
+ * Extracts dependencies from a GLTF file using @dcl/gltf-validator-ts
48
+ */
49
+ async function extractGltfDependencies(components, gltfPath) {
50
+ const { fs, logger } = components;
51
+ const dependencies = {
52
+ textures: [],
53
+ binaries: []
54
+ };
55
+ try {
56
+ const gltfBuffer = await fs.readFile(gltfPath);
57
+ const result = await (0, gltf_validator_ts_1.validateBytes)(new Uint8Array(gltfBuffer), {
58
+ externalResourceFunction: () => Promise.resolve(new Uint8Array())
59
+ });
60
+ if (result.info && result.info.resources) {
61
+ for (const resource of result.info.resources) {
62
+ if (resource.storage === 'external' && resource.uri) {
63
+ const uri = resource.uri;
64
+ if (resource.pointer && resource.pointer.includes('image')) {
65
+ dependencies.textures.push(uri);
66
+ }
67
+ else if (resource.pointer && resource.pointer.includes('buffer')) {
68
+ dependencies.binaries.push(uri);
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ catch (error) {
75
+ logger.error(` ⚠ Failed to extract dependencies from GLTF "${gltfPath}": ${error}`);
76
+ }
77
+ return dependencies;
78
+ }
79
+ /**
80
+ * Builds the destination path following Creator Hub conventions
81
+ */
82
+ function getDestinationPath(sceneRoot, originalPath) {
83
+ const fileName = path_1.default.basename(originalPath);
84
+ const extension = path_1.default.extname(originalPath);
85
+ const assetType = getAssetType(extension);
86
+ if (assetType === 'Models') {
87
+ // Models get their own folder: assets/scene/Models/{modelName}/file.glb
88
+ const modelName = path_1.default.basename(originalPath, extension);
89
+ return path_1.default.join(sceneRoot, 'assets', 'scene', 'Models', modelName, fileName);
90
+ }
91
+ // Other assets go directly in type folder: assets/scene/Images/file.png
92
+ return path_1.default.join(sceneRoot, 'assets', 'scene', assetType, fileName);
93
+ }
94
+ /**
95
+ * Recursively finds all asset paths in component data
96
+ */
97
+ function collectAssetPaths(data, assetPaths) {
98
+ if (data === null || data === undefined) {
99
+ return;
100
+ }
101
+ if (typeof data === 'string') {
102
+ if (looksLikeAssetPath(data)) {
103
+ assetPaths.add(data);
104
+ }
105
+ return;
106
+ }
107
+ if (Array.isArray(data)) {
108
+ for (const item of data) {
109
+ collectAssetPaths(item, assetPaths);
110
+ }
111
+ return;
112
+ }
113
+ if (typeof data === 'object') {
114
+ for (const value of Object.values(data)) {
115
+ collectAssetPaths(value, assetPaths);
116
+ }
117
+ }
118
+ }
119
+ /**
120
+ * Recursively replaces asset paths in component data
121
+ * Returns an object with the updated data and a flag indicating if changes were made
122
+ */
123
+ function replaceAssetPaths(data, pathMapping) {
124
+ if (data === null || data === undefined) {
125
+ return { data, hasChanges: false };
126
+ }
127
+ if (typeof data === 'string') {
128
+ const newPath = pathMapping.get(data);
129
+ if (newPath !== undefined) {
130
+ return { data: newPath, hasChanges: true };
131
+ }
132
+ return { data, hasChanges: false };
133
+ }
134
+ if (Array.isArray(data)) {
135
+ let hasChanges = false;
136
+ const result = data.map((item) => {
137
+ const replaced = replaceAssetPaths(item, pathMapping);
138
+ if (replaced.hasChanges)
139
+ hasChanges = true;
140
+ return replaced.data;
141
+ });
142
+ return { data: result, hasChanges };
143
+ }
144
+ if (typeof data === 'object') {
145
+ let hasChanges = false;
146
+ const result = {};
147
+ for (const [key, value] of Object.entries(data)) {
148
+ const replaced = replaceAssetPaths(value, pathMapping);
149
+ if (replaced.hasChanges)
150
+ hasChanges = true;
151
+ result[key] = replaced.data;
152
+ }
153
+ return { data: result, hasChanges };
154
+ }
155
+ return { data, hasChanges: false };
156
+ }
157
+ /**
158
+ * Main asset migration function
159
+ *
160
+ * Process:
161
+ * 1. Scan all components to find asset references
162
+ * 2. Copy asset files to new Creator Hub structure
163
+ * 3. Update all components with new asset paths
164
+ */
165
+ async function migrateAssets(components, project, engine) {
166
+ const { fs, logger } = components;
167
+ const sceneRoot = project.workingDirectory;
168
+ // Step 1: find all asset paths in the engine
169
+ const assetPaths = new Set();
170
+ for (const component of engine.componentsIter()) {
171
+ for (const [entity] of engine.getEntitiesWith(component)) {
172
+ const componentData = component.get(entity);
173
+ if (componentData) {
174
+ collectAssetPaths(componentData, assetPaths);
175
+ }
176
+ }
177
+ }
178
+ if (assetPaths.size === 0) {
179
+ logger.log('No assets found to migrate');
180
+ return 0;
181
+ }
182
+ logger.log(`Found ${assetPaths.size} asset reference(s)`);
183
+ // Step 2: copy files to new locations
184
+ const pathMapping = new Map();
185
+ for (const originalPath of assetPaths) {
186
+ const absoluteOriginalPath = path_1.default.isAbsolute(originalPath) ? originalPath : path_1.default.join(sceneRoot, originalPath);
187
+ if (!(await fs.fileExists(absoluteOriginalPath))) {
188
+ logger.warn(` ⚠ Asset not found: ${originalPath}`);
189
+ continue;
190
+ }
191
+ const assetType = getAssetType(path_1.default.extname(originalPath));
192
+ const newAbsolutePath = getDestinationPath(sceneRoot, originalPath);
193
+ const newRelativePath = path_1.default.relative(sceneRoot, newAbsolutePath);
194
+ await fs.mkdir(path_1.default.dirname(newAbsolutePath), { recursive: true });
195
+ await fs.copyFile(absoluteOriginalPath, newAbsolutePath);
196
+ pathMapping.set(originalPath, newRelativePath);
197
+ logger.log(` ✓ ${originalPath} → ${newRelativePath}`);
198
+ // special handling for models: copy dependencies
199
+ if (assetType === 'Models') {
200
+ const dependencies = await extractGltfDependencies(components, absoluteOriginalPath);
201
+ if (dependencies.textures.length === 0 && dependencies.binaries.length === 0) {
202
+ continue;
203
+ }
204
+ const allDependencies = [...dependencies.textures, ...dependencies.binaries];
205
+ for (const depFileName of allDependencies) {
206
+ const depOriginalPath = path_1.default.join(path_1.default.dirname(absoluteOriginalPath), depFileName);
207
+ if (await fs.fileExists(depOriginalPath)) {
208
+ const depNewPath = path_1.default.join(path_1.default.dirname(newAbsolutePath), depFileName);
209
+ await fs.copyFile(depOriginalPath, depNewPath);
210
+ const depOriginalRelative = path_1.default.join(path_1.default.dirname(originalPath), depFileName);
211
+ const depNewRelative = path_1.default.relative(sceneRoot, depNewPath);
212
+ pathMapping.set(depOriginalRelative, depNewRelative);
213
+ logger.log(` ↳ ${depFileName}`);
214
+ }
215
+ }
216
+ }
217
+ }
218
+ logger.log(`Migrated ${pathMapping.size} asset file(s)`);
219
+ // Step 3: update components with new paths
220
+ let updatedCount = 0;
221
+ for (const component of engine.componentsIter()) {
222
+ for (const [entity] of engine.getEntitiesWith(component)) {
223
+ const componentData = component.get(entity);
224
+ if (componentData) {
225
+ const { data: updatedData, hasChanges } = replaceAssetPaths(componentData, pathMapping);
226
+ if (hasChanges) {
227
+ // only supporting LastWriteWinElementSetComponentDefinition (inspector does the same thing)
228
+ if ('createOrReplace' in component) {
229
+ component.createOrReplace(entity, updatedData);
230
+ updatedCount++;
231
+ }
232
+ }
233
+ }
234
+ }
235
+ }
236
+ return updatedCount;
237
+ }
238
+ exports.migrateAssets = migrateAssets;
239
+ //# sourceMappingURL=asset-migrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-migrator.js","sourceRoot":"","sources":["../../../src/commands/code-to-composite/asset-migrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { CliComponents } from '../../components';
2
+ /**
3
+ * Replaces the entrypoint file with a stub main() function
4
+ */
5
+ export declare function commentEntrypoint({ fs }: Pick<CliComponents, 'fs'>, entrypointPath: string): Promise<void>;
6
+ /**
7
+ * Comments out the entrypoint and all source files in the src directory
8
+ *
9
+ * NOTE: Need to comment out all the src files otherwise typechecker will fail preventing deploys, etc.
10
+ */
11
+ export declare function commentSourceFiles(components: Pick<CliComponents, 'fs'>, sceneCodeEntrypoint: string, bundleEntrypoint: string): Promise<number>;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.commentSourceFiles = exports.commentEntrypoint = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const glob_1 = require("glob");
9
+ const COMMENT_MARKER = 'COMMENTED BY "@dcl/sdk-commands code-to-composite" COMMAND';
10
+ /**
11
+ * Checks if a file has already been commented by this command
12
+ */
13
+ function isAlreadyCommented(content) {
14
+ return content.includes(COMMENT_MARKER);
15
+ }
16
+ /**
17
+ * Generates the comment header for migrated files
18
+ */
19
+ function generateCommentHeader(content) {
20
+ // use line-by-line commenting to avoid issues with existing /* */ comments
21
+ const commentedLines = content.split('\n').map(line => `// ${line}`).join('\n');
22
+ return `// ============================================================================
23
+ // ${COMMENT_MARKER}
24
+ //
25
+ // This code has been migrated to main.composite and main.crdt files.
26
+ // The scene can now be edited visually using the Creator Hub app.
27
+ //
28
+ // To restore code-based workflow: Uncomment the code below
29
+ // For hybrid workflow: Uncomment specific parts you want to keep dynamic
30
+ //
31
+ // Learn more: https://docs.decentraland.org/creator
32
+ // ============================================================================
33
+ //
34
+ ${commentedLines}`;
35
+ }
36
+ /**
37
+ * Replaces the entrypoint file with a stub main() function
38
+ */
39
+ async function commentEntrypoint({ fs }, entrypointPath) {
40
+ const stubContent = `// ${COMMENT_MARKER}
41
+ // Scene content is managed by Creator Hub (main.composite)
42
+
43
+ export function main() {
44
+ // Add dynamic code, systems, or event handlers here
45
+ }
46
+ `;
47
+ await fs.writeFile(entrypointPath, stubContent);
48
+ }
49
+ exports.commentEntrypoint = commentEntrypoint;
50
+ /**
51
+ * Comments out a single source file
52
+ */
53
+ async function commentSourceFile({ fs }, filePath) {
54
+ const currentContent = await fs.readFile(filePath, 'utf-8');
55
+ if (isAlreadyCommented(currentContent)) {
56
+ return;
57
+ }
58
+ const commentedContent = generateCommentHeader(currentContent) + '\n';
59
+ await fs.writeFile(filePath, commentedContent);
60
+ }
61
+ /**
62
+ * Comments out the entrypoint and all source files in the src directory
63
+ *
64
+ * NOTE: Need to comment out all the src files otherwise typechecker will fail preventing deploys, etc.
65
+ */
66
+ async function commentSourceFiles(components, sceneCodeEntrypoint, bundleEntrypoint) {
67
+ const normalizedBundleEntrypoint = path_1.default.normalize(bundleEntrypoint);
68
+ const normalizedSceneCodeEntrypoint = path_1.default.normalize(sceneCodeEntrypoint);
69
+ const srcDir = path_1.default.dirname(normalizedSceneCodeEntrypoint);
70
+ const sourceFiles = (0, glob_1.globSync)('**/*.{ts,tsx,js,jsx}', {
71
+ cwd: srcDir,
72
+ absolute: true,
73
+ ignore: ['**/*.d.ts', '**/node_modules/**']
74
+ });
75
+ const filesToComment = sourceFiles.filter(file => {
76
+ const normalized = path_1.default.normalize(file);
77
+ return normalized !== normalizedBundleEntrypoint &&
78
+ normalized !== normalizedSceneCodeEntrypoint;
79
+ });
80
+ await Promise.all([
81
+ commentEntrypoint(components, normalizedBundleEntrypoint),
82
+ commentSourceFile(components, normalizedSceneCodeEntrypoint),
83
+ ...filesToComment.map(file => commentSourceFile(components, file))
84
+ ]);
85
+ return filesToComment.length;
86
+ }
87
+ exports.commentSourceFiles = commentSourceFiles;
88
+ //# sourceMappingURL=code-commenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-commenter.js","sourceRoot":"","sources":["../../../src/commands/code-to-composite/code-commenter.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAuB;AACvB,+BAA+B;AAI/B,MAAM,cAAc,GAAG,4DAA4D,CAAA;AAEnF;;GAEG;AACH,SAAS,kBAAkB,CAAC,OAAe;IACzC,OAAO,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAA;AACzC,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,OAAe;IAC5C,2EAA2E;IAC3E,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE/E,OAAO;KACJ,cAAc;;;;;;;;;;;EAWjB,cAAc,EAAE,CAAA;AAClB,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,iBAAiB,CAAC,EAAE,EAAE,EAA6B,EAAE,cAAsB;IAC/F,MAAM,WAAW,GAAG,MAAM,cAAc;;;;;;CAMzC,CAAA;IAEC,MAAM,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;AACjD,CAAC;AAVD,8CAUC;AAED;;GAEG;AACH,KAAK,UAAU,iBAAiB,CAAC,EAAE,EAAE,EAA6B,EAAE,QAAgB;IAClF,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAE3D,IAAI,kBAAkB,CAAC,cAAc,CAAC,EAAE;QACtC,OAAM;KACP;IAED,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,cAAc,CAAC,GAAG,IAAI,CAAA;IAErE,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAA;AAChD,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,kBAAkB,CACtC,UAAqC,EACrC,mBAA2B,EAC3B,gBAAwB;IAExB,MAAM,0BAA0B,GAAG,cAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAA;IACnE,MAAM,6BAA6B,GAAG,cAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAA;IACzE,MAAM,MAAM,GAAG,cAAI,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAA;IAE1D,MAAM,WAAW,GAAG,IAAA,eAAQ,EAAC,sBAAsB,EAAE;QACnD,GAAG,EAAE,MAAM;QACX,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,CAAC,WAAW,EAAE,oBAAoB,CAAC;KAC5C,CAAC,CAAA;IAEF,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QAC/C,MAAM,UAAU,GAAG,cAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACvC,OAAO,UAAU,KAAK,0BAA0B;YACzC,UAAU,KAAK,6BAA6B,CAAA;IACrD,CAAC,CAAC,CAAA;IAEF,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,iBAAiB,CAAC,UAAU,EAAE,0BAA0B,CAAC;QACzD,iBAAiB,CAAC,UAAU,EAAE,6BAA6B,CAAC;QAC5D,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;KACnE,CAAC,CAAA;IAEF,OAAO,cAAc,CAAC,MAAM,CAAA;AAC9B,CAAC;AA5BD,gDA4BC"}
@@ -0,0 +1,6 @@
1
+ import { CliComponents } from '../../components';
2
+ import { IEngine } from '@dcl/ecs/dist-cjs';
3
+ /**
4
+ * Generates composite and CRDT files from an ECS engine state.
5
+ */
6
+ export declare function generateCompositeFiles(components: Pick<CliComponents, 'fs' | 'logger'>, engine: IEngine, compositeFilePath: string, crdtFilePath: string, entityNamesFilePath: string): Promise<void>;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.generateCompositeFiles = void 0;
27
+ const inspector_1 = require("@dcl/inspector");
28
+ const fs_1 = require("../start/data-layer/fs");
29
+ const dist_cjs_1 = require("@dcl/ecs/dist-cjs");
30
+ const path = __importStar(require("path"));
31
+ async function ensureDirectoryExists({ fs }, filePath) {
32
+ const dir = path.dirname(filePath);
33
+ await fs.mkdir(dir, { recursive: true });
34
+ }
35
+ /**
36
+ * Generates composite and CRDT files from an ECS engine state.
37
+ */
38
+ async function generateCompositeFiles(components, engine, compositeFilePath, crdtFilePath, entityNamesFilePath) {
39
+ const { fs } = components;
40
+ // ensure all directories exist
41
+ await ensureDirectoryExists(components, compositeFilePath);
42
+ await ensureDirectoryExists(components, crdtFilePath);
43
+ await ensureDirectoryExists(components, entityNamesFilePath);
44
+ const _engine = engine;
45
+ // generate composite JSON
46
+ const composite = (0, inspector_1.dumpEngineToComposite)(_engine, 'json');
47
+ await fs.writeFile(compositeFilePath, JSON.stringify(dist_cjs_1.Composite.toJson(composite), null, 2));
48
+ // generate CRDT binary
49
+ const crdtData = (0, inspector_1.dumpEngineToCrdtCommands)(_engine);
50
+ await fs.writeFile(crdtFilePath, crdtData);
51
+ const workingDirectory = path.dirname(compositeFilePath);
52
+ const fsAdapter = (0, fs_1.createFileSystemInterfaceFromFsComponent)({ fs }, workingDirectory);
53
+ await (0, inspector_1.generateEntityNamesType)(_engine, entityNamesFilePath, 'EntityNames', fsAdapter);
54
+ }
55
+ exports.generateCompositeFiles = generateCompositeFiles;
56
+ //# sourceMappingURL=composite-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composite-generator.js","sourceRoot":"","sources":["../../../src/commands/code-to-composite/composite-generator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8CAKuB;AAEvB,+CAAiF;AAEjF,gDAAsD;AACtD,2CAA4B;AAE5B,KAAK,UAAU,qBAAqB,CAAC,EAAE,EAAE,EAA6B,EAAE,QAAgB;IACtF,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAClC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;AAC1C,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,sBAAsB,CAC1C,UAAgD,EAChD,MAAe,EACf,iBAAyB,EACzB,YAAoB,EACpB,mBAA2B;IAE3B,MAAM,EAAE,EAAE,EAAE,GAAG,UAAU,CAAA;IAEzB,+BAA+B;IAC/B,MAAM,qBAAqB,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAA;IAC1D,MAAM,qBAAqB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IACrD,MAAM,qBAAqB,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAA;IAE5D,MAAM,OAAO,GAAG,MAA2B,CAAA;IAE3C,0BAA0B;IAC1B,MAAM,SAAS,GAAG,IAAA,iCAAqB,EAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IACxD,MAAM,EAAE,CAAC,SAAS,CAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,oBAAS,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAE3F,uBAAuB;IACvB,MAAM,QAAQ,GAAG,IAAA,oCAAwB,EAAC,OAAO,CAAC,CAAA;IAClD,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;IAE1C,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACxD,MAAM,SAAS,GAAwB,IAAA,6CAAwC,EAAC,EAAE,EAAE,EAAE,EAAE,gBAAgB,CAAC,CAAA;IACzG,MAAM,IAAA,mCAAuB,EAAC,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,SAAS,CAAC,CAAA;AACvF,CAAC;AA3BD,wDA2BC"}
@@ -0,0 +1,16 @@
1
+ import { Result } from 'arg';
2
+ import { CliComponents } from '../../components';
3
+ interface Options {
4
+ args: Result<typeof args>;
5
+ components: Pick<CliComponents, 'fs' | 'logger' | 'analytics' | 'spawner'>;
6
+ }
7
+ export declare const args: {
8
+ '--dir': StringConstructor;
9
+ '--help': BooleanConstructor;
10
+ '-h': string;
11
+ '--yes': BooleanConstructor;
12
+ '-y': string;
13
+ };
14
+ export declare function help(options: Options): void;
15
+ export declare function main(options: Options): Promise<void>;
16
+ export {};
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.main = exports.help = exports.args = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const prompts_1 = __importDefault(require("prompts"));
9
+ const args_1 = require("../../logic/args");
10
+ const workspace_validations_1 = require("../../logic/workspace-validations");
11
+ const beautiful_logs_1 = require("../../logic/beautiful-logs");
12
+ const scene_executor_1 = require("./scene-executor");
13
+ const composite_generator_1 = require("./composite-generator");
14
+ const code_commenter_1 = require("./code-commenter");
15
+ const asset_migrator_1 = require("./asset-migrator");
16
+ const name_generator_1 = require("./name-generator");
17
+ exports.args = (0, args_1.declareArgs)({
18
+ '--dir': String,
19
+ '--help': Boolean,
20
+ '-h': '--help',
21
+ '--yes': Boolean,
22
+ '-y': '--yes',
23
+ });
24
+ function help(options) {
25
+ options.components.logger.log(`
26
+ Usage: 'sdk-commands code-to-composite [options]'
27
+
28
+ Description:
29
+
30
+ Migrates a code-only scene to Creator Hub-compatible format by generating
31
+ composite/crdt files and commenting out the original code.
32
+
33
+ Options:
34
+
35
+ -h, --help Displays complete help
36
+ --dir Path to directory to export
37
+ -y, --yes Skip the confirmation prompt
38
+
39
+ Example:
40
+
41
+ - Export a code-only scene to Creator Hub format:
42
+ '$ sdk-commands code-to-composite'
43
+
44
+ - Export a specific directory:
45
+ '$ sdk-commands code-to-composite --dir ./my-scene'
46
+ `);
47
+ }
48
+ exports.help = help;
49
+ async function main(options) {
50
+ const workingDirectory = path_1.default.resolve(process.cwd(), options.args['--dir'] || '.');
51
+ const workspace = await (0, workspace_validations_1.getValidWorkspace)(options.components, workingDirectory);
52
+ const shouldContinue = options.args['--yes'] ? true : await promptForDestructiveAction(options.components);
53
+ if (!shouldContinue)
54
+ return;
55
+ const MAX_STEPS = 5;
56
+ for (const project of workspace.projects) {
57
+ (0, beautiful_logs_1.printCurrentProjectStarting)(options.components.logger, project, workspace);
58
+ if (project.kind === 'scene') {
59
+ await exportSceneToCrdt(options, project, MAX_STEPS);
60
+ }
61
+ else {
62
+ options.components.logger.warn(`Project ${project.workingDirectory} is not a scene, skipping...`);
63
+ }
64
+ }
65
+ }
66
+ exports.main = main;
67
+ async function promptForDestructiveAction(components) {
68
+ const { logger } = components;
69
+ (0, beautiful_logs_1.printWarning)(logger, 'This command will modify your scene code by commenting it out and creating composite/CRDT files.');
70
+ logger.log(' - Your original code will be backed up with a .backup.ts extension');
71
+ logger.log(' - The scene will be converted to Creator Hub format');
72
+ logger.log(' - Files will be moved around');
73
+ logger.log(' - If you are not using any version control system, undoing this operation will be REALLY cumbersome');
74
+ logger.log('');
75
+ let cancelled = false;
76
+ const onCancel = () => {
77
+ cancelled = true;
78
+ };
79
+ const { confirmed } = await (0, prompts_1.default)({
80
+ type: 'confirm',
81
+ name: 'confirmed',
82
+ message: 'Do you want to continue?',
83
+ initial: false
84
+ }, { onCancel });
85
+ if (cancelled || !confirmed) {
86
+ logger.log('Operation cancelled by user.');
87
+ return false;
88
+ }
89
+ return true;
90
+ }
91
+ async function exportSceneToCrdt(options, project, maxSteps) {
92
+ const { logger } = options.components;
93
+ let currentStep = 1;
94
+ const compositeFilePath = path_1.default.join(project.workingDirectory, 'assets', 'scene', 'main.composite');
95
+ const crdtFilePath = path_1.default.join(project.workingDirectory, 'main.crdt');
96
+ const entityNamesFilePath = path_1.default.join(project.workingDirectory, 'src', 'entity-names.ts');
97
+ // Step 1: execute scene code to populate engine
98
+ (0, beautiful_logs_1.printProgressStep)(logger, 'Executing scene code to capture state', currentStep++, maxSteps);
99
+ const { engine, sceneCodeEntrypoint } = await (0, scene_executor_1.executeSceneCode)(options.components, project, crdtFilePath);
100
+ (0, beautiful_logs_1.printProgressInfo)(logger, `Engine state captured successfully`);
101
+ // Step 2: migrate assets (before generating composite/crdt)
102
+ (0, beautiful_logs_1.printProgressStep)(logger, 'Organizing assets for Creator Hub', currentStep++, maxSteps);
103
+ const updatedCount = await (0, asset_migrator_1.migrateAssets)(options.components, project, engine);
104
+ (0, beautiful_logs_1.printProgressInfo)(logger, `Migrated ${updatedCount} asset file(s) successfully`);
105
+ // Step 3: generate entity names
106
+ (0, beautiful_logs_1.printProgressStep)(logger, 'Generating names for entities', currentStep++, maxSteps);
107
+ const namedEntitiesCount = await (0, name_generator_1.generateEntityNames)(options.components, engine);
108
+ (0, beautiful_logs_1.printProgressInfo)(logger, `Generated names for ${namedEntitiesCount} entity/entities`);
109
+ // Step 4: generate composite and crdt files (with updated asset paths and names)
110
+ (0, beautiful_logs_1.printProgressStep)(logger, 'Generating composite and crdt files', currentStep++, maxSteps);
111
+ await (0, composite_generator_1.generateCompositeFiles)(options.components, engine, compositeFilePath, crdtFilePath, entityNamesFilePath);
112
+ (0, beautiful_logs_1.printProgressInfo)(logger, `Generated main.composite ✅ (${compositeFilePath})`);
113
+ (0, beautiful_logs_1.printProgressInfo)(logger, `Generated main.crdt ✅ (${crdtFilePath})`);
114
+ (0, beautiful_logs_1.printProgressInfo)(logger, `Generated entity-names.ts ✅ (${entityNamesFilePath})`);
115
+ // Step 5: comment out original code
116
+ (0, beautiful_logs_1.printProgressStep)(logger, 'Commenting out original code', currentStep++, maxSteps);
117
+ const bundleEntrypoint = path_1.default.join(project.workingDirectory, project.scene.main);
118
+ const commentedFiles = await (0, code_commenter_1.commentSourceFiles)(options.components, sceneCodeEntrypoint, bundleEntrypoint);
119
+ const relativeEntrypoint = path_1.default.relative(project.workingDirectory, sceneCodeEntrypoint);
120
+ (0, beautiful_logs_1.printProgressInfo)(logger, `Commented out bundle entrypoint ${project.scene.main} and added stub main() function`);
121
+ (0, beautiful_logs_1.printProgressInfo)(logger, `Commented out scene code entrypoint ${relativeEntrypoint}`);
122
+ if (commentedFiles > 0) {
123
+ (0, beautiful_logs_1.printProgressInfo)(logger, `Commented out ${commentedFiles} additional source file(s)`);
124
+ }
125
+ (0, beautiful_logs_1.printSuccess)(logger, 'Scene successfully migrated to Creator Hub format!', `\nNext steps:
126
+ - Open your scene in the Creator Hub to edit visually
127
+ - Uncomment parts of the code in src/ for hybrid workflows
128
+ - Use "src/entity-names.ts" to reference entities by name in code`);
129
+ }
130
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/code-to-composite/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { IEngine } from '@dcl/ecs/dist-cjs';
2
+ import { CliComponents } from '../../components';
3
+ /**
4
+ * Generates Name components for entities that don't have them
5
+ *
6
+ * Automatically generates Name components for entities based on their other components.
7
+ * This makes entities easier to identify and work with in the Creator Hub.
8
+ */
9
+ export declare function generateEntityNames(components: Pick<CliComponents, 'logger'>, engine: IEngine): Promise<number>;