@dcl/sdk-commands 7.0.0-4286109573.commit-baaf951 → 7.0.0-4294380152.commit-0d08b10
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.d.ts +1 -1
- package/dist/commands/build/index.js +9 -0
- package/dist/commands/export-static/index.d.ts +1 -1
- package/dist/commands/export-static/index.js +7 -0
- package/dist/commands/init/index.d.ts +1 -1
- package/dist/commands/init/index.js +1 -0
- package/dist/commands/start/index.d.ts +1 -1
- package/dist/commands/start/index.js +9 -1
- package/dist/commands/start/server/endpoints.js +2 -3
- package/dist/components/analytics.d.ts +38 -0
- package/dist/components/analytics.js +66 -0
- package/dist/components/dcl-info-config.d.ts +11 -0
- package/dist/components/dcl-info-config.js +75 -0
- package/dist/components/index.d.ts +5 -1
- package/dist/components/index.js +9 -3
- package/dist/index.js +2 -1
- package/dist/logic/config.d.ts +16 -0
- package/dist/logic/config.js +42 -0
- package/dist/logic/dcl-ignore.js +1 -0
- package/dist/logic/fs.d.ts +12 -0
- package/dist/logic/fs.js +29 -1
- package/dist/logic/project-files.d.ts +5 -0
- package/dist/logic/project-files.js +18 -2
- package/dist/logic/scene-validations.d.ts +4 -0
- package/dist/logic/scene-validations.js +11 -3
- package/package.json +10 -4
- package/src/commands/build/index.ts +0 -68
- package/src/commands/export-static/index.ts +0 -142
- package/src/commands/init/index.ts +0 -67
- package/src/commands/init/repos.ts +0 -17
- package/src/commands/start/index.ts +0 -213
- package/src/commands/start/server/endpoints.ts +0 -473
- 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/eth.ts +0 -3
- package/src/components/fetch.ts +0 -11
- package/src/components/fs.ts +0 -62
- package/src/components/index.ts +0 -18
- 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/coordinates.ts +0 -95
- package/src/logic/dcl-ignore.ts +0 -49
- package/src/logic/error.ts +0 -1
- package/src/logic/exec.ts +0 -36
- package/src/logic/fs.ts +0 -41
- package/src/logic/get-free-port.ts +0 -15
- package/src/logic/project-files.ts +0 -76
- package/src/logic/project-validations.ts +0 -61
- package/src/logic/realm.ts +0 -28
- package/src/logic/scene-validations.ts +0 -73
- package/tsconfig.json +0 -28
package/src/components/fs.ts
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs'
|
|
2
|
-
import * as fsPromises from 'fs/promises'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @public
|
|
6
|
-
*
|
|
7
|
-
* This may be moved to well-known-components in the future
|
|
8
|
-
*/
|
|
9
|
-
export type IFileSystemComponent = Pick<typeof fs, 'createReadStream'> &
|
|
10
|
-
Pick<typeof fs, 'createWriteStream'> &
|
|
11
|
-
Pick<
|
|
12
|
-
typeof fsPromises,
|
|
13
|
-
'access' | 'opendir' | 'stat' | 'unlink' | 'mkdir' | 'readFile' | 'writeFile' | 'rename' | 'rmdir'
|
|
14
|
-
> & {
|
|
15
|
-
constants: Pick<typeof fs.constants, 'F_OK' | 'R_OK'>
|
|
16
|
-
} & {
|
|
17
|
-
fileExists(path: string): Promise<boolean>
|
|
18
|
-
directoryExists(path: string): Promise<boolean>
|
|
19
|
-
readdir(path: string): Promise<string[]>
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async function fileExists(path: string): Promise<boolean> {
|
|
23
|
-
try {
|
|
24
|
-
await fs.promises.access(path, fs.constants.F_OK | fs.constants.R_OK)
|
|
25
|
-
return true
|
|
26
|
-
} catch (error) {
|
|
27
|
-
return false
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
async function directoryExists(path: string): Promise<boolean> {
|
|
31
|
-
try {
|
|
32
|
-
return (await fs.promises.lstat(path)).isDirectory()
|
|
33
|
-
} catch (error) {
|
|
34
|
-
return false
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* @public
|
|
40
|
-
*/
|
|
41
|
-
export function createFsComponent(): IFileSystemComponent {
|
|
42
|
-
return {
|
|
43
|
-
createReadStream: fs.createReadStream,
|
|
44
|
-
createWriteStream: fs.createWriteStream,
|
|
45
|
-
access: fsPromises.access,
|
|
46
|
-
writeFile: fsPromises.writeFile,
|
|
47
|
-
opendir: fsPromises.opendir,
|
|
48
|
-
stat: fsPromises.stat,
|
|
49
|
-
unlink: fsPromises.unlink,
|
|
50
|
-
mkdir: fsPromises.mkdir,
|
|
51
|
-
rmdir: fsPromises.rmdir,
|
|
52
|
-
readdir: fsPromises.readdir,
|
|
53
|
-
readFile: fsPromises.readFile,
|
|
54
|
-
constants: {
|
|
55
|
-
F_OK: fs.constants.F_OK,
|
|
56
|
-
R_OK: fs.constants.R_OK
|
|
57
|
-
},
|
|
58
|
-
rename: fsPromises.rename,
|
|
59
|
-
fileExists,
|
|
60
|
-
directoryExists
|
|
61
|
-
}
|
|
62
|
-
}
|
package/src/components/index.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { ILoggerComponent } from '@well-known-components/interfaces'
|
|
2
|
-
import { createFetchComponent, IFetchComponent } from './fetch'
|
|
3
|
-
import { createFsComponent, IFileSystemComponent } from './fs'
|
|
4
|
-
import { createStdoutCliLogger } from './log'
|
|
5
|
-
|
|
6
|
-
export type CliComponents = {
|
|
7
|
-
fs: IFileSystemComponent
|
|
8
|
-
fetch: IFetchComponent
|
|
9
|
-
logger: ILoggerComponent.ILogger
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function initComponents(): CliComponents {
|
|
13
|
-
return {
|
|
14
|
-
fs: createFsComponent(),
|
|
15
|
-
fetch: createFetchComponent(),
|
|
16
|
-
logger: createStdoutCliLogger()
|
|
17
|
-
}
|
|
18
|
-
}
|
package/src/components/log.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { ILoggerComponent } from '@well-known-components/interfaces'
|
|
2
|
-
import { createColors } from 'colorette'
|
|
3
|
-
import { CliError } from '../logic/error'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* This file imitates "cargo" logs. The words are aligned with the colon like this:
|
|
7
|
-
* V
|
|
8
|
-
* Error: some text provided as argumen
|
|
9
|
-
* Info: some text provided as argumen
|
|
10
|
-
* Success: some text provided as argumen
|
|
11
|
-
* Warning: some text provided as argumen
|
|
12
|
-
* ^
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const stderr = (...parameters: readonly unknown[]) => {
|
|
16
|
-
process.stderr.write(`${parameters.filter(($) => $ !== undefined).join('')}\n`)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// @see https://no-color.org
|
|
20
|
-
// @see https://www.npmjs.com/package/chalk
|
|
21
|
-
export const colors = createColors({
|
|
22
|
-
useColor: process.env.FORCE_COLOR !== '0' && !process.env.NO_COLOR
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
export function createStdoutCliLogger(): ILoggerComponent.ILogger {
|
|
26
|
-
return {
|
|
27
|
-
log(message, extra) {
|
|
28
|
-
stderr(message, extra && JSON.stringify(extra))
|
|
29
|
-
},
|
|
30
|
-
debug(message, extra) {
|
|
31
|
-
stderr(colors.blueBright('debug: '), message, extra && JSON.stringify(extra))
|
|
32
|
-
},
|
|
33
|
-
error(error, extra) {
|
|
34
|
-
stderr(colors.redBright('error: '), error, extra && JSON.stringify(extra))
|
|
35
|
-
/* istanbul ignore next */
|
|
36
|
-
if (!(error instanceof CliError) || process.env.DEBUG) {
|
|
37
|
-
// print the stacktrace if it is not a CliError
|
|
38
|
-
console.error(error)
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
info(message, extra) {
|
|
42
|
-
stderr(colors.blueBright('info: '), message, extra && JSON.stringify(extra))
|
|
43
|
-
},
|
|
44
|
-
warn(message, extra) {
|
|
45
|
-
stderr(colors.yellow('warning: '), message, extra && JSON.stringify(extra))
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/* istanbul ignore file */
|
|
4
|
-
|
|
5
|
-
import { getArgs } from './logic/args'
|
|
6
|
-
import { CliError } from './logic/error'
|
|
7
|
-
import { COMMANDS_PATH, getCommands } from './logic/commands'
|
|
8
|
-
import { CliComponents, initComponents } from './components'
|
|
9
|
-
import { printCommand } from './logic/beautiful-logs'
|
|
10
|
-
import { colors } from './components/log'
|
|
11
|
-
|
|
12
|
-
export interface Options {
|
|
13
|
-
args: ReturnType<typeof getArgs>
|
|
14
|
-
components: CliComponents
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// leaving args as "any" since we don't know yet if we will use them
|
|
18
|
-
type FileFn = (options: Options) => Promise<void>
|
|
19
|
-
|
|
20
|
-
interface FileExports {
|
|
21
|
-
help?: FileFn
|
|
22
|
-
main?: FileFn
|
|
23
|
-
args?: ReturnType<typeof getArgs>
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const listCommandsStr = (commands: string[]) => commands.map(($) => `\t *sdk-commands ${$} \n`).join('')
|
|
27
|
-
|
|
28
|
-
const commandFnsAreValid = (fns: FileExports): fns is Required<FileExports> => {
|
|
29
|
-
const { help, main } = fns
|
|
30
|
-
if (!help || !main) {
|
|
31
|
-
throw new CliError(`Command does not follow implementation rules:
|
|
32
|
-
* Requires a "help" function
|
|
33
|
-
* Requires a "main" function
|
|
34
|
-
`)
|
|
35
|
-
}
|
|
36
|
-
return true
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async function main() {
|
|
40
|
-
const helpMessage = (commands: string[]) => `Here is the list of commands:\n${listCommandsStr(commands)}`
|
|
41
|
-
const args = getArgs()
|
|
42
|
-
const command = process.argv[2]
|
|
43
|
-
const needsHelp = args['--help']
|
|
44
|
-
const components: CliComponents = initComponents()
|
|
45
|
-
|
|
46
|
-
const commands = await getCommands(components)
|
|
47
|
-
|
|
48
|
-
if (!commands.includes(command)) {
|
|
49
|
-
if (needsHelp) {
|
|
50
|
-
components.logger.info(helpMessage(commands))
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
throw new CliError(`Command ${command} is invalid. ${helpMessage(commands)}`)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
57
|
-
const cmd = require(`${COMMANDS_PATH}/${command}`)
|
|
58
|
-
|
|
59
|
-
if (commandFnsAreValid(cmd)) {
|
|
60
|
-
const options = { args: cmd.args, components }
|
|
61
|
-
if (needsHelp) {
|
|
62
|
-
await cmd.help(options)
|
|
63
|
-
} else {
|
|
64
|
-
printCommand(components.logger, command)
|
|
65
|
-
|
|
66
|
-
const ret = await cmd.main(options)
|
|
67
|
-
// print the result of the evaluation as json in the standard output
|
|
68
|
-
if (cmd.args['--json']) {
|
|
69
|
-
process.stdout.write(JSON.stringify(ret, null, 2))
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// rollup watcher leaves many open FSWatcher even in build mode. we must call
|
|
75
|
-
// process.exit at this point to prevent the program halting forever
|
|
76
|
-
process.exit(process.exitCode || 0)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
main().catch(function handleError(err: Error) {
|
|
80
|
-
if (err instanceof CliError) {
|
|
81
|
-
console.error(colors.redBright('Error: ') + err.message)
|
|
82
|
-
} else {
|
|
83
|
-
// log with console to show stacktrace and debug information
|
|
84
|
-
console.error(err)
|
|
85
|
-
console.warn(`Developer: All errors thrown must be an instance of "CliError"`)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// set an exit code but not finish the program immediately to close any pending work
|
|
89
|
-
process.exitCode = 1
|
|
90
|
-
})
|
package/src/logic/args.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import arg, { Result } from 'arg'
|
|
2
|
-
|
|
3
|
-
export type Args = {
|
|
4
|
-
[key: string]: string | StringConstructor | NumberConstructor | BooleanConstructor
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
// updating to TS 4.9 will prevent losing types when
|
|
8
|
-
// enforcing type to be "Args" by using "satisfies Args"
|
|
9
|
-
export const DEFAULT_ARGS = {
|
|
10
|
-
'--help': Boolean,
|
|
11
|
-
'--json': Boolean,
|
|
12
|
-
'-h': '--help'
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function getArgs(): Result<typeof DEFAULT_ARGS>
|
|
16
|
-
export function getArgs<T extends Args>(args: T): Result<typeof DEFAULT_ARGS & T>
|
|
17
|
-
export function getArgs<T extends Args>(args?: T) {
|
|
18
|
-
return arg({ ...DEFAULT_ARGS, ...args }, { permissive: true })
|
|
19
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { ILoggerComponent } from '@well-known-components/interfaces'
|
|
2
|
-
import { colors } from '../components/log'
|
|
3
|
-
|
|
4
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
5
|
-
const { name, version } = require('../../package.json')
|
|
6
|
-
|
|
7
|
-
export function printProgressStep(logger: ILoggerComponent.ILogger, log: string, currentStep: number, maxStep: number) {
|
|
8
|
-
logger.log(colors.dim(`[${currentStep}/${maxStep}]`) + ' ' + log)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function printProgressInfo(logger: ILoggerComponent.ILogger, log: string) {
|
|
12
|
-
logger.log(colors.dim(log))
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function printCommand(logger: ILoggerComponent.ILogger, commandName: string) {
|
|
16
|
-
logger.log(colors.bold(`${name} ${commandName} v${version}`))
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function printSuccess(logger: ILoggerComponent.ILogger, operationSuccessfulMessage: string, summary: string) {
|
|
20
|
-
// print a space before the success callout
|
|
21
|
-
logger.log('')
|
|
22
|
-
logger.log(colors.greenBright(operationSuccessfulMessage))
|
|
23
|
-
if (typeof summary === 'string') {
|
|
24
|
-
logger.log(summary)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Entity } from '@dcl/schemas'
|
|
2
|
-
import { fetch } from 'undici'
|
|
3
|
-
|
|
4
|
-
export async function fetchEntityByPointer(
|
|
5
|
-
baseUrl: string,
|
|
6
|
-
pointers: string[]
|
|
7
|
-
): Promise<{
|
|
8
|
-
baseUrl: string
|
|
9
|
-
deployments: Entity[]
|
|
10
|
-
}> {
|
|
11
|
-
if (pointers.length === 0)
|
|
12
|
-
return {
|
|
13
|
-
baseUrl,
|
|
14
|
-
deployments: []
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const activeEntities = baseUrl + '/content/entities/active'
|
|
18
|
-
|
|
19
|
-
const response = await fetch(activeEntities, {
|
|
20
|
-
method: 'post',
|
|
21
|
-
headers: { 'content-type': 'application/json', connection: 'close' },
|
|
22
|
-
body: JSON.stringify({ pointers })
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
const deployments: Entity[] = response.ok ? ((await response.json()) as Entity[]) : []
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
baseUrl,
|
|
29
|
-
deployments
|
|
30
|
-
}
|
|
31
|
-
}
|
package/src/logic/commands.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'path'
|
|
2
|
-
import { CliComponents } from '../components'
|
|
3
|
-
import { CliError } from './error'
|
|
4
|
-
|
|
5
|
-
export const COMMANDS_PATH = resolve(__dirname, '../commands')
|
|
6
|
-
|
|
7
|
-
export async function getCommands({ fs }: Pick<CliComponents, 'fs'>): Promise<string[]> {
|
|
8
|
-
const commandDirs = await fs.readdir(COMMANDS_PATH)
|
|
9
|
-
|
|
10
|
-
const commands = commandDirs.map(async (dir) => {
|
|
11
|
-
const path = resolve(COMMANDS_PATH, dir)
|
|
12
|
-
|
|
13
|
-
const statDir = await fs.stat(path)
|
|
14
|
-
|
|
15
|
-
if (!statDir.isDirectory()) {
|
|
16
|
-
throw new CliError('Developer: All commands must be inside a folder')
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const statIndex = await fs.stat(`${path}/index.js`)
|
|
20
|
-
if (!statIndex.isFile()) {
|
|
21
|
-
throw new CliError('Developer: All commands must have an "index.js" file inside')
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return dir
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
return Promise.all(commands)
|
|
28
|
-
}
|
package/src/logic/coordinates.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
export interface IBounds {
|
|
2
|
-
minX: number
|
|
3
|
-
minY: number
|
|
4
|
-
maxX: number
|
|
5
|
-
maxY: number
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export type Coords = {
|
|
9
|
-
x: number
|
|
10
|
-
y: number
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Returns metaverse coordinates bounds.
|
|
15
|
-
* TODO: use functions from @dcl/schemas
|
|
16
|
-
*/
|
|
17
|
-
export function getBounds(): IBounds {
|
|
18
|
-
return {
|
|
19
|
-
minX: -150,
|
|
20
|
-
minY: -150,
|
|
21
|
-
maxX: 165,
|
|
22
|
-
maxY: 165
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Parses a string-based set of coordinates.
|
|
28
|
-
* - All spaces are removed
|
|
29
|
-
* - Leading zeroes are removed
|
|
30
|
-
* - `-0` is converted to `0`
|
|
31
|
-
* @param coordinates An string containing coordinates in the `x,y; x,y; ...` format
|
|
32
|
-
*/
|
|
33
|
-
export function parse(coordinates: string): string[] {
|
|
34
|
-
return coordinates.split(';').map((coord: string) => {
|
|
35
|
-
const [x, y] = coord.split(',').map(($) => {
|
|
36
|
-
return parseInt($, 10)
|
|
37
|
-
.toString() // removes spaces :)
|
|
38
|
-
.replace('-0', '0')
|
|
39
|
-
.replace(/undefined|NaN/g, '0')
|
|
40
|
-
})
|
|
41
|
-
return `${x},${y}`
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Converts a string-based set of coordinates to an object
|
|
47
|
-
* @param coords A string containing a set of coordinates
|
|
48
|
-
*/
|
|
49
|
-
export function getObject(coords: string): Coords {
|
|
50
|
-
const [x, y] = parse(coords)[0].split(',')
|
|
51
|
-
return { x: parseInt(x.toString(), 10), y: parseInt(y.toString(), 10) }
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Returns true if the given coordinates are in metaverse bounds
|
|
56
|
-
*/
|
|
57
|
-
export function inBounds(x: number, y: number): boolean {
|
|
58
|
-
const { minX, minY, maxX, maxY } = getBounds()
|
|
59
|
-
return x >= minX && x <= maxX && y >= minY && y <= maxY
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Returns true if the given parcels array are connected
|
|
64
|
-
*/
|
|
65
|
-
export function areConnected(parcels: Coords[]): boolean {
|
|
66
|
-
if (parcels.length === 0) {
|
|
67
|
-
return false
|
|
68
|
-
}
|
|
69
|
-
const visited = visitParcel(parcels[0], parcels)
|
|
70
|
-
return visited.length === parcels.length
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function visitParcel(parcel: Coords, allParcels: Coords[], visited: Coords[] = []): Coords[] {
|
|
74
|
-
const isVisited = visited.some((visitedParcel) => isEqual(visitedParcel, parcel))
|
|
75
|
-
if (!isVisited) {
|
|
76
|
-
visited.push(parcel)
|
|
77
|
-
const neighbours = getNeighbours(parcel.x, parcel.y, allParcels)
|
|
78
|
-
neighbours.forEach((neighbours) => visitParcel(neighbours, allParcels, visited))
|
|
79
|
-
}
|
|
80
|
-
return visited
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function getIsNeighbourMatcher(x: number, y: number) {
|
|
84
|
-
return (coords: Coords) =>
|
|
85
|
-
(coords.x === x && (coords.y + 1 === y || coords.y - 1 === y)) ||
|
|
86
|
-
(coords.y === y && (coords.x + 1 === x || coords.x - 1 === x))
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function getNeighbours(x: number, y: number, parcels: Coords[]): Coords[] {
|
|
90
|
-
return parcels.filter(getIsNeighbourMatcher(x, y))
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function isEqual(p1: Coords, p2: Coords): boolean {
|
|
94
|
-
return p1.x === p2.x && p1.y === p2.y
|
|
95
|
-
}
|
package/src/logic/dcl-ignore.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import { CliComponents } from '../components'
|
|
3
|
-
|
|
4
|
-
export const defaultDclIgnore = [
|
|
5
|
-
'.*',
|
|
6
|
-
'package.json',
|
|
7
|
-
'package-lock.json',
|
|
8
|
-
'yarn-lock.json',
|
|
9
|
-
'build.json',
|
|
10
|
-
'export',
|
|
11
|
-
'tsconfig.json',
|
|
12
|
-
'tslint.json',
|
|
13
|
-
'node_modules',
|
|
14
|
-
'**/*.ts',
|
|
15
|
-
'**/*.tsx',
|
|
16
|
-
'Dockerfile',
|
|
17
|
-
'dist',
|
|
18
|
-
'README.md',
|
|
19
|
-
'*.blend',
|
|
20
|
-
'*.fbx',
|
|
21
|
-
'*.zip',
|
|
22
|
-
'*.rar'
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
export async function getDCLIgnoreFileContents(
|
|
26
|
-
components: Pick<CliComponents, 'fs'>,
|
|
27
|
-
dir: string
|
|
28
|
-
): Promise<string | null> {
|
|
29
|
-
try {
|
|
30
|
-
return components.fs.readFile(path.resolve(dir, '.dclignore'), 'utf8')
|
|
31
|
-
} catch (e) {}
|
|
32
|
-
|
|
33
|
-
return null
|
|
34
|
-
}
|
|
35
|
-
|
|
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
|
-
export async function getDCLIgnorePatterns(components: Pick<CliComponents, 'fs'>, dir: string): Promise<string[]> {
|
|
41
|
-
const ignoredContent = await getDCLIgnoreFileContents(components, dir)
|
|
42
|
-
const ignored = (ignoredContent?.split('\n') || defaultDclIgnore).filter(Boolean)
|
|
43
|
-
ignored.push(...defaultDclIgnore)
|
|
44
|
-
|
|
45
|
-
// by default many files need to be ignored
|
|
46
|
-
ignored.push('.*', 'node_modules', '**/*.ts', '**/*.tsx')
|
|
47
|
-
|
|
48
|
-
return Array.from(new Set(ignored))
|
|
49
|
-
}
|
package/src/logic/error.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export class CliError extends Error {}
|
package/src/logic/exec.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'child_process'
|
|
2
|
-
|
|
3
|
-
interface Options {
|
|
4
|
-
env: { [key: string]: string }
|
|
5
|
-
silent: boolean
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function exec(
|
|
9
|
-
cwd: string,
|
|
10
|
-
command: string,
|
|
11
|
-
args: string[],
|
|
12
|
-
{ env, silent }: Partial<Options> = {}
|
|
13
|
-
): Promise<void> {
|
|
14
|
-
return new Promise((resolve, reject) => {
|
|
15
|
-
const child = spawn(command, args, {
|
|
16
|
-
shell: true,
|
|
17
|
-
cwd,
|
|
18
|
-
env: { ...process.env, NODE_ENV: '', ...env }
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
if (!silent) {
|
|
22
|
-
child.stdout.pipe(process.stdout)
|
|
23
|
-
child.stderr.pipe(process.stderr)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
child.on('close', (code: number) => {
|
|
27
|
-
if (code !== 0) {
|
|
28
|
-
const _ = `${command} ${args.join(' ')}`
|
|
29
|
-
reject(new Error(`Command "${_}" exited with code ${code}. Please try running the command manually`))
|
|
30
|
-
return
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
resolve(undefined)
|
|
34
|
-
})
|
|
35
|
-
})
|
|
36
|
-
}
|
package/src/logic/fs.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import extractZip from 'extract-zip'
|
|
2
|
-
import { resolve } from 'path'
|
|
3
|
-
import { IFileSystemComponent } from '../components/fs'
|
|
4
|
-
import { IFetchComponent } from '../components/fetch'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Check's if directory is empty
|
|
8
|
-
* @param dir Directory to check for emptyness
|
|
9
|
-
*/
|
|
10
|
-
export async function isDirectoryEmpty(components: { fs: IFileSystemComponent }, dir: string): Promise<boolean> {
|
|
11
|
-
const files = await components.fs.readdir(dir)
|
|
12
|
-
return !files.length
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Download a file
|
|
17
|
-
* @param url URL of the file
|
|
18
|
-
* @param dest Path to where to save the file
|
|
19
|
-
*/
|
|
20
|
-
export async function download(
|
|
21
|
-
components: { fs: IFileSystemComponent; fetch: IFetchComponent },
|
|
22
|
-
url: string,
|
|
23
|
-
dest: string
|
|
24
|
-
): Promise<string> {
|
|
25
|
-
// we should remove this package and use the native "fetch" when Node
|
|
26
|
-
// releases it as stable: https://nodejs.org/docs/latest-v18.x/api/globals.html#fetch
|
|
27
|
-
const data = await (await components.fetch.fetch(url)).arrayBuffer()
|
|
28
|
-
await components.fs.writeFile(dest, Buffer.from(data))
|
|
29
|
-
return dest
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Extracts a .zip file
|
|
34
|
-
* @param url Path of the zip file
|
|
35
|
-
* @param dest Path to where to extract the zip file
|
|
36
|
-
*/
|
|
37
|
-
export async function extract(path: string, dest: string): Promise<string> {
|
|
38
|
-
const destPath = resolve(dest)
|
|
39
|
-
await extractZip(resolve(path), { dir: destPath })
|
|
40
|
-
return destPath
|
|
41
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import portfinder from 'portfinder'
|
|
2
|
-
|
|
3
|
-
export async function previewPort() {
|
|
4
|
-
let resolvedPort = 0
|
|
5
|
-
|
|
6
|
-
if (!resolvedPort) {
|
|
7
|
-
try {
|
|
8
|
-
resolvedPort = await portfinder.getPortPromise()
|
|
9
|
-
} catch (e) {
|
|
10
|
-
resolvedPort = 2044
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return resolvedPort
|
|
15
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { ContentMapping } from '@dcl/schemas/dist/misc/content-mapping'
|
|
2
|
-
import { CliComponents } from '../components'
|
|
3
|
-
import { getDCLIgnorePatterns } from './dcl-ignore'
|
|
4
|
-
import { sync as globSync } from 'glob'
|
|
5
|
-
import ignore from 'ignore'
|
|
6
|
-
import path from 'path'
|
|
7
|
-
import { CliError } from './error'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Returns an array of the publishable files for a given folder.
|
|
11
|
-
*/
|
|
12
|
-
export async function getPublishableFiles(
|
|
13
|
-
components: Pick<CliComponents, 'fs'>,
|
|
14
|
-
projectRoot: string
|
|
15
|
-
): Promise<Array<string>> {
|
|
16
|
-
const ignorePatterns = await getDCLIgnorePatterns(components, projectRoot)
|
|
17
|
-
|
|
18
|
-
const ig = ignore().add(ignorePatterns)
|
|
19
|
-
|
|
20
|
-
const allFiles = globSync('**/*', {
|
|
21
|
-
cwd: projectRoot,
|
|
22
|
-
absolute: false,
|
|
23
|
-
dot: false,
|
|
24
|
-
ignore: ignorePatterns,
|
|
25
|
-
nodir: true
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
return ig.filter(allFiles)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* This function converts paths to decentraland-compatible paths.
|
|
33
|
-
* - From windows separators to unix separators.
|
|
34
|
-
* - All to lowercase
|
|
35
|
-
*/
|
|
36
|
-
export function normalizeDecentralandFilename(filename: string) {
|
|
37
|
-
return filename.replace(/(\\)/g, '/').toLowerCase()
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Returns the content mappings for a specific project folder.
|
|
42
|
-
*/
|
|
43
|
-
export async function getProjectContentMappings(
|
|
44
|
-
components: Pick<CliComponents, 'fs'>,
|
|
45
|
-
projectRoot: string,
|
|
46
|
-
hashingFunction: (filePath: string) => Promise<string>
|
|
47
|
-
): Promise<ContentMapping[]> {
|
|
48
|
-
const projectFiles = await getPublishableFiles(components, projectRoot)
|
|
49
|
-
const ret: ContentMapping[] = []
|
|
50
|
-
|
|
51
|
-
const usedFilenames = new Set<string>()
|
|
52
|
-
|
|
53
|
-
for (const file of projectFiles) {
|
|
54
|
-
const absolutePath = path.resolve(projectRoot, file)
|
|
55
|
-
|
|
56
|
-
/* istanbul ignore if */
|
|
57
|
-
if (!(await components.fs.fileExists(absolutePath))) continue
|
|
58
|
-
|
|
59
|
-
// remove heading '/'
|
|
60
|
-
const normalizedFile = normalizeDecentralandFilename(file).replace(/^\/+/, '')
|
|
61
|
-
|
|
62
|
-
/* istanbul ignore if */
|
|
63
|
-
if (usedFilenames.has(normalizedFile)) {
|
|
64
|
-
throw new CliError(
|
|
65
|
-
`DuplicatedFilenameError: the file ${file} exists with a different casing. Please manually remove one occurrence`
|
|
66
|
-
)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
ret.push({
|
|
70
|
-
file: normalizedFile,
|
|
71
|
-
hash: await hashingFunction(absolutePath)
|
|
72
|
-
})
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return ret
|
|
76
|
-
}
|