@dcl/sdk 7.0.6-4197661608.commit-41efaad → 7.0.6-4197739270.commit-db87ed8

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.
@@ -1,13 +1,15 @@
1
1
  import { Router } from '@well-known-components/http-server'
2
2
  import { PreviewComponents } from './types'
3
3
  import * as path from 'path'
4
- import * as fs from 'fs'
5
4
  import { sync as globSync } from 'glob'
6
5
  import { WearableJson } from '@dcl/schemas/dist/sdk'
7
- import { ContentMapping, Entity, EntityType } from '@dcl/schemas'
6
+ import { ContentMapping, Entity, EntityType, Locale, Wearable } from '@dcl/schemas'
8
7
  import ignore from 'ignore'
9
8
  import fetch, { Headers } from 'node-fetch'
10
9
  import { fetchEntityByPointer } from './catalyst'
10
+ import { CliComponents } from '../../components'
11
+ import { statSync } from 'fs'
12
+ import { getDCLIgnorePatterns } from '../../utils/dcl-ignore'
11
13
 
12
14
  function getCatalystUrl(): URL {
13
15
  return new URL('https://peer.decentraland.org')
@@ -17,13 +19,17 @@ function smartWearableNameToId(name: string) {
17
19
  return name.toLocaleLowerCase().replace(/ /g, '-')
18
20
  }
19
21
 
20
- export function setupEcs6Endpoints(dir: string, router: Router<PreviewComponents>) {
22
+ type LambdasWearable = Wearable & {
23
+ baseUrl: string
24
+ }
25
+
26
+ export function setupEcs6Endpoints(components: CliComponents, dir: string, router: Router<PreviewComponents>) {
21
27
  const baseFolders = [dir]
22
28
  // handle old preview scene.json
23
29
  router.get('/scene.json', async () => {
24
30
  return {
25
31
  headers: { 'content-type': 'application/json' },
26
- body: fs.createReadStream(path.join(dir, 'scene.json'))
32
+ body: components.fs.createReadStream(path.join(dir, 'scene.json'))
27
33
  }
28
34
  })
29
35
 
@@ -58,10 +64,10 @@ export function setupEcs6Endpoints(dir: string, router: Router<PreviewComponents
58
64
  const baseUrl = `${ctx.url.protocol}//${ctx.url.host}/content/contents`
59
65
 
60
66
  try {
61
- const previewWearables = getAllPreviewWearables({
67
+ const previewWearables = await getAllPreviewWearables(components, {
62
68
  baseFolders,
63
69
  baseUrl
64
- }).map((wearable) => wearable.id)
70
+ })
65
71
 
66
72
  if (previewWearables.length === 1) {
67
73
  const catalystUrl = getCatalystUrl()
@@ -81,7 +87,7 @@ export function setupEcs6Endpoints(dir: string, router: Router<PreviewComponents
81
87
  const deployedProfile = (await req.json()) as any[]
82
88
 
83
89
  if (deployedProfile?.length === 1) {
84
- deployedProfile[0].avatars[0].avatar.wearables.push(...previewWearables)
90
+ deployedProfile[0].avatars[0].avatar.wearables.push(...previewWearables.map(($) => $.id))
85
91
  return {
86
92
  headers: {
87
93
  'content-type': req.headers.get('content-type') || 'application/binary'
@@ -132,14 +138,14 @@ export function setupEcs6Endpoints(dir: string, router: Router<PreviewComponents
132
138
  return res
133
139
  })
134
140
 
135
- serveStatic(dir, router)
141
+ serveStatic(components, dir, router)
136
142
 
137
143
  // TODO: get workspace scenes & wearables...
138
144
 
139
- serveFolders(router, baseFolders)
145
+ serveFolders(components, router, baseFolders)
140
146
  }
141
147
 
142
- function serveFolders(router: Router<PreviewComponents>, baseFolders: string[]) {
148
+ function serveFolders(components: Pick<CliComponents, 'fs'>, router: Router<PreviewComponents>, baseFolders: string[]) {
143
149
  router.get('/content/contents/:hash', async (ctx: any, next: any) => {
144
150
  if (ctx.params.hash && ctx.params.hash.startsWith('b64-')) {
145
151
  const fullPath = path.resolve(Buffer.from(ctx.params.hash.replace(/^b64-/, ''), 'base64').toString('utf8'))
@@ -155,7 +161,7 @@ function serveFolders(router: Router<PreviewComponents>, baseFolders: string[])
155
161
  'x-sent': true,
156
162
  'cache-control': 'no-cache,private,max-age=1'
157
163
  },
158
- body: fs.createReadStream(fullPath)
164
+ body: components.fs.createReadStream(fullPath)
159
165
  }
160
166
  }
161
167
 
@@ -171,7 +177,7 @@ function serveFolders(router: Router<PreviewComponents>, baseFolders: string[])
171
177
  pointers && typeof pointers === 'string' ? [pointers as string] : (pointers as string[])
172
178
  )
173
179
 
174
- const resultEntities = getSceneJson({
180
+ const resultEntities = await getSceneJson(components, {
175
181
  baseFolders,
176
182
  pointers: Array.from(requestedPointers)
177
183
  })
@@ -203,7 +209,7 @@ function serveFolders(router: Router<PreviewComponents>, baseFolders: string[])
203
209
 
204
210
  router.get('/preview-wearables/:id', async (ctx) => {
205
211
  const baseUrl = `${ctx.url.protocol}//${ctx.url.host}/content/contents`
206
- const wearables = getAllPreviewWearables({
212
+ const wearables = await getAllPreviewWearables(components, {
207
213
  baseUrl,
208
214
  baseFolders
209
215
  })
@@ -221,7 +227,7 @@ function serveFolders(router: Router<PreviewComponents>, baseFolders: string[])
221
227
  return {
222
228
  body: {
223
229
  ok: true,
224
- data: getAllPreviewWearables({ baseUrl, baseFolders })
230
+ data: await getAllPreviewWearables(components, { baseUrl, baseFolders })
225
231
  }
226
232
  }
227
233
  })
@@ -229,19 +235,22 @@ function serveFolders(router: Router<PreviewComponents>, baseFolders: string[])
229
235
 
230
236
  const defaultHashMaker = (str: string) => 'b64-' + Buffer.from(str).toString('base64')
231
237
 
232
- function getAllPreviewWearables({ baseFolders, baseUrl }: { baseFolders: string[]; baseUrl: string }) {
238
+ async function getAllPreviewWearables(
239
+ components: Pick<CliComponents, 'fs'>,
240
+ { baseFolders, baseUrl }: { baseFolders: string[]; baseUrl: string }
241
+ ) {
233
242
  const wearablePathArray: string[] = []
234
243
  for (const wearableDir of baseFolders) {
235
244
  const wearableJsonPath = path.resolve(wearableDir, 'wearable.json')
236
- if (fs.existsSync(wearableJsonPath)) {
245
+ if (await components.fs.fileExists(wearableJsonPath)) {
237
246
  wearablePathArray.push(wearableJsonPath)
238
247
  }
239
248
  }
240
249
 
241
- const ret: ReturnType<typeof serveWearable>[] = []
250
+ const ret: LambdasWearable[] = []
242
251
  for (const wearableJsonPath of wearablePathArray) {
243
252
  try {
244
- ret.push(serveWearable({ wearableJsonPath, baseUrl }))
253
+ ret.push(await serveWearable(components, { wearableJsonPath, baseUrl }))
245
254
  } catch (err) {
246
255
  console.error(`Couldn't mock the wearable ${wearableJsonPath}. Please verify the correct format and scheme.`, err)
247
256
  }
@@ -249,9 +258,12 @@ function getAllPreviewWearables({ baseFolders, baseUrl }: { baseFolders: string[
249
258
  return ret
250
259
  }
251
260
 
252
- function serveWearable({ wearableJsonPath, baseUrl }: { wearableJsonPath: string; baseUrl: string }) {
261
+ async function serveWearable(
262
+ components: Pick<CliComponents, 'fs'>,
263
+ { wearableJsonPath, baseUrl }: { wearableJsonPath: string; baseUrl: string }
264
+ ): Promise<LambdasWearable> {
253
265
  const wearableDir = path.dirname(wearableJsonPath)
254
- const wearableJson = JSON.parse(fs.readFileSync(wearableJsonPath).toString())
266
+ const wearableJson = JSON.parse((await components.fs.readFile(wearableJsonPath)).toString())
255
267
 
256
268
  if (!WearableJson.validate(wearableJson)) {
257
269
  const errors = (WearableJson.validate.errors || []).map((a) => `${a.data} ${a.message}`).join('')
@@ -260,16 +272,9 @@ function serveWearable({ wearableJsonPath, baseUrl }: { wearableJsonPath: string
260
272
  throw new Error(`Invalid wearable.json (${wearableJsonPath})`)
261
273
  }
262
274
 
263
- const dclIgnorePath = path.resolve(wearableDir, '.dclignore')
264
- let ignoreFileContent = ''
265
- if (fs.existsSync(dclIgnorePath)) {
266
- ignoreFileContent = fs.readFileSync(path.resolve(wearableDir, '.dclignore'), 'utf-8')
267
- }
268
-
269
- const hashedFiles = getFilesFromFolder({
275
+ const hashedFiles = await getFilesFromFolder(components, {
270
276
  folder: wearableDir,
271
- addOriginalPath: false,
272
- ignorePattern: ignoreFileContent
277
+ addOriginalPath: false
273
278
  })
274
279
 
275
280
  const thumbnailFiltered = hashedFiles.filter(($) => $?.file === 'thumbnail.png')
@@ -291,9 +296,11 @@ function serveWearable({ wearableJsonPath, baseUrl }: { wearableJsonPath: string
291
296
  return {
292
297
  id: wearableId,
293
298
  rarity: wearableJson.rarity,
294
- i18n: [{ code: 'en', text: wearableJson.name }],
299
+ i18n: [{ code: 'en' as Locale, text: wearableJson.name }],
295
300
  description: wearableJson.description,
296
301
  thumbnail: thumbnail || '',
302
+ image: thumbnail || '',
303
+ collectionAddress: '0x0',
297
304
  baseUrl: `${baseUrl}/`,
298
305
  name: wearableJson.name || '',
299
306
  data: {
@@ -301,38 +308,36 @@ function serveWearable({ wearableJsonPath, baseUrl }: { wearableJsonPath: string
301
308
  replaces: [],
302
309
  hides: [],
303
310
  tags: [],
304
- scene: hashedFiles,
305
311
  representations: representations as any
312
+ // scene: hashedFiles as any,
306
313
  }
307
314
  }
308
315
  }
309
316
 
310
- function getSceneJson({
311
- baseFolders,
312
- pointers,
313
- customHashMaker
314
- }: {
315
- baseFolders: string[]
316
- pointers: string[]
317
- customHashMaker?: (str: string) => string
318
- }): Entity[] {
317
+ async function getSceneJson(
318
+ components: Pick<CliComponents, 'fs'>,
319
+ {
320
+ baseFolders,
321
+ pointers,
322
+ customHashMaker
323
+ }: {
324
+ baseFolders: string[]
325
+ pointers: string[]
326
+ customHashMaker?: (str: string) => string
327
+ }
328
+ ): Promise<Entity[]> {
319
329
  const requestedPointers = new Set<string>(pointers)
320
330
  const resultEntities: Entity[] = []
321
331
 
322
- const allDeployments = baseFolders.map((folder) => {
323
- const dclIgnorePath = path.resolve(folder, '.dclignore')
324
- let ignoreFileContent = ''
325
- if (fs.existsSync(dclIgnorePath)) {
326
- ignoreFileContent = fs.readFileSync(path.resolve(folder, '.dclignore'), 'utf-8')
327
- }
328
-
329
- return entityV3FromFolder({
330
- folder,
331
- addOriginalPath: false,
332
- ignorePattern: ignoreFileContent,
333
- customHashMaker
332
+ const allDeployments = await Promise.all(
333
+ baseFolders.map(async (folder) => {
334
+ return entityV3FromFolder(components, {
335
+ folder,
336
+ addOriginalPath: false,
337
+ customHashMaker
338
+ })
334
339
  })
335
- })
340
+ )
336
341
 
337
342
  for (const pointer of Array.from(requestedPointers)) {
338
343
  // get deployment by pointer
@@ -350,7 +355,7 @@ function getSceneJson({
350
355
  return resultEntities
351
356
  }
352
357
 
353
- function serveStatic(dir: string, router: Router<PreviewComponents>) {
358
+ function serveStatic(components: Pick<CliComponents, 'fs'>, dir: string, router: Router<PreviewComponents>) {
354
359
  const sdkPath = path.dirname(
355
360
  require.resolve('@dcl/sdk/package.json', {
356
361
  paths: [dir]
@@ -387,18 +392,23 @@ function serveStatic(dir: string, router: Router<PreviewComponents>) {
387
392
  router.get(route.route, async (_ctx) => {
388
393
  return {
389
394
  headers: { 'Content-Type': route.type },
390
- body: fs.createReadStream(route.path)
395
+ body: components.fs.createReadStream(route.path)
391
396
  }
392
397
  })
393
398
  }
394
399
 
395
- function createStaticRoutes(route: string, folder: string, transform = (str: string) => str) {
400
+ function createStaticRoutes(
401
+ components: Pick<CliComponents, 'fs'>,
402
+ route: string,
403
+ folder: string,
404
+ transform = (str: string) => str
405
+ ) {
396
406
  router.get(route, async (ctx, next) => {
397
407
  const file = ctx.params.path
398
408
  const fullPath = path.resolve(folder, transform(file))
399
409
 
400
410
  // only return files IF the file is within a baseFolder
401
- if (!fs.existsSync(fullPath)) {
411
+ if (!(await components.fs.fileExists(fullPath))) {
402
412
  return next()
403
413
  }
404
414
 
@@ -414,14 +424,14 @@ function serveStatic(dir: string, router: Router<PreviewComponents>) {
414
424
 
415
425
  return {
416
426
  headers,
417
- body: fs.createReadStream(fullPath)
427
+ body: components.fs.createReadStream(fullPath)
418
428
  }
419
429
  })
420
430
  }
421
431
 
422
- createStaticRoutes('/images/decentraland-connect/:path+', dclKernelImagesDecentralandConnect)
423
- createStaticRoutes('/default-profile/:path+', dclKernelDefaultProfilePath)
424
- createStaticRoutes('/@/explorer/:path+', dclExplorerJsonPath, (filePath) => filePath.replace(/.br+$/, ''))
432
+ createStaticRoutes(components, '/images/decentraland-connect/:path+', dclKernelImagesDecentralandConnect)
433
+ createStaticRoutes(components, '/default-profile/:path+', dclKernelDefaultProfilePath)
434
+ createStaticRoutes(components, '/@/explorer/:path+', dclExplorerJsonPath, (filePath) => filePath.replace(/.br+$/, ''))
425
435
 
426
436
  router.get('/feature-flags/:file', async (ctx) => {
427
437
  const res = await fetch(`https://feature-flags.decentraland.zone/${ctx.params.file}`, {
@@ -435,24 +445,25 @@ function serveStatic(dir: string, router: Router<PreviewComponents>) {
435
445
  })
436
446
  }
437
447
 
438
- function entityV3FromFolder({
439
- folder,
440
- addOriginalPath,
441
- ignorePattern,
442
- customHashMaker
443
- }: {
444
- folder: string
445
- addOriginalPath?: boolean
446
- ignorePattern?: string
447
- customHashMaker?: (str: string) => string
448
- }): Entity | null {
448
+ async function entityV3FromFolder(
449
+ components: Pick<CliComponents, 'fs'>,
450
+ {
451
+ folder,
452
+ addOriginalPath,
453
+ customHashMaker
454
+ }: {
455
+ folder: string
456
+ addOriginalPath?: boolean
457
+ customHashMaker?: (str: string) => string
458
+ }
459
+ ): Promise<Entity | null> {
449
460
  const sceneJsonPath = path.resolve(folder, './scene.json')
450
461
  let isParcelScene = true
451
462
 
452
463
  const wearableJsonPath = path.resolve(folder, './wearable.json')
453
- if (fs.existsSync(wearableJsonPath)) {
464
+ if (await components.fs.fileExists(wearableJsonPath)) {
454
465
  try {
455
- const wearableJson = JSON.parse(fs.readFileSync(wearableJsonPath).toString())
466
+ const wearableJson = JSON.parse(await components.fs.readFile(wearableJsonPath, 'utf-8'))
456
467
  if (!WearableJson.validate(wearableJson)) {
457
468
  const errors = (WearableJson.validate.errors || []).map((a) => `${a.data} ${a.message}`).join('')
458
469
 
@@ -468,17 +479,16 @@ function entityV3FromFolder({
468
479
 
469
480
  const hashMaker = customHashMaker ? customHashMaker : defaultHashMaker
470
481
 
471
- if (fs.existsSync(sceneJsonPath) && isParcelScene) {
472
- const sceneJson = JSON.parse(fs.readFileSync(sceneJsonPath).toString())
482
+ if ((await components.fs.fileExists(sceneJsonPath)) && isParcelScene) {
483
+ const sceneJson = JSON.parse(await components.fs.readFile(sceneJsonPath, 'utf-8'))
473
484
  const { base, parcels }: { base: string; parcels: string[] } = sceneJson.scene
474
485
  const pointers = new Set<string>()
475
486
  pointers.add(base)
476
487
  parcels.forEach(($) => pointers.add($))
477
488
 
478
- const mappedFiles = getFilesFromFolder({
489
+ const mappedFiles = await getFilesFromFolder(components, {
479
490
  folder,
480
491
  addOriginalPath,
481
- ignorePattern,
482
492
  customHashMaker
483
493
  })
484
494
 
@@ -496,49 +506,30 @@ function entityV3FromFolder({
496
506
  return null
497
507
  }
498
508
 
499
- const defaultDclIgnore = () =>
500
- [
501
- '.*',
502
- 'package.json',
503
- 'package-lock.json',
504
- 'yarn-lock.json',
505
- 'build.json',
506
- 'export',
507
- 'tsconfig.json',
508
- 'tslint.json',
509
- 'node_modules',
510
- '*.ts',
511
- '*.tsx',
512
- 'Dockerfile',
513
- 'dist',
514
- 'README.md',
515
- '*.blend',
516
- '*.fbx',
517
- '*.zip',
518
- '*.rar'
519
- ].join('\n')
520
-
521
- export function getFilesFromFolder({
522
- folder,
523
- addOriginalPath,
524
- ignorePattern,
525
- customHashMaker
526
- }: {
527
- folder: string
528
- addOriginalPath?: boolean
529
- ignorePattern?: string
530
- customHashMaker?: (str: string) => string
531
- }): ContentMapping[] {
509
+ export async function getFilesFromFolder(
510
+ components: Pick<CliComponents, 'fs'>,
511
+ {
512
+ folder,
513
+ addOriginalPath,
514
+ customHashMaker
515
+ }: {
516
+ folder: string
517
+ addOriginalPath?: boolean
518
+ customHashMaker?: (str: string) => string
519
+ }
520
+ ): Promise<ContentMapping[]> {
532
521
  const hashMaker = customHashMaker ? customHashMaker : defaultHashMaker
522
+ const ignorePatterns = await getDCLIgnorePatterns(components, folder)
533
523
 
534
524
  const allFiles = globSync('**/*', {
525
+ ignore: ignorePatterns,
535
526
  cwd: folder,
536
527
  dot: false,
537
528
  absolute: true
538
529
  })
539
530
  .map((file) => {
540
531
  try {
541
- if (!fs.statSync(file).isFile()) return
532
+ if (!statSync(file).isFile()) return
542
533
  } catch (err) {
543
534
  return
544
535
  }
@@ -548,8 +539,7 @@ export function getFilesFromFolder({
548
539
  })
549
540
  .filter(($) => !!$) as string[]
550
541
 
551
- const ensureIgnorePattern = ignorePattern && ignorePattern !== '' ? ignorePattern : defaultDclIgnore()
552
- const ig = ignore().add(ensureIgnorePattern)
542
+ const ig = ignore().add(ignorePatterns)
553
543
  const filteredFiles = ig.filter(allFiles)
554
544
 
555
545
  const ret: (ContentMapping & { original_path: string | undefined })[] = []
@@ -557,9 +547,9 @@ export function getFilesFromFolder({
557
547
  for (const file of filteredFiles) {
558
548
  const absolutePath = path.resolve(folder, file)
559
549
  try {
560
- if (!fs.statSync(absolutePath).isFile()) continue
550
+ if (!statSync(absolutePath).isFile()) continue
561
551
  } catch (err) {
562
- console.log(err)
552
+ console.error(err)
563
553
  continue
564
554
  }
565
555
 
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.providerInstance = void 0;
4
4
  const eth_connect_1 = require("eth-connect");
5
- exports.providerInstance = new eth_connect_1.HTTPProvider('https://goerli.infura.io/');
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZXRoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUEwQztBQUU3QixRQUFBLGdCQUFnQixHQUFHLElBQUksMEJBQVksQ0FBQywyQkFBMkIsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSFRUUFByb3ZpZGVyIH0gZnJvbSAnZXRoLWNvbm5lY3QnXG5cbmV4cG9ydCBjb25zdCBwcm92aWRlckluc3RhbmNlID0gbmV3IEhUVFBQcm92aWRlcignaHR0cHM6Ly9nb2VybGkuaW5mdXJhLmlvLycpXG4iXX0=
5
+ exports.providerInstance = new eth_connect_1.HTTPProvider('https://rpc.decentraland.org/mainnet?project=sdk-commands');
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZXRoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUEwQztBQUU3QixRQUFBLGdCQUFnQixHQUFHLElBQUksMEJBQVksQ0FBQywyREFBMkQsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSFRUUFByb3ZpZGVyIH0gZnJvbSAnZXRoLWNvbm5lY3QnXG5cbmV4cG9ydCBjb25zdCBwcm92aWRlckluc3RhbmNlID0gbmV3IEhUVFBQcm92aWRlcignaHR0cHM6Ly9ycGMuZGVjZW50cmFsYW5kLm9yZy9tYWlubmV0P3Byb2plY3Q9c2RrLWNvbW1hbmRzJylcbiJdfQ==
@@ -1,3 +1,3 @@
1
1
  import { HTTPProvider } from 'eth-connect'
2
2
 
3
- export const providerInstance = new HTTPProvider('https://goerli.infura.io/')
3
+ export const providerInstance = new HTTPProvider('https://rpc.decentraland.org/mainnet?project=sdk-commands')
@@ -1,10 +1,33 @@
1
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
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
29
  exports.main = exports.args = exports.help = void 0;
7
- const path_1 = require("path");
30
+ const path_1 = __importStar(require("path"));
8
31
  const fp_future_1 = __importDefault(require("fp-future"));
9
32
  const interfaces_1 = require("@well-known-components/interfaces");
10
33
  const rooms_1 = require("@dcl/mini-comms/dist/adapters/rooms");
@@ -14,10 +37,12 @@ const logger_1 = require("@well-known-components/logger");
14
37
  const metrics_1 = require("@well-known-components/metrics");
15
38
  const ws_1 = require("./ws");
16
39
  const args_1 = require("../../utils/args");
40
+ const helpers_1 = require("../../commands/build/helpers");
17
41
  const project_1 = require("./project");
18
42
  const port_1 = require("./port");
19
43
  const eth_1 = require("./eth");
20
44
  const wire_1 = require("./wire");
45
+ const error_1 = require("../../utils/error");
21
46
  function help() {
22
47
  return ``;
23
48
  }
@@ -33,6 +58,10 @@ async function main(options) {
33
58
  const dir = (0, path_1.resolve)(process.cwd(), options.args['--dir'] || '.');
34
59
  await (0, project_1.validateExistingProject)(options.components, dir);
35
60
  await (0, project_1.validateSceneOptions)(options.components, dir);
61
+ if (await (0, helpers_1.needsDependencies)(options.components, dir)) {
62
+ const npmModulesPath = path_1.default.resolve(dir, 'node_modules');
63
+ throw new error_1.CliError(`Couldn\'t find ${npmModulesPath}, please run: npm install`);
64
+ }
36
65
  const port = options.args['--port'] || (await (0, port_1.previewPort)());
37
66
  const program = await interfaces_1.Lifecycle.run({
38
67
  async initComponents() {
@@ -40,7 +69,7 @@ async function main(options) {
40
69
  const config = (0, env_config_provider_1.createRecordConfigComponent)(Object.assign({ HTTP_SERVER_PORT: port.toString(), HTTP_SERVER_HOST: '0.0.0.0' }, process.env));
41
70
  const logs = await (0, logger_1.createConsoleLogComponent)({});
42
71
  const ws = await (0, ws_1.createWsComponent)({ logs });
43
- const server = await (0, http_server_1.createServerComponent)({ config, logs, ws: ws.ws }, { cors: {} });
72
+ const server = await (0, http_server_1.createServerComponent)({ config, logs, ws: ws.ws }, {});
44
73
  const rooms = await (0, rooms_1.createRoomsComponent)({
45
74
  metrics,
46
75
  logs,
@@ -68,4 +97,4 @@ async function main(options) {
68
97
  return program;
69
98
  }
70
99
  exports.main = main;
71
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSwrQkFBOEI7QUFDOUIsMERBQThCO0FBQzlCLGtFQUE2RTtBQUM3RSwrREFBd0Y7QUFDeEYsb0ZBQXdGO0FBQ3hGLG9FQUEwRTtBQUMxRSwwREFBeUU7QUFDekUsNERBQTJFO0FBQzNFLDZCQUF3QztBQUd4QywyQ0FBMEM7QUFFMUMsdUNBQXlFO0FBQ3pFLGlDQUFvQztBQUNwQywrQkFBd0M7QUFDeEMsaUNBQTZCO0FBRTdCLFNBQWdCLElBQUk7SUFDbEIsT0FBTyxFQUFFLENBQUE7QUFDWCxDQUFDO0FBRkQsb0JBRUM7QUFPWSxRQUFBLElBQUksR0FBRyxJQUFBLGNBQU8sRUFBQztJQUMxQixTQUFTLEVBQUUsT0FBTztJQUNsQixJQUFJLEVBQUUsU0FBUztJQUNmLE9BQU8sRUFBRSxNQUFNO0lBQ2YsUUFBUSxFQUFFLE1BQU07SUFDaEIsSUFBSSxFQUFFLFFBQVE7Q0FDZixDQUFDLENBQUE7QUFJSyxLQUFLLFVBQVUsSUFBSSxDQUFDLE9BQWdCO0lBQ3pDLE1BQU0sR0FBRyxHQUFHLElBQUEsY0FBTyxFQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFBO0lBQ2hFLE1BQU0sSUFBQSxpQ0FBdUIsRUFBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBQ3RELE1BQU0sSUFBQSw4QkFBb0IsRUFBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBRW5ELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUEsa0JBQVcsR0FBRSxDQUFDLENBQUE7SUFFNUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxzQkFBUyxDQUFDLEdBQUcsQ0FBb0I7UUFDckQsS0FBSyxDQUFDLGNBQWM7WUFDbEIsTUFBTSxPQUFPLEdBQUcsSUFBQSxvQ0FBMEIsRUFBQyxvQkFBWSxDQUFDLENBQUE7WUFDeEQsTUFBTSxNQUFNLEdBQUcsSUFBQSxpREFBMkIsa0JBQ3hDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFDakMsZ0JBQWdCLEVBQUUsU0FBUyxJQUN4QixPQUFPLENBQUMsR0FBRyxFQUNkLENBQUE7WUFDRixNQUFNLElBQUksR0FBRyxNQUFNLElBQUEsa0NBQXlCLEVBQUMsRUFBRSxDQUFDLENBQUE7WUFDaEQsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFBLHNCQUFpQixFQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtZQUM1QyxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsbUNBQXFCLEVBQW9CLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUE7WUFDeEcsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFBLDRCQUFvQixFQUFDO2dCQUN2QyxPQUFPO2dCQUNQLElBQUk7Z0JBQ0osTUFBTTthQUNQLENBQUMsQ0FBQTtZQUVGLE1BQU0sYUFBYSxHQUFHLElBQUEsbUJBQU0sR0FBUSxDQUFBO1lBQ3BDLE1BQU0sUUFBUSxHQUF3QztnQkFDcEQsYUFBYTtnQkFDYixLQUFLLENBQUMsSUFBSTtvQkFHUixhQUFhLENBQUMsT0FBTyxFQUFFLENBQUE7Z0JBQ3pCLENBQUM7YUFDRixDQUFBO1lBRUQsdUNBQ0ssT0FBTyxDQUFDLFVBQVUsS0FDckIsSUFBSSxFQUNKLGdCQUFnQixFQUFFLHNCQUFnQixFQUNsQyxLQUFLO2dCQUNMLE1BQU07Z0JBQ04sT0FBTztnQkFDUCxNQUFNO2dCQUNOLEVBQUU7Z0JBQ0YsUUFBUSxJQUNUO1FBQ0gsQ0FBQztRQUNELEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxVQUFVLEVBQUUsZUFBZSxFQUFFO1lBQ3hDLE1BQU0sSUFBQSxXQUFJLEVBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFBO1lBQ3RELE1BQU0sZUFBZSxFQUFFLENBQUE7UUFDekIsQ0FBQztLQUNGLENBQUMsQ0FBQTtJQUVGLE9BQU8sT0FBTyxDQUFBO0FBQ2hCLENBQUM7QUFyREQsb0JBcURDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVzb2x2ZSB9IGZyb20gJ3BhdGgnXG5pbXBvcnQgZnV0dXJlIGZyb20gJ2ZwLWZ1dHVyZSdcbmltcG9ydCB7IExpZmVjeWNsZSwgSUJhc2VDb21wb25lbnQgfSBmcm9tICdAd2VsbC1rbm93bi1jb21wb25lbnRzL2ludGVyZmFjZXMnXG5pbXBvcnQgeyByb29tc01ldHJpY3MsIGNyZWF0ZVJvb21zQ29tcG9uZW50IH0gZnJvbSAnQGRjbC9taW5pLWNvbW1zL2Rpc3QvYWRhcHRlcnMvcm9vbXMnXG5pbXBvcnQgeyBjcmVhdGVSZWNvcmRDb25maWdDb21wb25lbnQgfSBmcm9tICdAd2VsbC1rbm93bi1jb21wb25lbnRzL2Vudi1jb25maWctcHJvdmlkZXInXG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZXJDb21wb25lbnQgfSBmcm9tICdAd2VsbC1rbm93bi1jb21wb25lbnRzL2h0dHAtc2VydmVyJ1xuaW1wb3J0IHsgY3JlYXRlQ29uc29sZUxvZ0NvbXBvbmVudCB9IGZyb20gJ0B3ZWxsLWtub3duLWNvbXBvbmVudHMvbG9nZ2VyJ1xuaW1wb3J0IHsgY3JlYXRlVGVzdE1ldHJpY3NDb21wb25lbnQgfSBmcm9tICdAd2VsbC1rbm93bi1jb21wb25lbnRzL21ldHJpY3MnXG5pbXBvcnQgeyBjcmVhdGVXc0NvbXBvbmVudCB9IGZyb20gJy4vd3MnXG5cbmltcG9ydCB7IENsaUNvbXBvbmVudHMgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzJ1xuaW1wb3J0IHsgZ2V0QXJncyB9IGZyb20gJy4uLy4uL3V0aWxzL2FyZ3MnXG5pbXBvcnQgeyBJU2lnbmFsZXJDb21wb25lbnQsIFByZXZpZXdDb21wb25lbnRzIH0gZnJvbSAnLi90eXBlcydcbmltcG9ydCB7IHZhbGlkYXRlRXhpc3RpbmdQcm9qZWN0LCB2YWxpZGF0ZVNjZW5lT3B0aW9ucyB9IGZyb20gJy4vcHJvamVjdCdcbmltcG9ydCB7IHByZXZpZXdQb3J0IH0gZnJvbSAnLi9wb3J0J1xuaW1wb3J0IHsgcHJvdmlkZXJJbnN0YW5jZSB9IGZyb20gJy4vZXRoJ1xuaW1wb3J0IHsgd2lyZSB9IGZyb20gJy4vd2lyZSdcblxuZXhwb3J0IGZ1bmN0aW9uIGhlbHAoKSB7XG4gIHJldHVybiBgYFxufVxuXG5pbnRlcmZhY2UgT3B0aW9ucyB7XG4gIGFyZ3M6IE9taXQ8dHlwZW9mIGFyZ3MsICdfJz5cbiAgY29tcG9uZW50czogUGljazxDbGlDb21wb25lbnRzLCAnZmV0Y2gnIHwgJ2ZzJz5cbn1cblxuZXhwb3J0IGNvbnN0IGFyZ3MgPSBnZXRBcmdzKHtcbiAgJy0td2F0Y2gnOiBCb29sZWFuLFxuICAnLXcnOiAnLS13YXRjaCcsXG4gICctLWRpcic6IFN0cmluZyxcbiAgJy0tcG9ydCc6IE51bWJlcixcbiAgJy1wJzogJy0tcG9ydCdcbn0pXG5cbi8vIGNvcHkvcGFzdGUgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZGVjZW50cmFsYW5kL2NsaS9ibG9iLzMyZGU5NmJjZmM0ZWYxYzI2YzU1ODBjNzc2N2FkNmM4Y2FjM2IzNjcvc3JjL2xpYi9EZWNlbnRyYWxhbmQudHNcbi8vIFRPRE86IHJlZmFjdG9yIHRoaXMgc3R1ZmYgY29tcGxldGVseVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1haW4ob3B0aW9uczogT3B0aW9ucykge1xuICBjb25zdCBkaXIgPSByZXNvbHZlKHByb2Nlc3MuY3dkKCksIG9wdGlvbnMuYXJnc1snLS1kaXInXSB8fCAnLicpXG4gIGF3YWl0IHZhbGlkYXRlRXhpc3RpbmdQcm9qZWN0KG9wdGlvbnMuY29tcG9uZW50cywgZGlyKVxuICBhd2FpdCB2YWxpZGF0ZVNjZW5lT3B0aW9ucyhvcHRpb25zLmNvbXBvbmVudHMsIGRpcilcblxuICBjb25zdCBwb3J0ID0gb3B0aW9ucy5hcmdzWyctLXBvcnQnXSB8fCAoYXdhaXQgcHJldmlld1BvcnQoKSlcblxuICBjb25zdCBwcm9ncmFtID0gYXdhaXQgTGlmZWN5Y2xlLnJ1bjxQcmV2aWV3Q29tcG9uZW50cz4oe1xuICAgIGFzeW5jIGluaXRDb21wb25lbnRzKCkge1xuICAgICAgY29uc3QgbWV0cmljcyA9IGNyZWF0ZVRlc3RNZXRyaWNzQ29tcG9uZW50KHJvb21zTWV0cmljcylcbiAgICAgIGNvbnN0IGNvbmZpZyA9IGNyZWF0ZVJlY29yZENvbmZpZ0NvbXBvbmVudCh7XG4gICAgICAgIEhUVFBfU0VSVkVSX1BPUlQ6IHBvcnQudG9TdHJpbmcoKSxcbiAgICAgICAgSFRUUF9TRVJWRVJfSE9TVDogJzAuMC4wLjAnLFxuICAgICAgICAuLi5wcm9jZXNzLmVudlxuICAgICAgfSlcbiAgICAgIGNvbnN0IGxvZ3MgPSBhd2FpdCBjcmVhdGVDb25zb2xlTG9nQ29tcG9uZW50KHt9KVxuICAgICAgY29uc3Qgd3MgPSBhd2FpdCBjcmVhdGVXc0NvbXBvbmVudCh7IGxvZ3MgfSlcbiAgICAgIGNvbnN0IHNlcnZlciA9IGF3YWl0IGNyZWF0ZVNlcnZlckNvbXBvbmVudDxQcmV2aWV3Q29tcG9uZW50cz4oeyBjb25maWcsIGxvZ3MsIHdzOiB3cy53cyB9LCB7IGNvcnM6IHt9IH0pXG4gICAgICBjb25zdCByb29tcyA9IGF3YWl0IGNyZWF0ZVJvb21zQ29tcG9uZW50KHtcbiAgICAgICAgbWV0cmljcyxcbiAgICAgICAgbG9ncyxcbiAgICAgICAgY29uZmlnXG4gICAgICB9KVxuXG4gICAgICBjb25zdCBwcm9ncmFtQ2xvc2VkID0gZnV0dXJlPHZvaWQ+KClcbiAgICAgIGNvbnN0IHNpZ25hbGVyOiBJQmFzZUNvbXBvbmVudCAmIElTaWduYWxlckNvbXBvbmVudCA9IHtcbiAgICAgICAgcHJvZ3JhbUNsb3NlZCxcbiAgICAgICAgYXN5bmMgc3RvcCgpIHtcbiAgICAgICAgICAvLyB0aGlzIHByb21pc2UgaXMgcmVzb2x2ZWQgdXBvbiBTSUdURVJNIG9yIFNJR0hVUFxuICAgICAgICAgIC8vIG9yIHdoZW4gcHJvZ3JhbS5zdG9wIGlzIGNhbGxlZFxuICAgICAgICAgIHByb2dyYW1DbG9zZWQucmVzb2x2ZSgpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ub3B0aW9ucy5jb21wb25lbnRzLFxuICAgICAgICBsb2dzLFxuICAgICAgICBldGhlcmV1bVByb3ZpZGVyOiBwcm92aWRlckluc3RhbmNlLFxuICAgICAgICByb29tcyxcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBtZXRyaWNzLFxuICAgICAgICBzZXJ2ZXIsXG4gICAgICAgIHdzLFxuICAgICAgICBzaWduYWxlclxuICAgICAgfVxuICAgIH0sXG4gICAgYXN5bmMgbWFpbih7IGNvbXBvbmVudHMsIHN0YXJ0Q29tcG9uZW50cyB9KSB7XG4gICAgICBhd2FpdCB3aXJlKGNvbXBvbmVudHMsIGRpciwgISFvcHRpb25zLmFyZ3NbJy0td2F0Y2gnXSlcbiAgICAgIGF3YWl0IHN0YXJ0Q29tcG9uZW50cygpXG4gICAgfVxuICB9KVxuXG4gIHJldHVybiBwcm9ncmFtXG59XG4iXX0=
100
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDZDQUFvQztBQUNwQywwREFBOEI7QUFDOUIsa0VBQTZFO0FBQzdFLCtEQUF3RjtBQUN4RixvRkFBd0Y7QUFDeEYsb0VBQTBFO0FBQzFFLDBEQUF5RTtBQUN6RSw0REFBMkU7QUFDM0UsNkJBQXdDO0FBR3hDLDJDQUEwQztBQUMxQywwREFBZ0U7QUFFaEUsdUNBQXlFO0FBQ3pFLGlDQUFvQztBQUNwQywrQkFBd0M7QUFDeEMsaUNBQTZCO0FBQzdCLDZDQUE0QztBQUU1QyxTQUFnQixJQUFJO0lBQ2xCLE9BQU8sRUFBRSxDQUFBO0FBQ1gsQ0FBQztBQUZELG9CQUVDO0FBT1ksUUFBQSxJQUFJLEdBQUcsSUFBQSxjQUFPLEVBQUM7SUFDMUIsU0FBUyxFQUFFLE9BQU87SUFDbEIsSUFBSSxFQUFFLFNBQVM7SUFDZixPQUFPLEVBQUUsTUFBTTtJQUNmLFFBQVEsRUFBRSxNQUFNO0lBQ2hCLElBQUksRUFBRSxRQUFRO0NBQ2YsQ0FBQyxDQUFBO0FBSUssS0FBSyxVQUFVLElBQUksQ0FBQyxPQUFnQjtJQUN6QyxNQUFNLEdBQUcsR0FBRyxJQUFBLGNBQU8sRUFBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQTtJQUNoRSxNQUFNLElBQUEsaUNBQXVCLEVBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUN0RCxNQUFNLElBQUEsOEJBQW9CLEVBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUVuRCxJQUFJLE1BQU0sSUFBQSwyQkFBaUIsRUFBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxFQUFFO1FBQ3BELE1BQU0sY0FBYyxHQUFHLGNBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQyxDQUFBO1FBQ3hELE1BQU0sSUFBSSxnQkFBUSxDQUFDLGtCQUFrQixjQUFjLDJCQUEyQixDQUFDLENBQUE7S0FDaEY7SUFFRCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFBLGtCQUFXLEdBQUUsQ0FBQyxDQUFBO0lBRTVELE1BQU0sT0FBTyxHQUFHLE1BQU0sc0JBQVMsQ0FBQyxHQUFHLENBQW9CO1FBQ3JELEtBQUssQ0FBQyxjQUFjO1lBQ2xCLE1BQU0sT0FBTyxHQUFHLElBQUEsb0NBQTBCLEVBQUMsb0JBQVksQ0FBQyxDQUFBO1lBQ3hELE1BQU0sTUFBTSxHQUFHLElBQUEsaURBQTJCLGtCQUN4QyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQ2pDLGdCQUFnQixFQUFFLFNBQVMsSUFDeEIsT0FBTyxDQUFDLEdBQUcsRUFDZCxDQUFBO1lBQ0YsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFBLGtDQUF5QixFQUFDLEVBQUUsQ0FBQyxDQUFBO1lBQ2hELE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSxzQkFBaUIsRUFBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7WUFDNUMsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFBLG1DQUFxQixFQUFvQixFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQTtZQUM5RixNQUFNLEtBQUssR0FBRyxNQUFNLElBQUEsNEJBQW9CLEVBQUM7Z0JBQ3ZDLE9BQU87Z0JBQ1AsSUFBSTtnQkFDSixNQUFNO2FBQ1AsQ0FBQyxDQUFBO1lBRUYsTUFBTSxhQUFhLEdBQUcsSUFBQSxtQkFBTSxHQUFRLENBQUE7WUFDcEMsTUFBTSxRQUFRLEdBQXdDO2dCQUNwRCxhQUFhO2dCQUNiLEtBQUssQ0FBQyxJQUFJO29CQUdSLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQTtnQkFDekIsQ0FBQzthQUNGLENBQUE7WUFFRCx1Q0FDSyxPQUFPLENBQUMsVUFBVSxLQUNyQixJQUFJLEVBQ0osZ0JBQWdCLEVBQUUsc0JBQWdCLEVBQ2xDLEtBQUs7Z0JBQ0wsTUFBTTtnQkFDTixPQUFPO2dCQUNQLE1BQU07Z0JBQ04sRUFBRTtnQkFDRixRQUFRLElBQ1Q7UUFDSCxDQUFDO1FBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQUU7WUFDeEMsTUFBTSxJQUFBLFdBQUksRUFBQyxVQUFVLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUE7WUFDdEQsTUFBTSxlQUFlLEVBQUUsQ0FBQTtRQUN6QixDQUFDO0tBQ0YsQ0FBQyxDQUFBO0lBRUYsT0FBTyxPQUFPLENBQUE7QUFDaEIsQ0FBQztBQTFERCxvQkEwREMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCwgeyByZXNvbHZlIH0gZnJvbSAncGF0aCdcbmltcG9ydCBmdXR1cmUgZnJvbSAnZnAtZnV0dXJlJ1xuaW1wb3J0IHsgTGlmZWN5Y2xlLCBJQmFzZUNvbXBvbmVudCB9IGZyb20gJ0B3ZWxsLWtub3duLWNvbXBvbmVudHMvaW50ZXJmYWNlcydcbmltcG9ydCB7IHJvb21zTWV0cmljcywgY3JlYXRlUm9vbXNDb21wb25lbnQgfSBmcm9tICdAZGNsL21pbmktY29tbXMvZGlzdC9hZGFwdGVycy9yb29tcydcbmltcG9ydCB7IGNyZWF0ZVJlY29yZENvbmZpZ0NvbXBvbmVudCB9IGZyb20gJ0B3ZWxsLWtub3duLWNvbXBvbmVudHMvZW52LWNvbmZpZy1wcm92aWRlcidcbmltcG9ydCB7IGNyZWF0ZVNlcnZlckNvbXBvbmVudCB9IGZyb20gJ0B3ZWxsLWtub3duLWNvbXBvbmVudHMvaHR0cC1zZXJ2ZXInXG5pbXBvcnQgeyBjcmVhdGVDb25zb2xlTG9nQ29tcG9uZW50IH0gZnJvbSAnQHdlbGwta25vd24tY29tcG9uZW50cy9sb2dnZXInXG5pbXBvcnQgeyBjcmVhdGVUZXN0TWV0cmljc0NvbXBvbmVudCB9IGZyb20gJ0B3ZWxsLWtub3duLWNvbXBvbmVudHMvbWV0cmljcydcbmltcG9ydCB7IGNyZWF0ZVdzQ29tcG9uZW50IH0gZnJvbSAnLi93cydcblxuaW1wb3J0IHsgQ2xpQ29tcG9uZW50cyB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMnXG5pbXBvcnQgeyBnZXRBcmdzIH0gZnJvbSAnLi4vLi4vdXRpbHMvYXJncydcbmltcG9ydCB7IG5lZWRzRGVwZW5kZW5jaWVzIH0gZnJvbSAnLi4vLi4vY29tbWFuZHMvYnVpbGQvaGVscGVycydcbmltcG9ydCB7IElTaWduYWxlckNvbXBvbmVudCwgUHJldmlld0NvbXBvbmVudHMgfSBmcm9tICcuL3R5cGVzJ1xuaW1wb3J0IHsgdmFsaWRhdGVFeGlzdGluZ1Byb2plY3QsIHZhbGlkYXRlU2NlbmVPcHRpb25zIH0gZnJvbSAnLi9wcm9qZWN0J1xuaW1wb3J0IHsgcHJldmlld1BvcnQgfSBmcm9tICcuL3BvcnQnXG5pbXBvcnQgeyBwcm92aWRlckluc3RhbmNlIH0gZnJvbSAnLi9ldGgnXG5pbXBvcnQgeyB3aXJlIH0gZnJvbSAnLi93aXJlJ1xuaW1wb3J0IHsgQ2xpRXJyb3IgfSBmcm9tICcuLi8uLi91dGlscy9lcnJvcidcblxuZXhwb3J0IGZ1bmN0aW9uIGhlbHAoKSB7XG4gIHJldHVybiBgYFxufVxuXG5pbnRlcmZhY2UgT3B0aW9ucyB7XG4gIGFyZ3M6IE9taXQ8dHlwZW9mIGFyZ3MsICdfJz5cbiAgY29tcG9uZW50czogUGljazxDbGlDb21wb25lbnRzLCAnZmV0Y2gnIHwgJ2ZzJz5cbn1cblxuZXhwb3J0IGNvbnN0IGFyZ3MgPSBnZXRBcmdzKHtcbiAgJy0td2F0Y2gnOiBCb29sZWFuLFxuICAnLXcnOiAnLS13YXRjaCcsXG4gICctLWRpcic6IFN0cmluZyxcbiAgJy0tcG9ydCc6IE51bWJlcixcbiAgJy1wJzogJy0tcG9ydCdcbn0pXG5cbi8vIGNvcHkvcGFzdGUgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZGVjZW50cmFsYW5kL2NsaS9ibG9iLzMyZGU5NmJjZmM0ZWYxYzI2YzU1ODBjNzc2N2FkNmM4Y2FjM2IzNjcvc3JjL2xpYi9EZWNlbnRyYWxhbmQudHNcbi8vIFRPRE86IHJlZmFjdG9yIHRoaXMgc3R1ZmYgY29tcGxldGVseVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1haW4ob3B0aW9uczogT3B0aW9ucykge1xuICBjb25zdCBkaXIgPSByZXNvbHZlKHByb2Nlc3MuY3dkKCksIG9wdGlvbnMuYXJnc1snLS1kaXInXSB8fCAnLicpXG4gIGF3YWl0IHZhbGlkYXRlRXhpc3RpbmdQcm9qZWN0KG9wdGlvbnMuY29tcG9uZW50cywgZGlyKVxuICBhd2FpdCB2YWxpZGF0ZVNjZW5lT3B0aW9ucyhvcHRpb25zLmNvbXBvbmVudHMsIGRpcilcblxuICBpZiAoYXdhaXQgbmVlZHNEZXBlbmRlbmNpZXMob3B0aW9ucy5jb21wb25lbnRzLCBkaXIpKSB7XG4gICAgY29uc3QgbnBtTW9kdWxlc1BhdGggPSBwYXRoLnJlc29sdmUoZGlyLCAnbm9kZV9tb2R1bGVzJylcbiAgICB0aHJvdyBuZXcgQ2xpRXJyb3IoYENvdWxkblxcJ3QgZmluZCAke25wbU1vZHVsZXNQYXRofSwgcGxlYXNlIHJ1bjogbnBtIGluc3RhbGxgKVxuICB9XG5cbiAgY29uc3QgcG9ydCA9IG9wdGlvbnMuYXJnc1snLS1wb3J0J10gfHwgKGF3YWl0IHByZXZpZXdQb3J0KCkpXG5cbiAgY29uc3QgcHJvZ3JhbSA9IGF3YWl0IExpZmVjeWNsZS5ydW48UHJldmlld0NvbXBvbmVudHM+KHtcbiAgICBhc3luYyBpbml0Q29tcG9uZW50cygpIHtcbiAgICAgIGNvbnN0IG1ldHJpY3MgPSBjcmVhdGVUZXN0TWV0cmljc0NvbXBvbmVudChyb29tc01ldHJpY3MpXG4gICAgICBjb25zdCBjb25maWcgPSBjcmVhdGVSZWNvcmRDb25maWdDb21wb25lbnQoe1xuICAgICAgICBIVFRQX1NFUlZFUl9QT1JUOiBwb3J0LnRvU3RyaW5nKCksXG4gICAgICAgIEhUVFBfU0VSVkVSX0hPU1Q6ICcwLjAuMC4wJyxcbiAgICAgICAgLi4ucHJvY2Vzcy5lbnZcbiAgICAgIH0pXG4gICAgICBjb25zdCBsb2dzID0gYXdhaXQgY3JlYXRlQ29uc29sZUxvZ0NvbXBvbmVudCh7fSlcbiAgICAgIGNvbnN0IHdzID0gYXdhaXQgY3JlYXRlV3NDb21wb25lbnQoeyBsb2dzIH0pXG4gICAgICBjb25zdCBzZXJ2ZXIgPSBhd2FpdCBjcmVhdGVTZXJ2ZXJDb21wb25lbnQ8UHJldmlld0NvbXBvbmVudHM+KHsgY29uZmlnLCBsb2dzLCB3czogd3Mud3MgfSwge30pXG4gICAgICBjb25zdCByb29tcyA9IGF3YWl0IGNyZWF0ZVJvb21zQ29tcG9uZW50KHtcbiAgICAgICAgbWV0cmljcyxcbiAgICAgICAgbG9ncyxcbiAgICAgICAgY29uZmlnXG4gICAgICB9KVxuXG4gICAgICBjb25zdCBwcm9ncmFtQ2xvc2VkID0gZnV0dXJlPHZvaWQ+KClcbiAgICAgIGNvbnN0IHNpZ25hbGVyOiBJQmFzZUNvbXBvbmVudCAmIElTaWduYWxlckNvbXBvbmVudCA9IHtcbiAgICAgICAgcHJvZ3JhbUNsb3NlZCxcbiAgICAgICAgYXN5bmMgc3RvcCgpIHtcbiAgICAgICAgICAvLyB0aGlzIHByb21pc2UgaXMgcmVzb2x2ZWQgdXBvbiBTSUdURVJNIG9yIFNJR0hVUFxuICAgICAgICAgIC8vIG9yIHdoZW4gcHJvZ3JhbS5zdG9wIGlzIGNhbGxlZFxuICAgICAgICAgIHByb2dyYW1DbG9zZWQucmVzb2x2ZSgpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ub3B0aW9ucy5jb21wb25lbnRzLFxuICAgICAgICBsb2dzLFxuICAgICAgICBldGhlcmV1bVByb3ZpZGVyOiBwcm92aWRlckluc3RhbmNlLFxuICAgICAgICByb29tcyxcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBtZXRyaWNzLFxuICAgICAgICBzZXJ2ZXIsXG4gICAgICAgIHdzLFxuICAgICAgICBzaWduYWxlclxuICAgICAgfVxuICAgIH0sXG4gICAgYXN5bmMgbWFpbih7IGNvbXBvbmVudHMsIHN0YXJ0Q29tcG9uZW50cyB9KSB7XG4gICAgICBhd2FpdCB3aXJlKGNvbXBvbmVudHMsIGRpciwgISFvcHRpb25zLmFyZ3NbJy0td2F0Y2gnXSlcbiAgICAgIGF3YWl0IHN0YXJ0Q29tcG9uZW50cygpXG4gICAgfVxuICB9KVxuXG4gIHJldHVybiBwcm9ncmFtXG59XG4iXX0=
@@ -1,4 +1,4 @@
1
- import { resolve } from 'path'
1
+ import path, { resolve } from 'path'
2
2
  import future from 'fp-future'
3
3
  import { Lifecycle, IBaseComponent } from '@well-known-components/interfaces'
4
4
  import { roomsMetrics, createRoomsComponent } from '@dcl/mini-comms/dist/adapters/rooms'
@@ -10,11 +10,13 @@ import { createWsComponent } from './ws'
10
10
 
11
11
  import { CliComponents } from '../../components'
12
12
  import { getArgs } from '../../utils/args'
13
+ import { needsDependencies } from '../../commands/build/helpers'
13
14
  import { ISignalerComponent, PreviewComponents } from './types'
14
15
  import { validateExistingProject, validateSceneOptions } from './project'
15
16
  import { previewPort } from './port'
16
17
  import { providerInstance } from './eth'
17
18
  import { wire } from './wire'
19
+ import { CliError } from '../../utils/error'
18
20
 
19
21
  export function help() {
20
22
  return ``
@@ -40,6 +42,11 @@ export async function main(options: Options) {
40
42
  await validateExistingProject(options.components, dir)
41
43
  await validateSceneOptions(options.components, dir)
42
44
 
45
+ if (await needsDependencies(options.components, dir)) {
46
+ const npmModulesPath = path.resolve(dir, 'node_modules')
47
+ throw new CliError(`Couldn\'t find ${npmModulesPath}, please run: npm install`)
48
+ }
49
+
43
50
  const port = options.args['--port'] || (await previewPort())
44
51
 
45
52
  const program = await Lifecycle.run<PreviewComponents>({
@@ -52,7 +59,7 @@ export async function main(options: Options) {
52
59
  })
53
60
  const logs = await createConsoleLogComponent({})
54
61
  const ws = await createWsComponent({ logs })
55
- const server = await createServerComponent<PreviewComponents>({ config, logs, ws: ws.ws }, { cors: {} })
62
+ const server = await createServerComponent<PreviewComponents>({ config, logs, ws: ws.ws }, {})
56
63
  const rooms = await createRoomsComponent({
57
64
  metrics,
58
65
  logs,
@@ -68,10 +68,10 @@ async function validateExistingProject(components, dir) {
68
68
  if (!isValidMainFormat(sceneFile.main)) {
69
69
  throw new error_1.CliError(`Main scene format file (${sceneFile.main}) is not a supported format`);
70
70
  }
71
- if (sceneFile.main !== null && !(await components.fs.existPath((0, path_1.resolve)(dir, sceneFile.main)))) {
71
+ if (sceneFile.main !== null && !(await components.fs.fileExists((0, path_1.resolve)(dir, sceneFile.main)))) {
72
72
  throw new error_1.CliError(`Main scene file ${sceneFile.main} is missing in folder ${dir}`);
73
73
  }
74
74
  }
75
75
  }
76
76
  exports.validateExistingProject = validateExistingProject;
77
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvamVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInByb2plY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0JBQThCO0FBRzlCLDZDQUE0QztBQUM1QywrQ0FBNEU7QUFHL0QsUUFBQSxVQUFVLEdBQUcsWUFBWSxDQUFBO0FBTXRDLFNBQVMsV0FBVyxDQUFDLEdBQVc7SUFDOUIsT0FBTyxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQ2pDLENBQUM7QUFNRCxTQUFTLGlCQUFpQixDQUFDLElBQW1CO0lBQzVDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUE7SUFDMUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7SUFDbkQsT0FBTyxJQUFJLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQTtBQUN6RSxDQUFDO0FBTUQsU0FBZ0IsZ0JBQWdCLENBQUMsR0FBVztJQUMxQyxPQUFPLElBQUEsY0FBTyxFQUFDLEdBQUcsRUFBRSxrQkFBVSxDQUFDLENBQUE7QUFDakMsQ0FBQztBQUZELDRDQUVDO0FBS00sS0FBSyxVQUFVLFlBQVksQ0FBQyxVQUF3QyxFQUFFLEdBQVc7SUFDdEYsSUFBSTtRQUNGLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxVQUFVLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFBO1FBQzFGLE9BQU8sU0FBeUIsQ0FBQTtLQUNqQztJQUFDLE9BQU8sQ0FB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cm9tICdwYXRoJ1xuaW1wb3J0IHsgU2NlbmUgfSBmcm9tICdAZGNsL3NjaGVtYXMnXG5cbmltcG9ydCB7IENsaUVycm9yIH0gZnJvbSAnLi4vLi4vdXRpbHMvZXJyb3InXG5pbXBvcnQgeyBnZXRPYmplY3QsIGluQm91bmRzLCBnZXRCb3VuZHMsIGFyZUNvbm5lY3RlZCB9IGZyb20gJy4vY29vcmRpbmF0ZXMnXG5pbXBvcnQgeyBJRmlsZVN5c3RlbUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvZnMnXG5cbmV4cG9ydCBjb25zdCBTQ0VORV9GSUxFID0gJ3NjZW5lLmpzb24nXG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBVUkwgaXMgYSB2YWxpZCB3ZWJzb2NrZXQgVVJMLlxuICogQHBhcmFtIHVybCBUaGUgZ2l2ZW4gVVJMLlxuICovXG5mdW5jdGlvbiBpc1dlYlNvY2tldCh1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gL3dzcz9cXDpcXC9cXC8vZ2kudGVzdCh1cmwpXG59XG5cbi8qKlxuICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb3ZpZGVkIHBhdGggY29udGFpbnMgYSB2YWxpZCBtYWluIGZpbGUgZm9ybWF0LlxuICogQHBhcmFtIHBhdGggVGhlIHBhdGggdG8gdGhlIG1haW4gZmlsZS5cbiAqL1xuZnVuY3Rpb24gaXNWYWxpZE1haW5Gb3JtYXQocGF0aDogc3RyaW5nIHwgbnVsbCk6IGJvb2xlYW4ge1xuICBjb25zdCBzdXBwb3J0ZWRFeHRlbnNpb25zID0gbmV3IFNldChbJ2pzJywgJ2h0bWwnLCAneG1sJ10pXG4gIGNvbnN0IG1haW5FeHQgPSBwYXRoID8gcGF0aC5zcGxpdCgnLicpLnBvcCgpIDogbnVsbFxuICByZXR1cm4gcGF0aCA9PT0gbnVsbCB8fCAhIShtYWluRXh0ICYmIHN1cHBvcnRlZEV4dGVuc2lvbnMuaGFzKG1haW5FeHQpKVxufVxuXG4vKipcbiAqIENvbXBvc2VzIHRoZSBwYXRoIHRvIHRoZSBgc2NlbmUuanNvbmAgZmlsZSBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgcGF0aC5cbiAqIEBwYXJhbSBkaXIgVGhlIHBhdGggdG8gdGhlIGRpcmVjdG9yeSBjb250YWluaW5nIHRoZSBzY2VuZSBmaWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2NlbmVGaWxlUGF0aChkaXI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiByZXNvbHZlKGRpciwgU0NFTkVfRklMRSlcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBjb250ZW50cyBvZiB0aGUgYHNjZW5lLmpzb25gIGZpbGUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRTY2VuZUZpbGUoY29tcG9uZW50czogeyBmczogSUZpbGVTeXN0ZW1Db21wb25lbnQgfSwgZGlyOiBzdHJpbmcpOiBQcm9taXNlPFNjZW5lPiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc2NlbmVGaWxlID0gSlNPTi5wYXJzZShhd2FpdCBjb21wb25lbnRzLmZzLnJlYWRGaWxlKGdldFNjZW5lRmlsZVBhdGgoZGlyKSwgJ3V0Zi04JykpXG4gICAgcmV0dXJuIHNjZW5lRmlsZSBhcyBhbnkgYXMgU2NlbmVcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBDbGlFcnJvcihgVW5hYmxlIHRvIHJlYWQgJ3NjZW5lLmpzb24nIGZpbGUuIFRyeSBpbml0aWFsaXppbmcgdGhlIHByb2plY3QgdXNpbmcgJ2RjbCBpbml0Jy5cbiAgICAgICAgXFx0ID4gRm9sZGVyOiAke2Rpcn1cbiAgICAgICAgYClcbiAgfVxufVxuXG4vKipcbiAqIEZhaWxzIHRoZSBleGVjdXRpb24gaWYgb25lIG9mIHRoZSBwYXJjZWwgZGF0YSBpcyBpbnZhbGlkXG4gKiBAcGFyYW0gc2NlbmVGaWxlIFRoZSBKU09OIHBhcnNlZCBmaWxlIG9mIHNjZW5lLmpzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlU2NlbmVEYXRhKHNjZW5lRmlsZTogU2NlbmUpOiB2b2lkIHtcbiAgY29uc3QgeyBiYXNlLCBwYXJjZWxzIH0gPSBzY2VuZUZpbGUuc2NlbmVcbiAgY29uc3QgcGFyY2VsU2V0ID0gbmV3IFNldChwYXJjZWxzKVxuXG4gIGlmICghYmFzZSkge1xuICAgIHRocm93IG5ldyBDbGlFcnJvcignTWlzc2luZyBzY2VuZSBiYXNlIGF0dHJpYnV0ZSBhdCBzY2VuZS5qc29uJylcbiAgfVxuXG4gIGlmICghcGFyY2Vscykge1xuICAgIHRocm93IG5ldyBDbGlFcnJvcignTWlzc2luZyBzY2VuZSBwYXJjZWxzIGF0dHJpYnV0ZSBhdCBzY2VuZS5qc29uJylcbiAgfVxuXG4gIGlmIChwYXJjZWxTZXQuc2l6ZSA8IHBhcmNlbHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IENsaUVycm9yKGBUaGVyZSBhcmUgZHVwbGljYXRlZCBwYXJjZWxzIGF0IHNjZW5lLmpzb24uYClcbiAgfVxuXG4gIGlmICghcGFyY2VsU2V0LmhhcyhiYXNlKSkge1xuICAgIHRocm93IG5ldyBDbGlFcnJvcihgWW91ciBiYXNlIHBhcmNlbCAke2Jhc2V9IHNob3VsZCBiZSBpbmNsdWRlZCBvbiBwYXJjZWxzIGF0dHJpYnV0ZSBhdCBzY2VuZS5qc29uYClcbiAgfVxuXG4gIGNvbnN0IG9ialBhcmNlbHMgPSBwYXJjZWxzLm1hcChnZXRPYmplY3QpXG4gIG9ialBhcmNlbHMuZm9yRWFjaCgoeyB4LCB5IH0pID0+IHtcbiAgICBpZiAoaW5Cb3VuZHMoeCwgeSkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjb25zdCB7IG1pblgsIG1heFggfSA9IGdldEJvdW5kcygpXG4gICAgdGhyb3cgbmV3IENsaUVycm9yKGBDb29yZGluYXRlcyAke3h9LCR7eX0gYXJlIG91dHNpZGUgb2YgYWxsb3dlZCBsaW1pdHMgKGZyb20gJHttaW5YfSB0byAke21heFh9KWApXG4gIH0pXG5cbiAgaWYgKCFhcmVDb25uZWN0ZWQob2JqUGFyY2VscykpIHtcbiAgICB0aHJvdyBuZXcgQ2xpRXJyb3IoJ1BhcmNlbHMgZGVzY3JpYmVkIG9uIHNjZW5lLmpzb24gYXJlIG5vdCBjb25uZWN0ZWQuIFRoZXkgc2hvdWxkIGJlIG9uZSBuZXh0IHRvIGVhY2ggb3RoZXInKVxuICB9XG59XG5cbi8qKlxuICogRmFpbHMgdGhlIGV4ZWN1dGlvbiBpZiBvbmUgb2YgdGhlIHBhcmNlbCBkYXRhIGlzIGludmFsaWRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlU2NlbmVPcHRpb25zKGNvbXBvbmVudHM6IHsgZnM6IElGaWxlU3lzdGVtQ29tcG9uZW50IH0sIGRpcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHNjZW5lRmlsZSA9IGF3YWl0IGdldFNjZW5lRmlsZShjb21wb25lbnRzLCBkaXIpXG4gIHJldHVybiB2YWxpZGF0ZVNjZW5lRGF0YShzY2VuZUZpbGUpXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIGFsbCB0aGUgY29uZGl0aW9ucyByZXF1aXJlZCB0byBvcGVyYXRlIG92ZXIgYW4gZXhpc3RpbmcgcHJvamVjdC5cbiAqIFRocm93cyBpZiBhIHByb2plY3QgY29udGFpbnMgYW4gaW52YWxpZCBtYWluIHBhdGggb3IgaWYgdGhlIGBzY2VuZS5qc29uYCBmaWxlIGlzIG1pc3NpbmcuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB2YWxpZGF0ZUV4aXN0aW5nUHJvamVjdChjb21wb25lbnRzOiB7IGZzOiBJRmlsZVN5c3RlbUNvbXBvbmVudCB9LCBkaXI6IHN0cmluZykge1xuICBjb25zdCBzY2VuZUZpbGUgPSBhd2FpdCBnZXRTY2VuZUZpbGUoY29tcG9uZW50cywgZGlyKVxuXG4gIGlmICghaXNXZWJTb2NrZXQoc2NlbmVGaWxlLm1haW4pKSB7XG4gICAgaWYgKCFpc1ZhbGlkTWFpbkZvcm1hdChzY2VuZUZpbGUubWFpbikpIHtcbiAgICAgIHRocm93IG5ldyBDbGlFcnJvcihgTWFpbiBzY2VuZSBmb3JtYXQgZmlsZSAoJHtzY2VuZUZpbGUubWFpbn0pIGlzIG5vdCBhIHN1cHBvcnRlZCBmb3JtYXRgKVxuICAgIH1cblxuICAgIGlmIChzY2VuZUZpbGUubWFpbiAhPT0gbnVsbCAmJiAhKGF3YWl0IGNvbXBvbmVudHMuZnMuZXhpc3RQYXRoKHJlc29sdmUoZGlyLCBzY2VuZUZpbGUubWFpbikpKSkge1xuICAgICAgdGhyb3cgbmV3IENsaUVycm9yKGBNYWluIHNjZW5lIGZpbGUgJHtzY2VuZUZpbGUubWFpbn0gaXMgbWlzc2luZyBpbiBmb2xkZXIgJHtkaXJ9YClcbiAgICB9XG4gIH1cbn1cbiJdfQ==
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvamVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInByb2plY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0JBQThCO0FBRzlCLDZDQUE0QztBQUM1QywrQ0FBNEU7QUFHL0QsUUFBQSxVQUFVLEdBQUcsWUFBWSxDQUFBO0FBTXRDLFNBQVMsV0FBVyxDQUFDLEdBQVc7SUFDOUIsT0FBTyxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQ2pDLENBQUM7QUFNRCxTQUFTLGlCQUFpQixDQUFDLElBQW1CO0lBQzVDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUE7SUFDMUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7SUFDbkQsT0FBTyxJQUFJLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQTtBQUN6RSxDQUFDO0FBTUQsU0FBZ0IsZ0JBQWdCLENBQUMsR0FBVztJQUMxQyxPQUFPLElBQUEsY0FBTyxFQUFDLEdBQUcsRUFBRSxrQkFBVSxDQUFDLENBQUE7QUFDakMsQ0FBQztBQUZELDRDQUVDO0FBS00sS0FBSyxVQUFVLFlBQVksQ0FBQyxVQUF3QyxFQUFFLEdBQVc7SUFDdEYsSUFBSTtRQUNGLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxVQUFVLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFBO1FBQzFGLE9BQU8sU0FBeUIsQ0FBQTtLQUNqQztJQUFDLE9BQU8sQ0FB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cm9tICdwYXRoJ1xuaW1wb3J0IHsgU2NlbmUgfSBmcm9tICdAZGNsL3NjaGVtYXMnXG5cbmltcG9ydCB7IENsaUVycm9yIH0gZnJvbSAnLi4vLi4vdXRpbHMvZXJyb3InXG5pbXBvcnQgeyBnZXRPYmplY3QsIGluQm91bmRzLCBnZXRCb3VuZHMsIGFyZUNvbm5lY3RlZCB9IGZyb20gJy4vY29vcmRpbmF0ZXMnXG5pbXBvcnQgeyBJRmlsZVN5c3RlbUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvZnMnXG5cbmV4cG9ydCBjb25zdCBTQ0VORV9GSUxFID0gJ3NjZW5lLmpzb24nXG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBVUkwgaXMgYSB2YWxpZCB3ZWJzb2NrZXQgVVJMLlxuICogQHBhcmFtIHVybCBUaGUgZ2l2ZW4gVVJMLlxuICovXG5mdW5jdGlvbiBpc1dlYlNvY2tldCh1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gL3dzcz9cXDpcXC9cXC8vZ2kudGVzdCh1cmwpXG59XG5cbi8qKlxuICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb3ZpZGVkIHBhdGggY29udGFpbnMgYSB2YWxpZCBtYWluIGZpbGUgZm9ybWF0LlxuICogQHBhcmFtIHBhdGggVGhlIHBhdGggdG8gdGhlIG1haW4gZmlsZS5cbiAqL1xuZnVuY3Rpb24gaXNWYWxpZE1haW5Gb3JtYXQocGF0aDogc3RyaW5nIHwgbnVsbCk6IGJvb2xlYW4ge1xuICBjb25zdCBzdXBwb3J0ZWRFeHRlbnNpb25zID0gbmV3IFNldChbJ2pzJywgJ2h0bWwnLCAneG1sJ10pXG4gIGNvbnN0IG1haW5FeHQgPSBwYXRoID8gcGF0aC5zcGxpdCgnLicpLnBvcCgpIDogbnVsbFxuICByZXR1cm4gcGF0aCA9PT0gbnVsbCB8fCAhIShtYWluRXh0ICYmIHN1cHBvcnRlZEV4dGVuc2lvbnMuaGFzKG1haW5FeHQpKVxufVxuXG4vKipcbiAqIENvbXBvc2VzIHRoZSBwYXRoIHRvIHRoZSBgc2NlbmUuanNvbmAgZmlsZSBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgcGF0aC5cbiAqIEBwYXJhbSBkaXIgVGhlIHBhdGggdG8gdGhlIGRpcmVjdG9yeSBjb250YWluaW5nIHRoZSBzY2VuZSBmaWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2NlbmVGaWxlUGF0aChkaXI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiByZXNvbHZlKGRpciwgU0NFTkVfRklMRSlcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBjb250ZW50cyBvZiB0aGUgYHNjZW5lLmpzb25gIGZpbGUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRTY2VuZUZpbGUoY29tcG9uZW50czogeyBmczogSUZpbGVTeXN0ZW1Db21wb25lbnQgfSwgZGlyOiBzdHJpbmcpOiBQcm9taXNlPFNjZW5lPiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc2NlbmVGaWxlID0gSlNPTi5wYXJzZShhd2FpdCBjb21wb25lbnRzLmZzLnJlYWRGaWxlKGdldFNjZW5lRmlsZVBhdGgoZGlyKSwgJ3V0Zi04JykpXG4gICAgcmV0dXJuIHNjZW5lRmlsZSBhcyBhbnkgYXMgU2NlbmVcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBDbGlFcnJvcihgVW5hYmxlIHRvIHJlYWQgJ3NjZW5lLmpzb24nIGZpbGUuIFRyeSBpbml0aWFsaXppbmcgdGhlIHByb2plY3QgdXNpbmcgJ2RjbCBpbml0Jy5cbiAgICAgICAgXFx0ID4gRm9sZGVyOiAke2Rpcn1cbiAgICAgICAgYClcbiAgfVxufVxuXG4vKipcbiAqIEZhaWxzIHRoZSBleGVjdXRpb24gaWYgb25lIG9mIHRoZSBwYXJjZWwgZGF0YSBpcyBpbnZhbGlkXG4gKiBAcGFyYW0gc2NlbmVGaWxlIFRoZSBKU09OIHBhcnNlZCBmaWxlIG9mIHNjZW5lLmpzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlU2NlbmVEYXRhKHNjZW5lRmlsZTogU2NlbmUpOiB2b2lkIHtcbiAgY29uc3QgeyBiYXNlLCBwYXJjZWxzIH0gPSBzY2VuZUZpbGUuc2NlbmVcbiAgY29uc3QgcGFyY2VsU2V0ID0gbmV3IFNldChwYXJjZWxzKVxuXG4gIGlmICghYmFzZSkge1xuICAgIHRocm93IG5ldyBDbGlFcnJvcignTWlzc2luZyBzY2VuZSBiYXNlIGF0dHJpYnV0ZSBhdCBzY2VuZS5qc29uJylcbiAgfVxuXG4gIGlmICghcGFyY2Vscykge1xuICAgIHRocm93IG5ldyBDbGlFcnJvcignTWlzc2luZyBzY2VuZSBwYXJjZWxzIGF0dHJpYnV0ZSBhdCBzY2VuZS5qc29uJylcbiAgfVxuXG4gIGlmIChwYXJjZWxTZXQuc2l6ZSA8IHBhcmNlbHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IENsaUVycm9yKGBUaGVyZSBhcmUgZHVwbGljYXRlZCBwYXJjZWxzIGF0IHNjZW5lLmpzb24uYClcbiAgfVxuXG4gIGlmICghcGFyY2VsU2V0LmhhcyhiYXNlKSkge1xuICAgIHRocm93IG5ldyBDbGlFcnJvcihgWW91ciBiYXNlIHBhcmNlbCAke2Jhc2V9IHNob3VsZCBiZSBpbmNsdWRlZCBvbiBwYXJjZWxzIGF0dHJpYnV0ZSBhdCBzY2VuZS5qc29uYClcbiAgfVxuXG4gIGNvbnN0IG9ialBhcmNlbHMgPSBwYXJjZWxzLm1hcChnZXRPYmplY3QpXG4gIG9ialBhcmNlbHMuZm9yRWFjaCgoeyB4LCB5IH0pID0+IHtcbiAgICBpZiAoaW5Cb3VuZHMoeCwgeSkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjb25zdCB7IG1pblgsIG1heFggfSA9IGdldEJvdW5kcygpXG4gICAgdGhyb3cgbmV3IENsaUVycm9yKGBDb29yZGluYXRlcyAke3h9LCR7eX0gYXJlIG91dHNpZGUgb2YgYWxsb3dlZCBsaW1pdHMgKGZyb20gJHttaW5YfSB0byAke21heFh9KWApXG4gIH0pXG5cbiAgaWYgKCFhcmVDb25uZWN0ZWQob2JqUGFyY2VscykpIHtcbiAgICB0aHJvdyBuZXcgQ2xpRXJyb3IoJ1BhcmNlbHMgZGVzY3JpYmVkIG9uIHNjZW5lLmpzb24gYXJlIG5vdCBjb25uZWN0ZWQuIFRoZXkgc2hvdWxkIGJlIG9uZSBuZXh0IHRvIGVhY2ggb3RoZXInKVxuICB9XG59XG5cbi8qKlxuICogRmFpbHMgdGhlIGV4ZWN1dGlvbiBpZiBvbmUgb2YgdGhlIHBhcmNlbCBkYXRhIGlzIGludmFsaWRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlU2NlbmVPcHRpb25zKGNvbXBvbmVudHM6IHsgZnM6IElGaWxlU3lzdGVtQ29tcG9uZW50IH0sIGRpcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHNjZW5lRmlsZSA9IGF3YWl0IGdldFNjZW5lRmlsZShjb21wb25lbnRzLCBkaXIpXG4gIHJldHVybiB2YWxpZGF0ZVNjZW5lRGF0YShzY2VuZUZpbGUpXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIGFsbCB0aGUgY29uZGl0aW9ucyByZXF1aXJlZCB0byBvcGVyYXRlIG92ZXIgYW4gZXhpc3RpbmcgcHJvamVjdC5cbiAqIFRocm93cyBpZiBhIHByb2plY3QgY29udGFpbnMgYW4gaW52YWxpZCBtYWluIHBhdGggb3IgaWYgdGhlIGBzY2VuZS5qc29uYCBmaWxlIGlzIG1pc3NpbmcuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB2YWxpZGF0ZUV4aXN0aW5nUHJvamVjdChjb21wb25lbnRzOiB7IGZzOiBJRmlsZVN5c3RlbUNvbXBvbmVudCB9LCBkaXI6IHN0cmluZykge1xuICBjb25zdCBzY2VuZUZpbGUgPSBhd2FpdCBnZXRTY2VuZUZpbGUoY29tcG9uZW50cywgZGlyKVxuXG4gIGlmICghaXNXZWJTb2NrZXQoc2NlbmVGaWxlLm1haW4pKSB7XG4gICAgaWYgKCFpc1ZhbGlkTWFpbkZvcm1hdChzY2VuZUZpbGUubWFpbikpIHtcbiAgICAgIHRocm93IG5ldyBDbGlFcnJvcihgTWFpbiBzY2VuZSBmb3JtYXQgZmlsZSAoJHtzY2VuZUZpbGUubWFpbn0pIGlzIG5vdCBhIHN1cHBvcnRlZCBmb3JtYXRgKVxuICAgIH1cblxuICAgIGlmIChzY2VuZUZpbGUubWFpbiAhPT0gbnVsbCAmJiAhKGF3YWl0IGNvbXBvbmVudHMuZnMuZmlsZUV4aXN0cyhyZXNvbHZlKGRpciwgc2NlbmVGaWxlLm1haW4pKSkpIHtcbiAgICAgIHRocm93IG5ldyBDbGlFcnJvcihgTWFpbiBzY2VuZSBmaWxlICR7c2NlbmVGaWxlLm1haW59IGlzIG1pc3NpbmcgaW4gZm9sZGVyICR7ZGlyfWApXG4gICAgfVxuICB9XG59XG4iXX0=