diff --git a/.eslintrc.json b/.eslintrc.json index ed65eed..fe00fd4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,6 @@ { - "extends": ["@adobe/eslint-config-aio-lib-config"] + "extends": ["@adobe/eslint-config-aio-lib-config"], + "parserOptions": { + "ecmaVersion": 2020 + } } \ No newline at end of file diff --git a/src/index.js b/src/index.js index d35ffa3..c63f592 100644 --- a/src/index.js +++ b/src/index.js @@ -158,7 +158,7 @@ function loadCommonConfig () { ow: owConfig, aio: aioConfig, // soon not needed anymore (for old headless validator) - imsOrgId: aioConfig && aioConfig.project && aioConfig.project.org && aioConfig.project.org.ims_org_id + imsOrgId: aioConfig.project?.org?.ims_org_id } } @@ -289,7 +289,9 @@ function loadUserConfigLegacy (commonConfig) { // todo: new value usingLegacyConfig // this module should not console.log/warn ... or include chalk ... if (commonConfig.aio.cna !== undefined || commonConfig.aio.app !== undefined) { - aioLogger.warn('App config in \'.aio\' file is deprecated. Please move your \'.aio.app\' or \'.aio.cna\' to \'app.config.yaml\'.') + // this might have never have been seen in the wild as we don't know + // what log-level users have set + aioLogger.error('App config in \'.aio\' file is deprecated. Please move your \'.aio.app\' or \'.aio.cna\' to \'app.config.yaml\'.') const appConfig = { ...commonConfig.aio.app, ...commonConfig.aio.cna } Object.entries(appConfig).forEach(([k, v]) => { legacyAppConfig[k] = v @@ -344,7 +346,7 @@ function loadUserConfigLegacy (commonConfig) { }) // todo: new val usingLegacyHooks:Boolean if (Object.keys(hooks).length > 0) { - aioLogger.warn('hooks in \'package.json\' are deprecated. Please move your hooks to \'app.config.yaml\' under the \'hooks\' key') + aioLogger.error('hooks in \'package.json\' are deprecated. Please move your hooks to \'app.config.yaml\' under the \'hooks\' key') legacyAppConfig.hooks = hooks // build index includeIndex[`${defaults.APPLICATION_CONFIG_KEY}.hooks`] = { file: 'package.json', key: 'scripts' } @@ -421,7 +423,10 @@ function buildExtConfigs (userConfig, commonConfig, includeIndex) { /** @private */ function buildAppConfig (userConfig, commonConfig, includeIndex) { - const fullAppConfig = buildSingleConfig(defaults.APPLICATION_CONFIG_KEY, userConfig[defaults.APPLICATION_CONFIG_KEY], commonConfig, includeIndex) + const fullAppConfig = buildSingleConfig(defaults.APPLICATION_CONFIG_KEY, + userConfig[defaults.APPLICATION_CONFIG_KEY], + commonConfig, + includeIndex) if (!fullAppConfig.app.hasBackend && !fullAppConfig.app.hasFrontend) { // only set application config if there is an actuall app, meaning either some backend or frontend @@ -488,6 +493,13 @@ function buildSingleConfig (configName, singleUserConfig, commonConfig, includeI config.app.hasFrontend = fs.existsSync(web) config.app.dist = path.resolve(dist, dist === defaultDistPath ? subFolderName : '') + if (singleUserConfig.events) { + config.events = { ...singleUserConfig.events } + } + if (commonConfig?.aio?.project) { + config.project = commonConfig.aio.project + } + // actions config.actions.src = path.resolve(actions) // needed for app add first action if (config.app.hasBackend) { diff --git a/test/__fixtures__/exc-with-events/app.config.yaml b/test/__fixtures__/exc-with-events/app.config.yaml new file mode 100644 index 0000000..fa4da76 --- /dev/null +++ b/test/__fixtures__/exc-with-events/app.config.yaml @@ -0,0 +1,3 @@ +extensions: + 'dx/excshell/1': + $include: src/dx-excshell-1/ext.config.yaml diff --git a/test/__fixtures__/exc-with-events/package.json b/test/__fixtures__/exc-with-events/package.json new file mode 100644 index 0000000..57698ed --- /dev/null +++ b/test/__fixtures__/exc-with-events/package.json @@ -0,0 +1,4 @@ +{ + "version": "1.0.0", + "name": "exc" +} diff --git a/test/__fixtures__/exc-with-events/src/dx-excshell-1/actions/action.js b/test/__fixtures__/exc-with-events/src/dx-excshell-1/actions/action.js new file mode 100644 index 0000000..c491ed6 --- /dev/null +++ b/test/__fixtures__/exc-with-events/src/dx-excshell-1/actions/action.js @@ -0,0 +1,17 @@ +/* +Copyright 2019 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +/** @private */ +function main (args) { + return 'hello' +} +exports.main = main diff --git a/test/__fixtures__/exc-with-events/src/dx-excshell-1/actions/somefile.txt b/test/__fixtures__/exc-with-events/src/dx-excshell-1/actions/somefile.txt new file mode 100644 index 0000000..d9851e6 --- /dev/null +++ b/test/__fixtures__/exc-with-events/src/dx-excshell-1/actions/somefile.txt @@ -0,0 +1 @@ +include me ! \ No newline at end of file diff --git a/test/__fixtures__/exc-with-events/src/dx-excshell-1/ext.config.yaml b/test/__fixtures__/exc-with-events/src/dx-excshell-1/ext.config.yaml new file mode 100644 index 0000000..537a721 --- /dev/null +++ b/test/__fixtures__/exc-with-events/src/dx-excshell-1/ext.config.yaml @@ -0,0 +1,26 @@ +operations: + view: + - type: web + impl: index.html +actions: ./actions +web: ./web-src +events: + registrations: +runtimeManifest: + packages: + my-exc-package: + license: 'Apache-2.0' + actions: + action: + function: 'actions/action.js' + web: 'yes' + runtime: 'nodejs:14' + inputs: + LOG_LEVEL: 'debug' + annotations: + 'require-adobe-auth': true + final: true + include: + - [ 'actions/somefile.txt', 'file.txt' ] + limits: + concurrency: 189 diff --git a/test/__fixtures__/exc-with-events/src/dx-excshell-1/web-src/index.html b/test/__fixtures__/exc-with-events/src/dx-excshell-1/web-src/index.html new file mode 100644 index 0000000..9bd20dd --- /dev/null +++ b/test/__fixtures__/exc-with-events/src/dx-excshell-1/web-src/index.html @@ -0,0 +1,18 @@ + + + + + + + + + Runtime Starter + + + + + + + diff --git a/test/data-mocks/config-loader.js b/test/data-mocks/config-loader.js index 3331653..4598869 100644 --- a/test/data-mocks/config-loader.js +++ b/test/data-mocks/config-loader.js @@ -215,6 +215,7 @@ const nuiSingleConfig = { e2e: winCompat(`${root}/src/dx-asset-compute-worker-1/e2e`), unit: winCompat(`${root}/src/dx-asset-compute-worker-1/test`) }, + // events: {}, root: `${root}`, name: 'dx/asset-compute/worker/1', hooks: { @@ -269,6 +270,7 @@ const applicationSingleConfig = { e2e: winCompat(`${root}e2e`), unit: winCompat(`${root}test`) }, + // events: {}, root: `${root}`, name: 'application', hooks: { @@ -322,6 +324,7 @@ const applicationNoActionsSingleConfig = { }, root: `${root}`, name: 'application', + events: {}, hooks: { 'pre-app-run': 'echo hello' } diff --git a/test/index.test.js b/test/index.test.js index e52e32f..decb834 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -36,7 +36,10 @@ describe('load config', () => { test('standalone app config', async () => { global.loadFixtureApp('app') config = loadConfig() // {} or not for coverage - expect(config).toEqual(getMockConfig('app', global.fakeConfig.tvm)) + const mockConfig = getMockConfig('app', global.fakeConfig.tvm, { + 'all.application.project': expect.any(Object) + }) + expect(config).toEqual(mockConfig) }) test('not in an app', async () => { @@ -47,25 +50,42 @@ describe('load config', () => { test('exc extension config', async () => { global.loadFixtureApp('exc') config = loadConfig({}) - expect(config).toEqual(getMockConfig('exc', global.fakeConfig.tvm)) + expect(config).toEqual(getMockConfig('exc', global.fakeConfig.tvm, { + 'all.dx/excshell/1': expect.any(Object) + })) + }) + + test('exc with events config', async () => { + global.loadFixtureApp('exc-with-events') + config = loadConfig({}) + expect(config.all['dx/excshell/1']).toEqual(expect.objectContaining({ events: expect.any(Object) })) }) test('standalone app, exc and nui extension config', async () => { global.loadFixtureApp('app-exc-nui') config = loadConfig({}) - expect(config).toEqual(getMockConfig('app-exc-nui', global.fakeConfig.tvm)) + expect(config).toEqual(getMockConfig('app-exc-nui', global.fakeConfig.tvm, { + 'all.application.project': expect.any(Object), + 'all.dx/excshell/1.project': expect.any(Object), + 'all.dx/asset-compute/worker/1.project': expect.any(Object) + })) }) test('standalone app with no actions', async () => { global.loadFixtureApp('app-no-actions') config = loadConfig({}) - expect(config).toEqual(getMockConfig('app-no-actions', global.fakeConfig.tvm)) + expect(config).toEqual(getMockConfig('app-no-actions', global.fakeConfig.tvm, { + 'all.application.project': expect.any(Object), + 'all.application.events': expect.undefined + })) }) test('exc with complex include pattern', async () => { global.loadFixtureApp('exc-complex-includes') config = loadConfig({}) - expect(config).toEqual(getMockConfig('exc-complex-includes', global.fakeConfig.tvm)) + expect(config).toEqual(getMockConfig('exc-complex-includes', global.fakeConfig.tvm, { + 'all.dx/excshell/1.project': expect.any(Object) + })) }) test('standalone application with legacy configuration system', async () => { @@ -74,7 +94,9 @@ describe('load config', () => { // mock app config mockAIOConfig.get.mockImplementation(k => fullAioConfig) config = loadConfig({}) - expect(config).toEqual(getMockConfig('legacy-app', fullAioConfig)) + expect(config).toEqual(getMockConfig('legacy-app', fullAioConfig, { + 'all.application.project': expect.any(Object) + })) }) // corner cases - coverage @@ -87,6 +109,7 @@ describe('load config', () => { 'all.dx/excshell/1.app.name': 'unnamed-app', 'all.dx/excshell/1.app.version': '0.1.0', 'all.dx/excshell/1.ow.package': 'unnamed-app-0.1.0', + 'all.dx/excshell/1.project': expect.any(Object), 'packagejson.name': 'unnamed-app', 'packagejson.version': '0.1.0' })) @@ -105,6 +128,7 @@ describe('load config', () => { 'all.dx/excshell/1.actions.dist': path.resolve('/src/dx-excshell-1/new/dist/for/excshell/actions'), 'all.dx/excshell/1.web.distDev': path.resolve('/src/dx-excshell-1/new/dist/for/excshell/web-dev'), 'all.dx/excshell/1.web.distProd': path.resolve('/src/dx-excshell-1/new/dist/for/excshell/web-prod'), + 'all.dx/excshell/1.project': expect.any(Object), includeIndex: expect.any(Object) })) }) @@ -125,6 +149,7 @@ describe('load config', () => { secretAccessKey: 'fakesecret', params: { Bucket: 'fakebucket' } }, + 'all.dx/excshell/1.project': expect.any(Object), includeIndex: expect.any(Object) })) }) @@ -139,6 +164,7 @@ describe('load config', () => { config = loadConfig({}) expect(config).toEqual(getMockConfig('exc', global.fakeConfig.tvm, { 'all.dx/excshell/1.s3.tvmUrl': 'customurl', + 'all.dx/excshell/1.project': expect.any(Object), includeIndex: expect.any(Object) })) }) @@ -152,6 +178,7 @@ describe('load config', () => { config = loadConfig({}) expect(config).toEqual(getMockConfig('exc', global.fakeConfig.tvm, { + 'all.dx/excshell/1.project': expect.any(Object), includeIndex: expect.any(Object) })) }) @@ -166,6 +193,7 @@ describe('load config', () => { config = loadConfig({}) expect(config).toEqual(getMockConfig('exc', global.fakeConfig.tvm, { 'all.dx/excshell/1.manifest.full.packages.my-exc-package.actions.newAction': { web: 'yes' }, + 'all.dx/excshell/1.project': expect.any(Object), includeIndex: expect.any(Object) })) }) @@ -178,6 +206,7 @@ describe('load config', () => { expect(config).toEqual(getMockConfig('exc', global.fakeConfig.tvm, { 'all.dx/excshell/1.app.defaultHostname': 'dev.runtime.adobe.io', 'all.dx/excshell/1.app.hostname': 'dev.runtime.adobe.io', + 'all.dx/excshell/1.project': expect.any(Object), includeIndex: expect.any(Object) })) }) @@ -280,6 +309,8 @@ extensions: config = loadConfig({}) expect(config).toEqual(getMockConfig('legacy-app', fullAioConfig, { 'all.application.hooks': {}, + // 'all.application.events': expect.any(Object), + 'all.application.project': expect.any(Object), includeIndex: expect.any(Object), 'packagejson.scripts': {} })) @@ -304,6 +335,8 @@ extensions: 'all.application.manifest.full': { packages: { thepackage: 'takesover' } }, + // 'all.application.events': expect.any(Object), + 'all.application.project': expect.any(Object), 'all.application.manifest.package': undefined, 'all.application.hooks': { // already there diff --git a/test/jest.setup.js b/test/jest.setup.js index a652bc5..64ceb18 100644 --- a/test/jest.setup.js +++ b/test/jest.setup.js @@ -19,6 +19,11 @@ const eol = require('eol') const path = require('path') const fileSystem = require('jest-plugin-fs').default +const project = { + org: { + ims_org_id: '00000000000000000100000@AdobeOrg' + } +} // dont touch the real fs global.mockFs = () => { @@ -150,17 +155,19 @@ global.defaultAppHostName = 'adobeio-static.net' global.defaultTvmUrl = 'https://adobeio.adobeioruntime.net/apis/tvm/' global.defaultOwApihost = 'https://adobeioruntime.net' global.fakeS3Bucket = 'fake-bucket' -global.fakeOrgId = '00000000000000000100000@AdobeOrg' + global.fakeConfig = { tvm: { - project: { org: { ims_org_id: global.fakeOrgId } }, + project, runtime: { namespace: 'fake_ns', auth: 'fake:auth' } }, + events: {}, + project, local: { - project: { org: { ims_org_id: global.fakeOrgId } }, + project, runtime: { // those must match the once set by dev cmd apihost: 'http://localhost:3233', @@ -170,7 +177,7 @@ global.fakeConfig = { }, // todo delete those should not be passed via aio now creds: { - project: { org: { ims_org_id: global.fakeOrgId } }, + project, runtime: { namespace: 'fake_ns', auth: 'fake:auth'