diff --git a/src/deep-linking/util.spec.ts b/src/deep-linking/util.spec.ts index 2697683d..928e94dc 100644 --- a/src/deep-linking/util.spec.ts +++ b/src/deep-linking/util.spec.ts @@ -1,12 +1,53 @@ import { join } from 'path'; import * as util from './util'; +import * as Constants from '../util/constants'; import { FileCache } from '../util/file-cache'; import * as helpers from '../util/helpers'; import { DeepLinkConfigEntry } from '../util/interfaces'; import * as tsUtils from '../util/typescript-utils'; describe('util', () => { + describe('filterTypescriptFilesForDeepLinks', () => { + it('should return a list of files that are in the directory specified for deeplinking', () => { + const pagesDir = join('Users', 'dan', 'myApp', 'src', 'pages'); + + const knownFileContent = 'Some string'; + const pageOneTs = join(pagesDir, 'page-one', 'page-one.ts'); + const pageOneHtml = join(pagesDir, 'page-one', 'page-one.html'); + const pageOneModule = join(pagesDir, 'page-one', 'page-one.module.ts'); + + const pageTwoTs = join(pagesDir, 'page-two', 'page-two.ts'); + const pageTwoHtml = join(pagesDir, 'page-two', 'page-two.html'); + const pageTwoModule = join(pagesDir, 'page-two', 'page-two.module.ts'); + + const pageThreeTs = join(pagesDir, 'page-three', 'page-three.ts'); + const pageThreeHtml = join(pagesDir, 'page-three', 'page-three.html'); + const pageThreeModule = join(pagesDir, 'page-three', 'page-three.module.ts'); + + const someOtherFile = join('Users', 'hans-gruber', 'test.ts'); + + const fileCache = new FileCache(); + fileCache.set(pageOneTs, { path: pageOneTs, content: knownFileContent}); + fileCache.set(pageOneHtml, { path: pageOneHtml, content: knownFileContent}); + fileCache.set(pageOneModule, { path: pageOneModule, content: knownFileContent}); + fileCache.set(pageTwoTs, { path: pageTwoTs, content: knownFileContent}); + fileCache.set(pageTwoHtml, { path: pageTwoHtml, content: knownFileContent}); + fileCache.set(pageTwoModule, { path: pageTwoModule, content: knownFileContent}); + fileCache.set(pageThreeTs, { path: pageThreeTs, content: knownFileContent}); + fileCache.set(pageThreeHtml, { path: pageThreeHtml, content: knownFileContent}); + fileCache.set(pageThreeModule, { path: pageThreeModule, content: knownFileContent}); + fileCache.set(someOtherFile, { path: someOtherFile, content: knownFileContent}); + + spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValues(pagesDir, '.module.ts'); + + const results = util.filterTypescriptFilesForDeepLinks(fileCache); + expect(results.length).toEqual(3); + expect(results[0].path).toEqual(pageOneTs); + expect(results[1].path).toEqual(pageTwoTs); + expect(results[2].path).toEqual(pageThreeTs); + }); + }); describe('parseDeepLinkDecorator', () => { it('should return the decorator content from fully hydrated decorator', () => { const knownContent = ` @@ -1062,14 +1103,14 @@ export class PageThreeModule { `; - const prefix = join('Users', 'dan', 'myApp', 'src'); - const appNgModulePath = join(prefix, 'app', 'app.module.ts'); - const pageOneNgModulePath = join(prefix, 'pages', 'page-one', 'page-one.module.ts'); - const pageOnePath = join(prefix, 'pages', 'page-one', 'page-one.ts'); - const pageTwoNgModulePath = join(prefix, 'pages', 'page-two', 'page-two.module.ts'); - const pageTwoPath = join(prefix, 'pages', 'page-two', 'page-two.ts'); - const pageSettingsNgModulePath = join(prefix, 'pages', 'settings-page', 'settings-page.module.ts'); - const pageSettingsPath = join(prefix, 'pages', 'settings-page', 'settings-page.ts'); + const srcDir = join('Users', 'dan', 'myApp', 'src'); + const appNgModulePath = join(srcDir, 'app', 'app.module.ts'); + const pageOneNgModulePath = join(srcDir, 'pages', 'page-one', 'page-one.module.ts'); + const pageOnePath = join(srcDir, 'pages', 'page-one', 'page-one.ts'); + const pageTwoNgModulePath = join(srcDir, 'pages', 'page-two', 'page-two.module.ts'); + const pageTwoPath = join(srcDir, 'pages', 'page-two', 'page-two.ts'); + const pageSettingsNgModulePath = join(srcDir, 'pages', 'settings-page', 'settings-page.module.ts'); + const pageSettingsPath = join(srcDir, 'pages', 'settings-page', 'settings-page.ts'); const fileCache = new FileCache(); fileCache.set(pageOnePath, { path: pageOnePath, content: pageOneContent}); @@ -1081,7 +1122,13 @@ export class PageThreeModule { fileCache.set(pageSettingsPath, { path: pageSettingsPath, content: pageSettingsContent}); fileCache.set(pageSettingsNgModulePath, { path: pageSettingsNgModulePath, content: pageSettingsNgModuleContent}); - spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValue('.module.ts'); + spyOn(helpers, helpers.getStringPropertyValue.name).and.callFake((input: string) => { + if (input === Constants.ENV_VAR_DEEPLINKS_DIR) { + return srcDir; + } else { + return '.module.ts'; + } + }); const results = util.getDeepLinkData(appNgModulePath, fileCache, false); expect(results.length).toEqual(2); @@ -1249,14 +1296,14 @@ export class PageThreeModule { `; - const prefix = join('/Users', 'dan', 'myApp', 'src'); - const appNgModulePath = join(prefix, 'app', 'app.module.ts'); - const pageOneNgModulePath = join(prefix, 'pages', 'page-one', 'page-one.module.ts'); - const pageOnePath = join(prefix, 'pages', 'page-one', 'page-one.ts'); - const pageTwoNgModulePath = join(prefix, 'pages', 'page-two', 'page-two.module.ts'); - const pageTwoPath = join(prefix, 'pages', 'page-two', 'page-two.ts'); - const pageSettingsNgModulePath = join(prefix, 'pages', 'settings-page', 'fake-dir', 'settings-page.module.ts'); - const pageSettingsPath = join(prefix, 'pages', 'settings-page', 'fake-dir', 'settings-page.ts'); + const srcDir = join('/Users', 'dan', 'myApp', 'src'); + const appNgModulePath = join(srcDir, 'app', 'app.module.ts'); + const pageOneNgModulePath = join(srcDir, 'pages', 'page-one', 'page-one.module.ts'); + const pageOnePath = join(srcDir, 'pages', 'page-one', 'page-one.ts'); + const pageTwoNgModulePath = join(srcDir, 'pages', 'page-two', 'page-two.module.ts'); + const pageTwoPath = join(srcDir, 'pages', 'page-two', 'page-two.ts'); + const pageSettingsNgModulePath = join(srcDir, 'pages', 'settings-page', 'fake-dir', 'settings-page.module.ts'); + const pageSettingsPath = join(srcDir, 'pages', 'settings-page', 'fake-dir', 'settings-page.ts'); const fileCache = new FileCache(); fileCache.set(pageOnePath, { path: pageOnePath, content: pageOneContent}); @@ -1268,7 +1315,13 @@ export class PageThreeModule { fileCache.set(pageSettingsPath, { path: pageSettingsPath, content: pageSettingsContent}); fileCache.set(pageSettingsNgModulePath, { path: pageSettingsNgModulePath, content: pageSettingsNgModuleContent}); - spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValue('.module.ts'); + spyOn(helpers, helpers.getStringPropertyValue.name).and.callFake((input: string) => { + if (input === Constants.ENV_VAR_DEEPLINKS_DIR) { + return srcDir; + } else { + return '.module.ts'; + } + }); const results = util.getDeepLinkData(appNgModulePath, fileCache, false); expect(results.length).toEqual(3); @@ -1461,14 +1514,14 @@ export class PageThreeModule { `; - const prefix = join('/Users', 'dan', 'myApp', 'src'); - const appNgModulePath = join(prefix, 'app', 'app.module.ts'); - const pageOneNgModulePath = join(prefix, 'pages', 'page-one', 'page-one.not-module.ts'); - const pageOnePath = join(prefix, 'pages', 'page-one', 'page-one.ts'); - const pageTwoNgModulePath = join(prefix, 'pages', 'page-two', 'page-two.module.ts'); - const pageTwoPath = join(prefix, 'pages', 'page-two', 'page-two.ts'); - const pageSettingsNgModulePath = join(prefix, 'pages', 'settings-page', 'fake-dir', 'settings-page.module.ts'); - const pageSettingsPath = join(prefix, 'pages', 'settings-page', 'fake-dir', 'settings-page.ts'); + const srcDir = join('/Users', 'dan', 'myApp', 'src'); + const appNgModulePath = join(srcDir, 'app', 'app.module.ts'); + const pageOneNgModulePath = join(srcDir, 'pages', 'page-one', 'page-one.not-module.ts'); + const pageOnePath = join(srcDir, 'pages', 'page-one', 'page-one.ts'); + const pageTwoNgModulePath = join(srcDir, 'pages', 'page-two', 'page-two.module.ts'); + const pageTwoPath = join(srcDir, 'pages', 'page-two', 'page-two.ts'); + const pageSettingsNgModulePath = join(srcDir, 'pages', 'settings-page', 'fake-dir', 'settings-page.module.ts'); + const pageSettingsPath = join(srcDir, 'pages', 'settings-page', 'fake-dir', 'settings-page.ts'); const fileCache = new FileCache(); fileCache.set(pageOnePath, { path: pageOnePath, content: pageOneContent}); @@ -1480,7 +1533,13 @@ export class PageThreeModule { fileCache.set(pageSettingsPath, { path: pageSettingsPath, content: pageSettingsContent}); fileCache.set(pageSettingsNgModulePath, { path: pageSettingsNgModulePath, content: pageSettingsNgModuleContent}); - spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValue('.module.ts'); + spyOn(helpers, helpers.getStringPropertyValue.name).and.callFake((input: string) => { + if (input === Constants.ENV_VAR_DEEPLINKS_DIR) { + return srcDir; + } else { + return '.module.ts'; + } + }); const knownError = 'should never get here'; diff --git a/src/deep-linking/util.ts b/src/deep-linking/util.ts index 083556ff..553f8936 100644 --- a/src/deep-linking/util.ts +++ b/src/deep-linking/util.ts @@ -18,14 +18,14 @@ import { Logger } from '../logger/logger'; import * as Constants from '../util/constants'; import { FileCache } from '../util/file-cache'; import { changeExtension, getStringPropertyValue, replaceAll } from '../util/helpers'; -import { BuildContext, ChangedFile, DeepLinkConfigEntry, DeepLinkDecoratorAndClass, DeepLinkPathInfo } from '../util/interfaces'; +import { BuildContext, ChangedFile, DeepLinkConfigEntry, DeepLinkDecoratorAndClass, DeepLinkPathInfo, File } from '../util/interfaces'; import { appendAfter, getClassDeclarations, getTypescriptSourceFile, getNodeStringContent, replaceNode } from '../util/typescript-utils'; import { transpileTsString } from '../transpile'; export function getDeepLinkData(appNgModuleFilePath: string, fileCache: FileCache, isAot: boolean): DeepLinkConfigEntry[] { - // TODO, get `node_modules` out of here, use the property instead - const typescriptFiles = fileCache.getAll().filter(file => extname(file.path) === '.ts' && file.path.indexOf('node_modules') === -1); + // we only care about analyzing a subset of typescript files, so do that for efficiency + const typescriptFiles = filterTypescriptFilesForDeepLinks(fileCache); const deepLinkConfigEntries: DeepLinkConfigEntry[] = []; typescriptFiles.forEach(file => { const sourceFile = getTypescriptSourceFile(file.path, file.content); @@ -41,6 +41,12 @@ export function getDeepLinkData(appNgModuleFilePath: string, fileCache: FileCach return deepLinkConfigEntries; } +export function filterTypescriptFilesForDeepLinks(fileCache: FileCache): File[] { + const deepLinksDir = getStringPropertyValue(Constants.ENV_VAR_DEEPLINKS_DIR); + const moduleSuffix = getStringPropertyValue(Constants.ENV_NG_MODULE_FILE_NAME_SUFFIX); + return fileCache.getAll().filter(file => extname(file.path) === '.ts' && file.path.indexOf(moduleSuffix) === -1 && file.path.indexOf(deepLinksDir) >= 0); +} + export function getNgModulePathFromCorrespondingPage(filePath: string) { const newExtension = getStringPropertyValue(Constants.ENV_NG_MODULE_FILE_NAME_SUFFIX); return changeExtension(filePath, newExtension); diff --git a/src/util/config.spec.ts b/src/util/config.spec.ts index f0f7f51c..60875b0d 100644 --- a/src/util/config.spec.ts +++ b/src/util/config.spec.ts @@ -70,6 +70,7 @@ describe('config', () => { expect(context.rootDir).toEqual(process.cwd()); expect(context.tmpDir).toEqual(join(process.cwd(), Constants.TMP_DIR)); expect(context.srcDir).toEqual(join(process.cwd(), Constants.SRC_DIR)); + expect(fakeConfig[Constants.ENV_VAR_DEEPLINKS_DIR]).toEqual(context.srcDir); expect(context.wwwDir).toEqual(join(process.cwd(), Constants.WWW_DIR)); expect(context.wwwIndex).toEqual('index.html'); expect(context.buildDir).toEqual(join(process.cwd(), Constants.WWW_DIR, Constants.BUILD_DIR)); diff --git a/src/util/config.ts b/src/util/config.ts index 153d36c5..a9273e04 100644 --- a/src/util/config.ts +++ b/src/util/config.ts @@ -71,6 +71,10 @@ export function generateContext(context?: BuildContext): BuildContext { setProcessEnvVar(Constants.ENV_VAR_SRC_DIR, context.srcDir); Logger.debug(`srcDir set to ${context.srcDir}`); + const deepLinksDir = resolve(getConfigValue(context, '--deepLinksDir', null, Constants.ENV_VAR_DEEPLINKS_DIR, Constants.ENV_VAR_DEEPLINKS_DIR.toLowerCase(), context.srcDir)); + setProcessEnvVar(Constants.ENV_VAR_DEEPLINKS_DIR, deepLinksDir); + Logger.debug(`deepLinksDir set to ${deepLinksDir}`); + context.wwwDir = resolve(context.wwwDir || getConfigValue(context, '--wwwDir', null, Constants.ENV_VAR_WWW_DIR, Constants.ENV_VAR_WWW_DIR.toLowerCase(), join(context.rootDir, Constants.WWW_DIR))); setProcessEnvVar(Constants.ENV_VAR_WWW_DIR, context.wwwDir); Logger.debug(`wwwDir set to ${context.wwwDir}`); diff --git a/src/util/constants.ts b/src/util/constants.ts index ceb1f88f..bd3f2be5 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -26,6 +26,7 @@ export const ENV_VAR_DEV = 'dev'; export const ENV_VAR_IONIC_ENV = 'IONIC_ENV'; export const ENV_VAR_ROOT_DIR = 'IONIC_ROOT_DIR'; export const ENV_VAR_SRC_DIR = 'IONIC_SRC_DIR'; +export const ENV_VAR_DEEPLINKS_DIR = 'IONIC_DEEPLINKS_DIR'; export const ENV_VAR_PAGES_DIR = 'IONIC_PAGES_DIR'; export const ENV_VAR_COMPONENTS_DIR = 'IONIC_COMPONENTS_DIR'; export const ENV_VAR_DIRECTIVES_DIR = 'IONIC_DIRECTIVES_DIR';