@openwebf/webf 0.23.10 → 0.24.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/dist/commands.js CHANGED
@@ -20,6 +20,7 @@ const path_1 = __importDefault(require("path"));
20
20
  const os_1 = __importDefault(require("os"));
21
21
  const generator_1 = require("./generator");
22
22
  const module_1 = require("./module");
23
+ const peerDeps_1 = require("./peerDeps");
23
24
  const glob_1 = require("glob");
24
25
  const lodash_1 = __importDefault(require("lodash"));
25
26
  const inquirer_1 = __importDefault(require("inquirer"));
@@ -177,6 +178,33 @@ function readFlutterPackageMetadata(packagePath) {
177
178
  return null;
178
179
  }
179
180
  }
181
+ function copyReadmeToPackageRoot(params) {
182
+ const { sourceRoot, targetRoot } = params;
183
+ const targetPath = path_1.default.join(targetRoot, 'README.md');
184
+ if (fs_1.default.existsSync(targetPath)) {
185
+ return { copied: false, targetPath };
186
+ }
187
+ const candidateNames = ['README.md', 'Readme.md', 'readme.md'];
188
+ let sourcePath = null;
189
+ for (const candidate of candidateNames) {
190
+ const abs = path_1.default.join(sourceRoot, candidate);
191
+ if (fs_1.default.existsSync(abs)) {
192
+ sourcePath = abs;
193
+ break;
194
+ }
195
+ }
196
+ if (!sourcePath) {
197
+ return { copied: false, targetPath };
198
+ }
199
+ try {
200
+ const content = fs_1.default.readFileSync(sourcePath, 'utf-8');
201
+ writeFileIfChanged(targetPath, content);
202
+ return { copied: true, sourcePath, targetPath };
203
+ }
204
+ catch (_a) {
205
+ return { copied: false, targetPath };
206
+ }
207
+ }
180
208
  // Copy markdown docs that match .d.ts basenames from source to the built dist folder,
181
209
  // and generate an aggregated README.md in the dist directory.
