@stencil/angular-output-target 1.0.0 → 1.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.
@@ -1,10 +1,10 @@
1
1
  import type { ComponentCompilerEvent, ComponentCompilerProperty } from '@stencil/core/internal';
2
- import type { OutputType } from './types';
2
+ import type { ComponentInputProperty, OutputType } from './types';
3
3
  /**
4
4
  * Creates an Angular component declaration from formatted Stencil compiler metadata.
5
5
  *
6
6
  * @param tagName The tag name of the component.
7
- * @param inputs The inputs of the Stencil component (e.g. ['myInput']).
7
+ * @param inputs The inputs of the Stencil component (e.g. [{name: 'myInput', required: true]).
8
8
  * @param outputs The outputs/events of the Stencil component. (e.g. ['myOutput']).
9
9
  * @param methods The methods of the Stencil component. (e.g. ['myMethod']).
10
10
  * @param includeImportCustomElements Whether to define the component as a custom element.
@@ -12,7 +12,7 @@ import type { OutputType } from './types';
12
12
  * @param inlineComponentProps List of properties that should be inlined into the component definition.
13
13
  * @returns The component declaration as a string.
14
14
  */
15
- export declare const createAngularComponentDefinition: (tagName: string, inputs: readonly string[], outputs: readonly string[], methods: readonly string[], includeImportCustomElements?: boolean, standalone?: boolean, inlineComponentProps?: readonly ComponentCompilerProperty[]) => string;
15
+ export declare const createAngularComponentDefinition: (tagName: string, inputs: readonly ComponentInputProperty[], outputs: readonly string[], methods: readonly string[], includeImportCustomElements?: boolean, standalone?: boolean, inlineComponentProps?: readonly ComponentCompilerProperty[]) => string;
16
16
  /**
17
17
  * Creates the component interface type definition.
18
18
  * @param outputType The output type.
@@ -1,4 +1,4 @@
1
- import { createComponentEventTypeImports, dashToPascalCase, formatToQuotedList } from './utils';
1
+ import { createComponentEventTypeImports, dashToPascalCase, formatToQuotedList, mapPropName } from './utils';
2
2
  /**
3
3
  * Creates a property declaration.
4
4
  *
@@ -24,11 +24,30 @@ function createPropertyDeclaration(prop, type, inlinePropertyAsSetter = false) {
24
24
  ${eventName}: ${type};`;
25
25
  }
26
26
  }
27
+ /**
28
+ * Creates a formatted inputs text with required declaration.
29
+ *
30
+ * @param prop A ComponentCompilerEvent or ComponentCompilerProperty to turn into a property declaration.
31
+ * @param inputs The inputs of the Stencil component (e.g. [{name: 'myInput', required: true]).
32
+ * @returns The inputs list declaration as a string.
33
+ */
34
+ function formatInputs(inputs) {
35
+ return inputs
36
+ .map((item) => {
37
+ if (item.required) {
38
+ return `{ name: '${item.name}', required: true }`;
39
+ }
40
+ else {
41
+ return `'${item.name}'`;
42
+ }
43
+ })
44
+ .join(', ');
45
+ }
27
46
  /**
28
47
  * Creates an Angular component declaration from formatted Stencil compiler metadata.
29
48
  *
30
49
  * @param tagName The tag name of the component.
31
- * @param inputs The inputs of the Stencil component (e.g. ['myInput']).
50
+ * @param inputs The inputs of the Stencil component (e.g. [{name: 'myInput', required: true]).
32
51
  * @param outputs The outputs/events of the Stencil component. (e.g. ['myOutput']).
33
52
  * @param methods The methods of the Stencil component. (e.g. ['myMethod']).
34
53
  * @param includeImportCustomElements Whether to define the component as a custom element.
@@ -42,7 +61,10 @@ export const createAngularComponentDefinition = (tagName, inputs, outputs, metho
42
61
  const hasOutputs = outputs.length > 0;
43
62
  const hasMethods = methods.length > 0;
44
63
  // Formats the input strings into comma separated, single quoted values.
45
- const formattedInputs = formatToQuotedList(inputs);
64
+ const proxyCmpFormattedInputs = formatToQuotedList(inputs.map(mapPropName));
65
+ // Formats the input strings into comma separated, single quoted values if optional.
66
+ // Formats the required input strings into comma separated {name, required} objects.
67
+ const formattedInputs = formatInputs(inputs);
46
68
  // Formats the output strings into comma separated, single quoted values.
47
69
  const formattedOutputs = formatToQuotedList(outputs);
48
70
  // Formats the method strings into comma separated, single quoted values.
@@ -53,7 +75,7 @@ export const createAngularComponentDefinition = (tagName, inputs, outputs, metho
53
75
  proxyCmpOptions.push(`\n defineCustomElementFn: ${defineCustomElementFn}`);
54
76
  }
55
77
  if (hasInputs) {
56
- proxyCmpOptions.push(`\n inputs: [${formattedInputs}]`);
78
+ proxyCmpOptions.push(`\n inputs: [${proxyCmpFormattedInputs}]`);
57
79
  }
58
80
  if (hasMethods) {
59
81
  proxyCmpOptions.push(`\n methods: [${formattedMethods}]`);
package/dist/index.cjs.js CHANGED
@@ -15,6 +15,7 @@ const OutputTypes = {
15
15
  Standalone: 'standalone',
16
16
  };
17
17
  const toLowerCase = (str) => str.toLowerCase();
18
+ const mapPropName = (prop) => prop.name;
18
19
  const dashToPascalCase = (str) => toLowerCase(str)
19
20
  .split('-')
20
21
  .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
@@ -169,11 +170,30 @@ function createPropertyDeclaration(prop, type, inlinePropertyAsSetter = false) {
169
170
  ${eventName}: ${type};`;
170
171
  }
171
172
  }
173
+ /**
174
+ * Creates a formatted inputs text with required declaration.
175
+ *
176
+ * @param prop A ComponentCompilerEvent or ComponentCompilerProperty to turn into a property declaration.
177
+ * @param inputs The inputs of the Stencil component (e.g. [{name: 'myInput', required: true]).
178
+ * @returns The inputs list declaration as a string.
179
+ */
180
+ function formatInputs(inputs) {
181
+ return inputs
182
+ .map((item) => {
183
+ if (item.required) {
184
+ return `{ name: '${item.name}', required: true }`;
185
+ }
186
+ else {
187
+ return `'${item.name}'`;
188
+ }
189
+ })
190
+ .join(', ');
191
+ }
172
192
  /**
173
193
  * Creates an Angular component declaration from formatted Stencil compiler metadata.
174
194
  *
175
195
  * @param tagName The tag name of the component.
176
- * @param inputs The inputs of the Stencil component (e.g. ['myInput']).
196
+ * @param inputs The inputs of the Stencil component (e.g. [{name: 'myInput', required: true]).
177
197
  * @param outputs The outputs/events of the Stencil component. (e.g. ['myOutput']).
178
198
  * @param methods The methods of the Stencil component. (e.g. ['myMethod']).
179
199
  * @param includeImportCustomElements Whether to define the component as a custom element.
@@ -187,7 +207,10 @@ const createAngularComponentDefinition = (tagName, inputs, outputs, methods, inc
187
207
  const hasOutputs = outputs.length > 0;
188
208
  const hasMethods = methods.length > 0;
189
209
  // Formats the input strings into comma separated, single quoted values.
190
- const formattedInputs = formatToQuotedList(inputs);
210
+ const proxyCmpFormattedInputs = formatToQuotedList(inputs.map(mapPropName));
211
+ // Formats the input strings into comma separated, single quoted values if optional.
212
+ // Formats the required input strings into comma separated {name, required} objects.
213
+ const formattedInputs = formatInputs(inputs);
191
214
  // Formats the output strings into comma separated, single quoted values.
192
215
  const formattedOutputs = formatToQuotedList(outputs);
193
216
  // Formats the method strings into comma separated, single quoted values.
@@ -198,7 +221,7 @@ const createAngularComponentDefinition = (tagName, inputs, outputs, methods, inc
198
221
  proxyCmpOptions.push(`\n defineCustomElementFn: ${defineCustomElementFn}`);
199
222
  }
200
223
  if (hasInputs) {
201
- proxyCmpOptions.push(`\n inputs: [${formattedInputs}]`);
224
+ proxyCmpOptions.push(`\n inputs: [${proxyCmpFormattedInputs}]`);
202
225
  }
203
226
  if (hasMethods) {
204
227
  proxyCmpOptions.push(`\n methods: [${formattedMethods}]`);
@@ -522,7 +545,14 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
522
545
  }
523
546
  const proxyFileOutput = [];
524
547
  const filterInternalProps = (prop) => !prop.internal;
525
- const mapPropName = (prop) => prop.name;
548
+ // Ensure that virtual properties has required as false.
549
+ const mapInputProp = (prop) => {
550
+ var _a;
551
+ return ({
552
+ name: prop.name,
553
+ required: (_a = prop.required) !== null && _a !== void 0 ? _a : false,
554
+ });
555
+ };
526
556
  const { componentCorePackage, customElementsDir } = outputTarget;
527
557
  for (let cmpMeta of components) {
528
558
  const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
@@ -530,11 +560,11 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
530
560
  if (cmpMeta.properties) {
531
561
  internalProps.push(...cmpMeta.properties.filter(filterInternalProps));
532
562
  }
533
- const inputs = internalProps.map(mapPropName);
563
+ const inputs = internalProps.map(mapInputProp);
534
564
  if (cmpMeta.virtualProperties) {
535
- inputs.push(...cmpMeta.virtualProperties.map(mapPropName));
565
+ inputs.push(...cmpMeta.virtualProperties.map(mapInputProp));
536
566
  }
537
- inputs.sort();
567
+ const orderedInputs = sortBy(inputs, (cip) => cip.name);
538
568
  const outputs = [];
539
569
  if (cmpMeta.events) {
540
570
  outputs.push(...cmpMeta.events.filter(filterInternalProps).map(mapPropName));
@@ -550,7 +580,7 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
550
580
  * 2. Optionally the @NgModule decorated class (if includeSingleComponentAngularModules is true)
551
581
  * 3. The component interface (using declaration merging for types).
552
582
  */
