@stencil/angular-output-target 0.0.6 → 0.2.1-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/angular-component-lib/utils.ts +11 -8
- package/dist/generate-angular-component.js +46 -18
- package/dist/generate-angular-directives-file.js +1 -1
- package/dist/generate-value-accessors.d.ts +5 -0
- package/dist/generate-value-accessors.js +3 -2
- package/dist/index.cjs.js +77 -44
- package/dist/index.js +50 -20
- package/dist/output-angular.js +1 -1
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +3 -0
- package/package.json +1 -1
|
@@ -1,36 +1,39 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
/* tslint:disable */
|
|
1
3
|
import { fromEvent } from 'rxjs';
|
|
2
4
|
|
|
3
5
|
export const proxyInputs = (Cmp: any, inputs: string[]) => {
|
|
4
6
|
const Prototype = Cmp.prototype;
|
|
5
|
-
inputs.forEach(
|
|
7
|
+
inputs.forEach(item => {
|
|
6
8
|
Object.defineProperty(Prototype, item, {
|
|
7
9
|
get() {
|
|
8
10
|
return this.el[item];
|
|
9
11
|
},
|
|
10
12
|
set(val: any) {
|
|
11
13
|
this.z.runOutsideAngular(() => (this.el[item] = val));
|
|
12
|
-
}
|
|
14
|
+
}
|
|
13
15
|
});
|
|
14
16
|
});
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
export const proxyMethods = (Cmp: any, methods: string[]) => {
|
|
18
20
|
const Prototype = Cmp.prototype;
|
|
19
|
-
methods.forEach(
|
|
21
|
+
methods.forEach(methodName => {
|
|
20
22
|
Prototype[methodName] = function () {
|
|
21
23
|
const args = arguments;
|
|
22
|
-
return this.z.runOutsideAngular(() =>
|
|
24
|
+
return this.z.runOutsideAngular(() =>
|
|
25
|
+
this.el[methodName].apply(this.el, args)
|
|
26
|
+
);
|
|
23
27
|
};
|
|
24
28
|
});
|
|
25
29
|
};
|
|
26
30
|
|
|
27
31
|
export const proxyOutputs = (instance: any, el: any, events: string[]) => {
|
|
28
|
-
events.forEach(
|
|
29
|
-
}
|
|
32
|
+
events.forEach(eventName => instance[eventName] = fromEvent(el, eventName));
|
|
33
|
+
}
|
|
30
34
|
|
|
31
|
-
// tslint:disable-next-line: only-arrow-functions
|
|
32
35
|
export function ProxyCmp(opts: { inputs?: any; methods?: any }) {
|
|
33
|
-
const decorator = function
|
|
36
|
+
const decorator = function(cls: any) {
|
|
34
37
|
if (opts.inputs) {
|
|
35
38
|
proxyInputs(cls, opts.inputs);
|
|
36
39
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { dashToPascalCase, normalizePath } from './utils';
|
|
1
|
+
import { dashToPascalCase } from './utils';
|
|
3
2
|
export const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir) => (cmpMeta) => {
|
|
4
3
|
// Collect component meta
|
|
5
4
|
const inputs = [
|
|
@@ -19,30 +18,59 @@ export const createComponentDefinition = (componentCorePackage, distTypesDir, ro
|
|
|
19
18
|
if (inputs.length > 0) {
|
|
20
19
|
directiveOpts.push(`inputs: ['${inputs.join(`', '`)}']`);
|
|
21
20
|
}
|
|
22
|
-
if (outputs.length > 0) {
|
|
23
|
-
directiveOpts.push(`outputs: ['${outputs.map((output) => output.name).join(`', '`)}']`);
|
|
24
|
-
}
|
|
25
21
|
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
const outputsInterface = new Set();
|
|
23
|
+
const outputReferenceRemap = {};
|
|
24
|
+
outputs.forEach((output) => {
|
|
25
|
+
Object.entries(output.complexType.references).forEach(([reference, refObject]) => {
|
|
26
|
+
// Add import line for each local/import reference, and add new mapping name.
|
|
27
|
+
// `outputReferenceRemap` should be updated only if the import interface is set in outputsInterface,
|
|
28
|
+
// this will prevent global types to be remapped.
|
|
29
|
+
const remappedReference = `I${cmpMeta.componentClassName}${reference}`;
|
|
30
|
+
if (refObject.location === 'local' || refObject.location === 'import') {
|
|
31
|
+
outputReferenceRemap[reference] = remappedReference;
|
|
32
|
+
outputsInterface.add(`import { ${reference} as ${remappedReference} } from '${componentCorePackage}';`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
const componentEvents = [
|
|
37
|
+
'' // Empty first line
|
|
38
|
+
];
|
|
39
|
+
// Generate outputs
|
|
40
|
+
outputs.forEach((output, index) => {
|
|
41
|
+
componentEvents.push(` /**
|
|
42
|
+
* ${output.docs.text} ${output.docs.tags.map((tag) => `@${tag.name} ${tag.text}`)}
|
|
43
|
+
*/`);
|
|
44
|
+
/**
|
|
45
|
+
* The original attribute contains the original type defined by the devs.
|
|
46
|
+
* This regexp normalizes the reference, by removing linebreaks,
|
|
47
|
+
* replacing consecutive spaces with a single space, and adding a single space after commas.
|
|
48
|
+
**/
|
|
49
|
+
const outputTypeRemapped = Object.entries(outputReferenceRemap).reduce((type, [src, dst]) => {
|
|
50
|
+
return type
|
|
51
|
+
.replace(new RegExp(`^${src}$`, 'g'), `${dst}`)
|
|
52
|
+
.replace(new RegExp(`([^\\w])${src}([^\\w])`, 'g'), (v, p1, p2) => [p1, dst, p2].join(''));
|
|
53
|
+
}, output.complexType.original
|
|
54
|
+
.replace(/\n/g, ' ')
|
|
55
|
+
.replace(/\s{2,}/g, ' ')
|
|
56
|
+
.replace(/,\s*/g, ', '));
|
|
57
|
+
componentEvents.push(` ${output.name}: EventEmitter<CustomEvent<${outputTypeRemapped.trim()}>>;`);
|
|
58
|
+
if (index === outputs.length - 1) {
|
|
59
|
+
// Empty line to push end `}` to new line
|
|
60
|
+
componentEvents.push('\n');
|
|
61
|
+
}
|
|
62
|
+
});
|
|
31
63
|
const lines = [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {}
|
|
64
|
+
'',
|
|
65
|
+
`${[...outputsInterface].join('\n')}
|
|
66
|
+
export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {${componentEvents.length > 1 ? componentEvents.join('\n') : ''}}
|
|
67
|
+
|
|
35
68
|
${getProxyCmp(inputs, methods)}
|
|
36
69
|
@Component({
|
|
37
70
|
${directiveOpts.join(',\n ')}
|
|
38
71
|
})
|
|
39
72
|
export class ${tagNameAsPascal} {`,
|
|
40
73
|
];
|
|
41
|
-
// Generate outputs
|
|
42
|
-
outputs.forEach((output) => {
|
|
43
|
-
lines.push(` /** ${output.docs.text} ${output.docs.tags.map((tag) => `@${tag.name} ${tag.text}`)}*/`);
|
|
44
|
-
lines.push(` ${output.name}!: I${cmpMeta.componentClassName}['${output.method}'];`);
|
|
45
|
-
});
|
|
46
74
|
lines.push(' protected el: HTMLElement;');
|
|
47
75
|
lines.push(` constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
|
48
76
|
c.detach();
|
|
@@ -13,7 +13,7 @@ export function generateAngularDirectivesFile(compilerCtx, components, outputTar
|
|
|
13
13
|
import * as d from '${proxyPath}';
|
|
14
14
|
|
|
15
15
|
export const DIRECTIVES = [
|
|
16
|
-
${directives}
|
|
16
|
+
${directives}
|
|
17
17
|
];
|
|
18
18
|
`;
|
|
19
19
|
return compilerCtx.fs.writeFile(outputTarget.directivesArrayFile, c);
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import type { OutputTargetAngular } from './types';
|
|
2
2
|
import type { CompilerCtx, ComponentCompilerMeta, Config } from '@stencil/core/internal';
|
|
3
|
+
export interface ValueAccessor {
|
|
4
|
+
elementSelectors: string[];
|
|
5
|
+
eventTargets: [string, string][];
|
|
6
|
+
}
|
|
3
7
|
export default function generateValueAccessors(compilerCtx: CompilerCtx, components: ComponentCompilerMeta[], outputTarget: OutputTargetAngular, config: Config): Promise<void>;
|
|
8
|
+
export declare function createValueAccessor(srcFileContents: string, valueAccessor: ValueAccessor): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EOL } from 'os';
|
|
1
2
|
import path from 'path';
|
|
2
3
|
export default async function generateValueAccessors(compilerCtx, components, outputTarget, config) {
|
|
3
4
|
if (!Array.isArray(outputTarget.valueAccessorConfigs) ||
|
|
@@ -32,11 +33,11 @@ export default async function generateValueAccessors(compilerCtx, components, ou
|
|
|
32
33
|
}));
|
|
33
34
|
await copyResources(config, ['value-accessor.ts'], targetDir);
|
|
34
35
|
}
|
|
35
|
-
function createValueAccessor(srcFileContents, valueAccessor) {
|
|
36
|
+
export function createValueAccessor(srcFileContents, valueAccessor) {
|
|
36
37
|
const hostContents = valueAccessor.eventTargets.map((listItem) => VALUE_ACCESSOR_EVENTTARGETS.replace(VALUE_ACCESSOR_EVENT, listItem[0]).replace(VALUE_ACCESSOR_TARGETATTR, listItem[1]));
|
|
37
38
|
return srcFileContents
|
|
38
39
|
.replace(VALUE_ACCESSOR_SELECTORS, valueAccessor.elementSelectors.join(', '))
|
|
39
|
-
.replace(VALUE_ACCESSOR_EVENTTARGETS, hostContents.join(
|
|
40
|
+
.replace(VALUE_ACCESSOR_EVENTTARGETS, hostContents.join(`,${EOL}`));
|
|
40
41
|
}
|
|
41
42
|
function copyResources(config, resourcesFilesToCopy, directory) {
|
|
42
43
|
if (!config.sys || !config.sys.copy) {
|
package/dist/index.cjs.js
CHANGED
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var path = _interopDefault(require('path'));
|
|
5
|
+
var path = require('path');
|
|
8
6
|
var util = require('util');
|
|
9
|
-
var fs =
|
|
7
|
+
var fs = require('fs');
|
|
8
|
+
var os = require('os');
|
|
9
|
+
|
|
10
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
13
|
+
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
14
|
+
|
|
15
|
+
const readFile = util.promisify(fs__default['default'].readFile);
|
|
12
16
|
const toLowerCase = (str) => str.toLowerCase();
|
|
13
17
|
const dashToPascalCase = (str) => toLowerCase(str)
|
|
14
18
|
.split('-')
|
|
@@ -53,17 +57,17 @@ function normalizePath(str) {
|
|
|
53
57
|
return str;
|
|
54
58
|
}
|
|
55
59
|
function relativeImport(pathFrom, pathTo, ext) {
|
|
56
|
-
let relativePath =
|
|
60
|
+
let relativePath = path__default['default'].relative(path__default['default'].dirname(pathFrom), path__default['default'].dirname(pathTo));
|
|
57
61
|
if (relativePath === '') {
|
|
58
62
|
relativePath = '.';
|
|
59
63
|
}
|
|
60
64
|
else if (relativePath[0] !== '.') {
|
|
61
65
|
relativePath = './' + relativePath;
|
|
62
66
|
}
|
|
63
|
-
return normalizePath(`${relativePath}/${
|
|
67
|
+
return normalizePath(`${relativePath}/${path__default['default'].basename(pathTo, ext)}`);
|
|
64
68
|
}
|
|
65
69
|
async function readPackageJson(rootDir) {
|
|
66
|
-
const pkgJsonPath =
|
|
70
|
+
const pkgJsonPath = path__default['default'].join(rootDir, 'package.json');
|
|
67
71
|
let pkgJson;
|
|
68
72
|
try {
|
|
69
73
|
pkgJson = await readFile(pkgJsonPath, 'utf8');
|
|
@@ -103,30 +107,59 @@ const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir)
|
|
|
103
107
|
if (inputs.length > 0) {
|
|
104
108
|
directiveOpts.push(`inputs: ['${inputs.join(`', '`)}']`);
|
|
105
109
|
}
|
|
106
|
-
if (outputs.length > 0) {
|
|
107
|
-
directiveOpts.push(`outputs: ['${outputs.map((output) => output.name).join(`', '`)}']`);
|
|
108
|
-
}
|
|
109
110
|
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
const outputsInterface = new Set();
|
|
112
|
+
const outputReferenceRemap = {};
|
|
113
|
+
outputs.forEach((output) => {
|
|
114
|
+
Object.entries(output.complexType.references).forEach(([reference, refObject]) => {
|
|
115
|
+
// Add import line for each local/import reference, and add new mapping name.
|
|
116
|
+
// `outputReferenceRemap` should be updated only if the import interface is set in outputsInterface,
|
|
117
|
+
// this will prevent global types to be remapped.
|
|
118
|
+
const remappedReference = `I${cmpMeta.componentClassName}${reference}`;
|
|
119
|
+
if (refObject.location === 'local' || refObject.location === 'import') {
|
|
120
|
+
outputReferenceRemap[reference] = remappedReference;
|
|
121
|
+
outputsInterface.add(`import { ${reference} as ${remappedReference} } from '${componentCorePackage}';`);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
const componentEvents = [
|
|
126
|
+
'' // Empty first line
|
|
127
|
+
];
|
|
128
|
+
// Generate outputs
|
|
129
|
+
outputs.forEach((output, index) => {
|
|
130
|
+
componentEvents.push(` /**
|
|
131
|
+
* ${output.docs.text} ${output.docs.tags.map((tag) => `@${tag.name} ${tag.text}`)}
|
|
132
|
+
*/`);
|
|
133
|
+
/**
|
|
134
|
+
* The original attribute contains the original type defined by the devs.
|
|
135
|
+
* This regexp normalizes the reference, by removing linebreaks,
|
|
136
|
+
* replacing consecutive spaces with a single space, and adding a single space after commas.
|
|
137
|
+
**/
|
|
138
|
+
const outputTypeRemapped = Object.entries(outputReferenceRemap).reduce((type, [src, dst]) => {
|
|
139
|
+
return type
|
|
140
|
+
.replace(new RegExp(`^${src}$`, 'g'), `${dst}`)
|
|
141
|
+
.replace(new RegExp(`([^\\w])${src}([^\\w])`, 'g'), (v, p1, p2) => [p1, dst, p2].join(''));
|
|
142
|
+
}, output.complexType.original
|
|
143
|
+
.replace(/\n/g, ' ')
|
|
144
|
+
.replace(/\s{2,}/g, ' ')
|
|
145
|
+
.replace(/,\s*/g, ', '));
|
|
146
|
+
componentEvents.push(` ${output.name}: EventEmitter<CustomEvent<${outputTypeRemapped.trim()}>>;`);
|
|
147
|
+
if (index === outputs.length - 1) {
|
|
148
|
+
// Empty line to push end `}` to new line
|
|
149
|
+
componentEvents.push('\n');
|
|
150
|
+
}
|
|
151
|
+
});
|
|
115
152
|
const lines = [
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {}
|
|
153
|
+
'',
|
|
154
|
+
`${[...outputsInterface].join('\n')}
|
|
155
|
+
export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {${componentEvents.length > 1 ? componentEvents.join('\n') : ''}}
|
|
156
|
+
|
|
119
157
|
${getProxyCmp(inputs, methods)}
|
|
120
158
|
@Component({
|
|
121
159
|
${directiveOpts.join(',\n ')}
|
|
122
160
|
})
|
|
123
161
|
export class ${tagNameAsPascal} {`,
|
|
124
162
|
];
|
|
125
|
-
// Generate outputs
|
|
126
|
-
outputs.forEach((output) => {
|
|
127
|
-
lines.push(` /** ${output.docs.text} ${output.docs.tags.map((tag) => `@${tag.name} ${tag.text}`)}*/`);
|
|
128
|
-
lines.push(` ${output.name}!: I${cmpMeta.componentClassName}['${output.method}'];`);
|
|
129
|
-
});
|
|
130
163
|
lines.push(' protected el: HTMLElement;');
|
|
131
164
|
lines.push(` constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
|
132
165
|
c.detach();
|
|
@@ -166,7 +199,7 @@ function generateAngularDirectivesFile(compilerCtx, components, outputTarget) {
|
|
|
166
199
|
import * as d from '${proxyPath}';
|
|
167
200
|
|
|
168
201
|
export const DIRECTIVES = [
|
|
169
|
-
${directives}
|
|
202
|
+
${directives}
|
|
170
203
|
];
|
|
171
204
|
`;
|
|
172
205
|
return compilerCtx.fs.writeFile(outputTarget.directivesArrayFile, c);
|
|
@@ -177,7 +210,7 @@ async function generateValueAccessors(compilerCtx, components, outputTarget, con
|
|
|
177
210
|
outputTarget.valueAccessorConfigs.length === 0) {
|
|
178
211
|
return;
|
|
179
212
|
}
|
|
180
|
-
const targetDir =
|
|
213
|
+
const targetDir = path__default['default'].dirname(outputTarget.directivesProxyFile);
|
|
181
214
|
const normalizedValueAccessors = outputTarget.valueAccessorConfigs.reduce((allAccessors, va) => {
|
|
182
215
|
const elementSelectors = Array.isArray(va.elementSelectors)
|
|
183
216
|
? va.elementSelectors
|
|
@@ -197,8 +230,8 @@ async function generateValueAccessors(compilerCtx, components, outputTarget, con
|
|
|
197
230
|
await Promise.all(Object.keys(normalizedValueAccessors).map(async (type) => {
|
|
198
231
|
const valueAccessorType = type; // Object.keys converts to string
|
|
199
232
|
const targetFileName = `${type}-value-accessor.ts`;
|
|
200
|
-
const targetFilePath =
|
|
201
|
-
const srcFilePath =
|
|
233
|
+
const targetFilePath = path__default['default'].join(targetDir, targetFileName);
|
|
234
|
+
const srcFilePath = path__default['default'].join(__dirname, '../resources/control-value-accessors/', targetFileName);
|
|
202
235
|
const srcFileContents = await compilerCtx.fs.readFile(srcFilePath);
|
|
203
236
|
const finalText = createValueAccessor(srcFileContents, normalizedValueAccessors[valueAccessorType]);
|
|
204
237
|
await compilerCtx.fs.writeFile(targetFilePath, finalText);
|
|
@@ -209,7 +242,7 @@ function createValueAccessor(srcFileContents, valueAccessor) {
|
|
|
209
242
|
const hostContents = valueAccessor.eventTargets.map((listItem) => VALUE_ACCESSOR_EVENTTARGETS.replace(VALUE_ACCESSOR_EVENT, listItem[0]).replace(VALUE_ACCESSOR_TARGETATTR, listItem[1]));
|
|
210
243
|
return srcFileContents
|
|
211
244
|
.replace(VALUE_ACCESSOR_SELECTORS, valueAccessor.elementSelectors.join(', '))
|
|
212
|
-
.replace(VALUE_ACCESSOR_EVENTTARGETS, hostContents.join(
|
|
245
|
+
.replace(VALUE_ACCESSOR_EVENTTARGETS, hostContents.join(`,${os.EOL}`));
|
|
213
246
|
}
|
|
214
247
|
function copyResources(config, resourcesFilesToCopy, directory) {
|
|
215
248
|
if (!config.sys || !config.sys.copy) {
|
|
@@ -217,13 +250,13 @@ function copyResources(config, resourcesFilesToCopy, directory) {
|
|
|
217
250
|
}
|
|
218
251
|
const copyTasks = resourcesFilesToCopy.map((rf) => {
|
|
219
252
|
return {
|
|
220
|
-
src:
|
|
221
|
-
dest:
|
|
253
|
+
src: path__default['default'].join(__dirname, '../resources/control-value-accessors/', rf),
|
|
254
|
+
dest: path__default['default'].join(directory, rf),
|
|
222
255
|
keepDirStructure: false,
|
|
223
256
|
warn: false,
|
|
224
257
|
};
|
|
225
258
|
});
|
|
226
|
-
return config.sys.copy(copyTasks,
|
|
259
|
+
return config.sys.copy(copyTasks, path__default['default'].join(directory));
|
|
227
260
|
}
|
|
228
261
|
const VALUE_ACCESSOR_SELECTORS = `<VALUE_ACCESSOR_SELECTORS>`;
|
|
229
262
|
const VALUE_ACCESSOR_EVENT = `<VALUE_ACCESSOR_EVENT>`;
|
|
@@ -249,8 +282,8 @@ async function copyResources$1(config, outputTarget) {
|
|
|
249
282
|
if (!config.sys || !config.sys.copy || !config.sys.glob) {
|
|
250
283
|
throw new Error('stencil is not properly initialized at this step. Notify the developer');
|
|
251
284
|
}
|
|
252
|
-
const srcDirectory =
|
|
253
|
-
const destDirectory =
|
|
285
|
+
const srcDirectory = path__default['default'].join(__dirname, '..', 'angular-component-lib');
|
|
286
|
+
const destDirectory = path__default['default'].join(path__default['default'].dirname(outputTarget.directivesProxyFile), 'angular-component-lib');
|
|
254
287
|
return config.sys.copy([
|
|
255
288
|
{
|
|
256
289
|
src: srcDirectory,
|
|
@@ -261,12 +294,12 @@ async function copyResources$1(config, outputTarget) {
|
|
|
261
294
|
], srcDirectory);
|
|
262
295
|
}
|
|
263
296
|
function generateProxies(components, pkgData, outputTarget, rootDir) {
|
|
264
|
-
const distTypesDir =
|
|
265
|
-
const dtsFilePath =
|
|
297
|
+
const distTypesDir = path__default['default'].dirname(pkgData.types);
|
|
298
|
+
const dtsFilePath = path__default['default'].join(rootDir, distTypesDir, GENERATED_DTS);
|
|
266
299
|
const componentsTypeFile = relativeImport(outputTarget.directivesProxyFile, dtsFilePath, '.d.ts');
|
|
267
300
|
const imports = `/* tslint:disable */
|
|
268
301
|
/* auto-generated angular directive proxies */
|
|
269
|
-
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, NgZone } from '@angular/core';
|
|
302
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, NgZone } from '@angular/core';
|
|
270
303
|
import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils';\n`;
|
|
271
304
|
const typeImports = !outputTarget.componentCorePackage
|
|
272
305
|
? `import { ${IMPORT_TYPES} } from '${normalizePath(componentsTypeFile)}';`
|
|
@@ -275,7 +308,7 @@ import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils';\n`;
|
|
|
275
308
|
imports,
|
|
276
309
|
typeImports,
|
|
277
310
|
components
|
|
278
|
-
.map(createComponentDefinition(outputTarget.componentCorePackage
|
|
311
|
+
.map(createComponentDefinition(outputTarget.componentCorePackage))
|
|
279
312
|
.join('\n'),
|
|
280
313
|
];
|
|
281
314
|
return final.join('\n') + '\n';
|
|
@@ -303,14 +336,14 @@ function normalizeOutputTarget(config, outputTarget) {
|
|
|
303
336
|
if (outputTarget.directivesProxyFile == null) {
|
|
304
337
|
throw new Error('directivesProxyFile is required');
|
|
305
338
|
}
|
|
306
|
-
if (outputTarget.directivesProxyFile && !
|
|
307
|
-
results.directivesProxyFile = normalizePath(
|
|
339
|
+
if (outputTarget.directivesProxyFile && !path__default['default'].isAbsolute(outputTarget.directivesProxyFile)) {
|
|
340
|
+
results.directivesProxyFile = normalizePath(path__default['default'].join(config.rootDir, outputTarget.directivesProxyFile));
|
|
308
341
|
}
|
|
309
|
-
if (outputTarget.directivesArrayFile && !
|
|
310
|
-
results.directivesArrayFile = normalizePath(
|
|
342
|
+
if (outputTarget.directivesArrayFile && !path__default['default'].isAbsolute(outputTarget.directivesArrayFile)) {
|
|
343
|
+
results.directivesArrayFile = normalizePath(path__default['default'].join(config.rootDir, outputTarget.directivesArrayFile));
|
|
311
344
|
}
|
|
312
|
-
if (outputTarget.directivesUtilsFile && !
|
|
313
|
-
results.directivesUtilsFile = normalizePath(
|
|
345
|
+
if (outputTarget.directivesUtilsFile && !path__default['default'].isAbsolute(outputTarget.directivesUtilsFile)) {
|
|
346
|
+
results.directivesUtilsFile = normalizePath(path__default['default'].join(config.rootDir, outputTarget.directivesUtilsFile));
|
|
314
347
|
}
|
|
315
348
|
return results;
|
|
316
349
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { promisify } from 'util';
|
|
3
3
|
import fs from 'fs';
|
|
4
|
+
import { EOL } from 'os';
|
|
4
5
|
|
|
5
6
|
const readFile = promisify(fs.readFile);
|
|
6
7
|
const toLowerCase = (str) => str.toLowerCase();
|
|
@@ -97,30 +98,59 @@ const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir)
|
|
|
97
98
|
if (inputs.length > 0) {
|
|
98
99
|
directiveOpts.push(`inputs: ['${inputs.join(`', '`)}']`);
|
|
99
100
|
}
|
|
100
|
-
if (outputs.length > 0) {
|
|
101
|
-
directiveOpts.push(`outputs: ['${outputs.map((output) => output.name).join(`', '`)}']`);
|
|
102
|
-
}
|
|
103
101
|
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
const outputsInterface = new Set();
|
|
103
|
+
const outputReferenceRemap = {};
|
|
104
|
+
outputs.forEach((output) => {
|
|
105
|
+
Object.entries(output.complexType.references).forEach(([reference, refObject]) => {
|
|
106
|
+
// Add import line for each local/import reference, and add new mapping name.
|
|
107
|
+
// `outputReferenceRemap` should be updated only if the import interface is set in outputsInterface,
|
|
108
|
+
// this will prevent global types to be remapped.
|
|
109
|
+
const remappedReference = `I${cmpMeta.componentClassName}${reference}`;
|
|
110
|
+
if (refObject.location === 'local' || refObject.location === 'import') {
|
|
111
|
+
outputReferenceRemap[reference] = remappedReference;
|
|
112
|
+
outputsInterface.add(`import { ${reference} as ${remappedReference} } from '${componentCorePackage}';`);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
const componentEvents = [
|
|
117
|
+
'' // Empty first line
|
|
118
|
+
];
|
|
119
|
+
// Generate outputs
|
|
120
|
+
outputs.forEach((output, index) => {
|
|
121
|
+
componentEvents.push(` /**
|
|
122
|
+
* ${output.docs.text} ${output.docs.tags.map((tag) => `@${tag.name} ${tag.text}`)}
|
|
123
|
+
*/`);
|
|
124
|
+
/**
|
|
125
|
+
* The original attribute contains the original type defined by the devs.
|
|
126
|
+
* This regexp normalizes the reference, by removing linebreaks,
|
|
127
|
+
* replacing consecutive spaces with a single space, and adding a single space after commas.
|
|
128
|
+
**/
|
|
129
|
+
const outputTypeRemapped = Object.entries(outputReferenceRemap).reduce((type, [src, dst]) => {
|
|
130
|
+
return type
|
|
131
|
+
.replace(new RegExp(`^${src}$`, 'g'), `${dst}`)
|
|
132
|
+
.replace(new RegExp(`([^\\w])${src}([^\\w])`, 'g'), (v, p1, p2) => [p1, dst, p2].join(''));
|
|
133
|
+
}, output.complexType.original
|
|
134
|
+
.replace(/\n/g, ' ')
|
|
135
|
+
.replace(/\s{2,}/g, ' ')
|
|
136
|
+
.replace(/,\s*/g, ', '));
|
|
137
|
+
componentEvents.push(` ${output.name}: EventEmitter<CustomEvent<${outputTypeRemapped.trim()}>>;`);
|
|
138
|
+
if (index === outputs.length - 1) {
|
|
139
|
+
// Empty line to push end `}` to new line
|
|
140
|
+
componentEvents.push('\n');
|
|
141
|
+
}
|
|
142
|
+
});
|
|
109
143
|
const lines = [
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {}
|
|
144
|
+
'',
|
|
145
|
+
`${[...outputsInterface].join('\n')}
|
|
146
|
+
export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {${componentEvents.length > 1 ? componentEvents.join('\n') : ''}}
|
|
147
|
+
|
|
113
148
|
${getProxyCmp(inputs, methods)}
|
|
114
149
|
@Component({
|
|
115
150
|
${directiveOpts.join(',\n ')}
|
|
116
151
|
})
|
|
117
152
|
export class ${tagNameAsPascal} {`,
|
|
118
153
|
];
|
|
119
|
-
// Generate outputs
|
|
120
|
-
outputs.forEach((output) => {
|
|
121
|
-
lines.push(` /** ${output.docs.text} ${output.docs.tags.map((tag) => `@${tag.name} ${tag.text}`)}*/`);
|
|
122
|
-
lines.push(` ${output.name}!: I${cmpMeta.componentClassName}['${output.method}'];`);
|
|
123
|
-
});
|
|
124
154
|
lines.push(' protected el: HTMLElement;');
|
|
125
155
|
lines.push(` constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
|
126
156
|
c.detach();
|
|
@@ -160,7 +190,7 @@ function generateAngularDirectivesFile(compilerCtx, components, outputTarget) {
|
|
|
160
190
|
import * as d from '${proxyPath}';
|
|
161
191
|
|
|
162
192
|
export const DIRECTIVES = [
|
|
163
|
-
${directives}
|
|
193
|
+
${directives}
|
|
164
194
|
];
|
|
165
195
|
`;
|
|
166
196
|
return compilerCtx.fs.writeFile(outputTarget.directivesArrayFile, c);
|
|
@@ -203,7 +233,7 @@ function createValueAccessor(srcFileContents, valueAccessor) {
|
|
|
203
233
|
const hostContents = valueAccessor.eventTargets.map((listItem) => VALUE_ACCESSOR_EVENTTARGETS.replace(VALUE_ACCESSOR_EVENT, listItem[0]).replace(VALUE_ACCESSOR_TARGETATTR, listItem[1]));
|
|
204
234
|
return srcFileContents
|
|
205
235
|
.replace(VALUE_ACCESSOR_SELECTORS, valueAccessor.elementSelectors.join(', '))
|
|
206
|
-
.replace(VALUE_ACCESSOR_EVENTTARGETS, hostContents.join(
|
|
236
|
+
.replace(VALUE_ACCESSOR_EVENTTARGETS, hostContents.join(`,${EOL}`));
|
|
207
237
|
}
|
|
208
238
|
function copyResources(config, resourcesFilesToCopy, directory) {
|
|
209
239
|
if (!config.sys || !config.sys.copy) {
|
|
@@ -260,7 +290,7 @@ function generateProxies(components, pkgData, outputTarget, rootDir) {
|
|
|
260
290
|
const componentsTypeFile = relativeImport(outputTarget.directivesProxyFile, dtsFilePath, '.d.ts');
|
|
261
291
|
const imports = `/* tslint:disable */
|
|
262
292
|
/* auto-generated angular directive proxies */
|
|
263
|
-
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, NgZone } from '@angular/core';
|
|
293
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, NgZone } from '@angular/core';
|
|
264
294
|
import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils';\n`;
|
|
265
295
|
const typeImports = !outputTarget.componentCorePackage
|
|
266
296
|
? `import { ${IMPORT_TYPES} } from '${normalizePath(componentsTypeFile)}';`
|
|
@@ -269,7 +299,7 @@ import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils';\n`;
|
|
|
269
299
|
imports,
|
|
270
300
|
typeImports,
|
|
271
301
|
components
|
|
272
|
-
.map(createComponentDefinition(outputTarget.componentCorePackage
|
|
302
|
+
.map(createComponentDefinition(outputTarget.componentCorePackage))
|
|
273
303
|
.join('\n'),
|
|
274
304
|
];
|
|
275
305
|
return final.join('\n') + '\n';
|
package/dist/output-angular.js
CHANGED
|
@@ -39,7 +39,7 @@ export function generateProxies(components, pkgData, outputTarget, rootDir) {
|
|
|
39
39
|
const componentsTypeFile = relativeImport(outputTarget.directivesProxyFile, dtsFilePath, '.d.ts');
|
|
40
40
|
const imports = `/* tslint:disable */
|
|
41
41
|
/* auto-generated angular directive proxies */
|
|
42
|
-
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, NgZone } from '@angular/core';
|
|
42
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, NgZone } from '@angular/core';
|
|
43
43
|
import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils';\n`;
|
|
44
44
|
const typeImports = !outputTarget.componentCorePackage
|
|
45
45
|
? `import { ${IMPORT_TYPES} } from '${normalizePath(componentsTypeFile)}';`
|
package/dist/utils.d.ts
CHANGED
|
@@ -4,4 +4,5 @@ export declare const dashToPascalCase: (str: string) => string;
|
|
|
4
4
|
export declare function sortBy<T>(array: T[], prop: (item: T) => string): T[];
|
|
5
5
|
export declare function normalizePath(str: string): string;
|
|
6
6
|
export declare function relativeImport(pathFrom: string, pathTo: string, ext?: string): string;
|
|
7
|
+
export declare function isRelativePath(path: string): boolean | "";
|
|
7
8
|
export declare function readPackageJson(rootDir: string): Promise<PackageJSON>;
|
package/dist/utils.js
CHANGED
|
@@ -55,6 +55,9 @@ export function relativeImport(pathFrom, pathTo, ext) {
|
|
|
55
55
|
}
|
|
56
56
|
return normalizePath(`${relativePath}/${path.basename(pathTo, ext)}`);
|
|
57
57
|
}
|
|
58
|
+
export function isRelativePath(path) {
|
|
59
|
+
return path && path.startsWith('.');
|
|
60
|
+
}
|
|
58
61
|
export async function readPackageJson(rootDir) {
|
|
59
62
|
const pkgJsonPath = path.join(rootDir, 'package.json');
|
|
60
63
|
let pkgJson;
|