@dcl/sdk-commands 7.0.0-4293371227.commit-54082c6 → 7.0.0-4295573637.commit-6d503ad
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.
- package/dist/commands/build/index.js +1 -1
- package/dist/commands/deploy/index.d.ts +31 -0
- package/dist/commands/deploy/index.js +131 -0
- package/dist/commands/deploy/linker-dapp/api.d.ts +24 -0
- package/dist/commands/deploy/linker-dapp/api.js +92 -0
- package/dist/commands/deploy/linker-dapp/catalyst-pointers.d.ts +20 -0
- package/dist/commands/deploy/linker-dapp/catalyst-pointers.js +45 -0
- package/dist/commands/deploy/linker-dapp/routes.d.ts +8 -0
- package/dist/commands/deploy/linker-dapp/routes.js +91 -0
- package/dist/commands/export-static/index.js +1 -1
- package/dist/commands/start/index.js +2 -3
- package/dist/components/analytics.js +5 -1
- package/dist/logic/account.d.ts +6 -0
- package/dist/logic/account.js +21 -0
- package/dist/logic/dcl-info.d.ts +26 -0
- package/dist/logic/dcl-info.js +90 -0
- package/dist/logic/get-free-port.d.ts +1 -1
- package/dist/logic/get-free-port.js +6 -6
- package/dist/logic/project-files.d.ts +0 -2
- package/dist/logic/project-files.js +2 -8
- package/dist/logic/project-validations.js +1 -1
- package/dist/logic/scene-validations.d.ts +18 -3
- package/dist/logic/scene-validations.js +40 -7
- package/package.json +8 -3
- package/src/commands/build/index.ts +0 -77
- package/src/commands/export-static/index.ts +0 -150
- package/src/commands/init/index.ts +0 -68
- package/src/commands/init/repos.ts +0 -17
- package/src/commands/start/index.ts +0 -221
- package/src/commands/start/server/endpoints.ts +0 -471
- package/src/commands/start/server/file-watch-notifier.ts +0 -45
- package/src/commands/start/server/realm.ts +0 -63
- package/src/commands/start/server/routes.ts +0 -36
- package/src/commands/start/server/ws.ts +0 -24
- package/src/commands/start/types.ts +0 -26
- package/src/components/analytics.ts +0 -92
- package/src/components/dcl-info-config.ts +0 -63
- package/src/components/eth.ts +0 -3
- package/src/components/fetch.ts +0 -11
- package/src/components/fs.ts +0 -62
- package/src/components/index.ts +0 -26
- package/src/components/log.ts +0 -48
- package/src/index.ts +0 -90
- package/src/logic/args.ts +0 -19
- package/src/logic/beautiful-logs.ts +0 -26
- package/src/logic/catalyst-requests.ts +0 -31
- package/src/logic/commands.ts +0 -28
- package/src/logic/config.ts +0 -45
- package/src/logic/coordinates.ts +0 -95
- package/src/logic/dcl-ignore.ts +0 -50
- package/src/logic/error.ts +0 -1
- package/src/logic/exec.ts +0 -36
- package/src/logic/fs.ts +0 -76
- package/src/logic/get-free-port.ts +0 -15
- package/src/logic/project-files.ts +0 -92
- package/src/logic/project-validations.ts +0 -61
- package/src/logic/realm.ts +0 -28
- package/src/logic/scene-validations.ts +0 -81
- package/tsconfig.json +0 -28
|
@@ -3,18 +3,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.getPort = void 0;
|
|
7
7
|
const portfinder_1 = __importDefault(require("portfinder"));
|
|
8
|
-
async function
|
|
9
|
-
let resolvedPort = 0;
|
|
8
|
+
async function getPort(port = 0, failoverPort = 2044) {
|
|
9
|
+
let resolvedPort = port && Number.isInteger(port) ? port : 0;
|
|
10
10
|
if (!resolvedPort) {
|
|
11
11
|
try {
|
|
12
|
-
resolvedPort = await portfinder_1.default.getPortPromise();
|
|
12
|
+
resolvedPort = await portfinder_1.default.getPortPromise({ port: resolvedPort });
|
|
13
13
|
}
|
|
14
14
|
catch (e) {
|
|
15
|
-
resolvedPort =
|
|
15
|
+
resolvedPort = failoverPort;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
return resolvedPort;
|
|
19
19
|
}
|
|
20
|
-
exports.
|
|
20
|
+
exports.getPort = getPort;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ContentMapping } from '@dcl/schemas/dist/misc/content-mapping';
|
|
2
2
|
import { CliComponents } from '../components';
|
|
3
|
-
import { Scene } from '@dcl/schemas';
|
|
4
3
|
/**
|
|
5
4
|
* Returns an array of the publishable files for a given folder.
|
|
6
5
|
*
|
|
@@ -17,5 +16,4 @@ export declare function normalizeDecentralandFilename(filename: string): string;
|
|
|
17
16
|
* Returns the content mappings for a specific project folder.
|
|
18
17
|
*/
|
|
19
18
|
export declare function getProjectContentMappings(components: Pick<CliComponents, 'fs'>, projectRoot: string, hashingFunction: (filePath: string) => Promise<string>): Promise<ContentMapping[]>;
|
|
20
|
-
export declare function getSceneJson(components: Pick<CliComponents, 'fs'>, projectRoot: string): Promise<Scene>;
|
|
21
19
|
export declare const b64HashingFunction: (str: string) => Promise<string>;
|
|
@@ -3,13 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.b64HashingFunction = exports.
|
|
6
|
+
exports.b64HashingFunction = exports.getProjectContentMappings = exports.normalizeDecentralandFilename = exports.getPublishableFiles = void 0;
|
|
7
7
|
const dcl_ignore_1 = require("./dcl-ignore");
|
|
8
8
|
const glob_1 = require("glob");
|
|
9
9
|
const ignore_1 = __importDefault(require("ignore"));
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
11
|
const error_1 = require("./error");
|
|
12
|
-
const scene_validations_1 = require("./scene-validations");
|
|
13
12
|
/**
|
|
14
13
|
* Returns an array of the publishable files for a given folder.
|
|
15
14
|
*
|
|
@@ -60,6 +59,7 @@ hashingFunction) {
|
|
|
60
59
|
if (usedFilenames.has(normalizedFile)) {
|
|
61
60
|
throw new error_1.CliError(`DuplicatedFilenameError: the file ${file} exists with a different casing. Please manually remove one occurrence`);
|
|
62
61
|
}
|
|
62
|
+
usedFilenames.add(normalizedFile);
|
|
63
63
|
ret.push({
|
|
64
64
|
file: normalizedFile,
|
|
65
65
|
hash: await hashingFunction(absolutePath)
|
|
@@ -68,11 +68,5 @@ hashingFunction) {
|
|
|
68
68
|
return ret;
|
|
69
69
|
}
|
|
70
70
|
exports.getProjectContentMappings = getProjectContentMappings;
|
|
71
|
-
async function getSceneJson(components, projectRoot) {
|
|
72
|
-
const sceneJsonContent = await components.fs.readFile((0, scene_validations_1.getSceneFilePath)(projectRoot), 'utf8');
|
|
73
|
-
const sceneJson = JSON.parse(sceneJsonContent);
|
|
74
|
-
return sceneJson;
|
|
75
|
-
}
|
|
76
|
-
exports.getSceneJson = getSceneJson;
|
|
77
71
|
const b64HashingFunction = async (str) => 'b64-' + Buffer.from(str).toString('base64');
|
|
78
72
|
exports.b64HashingFunction = b64HashingFunction;
|
|
@@ -16,7 +16,7 @@ async function assertValidProjectFolder(components, projectRoot) {
|
|
|
16
16
|
switch (true) {
|
|
17
17
|
// case wearable
|
|
18
18
|
case await components.fs.fileExists((0, path_1.resolve)(projectRoot, 'scene.json')): {
|
|
19
|
-
return { scene: await (0, scene_validations_1.
|
|
19
|
+
return { scene: await (0, scene_validations_1.getValidSceneJson)(components, projectRoot) };
|
|
20
20
|
}
|
|
21
21
|
default: {
|
|
22
22
|
throw new error_1.CliError(`UnknownProjectKind: the kind of project of the folder ${projectRoot} cannot be identified`);
|
|
@@ -1,17 +1,32 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { Scene } from '@dcl/schemas';
|
|
2
3
|
import { CliComponents } from '../components';
|
|
4
|
+
export interface IFile {
|
|
5
|
+
path: string;
|
|
6
|
+
content: Buffer;
|
|
7
|
+
size: number;
|
|
8
|
+
}
|
|
3
9
|
export declare const SCENE_FILE = "scene.json";
|
|
10
|
+
export declare const MAX_FILE_SIZE_BYTES: number;
|
|
4
11
|
/**
|
|
5
12
|
* Composes the path to the `scene.json` file based on the provided path.
|
|
6
13
|
* @param projectRoot The path to the directory containing the scene file.
|
|
7
14
|
*/
|
|
8
15
|
export declare function getSceneFilePath(projectRoot: string): string;
|
|
9
|
-
export declare function assertValidScene(scene: Scene):
|
|
16
|
+
export declare function assertValidScene(scene: Scene): void;
|
|
10
17
|
/**
|
|
11
|
-
*
|
|
18
|
+
* Get valid Scene JSON
|
|
12
19
|
*/
|
|
13
|
-
export declare function
|
|
20
|
+
export declare function getValidSceneJson(components: Pick<CliComponents, 'fs' | 'logger'>, projectRoot: string): Promise<Scene>;
|
|
14
21
|
export declare function getBaseCoords(scene: Scene): {
|
|
15
22
|
x: number;
|
|
16
23
|
y: number;
|
|
17
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Returns a promise of an array of objects containing the path and the content for all the files in the project.
|
|
27
|
+
* All the paths added to the `.dclignore` file will be excluded from the results.
|
|
28
|
+
* Windows directory separators are replaced for POSIX separators.
|
|
29
|
+
* @param ignoreFile The contents of the .dclignore file
|
|
30
|
+
*/
|
|
31
|
+
export declare function getFiles(components: Pick<CliComponents, 'fs' | 'logger'>, dir: string): Promise<IFile[]>;
|
|
32
|
+
export declare function validateFilesSizes(files: IFile[]): void;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getBaseCoords = exports.
|
|
3
|
+
exports.validateFilesSizes = exports.getFiles = exports.getBaseCoords = exports.getValidSceneJson = exports.assertValidScene = exports.getSceneFilePath = exports.MAX_FILE_SIZE_BYTES = exports.SCENE_FILE = void 0;
|
|
4
4
|
const path_1 = require("path");
|
|
5
5
|
const schemas_1 = require("@dcl/schemas");
|
|
6
6
|
const error_1 = require("./error");
|
|
7
7
|
const coordinates_1 = require("./coordinates");
|
|
8
8
|
const project_files_1 = require("./project-files");
|
|
9
9
|
exports.SCENE_FILE = 'scene.json';
|
|
10
|
+
exports.MAX_FILE_SIZE_BYTES = 50 * 1e6; // 50mb
|
|
10
11
|
/**
|
|
11
12
|
* Composes the path to the `scene.json` file based on the provided path.
|
|
12
13
|
* @param projectRoot The path to the directory containing the scene file.
|
|
@@ -46,22 +47,23 @@ function assertValidScene(scene) {
|
|
|
46
47
|
if (!scene.main?.endsWith('.js')) {
|
|
47
48
|
throw new error_1.CliError(`Main scene format file (${scene.main}) is not a supported format`);
|
|
48
49
|
}
|
|
49
|
-
return scene;
|
|
50
50
|
}
|
|
51
51
|
exports.assertValidScene = assertValidScene;
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
53
|
+
* Get valid Scene JSON
|
|
54
54
|
*/
|
|
55
|
-
async function
|
|
55
|
+
async function getValidSceneJson(components, projectRoot) {
|
|
56
56
|
try {
|
|
57
|
-
const
|
|
58
|
-
|
|
57
|
+
const sceneJsonRaw = await components.fs.readFile(getSceneFilePath(projectRoot), 'utf8');
|
|
58
|
+
const sceneJson = JSON.parse(sceneJsonRaw);
|
|
59
|
+
assertValidScene(sceneJson);
|
|
60
|
+
return sceneJson;
|
|
59
61
|
}
|
|
60
62
|
catch (err) {
|
|
61
63
|
throw new error_1.CliError(`Error reading the scene.json file: ${err.message}`);
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
|
-
exports.
|
|
66
|
+
exports.getValidSceneJson = getValidSceneJson;
|
|
65
67
|
function getBaseCoords(scene) {
|
|
66
68
|
const [x, y] = scene.scene.base
|
|
67
69
|
.replace(/\ /g, '')
|
|
@@ -70,3 +72,34 @@ function getBaseCoords(scene) {
|
|
|
70
72
|
return { x, y };
|
|
71
73
|
}
|
|
72
74
|
exports.getBaseCoords = getBaseCoords;
|
|
75
|
+
/**
|
|
76
|
+
* Returns a promise of an array of objects containing the path and the content for all the files in the project.
|
|
77
|
+
* All the paths added to the `.dclignore` file will be excluded from the results.
|
|
78
|
+
* Windows directory separators are replaced for POSIX separators.
|
|
79
|
+
* @param ignoreFile The contents of the .dclignore file
|
|
80
|
+
*/
|
|
81
|
+
async function getFiles(components, dir) {
|
|
82
|
+
const files = await (0, project_files_1.getPublishableFiles)(components, dir);
|
|
83
|
+
const data = [];
|
|
84
|
+
for (let i = 0; i < files.length; i++) {
|
|
85
|
+
const file = files[i];
|
|
86
|
+
const filePath = (0, path_1.resolve)(dir, file);
|
|
87
|
+
const stat = await components.fs.stat(filePath);
|
|
88
|
+
const content = await components.fs.readFile(filePath);
|
|
89
|
+
data.push({
|
|
90
|
+
path: file.replace(/\\/g, '/'),
|
|
91
|
+
content: Buffer.from(content),
|
|
92
|
+
size: stat.size
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return data;
|
|
96
|
+
}
|
|
97
|
+
exports.getFiles = getFiles;
|
|
98
|
+
function validateFilesSizes(files) {
|
|
99
|
+
for (const { path, size } of files) {
|
|
100
|
+
if (size > exports.MAX_FILE_SIZE_BYTES) {
|
|
101
|
+
throw new error_1.CliError(`Maximum file size exceeded: '${path}' is larger than ${exports.MAX_FILE_SIZE_BYTES / 1e6}MB`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.validateFilesSizes = validateFilesSizes;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcl/sdk-commands",
|
|
3
|
-
"version": "7.0.0-
|
|
3
|
+
"version": "7.0.0-4295573637.commit-6d503ad",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "tsc -p tsconfig.json",
|
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
"author": "Decentraland",
|
|
17
17
|
"license": "Apache-2.0",
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@dcl/dcl-rollup": "7.0.6-
|
|
19
|
+
"@dcl/dcl-rollup": "7.0.6-4295573637.commit-6d503ad",
|
|
20
20
|
"@dcl/hashing": "1.1.3",
|
|
21
|
+
"@dcl/linker-dapp": "0.7.0",
|
|
21
22
|
"@dcl/mini-comms": "1.0.1-20230216163137.commit-a4c75be",
|
|
22
23
|
"@dcl/protocol": "1.0.0-4114477251.commit-ccb88d6",
|
|
23
24
|
"@dcl/schemas": "6.10.0",
|
|
@@ -29,6 +30,7 @@
|
|
|
29
30
|
"arg": "5.0.2",
|
|
30
31
|
"chokidar": "^3.5.3",
|
|
31
32
|
"colorette": "^2.0.19",
|
|
33
|
+
"dcl-catalyst-client": "^14.0.9",
|
|
32
34
|
"extract-zip": "2.0.1",
|
|
33
35
|
"ignore": "^5.2.4",
|
|
34
36
|
"node-fetch": "^2.6.8",
|
|
@@ -49,5 +51,8 @@
|
|
|
49
51
|
"displayName": "SDK",
|
|
50
52
|
"tsconfig": "./tsconfig.json"
|
|
51
53
|
},
|
|
52
|
-
"
|
|
54
|
+
"files": [
|
|
55
|
+
"dist"
|
|
56
|
+
],
|
|
57
|
+
"commit": "6d503ad455f1a93eca45772ca3ba698f7ad6e089"
|
|
53
58
|
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'path'
|
|
2
|
-
import { CliComponents } from '../../components'
|
|
3
|
-
import { getArgs } from '../../logic/args'
|
|
4
|
-
import { compile } from '@dcl/dcl-rollup/compile'
|
|
5
|
-
import future from 'fp-future'
|
|
6
|
-
import { assertValidProjectFolder, installDependencies, needsDependencies } from '../../logic/project-validations'
|
|
7
|
-
import { getBaseCoords } from '../../logic/scene-validations'
|
|
8
|
-
import { b64HashingFunction, getSceneJson } from '../../logic/project-files'
|
|
9
|
-
|
|
10
|
-
interface Options {
|
|
11
|
-
args: Omit<typeof args, '_'>
|
|
12
|
-
components: Pick<CliComponents, 'fs' | 'logger' | 'dclInfoConfig' | 'analytics'>
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const args = getArgs({
|
|
16
|
-
'--watch': Boolean,
|
|
17
|
-
'-w': '--watch',
|
|
18
|
-
'--production': Boolean,
|
|
19
|
-
'-p': '--production',
|
|
20
|
-
'--skip-install': Boolean,
|
|
21
|
-
'--dir': String
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
export function help() {
|
|
25
|
-
return `
|
|
26
|
-
Usage: 'sdk-commands build [options]'
|
|
27
|
-
Options:'
|
|
28
|
-
-h, --help Displays complete help
|
|
29
|
-
-w, --watch Watch for file changes and build on change
|
|
30
|
-
-p, --production Build without sourcemaps
|
|
31
|
-
--skip-install Skip installing dependencies
|
|
32
|
-
--dir Path to directory to build
|
|
33
|
-
|
|
34
|
-
Example:
|
|
35
|
-
- Build your scene:
|
|
36
|
-
'$ sdk-commands build'
|
|
37
|
-
`
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export async function main(options: Options) {
|
|
41
|
-
const projectRoot = resolve(process.cwd(), options.args['--dir'] || '.')
|
|
42
|
-
await assertValidProjectFolder(options.components, projectRoot)
|
|
43
|
-
|
|
44
|
-
const shouldInstallDeps = await needsDependencies(options.components, projectRoot)
|
|
45
|
-
|
|
46
|
-
if (shouldInstallDeps && !options.args['--skip-install']) {
|
|
47
|
-
await installDependencies(options.components, projectRoot)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const watch = !!options.args['--watch']
|
|
51
|
-
|
|
52
|
-
const watchingFuture = future<any>()
|
|
53
|
-
|
|
54
|
-
await compile({
|
|
55
|
-
project: projectRoot,
|
|
56
|
-
watch,
|
|
57
|
-
production: !!options.args['--production'],
|
|
58
|
-
watchingFuture
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
if (!watch) {
|
|
62
|
-
watchingFuture.resolve(null)
|
|
63
|
-
}
|
|
64
|
-
const sceneJson = await getSceneJson(options.components, projectRoot)
|
|
65
|
-
const coords = getBaseCoords(sceneJson)
|
|
66
|
-
|
|
67
|
-
await options.components.analytics.track('Build scene', {
|
|
68
|
-
projectHash: await b64HashingFunction(projectRoot),
|
|
69
|
-
coords,
|
|
70
|
-
isWorkspace: false
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
await watchingFuture
|
|
74
|
-
|
|
75
|
-
// track stuff...
|
|
76
|
-
// https://github.com/decentraland/cli/blob/main/src/commands/build.ts
|
|
77
|
-
}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'path'
|
|
2
|
-
import { getArgs } from '../../logic/args'
|
|
3
|
-
import { hashV1 } from '@dcl/hashing'
|
|
4
|
-
import { CliComponents } from '../../components'
|
|
5
|
-
import { assertValidProjectFolder } from '../../logic/project-validations'
|
|
6
|
-
import { b64HashingFunction, getProjectContentMappings, getSceneJson } from '../../logic/project-files'
|
|
7
|
-
import { CliError } from '../../logic/error'
|
|
8
|
-
import { Entity, EntityType } from '@dcl/schemas'
|
|
9
|
-
import { colors } from '../../components/log'
|
|
10
|
-
import { printProgressInfo, printProgressStep, printSuccess } from '../../logic/beautiful-logs'
|
|
11
|
-
import { createStaticRealm } from '../../logic/realm'
|
|
12
|
-
import { getBaseCoords } from '../../logic/scene-validations'
|
|
13
|
-
|
|
14
|
-
interface Options {
|
|
15
|
-
args: typeof args
|
|
16
|
-
components: Pick<CliComponents, 'fetch' | 'fs' | 'logger' | 'dclInfoConfig' | 'analytics'>
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const args = getArgs({
|
|
20
|
-
'--dir': String,
|
|
21
|
-
'--destination': String,
|
|
22
|
-
'--timestamp': String,
|
|
23
|
-
'--realmName': String,
|
|
24
|
-
'--baseUrl': String
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
export async function help() {
|
|
28
|
-
return `
|
|
29
|
-
Usage:
|
|
30
|
-
sdk-commands export-static --dir <directory> --destination <directory>
|
|
31
|
-
|
|
32
|
-
Description:
|
|
33
|
-
|
|
34
|
-
Exports all the contents of the scene as if they were uploaded to a content server
|
|
35
|
-
|
|
36
|
-
Options:
|
|
37
|
-
|
|
38
|
-
--dir <directory> The project's root folder to export
|
|
39
|
-
--destination <directory> A path in which all the assets will be stored
|
|
40
|
-
--timestamp <timestamp> A date to use in the deployable entity. Defaults to now()
|
|
41
|
-
--realmName <name> Creates a /<name>/about endpoint to expose the current deployment as a realm. Requires --baseUrl
|
|
42
|
-
--baseUrl <baseUrl> It is the public URL in which the --destination directory will be avaiable
|
|
43
|
-
`
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export async function main(options: Options) {
|
|
47
|
-
const { fs, logger } = options.components
|
|
48
|
-
const projectRoot = resolve(process.cwd(), options.args['--dir'] || '.')
|
|
49
|
-
const destDirectory = resolve(process.cwd(), options.args['--destination'] || '.')
|
|
50
|
-
const willCreateRealm = !!args['--realmName']
|
|
51
|
-
let currentStep = 1
|
|
52
|
-
const maxSteps = 3 + (willCreateRealm ? 1 : 0)
|
|
53
|
-
|
|
54
|
-
if (willCreateRealm && !args['--baseUrl']) {
|
|
55
|
-
throw new CliError(`--baseUrl is mandatory when --realmName is provided`)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (willCreateRealm && !/^[a-z][a-z0-9-/]*$/i.test(args['--realmName']!)) {
|
|
59
|
-
throw new CliError(`--realmName has invalid characters`)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
printProgressStep(logger, 'Reading project files...', currentStep++, maxSteps)
|
|
63
|
-
|
|
64
|
-
await fs.mkdir(destDirectory, { recursive: true })
|
|
65
|
-
if (!(await fs.directoryExists(destDirectory))) {
|
|
66
|
-
throw new CliError(`The destination path ${destDirectory} is not a directory`)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const project = await assertValidProjectFolder(options.components, projectRoot)
|
|
70
|
-
const filesToExport = await getProjectContentMappings(options.components, projectRoot, async (file) => {
|
|
71
|
-
return await hashV1(fs.createReadStream(resolve(projectRoot, file)))
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
printProgressStep(logger, 'Copying files...', currentStep++, maxSteps)
|
|
75
|
-
|
|
76
|
-
for (const { file, hash } of filesToExport) {
|
|
77
|
-
const src = resolve(projectRoot, file)
|
|
78
|
-
const dst = resolve(destDirectory, hash)
|
|
79
|
-
|
|
80
|
-
if (src.startsWith(destDirectory)) continue
|
|
81
|
-
|
|
82
|
-
printProgressInfo(logger, `> ${hash} -> ${file}`)
|
|
83
|
-
|
|
84
|
-
if (!(await fs.fileExists(dst))) {
|
|
85
|
-
const content = await fs.readFile(src)
|
|
86
|
-
await fs.writeFile(dst, content)
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// entity with ID are the deployed ones, when we generate the entity the ID is not
|
|
91
|
-
// available because it is the result of hashing the following structure
|
|
92
|
-
const entity: Omit<Entity, 'id'> = {
|
|
93
|
-
content: filesToExport,
|
|
94
|
-
pointers: [],
|
|
95
|
-
timestamp: args['--timestamp'] ? new Date(args['--timestamp']).getTime() : Date.now(),
|
|
96
|
-
type: EntityType.SCENE,
|
|
97
|
-
// for now, the only valid export is for scenes
|
|
98
|
-
metadata: project.scene,
|
|
99
|
-
version: 'v3'
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
printProgressStep(logger, 'Generating files...', currentStep++, maxSteps)
|
|
103
|
-
|
|
104
|
-
// create the entity file and get the entityId
|
|
105
|
-
const entityRaw = Buffer.from(JSON.stringify(entity), 'utf8')
|
|
106
|
-
const entityId = await hashV1(entityRaw)
|
|
107
|
-
const dst = resolve(destDirectory, entityId)
|
|
108
|
-
await fs.writeFile(dst, entityRaw)
|
|
109
|
-
|
|
110
|
-
printProgressInfo(logger, `> ${entityId} -> [ENTITY FILE]`)
|
|
111
|
-
|
|
112
|
-
let urn = `urn:decentraland:entity:${entityId}`
|
|
113
|
-
|
|
114
|
-
if (args['--baseUrl']) {
|
|
115
|
-
urn += '?baseUrl=' + args['--baseUrl']
|
|
116
|
-
// baseUrl must end with /
|
|
117
|
-
if (!urn.endsWith('/')) urn += '/'
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (willCreateRealm) {
|
|
121
|
-
// prepare the realm object
|
|
122
|
-
printProgressStep(logger, 'Creating realm file...', currentStep++, maxSteps)
|
|
123
|
-
const realm = createStaticRealm()
|
|
124
|
-
const realmName = args['--realmName']!
|
|
125
|
-
|
|
126
|
-
realm.configurations!.scenesUrn = [urn]
|
|
127
|
-
realm.configurations!.realmName = realmName
|
|
128
|
-
|
|
129
|
-
// write the realm file
|
|
130
|
-
const realmDirectory = resolve(destDirectory, realmName)
|
|
131
|
-
await fs.mkdir(realmDirectory, { recursive: true })
|
|
132
|
-
if (!(await fs.directoryExists(realmDirectory))) {
|
|
133
|
-
throw new CliError(`The destination path ${realmDirectory} is not a directory`)
|
|
134
|
-
}
|
|
135
|
-
const dst = resolve(realmDirectory, 'about')
|
|
136
|
-
await fs.writeFile(dst, JSON.stringify(realm, null, 2))
|
|
137
|
-
printProgressInfo(logger, `> ${realmName}/about -> [REALM FILE]`)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
printSuccess(logger, `Export finished!`, `=> The entity URN is ${colors.bold(urn)}`)
|
|
141
|
-
const sceneJson = await getSceneJson(options.components, projectRoot)
|
|
142
|
-
const coords = getBaseCoords(sceneJson)
|
|
143
|
-
|
|
144
|
-
await options.components.analytics.track('Export static', {
|
|
145
|
-
projectHash: await b64HashingFunction(projectRoot),
|
|
146
|
-
coords
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
return { urn, entityId, destination: destDirectory }
|
|
150
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { join, resolve } from 'path'
|
|
2
|
-
|
|
3
|
-
import { getArgs } from '../../logic/args'
|
|
4
|
-
import { CliError } from '../../logic/error'
|
|
5
|
-
import { CliComponents } from '../../components'
|
|
6
|
-
import { isDirectoryEmpty, download, extract } from '../../logic/fs'
|
|
7
|
-
|
|
8
|
-
import { get as getRepo } from './repos'
|
|
9
|
-
import { installDependencies, needsDependencies } from '../../logic/project-validations'
|
|
10
|
-
|
|
11
|
-
interface Options {
|
|
12
|
-
args: typeof args
|
|
13
|
-
components: Pick<CliComponents, 'fetch' | 'fs' | 'logger' | 'dclInfoConfig' | 'analytics'>
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const args = getArgs({
|
|
17
|
-
'--yes': Boolean,
|
|
18
|
-
'-y': '--yes',
|
|
19
|
-
'--dir': String,
|
|
20
|
-
'--skip-install': Boolean
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
export async function help() {}
|
|
24
|
-
|
|
25
|
-
export async function main(options: Options) {
|
|
26
|
-
const dir = resolve(process.cwd(), options.args['--dir'] || '.')
|
|
27
|
-
const isEmpty = await isDirectoryEmpty(options.components, dir)
|
|
28
|
-
const yes = options.args['--yes']
|
|
29
|
-
|
|
30
|
-
if (!isEmpty && !yes) {
|
|
31
|
-
throw new CliError('The target directory specified is not empty. Run this command with --yes to override.')
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// download and extract template project
|
|
35
|
-
const scene = 'scene-template'
|
|
36
|
-
const { url, contentFolders } = getRepo(scene)
|
|
37
|
-
const zip = await download(options.components, url, join(dir, `${scene}.zip`))
|
|
38
|
-
await extract(zip, dir)
|
|
39
|
-
await options.components.fs.unlink(zip)
|
|
40
|
-
await moveFilesFromDirs(options.components, dir, contentFolders)
|
|
41
|
-
|
|
42
|
-
// npm install
|
|
43
|
-
const shouldInstallDeps = await needsDependencies(options.components, dir)
|
|
44
|
-
if (shouldInstallDeps && !options.args['--skip-install']) {
|
|
45
|
-
await installDependencies(options.components, dir)
|
|
46
|
-
}
|
|
47
|
-
await options.components.analytics.track('Scene created', { projectType: scene, url })
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const moveFilesFromDir = async (components: Pick<CliComponents, 'fs'>, dir: string, folder: string) => {
|
|
51
|
-
const files = await components.fs.readdir(folder)
|
|
52
|
-
await Promise.all(
|
|
53
|
-
files.map(($) => {
|
|
54
|
-
const filePath = resolve(folder, $)
|
|
55
|
-
return components.fs.rename(filePath, resolve(dir, $))
|
|
56
|
-
})
|
|
57
|
-
)
|
|
58
|
-
await components.fs.rmdir(folder)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const moveFilesFromDirs = async (components: Pick<CliComponents, 'fs'>, dir: string, folders: string[]) => {
|
|
62
|
-
await Promise.all(
|
|
63
|
-
folders.map(($) => {
|
|
64
|
-
const folderPath = resolve(dir, $)
|
|
65
|
-
return moveFilesFromDir(components, dir, folderPath)
|
|
66
|
-
})
|
|
67
|
-
)
|
|
68
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
type Scene = 'scene-template'
|
|
2
|
-
|
|
3
|
-
type Repos = {
|
|
4
|
-
[key in Scene]: {
|
|
5
|
-
url: string
|
|
6
|
-
contentFolders: string[]
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const REPOS: Repos = {
|
|
11
|
-
'scene-template': {
|
|
12
|
-
url: 'https://github.com/decentraland/sdk7-scene-template/archive/refs/heads/main.zip',
|
|
13
|
-
contentFolders: ['sdk7-scene-template-main']
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const get = (scene: Scene): Repos[Scene] => REPOS[scene]
|