@nativescript/vite 8.0.0-alpha.30 → 8.0.0-alpha.31
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/configuration/angular.js +8 -8
- package/configuration/angular.js.map +1 -1
- package/configuration/solid.js +2 -2
- package/configuration/solid.js.map +1 -1
- package/hmr/client/framework-client-strategy.d.ts +73 -0
- package/hmr/client/framework-client-strategy.js +19 -0
- package/hmr/client/framework-client-strategy.js.map +1 -0
- package/hmr/client/index.js +77 -186
- package/hmr/client/index.js.map +1 -1
- package/hmr/client/utils.js.map +1 -1
- package/hmr/entry-runtime.js.map +1 -1
- package/hmr/frameworks/angular/build/angular-linker.js.map +1 -0
- package/hmr/frameworks/angular/build/inject-component-hmr-registration.js.map +1 -0
- package/hmr/frameworks/angular/build/inject-hmr-vite-ignore.js.map +1 -0
- package/hmr/frameworks/angular/build/inline-decorator-component-templates.js.map +1 -0
- package/hmr/frameworks/angular/build/js-lexer.js.map +1 -0
- package/hmr/frameworks/angular/build/shared-linker.js.map +1 -0
- package/hmr/frameworks/angular/build/synthesize-decorator-ctor-parameters.js.map +1 -0
- package/hmr/frameworks/angular/build/synthesize-injectable-factories.js.map +1 -0
- package/hmr/frameworks/angular/build/util.js.map +1 -0
- package/hmr/frameworks/angular/client/index.js.map +1 -1
- package/hmr/frameworks/angular/client/strategy.d.ts +9 -0
- package/hmr/frameworks/angular/client/strategy.js +19 -0
- package/hmr/frameworks/angular/client/strategy.js.map +1 -0
- package/hmr/frameworks/angular/server/angular-root-component.js.map +1 -0
- package/hmr/frameworks/angular/server/strategy.js +440 -2
- package/hmr/frameworks/angular/server/strategy.js.map +1 -1
- package/hmr/{server → frameworks/angular/server}/websocket-angular-entry.js +2 -2
- package/hmr/frameworks/angular/server/websocket-angular-entry.js.map +1 -0
- package/hmr/{server → frameworks/angular/server}/websocket-angular-hot-update.d.ts +0 -11
- package/hmr/{server → frameworks/angular/server}/websocket-angular-hot-update.js +3 -80
- package/hmr/frameworks/angular/server/websocket-angular-hot-update.js.map +1 -0
- package/hmr/frameworks/solid/build/solid-jsx-deps.js.map +1 -0
- package/hmr/frameworks/solid/server/strategy.js +360 -1
- package/hmr/frameworks/solid/server/strategy.js.map +1 -1
- package/hmr/frameworks/typescript/server/strategy.js +27 -0
- package/hmr/frameworks/typescript/server/strategy.js.map +1 -1
- package/hmr/frameworks/vue/client/index.js.map +1 -1
- package/hmr/frameworks/vue/client/strategy.d.ts +7 -0
- package/hmr/frameworks/vue/client/strategy.js +83 -0
- package/hmr/frameworks/vue/client/strategy.js.map +1 -0
- package/hmr/frameworks/vue/client/vue-sfc-update-overlay.js.map +1 -0
- package/hmr/frameworks/vue/server/sfc-route-assemble.d.ts +7 -0
- package/hmr/{server/websocket-sfc.js → frameworks/vue/server/sfc-route-assemble.js} +19 -536
- package/hmr/frameworks/vue/server/sfc-route-assemble.js.map +1 -0
- package/hmr/frameworks/vue/server/sfc-route-meta.d.ts +7 -0
- package/hmr/frameworks/vue/server/sfc-route-meta.js +80 -0
- package/hmr/frameworks/vue/server/sfc-route-meta.js.map +1 -0
- package/hmr/frameworks/vue/server/sfc-route-serve.d.ts +8 -0
- package/hmr/frameworks/vue/server/sfc-route-serve.js +457 -0
- package/hmr/frameworks/vue/server/sfc-route-serve.js.map +1 -0
- package/hmr/frameworks/vue/server/sfc-route-shared.d.ts +19 -0
- package/hmr/frameworks/vue/server/sfc-route-shared.js +14 -0
- package/hmr/frameworks/vue/server/sfc-route-shared.js.map +1 -0
- package/hmr/frameworks/vue/server/strategy.js +244 -0
- package/hmr/frameworks/vue/server/strategy.js.map +1 -1
- package/hmr/frameworks/vue/server/websocket-sfc.d.ts +15 -0
- package/hmr/frameworks/vue/server/websocket-sfc.js +20 -0
- package/hmr/frameworks/vue/server/websocket-sfc.js.map +1 -0
- package/hmr/server/device-transform-helpers.d.ts +24 -0
- package/hmr/server/device-transform-helpers.js +327 -0
- package/hmr/server/device-transform-helpers.js.map +1 -0
- package/hmr/server/framework-strategy.d.ts +95 -1
- package/hmr/server/hmr-module-graph.js.map +1 -1
- package/hmr/server/import-map.d.ts +11 -2
- package/hmr/server/import-map.js +21 -54
- package/hmr/server/import-map.js.map +1 -1
- package/hmr/server/index.js +7 -17
- package/hmr/server/index.js.map +1 -1
- package/hmr/server/process-code-for-device.d.ts +15 -0
- package/hmr/server/process-code-for-device.js +654 -0
- package/hmr/server/process-code-for-device.js.map +1 -0
- package/hmr/server/rewrite-imports.d.ts +2 -0
- package/hmr/server/rewrite-imports.js +604 -0
- package/hmr/server/rewrite-imports.js.map +1 -0
- package/hmr/server/transform-cache-invalidation.d.ts +11 -0
- package/hmr/server/transform-cache-invalidation.js +84 -0
- package/hmr/server/transform-cache-invalidation.js.map +1 -0
- package/hmr/server/websocket-device-transform.d.ts +3 -21
- package/hmr/server/websocket-device-transform.js +6 -1569
- package/hmr/server/websocket-device-transform.js.map +1 -1
- package/hmr/server/websocket-hmr-pending.d.ts +2 -8
- package/hmr/server/websocket-hmr-pending.js.map +1 -1
- package/hmr/server/websocket-hot-update.d.ts +40 -14
- package/hmr/server/websocket-hot-update.js +24 -854
- package/hmr/server/websocket-hot-update.js.map +1 -1
- package/hmr/server/websocket-import-map-route.js +3 -1
- package/hmr/server/websocket-import-map-route.js.map +1 -1
- package/hmr/server/websocket-ns-core.d.ts +4 -4
- package/hmr/server/websocket-ns-core.js +3 -2
- package/hmr/server/websocket-ns-core.js.map +1 -1
- package/hmr/server/websocket-ns-entry.d.ts +0 -1
- package/hmr/server/websocket-ns-entry.js +1 -1
- package/hmr/server/websocket-ns-entry.js.map +1 -1
- package/hmr/server/websocket-ns-m.d.ts +0 -1
- package/hmr/server/websocket-ns-m.js +24 -129
- package/hmr/server/websocket-ns-m.js.map +1 -1
- package/hmr/server/websocket-vendor-unifier.d.ts +0 -1
- package/hmr/server/websocket-vendor-unifier.js +2 -1
- package/hmr/server/websocket-vendor-unifier.js.map +1 -1
- package/hmr/server/websocket.d.ts +11 -12
- package/hmr/server/websocket.js +25 -33
- package/hmr/server/websocket.js.map +1 -1
- package/hmr/shared/ns-globals.d.ts +118 -0
- package/hmr/shared/ns-globals.js +27 -0
- package/hmr/shared/ns-globals.js.map +1 -0
- package/hmr/shared/protocol.d.ts +136 -0
- package/hmr/shared/protocol.js +28 -0
- package/hmr/shared/protocol.js.map +1 -0
- package/hmr/shared/vendor/manifest-collect.d.ts +0 -28
- package/hmr/shared/vendor/manifest-collect.js +2 -2
- package/hmr/shared/vendor/manifest-collect.js.map +1 -1
- package/hmr/shared/vendor/manifest.d.ts +1 -3
- package/hmr/shared/vendor/manifest.js +1 -3
- package/hmr/shared/vendor/manifest.js.map +1 -1
- package/hmr/shared/vendor/vendor-esbuild-plugins.js +1 -1
- package/hmr/shared/vendor/vendor-esbuild-plugins.js.map +1 -1
- package/package.json +1 -1
- package/helpers/angular/angular-linker.js.map +0 -1
- package/helpers/angular/inject-component-hmr-registration.js.map +0 -1
- package/helpers/angular/inject-hmr-vite-ignore.js.map +0 -1
- package/helpers/angular/inline-decorator-component-templates.js.map +0 -1
- package/helpers/angular/js-lexer.js.map +0 -1
- package/helpers/angular/shared-linker.js.map +0 -1
- package/helpers/angular/synthesize-decorator-ctor-parameters.js.map +0 -1
- package/helpers/angular/synthesize-injectable-factories.js.map +0 -1
- package/helpers/angular/util.js.map +0 -1
- package/helpers/prelink-angular.d.ts +0 -2
- package/helpers/prelink-angular.js +0 -96
- package/helpers/prelink-angular.js.map +0 -1
- package/helpers/solid-jsx-deps.js.map +0 -1
- package/hmr/client/vue-sfc-update-overlay.js.map +0 -1
- package/hmr/server/angular-root-component.js.map +0 -1
- package/hmr/server/websocket-angular-entry.js.map +0 -1
- package/hmr/server/websocket-angular-hot-update.js.map +0 -1
- package/hmr/server/websocket-sfc.d.ts +0 -24
- package/hmr/server/websocket-sfc.js.map +0 -1
- /package/{helpers/angular → hmr/frameworks/angular/build}/angular-linker.d.ts +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/angular-linker.js +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/inject-component-hmr-registration.d.ts +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/inject-component-hmr-registration.js +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/inject-hmr-vite-ignore.d.ts +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/inject-hmr-vite-ignore.js +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/inline-decorator-component-templates.d.ts +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/inline-decorator-component-templates.js +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/js-lexer.d.ts +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/js-lexer.js +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/shared-linker.d.ts +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/shared-linker.js +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/synthesize-decorator-ctor-parameters.d.ts +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/synthesize-decorator-ctor-parameters.js +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/synthesize-injectable-factories.d.ts +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/synthesize-injectable-factories.js +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/util.d.ts +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/util.js +0 -0
- /package/hmr/{server → frameworks/angular/server}/angular-root-component.d.ts +0 -0
- /package/hmr/{server → frameworks/angular/server}/angular-root-component.js +0 -0
- /package/hmr/{server → frameworks/angular/server}/websocket-angular-entry.d.ts +0 -0
- /package/{helpers → hmr/frameworks/solid/build}/solid-jsx-deps.d.ts +0 -0
- /package/{helpers → hmr/frameworks/solid/build}/solid-jsx-deps.js +0 -0
- /package/hmr/{client → frameworks/vue/client}/vue-sfc-update-overlay.d.ts +0 -0
- /package/hmr/{client → frameworks/vue/client}/vue-sfc-update-overlay.js +0 -0
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
// Device code-transform: cleans Vite/framework noise out of a served module,
|
|
2
|
+
// injects NativeScript build globals + the process.env shim, normalizes
|
|
3
|
+
// imports/helpers for the on-device ESM runtime, and collects an importer's
|
|
4
|
+
// app-relative dependencies. Pure functions only.
|
|
5
|
+
import { sanitizeStrayCoreReferences, isDeepCoreSubpath } from './core-sanitize.js';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
import * as PAT from './constants.js';
|
|
8
|
+
import { astNormalizeModuleImportsAndHelpers, astVerifyAndAnnotateDuplicates } from '../helpers/ast-normalizer.js';
|
|
9
|
+
import { stripDanglingViteCjsImports } from '../helpers/sanitize.js';
|
|
10
|
+
import { getVendorManifest, resolveVendorSpecifier } from '../shared/vendor/registry.js';
|
|
11
|
+
import { getProjectRootPath } from '../../helpers/project.js';
|
|
12
|
+
import { createProcessSfcCode } from '../frameworks/vue/server/sfc-transforms.js';
|
|
13
|
+
import { getCliFlags } from '../../helpers/cli-flags.js';
|
|
14
|
+
import { linkAngularPartialsIfNeeded } from '../frameworks/angular/server/linker.js';
|
|
15
|
+
import { isCoreGlobalsReference, isNativeScriptCoreModule, isNativeScriptPluginModule, normalizeNativeScriptCoreSpecifier, resolveVendorFromCandidate } from './websocket-module-specifiers.js';
|
|
16
|
+
import { ensureNativeScriptModuleBindings, getProcessCodeResolvedSpecifierOverrides } from './websocket-module-bindings.js';
|
|
17
|
+
import { deduplicateLinkerImports, ensureDestructureRtImports, ensureVariableDynamicImportHelper, hoistTopLevelStaticImports, repairImportEqualsAssignments, stripCoreGlobalsImports, stripViteDynamicImportVirtual } from './websocket-served-module-helpers.js';
|
|
18
|
+
import { buildNodeModuleProvenancePrelude, normalizeImportPath, removeNamedImports, rewriteVitePrebundleImportsForDevice, shouldRemapImport } from './device-transform-helpers.js';
|
|
19
|
+
// Build a serialized process.env object from CLI --env.* flags.
|
|
20
|
+
// This is injected into every HTTP-served module so app code referencing
|
|
21
|
+
// process.env.TEST_ENV (etc.) works on device in HMR dev mode.
|
|
22
|
+
const __processEnvEntries = { NODE_ENV: 'development' };
|
|
23
|
+
try {
|
|
24
|
+
const flags = getCliFlags();
|
|
25
|
+
for (const [k, v] of Object.entries(flags || {})) {
|
|
26
|
+
// Skip internal NativeScript build flags
|
|
27
|
+
if (['ios', 'android', 'visionos', 'platform', 'hmr', 'verbose'].includes(k))
|
|
28
|
+
continue;
|
|
29
|
+
__processEnvEntries[k] = String(v);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch { }
|
|
33
|
+
const __processEnvJson = JSON.stringify(__processEnvEntries);
|
|
34
|
+
const processSfcCode = createProcessSfcCode(processCodeForDevice);
|
|
35
|
+
function collectImportDependencies(code, importerPath) {
|
|
36
|
+
const importerDir = path.posix.dirname(importerPath);
|
|
37
|
+
const deps = new Set();
|
|
38
|
+
const patterns = [PAT.IMPORT_PATTERN_1, PAT.IMPORT_PATTERN_2, PAT.EXPORT_PATTERN, PAT.IMPORT_PATTERN_3];
|
|
39
|
+
for (const pattern of patterns) {
|
|
40
|
+
pattern.lastIndex = 0;
|
|
41
|
+
let match;
|
|
42
|
+
while ((match = pattern.exec(code)) !== null) {
|
|
43
|
+
const rawSpec = match[2];
|
|
44
|
+
const spec = normalizeNativeScriptCoreSpecifier(rawSpec);
|
|
45
|
+
if (!spec || !shouldRemapImport(spec)) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (resolveVendorFromCandidate(spec)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
// Manifest-aware vendor spec detection
|
|
52
|
+
try {
|
|
53
|
+
if (resolveVendorSpecifier && resolveVendorSpecifier(spec)) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch { }
|
|
58
|
+
const normalized = normalizeImportPath(spec, importerDir);
|
|
59
|
+
if (normalized) {
|
|
60
|
+
if (resolveVendorFromCandidate(normalized)) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
if (resolveVendorSpecifier && resolveVendorSpecifier(normalized)) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch { }
|
|
69
|
+
if (isCoreGlobalsReference(normalized)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (isNativeScriptCoreModule(normalized)) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (isNativeScriptPluginModule(normalized)) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
deps.add(normalized);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return deps;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Clean code: remove Vite/Vue noise, rewrite to vendor
|
|
86
|
+
*/
|
|
87
|
+
function cleanCode(code, strategy) {
|
|
88
|
+
let result = code;
|
|
89
|
+
// Remove Vite client and hot module noise
|
|
90
|
+
result = result.replace(PAT.VITE_CLIENT_IMPORT, '');
|
|
91
|
+
result = result.replace(PAT.IMPORT_META_HOT_ASSIGNMENT, '');
|
|
92
|
+
// Keep import.meta.hot call sites; runtime now provides a stable import.meta.hot.
|
|
93
|
+
result = strategy.preClean?.(result) ?? result;
|
|
94
|
+
result = strategy.rewriteFrameworkImports?.(result) ?? result;
|
|
95
|
+
// Vendor manifest-driven import rewrites
|
|
96
|
+
// NOTE: Static and side-effect vendor imports are intentionally NOT rewritten here.
|
|
97
|
+
// They are left as import statements so that ensureNativeScriptModuleBindings()
|
|
98
|
+
// (called later in processCodeForDevice) can transform them using the robust
|
|
99
|
+
// __nsVendorRequire + __nsPick pattern that works on device.
|
|
100
|
+
// Only dynamic imports are handled here since ensureNativeScriptModuleBindings
|
|
101
|
+
// does not process dynamic import() calls.
|
|
102
|
+
try {
|
|
103
|
+
const manifest = getVendorManifest();
|
|
104
|
+
if (manifest) {
|
|
105
|
+
// Dynamic import rewrites: import('pkg') -> Promise.resolve(__nsVendor('id'))
|
|
106
|
+
const dynImportRE = /(import\(\s*["'])([^"']+)(["']\s*\))/g;
|
|
107
|
+
result = result.replace(dynImportRE, (full, pre, spec, post) => {
|
|
108
|
+
if (isNativeScriptCoreModule(spec))
|
|
109
|
+
return full;
|
|
110
|
+
const resolved = resolveVendorSpecifier(spec);
|
|
111
|
+
if (!resolved || /^@nativescript\/core(\b|\/)/i.test(resolved))
|
|
112
|
+
return full;
|
|
113
|
+
return `Promise.resolve(__nsVendor(${JSON.stringify(resolved)}))`;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
// Non-fatal; fallback to original code if manifest logic fails
|
|
119
|
+
}
|
|
120
|
+
result = result.replace(PAT.VITE_CLIENT_IMPORT, '').replace(PAT.IMPORT_META_HOT_ASSIGNMENT, '');
|
|
121
|
+
// Clean up HMR noise
|
|
122
|
+
result = strategy.postClean?.(result) ?? result;
|
|
123
|
+
result = stripCoreGlobalsImports(result);
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Process code for device: inject globals, remove framework imports
|
|
128
|
+
*/
|
|
129
|
+
function processCodeForDevice(code, isVitePreBundled, preserveVendorImports = false, isNodeModule = false, sourceId, options) {
|
|
130
|
+
let result = code;
|
|
131
|
+
const resolvedSpecifierOverrides = options?.resolvedSpecifierOverrides || getProcessCodeResolvedSpecifierOverrides(sourceId, getProjectRootPath());
|
|
132
|
+
const bindingOptions = {
|
|
133
|
+
preserveNonPluginVendorImports: preserveVendorImports,
|
|
134
|
+
resolvedSpecifierOverrides,
|
|
135
|
+
};
|
|
136
|
+
// Ensure Angular partial declarations are linked before any sanitizers run so runtime never hits the JIT path.
|
|
137
|
+
result = linkAngularPartialsIfNeeded(result);
|
|
138
|
+
// Post-linker: deduplicate/resolve imports the Angular linker injected with bare specifiers
|
|
139
|
+
result = deduplicateLinkerImports(result);
|
|
140
|
+
// First: aggressively strip any lingering virtual dynamic-import-helper before anything else.
|
|
141
|
+
// Doing this up-front prevents downstream dependency collection from seeing the virtual id.
|
|
142
|
+
result = stripViteDynamicImportVirtual(result);
|
|
143
|
+
// Skip reactive injection for Vite pre-bundled deps (they have Vue bundled already)
|
|
144
|
+
if (isVitePreBundled) {
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
// Inject ALL NativeScript/build globals at the top (matching global-defines.ts)
|
|
148
|
+
// This ensures any code using __DEV__, __ANDROID__, __IOS__, etc. works correctly
|
|
149
|
+
const allGlobals = [
|
|
150
|
+
// Minimal process shim — populated with CLI --env.* flags at module load time.
|
|
151
|
+
// In production builds, Vite/Rollup replaces process.env.* statically.
|
|
152
|
+
// In HMR dev mode the code runs as-is on device, so we need the shim.
|
|
153
|
+
//
|
|
154
|
+
// IMPORTANT: every check goes through `globalThis.process` (a member
|
|
155
|
+
// expression), NEVER bare `typeof process` (an identifier reference).
|
|
156
|
+
// bare identifier resolution
|
|
157
|
+
// against runtime-added global object properties is not reliable in
|
|
158
|
+
// V8 module scope. `globalThis.process` is unambiguous: it always
|
|
159
|
+
// reads the `process` property off the (single) global object.
|
|
160
|
+
//
|
|
161
|
+
// The shim is also strictly additive — it only initializes
|
|
162
|
+
// `globalThis.process` and `globalThis.process.env` if they are
|
|
163
|
+
// missing. App code that pre-populates `process.env` (e.g. an Azure
|
|
164
|
+
// App Configuration boot module) is preserved; we never overwrite a
|
|
165
|
+
// populated env with the bare `{ NODE_ENV: 'development' }` stub.
|
|
166
|
+
`if (typeof globalThis.process === "undefined" || globalThis.process === null) { globalThis.process = { env: ${__processEnvJson} }; } else if (!globalThis.process.env) { globalThis.process.env = ${__processEnvJson}; }`,
|
|
167
|
+
'const __ANDROID__ = globalThis.__ANDROID__ !== undefined ? globalThis.__ANDROID__ : false;',
|
|
168
|
+
'const __IOS__ = globalThis.__IOS__ !== undefined ? globalThis.__IOS__ : false;',
|
|
169
|
+
'const __VISIONOS__ = globalThis.__VISIONOS__ !== undefined ? globalThis.__VISIONOS__ : false;',
|
|
170
|
+
'const __APPLE__ = globalThis.__APPLE__ !== undefined ? globalThis.__APPLE__ : (__IOS__ || __VISIONOS__);',
|
|
171
|
+
'const __DEV__ = globalThis.__DEV__ !== undefined ? globalThis.__DEV__ : false;',
|
|
172
|
+
'const __COMMONJS__ = globalThis.__COMMONJS__ !== undefined ? globalThis.__COMMONJS__ : false;',
|
|
173
|
+
'const __NS_WEBPACK__ = globalThis.__NS_WEBPACK__ !== undefined ? globalThis.__NS_WEBPACK__ : false;',
|
|
174
|
+
'const __NS_ENV_VERBOSE__ = globalThis.__NS_ENV_VERBOSE__ !== undefined ? !!globalThis.__NS_ENV_VERBOSE__ : false;',
|
|
175
|
+
"const __CSS_PARSER__ = globalThis.__CSS_PARSER__ !== undefined ? globalThis.__CSS_PARSER__ : 'css-tree';",
|
|
176
|
+
'const __UI_USE_XML_PARSER__ = globalThis.__UI_USE_XML_PARSER__ !== undefined ? globalThis.__UI_USE_XML_PARSER__ : true;',
|
|
177
|
+
'const __UI_USE_EXTERNAL_RENDERER__ = globalThis.__UI_USE_EXTERNAL_RENDERER__ !== undefined ? globalThis.__UI_USE_EXTERNAL_RENDERER__ : false;',
|
|
178
|
+
'const __TEST__ = globalThis.__TEST__ !== undefined ? globalThis.__TEST__ : false;',
|
|
179
|
+
];
|
|
180
|
+
result = allGlobals.join('\n') + '\n' + result;
|
|
181
|
+
const nodeModuleProvenancePrelude = buildNodeModuleProvenancePrelude(sourceId);
|
|
182
|
+
if (nodeModuleProvenancePrelude) {
|
|
183
|
+
result = nodeModuleProvenancePrelude + result;
|
|
184
|
+
}
|
|
185
|
+
// AST normalization: inject /ns/rt helper aliases for underscore-prefixed identifiers.
|
|
186
|
+
// ONLY for app source files — library code in node_modules should be served as-is.
|
|
187
|
+
// Running the normalizer on libraries like tslib injects harmful destructures
|
|
188
|
+
// (e.g., `const { SuppressedError } = __ns_rt_ns_1`) that shadow globals.
|
|
189
|
+
if (!isNodeModule) {
|
|
190
|
+
// CRITICAL ORDERING: canonicalise any bare `@nativescript/core[/sub]`
|
|
191
|
+
// specifiers to `/ns/core[/sub]` BEFORE the AST normaliser sees them.
|
|
192
|
+
// `astNormalizeModuleImportsAndHelpers` defensively rewrites bare
|
|
193
|
+
// `@nativescript/core` imports and emits a one-shot
|
|
194
|
+
// `[ast-normalizer] unexpected @nativescript/core spec` warning —
|
|
195
|
+
// the warning means the upstream rewriter regressed. For Vue SFC
|
|
196
|
+
// `<script>` blocks the bare specifier flows through Vite's
|
|
197
|
+
// transform pipeline without a per-statement source-string rewrite
|
|
198
|
+
// (Vite's resolver only edits the module graph, not the emitted
|
|
199
|
+
// code), so the only upstream rewriter that can canonicalise these
|
|
200
|
+
// in dev mode is this regex sweep. Running it here keeps the AST
|
|
201
|
+
// normaliser purely a tripwire instead of an active rewriter.
|
|
202
|
+
try {
|
|
203
|
+
result = sanitizeStrayCoreReferences(result);
|
|
204
|
+
}
|
|
205
|
+
catch { }
|
|
206
|
+
try {
|
|
207
|
+
result = astNormalizeModuleImportsAndHelpers(result);
|
|
208
|
+
}
|
|
209
|
+
catch { }
|
|
210
|
+
// Verify there are no duplicate top-level const/let bindings after AST normalization
|
|
211
|
+
try {
|
|
212
|
+
result = astVerifyAndAnnotateDuplicates(result);
|
|
213
|
+
}
|
|
214
|
+
catch { }
|
|
215
|
+
}
|
|
216
|
+
// If AST marker present OR this is a node_modules file, skip regex-based helper
|
|
217
|
+
// alias injection. Library code should NOT get /ns/rt destructures injected —
|
|
218
|
+
// underscore-prefixed identifiers in libraries are internal variables, not NS helpers.
|
|
219
|
+
if (!isNodeModule && !/^\s*(?:\/\/|\/\*) \[ast-normalized\]/m.test(result)) {
|
|
220
|
+
try {
|
|
221
|
+
const underscored = new Set();
|
|
222
|
+
const re = /(^|[^.\w$])_([A-Za-z]\w*)\b/g;
|
|
223
|
+
let m;
|
|
224
|
+
while ((m = re.exec(result))) {
|
|
225
|
+
const name = m[2];
|
|
226
|
+
if (name === 'ctx' || name === 'cache')
|
|
227
|
+
continue;
|
|
228
|
+
if (name.startsWith('hoisted_'))
|
|
229
|
+
continue;
|
|
230
|
+
if (name.startsWith('component_'))
|
|
231
|
+
continue;
|
|
232
|
+
if (name.startsWith('directive_'))
|
|
233
|
+
continue;
|
|
234
|
+
if (name === 'sfc_main')
|
|
235
|
+
continue;
|
|
236
|
+
if (name === 'ns_sfc__' || name.startsWith('ns_sfc'))
|
|
237
|
+
continue;
|
|
238
|
+
if (name.startsWith('sfc'))
|
|
239
|
+
continue;
|
|
240
|
+
try {
|
|
241
|
+
const declRE = new RegExp(`(^|\\n)\\s*(?:const|let|var)\\s+_${name}\\b`);
|
|
242
|
+
if (declRE.test(result))
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
catch { }
|
|
246
|
+
underscored.add(name);
|
|
247
|
+
}
|
|
248
|
+
if (underscored.size) {
|
|
249
|
+
const needed = [];
|
|
250
|
+
for (const n of underscored) {
|
|
251
|
+
const aliasNeedle = new RegExp(`\\b${n}\\s+as\\s+_${n}\\b`);
|
|
252
|
+
if (!aliasNeedle.test(result))
|
|
253
|
+
needed.push(n);
|
|
254
|
+
}
|
|
255
|
+
if (needed.length) {
|
|
256
|
+
const importLine = `import { ${needed.map((n) => `${n} as _${n}`).join(', ')} } from "/ns/rt";\n`;
|
|
257
|
+
result = importLine + result;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
catch { }
|
|
262
|
+
}
|
|
263
|
+
// In strict dev mode, proactively surface duplicate-binding diagnostics to avoid "already declared" runtime errors
|
|
264
|
+
try {
|
|
265
|
+
if (/^\s*\/\/ \[ast-verify\]\[duplicate-bindings\]/m.test(result)) {
|
|
266
|
+
const diagnosticLine = (result.match(/^\s*\/\/ \[ast-verify\]\[duplicate-bindings\][^\n]*/m) || [])[0] || '// [ast-verify][duplicate-bindings]';
|
|
267
|
+
const brief = diagnosticLine.replace(/^[^:]*:?\s?/, '');
|
|
268
|
+
const escaped = brief.replace(/["\\]/g, '\\$&');
|
|
269
|
+
const thrower = `throw new Error("[nsv-hmr] Duplicate top-level bindings detected: ${escaped}");`;
|
|
270
|
+
result = `${thrower}\n` + result;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
catch { }
|
|
274
|
+
// Remove Vite internal imports (dynamic-import-helper, etc.)
|
|
275
|
+
// This handles both standalone lines and concatenated imports on the same line
|
|
276
|
+
result = result.replace(/import\s+[^;]+\s+from\s+["']\/@id\/[^"']*["'];?\s*/g, '');
|
|
277
|
+
// Also remove side-effect only virtual id imports like: import "/@id/__x00__vite/dynamic-import-helper.js";
|
|
278
|
+
// These can slip through and cause the NativeScript runtime to attempt resolving
|
|
279
|
+
// a non-existent physical file (e.g. /@id/__x00__vite/dynamic-import-helper.js) leading to
|
|
280
|
+
// module not found crashes during HMR evaluation.
|
|
281
|
+
if (/^[\t ]*import\s+["']\/@id\/[^"']+["'];?\s*$/m.test(result)) {
|
|
282
|
+
result = result.replace(/^[\t ]*import\s+["']\/@id\/[^"']+["'];?\s*$/gm, '');
|
|
283
|
+
// Inject a lightweight marker comment (harmless if left in output) so devs can confirm rewrite took place when viewing streamed artifact.
|
|
284
|
+
result = `// [hmr-sanitize] stripped virtual /@id/ side-effect imports\n${result}`;
|
|
285
|
+
}
|
|
286
|
+
// IMPORTANT: Perform vendor-module binding injection BEFORE stripping Vite prebundle imports.
|
|
287
|
+
// This allows the rewriter to see and canonicalize '/node_modules/.vite/deps/*' specifiers back
|
|
288
|
+
// to their package ids (e.g., '@nativescript/firebase-core') and generate require-based bindings
|
|
289
|
+
// so named imports like `{ firebase }` are preserved as const bindings.
|
|
290
|
+
//
|
|
291
|
+
// Some upstream transforms can emit a multiline form:
|
|
292
|
+
// import { x } from
|
|
293
|
+
// "/node_modules/.vite/deps/...";
|
|
294
|
+
// If we don't normalize it, later stripping of naked string-only lines can leave
|
|
295
|
+
// an invalid `import ... from` statement.
|
|
296
|
+
try {
|
|
297
|
+
result = result.replace(/(^|\n)([\t ]*import\s+[^;]*?\s+from)\s*\n\s*("\/?node_modules\/\.vite\/deps\/[^"\n]+"\s*;?\s*)/gm, (_m, p1, p2, p3) => `${p1}${p2} ${p3}`);
|
|
298
|
+
}
|
|
299
|
+
catch { }
|
|
300
|
+
// When preserveVendorImports is true (HMR /ns/m/ endpoint), skip the
|
|
301
|
+
// __nsVendorRequire + __nsPick rewrite. Vendor imports stay as bare
|
|
302
|
+
// specifiers so the device-side import map resolves them via V8's native
|
|
303
|
+
// module system, which correctly handles export * re-exports.
|
|
304
|
+
result = ensureNativeScriptModuleBindings(result, bindingOptions);
|
|
305
|
+
// Repair any accidental "import ... = expr" assignments that may have slipped in.
|
|
306
|
+
try {
|
|
307
|
+
result = repairImportEqualsAssignments(result);
|
|
308
|
+
}
|
|
309
|
+
catch { }
|
|
310
|
+
// Strip Vite prebundle deps imports (both named and side-effect) and any malformed const string artifacts
|
|
311
|
+
// Example problematic line observed: const "/node_modules/.vite/deps/@nativescript_firebase-messaging.js?v=...";
|
|
312
|
+
if (/node_modules\/\.vite\/deps\//.test(result)) {
|
|
313
|
+
result = rewriteVitePrebundleImportsForDevice(result, preserveVendorImports);
|
|
314
|
+
// Malformed const string lines accidentally produced by upstream transforms
|
|
315
|
+
result = result.replace(/^[\t ]*const\s+["']\/?node_modules\/\.vite\/deps\/[^"']+["'];?\s*$/gm, '// [hmr-sanitize] stripped malformed const prebundle ref\n');
|
|
316
|
+
// Naked string-only lines pointing at prebundle deps
|
|
317
|
+
result = result.replace(/^[\t ]*["']\/?node_modules\/\.vite\/deps\/[^"']+["'];?\s*$/gm, '// [hmr-sanitize] stripped prebundle side-effect literal\n');
|
|
318
|
+
}
|
|
319
|
+
// Dynamic aliasing covers helper imports; no further static list handling needed.
|
|
320
|
+
// Handle navigation helpers (dev bridge): $navigateTo, $navigateBack
|
|
321
|
+
// Note: do NOT inject $showModal as a named import; AST normalizer/destructure covers it when imported,
|
|
322
|
+
// and free-uses are handled via AST injection. This avoids duplicate identifier redeclarations.
|
|
323
|
+
if (/\$(?:navigate(?:To|Back)|showModal)\b/.test(result)) {
|
|
324
|
+
const navHelpers = [];
|
|
325
|
+
// Only consider free uses (not property access like obj.$navigateTo)
|
|
326
|
+
const needTo = /(^|[^.\w$])\$navigateTo\b/.test(result);
|
|
327
|
+
const needBack = /(^|[^.\w$])\$navigateBack\b/.test(result);
|
|
328
|
+
if (needTo)
|
|
329
|
+
navHelpers.push('$navigateTo');
|
|
330
|
+
if (needBack)
|
|
331
|
+
navHelpers.push('$navigateBack');
|
|
332
|
+
// Intentionally exclude $showModal from navHelpers injection to prevent named import reinsertion
|
|
333
|
+
// Remove any direct imports/usages that might shadow globals
|
|
334
|
+
// 1) From 'vue' or 'nativescript-vue' sources
|
|
335
|
+
result = removeNamedImports(result, navHelpers);
|
|
336
|
+
// 2) From our runtime bridge '/ns/rt' (versioned or not)
|
|
337
|
+
try {
|
|
338
|
+
// Do NOT re-introduce named imports from /ns/rt for nav helpers; drop them entirely after removing nav helpers.
|
|
339
|
+
const rtNamedRE = /(^|\n)\s*import\s*\{([^}]+)\}\s*from\s*["'](?:https?:\/\/[^"']+)?\/ns\/rt(?:\/[\d]+)?["'];?\s*/gm;
|
|
340
|
+
// Also compute locally-declared helpers to drop regardless of free-use detection
|
|
341
|
+
const hasLocalToForDrop = /(^|[\n;])\s*(?:const|let|var|function)\s+\$navigateTo\b/.test(result);
|
|
342
|
+
const hasLocalBackForDrop = /(^|[\n;])\s*(?:const|let|var|function)\s+\$navigateBack\b/.test(result);
|
|
343
|
+
result = result.replace(rtNamedRE, (full, pfx, specList) => {
|
|
344
|
+
const drop = new Set(navHelpers);
|
|
345
|
+
if (hasLocalToForDrop)
|
|
346
|
+
drop.add('$navigateTo');
|
|
347
|
+
if (hasLocalBackForDrop)
|
|
348
|
+
drop.add('$navigateBack');
|
|
349
|
+
const remaining = String(specList)
|
|
350
|
+
.split(',')
|
|
351
|
+
.map((s) => s.trim())
|
|
352
|
+
.filter(Boolean)
|
|
353
|
+
.filter((entry) => {
|
|
354
|
+
const base = entry.split(/\s+as\s+/i)[0].trim();
|
|
355
|
+
return !drop.has(base);
|
|
356
|
+
});
|
|
357
|
+
if (!remaining.length)
|
|
358
|
+
return pfx || '';
|
|
359
|
+
// Preserve non-navigation named imports for later normalization
|
|
360
|
+
return `${pfx}import { ${remaining.join(', ')} } from "/ns/rt";`;
|
|
361
|
+
});
|
|
362
|
+
// Also strip $navigateTo/$navigateBack from any destructuring previously created from /ns/rt
|
|
363
|
+
// Also remove from destructures bound off any __ns_rt_ns temp (including _re)
|
|
364
|
+
const rtDestructureRE = /(^|[\n;])\s*const\s*\{([^}]+)\}\s*=\s*(__ns_rt_ns(?:\d+|_re))\s*;?\s*/gm;
|
|
365
|
+
result = result.replace(rtDestructureRE, (full, pfx, specList, varName) => {
|
|
366
|
+
const cleaned = String(specList)
|
|
367
|
+
.split(',')
|
|
368
|
+
.map((s) => s.trim())
|
|
369
|
+
.filter(Boolean)
|
|
370
|
+
.filter((seg) => {
|
|
371
|
+
const lhs = seg.split(':')[0].trim();
|
|
372
|
+
return !/^\$navigate(?:To|Back)$/.test(lhs);
|
|
373
|
+
});
|
|
374
|
+
if (!cleaned.length)
|
|
375
|
+
return pfx || '';
|
|
376
|
+
return `${pfx}const { ${cleaned.join(', ')} } = ${varName};`;
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
catch { }
|
|
380
|
+
// Inject named imports from /ns/rt to provide bindings without redeclaration collisions
|
|
381
|
+
const imports = [];
|
|
382
|
+
const hasImportTo = /(^|\n)\s*import\s*\{[^}]*\$navigateTo[^}]*\}\s*from\s*["'](?:https?:\/\/[^"']+)?\/ns\/rt(?:\/[\d]+)?["']/.test(result);
|
|
383
|
+
const hasImportBack = /(^|\n)\s*import\s*\{[^}]*\$navigateBack[^}]*\}\s*from\s*["'](?:https?:\/\/[^"']+)?\/ns\/rt(?:\/[\d]+)?["']/.test(result);
|
|
384
|
+
// Avoid adding named imports if a local binding already exists (e.g., wrapper const)
|
|
385
|
+
const hasLocalTo = /(^|[\n;])\s*(?:const|let|var|function)\s+\$navigateTo\b/.test(result);
|
|
386
|
+
const hasLocalBack = /(^|[\n;])\s*(?:const|let|var|function)\s+\$navigateBack\b/.test(result);
|
|
387
|
+
if (needTo && !hasImportTo && !hasLocalTo)
|
|
388
|
+
imports.push('$navigateTo');
|
|
389
|
+
if (needBack && !hasImportBack && !hasLocalBack)
|
|
390
|
+
imports.push('$navigateBack');
|
|
391
|
+
// Do not inject $showModal named import; avoid duplicates with destructures created upstream
|
|
392
|
+
if (imports.length) {
|
|
393
|
+
result = `import { ${imports.join(', ')} } from "/ns/rt";\n` + result;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
// Ensure vendor bindings also apply after potential wrapper injections above
|
|
397
|
+
// (idempotent: second pass will be a no-op if imports already consumed).
|
|
398
|
+
result = ensureNativeScriptModuleBindings(result, bindingOptions);
|
|
399
|
+
try {
|
|
400
|
+
result = repairImportEqualsAssignments(result);
|
|
401
|
+
}
|
|
402
|
+
catch { }
|
|
403
|
+
// Rewrite any previously-injected vendor-based core access to the unified HTTP core bridge
|
|
404
|
+
try {
|
|
405
|
+
const vendorCoreRE1 = /globalThis\.__nsVendor\s*\(\s*["']@nativescript\/core["']\s*\)/g;
|
|
406
|
+
const vendorCoreRE2 = /__nsVendor\s*\(\s*["']@nativescript\/core["']\s*\)/g;
|
|
407
|
+
if (vendorCoreRE1.test(result) || vendorCoreRE2.test(result)) {
|
|
408
|
+
const hasImport = /import\s+__ns_core_bridge\s+from\s+["'][^"']*\/(?:\@ns|ns)\/core(?:\/[^"']+)?["']\s*;?/.test(result) || /(^|\n)\s*import\s+__ns_core_bridge\s+from\s+["']\/(?:\@ns|ns)\/core["']\s*;?/m.test(result);
|
|
409
|
+
if (!hasImport) {
|
|
410
|
+
result = `import __ns_core_bridge from "/ns/core";\n` + result;
|
|
411
|
+
}
|
|
412
|
+
result = result.replace(vendorCoreRE1, '__ns_core_bridge');
|
|
413
|
+
result = result.replace(vendorCoreRE2, '__ns_core_bridge');
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
catch { }
|
|
417
|
+
// Rewrite any explicit require('@nativescript/core[/sub]') calls to the unified core bridge
|
|
418
|
+
try {
|
|
419
|
+
const reqCoreRE1 = /(^|[^.\w$])require\(\s*["']@nativescript\/core([^"'\n]*)["']\s*\)/g;
|
|
420
|
+
const reqCoreRE2 = /(?:globalThis|window|self)\.require\(\s*["']@nativescript\/core([^"'\n]*)["']\s*\)/g;
|
|
421
|
+
if (reqCoreRE1.test(result) || reqCoreRE2.test(result)) {
|
|
422
|
+
const hasImport = /import\s+__ns_core_bridge\s+from\s+["'][^"']*\/(?:\@ns|ns)\/core(?:\/[^"']+)?["']\s*;?/.test(result) || /(^|\n)\s*import\s+__ns_core_bridge\s+from\s+["']\/(?:\@ns|ns)\/core["']\s*;?/m.test(result);
|
|
423
|
+
if (!hasImport) {
|
|
424
|
+
result = `import __ns_core_bridge from "/ns/core";\n` + result;
|
|
425
|
+
}
|
|
426
|
+
result = result.replace(reqCoreRE1, (_m, p1, _sub) => `${p1}__ns_core_bridge`);
|
|
427
|
+
result = result.replace(reqCoreRE2, '__ns_core_bridge');
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
catch { }
|
|
431
|
+
// Apply the three-pass safety net for stray @nativescript/core references
|
|
432
|
+
// (naked string literals, dangling `from` merges, lingering resolved-path
|
|
433
|
+
// references). Centralised in core-sanitize.sanitizeStrayCoreReferences so
|
|
434
|
+
// every NS-M emitter applies the same passes in the same order.
|
|
435
|
+
result = sanitizeStrayCoreReferences(result);
|
|
436
|
+
result = ensureVariableDynamicImportHelper(result);
|
|
437
|
+
// Normalize any lingering @nativescript/core imports to the /ns/core bridge (non-destructive best-effort)
|
|
438
|
+
try {
|
|
439
|
+
// Rewrite named imports from the /ns/core bridge into default import + destructuring.
|
|
440
|
+
// This makes `import { Frame } from '@nativescript/core'` work even if the bridge provides only a default export.
|
|
441
|
+
{
|
|
442
|
+
let __core_ns_seq = 0;
|
|
443
|
+
const toDestructureCore = (specList) => specList
|
|
444
|
+
.split(',')
|
|
445
|
+
.map((s) => s.trim())
|
|
446
|
+
.filter(Boolean)
|
|
447
|
+
.map((seg) => {
|
|
448
|
+
const m = seg.split(/\s+as\s+/i);
|
|
449
|
+
return m.length === 2 ? `${m[0].trim()}: ${m[1].trim()}` : seg;
|
|
450
|
+
})
|
|
451
|
+
.join(', ');
|
|
452
|
+
const reNamed = /(^|\n)\s*import\s*\{([^}]+)\}\s*from\s*["']((?:https?:\/\/[^"']+)?\/ns\/core(?:\/[^"']+)?)['"];?\s*/gm;
|
|
453
|
+
result = result.replace(reNamed, (_full, pfx, specList, src) => {
|
|
454
|
+
// Deep subpath URLs serve actual ESM with real named exports — skip.
|
|
455
|
+
if (isDeepCoreSubpath(src))
|
|
456
|
+
return _full;
|
|
457
|
+
__core_ns_seq++;
|
|
458
|
+
const tmp = `__ns_core_ns${__core_ns_seq}`;
|
|
459
|
+
const decl = `const { ${toDestructureCore(specList)} } = ${tmp};`;
|
|
460
|
+
return `${pfx}import ${tmp} from ${JSON.stringify(src)};\n${decl}\n`;
|
|
461
|
+
});
|
|
462
|
+
const reMixed = /(^|\n)\s*import\s+([A-Za-z_$][\w$]*)\s*,\s*\{([^}]+)\}\s*from\s*["']((?:https?:\/\/[^"']+)?\/ns\/core(?:\/[^"']+)?)['"];?\s*/gm;
|
|
463
|
+
result = result.replace(reMixed, (_full, pfx, defName, specList, src) => {
|
|
464
|
+
if (isDeepCoreSubpath(src))
|
|
465
|
+
return _full;
|
|
466
|
+
const decl = `const { ${toDestructureCore(specList)} } = ${defName};`;
|
|
467
|
+
return `${pfx}import ${defName} from ${JSON.stringify(src)};\n${decl}\n`;
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
catch { }
|
|
472
|
+
// Note: Removed legacy var-based underscore prelude to avoid const/var redeclaration conflicts.
|
|
473
|
+
// Normalize concatenated imports that may have ended up after a statement on the same line
|
|
474
|
+
try {
|
|
475
|
+
// Common concatenations
|
|
476
|
+
// Keep a single semicolon before the import to avoid generating ';;'
|
|
477
|
+
result = result.replace(/;\s*import\s+/g, ';\nimport ');
|
|
478
|
+
result = result.replace(/}\s*import\s+/g, '}\nimport ');
|
|
479
|
+
// Fallback: ensure any static import that isn't at start of line gets a newline before it.
|
|
480
|
+
//
|
|
481
|
+
// Only match after **structural** statement-ending characters: `;`, `}`, `)`, `]`. We
|
|
482
|
+
// deliberately do NOT include `'`, `"`, or `` ` `` here — those are string-literal
|
|
483
|
+
// terminators (and openers!), and including them caused the regex to fire inside
|
|
484
|
+
// example code embedded in error strings. Concrete failure observed:
|
|
485
|
+
// `@supabase/realtime-js` throws an Error whose message contains the literal
|
|
486
|
+
// `' import ws from "ws"\n' +`. With `'` in the delimiter class, the engine matched
|
|
487
|
+
// the opening `'` of that string literal as a "statement terminator" and rewrote the
|
|
488
|
+
// example to `'\nimport ws from "..."` — splitting the string across two lines and
|
|
489
|
+
// producing a SyntaxError on device. The structural delimiters below do not appear
|
|
490
|
+
// inside string-literal openers, so the rewrite is safe.
|
|
491
|
+
result = result.replace(/([;}\)\]])\s*(import\s+[^;\n]*\s+from\s*["'][^"']+["'])/g, '$1\n$2');
|
|
492
|
+
}
|
|
493
|
+
catch { }
|
|
494
|
+
// Collapse duplicate destructuring from the same temp namespace var (e.g., multiple const { x } = __ns_rt_ns1)
|
|
495
|
+
try {
|
|
496
|
+
const collapse = (code, prefix) => {
|
|
497
|
+
const re = new RegExp(`(^|\\n)\\s*const\\s*\\{([^}]+)\\}\\s*=\\s*(${prefix}\\d+)\\s*;?\\s*`, 'gm');
|
|
498
|
+
const byVar = {};
|
|
499
|
+
code.replace(re, (_full, _pfx, specList, varName) => {
|
|
500
|
+
const set = (byVar[varName] || (byVar[varName] = new Set()));
|
|
501
|
+
String(specList)
|
|
502
|
+
.split(',')
|
|
503
|
+
.map((s) => s.trim())
|
|
504
|
+
.filter(Boolean)
|
|
505
|
+
.forEach((seg) => set.add(seg));
|
|
506
|
+
return '';
|
|
507
|
+
});
|
|
508
|
+
if (Object.keys(byVar).length) {
|
|
509
|
+
// Remove all existing destructures first
|
|
510
|
+
code = code.replace(re, (full, pfx) => pfx || '');
|
|
511
|
+
// Re-emit one per var
|
|
512
|
+
const blocks = Object.entries(byVar).map(([varName, set]) => `const { ${Array.from(set).join(', ')} } = ${varName};`);
|
|
513
|
+
code = blocks.join('\n') + '\n' + code;
|
|
514
|
+
}
|
|
515
|
+
return code;
|
|
516
|
+
};
|
|
517
|
+
result = collapse(result, '__ns_rt_ns');
|
|
518
|
+
result = collapse(result, '__ns_core_ns');
|
|
519
|
+
}
|
|
520
|
+
catch { }
|
|
521
|
+
// After consolidating destructures, hoist static import declarations to the very top so imports
|
|
522
|
+
// always come before any statements that might reference their bindings. This ordering avoids
|
|
523
|
+
// device runtimes that are stricter about imports-first semantics during module instantiation.
|
|
524
|
+
try {
|
|
525
|
+
result = hoistTopLevelStaticImports(result);
|
|
526
|
+
}
|
|
527
|
+
catch { }
|
|
528
|
+
// Final safety: normalize any lingering named imports from /ns/rt into default+destructure
|
|
529
|
+
// Skip for node_modules (no /ns/rt helpers needed) and when AST marker present
|
|
530
|
+
try {
|
|
531
|
+
if (!isNodeModule && !/^\s*\/\* \[ast-normalized\] \*\//m.test(result)) {
|
|
532
|
+
result = ensureDestructureRtImports(result);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
catch { }
|
|
536
|
+
// Post-pass: if both a destructure from __ns_rt_ns* and named imports from /ns/rt exist,
|
|
537
|
+
// remove overlapping named specifiers to avoid "Identifier has already been declared".
|
|
538
|
+
try {
|
|
539
|
+
// Collect all bindings destructured from any __ns_rt_ns* temp
|
|
540
|
+
const rtDestructureRE = /(^|\n)\s*const\s*\{([^}]+)\}\s*=\s*(__ns_rt_ns(?:\d+|_re))\s*;?\s*/gm;
|
|
541
|
+
const rtBound = new Set();
|
|
542
|
+
let m;
|
|
543
|
+
while ((m = rtDestructureRE.exec(result)) !== null) {
|
|
544
|
+
const specList = String(m[2] || '');
|
|
545
|
+
specList
|
|
546
|
+
.split(',')
|
|
547
|
+
.map((s) => s.trim())
|
|
548
|
+
.filter(Boolean)
|
|
549
|
+
.forEach((seg) => {
|
|
550
|
+
const bind = seg.includes(':') ? seg.split(':')[1].trim() : seg;
|
|
551
|
+
if (bind)
|
|
552
|
+
rtBound.add(bind);
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
if (rtBound.size) {
|
|
556
|
+
// Rewrite named imports from /ns/rt by removing any specifiers already provided via destructure
|
|
557
|
+
const rtNamedImportRE = /(^|\n)\s*import\s*\{([^}]+)\}\s*from\s*["']((?:https?:\/\/[^"']+)?\/ns\/rt(?:\/[\d]+)?)["'];?\s*/gm;
|
|
558
|
+
const edits = [];
|
|
559
|
+
while ((m = rtNamedImportRE.exec(result)) !== null) {
|
|
560
|
+
const full = m[0];
|
|
561
|
+
const pfx = m[1] || '';
|
|
562
|
+
const specList = String(m[2] || '');
|
|
563
|
+
const src = m[3];
|
|
564
|
+
const kept = [];
|
|
565
|
+
specList
|
|
566
|
+
.split(',')
|
|
567
|
+
.map((s) => s.trim())
|
|
568
|
+
.filter(Boolean)
|
|
569
|
+
.forEach((seg) => {
|
|
570
|
+
const name = seg.split(/\s+as\s+/i)[0].trim();
|
|
571
|
+
if (!rtBound.has(name))
|
|
572
|
+
kept.push(seg);
|
|
573
|
+
});
|
|
574
|
+
let replacement = '';
|
|
575
|
+
if (kept.length) {
|
|
576
|
+
replacement = `${pfx}import { ${kept.join(', ')} } from ${JSON.stringify(src)};`;
|
|
577
|
+
}
|
|
578
|
+
else {
|
|
579
|
+
// Drop the import entirely if nothing remains
|
|
580
|
+
replacement = pfx || '';
|
|
581
|
+
}
|
|
582
|
+
edits.push({
|
|
583
|
+
start: rtNamedImportRE.lastIndex - full.length,
|
|
584
|
+
end: rtNamedImportRE.lastIndex,
|
|
585
|
+
text: replacement,
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
if (edits.length) {
|
|
589
|
+
// Apply edits in reverse order
|
|
590
|
+
edits
|
|
591
|
+
.sort((a, b) => b.start - a.start)
|
|
592
|
+
.forEach((e) => {
|
|
593
|
+
result = result.slice(0, e.start) + e.text + result.slice(e.end);
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
catch { }
|
|
599
|
+
// Tidy-ups: remove stray lines that are only semicolons and collapse excessive blank lines
|
|
600
|
+
try {
|
|
601
|
+
// Remove lines that contain only an optional whitespace and a single ';'
|
|
602
|
+
result = result.replace(/^[ \t]*;[ \t]*$/gm, '');
|
|
603
|
+
// Collapse 3+ blank lines into at most 2 to keep output compact and consistent
|
|
604
|
+
result = result.replace(/\n{3,}/g, '\n\n');
|
|
605
|
+
}
|
|
606
|
+
catch { }
|
|
607
|
+
// De-duplicate destructured bindings across different temp vars to avoid 'Identifier has already been declared'
|
|
608
|
+
try {
|
|
609
|
+
const reDestructureAny = /(^|\n)\s*const\s*\{([^}]+)\}\s*=\s*(__ns_(?:rt|core)_[A-Za-z0-9_]+)\s*;?\s*/gm;
|
|
610
|
+
const seenBindings = new Set();
|
|
611
|
+
const edits = [];
|
|
612
|
+
let m;
|
|
613
|
+
while ((m = reDestructureAny.exec(result)) !== null) {
|
|
614
|
+
const full = m[0];
|
|
615
|
+
const pfx = m.index;
|
|
616
|
+
const specList = m[2];
|
|
617
|
+
const varName = m[3];
|
|
618
|
+
const entries = specList
|
|
619
|
+
.split(',')
|
|
620
|
+
.map((s) => s.trim())
|
|
621
|
+
.filter(Boolean);
|
|
622
|
+
const kept = [];
|
|
623
|
+
for (const seg of entries) {
|
|
624
|
+
const bind = seg.includes(':') ? seg.split(':')[1].trim() : seg;
|
|
625
|
+
if (seenBindings.has(bind))
|
|
626
|
+
continue;
|
|
627
|
+
seenBindings.add(bind);
|
|
628
|
+
kept.push(seg);
|
|
629
|
+
}
|
|
630
|
+
const replacement = kept.length ? `${m[1]}const { ${kept.join(', ')} } = ${varName};` : m[1] || '';
|
|
631
|
+
edits.push({ start: pfx, end: pfx + full.length, text: replacement });
|
|
632
|
+
}
|
|
633
|
+
if (edits.length) {
|
|
634
|
+
// Apply edits in reverse order to not mess up indices
|
|
635
|
+
edits
|
|
636
|
+
.sort((a, b) => b.start - a.start)
|
|
637
|
+
.forEach((e) => {
|
|
638
|
+
result = result.slice(0, e.start) + e.text + result.slice(e.end);
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
catch { }
|
|
643
|
+
// As a final safety net, neutralize any uses of Vite's CJS import helpers when the helper variable
|
|
644
|
+
// itself is not declared (e.g., stripped earlier during sanitation). This prevents runtime errors like
|
|
645
|
+
// "Cannot read properties of undefined (reading 'initNorrix')" on device when accessing
|
|
646
|
+
// __vite__cjsImportX__pkg["prop"].
|
|
647
|
+
try {
|
|
648
|
+
result = stripDanglingViteCjsImports(result);
|
|
649
|
+
}
|
|
650
|
+
catch { }
|
|
651
|
+
return result;
|
|
652
|
+
}
|
|
653
|
+
export { processCodeForDevice, cleanCode, collectImportDependencies, processSfcCode };
|
|
654
|
+
//# sourceMappingURL=process-code-for-device.js.map
|