diff --git a/registry/server/common/services/AppAssetsDiscovery.ts b/registry/server/common/services/AppAssetsDiscovery.ts index 745ccafa..b8262cea 100644 --- a/registry/server/common/services/AppAssetsDiscovery.ts +++ b/registry/server/common/services/AppAssetsDiscovery.ts @@ -3,6 +3,7 @@ import _ from 'lodash'; import urljoin from 'url-join'; import knex from '../../db'; +import manifestProcessor from './assetsManifestProcessor'; export default class AppAssetsDiscovery { private timerId?: NodeJS.Timeout; @@ -53,10 +54,7 @@ export default class AppAssetsDiscovery { continue; } - let data = _.pick(res.data, ['spaBundle', 'cssBundle', 'dependencies']); - if (data.dependencies !== undefined) { - data.dependencies = JSON.stringify(data.dependencies); - } + let data = manifestProcessor(reqUrl, res.data); await knex('apps').where('name', app.name).update(Object.assign({}, data, { assetsDiscoveryUpdatedAt: now, diff --git a/registry/server/common/services/assetsManifestProcessor.ts b/registry/server/common/services/assetsManifestProcessor.ts new file mode 100644 index 00000000..4b74d226 --- /dev/null +++ b/registry/server/common/services/assetsManifestProcessor.ts @@ -0,0 +1,23 @@ +import _ from 'lodash'; +import url from 'url'; + + +export default function processManifest(baseUrl: string, manifest: any) { + let data = _.pick(manifest, ['spaBundle', 'cssBundle', 'dependencies']); + + if (data.spaBundle) { + data.spaBundle = url.resolve(baseUrl, data.spaBundle); + } + if (data.cssBundle) { + data.cssBundle = url.resolve(baseUrl, data.cssBundle); + } + + if (data.dependencies !== undefined && _.isPlainObject(data.dependencies)) { + data.dependencies = _.mapValues(data.dependencies, v => url.resolve(baseUrl, v)); + data.dependencies = JSON.stringify(data.dependencies); + } else { + delete data.dependencies; + } + + return data; +} diff --git a/registry/tests/assetsManifestProcessor.spec.ts b/registry/tests/assetsManifestProcessor.spec.ts new file mode 100644 index 00000000..26781a19 --- /dev/null +++ b/registry/tests/assetsManifestProcessor.spec.ts @@ -0,0 +1,59 @@ +import { expect } from './common'; + +import processor from '../server/common/services/assetsManifestProcessor' + +describe('assetsManifestProcessor', () => { + it('perform basic link resolution & cleanup of extra props', () => { + expect(processor('https://example.com/folder/assets-discovery.js', { + a: 'tst', + spaBundle: 'https://example.com/aa.js', + cssBundle: './tst/aa.js', + dependencies: { + a1: 'https://example.com/aa.js', + a2: './tst/aa.js', + } + })).to.eql({ + spaBundle: 'https://example.com/aa.js', + cssBundle: 'https://example.com/folder/tst/aa.js', + dependencies: JSON.stringify({ + a1: 'https://example.com/aa.js', + a2: 'https://example.com/folder/tst/aa.js', + }) + }); + }); + + it('handles absence of dependencies object or invalid type correctly', () => { + expect(processor('https://example.com/folder/assets-discovery.js', { + spaBundle: 'https://example.com/aa.js', + cssBundle: './tst/aa.js', + })).to.eql({ + spaBundle: 'https://example.com/aa.js', + cssBundle: 'https://example.com/folder/tst/aa.js', + }); + + expect(processor('https://example.com/folder/assets-discovery.js', { + spaBundle: 'https://example.com/aa.js', + cssBundle: './tst/aa.js', + dependencies: ['aaa'] + })).to.eql({ + spaBundle: 'https://example.com/aa.js', + cssBundle: 'https://example.com/folder/tst/aa.js', + }); + }); + + it('handles absence of cssBundle correctly', () => { + expect(processor('https://example.com/folder/assets-discovery.js', { + spaBundle: 'https://example.com/aa.js', + })).to.eql({ + spaBundle: 'https://example.com/aa.js', + }); + }); + + it('handles absence of spaBundle correctly', () => { + expect(processor('https://example.com/folder/assets-discovery.js', { + cssBundle: 'https://example.com/aa.css', + })).to.eql({ + cssBundle: 'https://example.com/aa.css', + }); + }); +});