Skip to content

Commit eab5873

Browse files
clydindgp1130
authored andcommitted
fix(@schematics/angular): migrate localized base HREF options for 9.0
(cherry picked from commit df4c035)
1 parent 6e0e14e commit eab5873

File tree

2 files changed

+120
-6
lines changed

2 files changed

+120
-6
lines changed

packages/schematics/angular/migrations/update-9/update-workspace-config.ts

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,16 @@ function addProjectI18NOptions(
7070
return;
7171
}
7272

73+
const mainOptions = findPropertyInAstObject(browserConfig, 'options');
74+
const mainBaseHref =
75+
mainOptions &&
76+
mainOptions.kind === 'object' &&
77+
findPropertyInAstObject(mainOptions, 'baseHref');
78+
const hasMainBaseHref =
79+
!!mainBaseHref && mainBaseHref.kind === 'string' && mainBaseHref.value !== '/';
80+
7381
// browser builder options
74-
let locales: Record<string, string> | undefined;
82+
let locales: Record<string, string | { translation: string; baseHref: string }> | undefined;
7583
const options = getAllOptions(browserConfig);
7684
for (const option of options) {
7785
const localeId = findPropertyInAstObject(option, 'i18nLocale');
@@ -87,12 +95,37 @@ function addProjectI18NOptions(
8795
const localIdValue = localeId.value;
8896
const localeFileValue = localeFile.value;
8997

98+
const baseHref = findPropertyInAstObject(option, 'baseHref');
99+
let baseHrefValue;
100+
// if the main options has a non-default base href, the i18n configuration
101+
// for the locale baseHref is disabled to more obviously mimic existing behavior
102+
if (baseHref && !hasMainBaseHref) {
103+
if (baseHref.kind === 'string' && baseHref.value !== `/${localIdValue}/`) {
104+
baseHrefValue = baseHref.value;
105+
}
106+
} else {
107+
// If the configuration does not contain a baseHref, ensure the main option value is used.
108+
baseHrefValue = '';
109+
}
110+
90111
if (!locales) {
91112
locales = {
92-
[localIdValue]: localeFileValue,
113+
[localIdValue]:
114+
baseHrefValue === undefined
115+
? localeFileValue
116+
: {
117+
translation: localeFileValue,
118+
baseHref: baseHrefValue,
119+
},
93120
};
94121
} else {
95-
locales[localIdValue] = localeFileValue;
122+
locales[localIdValue] =
123+
baseHrefValue === undefined
124+
? localeFileValue
125+
: {
126+
translation: localeFileValue,
127+
baseHref: baseHrefValue,
128+
};
96129
}
97130
}
98131

@@ -127,6 +160,13 @@ function addProjectI18NOptions(
127160

128161
function addBuilderI18NOptions(recorder: UpdateRecorder, builderConfig: JsonAstObject, projectConfig: JsonAstObject) {
129162
const options = getAllOptions(builderConfig);
163+
const mainOptions = findPropertyInAstObject(builderConfig, 'options');
164+
const mainBaseHref =
165+
mainOptions &&
166+
mainOptions.kind === 'object' &&
167+
findPropertyInAstObject(mainOptions, 'baseHref');
168+
const hasMainBaseHref =
169+
!!mainBaseHref && mainBaseHref.kind === 'string' && mainBaseHref.value !== '/';
130170

131171
for (const option of options) {
132172
const localeId = findPropertyInAstObject(option, 'i18nLocale');
@@ -145,6 +185,14 @@ function addBuilderI18NOptions(recorder: UpdateRecorder, builderConfig: JsonAstO
145185
if (i18nFormat) {
146186
removePropertyInAstObject(recorder, option, 'i18nFormat');
147187
}
188+
189+
// localize base HREF values are controlled by the i18n configuration
190+
// except if the main options has a non-default base href, the i18n configuration
191+
// for the locale baseHref is disabled in that case to more obviously mimic existing behavior
192+
const baseHref = findPropertyInAstObject(option, 'baseHref');
193+
if (localeId && i18nFile && baseHref && !hasMainBaseHref) {
194+
removePropertyInAstObject(recorder, option, 'baseHref');
195+
}
148196
}
149197
}
150198

packages/schematics/angular/migrations/update-9/update-workspace-config_spec.ts

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,42 @@ describe('Migration to version 9', () => {
350350
expect(config.configurations.de.i18nLocale).toBeUndefined();
351351
});
352352

353+
it('should remove baseHref option when used with i18n options and no main base href', async () => {
354+
let config = getWorkspaceTargets(tree);
355+
config.build.configurations.fr = { ...getI18NConfig('fr'), baseHref: '/fr/' };
356+
config.build.configurations.de = { ...getI18NConfig('de'), baseHref: '/abc/' };
357+
updateWorkspaceTargets(tree, config);
358+
359+
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
360+
config = getWorkspaceTargets(tree2).build;
361+
expect(config.configurations.fr.baseHref).toBeUndefined();
362+
expect(config.configurations.de.baseHref).toBeUndefined();
363+
});
364+
365+
it('should keep baseHref option when not used with i18n options', async () => {
366+
let config = getWorkspaceTargets(tree);
367+
config.build.options = getI18NConfig('fr');
368+
config.build.configurations.de = getI18NConfig('de');
369+
config.build.configurations.staging = { baseHref: '/de/' };
370+
updateWorkspaceTargets(tree, config);
371+
372+
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
373+
config = getWorkspaceTargets(tree2).build;
374+
expect(config.configurations.staging.baseHref).toBe('/de/');
375+
});
376+
377+
it('should keep baseHref options when used with i18n options and main baseHref option', async () => {
378+
let config = getWorkspaceTargets(tree);
379+
config.build.options = { baseHref: '/my-app/' };
380+
config.build.configurations.de = { ...getI18NConfig('de'), baseHref: '/de/' };
381+
updateWorkspaceTargets(tree, config);
382+
383+
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
384+
config = getWorkspaceTargets(tree2).build;
385+
expect(config.options.baseHref).toBe('/my-app/');
386+
expect(config.configurations.de.baseHref).toBe('/de/');
387+
});
388+
353389
it('should remove deprecated extract-i18n options', async () => {
354390
let config = getWorkspaceTargets(tree);
355391
config['extract-i18n'].options.i18nFormat = 'xmb';
@@ -379,19 +415,49 @@ describe('Migration to version 9', () => {
379415

380416
it(`should add i18n 'locales' project config`, async () => {
381417
const config = getWorkspaceTargets(tree);
382-
config.build.options.aot = false;
383-
config.build.options = getI18NConfig('fr');
418+
config.build.configurations.fr = getI18NConfig('fr');
384419
config.build.configurations.de = getI18NConfig('de');
385420
updateWorkspaceTargets(tree, config);
386421

387422
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
388423
const projectConfig = JSON.parse(tree2.readContent(workspacePath)).projects['migration-test'];
389424
expect(projectConfig.i18n.sourceLocale).toBeUndefined();
390425
expect(projectConfig.i18n.locales).toEqual({
391-
de: 'src/locale/messages.de.xlf',
426+
de: { translation: 'src/locale/messages.de.xlf', baseHref: '' },
427+
fr: { translation: 'src/locale/messages.fr.xlf', baseHref: '' },
428+
});
429+
});
430+
431+
it(`should add i18n 'locales' project config when using baseHref options`, async () => {
432+
const config = getWorkspaceTargets(tree);
433+
config.build.configurations.fr = { ...getI18NConfig('fr'), baseHref: '/fr/' };
434+
config.build.configurations.de = { ...getI18NConfig('de'), baseHref: '/abc/' };
435+
updateWorkspaceTargets(tree, config);
436+
437+
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
438+
const projectConfig = JSON.parse(tree2.readContent(workspacePath)).projects['migration-test'];
439+
expect(projectConfig.i18n.sourceLocale).toBeUndefined();
440+
expect(projectConfig.i18n.locales).toEqual({
441+
de: { translation: 'src/locale/messages.de.xlf', baseHref: '/abc/' },
392442
fr: 'src/locale/messages.fr.xlf',
393443
});
394444
});
445+
446+
it(`should add i18n 'locales' project config when using baseHref options and main base href`, async () => {
447+
const config = getWorkspaceTargets(tree);
448+
config.build.options = { baseHref: '/my-app/' };
449+
config.build.configurations.fr = { ...getI18NConfig('fr'), baseHref: '/fr/' };
450+
config.build.configurations.de = { ...getI18NConfig('de'), baseHref: '/abc/' };
451+
updateWorkspaceTargets(tree, config);
452+
453+
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
454+
const projectConfig = JSON.parse(tree2.readContent(workspacePath)).projects['migration-test'];
455+
expect(projectConfig.i18n.sourceLocale).toBeUndefined();
456+
expect(projectConfig.i18n.locales).toEqual({
457+
de: { translation: 'src/locale/messages.de.xlf', baseHref: '' },
458+
fr: { translation: 'src/locale/messages.fr.xlf', baseHref: '' },
459+
});
460+
});
395461
});
396462

397463
describe('when i18n builder options are not set', () => {

0 commit comments

Comments
 (0)