Skip to content
This repository has been archived by the owner on May 1, 2020. It is now read-only.

feat(IonicPage): add config option for module filename #1140

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions src/deep-linking/util.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import { IonicPage, NavController } from 'ionic-angular';

@IonicPage({
name: 'someName',
moduleName: 'someModuleName',
segment: 'someSegmentBro',
defaultHistory: ['page-one', 'page-two'],
priority: 'high'
Expand Down Expand Up @@ -100,8 +101,9 @@ export class HomePage {

const sourceFile = tsUtils.getTypescriptSourceFile(knownPath, knownContent);

const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile);
const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile, knownPath);
expect(result.name).toEqual('someName');
expect(result.moduleName).toEqual('someModuleName');
expect(result.segment).toEqual('someSegmentBro');
expect(result.defaultHistory[0]).toEqual('page-one');
expect(result.defaultHistory[1]).toEqual('page-two');
Expand Down Expand Up @@ -158,7 +160,7 @@ export class HomePage {

const sourceFile = tsUtils.getTypescriptSourceFile(knownPath, knownContent);

const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile);
const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile, knownPath);
expect(result.name).toEqual('HomePage');
expect(result.segment).toEqual('someSegmentBro');
expect(result.defaultHistory[0]).toEqual('page-one');
Expand Down Expand Up @@ -215,7 +217,7 @@ export class HomePage {

const sourceFile = tsUtils.getTypescriptSourceFile(knownPath, knownContent);

const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile);
const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile, knownPath);
expect(result.name).toEqual('HomePage');
expect(result.segment).toEqual('path');
expect(result.defaultHistory[0]).toEqual('page-one');
Expand Down Expand Up @@ -271,7 +273,7 @@ export class HomePage {

const sourceFile = tsUtils.getTypescriptSourceFile(knownPath, knownContent);

const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile);
const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile, knownPath);
expect(result.name).toEqual('HomePage');
expect(result.segment).toEqual('about');
expect(result.defaultHistory).toBeTruthy();
Expand Down Expand Up @@ -326,7 +328,7 @@ export class HomePage {

const sourceFile = tsUtils.getTypescriptSourceFile(knownPath, knownContent);

const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile);
const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile, knownPath);
expect(result.name).toEqual('HomePage');
expect(result.segment).toEqual('path');
expect(result.defaultHistory).toBeTruthy();
Expand Down Expand Up @@ -380,7 +382,7 @@ export class HomePage {

const sourceFile = tsUtils.getTypescriptSourceFile(knownPath, knownContent);

const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile);
const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile, knownPath);
expect(result.name).toEqual('HomePage');
expect(result.segment).toEqual('path');
expect(result.defaultHistory).toBeTruthy();
Expand Down Expand Up @@ -441,7 +443,7 @@ export class HomePage {

try {

util.getDeepLinkDecoratorContentForSourceFile(sourceFile);
util.getDeepLinkDecoratorContentForSourceFile(sourceFile, knownPath);
throw new Error(knownErrorMsg);
} catch (ex) {
expect(ex.message).not.toEqual(knownErrorMsg);
Expand Down Expand Up @@ -490,7 +492,7 @@ export class HomePage {
const knownPath = join(process.cwd(), 'some', 'fake', 'path');

const sourceFile = tsUtils.getTypescriptSourceFile(knownPath, knownContent);
const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile);
const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile, knownPath);
expect(result).toEqual(null);
});

Expand Down Expand Up @@ -533,7 +535,7 @@ export function removeDecorators(fileName: string, source: string): string {
const knownPath = join(process.cwd(), 'some', 'fake', 'path');

const sourceFile = tsUtils.getTypescriptSourceFile(knownPath, knownContent);
const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile);
const result = util.getDeepLinkDecoratorContentForSourceFile(sourceFile, knownPath);
expect(result).toEqual(null);
});
});
Expand All @@ -546,7 +548,7 @@ export function removeDecorators(fileName: string, source: string): string {

spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValue('.module.ts');

const result = util.getNgModulePathFromCorrespondingPage(pagePath);
const result = util.getNgModulePathFromCorrespondingPage(pagePath, null);
expect(result).toEqual(ngModulePath);
});
});
Expand Down Expand Up @@ -1542,6 +1544,7 @@ export class AppModule {}
it('should convert to a flat string format', () => {
const entry: DeepLinkConfigEntry = {
name: 'HomePage',
moduleName: null,
segment: null,
defaultHistory: [],
priority: 'low',
Expand All @@ -1558,6 +1561,7 @@ export class AppModule {}
it('should handle defaultHistory entries and segment', () => {
const entry: DeepLinkConfigEntry = {
name: 'HomePage',
moduleName: null,
segment: 'idkMan',
defaultHistory: ['page-two', 'page-three', 'page-four'],
priority: 'low',
Expand All @@ -1577,6 +1581,7 @@ export class AppModule {}
const list: DeepLinkConfigEntry[] = [];
list.push({
name: 'HomePage',
moduleName: 'someModuleName',
segment: 'idkMan',
defaultHistory: ['page-two', 'page-three', 'page-four'],
priority: 'low',
Expand All @@ -1587,6 +1592,7 @@ export class AppModule {}
});
list.push({
name: 'PageTwo',
moduleName: null,
segment: null,
defaultHistory: [],
priority: 'low',
Expand All @@ -1597,6 +1603,7 @@ export class AppModule {}
});
list.push({
name: 'SettingsPage',
moduleName: null,
segment: null,
defaultHistory: [],
priority: 'low',
Expand Down
26 changes: 19 additions & 7 deletions src/deep-linking/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
import { Logger } from '../logger/logger';
import * as Constants from '../util/constants';
import { FileCache } from '../util/file-cache';
import { changeExtension, getStringPropertyValue, replaceAll, toUnixPath } from '../util/helpers';
import { changeExtension, changeModuleName, getStringPropertyValue, replaceAll, toUnixPath } from '../util/helpers';
import { BuildContext, ChangedFile, DeepLinkConfigEntry, DeepLinkDecoratorAndClass, DeepLinkPathInfo, File } from '../util/interfaces';
import {
appendAfter,
Expand All @@ -38,11 +38,11 @@ export function getDeepLinkData(appNgModuleFilePath: string, fileCache: FileCach
const deepLinkConfigEntries: DeepLinkConfigEntry[] = [];
typescriptFiles.forEach(file => {
const sourceFile = getTypescriptSourceFile(file.path, file.content);
const deepLinkDecoratorData = getDeepLinkDecoratorContentForSourceFile(sourceFile);
const deepLinkDecoratorData = getDeepLinkDecoratorContentForSourceFile(sourceFile, file.path);

if (deepLinkDecoratorData) {
// sweet, the page has a DeepLinkDecorator, which means it meets the criteria to process that bad boy
const pathInfo = getNgModuleDataFromPage(appNgModuleFilePath, file.path, deepLinkDecoratorData.className, fileCache, isAot);
const pathInfo = getNgModuleDataFromPage(appNgModuleFilePath, file.path, deepLinkDecoratorData.className, fileCache, isAot, deepLinkDecoratorData.moduleName);
const deepLinkConfigEntry = Object.assign({}, deepLinkDecoratorData, pathInfo);
deepLinkConfigEntries.push(deepLinkConfigEntry);
}
Expand All @@ -56,18 +56,24 @@ export function filterTypescriptFilesForDeepLinks(fileCache: FileCache): File[]
return fileCache.getAll().filter(file => extname(file.path) === '.ts' && file.path.indexOf(moduleSuffix) === -1 && file.path.indexOf(deepLinksDir) >= 0);
}

export function getNgModulePathFromCorrespondingPage(filePath: string) {
export function getNgModulePathFromCorrespondingPage(filePath: string, moduleName: string) {
const newExtension = getStringPropertyValue(Constants.ENV_NG_MODULE_FILE_NAME_SUFFIX);

if (moduleName) {
filePath = changeModuleName(filePath, moduleName);
}

return changeExtension(filePath, newExtension);
}

export function getRelativePathToPageNgModuleFromAppNgModule(pathToAppNgModule: string, pathToPageNgModule: string) {
return relative(dirname(pathToAppNgModule), pathToPageNgModule);
}

export function getNgModuleDataFromPage(appNgModuleFilePath: string, filePath: string, className: string, fileCache: FileCache, isAot: boolean): DeepLinkPathInfo {
const ngModulePath = getNgModulePathFromCorrespondingPage(filePath);
export function getNgModuleDataFromPage(appNgModuleFilePath: string, filePath: string, className: string, fileCache: FileCache, isAot: boolean, moduleName?: string): DeepLinkPathInfo {
const ngModulePath = getNgModulePathFromCorrespondingPage(filePath, moduleName);
let ngModuleFile = fileCache.get(ngModulePath);

if (!ngModuleFile) {
throw new Error(`${filePath} has a @IonicPage decorator, but it does not have a corresponding "NgModule" at ${ngModulePath}`);
}
Expand All @@ -86,7 +92,7 @@ export function getNgModuleDataFromPage(appNgModuleFilePath: string, filePath: s
};
}

export function getDeepLinkDecoratorContentForSourceFile(sourceFile: SourceFile): DeepLinkDecoratorAndClass {
export function getDeepLinkDecoratorContentForSourceFile(sourceFile: SourceFile, filePath: string): DeepLinkDecoratorAndClass {
const classDeclarations = getClassDeclarations(sourceFile);
const defaultSegment = basename(changeExtension(sourceFile.fileName, ''));
const list: DeepLinkDecoratorAndClass[] = [];
Expand All @@ -106,13 +112,18 @@ export function getDeepLinkDecoratorContentForSourceFile(sourceFile: SourceFile)
propertyList = deepLinkObject.properties;
}

const extension = extname(filePath);
const extensionlessfileName = basename(filePath, extension);

const deepLinkName = getStringValueFromDeepLinkDecorator(sourceFile, propertyList, className, DEEPLINK_DECORATOR_NAME_ATTRIBUTE);
const deepLinkModuleName = getStringValueFromDeepLinkDecorator(sourceFile, propertyList, extensionlessfileName, DEEPLINK_DECORATOR_MODULE_NAME_ATTRIBUTE);
const deepLinkSegment = getStringValueFromDeepLinkDecorator(sourceFile, propertyList, defaultSegment, DEEPLINK_DECORATOR_SEGMENT_ATTRIBUTE);
const deepLinkPriority = getStringValueFromDeepLinkDecorator(sourceFile, propertyList, 'low', DEEPLINK_DECORATOR_PRIORITY_ATTRIBUTE);
const deepLinkDefaultHistory = getArrayValueFromDeepLinkDecorator(sourceFile, propertyList, [], DEEPLINK_DECORATOR_DEFAULT_HISTORY_ATTRIBUTE);
const rawStringContent = getNodeStringContent(sourceFile, decorator.expression);
list.push({
name: deepLinkName,
moduleName: deepLinkModuleName,
segment: deepLinkSegment,
priority: deepLinkPriority,
defaultHistory: deepLinkDefaultHistory,
Expand Down Expand Up @@ -378,6 +389,7 @@ export class ${className}Module {}
const DEEPLINK_DECORATOR_TEXT = 'IonicPage';
const DEEPLINK_DECORATOR_NAME_ATTRIBUTE = 'name';
const DEEPLINK_DECORATOR_SEGMENT_ATTRIBUTE = 'segment';
const DEEPLINK_DECORATOR_MODULE_NAME_ATTRIBUTE = 'moduleName';
const DEEPLINK_DECORATOR_PRIORITY_ATTRIBUTE = 'priority';
const DEEPLINK_DECORATOR_DEFAULT_HISTORY_ATTRIBUTE = 'defaultHistory';

Expand Down
4 changes: 2 additions & 2 deletions src/upgrade-scripts/add-default-ngmodules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ export function readTsFiles(context: BuildContext, tsFilePaths: string[]) {
export function generateAndWriteNgModules(fileCache: FileCache) {
fileCache.getAll().forEach(file => {
const sourceFile = getTypescriptSourceFile(file.path, file.content);
const deepLinkDecoratorData = getDeepLinkDecoratorContentForSourceFile(sourceFile);
const deepLinkDecoratorData = getDeepLinkDecoratorContentForSourceFile(sourceFile, file.path);
if (deepLinkDecoratorData) {
// we have a valid DeepLink decorator
const correspondingNgModulePath = getNgModulePathFromCorrespondingPage(file.path);
const correspondingNgModulePath = getNgModulePathFromCorrespondingPage(file.path, deepLinkDecoratorData.moduleName);
const ngModuleFile = fileCache.get(correspondingNgModulePath);
if (!ngModuleFile) {
// the ngModule file does not exist, so go ahead and create a default one
Expand Down
7 changes: 7 additions & 0 deletions src/util/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,13 @@ export function changeExtension(filePath: string, newExtension: string) {
return join(dir, newFileName);
}

export function changeModuleName(filePath: string, newModuleName: string) {
const dir = dirname(filePath);
const extension = extname(filePath);
const newFileName = newModuleName + extension;
return join(dir, newFileName);
}

export function escapeHtml(unsafe: string) {
return unsafe
.replace(/&/g, '&')
Expand Down
1 change: 1 addition & 0 deletions src/util/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ export interface VirtualFileSystem {

export interface DeepLinkDecoratorAndClass {
name: string;
moduleName: string;
segment: string;
defaultHistory: string[];
priority: string;
Expand Down