@stencil/angular-output-target 0.2.1-0 → 0.4.0-1
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 +23 -6
- package/dist/generate-angular-component.d.ts +1 -1
- package/dist/generate-angular-component.js +14 -9
- package/dist/index.cjs.js +46 -19
- package/dist/index.js +46 -18
- package/dist/output-angular.js +31 -6
- package/dist/types.d.ts +2 -0
- package/dist/utils.d.ts +2 -1
- package/dist/utils.js +3 -5
- package/package.json +4 -1
|
@@ -32,13 +32,30 @@ export const proxyOutputs = (instance: any, el: any, events: string[]) => {
|
|
|
32
32
|
events.forEach(eventName => instance[eventName] = fromEvent(el, eventName));
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
export const defineCustomElement = (tagName: string, customElement: any) => {
|
|
36
|
+
if (
|
|
37
|
+
customElement !== undefined &&
|
|
38
|
+
typeof customElements !== 'undefined' &&
|
|
39
|
+
!customElements.get(tagName)
|
|
40
|
+
) {
|
|
41
|
+
customElements.define(tagName, customElement);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// tslint:disable-next-line: only-arrow-functions
|
|
46
|
+
export function ProxyCmp(opts: { tagName: string, defineCustomElementFn?: () => void, inputs?: any; methods?: any }) {
|
|
47
|
+
const decorator = function (cls: any) {
|
|
48
|
+
const { tagName, customElement, inputs, methods } = opts;
|
|
49
|
+
|
|
50
|
+
if (defineCustomElementFn !== undefined) {
|
|
51
|
+
defineCustomElementFn();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (inputs) {
|
|
55
|
+
proxyInputs(cls, inputs);
|
|
39
56
|
}
|
|
40
|
-
if (
|
|
41
|
-
proxyMethods(cls,
|
|
57
|
+
if (methods) {
|
|
58
|
+
proxyMethods(cls, methods);
|
|
42
59
|
}
|
|
43
60
|
return cls;
|
|
44
61
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { ComponentCompilerMeta } from '@stencil/core/internal';
|
|
2
|
-
export declare const createComponentDefinition: (componentCorePackage: string, distTypesDir: string, rootDir: string) => (cmpMeta: ComponentCompilerMeta) => string;
|
|
2
|
+
export declare const createComponentDefinition: (componentCorePackage: string, distTypesDir: string, rootDir: string, includeImportCustomElements?: boolean, customElementsDir?: string) => (cmpMeta: ComponentCompilerMeta) => string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { dashToPascalCase } from './utils';
|
|
2
|
-
export const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir) => (cmpMeta) => {
|
|
1
|
+
import { dashToPascalCase, normalizePath } from './utils';
|
|
2
|
+
export const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir, includeImportCustomElements = false, customElementsDir = 'components') => (cmpMeta) => {
|
|
3
3
|
// Collect component meta
|
|
4
4
|
const inputs = [
|
|
5
5
|
...cmpMeta.properties.filter((prop) => !prop.internal).map((prop) => prop.name),
|
|
@@ -29,7 +29,12 @@ export const createComponentDefinition = (componentCorePackage, distTypesDir, ro
|
|
|
29
29
|
const remappedReference = `I${cmpMeta.componentClassName}${reference}`;
|
|
30
30
|
if (refObject.location === 'local' || refObject.location === 'import') {
|
|
31
31
|
outputReferenceRemap[reference] = remappedReference;
|
|
32
|
-
|
|
32
|
+
let importLocation = componentCorePackage;
|
|
33
|
+
if (componentCorePackage !== undefined) {
|
|
34
|
+
const dirPath = includeImportCustomElements ? `/${customElementsDir || 'components'}` : '';
|
|
35
|
+
importLocation = `${normalizePath(componentCorePackage)}${dirPath}`;
|
|
36
|
+
}
|
|
37
|
+
outputsInterface.add(`import type { ${reference} as ${remappedReference} } from '${importLocation}';`);
|
|
33
38
|
}
|
|
34
39
|
});
|
|
35
40
|
});
|
|
@@ -65,7 +70,7 @@ export const createComponentDefinition = (componentCorePackage, distTypesDir, ro
|
|
|
65
70
|
`${[...outputsInterface].join('\n')}
|
|
66
71
|
export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {${componentEvents.length > 1 ? componentEvents.join('\n') : ''}}
|
|
67
72
|
|
|
68
|
-
${getProxyCmp(inputs, methods)}
|
|
73
|
+
${getProxyCmp(cmpMeta.tagName, includeImportCustomElements, inputs, methods)}
|
|
69
74
|
@Component({
|
|
70
75
|
${directiveOpts.join(',\n ')}
|
|
71
76
|
})
|
|
@@ -82,13 +87,13 @@ export class ${tagNameAsPascal} {`,
|
|
|
82
87
|
lines.push(`}`);
|
|
83
88
|
return lines.join('\n');
|
|
84
89
|
};
|
|
85
|
-
function getProxyCmp(inputs, methods) {
|
|
90
|
+
function getProxyCmp(tagName, includeCustomElement, inputs, methods) {
|
|
86
91
|
const hasInputs = inputs.length > 0;
|
|
87
92
|
const hasMethods = methods.length > 0;
|
|
88
|
-
const proxMeta = [
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
const proxMeta = [
|
|
94
|
+
`tagName: \'${tagName}\'`,
|
|
95
|
+
`customElement: ${includeCustomElement ? 'define' + dashToPascalCase(tagName) : 'undefined'}`
|
|
96
|
+
];
|
|
92
97
|
if (hasInputs)
|
|
93
98
|
proxMeta.push(`inputs: ['${inputs.join(`', '`)}']`);
|
|
94
99
|
if (hasMethods)
|
package/dist/index.cjs.js
CHANGED
|
@@ -3,16 +3,12 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var path = require('path');
|
|
6
|
-
var util = require('util');
|
|
7
|
-
var fs = require('fs');
|
|
8
6
|
var os = require('os');
|
|
9
7
|
|
|
10
8
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
11
9
|
|
|
12
10
|
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
13
|
-
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
14
11
|
|
|
15
|
-
const readFile = util.promisify(fs__default['default'].readFile);
|
|
16
12
|
const toLowerCase = (str) => str.toLowerCase();
|
|
17
13
|
const dashToPascalCase = (str) => toLowerCase(str)
|
|
18
14
|
.split('-')
|
|
@@ -66,11 +62,12 @@ function relativeImport(pathFrom, pathTo, ext) {
|
|
|
66
62
|
}
|
|
67
63
|
return normalizePath(`${relativePath}/${path__default['default'].basename(pathTo, ext)}`);
|
|
68
64
|
}
|
|
69
|
-
async function readPackageJson(rootDir) {
|
|
65
|
+
async function readPackageJson(config, rootDir) {
|
|
66
|
+
var _a;
|
|
70
67
|
const pkgJsonPath = path__default['default'].join(rootDir, 'package.json');
|
|
71
68
|
let pkgJson;
|
|
72
69
|
try {
|
|
73
|
-
pkgJson = await readFile(pkgJsonPath, 'utf8');
|
|
70
|
+
pkgJson = (await ((_a = config.sys) === null || _a === void 0 ? void 0 : _a.readFile(pkgJsonPath, 'utf8')));
|
|
74
71
|
}
|
|
75
72
|
catch (e) {
|
|
76
73
|
throw new Error(`Missing "package.json" file for distribution: ${pkgJsonPath}`);
|
|
@@ -88,7 +85,7 @@ const EXTENDED_PATH_REGEX = /^\\\\\?\\/;
|
|
|
88
85
|
const NON_ASCII_REGEX = /[^\x00-\x80]+/;
|
|
89
86
|
const SLASH_REGEX = /\\/g;
|
|
90
87
|
|
|
91
|
-
const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir) => (cmpMeta) => {
|
|
88
|
+
const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir, includeImportCustomElements = false, customElementsDir = 'components') => (cmpMeta) => {
|
|
92
89
|
// Collect component meta
|
|
93
90
|
const inputs = [
|
|
94
91
|
...cmpMeta.properties.filter((prop) => !prop.internal).map((prop) => prop.name),
|
|
@@ -118,7 +115,12 @@ const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir)
|
|
|
118
115
|
const remappedReference = `I${cmpMeta.componentClassName}${reference}`;
|
|
119
116
|
if (refObject.location === 'local' || refObject.location === 'import') {
|
|
120
117
|
outputReferenceRemap[reference] = remappedReference;
|
|
121
|
-
|
|
118
|
+
let importLocation = componentCorePackage;
|
|
119
|
+
if (componentCorePackage !== undefined) {
|
|
120
|
+
const dirPath = includeImportCustomElements ? `/${customElementsDir || 'components'}` : '';
|
|
121
|
+
importLocation = `${normalizePath(componentCorePackage)}${dirPath}`;
|
|
122
|
+
}
|
|
123
|
+
outputsInterface.add(`import type { ${reference} as ${remappedReference} } from '${importLocation}';`);
|
|
122
124
|
}
|
|
123
125
|
});
|
|
124
126
|
});
|
|
@@ -154,7 +156,7 @@ const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir)
|
|
|
154
156
|
`${[...outputsInterface].join('\n')}
|
|
155
157
|
export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {${componentEvents.length > 1 ? componentEvents.join('\n') : ''}}
|
|
156
158
|
|
|
157
|
-
${getProxyCmp(inputs, methods)}
|
|
159
|
+
${getProxyCmp(cmpMeta.tagName, includeImportCustomElements, inputs, methods)}
|
|
158
160
|
@Component({
|
|
159
161
|
${directiveOpts.join(',\n ')}
|
|
160
162
|
})
|
|
@@ -171,13 +173,13 @@ export class ${tagNameAsPascal} {`,
|
|
|
171
173
|
lines.push(`}`);
|
|
172
174
|
return lines.join('\n');
|
|
173
175
|
};
|
|
174
|
-
function getProxyCmp(inputs, methods) {
|
|
176
|
+
function getProxyCmp(tagName, includeCustomElement, inputs, methods) {
|
|
175
177
|
const hasInputs = inputs.length > 0;
|
|
176
178
|
const hasMethods = methods.length > 0;
|
|
177
|
-
const proxMeta = [
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
const proxMeta = [
|
|
180
|
+
`tagName: \'${tagName}\'`,
|
|
181
|
+
`customElement: ${includeCustomElement ? 'define' + dashToPascalCase(tagName) : 'undefined'}`
|
|
182
|
+
];
|
|
181
183
|
if (hasInputs)
|
|
182
184
|
proxMeta.push(`inputs: ['${inputs.join(`', '`)}']`);
|
|
183
185
|
if (hasMethods)
|
|
@@ -266,7 +268,7 @@ const VALUE_ACCESSOR_EVENTTARGETS = ` '(<VALUE_ACCESSOR_EVENT>)': 'handleChan
|
|
|
266
268
|
async function angularDirectiveProxyOutput(compilerCtx, outputTarget, components, config) {
|
|
267
269
|
const filteredComponents = getFilteredComponents(outputTarget.excludeComponents, components);
|
|
268
270
|
const rootDir = config.rootDir;
|
|
269
|
-
const pkgData = await readPackageJson(rootDir);
|
|
271
|
+
const pkgData = await readPackageJson(config, rootDir);
|
|
270
272
|
const finalText = generateProxies(filteredComponents, pkgData, outputTarget, config.rootDir);
|
|
271
273
|
await Promise.all([
|
|
272
274
|
compilerCtx.fs.writeFile(outputTarget.directivesProxyFile, finalText),
|
|
@@ -301,14 +303,39 @@ function generateProxies(components, pkgData, outputTarget, rootDir) {
|
|
|
301
303
|
/* auto-generated angular directive proxies */
|
|
302
304
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, NgZone } from '@angular/core';
|
|
303
305
|
import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils';\n`;
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
306
|
+
/**
|
|
307
|
+
* Generate JSX import type from correct location.
|
|
308
|
+
* When using custom elements build, we need to import from
|
|
309
|
+
* either the "components" directory or customElementsDir
|
|
310
|
+
* otherwise we risk bundlers pulling in lazy loaded imports.
|
|
311
|
+
*/
|
|
312
|
+
const generateTypeImports = () => {
|
|
313
|
+
let importLocation = outputTarget.componentCorePackage ? normalizePath(outputTarget.componentCorePackage) : normalizePath(componentsTypeFile);
|
|
314
|
+
importLocation += outputTarget.includeImportCustomElements ? `/${outputTarget.customElementsDir || 'components'}` : '';
|
|
315
|
+
return `import ${outputTarget.includeImportCustomElements ? 'type ' : ''}{ ${IMPORT_TYPES} } from '${importLocation}';\n`;
|
|
316
|
+
};
|
|
317
|
+
const typeImports = generateTypeImports();
|
|
318
|
+
let sourceImports = '';
|
|
319
|
+
/**
|
|
320
|
+
* Build an array of Custom Elements build imports and namespace them
|
|
321
|
+
* so that they do not conflict with the React wrapper names. For example,
|
|
322
|
+
* IonButton would be imported as IonButtonCmp so as to not conflict with the
|
|
323
|
+
* IonButton React Component that takes in the Web Component as a parameter.
|
|
324
|
+
*/
|
|
325
|
+
if (outputTarget.includeImportCustomElements && outputTarget.componentCorePackage !== undefined) {
|
|
326
|
+
const cmpImports = components.map(component => {
|
|
327
|
+
const pascalImport = dashToPascalCase(component.tagName);
|
|
328
|
+
return `import { defineCustomElement as define${pascalImport} } from '${normalizePath(outputTarget.componentCorePackage)}/${outputTarget.customElementsDir ||
|
|
329
|
+
'components'}/${component.tagName}.js';`;
|
|
330
|
+
});
|
|
331
|
+
sourceImports = cmpImports.join('\n');
|
|
332
|
+
}
|
|
307
333
|
const final = [
|
|
308
334
|
imports,
|
|
309
335
|
typeImports,
|
|
336
|
+
sourceImports,
|
|
310
337
|
components
|
|
311
|
-
.map(createComponentDefinition(outputTarget.componentCorePackage))
|
|
338
|
+
.map(createComponentDefinition(outputTarget.componentCorePackage, distTypesDir, rootDir, outputTarget.includeImportCustomElements, outputTarget.customElementsDir))
|
|
312
339
|
.join('\n'),
|
|
313
340
|
];
|
|
314
341
|
return final.join('\n') + '\n';
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import { promisify } from 'util';
|
|
3
|
-
import fs from 'fs';
|
|
4
2
|
import { EOL } from 'os';
|
|
5
3
|
|
|
6
|
-
const readFile = promisify(fs.readFile);
|
|
7
4
|
const toLowerCase = (str) => str.toLowerCase();
|
|
8
5
|
const dashToPascalCase = (str) => toLowerCase(str)
|
|
9
6
|
.split('-')
|
|
@@ -57,11 +54,12 @@ function relativeImport(pathFrom, pathTo, ext) {
|
|
|
57
54
|
}
|
|
58
55
|
return normalizePath(`${relativePath}/${path.basename(pathTo, ext)}`);
|
|
59
56
|
}
|
|
60
|
-
async function readPackageJson(rootDir) {
|
|
57
|
+
async function readPackageJson(config, rootDir) {
|
|
58
|
+
var _a;
|
|
61
59
|
const pkgJsonPath = path.join(rootDir, 'package.json');
|
|
62
60
|
let pkgJson;
|
|
63
61
|
try {
|
|
64
|
-
pkgJson = await readFile(pkgJsonPath, 'utf8');
|
|
62
|
+
pkgJson = (await ((_a = config.sys) === null || _a === void 0 ? void 0 : _a.readFile(pkgJsonPath, 'utf8')));
|
|
65
63
|
}
|
|
66
64
|
catch (e) {
|
|
67
65
|
throw new Error(`Missing "package.json" file for distribution: ${pkgJsonPath}`);
|
|
@@ -79,7 +77,7 @@ const EXTENDED_PATH_REGEX = /^\\\\\?\\/;
|
|
|
79
77
|
const NON_ASCII_REGEX = /[^\x00-\x80]+/;
|
|
80
78
|
const SLASH_REGEX = /\\/g;
|
|
81
79
|
|
|
82
|
-
const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir) => (cmpMeta) => {
|
|
80
|
+
const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir, includeImportCustomElements = false, customElementsDir = 'components') => (cmpMeta) => {
|
|
83
81
|
// Collect component meta
|
|
84
82
|
const inputs = [
|
|
85
83
|
...cmpMeta.properties.filter((prop) => !prop.internal).map((prop) => prop.name),
|
|
@@ -109,7 +107,12 @@ const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir)
|
|
|
109
107
|
const remappedReference = `I${cmpMeta.componentClassName}${reference}`;
|
|
110
108
|
if (refObject.location === 'local' || refObject.location === 'import') {
|
|
111
109
|
outputReferenceRemap[reference] = remappedReference;
|
|
112
|
-
|
|
110
|
+
let importLocation = componentCorePackage;
|
|
111
|
+
if (componentCorePackage !== undefined) {
|
|
112
|
+
const dirPath = includeImportCustomElements ? `/${customElementsDir || 'components'}` : '';
|
|
113
|
+
importLocation = `${normalizePath(componentCorePackage)}${dirPath}`;
|
|
114
|
+
}
|
|
115
|
+
outputsInterface.add(`import type { ${reference} as ${remappedReference} } from '${importLocation}';`);
|
|
113
116
|
}
|
|
114
117
|
});
|
|
115
118
|
});
|
|
@@ -145,7 +148,7 @@ const createComponentDefinition = (componentCorePackage, distTypesDir, rootDir)
|
|
|
145
148
|
`${[...outputsInterface].join('\n')}
|
|
146
149
|
export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {${componentEvents.length > 1 ? componentEvents.join('\n') : ''}}
|
|
147
150
|
|
|
148
|
-
${getProxyCmp(inputs, methods)}
|
|
151
|
+
${getProxyCmp(cmpMeta.tagName, includeImportCustomElements, inputs, methods)}
|
|
149
152
|
@Component({
|
|
150
153
|
${directiveOpts.join(',\n ')}
|
|
151
154
|
})
|
|
@@ -162,13 +165,13 @@ export class ${tagNameAsPascal} {`,
|
|
|
162
165
|
lines.push(`}`);
|
|
163
166
|
return lines.join('\n');
|
|
164
167
|
};
|
|
165
|
-
function getProxyCmp(inputs, methods) {
|
|
168
|
+
function getProxyCmp(tagName, includeCustomElement, inputs, methods) {
|
|
166
169
|
const hasInputs = inputs.length > 0;
|
|
167
170
|
const hasMethods = methods.length > 0;
|
|
168
|
-
const proxMeta = [
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
171
|
+
const proxMeta = [
|
|
172
|
+
`tagName: \'${tagName}\'`,
|
|
173
|
+
`customElement: ${includeCustomElement ? 'define' + dashToPascalCase(tagName) : 'undefined'}`
|
|
174
|
+
];
|
|
172
175
|
if (hasInputs)
|
|
173
176
|
proxMeta.push(`inputs: ['${inputs.join(`', '`)}']`);
|
|
174
177
|
if (hasMethods)
|
|
@@ -257,7 +260,7 @@ const VALUE_ACCESSOR_EVENTTARGETS = ` '(<VALUE_ACCESSOR_EVENT>)': 'handleChan
|
|
|
257
260
|
async function angularDirectiveProxyOutput(compilerCtx, outputTarget, components, config) {
|
|
258
261
|
const filteredComponents = getFilteredComponents(outputTarget.excludeComponents, components);
|
|
259
262
|
const rootDir = config.rootDir;
|
|
260
|
-
const pkgData = await readPackageJson(rootDir);
|
|
263
|
+
const pkgData = await readPackageJson(config, rootDir);
|
|
261
264
|
const finalText = generateProxies(filteredComponents, pkgData, outputTarget, config.rootDir);
|
|
262
265
|
await Promise.all([
|
|
263
266
|
compilerCtx.fs.writeFile(outputTarget.directivesProxyFile, finalText),
|
|
@@ -292,14 +295,39 @@ function generateProxies(components, pkgData, outputTarget, rootDir) {
|
|
|
292
295
|
/* auto-generated angular directive proxies */
|
|
293
296
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, NgZone } from '@angular/core';
|
|
294
297
|
import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils';\n`;
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
+
/**
|
|
299
|
+
* Generate JSX import type from correct location.
|
|
300
|
+
* When using custom elements build, we need to import from
|
|
301
|
+
* either the "components" directory or customElementsDir
|
|
302
|
+
* otherwise we risk bundlers pulling in lazy loaded imports.
|
|
303
|
+
*/
|
|
304
|
+
const generateTypeImports = () => {
|
|
305
|
+
let importLocation = outputTarget.componentCorePackage ? normalizePath(outputTarget.componentCorePackage) : normalizePath(componentsTypeFile);
|
|
306
|
+
importLocation += outputTarget.includeImportCustomElements ? `/${outputTarget.customElementsDir || 'components'}` : '';
|
|
307
|
+
return `import ${outputTarget.includeImportCustomElements ? 'type ' : ''}{ ${IMPORT_TYPES} } from '${importLocation}';\n`;
|
|
308
|
+
};
|
|
309
|
+
const typeImports = generateTypeImports();
|
|
310
|
+
let sourceImports = '';
|
|
311
|
+
/**
|
|
312
|
+
* Build an array of Custom Elements build imports and namespace them
|
|
313
|
+
* so that they do not conflict with the React wrapper names. For example,
|
|
314
|
+
* IonButton would be imported as IonButtonCmp so as to not conflict with the
|
|
315
|
+
* IonButton React Component that takes in the Web Component as a parameter.
|
|
316
|
+
*/
|
|
317
|
+
if (outputTarget.includeImportCustomElements && outputTarget.componentCorePackage !== undefined) {
|
|
318
|
+
const cmpImports = components.map(component => {
|
|
319
|
+
const pascalImport = dashToPascalCase(component.tagName);
|
|
320
|
+
return `import { defineCustomElement as define${pascalImport} } from '${normalizePath(outputTarget.componentCorePackage)}/${outputTarget.customElementsDir ||
|
|
321
|
+
'components'}/${component.tagName}.js';`;
|
|
322
|
+
});
|
|
323
|
+
sourceImports = cmpImports.join('\n');
|
|
324
|
+
}
|
|
298
325
|
const final = [
|
|
299
326
|
imports,
|
|
300
327
|
typeImports,
|
|
328
|
+
sourceImports,
|
|
301
329
|
components
|
|
302
|
-
.map(createComponentDefinition(outputTarget.componentCorePackage))
|
|
330
|
+
.map(createComponentDefinition(outputTarget.componentCorePackage, distTypesDir, rootDir, outputTarget.includeImportCustomElements, outputTarget.customElementsDir))
|
|
303
331
|
.join('\n'),
|
|
304
332
|
];
|
|
305
333
|
return final.join('\n') + '\n';
|
package/dist/output-angular.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import { relativeImport, normalizePath, sortBy, readPackageJson } from './utils';
|
|
2
|
+
import { relativeImport, normalizePath, sortBy, readPackageJson, dashToPascalCase } from './utils';
|
|
3
3
|
import { createComponentDefinition } from './generate-angular-component';
|
|
4
4
|
import { generateAngularDirectivesFile } from './generate-angular-directives-file';
|
|
5
5
|
import generateValueAccessors from './generate-value-accessors';
|
|
6
6
|
export async function angularDirectiveProxyOutput(compilerCtx, outputTarget, components, config) {
|
|
7
7
|
const filteredComponents = getFilteredComponents(outputTarget.excludeComponents, components);
|
|
8
8
|
const rootDir = config.rootDir;
|
|
9
|
-
const pkgData = await readPackageJson(rootDir);
|
|
9
|
+
const pkgData = await readPackageJson(config, rootDir);
|
|
10
10
|
const finalText = generateProxies(filteredComponents, pkgData, outputTarget, config.rootDir);
|
|
11
11
|
await Promise.all([
|
|
12
12
|
compilerCtx.fs.writeFile(outputTarget.directivesProxyFile, finalText),
|
|
@@ -41,14 +41,39 @@ export function generateProxies(components, pkgData, outputTarget, rootDir) {
|
|
|
41
41
|
/* auto-generated angular directive proxies */
|
|
42
42
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, NgZone } from '@angular/core';
|
|
43
43
|
import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils';\n`;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Generate JSX import type from correct location.
|
|
46
|
+
* When using custom elements build, we need to import from
|
|
47
|
+
* either the "components" directory or customElementsDir
|
|
48
|
+
* otherwise we risk bundlers pulling in lazy loaded imports.
|
|
49
|
+
*/
|
|
50
|
+
const generateTypeImports = () => {
|
|
51
|
+
let importLocation = outputTarget.componentCorePackage ? normalizePath(outputTarget.componentCorePackage) : normalizePath(componentsTypeFile);
|
|
52
|
+
importLocation += outputTarget.includeImportCustomElements ? `/${outputTarget.customElementsDir || 'components'}` : '';
|
|
53
|
+
return `import ${outputTarget.includeImportCustomElements ? 'type ' : ''}{ ${IMPORT_TYPES} } from '${importLocation}';\n`;
|
|
54
|
+
};
|
|
55
|
+
const typeImports = generateTypeImports();
|
|
56
|
+
let sourceImports = '';
|
|
57
|
+
/**
|
|
58
|
+
* Build an array of Custom Elements build imports and namespace them
|
|
59
|
+
* so that they do not conflict with the React wrapper names. For example,
|
|
60
|
+
* IonButton would be imported as IonButtonCmp so as to not conflict with the
|
|
61
|
+
* IonButton React Component that takes in the Web Component as a parameter.
|
|
62
|
+
*/
|
|
63
|
+
if (outputTarget.includeImportCustomElements && outputTarget.componentCorePackage !== undefined) {
|
|
64
|
+
const cmpImports = components.map(component => {
|
|
65
|
+
const pascalImport = dashToPascalCase(component.tagName);
|
|
66
|
+
return `import { defineCustomElement as define${pascalImport} } from '${normalizePath(outputTarget.componentCorePackage)}/${outputTarget.customElementsDir ||
|
|
67
|
+
'components'}/${component.tagName}.js';`;
|
|
68
|
+
});
|
|
69
|
+
sourceImports = cmpImports.join('\n');
|
|
70
|
+
}
|
|
47
71
|
const final = [
|
|
48
72
|
imports,
|
|
49
73
|
typeImports,
|
|
74
|
+
sourceImports,
|
|
50
75
|
components
|
|
51
|
-
.map(createComponentDefinition(outputTarget.componentCorePackage, distTypesDir, rootDir))
|
|
76
|
+
.map(createComponentDefinition(outputTarget.componentCorePackage, distTypesDir, rootDir, outputTarget.includeImportCustomElements, outputTarget.customElementsDir))
|
|
52
77
|
.join('\n'),
|
|
53
78
|
];
|
|
54
79
|
return final.join('\n') + '\n';
|
package/dist/types.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export interface OutputTargetAngular {
|
|
|
5
5
|
directivesUtilsFile?: string;
|
|
6
6
|
valueAccessorConfigs?: ValueAccessorConfig[];
|
|
7
7
|
excludeComponents?: string[];
|
|
8
|
+
includeImportCustomElements?: boolean;
|
|
9
|
+
customElementsDir?: string;
|
|
8
10
|
}
|
|
9
11
|
export declare type ValueAccessorTypes = 'text' | 'radio' | 'select' | 'number' | 'boolean';
|
|
10
12
|
export interface ValueAccessorConfig {
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Config } from '@stencil/core/internal';
|
|
1
2
|
import type { PackageJSON } from './types';
|
|
2
3
|
export declare const toLowerCase: (str: string) => string;
|
|
3
4
|
export declare const dashToPascalCase: (str: string) => string;
|
|
@@ -5,4 +6,4 @@ export declare function sortBy<T>(array: T[], prop: (item: T) => string): T[];
|
|
|
5
6
|
export declare function normalizePath(str: string): string;
|
|
6
7
|
export declare function relativeImport(pathFrom: string, pathTo: string, ext?: string): string;
|
|
7
8
|
export declare function isRelativePath(path: string): boolean | "";
|
|
8
|
-
export declare function readPackageJson(rootDir: string): Promise<PackageJSON>;
|
|
9
|
+
export declare function readPackageJson(config: Config, rootDir: string): Promise<PackageJSON>;
|
package/dist/utils.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import { promisify } from 'util';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
const readFile = promisify(fs.readFile);
|
|
5
2
|
export const toLowerCase = (str) => str.toLowerCase();
|
|
6
3
|
export const dashToPascalCase = (str) => toLowerCase(str)
|
|
7
4
|
.split('-')
|
|
@@ -58,11 +55,12 @@ export function relativeImport(pathFrom, pathTo, ext) {
|
|
|
58
55
|
export function isRelativePath(path) {
|
|
59
56
|
return path && path.startsWith('.');
|
|
60
57
|
}
|
|
61
|
-
export async function readPackageJson(rootDir) {
|
|
58
|
+
export async function readPackageJson(config, rootDir) {
|
|
59
|
+
var _a;
|
|
62
60
|
const pkgJsonPath = path.join(rootDir, 'package.json');
|
|
63
61
|
let pkgJson;
|
|
64
62
|
try {
|
|
65
|
-
pkgJson = await readFile(pkgJsonPath, 'utf8');
|
|
63
|
+
pkgJson = (await ((_a = config.sys) === null || _a === void 0 ? void 0 : _a.readFile(pkgJsonPath, 'utf8')));
|
|
66
64
|
}
|
|
67
65
|
catch (e) {
|
|
68
66
|
throw new Error(`Missing "package.json" file for distribution: ${pkgJsonPath}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stencil/angular-output-target",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-1",
|
|
4
4
|
"description": "Angular output target for @stencil/core components.",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"@angular/core": "8.2.14",
|
|
38
38
|
"@angular/forms": "8.2.14"
|
|
39
39
|
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"@stencil/core": "^2.9.0"
|
|
42
|
+
},
|
|
40
43
|
"jest": {
|
|
41
44
|
"transform": {
|
|
42
45
|
"^.+\\.(js|ts|tsx)$": "<rootDir>/test/jest.preprocessor.js"
|