diff --git a/mu-trees/addon/ember-config.js b/mu-trees/addon/ember-config.js index 54f21a10..3febd7ee 100644 --- a/mu-trees/addon/ember-config.js +++ b/mu-trees/addon/ember-config.js @@ -29,12 +29,7 @@ export default function generateConfig(name) { router: { definitiveCollection: 'main' }, serializer: { definitiveCollection: 'models' }, service: { definitiveCollection: 'services' }, - template: { - definitiveCollection: 'routes', - fallbackCollectionPrefixes: { - 'components': 'components' - } - }, + template: { definitiveCollection: 'components' }, transform: { definitiveCollection: 'transforms' }, view: { definitiveCollection: 'views' }, '-view-registry': { definitiveCollection: 'main' }, diff --git a/mu-trees/addon/resolvers/glimmer-wrapper/index.js b/mu-trees/addon/resolvers/glimmer-wrapper/index.js index 4f41df56..7c7bf00e 100644 --- a/mu-trees/addon/resolvers/glimmer-wrapper/index.js +++ b/mu-trees/addon/resolvers/glimmer-wrapper/index.js @@ -15,6 +15,8 @@ const Resolver = DefaultResolver.extend({ init() { this._super(...arguments); + this._configRootName = this.config.app.rootName || 'app'; + if (!this.glimmerModuleRegistry) { this.glimmerModuleRegistry = new RequireJSRegistry(this.config, 'src'); } @@ -24,38 +26,50 @@ const Resolver = DefaultResolver.extend({ normalize: null, - resolve(lookupString) { - /* - * Ember paritals are looked up as templates. Here we replace the template - * resolution with a partial resolute when appropriate. Try to keep this - * code as "pay-go" as possible. - */ + resolve(lookupString, referrer) { - if (lookupString.indexOf('template:') === 0) { - lookupString = this._templateToPartial(lookupString); - } - return this._resolve(lookupString); - }, + if (lookupString.indexOf('template:components/') === 0) { + /* + * Ember components require their lookupString to be massaged. Make this + * as "pay-go" as possible. + */ + if (referrer) { + // make absolute + let parts = referrer.split(':src/ui/'); + referrer = `${parts[0]}:/${this._configRootName}/${parts[1]}`; + referrer = referrer.split('/template.hbs')[0]; + } - _resolve(lookupString) { - return this._glimmerResolver.resolve(lookupString); - }, + lookupString = lookupString.replace('components/', ''); + } else if (lookupString.indexOf('template:') === 0) { + /* + * Ember partials are looked up as templates. Here we replace the template + * resolution with a partial resolute when appropriate. Try to keep this + * code as "pay-go" as possible. + */ + let match = TEMPLATE_TO_PARTIAL.exec(lookupString); + if (match) { + let namespace = match[1] || ''; + let name = match[2]; - /* - * templates may actually be partial lookups, so consider them as possibly - * such and return the correct lookupString. - */ - _templateToPartial(lookupString) { - let match = TEMPLATE_TO_PARTIAL.exec(lookupString); - if (!match) { - return lookupString; + lookupString = `partial:${namespace}${name}`; + } else { + if (referrer) { + throw new Error(`Cannot look up a route template ${lookupString} with a referrer`); + } + let parts = lookupString.split(':'); + lookupString = `template`; + referrer = `route:/${this._configRootName}/routes/${parts[1]}`; + } } - let namespace = match[1] || ''; - let name = match[2]; + return this._resolve(lookupString, referrer); + }, - return `partial:${namespace}${name}`; + _resolve(lookupString, referrer) { + return this._glimmerResolver.resolve(lookupString, referrer); } + }); export default Resolver; diff --git a/mu-trees/tests/unit/module-registries/requirejs-test.js b/mu-trees/tests/unit/module-registries/requirejs-test.js index 6e7a50a9..140041d5 100644 --- a/mu-trees/tests/unit/module-registries/requirejs-test.js +++ b/mu-trees/tests/unit/module-registries/requirejs-test.js @@ -12,12 +12,7 @@ export let config = { service: { definitiveCollection: 'services' }, route: { definitiveCollection: 'routes' }, router: { definitiveCollection: 'main' }, - template: { - definitiveCollection: 'routes', - fallbackCollectionPrefixes: { - 'components': 'components' - } - } + template: { definitiveCollection: 'components' } }, collections: { 'main': { diff --git a/mu-trees/tests/unit/resolvers/glimmer-wrapper/basic-test.js b/mu-trees/tests/unit/resolvers/glimmer-wrapper/basic-test.js index 9712686d..b1abdb30 100644 --- a/mu-trees/tests/unit/resolvers/glimmer-wrapper/basic-test.js +++ b/mu-trees/tests/unit/resolvers/glimmer-wrapper/basic-test.js @@ -288,9 +288,14 @@ test('Can not resolve a top level template of a non-definitive type', function(a }); assert.equal( - resolver.resolve('template:my-input', 'template:/app/routes/posts'), + resolver.resolve('template:components/my-input', 'template:/app/routes/posts'), undefined, - 'relative module specifier with source resolved' + 'route collection module not resolved' + ); + assert.equal( + resolver.resolve('template:components/my-input', 'template:src/ui/routes/posts'), + undefined, + 'route collection module not resolved' ); }); @@ -320,7 +325,42 @@ test('Can resolve a top level template of a definitive type', function(assert) { }); assert.equal( - resolver.resolve('template:my-input', 'template:/app/routes/posts'), + resolver.resolve('template:components/my-input', 'template:/app/routes/posts'), + template, + 'relative module specifier with source resolved' + ); + assert.equal( + resolver.resolve('template:components/my-input', 'template:src/ui/routes/posts'), + template, + 'relative module specifier with source resolved' + ); +}); + +test('Can resolve component template', function(assert) { + let template = {}; + let resolver = this.resolverForEntries({ + app: { + name: 'example-app' + }, + types: { + template: { definitiveCollection: 'components' } + }, + collections: { + components: { + group: 'ui', + types: [ 'template' ] + }, + routes: { + group: 'ui', + types: [ 'template' ] + } + } + }, { + 'template:/app/components/my-input': template + }); + + assert.equal( + resolver.resolve('template:components/my-input'), template, 'relative module specifier with source resolved' ); @@ -352,3 +392,113 @@ test('Can resolve a partial', function(assert) { 'partial resolved' ); }); + +test('Can resolve private component template', function(assert) { + let template = {}; + let notTemplate = {}; + let resolver = this.resolverForEntries({ + app: { + name: 'example-app' + }, + types: { + template: { definitiveCollection: 'components' } + }, + collections: { + components: { + group: 'ui', + types: [ 'template' ] + }, + routes: { + group: 'ui', + types: [ 'template' ], + privateCollections: ['components'] + } + } + }, { + 'template:/app/routes/my-page/my-input': notTemplate, + 'template:/app/routes/my-page/-components/my-input': template + }); + + + assert.equal( + resolver.resolve('template:components/my-input', 'template:src/ui/routes/my-page'), + template, + 'relative module specifier with source resolved w/ normalization' + ); +}); + +test('Can resolve template in a route correctly', function(assert) { + let routeTemplate = {}; + let componentTemplate = {}; + let resolver = this.resolverForEntries({ + app: { + name: 'example-app' + }, + types: { + route: { definitiveCollection: 'routes' }, + template: { definitiveCollection: 'components' } + }, + collections: { + components: { + group: 'ui', + types: [ 'template' ] + }, + routes: { + group: 'ui', + types: [ 'template' ], + privateCollections: ['components'] + } + } + }, { + 'template:/app/routes/my-page': routeTemplate, + 'template:/app/components/my-page': componentTemplate + }); + + assert.equal( + resolver.resolve('template:my-page'), + routeTemplate, + 'relative module found in routes' + ); + assert.equal( + resolver.resolve('template:components/my-page'), + componentTemplate, + 'relative module found in routes' + ); +}); + +test('Does not fall back when resolving route', function(assert) { + let componentTemplate = {}; + let resolver = this.resolverForEntries({ + app: { + name: 'example-app' + }, + types: { + route: { definitiveCollection: 'routes' }, + template: { definitiveCollection: 'components' } + }, + collections: { + components: { + group: 'ui', + types: [ 'template' ] + }, + routes: { + group: 'ui', + types: [ 'template' ], + privateCollections: ['components'] + } + } + }, { + 'template:/app/components/my-page': componentTemplate + }); + + assert.equal( + resolver.resolve('template:my-page'), + undefined, + 'relative module found in routes' + ); + assert.equal( + resolver.resolve('template:components/my-page'), + componentTemplate, + 'relative module found in routes' + ); +}); diff --git a/package.json b/package.json index 918511d7..0cd59523 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "ember-addon" ], "dependencies": { - "@glimmer/resolver": "^0.3.0", + "@glimmer/resolver": "0.4.0", "babel-plugin-debug-macros": "^0.1.1", "broccoli-funnel": "^1.1.0", "broccoli-merge-trees": "^2.0.0", diff --git a/yarn.lock b/yarn.lock index 815515d5..af820bb0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6,9 +6,9 @@ version "0.2.0" resolved "https://registry.yarnpkg.com/@glimmer/di/-/di-0.2.0.tgz#73bfd4a6ee4148a80bf092e8a5d29bcac9d4ce7e" -"@glimmer/resolver@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@glimmer/resolver/-/resolver-0.3.0.tgz#65451a2195259ce26518715631c38dd7c144e821" +"@glimmer/resolver@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@glimmer/resolver/-/resolver-0.4.0.tgz#7fe8709342064f144c14c06088d6dc4070ad7d1d" dependencies: "@glimmer/di" "^0.2.0"