1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', { value: true });
|
4 |
|
5 | var path = require('path');
|
6 | var os = require('os');
|
7 |
|
8 | function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
9 |
|
10 | var path__default = _interopDefaultLegacy(path);
|
11 |
|
12 | const toLowerCase = (str) => str.toLowerCase();
|
13 | const dashToPascalCase = (str) => toLowerCase(str)
|
14 | .split('-')
|
15 | .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
|
16 | .join('');
|
17 | function sortBy(array, prop) {
|
18 | return array.slice().sort((a, b) => {
|
19 | const nameA = prop(a);
|
20 | const nameB = prop(b);
|
21 | if (nameA < nameB)
|
22 | return -1;
|
23 | if (nameA > nameB)
|
24 | return 1;
|
25 | return 0;
|
26 | });
|
27 | }
|
28 | function normalizePath(str) {
|
29 |
|
30 |
|
31 |
|
32 | if (typeof str !== 'string') {
|
33 | throw new Error(`invalid path to normalize`);
|
34 | }
|
35 | str = str.trim();
|
36 | if (EXTENDED_PATH_REGEX.test(str) || NON_ASCII_REGEX.test(str)) {
|
37 | return str;
|
38 | }
|
39 | str = str.replace(SLASH_REGEX, '/');
|
40 |
|
41 |
|
42 | if (str.charAt(str.length - 1) === '/') {
|
43 | const colonIndex = str.indexOf(':');
|
44 | if (colonIndex > -1) {
|
45 | if (colonIndex < str.length - 2) {
|
46 | str = str.substring(0, str.length - 1);
|
47 | }
|
48 | }
|
49 | else if (str.length > 1) {
|
50 | str = str.substring(0, str.length - 1);
|
51 | }
|
52 | }
|
53 | return str;
|
54 | }
|
55 | function relativeImport(pathFrom, pathTo, ext) {
|
56 | let relativePath = path__default['default'].relative(path__default['default'].dirname(pathFrom), path__default['default'].dirname(pathTo));
|
57 | if (relativePath === '') {
|
58 | relativePath = '.';
|
59 | }
|
60 | else if (relativePath[0] !== '.') {
|
61 | relativePath = './' + relativePath;
|
62 | }
|
63 | return normalizePath(`${relativePath}/${path__default['default'].basename(pathTo, ext)}`);
|
64 | }
|
65 | async function readPackageJson(config, rootDir) {
|
66 | var _a;
|
67 | const pkgJsonPath = path__default['default'].join(rootDir, 'package.json');
|
68 | let pkgJson;
|
69 | try {
|
70 | pkgJson = (await ((_a = config.sys) === null || _a === void 0 ? void 0 : _a.readFile(pkgJsonPath, 'utf8')));
|
71 | }
|
72 | catch (e) {
|
73 | throw new Error(`Missing "package.json" file for distribution: ${pkgJsonPath}`);
|
74 | }
|
75 | let pkgData;
|
76 | try {
|
77 | pkgData = JSON.parse(pkgJson);
|
78 | }
|
79 | catch (e) {
|
80 | throw new Error(`Error parsing package.json: ${pkgJsonPath}, ${e}`);
|
81 | }
|
82 | return pkgData;
|
83 | }
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 | const formatToQuotedList = (list) => list.map((item) => `'${item}'`).join(', ');
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | const createImportStatement = (imports, module) => {
|
98 | if (imports.length === 0) {
|
99 | return '';
|
100 | }
|
101 | return `import { ${imports.join(', ')} } from '${module}';`;
|
102 | };
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 | const createComponentEventTypeImports = (componentTagName, events, options) => {
|
111 | const { componentCorePackage, includeImportCustomElements, customElementsDir } = options;
|
112 | const imports = [];
|
113 | const namedImports = new Set();
|
114 | const importPathName = normalizePath(componentCorePackage) + (includeImportCustomElements ? `/${customElementsDir || 'components'}` : '');
|
115 | events.forEach((event) => {
|
116 | Object.entries(event.complexType.references).forEach(([typeName, refObject]) => {
|
117 | if (refObject.location === 'local' || refObject.location === 'import') {
|
118 | const newTypeName = `I${componentTagName}${typeName}`;
|
119 |
|
120 | if (!namedImports.has(newTypeName)) {
|
121 | imports.push(`import type { ${typeName} as ${newTypeName} } from '${importPathName}';`);
|
122 | namedImports.add(newTypeName);
|
123 | }
|
124 | }
|
125 | });
|
126 | });
|
127 | return imports.join('\n');
|
128 | };
|
129 | const EXTENDED_PATH_REGEX = /^\\\\\?\\/;
|
130 | const NON_ASCII_REGEX = /[^\x00-\x80]+/;
|
131 | const SLASH_REGEX = /\\/g;
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 | const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false) => {
|
144 | const tagNameAsPascal = dashToPascalCase(tagName);
|
145 | const hasInputs = inputs.length > 0;
|
146 | const hasOutputs = outputs.length > 0;
|
147 | const hasMethods = methods.length > 0;
|
148 |
|
149 | const formattedInputs = formatToQuotedList(inputs);
|
150 |
|
151 | const formattedOutputs = formatToQuotedList(outputs);
|
152 |
|
153 | const formattedMethods = formatToQuotedList(methods);
|
154 | const proxyCmpOptions = [];
|
155 | if (includeImportCustomElements) {
|
156 | const defineCustomElementFn = `define${tagNameAsPascal}`;
|
157 | proxyCmpOptions.push(`\n defineCustomElementFn: ${defineCustomElementFn}`);
|
158 | }
|
159 | if (hasInputs) {
|
160 | proxyCmpOptions.push(`\n inputs: [${formattedInputs}]`);
|
161 | }
|
162 | if (hasMethods) {
|
163 | proxyCmpOptions.push(`\n methods: [${formattedMethods}]`);
|
164 | }
|
165 | |
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 | const output = `@ProxyCmp({${proxyCmpOptions.join(',')}\n})
|
173 | @Component({
|
174 | selector: '${tagName}',
|
175 | changeDetection: ChangeDetectionStrategy.OnPush,
|
176 | template: '<ng-content></ng-content>',
|
177 | // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
178 | inputs: [${formattedInputs}],
|
179 | })
|
180 | export class ${tagNameAsPascal} {
|
181 | protected el: HTMLElement;
|
182 | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
183 | c.detach();
|
184 | this.el = r.nativeElement;${hasOutputs
|
185 | ? `
|
186 | proxyOutputs(this, this.el, [${formattedOutputs}]);`
|
187 | : ''}
|
188 | }
|
189 | }`;
|
190 | return output;
|
191 | };
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 | const formatOutputType = (componentClassName, event) => {
|
199 | |
200 |
|
201 |
|
202 |
|
203 |
|
204 | return Object.entries(event.complexType.references)
|
205 | .filter(([_, refObject]) => refObject.location === 'local' || refObject.location === 'import')
|
206 | .reduce((type, [src, dst]) => {
|
207 | const renamedType = `I${componentClassName}${type}`;
|
208 | return (renamedType
|
209 | .replace(new RegExp(`^${src}$`, 'g'), `${dst}`)
|
210 |
|
211 | .replace(new RegExp(`([^\\w])${src}([^\\w])`, 'g'), (v, p1, p2) => [p1, dst, p2].join('')));
|
212 | }, event.complexType.original
|
213 | .replace(/\n/g, ' ')
|
214 | .replace(/\s{2,}/g, ' ')
|
215 | .replace(/,\s*/g, ', '));
|
216 | };
|
217 |
|
218 |
|
219 |
|
220 |
|
221 |
|
222 | const createDocComment = (doc) => {
|
223 | if (doc.text.trim().length === 0 && doc.tags.length === 0) {
|
224 | return '';
|
225 | }
|
226 | return `/**
|
227 | * ${doc.text}${doc.tags.length > 0 ? ' ' : ''}${doc.tags.map((tag) => `@${tag.name} ${tag.text}`)}
|
228 | */`;
|
229 | };
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 | const createComponentTypeDefinition = (tagNameAsPascal, events, componentCorePackage, includeImportCustomElements = false, customElementsDir) => {
|
240 | const publicEvents = events.filter((ev) => !ev.internal);
|
241 | const eventTypeImports = createComponentEventTypeImports(tagNameAsPascal, publicEvents, {
|
242 | componentCorePackage,
|
243 | includeImportCustomElements,
|
244 | customElementsDir,
|
245 | });
|
246 | const eventTypes = publicEvents.map((event) => {
|
247 | const comment = createDocComment(event.docs);
|
248 | let eventName = event.name;
|
249 | if (event.name.includes('-')) {
|
250 |
|
251 |
|
252 | eventName = `'${event.name}'`;
|
253 | }
|
254 | return `${comment.length > 0 ? ` ${comment}` : ''}
|
255 | ${eventName}: EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>;`;
|
256 | });
|
257 | const interfaceDeclaration = `export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {`;
|
258 | const typeDefinition = (eventTypeImports.length > 0 ? `${eventTypeImports + '\n\n'}` : '') +
|
259 | `${interfaceDeclaration}${eventTypes.length === 0
|
260 | ? '}'
|
261 | : `
|
262 | ${eventTypes.join('\n')}
|
263 | }`}`;
|
264 | return typeDefinition;
|
265 | };
|
266 |
|
267 | function generateAngularDirectivesFile(compilerCtx, components, outputTarget) {
|
268 |
|
269 | if (!outputTarget.directivesArrayFile) {
|
270 | return Promise.resolve();
|
271 | }
|
272 | const proxyPath = relativeImport(outputTarget.directivesArrayFile, outputTarget.directivesProxyFile, '.ts');
|
273 | const directives = components
|
274 | .map((cmpMeta) => dashToPascalCase(cmpMeta.tagName))
|
275 | .map((className) => `d.${className}`)
|
276 | .join(',\n ');
|
277 | const c = `
|
278 | import * as d from '${proxyPath}';
|
279 |
|
280 | export const DIRECTIVES = [
|
281 | ${directives}
|
282 | ];
|
283 | `;
|
284 | return compilerCtx.fs.writeFile(outputTarget.directivesArrayFile, c);
|
285 | }
|
286 |
|
287 | async function generateValueAccessors(compilerCtx, components, outputTarget, config) {
|
288 | if (!Array.isArray(outputTarget.valueAccessorConfigs) || outputTarget.valueAccessorConfigs.length === 0) {
|
289 | return;
|
290 | }
|
291 | const targetDir = path__default['default'].dirname(outputTarget.directivesProxyFile);
|
292 | const normalizedValueAccessors = outputTarget.valueAccessorConfigs.reduce((allAccessors, va) => {
|
293 | const elementSelectors = Array.isArray(va.elementSelectors) ? va.elementSelectors : [va.elementSelectors];
|
294 | const type = va.type;
|
295 | let allElementSelectors = [];
|
296 | let allEventTargets = [];
|
297 | if (allAccessors.hasOwnProperty(type)) {
|
298 | allElementSelectors = allAccessors[type].elementSelectors;
|
299 | allEventTargets = allAccessors[type].eventTargets;
|
300 | }
|
301 | return Object.assign(Object.assign({}, allAccessors), { [type]: {
|
302 | elementSelectors: allElementSelectors.concat(elementSelectors),
|
303 | eventTargets: allEventTargets.concat([[va.event, va.targetAttr]]),
|
304 | } });
|
305 | }, {});
|
306 | await Promise.all(Object.keys(normalizedValueAccessors).map(async (type) => {
|
307 | const valueAccessorType = type;
|
308 | const targetFileName = `${type}-value-accessor.ts`;
|
309 | const targetFilePath = path__default['default'].join(targetDir, targetFileName);
|
310 | const srcFilePath = path__default['default'].join(__dirname, '../resources/control-value-accessors/', targetFileName);
|
311 | const srcFileContents = await compilerCtx.fs.readFile(srcFilePath);
|
312 | const finalText = createValueAccessor(srcFileContents, normalizedValueAccessors[valueAccessorType]);
|
313 | await compilerCtx.fs.writeFile(targetFilePath, finalText);
|
314 | }));
|
315 | await copyResources(config, ['value-accessor.ts'], targetDir);
|
316 | }
|
317 | function createValueAccessor(srcFileContents, valueAccessor) {
|
318 | const hostContents = valueAccessor.eventTargets.map((listItem) => VALUE_ACCESSOR_EVENTTARGETS.replace(VALUE_ACCESSOR_EVENT, listItem[0]).replace(VALUE_ACCESSOR_TARGETATTR, listItem[1]));
|
319 | return srcFileContents
|
320 | .replace(VALUE_ACCESSOR_SELECTORS, valueAccessor.elementSelectors.join(', '))
|
321 | .replace(VALUE_ACCESSOR_EVENTTARGETS, hostContents.join(`,${os.EOL}`));
|
322 | }
|
323 | function copyResources(config, resourcesFilesToCopy, directory) {
|
324 | if (!config.sys || !config.sys.copy) {
|
325 | throw new Error('stencil is not properly intialized at this step. Notify the developer');
|
326 | }
|
327 | const copyTasks = resourcesFilesToCopy.map((rf) => {
|
328 | return {
|
329 | src: path__default['default'].join(__dirname, '../resources/control-value-accessors/', rf),
|
330 | dest: path__default['default'].join(directory, rf),
|
331 | keepDirStructure: false,
|
332 | warn: false,
|
333 | };
|
334 | });
|
335 | return config.sys.copy(copyTasks, path__default['default'].join(directory));
|
336 | }
|
337 | const VALUE_ACCESSOR_SELECTORS = `<VALUE_ACCESSOR_SELECTORS>`;
|
338 | const VALUE_ACCESSOR_EVENT = `<VALUE_ACCESSOR_EVENT>`;
|
339 | const VALUE_ACCESSOR_TARGETATTR = '<VALUE_ACCESSOR_TARGETATTR>';
|
340 | const VALUE_ACCESSOR_EVENTTARGETS = ` '(<VALUE_ACCESSOR_EVENT>)': 'handleChangeEvent($event.target.<VALUE_ACCESSOR_TARGETATTR>)'`;
|
341 |
|
342 |
|
343 |
|
344 |
|
345 |
|
346 |
|
347 | const generateAngularModuleForComponent = (componentTagName) => {
|
348 | const tagNameAsPascal = dashToPascalCase(componentTagName);
|
349 | const componentClassName = `${tagNameAsPascal}`;
|
350 | const moduleClassName = `${tagNameAsPascal}Module`;
|
351 | const moduleDefinition = `@NgModule({
|
352 | declarations: [${componentClassName}],
|
353 | exports: [${componentClassName}]
|
354 | })
|
355 | export class ${moduleClassName} { }`;
|
356 | return moduleDefinition;
|
357 | };
|
358 |
|
359 | async function angularDirectiveProxyOutput(compilerCtx, outputTarget, components, config) {
|
360 | const filteredComponents = getFilteredComponents(outputTarget.excludeComponents, components);
|
361 | const rootDir = config.rootDir;
|
362 | const pkgData = await readPackageJson(config, rootDir);
|
363 | const finalText = generateProxies(filteredComponents, pkgData, outputTarget, config.rootDir);
|
364 | await Promise.all([
|
365 | compilerCtx.fs.writeFile(outputTarget.directivesProxyFile, finalText),
|
366 | copyResources$1(config, outputTarget),
|
367 | generateAngularDirectivesFile(compilerCtx, filteredComponents, outputTarget),
|
368 | generateValueAccessors(compilerCtx, filteredComponents, outputTarget, config),
|
369 | ]);
|
370 | }
|
371 | function getFilteredComponents(excludeComponents = [], cmps) {
|
372 | return sortBy(cmps, (cmp) => cmp.tagName).filter((c) => !excludeComponents.includes(c.tagName) && !c.internal);
|
373 | }
|
374 | async function copyResources$1(config, outputTarget) {
|
375 | if (!config.sys || !config.sys.copy || !config.sys.glob) {
|
376 | throw new Error('stencil is not properly initialized at this step. Notify the developer');
|
377 | }
|
378 | const srcDirectory = path__default['default'].join(__dirname, '..', 'angular-component-lib');
|
379 | const destDirectory = path__default['default'].join(path__default['default'].dirname(outputTarget.directivesProxyFile), 'angular-component-lib');
|
380 | return config.sys.copy([
|
381 | {
|
382 | src: srcDirectory,
|
383 | dest: destDirectory,
|
384 | keepDirStructure: false,
|
385 | warn: false,
|
386 | },
|
387 | ], srcDirectory);
|
388 | }
|
389 | function generateProxies(components, pkgData, outputTarget, rootDir) {
|
390 | var _a;
|
391 | const distTypesDir = path__default['default'].dirname(pkgData.types);
|
392 | const dtsFilePath = path__default['default'].join(rootDir, distTypesDir, GENERATED_DTS);
|
393 | const componentsTypeFile = relativeImport(outputTarget.directivesProxyFile, dtsFilePath, '.d.ts');
|
394 | const includeSingleComponentAngularModules = (_a = outputTarget.includeSingleComponentAngularModules) !== null && _a !== void 0 ? _a : false;
|
395 | const includeOutputImports = components.some((component) => component.events.some((event) => !event.internal));
|
396 | |
397 |
|
398 |
|
399 | const angularCoreImports = ['ChangeDetectionStrategy', 'ChangeDetectorRef', 'Component', 'ElementRef'];
|
400 | if (includeOutputImports) {
|
401 | angularCoreImports.push('EventEmitter');
|
402 | }
|
403 | angularCoreImports.push('NgZone');
|
404 | |
405 |
|
406 |
|
407 | const componentLibImports = ['ProxyCmp'];
|
408 | if (includeOutputImports) {
|
409 | componentLibImports.push('proxyOutputs');
|
410 | }
|
411 | if (includeSingleComponentAngularModules) {
|
412 | angularCoreImports.push('NgModule');
|
413 | }
|
414 | const imports = `/* tslint:disable */
|
415 | /* auto-generated angular directive proxies */
|
416 | ${createImportStatement(angularCoreImports, '@angular/core')}
|
417 |
|
418 | ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n`;
|
419 | |
420 |
|
421 |
|
422 |
|
423 |
|
424 |
|
425 | const generateTypeImports = () => {
|
426 | let importLocation = outputTarget.componentCorePackage
|
427 | ? normalizePath(outputTarget.componentCorePackage)
|
428 | : normalizePath(componentsTypeFile);
|
429 | importLocation += outputTarget.includeImportCustomElements
|
430 | ? `/${outputTarget.customElementsDir || 'components'}`
|
431 | : '';
|
432 | return `import ${outputTarget.includeImportCustomElements ? 'type ' : ''}{ ${IMPORT_TYPES} } from '${importLocation}';\n`;
|
433 | };
|
434 | const typeImports = generateTypeImports();
|
435 | let sourceImports = '';
|
436 | |
437 |
|
438 |
|
439 |
|
440 |
|
441 |
|
442 | if (outputTarget.includeImportCustomElements && outputTarget.componentCorePackage !== undefined) {
|
443 | const cmpImports = components.map((component) => {
|
444 | const pascalImport = dashToPascalCase(component.tagName);
|
445 | return `import { defineCustomElement as define${pascalImport} } from '${normalizePath(outputTarget.componentCorePackage)}/${outputTarget.customElementsDir || 'components'}/${component.tagName}.js';`;
|
446 | });
|
447 | sourceImports = cmpImports.join('\n');
|
448 | }
|
449 | if (includeSingleComponentAngularModules) {
|
450 |
|
451 | if (!outputTarget.includeImportCustomElements) {
|
452 | throw new Error('Generating single component Angular modules requires the "includeImportCustomElements" option to be set to true.');
|
453 | }
|
454 | }
|
455 | const proxyFileOutput = [];
|
456 | const filterInternalProps = (prop) => !prop.internal;
|
457 | const mapPropName = (prop) => prop.name;
|
458 | const { includeImportCustomElements, componentCorePackage, customElementsDir } = outputTarget;
|
459 | for (let cmpMeta of components) {
|
460 | const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
461 | const inputs = [];
|
462 | if (cmpMeta.properties) {
|
463 | inputs.push(...cmpMeta.properties.filter(filterInternalProps).map(mapPropName));
|
464 | }
|
465 | if (cmpMeta.virtualProperties) {
|
466 | inputs.push(...cmpMeta.virtualProperties.map(mapPropName));
|
467 | }
|
468 | inputs.sort();
|
469 | const outputs = [];
|
470 | if (cmpMeta.events) {
|
471 | outputs.push(...cmpMeta.events.filter(filterInternalProps).map(mapPropName));
|
472 | }
|
473 | const methods = [];
|
474 | if (cmpMeta.methods) {
|
475 | methods.push(...cmpMeta.methods.filter(filterInternalProps).map(mapPropName));
|
476 | }
|
477 | |
478 |
|
479 |
|
480 |
|
481 |
|
482 |
|
483 | const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, includeImportCustomElements);
|
484 | const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName);
|
485 | const componentTypeDefinition = createComponentTypeDefinition(tagNameAsPascal, cmpMeta.events, componentCorePackage, includeImportCustomElements, customElementsDir);
|
486 | proxyFileOutput.push(componentDefinition, '\n');
|
487 | if (includeSingleComponentAngularModules) {
|
488 | proxyFileOutput.push(moduleDefinition, '\n');
|
489 | }
|
490 | proxyFileOutput.push(componentTypeDefinition, '\n');
|
491 | }
|
492 | const final = [imports, typeImports, sourceImports, ...proxyFileOutput];
|
493 | return final.join('\n') + '\n';
|
494 | }
|
495 | const GENERATED_DTS = 'components.d.ts';
|
496 | const IMPORT_TYPES = 'Components';
|
497 |
|
498 | const angularOutputTarget = (outputTarget) => ({
|
499 | type: 'custom',
|
500 | name: 'angular-library',
|
501 | validate(config) {
|
502 | return normalizeOutputTarget(config, outputTarget);
|
503 | },
|
504 | async generator(config, compilerCtx, buildCtx) {
|
505 | const timespan = buildCtx.createTimeSpan(`generate angular proxies started`, true);
|
506 | await angularDirectiveProxyOutput(compilerCtx, outputTarget, buildCtx.components, config);
|
507 | timespan.finish(`generate angular proxies finished`);
|
508 | },
|
509 | });
|
510 | function normalizeOutputTarget(config, outputTarget) {
|
511 | const results = Object.assign(Object.assign({}, outputTarget), { excludeComponents: outputTarget.excludeComponents || [], valueAccessorConfigs: outputTarget.valueAccessorConfigs || [] });
|
512 | if (config.rootDir == null) {
|
513 | throw new Error('rootDir is not set and it should be set by stencil itself');
|
514 | }
|
515 | if (outputTarget.directivesProxyFile == null) {
|
516 | throw new Error('directivesProxyFile is required. Please set it in the Stencil config.');
|
517 | }
|
518 | if (outputTarget.directivesProxyFile && !path__default['default'].isAbsolute(outputTarget.directivesProxyFile)) {
|
519 | results.directivesProxyFile = normalizePath(path__default['default'].join(config.rootDir, outputTarget.directivesProxyFile));
|
520 | }
|
521 | if (outputTarget.directivesArrayFile && !path__default['default'].isAbsolute(outputTarget.directivesArrayFile)) {
|
522 | results.directivesArrayFile = normalizePath(path__default['default'].join(config.rootDir, outputTarget.directivesArrayFile));
|
523 | }
|
524 | if (outputTarget.includeSingleComponentAngularModules !== undefined) {
|
525 | console.warn('**Experimental**: includeSingleComponentAngularModules is a developer preview feature and may change or be removed in the future.');
|
526 | }
|
527 | return results;
|
528 | }
|
529 |
|
530 | exports.angularOutputTarget = angularOutputTarget;
|