* Process code for device: inject globals, remove framework imports
(code: string, isVitePreBundled: boolean)
| 1143 | */ |
| 1144 | |
| 1145 | function processCodeForDevice(code: string, isVitePreBundled: boolean): string { |
| 1146 | let result = code; |
| 1147 | |
| 1148 | // Ensure Angular partial declarations are linked before any sanitizers run so runtime never hits the JIT path. |
| 1149 | result = linkAngularPartialsIfNeeded(result); |
| 1150 | |
| 1151 | // First: aggressively strip any lingering virtual dynamic-import-helper before anything else. |
| 1152 | // Doing this up-front prevents downstream dependency collection from seeing the virtual id. |
| 1153 | result = stripViteDynamicImportVirtual(result); |
| 1154 | |
| 1155 | // Skip reactive injection for Vite pre-bundled deps (they have Vue bundled already) |
| 1156 | if (isVitePreBundled) { |
| 1157 | return result; |
| 1158 | } |
| 1159 | |
| 1160 | // Inject ALL NativeScript/build globals at the top (matching global-defines.ts) |
| 1161 | // This ensures any code using __DEV__, __ANDROID__, __IOS__, etc. works correctly |
| 1162 | const allGlobals = [ |
| 1163 | 'const __ANDROID__ = globalThis.__ANDROID__ !== undefined ? globalThis.__ANDROID__ : false;', |
| 1164 | 'const __IOS__ = globalThis.__IOS__ !== undefined ? globalThis.__IOS__ : false;', |
| 1165 | 'const __VISIONOS__ = globalThis.__VISIONOS__ !== undefined ? globalThis.__VISIONOS__ : false;', |
| 1166 | 'const __APPLE__ = globalThis.__APPLE__ !== undefined ? globalThis.__APPLE__ : false;', |
| 1167 | 'const __DEV__ = globalThis.__DEV__ !== undefined ? globalThis.__DEV__ : false;', |
| 1168 | 'const __COMMONJS__ = globalThis.__COMMONJS__ !== undefined ? globalThis.__COMMONJS__ : false;', |
| 1169 | 'const __NS_WEBPACK__ = globalThis.__NS_WEBPACK__ !== undefined ? globalThis.__NS_WEBPACK__ : true;', |
| 1170 | 'const __NS_ENV_VERBOSE__ = globalThis.__NS_ENV_VERBOSE__ !== undefined ? !!globalThis.__NS_ENV_VERBOSE__ : false;', |
| 1171 | "const __CSS_PARSER__ = globalThis.__CSS_PARSER__ !== undefined ? globalThis.__CSS_PARSER__ : 'css-tree';", |
| 1172 | 'const __UI_USE_XML_PARSER__ = globalThis.__UI_USE_XML_PARSER__ !== undefined ? globalThis.__UI_USE_XML_PARSER__ : true;', |
| 1173 | 'const __UI_USE_EXTERNAL_RENDERER__ = globalThis.__UI_USE_EXTERNAL_RENDERER__ !== undefined ? globalThis.__UI_USE_EXTERNAL_RENDERER__ : false;', |
| 1174 | 'const __TEST__ = globalThis.__TEST__ !== undefined ? globalThis.__TEST__ : false;', |
| 1175 | ]; |
| 1176 | result = allGlobals.join('\n') + '\n' + result; |
| 1177 | |
| 1178 | // Prefer AST-based normalization for imports and helper aliases; fallback regex if parsing fails |
| 1179 | try { |
| 1180 | result = astNormalizeModuleImportsAndHelpers(result); |
| 1181 | } catch {} |
| 1182 | |
| 1183 | // Verify there are no duplicate top-level const/let bindings after AST normalization |
| 1184 | try { |
| 1185 | result = astVerifyAndAnnotateDuplicates(result); |
| 1186 | } catch {} |
| 1187 | |
| 1188 | // If AST marker present, skip regex-based helper alias injection to avoid duplicates |
| 1189 | // Accept both line and block comment markers emitted by the normalizer |
| 1190 | if (!/^\s*(?:\/\/|\/\*) \[ast-normalized\]/m.test(result)) { |
| 1191 | try { |
| 1192 | const underscored = new Set<string>(); |
| 1193 | const re = /(^|[^.\w$])_([A-Za-z]\w*)\b/g; |
| 1194 | let m: RegExpExecArray | null; |
| 1195 | while ((m = re.exec(result))) { |
| 1196 | const name = m[2]; |
| 1197 | if (name === 'ctx' || name === 'cache') continue; |
| 1198 | if (name.startsWith('hoisted_')) continue; |
| 1199 | if (name.startsWith('component_')) continue; |
| 1200 | if (name.startsWith('directive_')) continue; |
| 1201 | if (name === 'sfc_main') continue; |
| 1202 | if (name === 'ns_sfc__' || name.startsWith('ns_sfc')) continue; |
no test coverage detected