@dcl/sdk-commands 7.0.0-4217957637.commit-a393ef7
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/LICENSE +201 -0
- package/dist/commands/build/index.d.ts +20 -0
- package/dist/commands/build/index.js +58 -0
- package/dist/commands/export-static/index.d.ts +23 -0
- package/dist/commands/export-static/index.js +119 -0
- package/dist/commands/init/index.d.ts +18 -0
- package/dist/commands/init/index.js +52 -0
- package/dist/commands/init/repos.d.ts +9 -0
- package/dist/commands/init/repos.js +11 -0
- package/dist/commands/start/index.d.ts +30 -0
- package/dist/commands/start/index.js +217 -0
- package/dist/commands/start/server/endpoints.d.ts +4 -0
- package/dist/commands/start/server/endpoints.js +399 -0
- package/dist/commands/start/server/file-watch-notifier.d.ts +8 -0
- package/dist/commands/start/server/file-watch-notifier.js +44 -0
- package/dist/commands/start/server/realm.d.ts +7 -0
- package/dist/commands/start/server/realm.js +57 -0
- package/dist/commands/start/server/routes.d.ts +2 -0
- package/dist/commands/start/server/routes.js +32 -0
- package/dist/commands/start/server/ws.d.ts +11 -0
- package/dist/commands/start/server/ws.js +19 -0
- package/dist/commands/start/types.d.ts +18 -0
- package/dist/commands/start/types.js +2 -0
- package/dist/components/eth.d.ts +2 -0
- package/dist/components/eth.js +5 -0
- package/dist/components/fetch.d.ts +5 -0
- package/dist/components/fetch.js +33 -0
- package/dist/components/fs.d.ts +20 -0
- package/dist/components/fs.js +71 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/components/index.js +14 -0
- package/dist/components/log.d.ts +4 -0
- package/dist/components/log.js +47 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +67 -0
- package/dist/logic/args.d.ts +11 -0
- package/dist/logic/args.js +18 -0
- package/dist/logic/beautiful-logs.d.ts +5 -0
- package/dist/logic/beautiful-logs.js +27 -0
- package/dist/logic/catalyst-requests.d.ts +5 -0
- package/dist/logic/catalyst-requests.js +23 -0
- package/dist/logic/commands.d.ts +3 -0
- package/dist/logic/commands.js +23 -0
- package/dist/logic/coordinates.d.ts +37 -0
- package/dist/logic/coordinates.js +83 -0
- package/dist/logic/dcl-ignore.d.ts +8 -0
- package/dist/logic/dcl-ignore.js +48 -0
- package/dist/logic/error.d.ts +2 -0
- package/dist/logic/error.js +6 -0
- package/dist/logic/exec.d.ts +8 -0
- package/dist/logic/exec.js +26 -0
- package/dist/logic/fs.d.ts +24 -0
- package/dist/logic/fs.js +41 -0
- package/dist/logic/get-free-port.d.ts +1 -0
- package/dist/logic/get-free-port.js +20 -0
- package/dist/logic/project-files.d.ts +16 -0
- package/dist/logic/project-files.js +62 -0
- package/dist/logic/project-validations.d.ts +15 -0
- package/dist/logic/project-validations.js +56 -0
- package/dist/logic/realm.d.ts +2 -0
- package/dist/logic/realm.js +30 -0
- package/dist/logic/scene-validations.d.ts +13 -0
- package/dist/logic/scene-validations.js +64 -0
- package/package.json +50 -0
- package/src/commands/build/index.ts +68 -0
- package/src/commands/export-static/index.ts +142 -0
- package/src/commands/init/index.ts +67 -0
- package/src/commands/init/repos.ts +17 -0
- package/src/commands/start/index.ts +213 -0
- package/src/commands/start/server/endpoints.ts +473 -0
- package/src/commands/start/server/file-watch-notifier.ts +45 -0
- package/src/commands/start/server/realm.ts +63 -0
- package/src/commands/start/server/routes.ts +36 -0
- package/src/commands/start/server/ws.ts +24 -0
- package/src/commands/start/types.ts +26 -0
- package/src/components/eth.ts +3 -0
- package/src/components/fetch.ts +11 -0
- package/src/components/fs.ts +62 -0
- package/src/components/index.ts +18 -0
- package/src/components/log.ts +48 -0
- package/src/index.ts +90 -0
- package/src/logic/args.ts +19 -0
- package/src/logic/beautiful-logs.ts +26 -0
- package/src/logic/catalyst-requests.ts +31 -0
- package/src/logic/commands.ts +28 -0
- package/src/logic/coordinates.ts +95 -0
- package/src/logic/dcl-ignore.ts +49 -0
- package/src/logic/error.ts +1 -0
- package/src/logic/exec.ts +36 -0
- package/src/logic/fs.ts +41 -0
- package/src/logic/get-free-port.ts +15 -0
- package/src/logic/project-files.ts +76 -0
- package/src/logic/project-validations.ts +61 -0
- package/src/logic/realm.ts +28 -0
- package/src/logic/scene-validations.ts +73 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isEqual = exports.areConnected = exports.inBounds = exports.getObject = exports.parse = exports.getBounds = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Returns metaverse coordinates bounds.
|
|
6
|
+
* TODO: use functions from @dcl/schemas
|
|
7
|
+
*/
|
|
8
|
+
function getBounds() {
|
|
9
|
+
return {
|
|
10
|
+
minX: -150,
|
|
11
|
+
minY: -150,
|
|
12
|
+
maxX: 165,
|
|
13
|
+
maxY: 165
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
exports.getBounds = getBounds;
|
|
17
|
+
/**
|
|
18
|
+
* Parses a string-based set of coordinates.
|
|
19
|
+
* - All spaces are removed
|
|
20
|
+
* - Leading zeroes are removed
|
|
21
|
+
* - `-0` is converted to `0`
|
|
22
|
+
* @param coordinates An string containing coordinates in the `x,y; x,y; ...` format
|
|
23
|
+
*/
|
|
24
|
+
function parse(coordinates) {
|
|
25
|
+
return coordinates.split(';').map((coord) => {
|
|
26
|
+
const [x, y] = coord.split(',').map(($) => {
|
|
27
|
+
return parseInt($, 10)
|
|
28
|
+
.toString() // removes spaces :)
|
|
29
|
+
.replace('-0', '0')
|
|
30
|
+
.replace(/undefined|NaN/g, '0');
|
|
31
|
+
});
|
|
32
|
+
return `${x},${y}`;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
exports.parse = parse;
|
|
36
|
+
/**
|
|
37
|
+
* Converts a string-based set of coordinates to an object
|
|
38
|
+
* @param coords A string containing a set of coordinates
|
|
39
|
+
*/
|
|
40
|
+
function getObject(coords) {
|
|
41
|
+
const [x, y] = parse(coords)[0].split(',');
|
|
42
|
+
return { x: parseInt(x.toString(), 10), y: parseInt(y.toString(), 10) };
|
|
43
|
+
}
|
|
44
|
+
exports.getObject = getObject;
|
|
45
|
+
/**
|
|
46
|
+
* Returns true if the given coordinates are in metaverse bounds
|
|
47
|
+
*/
|
|
48
|
+
function inBounds(x, y) {
|
|
49
|
+
const { minX, minY, maxX, maxY } = getBounds();
|
|
50
|
+
return x >= minX && x <= maxX && y >= minY && y <= maxY;
|
|
51
|
+
}
|
|
52
|
+
exports.inBounds = inBounds;
|
|
53
|
+
/**
|
|
54
|
+
* Returns true if the given parcels array are connected
|
|
55
|
+
*/
|
|
56
|
+
function areConnected(parcels) {
|
|
57
|
+
if (parcels.length === 0) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const visited = visitParcel(parcels[0], parcels);
|
|
61
|
+
return visited.length === parcels.length;
|
|
62
|
+
}
|
|
63
|
+
exports.areConnected = areConnected;
|
|
64
|
+
function visitParcel(parcel, allParcels, visited = []) {
|
|
65
|
+
const isVisited = visited.some((visitedParcel) => isEqual(visitedParcel, parcel));
|
|
66
|
+
if (!isVisited) {
|
|
67
|
+
visited.push(parcel);
|
|
68
|
+
const neighbours = getNeighbours(parcel.x, parcel.y, allParcels);
|
|
69
|
+
neighbours.forEach((neighbours) => visitParcel(neighbours, allParcels, visited));
|
|
70
|
+
}
|
|
71
|
+
return visited;
|
|
72
|
+
}
|
|
73
|
+
function getIsNeighbourMatcher(x, y) {
|
|
74
|
+
return (coords) => (coords.x === x && (coords.y + 1 === y || coords.y - 1 === y)) ||
|
|
75
|
+
(coords.y === y && (coords.x + 1 === x || coords.x - 1 === x));
|
|
76
|
+
}
|
|
77
|
+
function getNeighbours(x, y, parcels) {
|
|
78
|
+
return parcels.filter(getIsNeighbourMatcher(x, y));
|
|
79
|
+
}
|
|
80
|
+
function isEqual(p1, p2) {
|
|
81
|
+
return p1.x === p2.x && p1.y === p2.y;
|
|
82
|
+
}
|
|
83
|
+
exports.isEqual = isEqual;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CliComponents } from '../components';
|
|
2
|
+
export declare const defaultDclIgnore: string[];
|
|
3
|
+
export declare function getDCLIgnoreFileContents(components: Pick<CliComponents, 'fs'>, dir: string): Promise<string | null>;
|
|
4
|
+
/**
|
|
5
|
+
* Returns the default .dclignore entries plus the ones provided by the user.
|
|
6
|
+
* In case of .dclignore not existing, it returns a pre-defined list.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getDCLIgnorePatterns(components: Pick<CliComponents, 'fs'>, dir: string): Promise<string[]>;
|
|
@@ -0,0 +1,48 @@
|
|
|
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.getDCLIgnorePatterns = exports.getDCLIgnoreFileContents = exports.defaultDclIgnore = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
exports.defaultDclIgnore = [
|
|
9
|
+
'.*',
|
|
10
|
+
'package.json',
|
|
11
|
+
'package-lock.json',
|
|
12
|
+
'yarn-lock.json',
|
|
13
|
+
'build.json',
|
|
14
|
+
'export',
|
|
15
|
+
'tsconfig.json',
|
|
16
|
+
'tslint.json',
|
|
17
|
+
'node_modules',
|
|
18
|
+
'**/*.ts',
|
|
19
|
+
'**/*.tsx',
|
|
20
|
+
'Dockerfile',
|
|
21
|
+
'dist',
|
|
22
|
+
'README.md',
|
|
23
|
+
'*.blend',
|
|
24
|
+
'*.fbx',
|
|
25
|
+
'*.zip',
|
|
26
|
+
'*.rar'
|
|
27
|
+
];
|
|
28
|
+
async function getDCLIgnoreFileContents(components, dir) {
|
|
29
|
+
try {
|
|
30
|
+
return components.fs.readFile(path_1.default.resolve(dir, '.dclignore'), 'utf8');
|
|
31
|
+
}
|
|
32
|
+
catch (e) { }
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
exports.getDCLIgnoreFileContents = getDCLIgnoreFileContents;
|
|
36
|
+
/**
|
|
37
|
+
* Returns the default .dclignore entries plus the ones provided by the user.
|
|
38
|
+
* In case of .dclignore not existing, it returns a pre-defined list.
|
|
39
|
+
*/
|
|
40
|
+
async function getDCLIgnorePatterns(components, dir) {
|
|
41
|
+
const ignoredContent = await getDCLIgnoreFileContents(components, dir);
|
|
42
|
+
const ignored = (ignoredContent?.split('\n') || exports.defaultDclIgnore).filter(Boolean);
|
|
43
|
+
ignored.push(...exports.defaultDclIgnore);
|
|
44
|
+
// by default many files need to be ignored
|
|
45
|
+
ignored.push('.*', 'node_modules', '**/*.ts', '**/*.tsx');
|
|
46
|
+
return Array.from(new Set(ignored));
|
|
47
|
+
}
|
|
48
|
+
exports.getDCLIgnorePatterns = getDCLIgnorePatterns;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.exec = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
function exec(cwd, command, args, { env, silent } = {}) {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
const child = (0, child_process_1.spawn)(command, args, {
|
|
8
|
+
shell: true,
|
|
9
|
+
cwd,
|
|
10
|
+
env: { ...process.env, NODE_ENV: '', ...env }
|
|
11
|
+
});
|
|
12
|
+
if (!silent) {
|
|
13
|
+
child.stdout.pipe(process.stdout);
|
|
14
|
+
child.stderr.pipe(process.stderr);
|
|
15
|
+
}
|
|
16
|
+
child.on('close', (code) => {
|
|
17
|
+
if (code !== 0) {
|
|
18
|
+
const _ = `${command} ${args.join(' ')}`;
|
|
19
|
+
reject(new Error(`Command "${_}" exited with code ${code}. Please try running the command manually`));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
resolve(undefined);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
exports.exec = exec;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { IFileSystemComponent } from '../components/fs';
|
|
2
|
+
import { IFetchComponent } from '../components/fetch';
|
|
3
|
+
/**
|
|
4
|
+
* Check's if directory is empty
|
|
5
|
+
* @param dir Directory to check for emptyness
|
|
6
|
+
*/
|
|
7
|
+
export declare function isDirectoryEmpty(components: {
|
|
8
|
+
fs: IFileSystemComponent;
|
|
9
|
+
}, dir: string): Promise<boolean>;
|
|
10
|
+
/**
|
|
11
|
+
* Download a file
|
|
12
|
+
* @param url URL of the file
|
|
13
|
+
* @param dest Path to where to save the file
|
|
14
|
+
*/
|
|
15
|
+
export declare function download(components: {
|
|
16
|
+
fs: IFileSystemComponent;
|
|
17
|
+
fetch: IFetchComponent;
|
|
18
|
+
}, url: string, dest: string): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Extracts a .zip file
|
|
21
|
+
* @param url Path of the zip file
|
|
22
|
+
* @param dest Path to where to extract the zip file
|
|
23
|
+
*/
|
|
24
|
+
export declare function extract(path: string, dest: string): Promise<string>;
|
package/dist/logic/fs.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
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.extract = exports.download = exports.isDirectoryEmpty = void 0;
|
|
7
|
+
const extract_zip_1 = __importDefault(require("extract-zip"));
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
/**
|
|
10
|
+
* Check's if directory is empty
|
|
11
|
+
* @param dir Directory to check for emptyness
|
|
12
|
+
*/
|
|
13
|
+
async function isDirectoryEmpty(components, dir) {
|
|
14
|
+
const files = await components.fs.readdir(dir);
|
|
15
|
+
return !files.length;
|
|
16
|
+
}
|
|
17
|
+
exports.isDirectoryEmpty = isDirectoryEmpty;
|
|
18
|
+
/**
|
|
19
|
+
* Download a file
|
|
20
|
+
* @param url URL of the file
|
|
21
|
+
* @param dest Path to where to save the file
|
|
22
|
+
*/
|
|
23
|
+
async function download(components, url, dest) {
|
|
24
|
+
// we should remove this package and use the native "fetch" when Node
|
|
25
|
+
// releases it as stable: https://nodejs.org/docs/latest-v18.x/api/globals.html#fetch
|
|
26
|
+
const data = await (await components.fetch.fetch(url)).arrayBuffer();
|
|
27
|
+
await components.fs.writeFile(dest, Buffer.from(data));
|
|
28
|
+
return dest;
|
|
29
|
+
}
|
|
30
|
+
exports.download = download;
|
|
31
|
+
/**
|
|
32
|
+
* Extracts a .zip file
|
|
33
|
+
* @param url Path of the zip file
|
|
34
|
+
* @param dest Path to where to extract the zip file
|
|
35
|
+
*/
|
|
36
|
+
async function extract(path, dest) {
|
|
37
|
+
const destPath = (0, path_1.resolve)(dest);
|
|
38
|
+
await (0, extract_zip_1.default)((0, path_1.resolve)(path), { dir: destPath });
|
|
39
|
+
return destPath;
|
|
40
|
+
}
|
|
41
|
+
exports.extract = extract;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function previewPort(): Promise<number>;
|
|
@@ -0,0 +1,20 @@
|
|
|
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.previewPort = void 0;
|
|
7
|
+
const portfinder_1 = __importDefault(require("portfinder"));
|
|
8
|
+
async function previewPort() {
|
|
9
|
+
let resolvedPort = 0;
|
|
10
|
+
if (!resolvedPort) {
|
|
11
|
+
try {
|
|
12
|
+
resolvedPort = await portfinder_1.default.getPortPromise();
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
resolvedPort = 2044;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return resolvedPort;
|
|
19
|
+
}
|
|
20
|
+
exports.previewPort = previewPort;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ContentMapping } from '@dcl/schemas/dist/misc/content-mapping';
|
|
2
|
+
import { CliComponents } from '../components';
|
|
3
|
+
/**
|
|
4
|
+
* Returns an array of the publishable files for a given folder.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getPublishableFiles(components: Pick<CliComponents, 'fs'>, projectRoot: string): Promise<Array<string>>;
|
|
7
|
+
/**
|
|
8
|
+
* This function converts paths to decentraland-compatible paths.
|
|
9
|
+
* - From windows separators to unix separators.
|
|
10
|
+
* - All to lowercase
|
|
11
|
+
*/
|
|
12
|
+
export declare function normalizeDecentralandFilename(filename: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Returns the content mappings for a specific project folder.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getProjectContentMappings(components: Pick<CliComponents, 'fs'>, projectRoot: string, hashingFunction: (filePath: string) => Promise<string>): Promise<ContentMapping[]>;
|
|
@@ -0,0 +1,62 @@
|
|
|
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.getProjectContentMappings = exports.normalizeDecentralandFilename = exports.getPublishableFiles = void 0;
|
|
7
|
+
const dcl_ignore_1 = require("./dcl-ignore");
|
|
8
|
+
const glob_1 = require("glob");
|
|
9
|
+
const ignore_1 = __importDefault(require("ignore"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const error_1 = require("./error");
|
|
12
|
+
/**
|
|
13
|
+
* Returns an array of the publishable files for a given folder.
|
|
14
|
+
*/
|
|
15
|
+
async function getPublishableFiles(components, projectRoot) {
|
|
16
|
+
const ignorePatterns = await (0, dcl_ignore_1.getDCLIgnorePatterns)(components, projectRoot);
|
|
17
|
+
const ig = (0, ignore_1.default)().add(ignorePatterns);
|
|
18
|
+
const allFiles = (0, glob_1.sync)('**/*', {
|
|
19
|
+
cwd: projectRoot,
|
|
20
|
+
absolute: false,
|
|
21
|
+
dot: false,
|
|
22
|
+
ignore: ignorePatterns,
|
|
23
|
+
nodir: true
|
|
24
|
+
});
|
|
25
|
+
return ig.filter(allFiles);
|
|
26
|
+
}
|
|
27
|
+
exports.getPublishableFiles = getPublishableFiles;
|
|
28
|
+
/**
|
|
29
|
+
* This function converts paths to decentraland-compatible paths.
|
|
30
|
+
* - From windows separators to unix separators.
|
|
31
|
+
* - All to lowercase
|
|
32
|
+
*/
|
|
33
|
+
function normalizeDecentralandFilename(filename) {
|
|
34
|
+
return filename.replace(/(\\)/g, '/').toLowerCase();
|
|
35
|
+
}
|
|
36
|
+
exports.normalizeDecentralandFilename = normalizeDecentralandFilename;
|
|
37
|
+
/**
|
|
38
|
+
* Returns the content mappings for a specific project folder.
|
|
39
|
+
*/
|
|
40
|
+
async function getProjectContentMappings(components, projectRoot, hashingFunction) {
|
|
41
|
+
const projectFiles = await getPublishableFiles(components, projectRoot);
|
|
42
|
+
const ret = [];
|
|
43
|
+
const usedFilenames = new Set();
|
|
44
|
+
for (const file of projectFiles) {
|
|
45
|
+
const absolutePath = path_1.default.resolve(projectRoot, file);
|
|
46
|
+
/* istanbul ignore if */
|
|
47
|
+
if (!(await components.fs.fileExists(absolutePath)))
|
|
48
|
+
continue;
|
|
49
|
+
// remove heading '/'
|
|
50
|
+
const normalizedFile = normalizeDecentralandFilename(file).replace(/^\/+/, '');
|
|
51
|
+
/* istanbul ignore if */
|
|
52
|
+
if (usedFilenames.has(normalizedFile)) {
|
|
53
|
+
throw new error_1.CliError(`DuplicatedFilenameError: the file ${file} exists with a different casing. Please manually remove one occurrence`);
|
|
54
|
+
}
|
|
55
|
+
ret.push({
|
|
56
|
+
file: normalizedFile,
|
|
57
|
+
hash: await hashingFunction(absolutePath)
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return ret;
|
|
61
|
+
}
|
|
62
|
+
exports.getProjectContentMappings = getProjectContentMappings;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Scene } from '@dcl/schemas';
|
|
2
|
+
import { CliComponents } from '../components';
|
|
3
|
+
/**
|
|
4
|
+
* Asserts that the projectRoot is a valid project
|
|
5
|
+
*/
|
|
6
|
+
export declare function assertValidProjectFolder(components: Pick<CliComponents, 'fs' | 'logger'>, projectRoot: string): Promise<{
|
|
7
|
+
scene: Scene;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function needsDependencies(components: Pick<CliComponents, 'fs'>, dir: string): Promise<boolean>;
|
|
10
|
+
export declare const npm: string;
|
|
11
|
+
export declare function installDependencies(components: Pick<CliComponents, 'logger'>, directory: string): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Run NPM commands
|
|
14
|
+
*/
|
|
15
|
+
export declare function npmRun(cwd: string, command: string, ...args: string[]): Promise<void>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.npmRun = exports.installDependencies = exports.npm = exports.needsDependencies = exports.assertValidProjectFolder = void 0;
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const error_1 = require("./error");
|
|
6
|
+
const exec_1 = require("./exec");
|
|
7
|
+
const scene_validations_1 = require("./scene-validations");
|
|
8
|
+
/**
|
|
9
|
+
* Asserts that the projectRoot is a valid project
|
|
10
|
+
*/
|
|
11
|
+
async function assertValidProjectFolder(components, projectRoot) {
|
|
12
|
+
// no validations for now, only check that it exists
|
|
13
|
+
if (!(await components.fs.fileExists((0, path_1.resolve)(projectRoot, 'package.json'))))
|
|
14
|
+
throw new error_1.CliError(`The project root doesn't have a package.json file`);
|
|
15
|
+
// now we will iterate over different file to evaluate the project kind
|
|
16
|
+
switch (true) {
|
|
17
|
+
// case wearable
|
|
18
|
+
case await components.fs.fileExists((0, path_1.resolve)(projectRoot, 'scene.json')): {
|
|
19
|
+
return { scene: await (0, scene_validations_1.validateSceneJson)(components, projectRoot) };
|
|
20
|
+
}
|
|
21
|
+
default: {
|
|
22
|
+
throw new error_1.CliError(`UnknownProjectKind: the kind of project of the folder ${projectRoot} cannot be identified`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.assertValidProjectFolder = assertValidProjectFolder;
|
|
27
|
+
/*
|
|
28
|
+
* Returns true if the project contains an empty node_modules folder
|
|
29
|
+
*/
|
|
30
|
+
async function needsDependencies(components, dir) {
|
|
31
|
+
const nodeModulesPath = (0, path_1.resolve)(dir, 'node_modules');
|
|
32
|
+
const hasNodeModulesFolder = await components.fs.directoryExists(nodeModulesPath);
|
|
33
|
+
const isNodeModulesEmpty = hasNodeModulesFolder && (await components.fs.readdir(nodeModulesPath)).length === 0;
|
|
34
|
+
return !hasNodeModulesFolder || isNodeModulesEmpty;
|
|
35
|
+
}
|
|
36
|
+
exports.needsDependencies = needsDependencies;
|
|
37
|
+
/* istanbul ignore next */
|
|
38
|
+
exports.npm = /^win/.test(process.platform) ? 'npm.cmd' : 'npm';
|
|
39
|
+
/*
|
|
40
|
+
* Runs "npm install" for desired project
|
|
41
|
+
*/
|
|
42
|
+
async function installDependencies(components, directory) {
|
|
43
|
+
components.logger.info('Installing dependencies...');
|
|
44
|
+
// TODO: test in windows
|
|
45
|
+
await (0, exec_1.exec)(directory, exports.npm, ['install']);
|
|
46
|
+
components.logger.log('Installing dependencies... ✅');
|
|
47
|
+
}
|
|
48
|
+
exports.installDependencies = installDependencies;
|
|
49
|
+
/**
|
|
50
|
+
* Run NPM commands
|
|
51
|
+
*/
|
|
52
|
+
async function npmRun(cwd, command, ...args) {
|
|
53
|
+
// TODO: test in windows
|
|
54
|
+
await (0, exec_1.exec)(cwd, exports.npm, ['run', command, '--silent', '--', ...args], { env: process.env });
|
|
55
|
+
}
|
|
56
|
+
exports.npmRun = npmRun;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createStaticRealm = void 0;
|
|
4
|
+
function createStaticRealm() {
|
|
5
|
+
return {
|
|
6
|
+
acceptingUsers: true,
|
|
7
|
+
bff: { healthy: false, publicUrl: `https://peer.decentraland.org/bff` },
|
|
8
|
+
comms: {
|
|
9
|
+
healthy: true,
|
|
10
|
+
protocol: 'v3',
|
|
11
|
+
fixedAdapter: `offline:offline`
|
|
12
|
+
},
|
|
13
|
+
configurations: {
|
|
14
|
+
networkId: 0,
|
|
15
|
+
globalScenesUrn: [],
|
|
16
|
+
scenesUrn: [],
|
|
17
|
+
realmName: 'SdkStaticExport'
|
|
18
|
+
},
|
|
19
|
+
content: {
|
|
20
|
+
healthy: true,
|
|
21
|
+
publicUrl: `https://peer.decentraland.org/content`
|
|
22
|
+
},
|
|
23
|
+
lambdas: {
|
|
24
|
+
healthy: true,
|
|
25
|
+
publicUrl: `https://peer.decentraland.org/lambdas`
|
|
26
|
+
},
|
|
27
|
+
healthy: true
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
exports.createStaticRealm = createStaticRealm;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Scene } from '@dcl/schemas';
|
|
2
|
+
import { CliComponents } from '../components';
|
|
3
|
+
export declare const SCENE_FILE = "scene.json";
|
|
4
|
+
/**
|
|
5
|
+
* Composes the path to the `scene.json` file based on the provided path.
|
|
6
|
+
* @param projectRoot The path to the directory containing the scene file.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getSceneFilePath(projectRoot: string): string;
|
|
9
|
+
export declare function assertValidScene(scene: Scene): Scene;
|
|
10
|
+
/**
|
|
11
|
+
* Fails the execution if one of the parcel data is invalid
|
|
12
|
+
*/
|
|
13
|
+
export declare function validateSceneJson(components: Pick<CliComponents, 'fs' | 'logger'>, projectRoot: string): Promise<Scene>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateSceneJson = exports.assertValidScene = exports.getSceneFilePath = exports.SCENE_FILE = void 0;
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const schemas_1 = require("@dcl/schemas");
|
|
6
|
+
const error_1 = require("./error");
|
|
7
|
+
const coordinates_1 = require("./coordinates");
|
|
8
|
+
exports.SCENE_FILE = 'scene.json';
|
|
9
|
+
/**
|
|
10
|
+
* Composes the path to the `scene.json` file based on the provided path.
|
|
11
|
+
* @param projectRoot The path to the directory containing the scene file.
|
|
12
|
+
*/
|
|
13
|
+
function getSceneFilePath(projectRoot) {
|
|
14
|
+
return (0, path_1.resolve)(projectRoot, exports.SCENE_FILE);
|
|
15
|
+
}
|
|
16
|
+
exports.getSceneFilePath = getSceneFilePath;
|
|
17
|
+
function assertValidScene(scene) {
|
|
18
|
+
if (!schemas_1.Scene.validate(scene)) {
|
|
19
|
+
const errors = [];
|
|
20
|
+
if (schemas_1.Scene.validate.errors) {
|
|
21
|
+
for (const error of schemas_1.Scene.validate.errors) {
|
|
22
|
+
errors.push(`Error validating scene.json: ${error.message}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
throw new error_1.CliError('Invalid scene.json file:\n' + errors.join('\n'));
|
|
26
|
+
}
|
|
27
|
+
const parcelSet = new Set(scene.scene?.parcels);
|
|
28
|
+
if (parcelSet.size < scene.scene?.parcels?.length) {
|
|
29
|
+
throw new error_1.CliError(`There are duplicated parcels at scene.json.`);
|
|
30
|
+
}
|
|
31
|
+
if (!parcelSet.has(scene.scene?.base)) {
|
|
32
|
+
throw new error_1.CliError(`Your base parcel ${scene.scene?.base} should be included on parcels attribute at scene.json`);
|
|
33
|
+
}
|
|
34
|
+
const objParcels = scene.scene?.parcels?.map(coordinates_1.getObject);
|
|
35
|
+
objParcels.forEach(({ x, y }) => {
|
|
36
|
+
if ((0, coordinates_1.inBounds)(x, y)) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const { minX, maxX } = (0, coordinates_1.getBounds)();
|
|
40
|
+
throw new error_1.CliError(`Coordinates ${x},${y} are outside of allowed limits (from ${minX} to ${maxX})`);
|
|
41
|
+
});
|
|
42
|
+
if (!(0, coordinates_1.areConnected)(objParcels)) {
|
|
43
|
+
throw new error_1.CliError('Parcels described on scene.json are not connected. They should be one next to each other');
|
|
44
|
+
}
|
|
45
|
+
if (!scene.main?.endsWith('.js')) {
|
|
46
|
+
throw new error_1.CliError(`Main scene format file (${scene.main}) is not a supported format`);
|
|
47
|
+
}
|
|
48
|
+
return scene;
|
|
49
|
+
}
|
|
50
|
+
exports.assertValidScene = assertValidScene;
|
|
51
|
+
/**
|
|
52
|
+
* Fails the execution if one of the parcel data is invalid
|
|
53
|
+
*/
|
|
54
|
+
async function validateSceneJson(components, projectRoot) {
|
|
55
|
+
try {
|
|
56
|
+
const sceneJsonRaw = await components.fs.readFile(getSceneFilePath(projectRoot), 'utf8');
|
|
57
|
+
const sceneJson = JSON.parse(sceneJsonRaw);
|
|
58
|
+
return assertValidScene(sceneJson);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
throw new error_1.CliError(`Error reading the scene.json file: ${err.message}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.validateSceneJson = validateSceneJson;
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dcl/sdk-commands",
|
|
3
|
+
"version": "7.0.0-4217957637.commit-a393ef7",
|
|
4
|
+
"description": "",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "tsc -p tsconfig.json",
|
|
7
|
+
"start": "tsc -p tsconfig.json --watch"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"sdk-commands": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [],
|
|
13
|
+
"tsdoc": {
|
|
14
|
+
"tsdocFlavor": "AEDoc"
|
|
15
|
+
},
|
|
16
|
+
"author": "Decentraland",
|
|
17
|
+
"license": "Apache-2.0",
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@dcl/dcl-rollup": "7.0.6-4217957637.commit-a393ef7",
|
|
20
|
+
"@dcl/hashing": "1.1.3",
|
|
21
|
+
"@dcl/mini-comms": "1.0.1-20230216163137.commit-a4c75be",
|
|
22
|
+
"@dcl/protocol": "1.0.0-4114477251.commit-ccb88d6",
|
|
23
|
+
"@dcl/schemas": "6.10.0",
|
|
24
|
+
"@well-known-components/env-config-provider": "^1.2.0",
|
|
25
|
+
"@well-known-components/http-server": "^2.0.0-20230216161243.commit-bfe3f0a",
|
|
26
|
+
"@well-known-components/logger": "^3.1.2",
|
|
27
|
+
"@well-known-components/metrics": "^2.0.1",
|
|
28
|
+
"arg": "5.0.2",
|
|
29
|
+
"chokidar": "^3.5.3",
|
|
30
|
+
"colorette": "^2.0.19",
|
|
31
|
+
"extract-zip": "2.0.1",
|
|
32
|
+
"ignore": "^5.2.4",
|
|
33
|
+
"node-fetch": "^2.6.8",
|
|
34
|
+
"open": "^8.4.0",
|
|
35
|
+
"portfinder": "^1.0.32",
|
|
36
|
+
"undici": "^5.19.1"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node-fetch": "^2.6.1",
|
|
40
|
+
"@types/ws": "^8.5.4"
|
|
41
|
+
},
|
|
42
|
+
"minCliVersion": "3.14.1",
|
|
43
|
+
"typedoc": {
|
|
44
|
+
"entryPoint": "./src/index.ts",
|
|
45
|
+
"readmeFile": "./README.md",
|
|
46
|
+
"displayName": "SDK",
|
|
47
|
+
"tsconfig": "./tsconfig.json"
|
|
48
|
+
},
|
|
49
|
+
"commit": "a393ef72d7ad52edf0a4c2f49ad2e22668c7a88d"
|
|
50
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
|
|
8
|
+
interface Options {
|
|
9
|
+
args: Omit<typeof args, '_'>
|
|
10
|
+
components: Pick<CliComponents, 'fs' | 'logger'>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const args = getArgs({
|
|
14
|
+
'--watch': Boolean,
|
|
15
|
+
'-w': '--watch',
|
|
16
|
+
'--production': Boolean,
|
|
17
|
+
'-p': '--production',
|
|
18
|
+
'--skip-install': Boolean,
|
|
19
|
+
'--dir': String
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
export function help() {
|
|
23
|
+
return `
|
|
24
|
+
Usage: 'sdk-commands build [options]'
|
|
25
|
+
Options:'
|
|
26
|
+
-h, --help Displays complete help
|
|
27
|
+
-w, --watch Watch for file changes and build on change
|
|
28
|
+
-p, --production Build without sourcemaps
|
|
29
|
+
--skip-install Skip installing dependencies
|
|
30
|
+
--dir Path to directory to build
|
|
31
|
+
|
|
32
|
+
Example:
|
|
33
|
+
- Build your scene:
|
|
34
|
+
'$ sdk-commands build'
|
|
35
|
+
`
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function main(options: Options) {
|
|
39
|
+
const projectRoot = resolve(process.cwd(), options.args['--dir'] || '.')
|
|
40
|
+
|
|
41
|
+
await assertValidProjectFolder(options.components, projectRoot)
|
|
42
|
+
|
|
43
|
+
const shouldInstallDeps = await needsDependencies(options.components, projectRoot)
|
|
44
|
+
|
|
45
|
+
if (shouldInstallDeps && !options.args['--skip-install']) {
|
|
46
|
+
await installDependencies(options.components, projectRoot)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const watch = !!options.args['--watch']
|
|
50
|
+
|
|
51
|
+
const watchingFuture = future<any>()
|
|
52
|
+
|
|
53
|
+
await compile({
|
|
54
|
+
project: projectRoot,
|
|
55
|
+
watch,
|
|
56
|
+
production: !!options.args['--production'],
|
|
57
|
+
watchingFuture
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
if (!watch) {
|
|
61
|
+
watchingFuture.resolve(null)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
await watchingFuture
|
|
65
|
+
|
|
66
|
+
// track stuff...
|
|
67
|
+
// https://github.com/decentraland/cli/blob/main/src/commands/build.ts
|
|
68
|
+
}
|