From 415c326b3b00bfef4f8432e2ca68a5f93b08e425 Mon Sep 17 00:00:00 2001 From: Nicolas Echezarreta Date: Thu, 5 Oct 2023 12:41:13 -0300 Subject: [PATCH] add: warning for missing keys on scene.json --- .../sdk-commands/src/commands/deploy/index.ts | 2 +- .../src/logic/scene-validations.ts | 32 +++++++++++++++++-- .../utils/scene-validation.spec.ts | 25 ++++++++------- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/packages/@dcl/sdk-commands/src/commands/deploy/index.ts b/packages/@dcl/sdk-commands/src/commands/deploy/index.ts index 2cfc6fca3..94224f22f 100644 --- a/packages/@dcl/sdk-commands/src/commands/deploy/index.ts +++ b/packages/@dcl/sdk-commands/src/commands/deploy/index.ts @@ -81,7 +81,7 @@ export async function main(options: Options) { throw new CliError(`You can't set both the 'target' and 'target-content' arguments.`) } - const sceneJson = await getValidSceneJson(options.components, projectRoot) + const sceneJson = await getValidSceneJson(options.components, projectRoot, { log: true }) const coords = getBaseCoords(sceneJson) const isWorld = sceneHasWorldCfg(sceneJson) const trackProps: Events['Scene deploy started'] = { diff --git a/packages/@dcl/sdk-commands/src/logic/scene-validations.ts b/packages/@dcl/sdk-commands/src/logic/scene-validations.ts index ba12a7615..66a5666dd 100644 --- a/packages/@dcl/sdk-commands/src/logic/scene-validations.ts +++ b/packages/@dcl/sdk-commands/src/logic/scene-validations.ts @@ -2,10 +2,12 @@ import { resolve } from 'path' import { Scene, getWorld, isInsideWorldLimits } from '@dcl/schemas' import { areConnected } from '@dcl/ecs/dist-cjs' +import { getMinimalSceneJson } from '../commands/init/project' import { CliError } from './error' import { getObject } from './coordinates' import { CliComponents } from '../components' import { getPublishableFiles } from './project-files' +import { printWarning } from './beautiful-logs' export interface IFile { path: string @@ -33,7 +35,18 @@ function getWorldRangesConstraintsMessage(): string { return str } -export function assertValidScene(scene: Scene) { +function checkMissingOrDefault>(obj: T, defaults: T) { + const missingKeys = Object.entries(defaults).reduce((acc: string[], [key, value]) => { + return obj[key] && obj[key] !== value ? acc : acc.concat(key) + }, []) + return missingKeys +} + +export function assertValidScene( + components: Pick, + scene: Scene, + opts: { log?: boolean } = { log: false } +) { if (!Scene.validate(scene)) { const errors: string[] = [] if (Scene.validate.errors) { @@ -71,6 +84,18 @@ export function assertValidScene(scene: Scene) { if (!scene.main?.endsWith('.js')) { throw new CliError(`Main scene format file (${scene.main}) is not a supported format`) } + + const defaults = getMinimalSceneJson() + const missingKeys = checkMissingOrDefault(scene.display ?? {}, defaults.display ?? {}) + + if (missingKeys.length && opts.log) { + const missingKeysMsg = missingKeys.join(', ') + printWarning( + components.logger, + `Don't forget to update your scene.json metadata: [${missingKeysMsg}] +https://docs.decentraland.org/creator/development-guide/scene-metadata/#scene-title-description-and-image` + ) + } } /** @@ -78,12 +103,13 @@ export function assertValidScene(scene: Scene) { */ export async function getValidSceneJson( components: Pick, - projectRoot: string + projectRoot: string, + opts?: { log?: boolean } ): Promise { try { const sceneJsonRaw = await components.fs.readFile(getSceneFilePath(projectRoot), 'utf8') const sceneJson = JSON.parse(sceneJsonRaw) as Scene - assertValidScene(sceneJson) + assertValidScene(components, sceneJson, opts) return sceneJson } catch (err: any) { throw new CliError(`Error reading the scene.json file: ${err.message}`) diff --git a/test/sdk-commands/utils/scene-validation.spec.ts b/test/sdk-commands/utils/scene-validation.spec.ts index 3bbaf9a95..269b65754 100644 --- a/test/sdk-commands/utils/scene-validation.spec.ts +++ b/test/sdk-commands/utils/scene-validation.spec.ts @@ -6,31 +6,32 @@ import { Stats } from 'fs' describe('scene validations', () => { it('sanity scene validations', async () => { - await expect(async () => v.assertValidScene({} as any)).rejects.toThrow() - await expect(async () => v.assertValidScene({ base: null } as any)).rejects.toThrow() - await expect(async () => v.assertValidScene({ main: 'test' } as any)).rejects.toThrow() - await expect(async () => v.assertValidScene({ main: 'test.js', scene: null as any })).rejects.toThrow() + const components = await initComponents() + await expect(async () => v.assertValidScene(components, {} as any)).rejects.toThrow() + await expect(async () => v.assertValidScene(components, { base: null } as any)).rejects.toThrow() + await expect(async () => v.assertValidScene(components, { main: 'test' } as any)).rejects.toThrow() + await expect(async () => v.assertValidScene(components, { main: 'test.js', scene: null as any })).rejects.toThrow() await expect(async () => - v.assertValidScene({ main: 'test.js', scene: { base: 'test', parcels: [] } }) + v.assertValidScene(components, { main: 'test.js', scene: { base: 'test', parcels: [] } }) ).rejects.toThrow() await expect(async () => - v.assertValidScene({ main: 'test.js', scene: { base: '0,0', parcels: [] } }) + v.assertValidScene(components, { main: 'test.js', scene: { base: '0,0', parcels: [] } }) ).rejects.toThrow() await expect(async () => - v.assertValidScene({ main: 'test.js', scene: { base: '0,0', parcels: ['0,0', '0,0'] } }) + v.assertValidScene(components, { main: 'test.js', scene: { base: '0,0', parcels: ['0,0', '0,0'] } }) ).rejects.toThrow() await expect(async () => - v.assertValidScene({ main: 'test.js', scene: { base: '0,0', parcels: ['0,0', '3,0'] } }) + v.assertValidScene(components, { main: 'test.js', scene: { base: '0,0', parcels: ['0,0', '3,0'] } }) ).rejects.toThrow() await expect(async () => - v.assertValidScene({ main: 'test.js', scene: { base: '1,0', parcels: ['0,0'] } }) + v.assertValidScene(components, { main: 'test.js', scene: { base: '1,0', parcels: ['0,0'] } }) ).rejects.toThrow() await expect(async () => - v.assertValidScene({ main: 'test.js', scene: { base: '1000,0', parcels: ['1000,0'] } }) + v.assertValidScene(components, { main: 'test.js', scene: { base: '1000,0', parcels: ['1000,0'] } }) ).rejects.toThrow() - v.assertValidScene({ main: 'test.js', scene: { base: '0,0', parcels: ['0,0'] } }) + v.assertValidScene(components, { main: 'test.js', scene: { base: '0,0', parcels: ['0,0'] } }) await expect(async () => - v.assertValidScene({ main: 'test.json', scene: { base: '1,0', parcels: ['1,0'] } }) + v.assertValidScene(components, { main: 'test.json', scene: { base: '1,0', parcels: ['1,0'] } }) ).rejects.toThrow() }) it('validates connected parcels', () => {