553
- const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
583
+ const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, orderedInputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
554
584
  const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName);
555
585
  const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir);
556
586
  proxyFileOutput.push(componentDefinition, '\n');
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ const OutputTypes = {
7
7
  Standalone: 'standalone',
8
8
  };
9
9
  const toLowerCase = (str) => str.toLowerCase();
10
+ const mapPropName = (prop) => prop.name;
10
11
  const dashToPascalCase = (str) => toLowerCase(str)
11
12
  .split('-')
12
13
  .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
@@ -161,11 +162,30 @@ function createPropertyDeclaration(prop, type, inlinePropertyAsSetter = false) {
161
162
  ${eventName}: ${type};`;
162
163
  }
163
164
  }
165
+ /**
166
+ * Creates a formatted inputs text with required declaration.
167
+ *
168
+ * @param prop A ComponentCompilerEvent or ComponentCompilerProperty to turn into a property declaration.
169
+ * @param inputs The inputs of the Stencil component (e.g. [{name: 'myInput', required: true]).
170
+ * @returns The inputs list declaration as a string.
171
+ */
172
+ function formatInputs(inputs) {
173
+ return inputs
174
+ .map((item) => {
175
+ if (item.required) {
176
+ return `{ name: '${item.name}', required: true }`;
177
+ }
178
+ else {
179
+ return `'${item.name}'`;
180
+ }
181
+ })
182
+ .join(', ');
183
+ }
164
184
  /**
165
185
  * Creates an Angular component declaration from formatted Stencil compiler metadata.
166
186
  *
167
187
  * @param tagName The tag name of the component.
168
- * @param inputs The inputs of the Stencil component (e.g. ['myInput']).
188
+ * @param inputs The inputs of the Stencil component (e.g. [{name: 'myInput', required: true]).
169
189
  * @param outputs The outputs/events of the Stencil component. (e.g. ['myOutput']).
170
190
  * @param methods The methods of the Stencil component. (e.g. ['myMethod']).
171
191
  * @param includeImportCustomElements Whether to define the component as a custom element.
@@ -179,7 +199,10 @@ const createAngularComponentDefinition = (tagName, inputs, outputs, methods, inc
179
199
  const hasOutputs = outputs.length > 0;
180
200
  const hasMethods = methods.length > 0;
181
201
  // Formats the input strings into comma separated, single quoted values.
182
- const formattedInputs = formatToQuotedList(inputs);
202
+ const proxyCmpFormattedInputs = formatToQuotedList(inputs.map(mapPropName));
203
+ // Formats the input strings into comma separated, single quoted values if optional.
204
+ // Formats the required input strings into comma separated {name, required} objects.
205
+ const formattedInputs = formatInputs(inputs);
183
206
  // Formats the output strings into comma separated, single quoted values.
184
207
  const formattedOutputs = formatToQuotedList(outputs);
185
208
  // Formats the method strings into comma separated, single quoted values.
@@ -190,7 +213,7 @@ const createAngularComponentDefinition = (tagName, inputs, outputs, methods, inc
190
213
  proxyCmpOptions.push(`\n defineCustomElementFn: ${defineCustomElementFn}`);
191
214
  }
192
215
  if (hasInputs) {
193
- proxyCmpOptions.push(`\n inputs: [${formattedInputs}]`);
216
+ proxyCmpOptions.push(`\n inputs: [${proxyCmpFormattedInputs}]`);
194
217
  }
195
218
  if (hasMethods) {
196
219
  proxyCmpOptions.push(`\n methods: [${formattedMethods}]`);
@@ -514,7 +537,14 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
514
537
  }
515
538
  const proxyFileOutput = [];
516
539
  const filterInternalProps = (prop) => !prop.internal;
517
- const mapPropName = (prop) => prop.name;
540
+ // Ensure that virtual properties has required as false.
541
+ const mapInputProp = (prop) => {
542
+ var _a;
543
+ return ({
544
+ name: prop.name,
545
+ required: (_a = prop.required) !== null && _a !== void 0 ? _a : false,
546
+ });
547
+ };
518
548
  const { componentCorePackage, customElementsDir } = outputTarget;
519
549
  for (let cmpMeta of components) {
520
550
  const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
@@ -522,11 +552,11 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
522
552
  if (cmpMeta.properties) {
523
553
  internalProps.push(...cmpMeta.properties.filter(filterInternalProps));
524
554
  }
525
- const inputs = internalProps.map(mapPropName);
555
+ const inputs = internalProps.map(mapInputProp);
526
556
  if (cmpMeta.virtualProperties) {
527
- inputs.push(...cmpMeta.virtualProperties.map(mapPropName));
557
+ inputs.push(...cmpMeta.virtualProperties.map(mapInputProp));
528
558
  }
529
- inputs.sort();
559
+ const orderedInputs = sortBy(inputs, (cip) => cip.name);
530
560
  const outputs = [];
531
561
  if (cmpMeta.events) {
532
562
  outputs.push(...cmpMeta.events.filter(filterInternalProps).map(mapPropName));
@@ -542,7 +572,7 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
542
572
  * 2. Optionally the @NgModule decorated class (if includeSingleComponentAngularModules is true)
543
573
  * 3. The component interface (using declaration merging for types).
544
574
  */
545
- const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
575
+ const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, orderedInputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
546
576
  const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName);
547
577
  const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir);
548
578
  proxyFileOutput.push(componentDefinition, '\n');
@@ -1,5 +1,5 @@
1
1
  import path from 'path';
2
- import { relativeImport, normalizePath, sortBy, readPackageJson, dashToPascalCase, createImportStatement, isOutputTypeCustomElementsBuild, OutputTypes, } from './utils';
2
+ import { relativeImport, normalizePath, sortBy, readPackageJson, dashToPascalCase, createImportStatement, isOutputTypeCustomElementsBuild, OutputTypes, mapPropName, } from './utils';
3
3
  import { createAngularComponentDefinition, createComponentTypeDefinition } from './generate-angular-component';
4
4
  import { generateAngularDirectivesFile } from './generate-angular-directives-file';
5
5
  import generateValueAccessors from './generate-value-accessors';
@@ -97,7 +97,14 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
97
97
  }
98
98
  const proxyFileOutput = [];
99
99
  const filterInternalProps = (prop) => !prop.internal;
100
- const mapPropName = (prop) => prop.name;
100
+ // Ensure that virtual properties has required as false.
101
+ const mapInputProp = (prop) => {
102
+ var _a;
103
+ return ({
104
+ name: prop.name,
105
+ required: (_a = prop.required) !== null && _a !== void 0 ? _a : false,
106
+ });
107
+ };
101
108
  const { componentCorePackage, customElementsDir } = outputTarget;
102
109
  for (let cmpMeta of components) {
103
110
  const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
@@ -105,11 +112,11 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
105
112
  if (cmpMeta.properties) {
106
113
  internalProps.push(...cmpMeta.properties.filter(filterInternalProps));
107
114
  }
108
- const inputs = internalProps.map(mapPropName);
115
+ const inputs = internalProps.map(mapInputProp);
109
116
  if (cmpMeta.virtualProperties) {
110
- inputs.push(...cmpMeta.virtualProperties.map(mapPropName));
117
+ inputs.push(...cmpMeta.virtualProperties.map(mapInputProp));
111
118
  }
112
- inputs.sort();
119
+ const orderedInputs = sortBy(inputs, (cip) => cip.name);
113
120
  const outputs = [];
114
121
  if (cmpMeta.events) {
115
122
  outputs.push(...cmpMeta.events.filter(filterInternalProps).map(mapPropName));
@@ -125,7 +132,7 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
125
132
  * 2. Optionally the @NgModule decorated class (if includeSingleComponentAngularModules is true)
126
133
  * 3. The component interface (using declaration merging for types).
127
134
  */
128
- const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
135
+ const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, orderedInputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
129
136
  const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName);
130
137
  const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir);
131
138
  proxyFileOutput.push(componentDefinition, '\n');
package/dist/types.d.ts CHANGED
@@ -44,3 +44,7 @@ export interface ValueAccessorConfig {
44
44
  export interface PackageJSON {
45
45
  types: string;
46
46
  }
47
+ export interface ComponentInputProperty {
48
+ name: string;
49
+ required: boolean;
50
+ }
package/dist/utils.d.ts CHANGED
@@ -4,6 +4,9 @@ export declare const OutputTypes: {
4
4
  [key: string]: OutputType;
5
5
  };
6
6
  export declare const toLowerCase: (str: string) => string;
7
+ export declare const mapPropName: (prop: {
8
+ name: string;
9
+ }) => string;
7
10
  export declare const dashToPascalCase: (str: string) => string;
8
11
  export declare function sortBy<T>(array: T[], prop: (item: T) => string): T[];
9
12
  export declare function normalizePath(str: string): string;
package/dist/utils.js CHANGED
@@ -5,6 +5,7 @@ export const OutputTypes = {
5
5
  Standalone: 'standalone',
6
6
  };
7
7
  export const toLowerCase = (str) => str.toLowerCase();
8
+ export const mapPropName = (prop) => prop.name;
8
9
  export const dashToPascalCase = (str) => toLowerCase(str)
9
10
  .split('-')
10
11
  .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stencil/angular-output-target",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Angular output target for @stencil/core components.",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.js",
@@ -50,7 +50,7 @@
50
50
  "devDependencies": {
51
51
  "@angular/core": "8.2.14",
52
52
  "@angular/forms": "8.2.14",
53
- "@stencil/core": "4.32.0",
53
+ "@stencil/core": "4.35.1",
54
54
  "@types/node": "^18.0.0",
55
55
  "npm-run-all2": "^6.2.4",
56
56
  "rimraf": "^5.0.0",