@openwebf/webf 0.23.2 → 0.23.7

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/dist/vue.js CHANGED
@@ -8,17 +8,61 @@ const lodash_1 = __importDefault(require("lodash"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const declaration_1 = require("./declaration");
11
+ const logger_1 = require("./logger");
11
12
  const utils_1 = require("./utils");
12
13
  function readTemplate(name) {
13
14
  return fs_1.default.readFileSync(path_1.default.join(__dirname, '../templates/' + name + '.tpl'), { encoding: 'utf-8' });
14
15
  }
15
16
  function generateReturnType(type) {
17
+ if ((0, utils_1.isUnionType)(type)) {
18
+ const values = type.value;
19
+ return values.map(v => {
20
+ if (v.value === declaration_1.FunctionArgumentType.null) {
21
+ return 'null';
22
+ }
23
+ if (typeof v.value === 'string') {
24
+ return `'${v.value}'`;
25
+ }
26
+ return 'any';
27
+ }).join(' | ');
28
+ }
29
+ // Handle unions like boolean | null, number | null, CustomType | null
30
+ if (Array.isArray(type.value)) {
31
+ const values = type.value;
32
+ const hasNull = values.some(v => v.value === declaration_1.FunctionArgumentType.null);
33
+ if (hasNull) {
34
+ const nonNulls = values.filter(v => v.value !== declaration_1.FunctionArgumentType.null);
35
+ if (nonNulls.length === 0) {
36
+ return 'null';
37
+ }
38
+ const parts = nonNulls.map(v => generateReturnType(v));
39
+ const unique = Array.from(new Set(parts));
40
+ unique.push('null');
41
+ return unique.join(' | ');
42
+ }
43
+ // Complex non-null unions are rare; fall back to any
44
+ return 'any';
45
+ }
16
46
  if ((0, utils_1.isPointerType)(type)) {
17
47
  const pointerType = (0, utils_1.getPointerType)(type);
48
+ // Map Dart's `Type` (from TS typeof) to TS `any`
49
+ if (pointerType === 'Type')
50
+ return 'any';
51
+ if (typeof pointerType === 'string' && pointerType.startsWith('typeof ')) {
52
+ const ident = pointerType.substring('typeof '.length).trim();
53
+ return `typeof __webfTypes.${ident}`;
54
+ }
18
55
  return pointerType;
19
56
  }
20
57
  if (type.isArray && typeof type.value === 'object' && !Array.isArray(type.value)) {
21
- return `${(0, utils_1.getPointerType)(type.value)}[]`;
58
+ const elemType = (0, utils_1.getPointerType)(type.value);
59
+ if (elemType === 'Type')
60
+ return 'any[]';
61
+ if (typeof elemType === 'string' && elemType.startsWith('typeof ')) {
62
+ const ident = elemType.substring('typeof '.length).trim();
63
+ return `(typeof __webfTypes.${ident})[]`;
64
+ }
65
+ return `${elemType}[]`;
22
66
  }
23
67
  switch (type.value) {
24
68
  case declaration_1.FunctionArgumentType.int:
@@ -87,19 +131,34 @@ function generateVueComponent(blob) {
87
131
  && !object.name.endsWith('Events');
88
132
  });
89
133
  const dependencies = others.map(object => {
90
- if (!object || !object.props) {
134
+ if (!object || !object.props || object.props.length === 0) {
91
135
  return '';
92
136
  }
93
- const props = object.props.map(prop => {
94
- if (prop.optional) {
95
- return `${prop.name}?: ${generateReturnType(prop.type)};`;
137
+ const interfaceLines = [];
138
+ if (object.documentation && object.documentation.trim().length > 0) {
139
+ interfaceLines.push('/**');
140
+ object.documentation.split('\n').forEach(line => {
141
+ interfaceLines.push(` * ${line}`);
142
+ });
143
+ interfaceLines.push(' */');
144
+ }
145
+ interfaceLines.push(`interface ${object.name} {`);
146
+ const propLines = object.props.map(prop => {
147
+ const lines = [];
148
+ if (prop.documentation && prop.documentation.trim().length > 0) {
149
+ lines.push(' /**');
150
+ prop.documentation.split('\n').forEach(line => {
151
+ lines.push(` * ${line}`);
152
+ });
153
+ lines.push(' */');
96
154
  }
97
- return `${prop.name}: ${generateReturnType(prop.type)};`;
98
- }).join('\n ');
99
- return `
100
- interface ${object.name} {
101
- ${props}
102
- }`;
155
+ const optionalToken = prop.optional ? '?' : '';
156
+ lines.push(` ${prop.name}${optionalToken}: ${generateReturnType(prop.type)};`);
157
+ return lines.join('\n');
158
+ });
159
+ interfaceLines.push(propLines.join('\n'));
160
+ interfaceLines.push('}');
161
+ return interfaceLines.join('\n');
103
162
  }).filter(dep => dep.trim() !== '').join('\n\n');
104
163
  const componentProperties = properties.length > 0 ? properties[0] : undefined;
105
164
  const componentEvents = events.length > 0 ? events[0] : undefined;
@@ -192,6 +251,9 @@ function generateVueTypings(blobs) {
192
251
  const members = e.members.map(m => m.initializer ? `${m.name} = ${m.initializer}` : `${m.name}`).join(', ');
193
252
  return `export declare enum ${e.name} { ${members} }`;
194
253
  }).join('\n');
254
+ // Always import the types namespace to support typeof references
255
+ const typesImport = `import * as __webfTypes from './src/types';`;
256
+ (0, logger_1.debug)(`[vue] Generating typings; importing types from ./src/types`);
195
257
  // Build mapping of template tag names to class names for GlobalComponents
196
258
  const componentMetas = componentNames.map(className => ({
197
259
  className,
@@ -207,6 +269,7 @@ function generateVueTypings(blobs) {
207
269
  components,
208
270
  consts: constDeclarations,
209
271
  enums: enumDeclarations,
272
+ typesImport,
210
273
  });
211
274
  return content.split('\n').filter(str => {
212
275
  return str.trim().length > 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openwebf/webf",
3
- "version": "0.23.2",
3
+ "version": "0.23.7",
4
4
  "description": "Command line tools for WebF",
5
5
  "main": "index.js",
6
6
  "bin": {
package/src/analyzer.ts CHANGED
@@ -286,6 +286,20 @@ function getParameterBaseType(type: ts.TypeNode, mode?: ParameterMode): Paramete
286
286
  return basicType;
287
287
  }
288
288
 
289
+ // Handle `typeof SomeIdentifier` (TypeQuery) by preserving the textual form
290
+ // so React/Vue can keep strong typing (e.g., `typeof CupertinoIcons`).
291
+ // Dart mapping will convert this to `dynamic` later.
292
+ if (type.kind === ts.SyntaxKind.TypeQuery) {
293
+ const tq = type as ts.TypeQueryNode;
294
+ const getEntityNameText = (name: ts.EntityName): string => {
295
+ if (ts.isIdentifier(name)) return name.text;
296
+ // Qualified name: A.B.C
297
+ return `${getEntityNameText(name.left)}.${name.right.text}`;
298
+ };
299
+ const nameText = getEntityNameText(tq.exprName);
300
+ return `typeof ${nameText}`;
301
+ }
302
+
289
303
  if (type.kind === ts.SyntaxKind.TypeReference) {
290
304
  const typeReference = type as ts.TypeReferenceNode;
291
305
  const typeName = typeReference.typeName;
@@ -405,7 +419,45 @@ function handleCustomEventType(typeReference: ts.TypeReferenceNode): ParameterBa
405
419
  const argument = typeReference.typeArguments[0];
406
420
  let genericType: string;
407
421
 
408
- if (ts.isTypeReferenceNode(argument) && ts.isIdentifier(argument.typeName)) {
422
+ // Preserve simple union/compound generic types (e.g., boolean | null)
423
+ if (ts.isUnionTypeNode(argument) || ts.isIntersectionTypeNode(argument)) {
424
+ const unionTypes = (argument as ts.UnionTypeNode | ts.IntersectionTypeNode).types ?? [];
425
+ const parts = unionTypes.map(t => {
426
+ // Literal union members: handle null/undefined explicitly
427
+ if (ts.isLiteralTypeNode(t)) {
428
+ const lit = t.literal;
429
+ if (lit.kind === ts.SyntaxKind.NullKeyword) return 'null';
430
+ if (lit.kind === ts.SyntaxKind.UndefinedKeyword) return 'undefined';
431
+ if (ts.isStringLiteral(lit)) return JSON.stringify(lit.text);
432
+ return 'any';
433
+ }
434
+ // Basic keywords: boolean, string, number, null, undefined
435
+ const basic = BASIC_TYPE_MAP[t.kind];
436
+ if (basic !== undefined) {
437
+ switch (basic) {
438
+ case FunctionArgumentType.boolean:
439
+ return 'boolean';
440
+ case FunctionArgumentType.dom_string:
441
+ return 'string';
442
+ case FunctionArgumentType.double:
443
+ case FunctionArgumentType.int:
444
+ return 'number';
445
+ case FunctionArgumentType.null:
446
+ return 'null';
447
+ case FunctionArgumentType.undefined:
448
+ return 'undefined';
449
+ default:
450
+ return 'any';
451
+ }
452
+ }
453
+ // Literal null/undefined keywords that BASIC_TYPE_MAP may not cover
454
+ if (t.kind === ts.SyntaxKind.NullKeyword) return 'null';
455
+ if (t.kind === ts.SyntaxKind.UndefinedKeyword) return 'undefined';
456
+ // Fallback: rely on toString of node kind
457
+ return 'any';
458
+ });
459
+ genericType = parts.join(' | ');
460
+ } else if (ts.isTypeReferenceNode(argument) && ts.isIdentifier(argument.typeName)) {
409
461
  const typeName = argument.typeName.text;
410
462
 
411
463
  // Check if it's a mapped type reference like 'int' or 'double'
@@ -699,7 +751,11 @@ function processEnumDeclaration(
699
751
  }
700
752
  return mem;
701
753
  });
702
-
754
+
755
+ // Register globally for cross-file lookups (e.g., Dart mapping decisions)
756
+ try {
757
+ EnumObject.globalEnumSet.add(enumObj.name);
758
+ } catch {}
703
759
  return enumObj;
704
760
  }
705
761