182
210
  function copyMarkdownDocsToDist(params) {
@@ -350,7 +378,8 @@ function createCommand(target, options) {
350
378
  // Do not overwrite existing index.ts created by the user
351
379
  // Leave merge to the codegen step which appends exports safely
352
380
  }
353
- (0, child_process_1.spawnSync)(NPM, ['install'], {
381
+ // Ensure devDependencies are installed even if the user's shell has NODE_ENV=production.
382
+ (0, child_process_1.spawnSync)(NPM, ['install', '--production=false'], {
354
383
  cwd: target,
355
384
  stdio: 'inherit'
356
385
  });
@@ -369,11 +398,8 @@ function createCommand(target, options) {
369
398
  const gitignorePath = path_1.default.join(target, '.gitignore');
370
399
  const gitignoreContent = lodash_1.default.template(gitignore)({});
371
400
  writeFileIfChanged(gitignorePath, gitignoreContent);
372
- (0, child_process_1.spawnSync)(NPM, ['install', '@openwebf/webf-enterprise-typings'], {
373
- cwd: target,
374
- stdio: 'inherit'
375
- });
376
- (0, child_process_1.spawnSync)(NPM, ['install', 'vue', '-D'], {
401
+ // Ensure devDependencies are installed even if the user's shell has NODE_ENV=production.
402
+ (0, child_process_1.spawnSync)(NPM, ['install', '--production=false'], {
377
403
  cwd: target,
378
404
  stdio: 'inherit'
379
405
  });
@@ -658,6 +684,16 @@ function generateCommand(distPath, options) {
658
684
  }
659
685
  // Auto-initialize typings in the output directory if needed
660
686
  ensureInitialized(resolvedDistPath);
687
+ // Copy README.md from the source Flutter package into the npm package root (so `npm publish` includes it).
688
+ if (options.flutterPackageSrc) {
689
+ const { copied } = copyReadmeToPackageRoot({
690
+ sourceRoot: options.flutterPackageSrc,
691
+ targetRoot: resolvedDistPath,
692
+ });
693
+ if (copied) {
694
+ console.log('📄 Copied README.md to package root');
695
+ }
696
+ }
661
697
  console.log(`\nGenerating ${framework} code from ${options.flutterPackageSrc}...`);
662
698
  yield (0, generator_1.dartGen)({
663
699
  source: options.flutterPackageSrc,
@@ -1003,7 +1039,7 @@ function ensureInitialized(targetPath) {
1003
1039
  }
1004
1040
  function buildPackage(packagePath) {
1005
1041
  return __awaiter(this, void 0, void 0, function* () {
1006
- var _a;
1042
+ var _a, _b, _c;
1007
1043
  const packageJsonPath = path_1.default.join(packagePath, 'package.json');
1008
1044
  if (!fs_1.default.existsSync(packageJsonPath)) {
1009
1045
  // Skip the error in test environment to avoid console warnings
@@ -1015,6 +1051,91 @@ function buildPackage(packagePath) {
1015
1051
  const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
1016
1052
  const packageName = packageJson.name;
1017
1053
  const packageVersion = packageJson.version;
1054
+ function getInstalledPackageJsonPath(pkgName) {
1055
+ const parts = pkgName.split('/');
1056
+ return path_1.default.join(packagePath, 'node_modules', ...parts, 'package.json');
1057
+ }
1058
+ function getInstalledPackageDir(pkgName) {
1059
+ const parts = pkgName.split('/');
1060
+ return path_1.default.join(packagePath, 'node_modules', ...parts);
1061
+ }
1062
+ function findUp(startDir, relativePathToFind) {
1063
+ let dir = path_1.default.resolve(startDir);
1064
+ while (true) {
1065
+ const candidate = path_1.default.join(dir, relativePathToFind);
1066
+ if (fs_1.default.existsSync(candidate))
1067
+ return candidate;
1068
+ const parent = path_1.default.dirname(dir);
1069
+ if (parent === dir)
1070
+ return null;
1071
+ dir = parent;
1072
+ }
1073
+ }
1074
+ function ensurePeerDependencyAvailableForBuild(peerName) {
1075
+ var _a, _b;
1076
+ const installedPkgJson = getInstalledPackageJsonPath(peerName);
1077
+ if (fs_1.default.existsSync(installedPkgJson))
1078
+ return;
1079
+ const peerRange = (_a = packageJson.peerDependencies) === null || _a === void 0 ? void 0 : _a[peerName];
1080
+ const localMap = {
1081
+ '@openwebf/react-core-ui': path_1.default.join('packages', 'react-core-ui'),
1082
+ '@openwebf/vue-core-ui': path_1.default.join('packages', 'vue-core-ui'),
1083
+ };
1084
+ let installSpec = null;
1085
+ const localRel = localMap[peerName];
1086
+ if (localRel) {
1087
+ const localPath = findUp(process.cwd(), localRel);
1088
+ if (localPath) {
1089
+ if (!(0, peerDeps_1.isPackageTypesReady)(localPath)) {
1090
+ const localPkgJsonPath = path_1.default.join(localPath, 'package.json');
1091
+ if (fs_1.default.existsSync(localPkgJsonPath)) {
1092
+ const localPkgJson = (0, peerDeps_1.readJsonFile)(localPkgJsonPath);
1093
+ if ((_b = localPkgJson.scripts) === null || _b === void 0 ? void 0 : _b.build) {
1094
+ if (process.env.WEBF_CODEGEN_BUILD_LOCAL_PEERS !== '1') {
1095
+ console.warn(`\n⚠️ Local ${peerName} found at ${localPath} but type declarations are missing; falling back to registry install.`);
1096
+ }
1097
+ else {
1098
+ console.log(`\n🔧 Local ${peerName} found at ${localPath} but build artifacts are missing; building it for DTS...`);
1099
+ const buildLocalResult = (0, child_process_1.spawnSync)(NPM, ['run', 'build'], {
1100
+ cwd: localPath,
1101
+ stdio: 'inherit'
1102
+ });
1103
+ if (buildLocalResult.status === 0) {
1104
+ if ((0, peerDeps_1.isPackageTypesReady)(localPath)) {
1105
+ installSpec = localPath;
1106
+ }
1107
+ else {
1108
+ console.warn(`\n⚠️ Built local ${peerName} but type declarations are still missing; falling back to registry install.`);
1109
+ }
1110
+ }
1111
+ else {
1112
+ console.warn(`\n⚠️ Failed to build local ${peerName}; falling back to registry install.`);
1113
+ }
1114
+ }
1115
+ }
1116
+ }
1117
+ }
1118
+ else {
1119
+ installSpec = localPath;
1120
+ }
1121
+ }
1122
+ }
1123
+ if (!installSpec) {
1124
+ installSpec = peerRange ? `${peerName}@${peerRange}` : peerName;
1125
+ }
1126
+ console.log(`\n📦 Installing peer dependency for build: ${peerName}...`);
1127
+ const installResult = (0, child_process_1.spawnSync)(NPM, ['install', '--no-save', installSpec], {
1128
+ cwd: packagePath,
1129
+ stdio: 'inherit'
1130
+ });
1131
+ if (installResult.status !== 0) {
1132
+ throw new Error(`Failed to install peer dependency for build: ${peerName}`);
1133
+ }
1134
+ const installedTypesFile = (0, peerDeps_1.getPackageTypesFileFromDir)(getInstalledPackageDir(peerName));
1135
+ if (installedTypesFile && !fs_1.default.existsSync(installedTypesFile)) {
1136
+ throw new Error(`Peer dependency ${peerName} was installed but type declarations were not found at ${installedTypesFile}`);
1137
+ }
1138
+ }
1018
1139
  // Check if node_modules exists
1019
1140
  const nodeModulesPath = path_1.default.join(packagePath, 'node_modules');
1020
1141
  if (!fs_1.default.existsSync(nodeModulesPath)) {
@@ -1035,6 +1156,13 @@ function buildPackage(packagePath) {
1035
1156
  }
1036
1157
  // Check if package has a build script
1037
1158
  if ((_a = packageJson.scripts) === null || _a === void 0 ? void 0 : _a.build) {
1159
+ // DTS build needs peer deps present locally to resolve types (even though they are not bundled).
1160
+ if ((_b = packageJson.peerDependencies) === null || _b === void 0 ? void 0 : _b['@openwebf/react-core-ui']) {
1161
+ ensurePeerDependencyAvailableForBuild('@openwebf/react-core-ui');
1162
+ }
1163
+ if ((_c = packageJson.peerDependencies) === null || _c === void 0 ? void 0 : _c['@openwebf/vue-core-ui']) {
1164
+ ensurePeerDependencyAvailableForBuild('@openwebf/vue-core-ui');
1165
+ }
1038
1166
  console.log(`\nBuilding ${packageName}@${packageVersion}...`);
1039
1167
  const buildResult = (0, child_process_1.spawnSync)(NPM, ['run', 'build'], {
1040
1168
  cwd: packagePath,
package/dist/generator.js CHANGED
@@ -378,11 +378,8 @@ function reactGen(_a) {
378
378
  (0, logger_1.warn)(`Failed to merge into existing index.ts. Skipping modifications: ${indexFilePath}`);
379
379
  }
380
380
  }
381
- (0, logger_1.timeEnd)('reactGen');
382
- (0, logger_1.success)(`React code generation completed. ${filesChanged} files changed.`);
383
- (0, logger_1.info)(`Output directory: ${normalizedTarget}`);
384
- (0, logger_1.info)('You can now import these components in your React project.');
385
- // Aggregate standalone type declarations (consts/enums/type aliases) into a single types.ts
381
+ // Always generate src/types.ts so generated components can safely import it.
382
+ // When there are no standalone declarations, emit an empty module (`export {};`).
386
383
  try {
387
384
  const consts = blobs.flatMap(b => b.objects.filter(o => o instanceof declaration_1.ConstObject));
388
385
  const enums = blobs.flatMap(b => b.objects.filter(o => o instanceof declaration_1.EnumObject));
@@ -395,38 +392,38 @@ function reactGen(_a) {
395
392
  typeAliases.forEach(t => { if (!typeAliasMap.has(t.name))
396
393
  typeAliasMap.set(t.name, t); });
397
394
  const hasAny = constMap.size > 0 || enums.length > 0 || typeAliasMap.size > 0;
398
- if (hasAny) {
399
- const constDecl = Array.from(constMap.values())
400
- .map(c => `export declare const ${c.name}: ${c.type};`)
401
- .join('\n');
402
- const enumDecl = enums
403
- .map(e => `export enum ${e.name} { ${e.members.map(m => m.initializer ? `${m.name} = ${m.initializer}` : `${m.name}`).join(', ')} }`)
404
- .join('\n');
405
- const typeAliasDecl = Array.from(typeAliasMap.values())
406
- .map(t => `export type ${t.name} = ${t.type};`)
407
- .join('\n');
408
- const typesContent = [
409
- '/* Generated by WebF CLI - aggregated type declarations */',
410
- typeAliasDecl,
411
- constDecl,
412
- enumDecl,
413
- ''
414
- ].filter(Boolean).join('\n');
415
- const typesPath = path_1.default.join(normalizedTarget, 'src', 'types.ts');
416
- if (writeFileIfChanged(typesPath, typesContent)) {
417
- filesChanged++;
418
- (0, logger_1.debug)(`Generated: src/types.ts`);
419
- try {
420
- const constNames = Array.from(constMap.keys());
421
- const aliasNames = Array.from(typeAliasMap.keys());
422
- const enumNames = enums.map(e => e.name);
423
- (0, logger_1.debug)(`[react] Aggregated types - consts: ${constNames.join(', ') || '(none)'}; typeAliases: ${aliasNames.join(', ') || '(none)'}; enums: ${enumNames.join(', ') || '(none)'}\n`);
424
- (0, logger_1.debug)(`[react] src/types.ts preview:\n` + typesContent.split('\n').slice(0, 20).join('\n'));
425
- }
426
- catch (_b) { }
395
+ const constDecl = Array.from(constMap.values())
396
+ .map(c => `export declare const ${c.name}: ${c.type};`)
397
+ .join('\n');
398
+ const enumDecl = enums
399
+ .map(e => `export enum ${e.name} { ${e.members.map(m => m.initializer ? `${m.name} = ${m.initializer}` : `${m.name}`).join(', ')} }`)
400
+ .join('\n');
401
+ const typeAliasDecl = Array.from(typeAliasMap.values())
402
+ .map(t => `export type ${t.name} = ${t.type};`)
403
+ .join('\n');
404
+ const typesContent = [
405
+ '/* Generated by WebF CLI - aggregated type declarations */',
406
+ hasAny ? typeAliasDecl : '',
407
+ hasAny ? constDecl : '',
408
+ hasAny ? enumDecl : '',
409
+ hasAny ? '' : 'export {};',
410
+ ''
411
+ ].filter(Boolean).join('\n');
412
+ const typesPath = path_1.default.join(normalizedTarget, 'src', 'types.ts');
413
+ if (writeFileIfChanged(typesPath, typesContent)) {
414
+ filesChanged++;
415
+ (0, logger_1.debug)(`Generated: src/types.ts`);
416
+ try {
417
+ const constNames = Array.from(constMap.keys());
418
+ const aliasNames = Array.from(typeAliasMap.keys());
419
+ const enumNames = enums.map(e => e.name);
420
+ (0, logger_1.debug)(`[react] Aggregated types - consts: ${constNames.join(', ') || '(none)'}; typeAliases: ${aliasNames.join(', ') || '(none)'}; enums: ${enumNames.join(', ') || '(none)'}\n`);
421
+ (0, logger_1.debug)(`[react] src/types.ts preview:\n` + typesContent.split('\n').slice(0, 20).join('\n'));
427
422
  }
428
- // Ensure index.ts re-exports these types so consumers get them on import.
429
- const indexFilePath = path_1.default.join(normalizedTarget, 'src', 'index.ts');
423
+ catch (_b) { }
424
+ }
425
+ // Only re-export from index.ts when there are actual declarations to surface.
426
+ if (hasAny) {
430
427
  try {
431
428
  let current = '';
432
429
  if (fs_1.default.existsSync(indexFilePath)) {
@@ -447,6 +444,10 @@ function reactGen(_a) {
447
444
  catch (e) {
448
445
  (0, logger_1.warn)('Failed to generate aggregated React types');
449
446
  }
447
+ (0, logger_1.timeEnd)('reactGen');
448
+ (0, logger_1.success)(`React code generation completed. ${filesChanged} files changed.`);
449
+ (0, logger_1.info)(`Output directory: ${normalizedTarget}`);
450
+ (0, logger_1.info)('You can now import these components in your React project.');
450
451
  });
451
452
  }
452
453
  function vueGen(_a) {
package/dist/module.js CHANGED
@@ -247,14 +247,14 @@ function mapTsParamTypeToDart(typeText, optionNames) {
247
247
  }
248
248
  return { dartType: 'dynamic', isByteData: false };
249
249
  }
250
- function mapTsPropertyTypeToDart(type) {
250
+ function mapTsPropertyTypeToDart(type, optional) {
251
251
  switch (type.kind) {
252
252
  case typescript_1.default.SyntaxKind.StringKeyword:
253
- return 'String?';
253
+ return optional ? 'String?' : 'String';
254
254
  case typescript_1.default.SyntaxKind.NumberKeyword:
255
- return 'num?';
255
+ return optional ? 'num?' : 'num';
256
256
  case typescript_1.default.SyntaxKind.BooleanKeyword:
257
- return 'bool?';
257
+ return optional ? 'bool?' : 'bool';
258
258
  default:
259
259
  return 'dynamic';
260
260
  }
@@ -288,28 +288,52 @@ function buildDartBindings(def, command) {
288
288
  continue;
289
289
  const key = member.name.getText(def.sourceFile).replace(/['"]/g, '');
290
290
  const fieldName = key;
291
- const dartType = member.type ? mapTsPropertyTypeToDart(member.type) : 'dynamic';
292
- propInfos.push({ fieldName, key, dartType });
291
+ const optional = !!member.questionToken;
292
+ const dartType = member.type ? mapTsPropertyTypeToDart(member.type, optional) : 'dynamic';
293
+ propInfos.push({ fieldName, key, dartType, optional });
293
294
  }
294
295
  lines.push(`class ${name} {`);
295
296
  for (const prop of propInfos) {
296
297
  lines.push(` final ${prop.dartType} ${prop.fieldName};`);
297
298
  }
298
299
  lines.push('');
299
- const ctorParams = propInfos.map(p => `this.${p.fieldName}`).join(', ');
300
+ const ctorParams = propInfos.map(p => {
301
+ if (p.optional || p.dartType === 'dynamic') {
302
+ return `this.${p.fieldName}`;
303
+ }
304
+ return `required this.${p.fieldName}`;
305
+ }).join(', ');
300
306
  lines.push(` const ${name}({${ctorParams}});`);
301
307
  lines.push('');
302
308
  lines.push(` factory ${name}.fromMap(Map<String, dynamic> map) {`);
303
309
  lines.push(` return ${name}(`);
304
310
  for (const prop of propInfos) {
305
- if (prop.dartType.startsWith('String')) {
306
- lines.push(` ${prop.fieldName}: map['${prop.key}']?.toString(),`);
311
+ const isString = prop.dartType.startsWith('String');
312
+ const isBool = prop.dartType.startsWith('bool');
313
+ const isNum = prop.dartType.startsWith('num');
314
+ if (isString) {
315
+ if (prop.optional) {
316
+ lines.push(` ${prop.fieldName}: map['${prop.key}']?.toString(),`);
317
+ }
318
+ else {
319
+ lines.push(` ${prop.fieldName}: map['${prop.key}']?.toString() ?? '',`);
320
+ }
307
321
  }
308
- else if (prop.dartType.startsWith('bool')) {
309
- lines.push(` ${prop.fieldName}: map['${prop.key}'] is bool ? map['${prop.key}'] as bool : null,`);
322
+ else if (isBool) {
323
+ if (prop.optional) {
324
+ lines.push(` ${prop.fieldName}: map['${prop.key}'] is bool ? map['${prop.key}'] as bool : null,`);
325
+ }
326
+ else {
327
+ lines.push(` ${prop.fieldName}: map['${prop.key}'] is bool ? map['${prop.key}'] as bool : false,`);
328
+ }
310
329
  }
311
- else if (prop.dartType.startsWith('num')) {
312
- lines.push(` ${prop.fieldName}: map['${prop.key}'] is num ? map['${prop.key}'] as num : null,`);
330
+ else if (isNum) {
331
+ if (prop.optional) {
332
+ lines.push(` ${prop.fieldName}: map['${prop.key}'] is num ? map['${prop.key}'] as num : null,`);
333
+ }
334
+ else {
335
+ lines.push(` ${prop.fieldName}: map['${prop.key}'] is num ? map['${prop.key}'] as num : 0,`);
336
+ }
313
337
  }
314
338
  else {
315
339
  lines.push(` ${prop.fieldName}: map['${prop.key}'],`);
@@ -321,7 +345,12 @@ function buildDartBindings(def, command) {
321
345
  lines.push(' Map<String, dynamic> toMap() {');
322
346
  lines.push(' final map = <String, dynamic>{};');
323
347
  for (const prop of propInfos) {
324
- lines.push(` if (${prop.fieldName} != null) { map['${prop.key}'] = ${prop.fieldName}; }`);
348
+ if (!prop.optional && (prop.dartType === 'String' || prop.dartType === 'bool' || prop.dartType === 'num')) {
349
+ lines.push(` map['${prop.key}'] = ${prop.fieldName};`);
350
+ }
351
+ else {
352
+ lines.push(` if (${prop.fieldName} != null) { map['${prop.key}'] = ${prop.fieldName}; }`);
353
+ }
325
354
  }
326
355
  lines.push(' return map;');
327
356
  lines.push(' }');
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.readJsonFile = readJsonFile;
7
+ exports.getPackageTypesFileFromDir = getPackageTypesFileFromDir;
8
+ exports.isPackageTypesReady = isPackageTypesReady;
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ function readJsonFile(jsonPath) {
12
+ return JSON.parse(fs_1.default.readFileSync(jsonPath, 'utf-8'));
13
+ }
14
+ function getPackageTypesFileFromDir(pkgDir) {
15
+ const pkgJsonPath = path_1.default.join(pkgDir, 'package.json');
16
+ if (!fs_1.default.existsSync(pkgJsonPath))
17
+ return null;
18
+ const pkgJson = readJsonFile(pkgJsonPath);
19
+ const typesRel = pkgJson.types;
20
+ if (!typesRel)
21
+ return null;
22
+ return path_1.default.join(pkgDir, typesRel);
23
+ }
24
+ function isPackageTypesReady(pkgDir) {
25
+ const typesFile = getPackageTypesFileFromDir(pkgDir);
26
+ return typesFile ? fs_1.default.existsSync(typesFile) : true;
27
+ }
package/dist/react.js CHANGED
@@ -55,14 +55,13 @@ function generateReturnType(type) {
55
55
  return pointerType;
56
56
  }
57
57
  if (type.isArray && typeof type.value === 'object' && !Array.isArray(type.value)) {
58
- const elemType = (0, utils_1.getPointerType)(type.value);
59
- // Map arrays of Dart `Type` to `any[]` in TS; parenthesize typeof
60
- if (elemType === 'Type')
58
+ const elemType = generateReturnType(type.value);
59
+ if (!elemType)
61
60
  return 'any[]';
62
- if (typeof elemType === 'string' && elemType.startsWith('typeof ')) {
63
- return `(${elemType})[]`;
61
+ if (/^[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(elemType)) {
62
+ return `${elemType}[]`;
64
63
  }
65
- return `${elemType}[]`;
64
+ return `(${elemType})[]`;
66
65
  }
67
66
  switch (type.value) {
68
67
  case declaration_1.FunctionArgumentType.int:
@@ -348,20 +347,13 @@ function generateReactComponent(blob, packageName, relativeDir) {
348
347
  return pointerType;
349
348
  }
350
349
  if (type.isArray && typeof type.value === 'object' && !Array.isArray(type.value)) {
351
- const elemType = (0, utils_1.getPointerType)(type.value);
352
- if (elemType === 'Type')
350
+ const elemType = genRT(type.value);
351
+ if (!elemType)
353
352
  return 'any[]';
354
- if (typeof elemType === 'string' && elemType.startsWith('typeof ')) {
355
- const ident = elemType.substring('typeof '.length).trim();
356
- return `(typeof __webfTypes.${ident})[]`;
357
- }
358
- if (typeof elemType === 'string' && /^(?:[A-Za-z_][A-Za-z0-9_]*)(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(elemType)) {
359
- const base = elemType.split('.')[0];
360
- if (!localTypeNames.has(base)) {
361
- return `__webfTypes.${elemType}[]`;
362
- }
353
+ if (/^[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(elemType)) {
354
+ return `${elemType}[]`;
363
355
  }
364
- return `${elemType}[]`;
356
+ return `(${elemType})[]`;
365
357
  }
366
358
  switch (type.value) {
367
359
  case declaration_1.FunctionArgumentType.int: