@swissjs/swite 0.3.3 → 0.3.5
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/CHANGELOG.md +19 -0
- package/dist/cli.js +8 -2
- package/dist/config/config.d.ts +39 -2
- package/dist/config/config.d.ts.map +1 -1
- package/dist/dev-engine/handlers/ui-handler.d.ts.map +1 -1
- package/dist/dev-engine/handlers/ui-handler.js +6 -3
- package/dist/dev-engine/handlers/uix-handler.d.ts.map +1 -1
- package/dist/dev-engine/handlers/uix-handler.js +6 -3
- package/dist/dev-engine/hmr/hmr.d.ts +1 -1
- package/dist/dev-engine/hmr/hmr.d.ts.map +1 -1
- package/dist/dev-engine/hmr/hmr.js +14 -2
- package/dist/dev-engine/middleware/middleware-setup.d.ts.map +1 -1
- package/dist/dev-engine/middleware/middleware-setup.js +2 -0
- package/dist/dev-engine/middleware/static-files.d.ts +2 -0
- package/dist/dev-engine/middleware/static-files.d.ts.map +1 -1
- package/dist/dev-engine/middleware/static-files.js +2 -1
- package/dist/dev-engine/server.js +4 -4
- package/dist/kernel/package-finder.d.ts +5 -2
- package/dist/kernel/package-finder.d.ts.map +1 -1
- package/dist/kernel/package-finder.js +11 -3
- package/dist/resolution/bare-import-resolver.d.ts.map +1 -1
- package/dist/resolution/bare-import-resolver.js +10 -2
- package/dist/resolution/cdn/cdn-fallback.d.ts.map +1 -1
- package/dist/resolution/cdn/cdn-fallback.js +4 -1
- package/dist/resolution/path/path-fixup.d.ts +6 -3
- package/dist/resolution/path/path-fixup.d.ts.map +1 -1
- package/dist/resolution/path/path-fixup.js +14 -10
- package/package.json +2 -2
- package/src/cli.ts +9 -2
- package/src/config/config.ts +36 -2
- package/src/dev-engine/handlers/ui-handler.ts +8 -3
- package/src/dev-engine/handlers/uix-handler.ts +8 -3
- package/src/dev-engine/hmr/hmr.ts +19 -3
- package/src/dev-engine/middleware/middleware-setup.ts +2 -0
- package/src/dev-engine/middleware/static-files.ts +4 -1
- package/src/dev-engine/server.ts +5 -5
- package/src/kernel/package-finder.ts +13 -3
- package/src/resolution/bare-import-resolver.ts +11 -2
- package/src/resolution/cdn/cdn-fallback.ts +4 -1
- package/src/resolution/path/path-fixup.ts +17 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- deps: bump @swissjs/core 0.1.10 → 0.1.11 (browser hotfix — guards `process.env` in reconciliation to prevent ReferenceError crash in browser environments)
|
|
8
|
+
|
|
9
|
+
## 0.3.4
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- fix(resolution): `findSwissLibMonorepo` now accepts `siblingRepositories` from user config, making sibling repo discovery configurable (#1)
|
|
14
|
+
- fix(resolution): Compiler path fixup (`/swiss-lib/` → `/swiss-packages/`) is now configurable via `compilerPathFixup` config key; can be disabled or given custom patterns (#2)
|
|
15
|
+
- fix(config): Added `publicDir`, `hmrPort`, `hmrHost`, `aliases`, `excludeFromHmr`, and `entry` to `SwiteUserConfig` (#3)
|
|
16
|
+
- fix(resolution): CDN fallback default changed to `false`; unscoped packages no longer fall through to jsDelivr without explicit `SWITE_CDN_FALLBACK_SCOPES` opt-in (#4)
|
|
17
|
+
- fix(hmr): HMR watcher now handles `add` and `unlink` events with full-page reload; `excludeFromHmr` patterns added to chokidar `ignored` list (#5)
|
|
18
|
+
- fix(dx): Added `--verbose` / `-v` flag and `SWITE_DEBUG=1` env var for resolver diagnostics; unresolved packages now log searched paths (#6)
|
|
19
|
+
- fix(static): CSS extraction entry point configurable via `SwiteUserConfig.entry` (defaults to `src/index.ui`); missing entry file no longer crashes server (#7)
|
|
20
|
+
- deps: bump `@swissjs/core` 0.1.9 → 0.1.10
|
|
21
|
+
|
|
3
22
|
## 0.3.3
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/dist/cli.js
CHANGED
|
@@ -7,6 +7,10 @@ import { startPythonDevService, stopPythonDevService, } from "./dev-engine/pytho
|
|
|
7
7
|
import { setProductionMode } from "./adapters/proxy/proxyToPython.js";
|
|
8
8
|
const [, , command, ...args] = process.argv;
|
|
9
9
|
const root = resolve(process.cwd());
|
|
10
|
+
// --verbose / -v enables full resolver diagnostic output
|
|
11
|
+
if (args.includes("--verbose") || args.includes("-v")) {
|
|
12
|
+
process.env["SWITE_DEBUG"] = "1";
|
|
13
|
+
}
|
|
10
14
|
async function dev() {
|
|
11
15
|
const config = await loadUserConfig(root);
|
|
12
16
|
const python = config.services?.python;
|
|
@@ -26,7 +30,8 @@ async function dev() {
|
|
|
26
30
|
root,
|
|
27
31
|
port: config.server?.port ?? 3000,
|
|
28
32
|
host: config.server?.host ?? "localhost",
|
|
29
|
-
|
|
33
|
+
hmrPort: config.server?.hmrPort,
|
|
34
|
+
publicDir: config.publicDir ?? "public",
|
|
30
35
|
open: false,
|
|
31
36
|
});
|
|
32
37
|
await server.start();
|
|
@@ -43,7 +48,8 @@ async function start() {
|
|
|
43
48
|
root,
|
|
44
49
|
port: config.server?.port ?? 3000,
|
|
45
50
|
host: config.server?.host ?? "localhost",
|
|
46
|
-
|
|
51
|
+
hmrPort: config.server?.hmrPort,
|
|
52
|
+
publicDir: config.publicDir ?? "public",
|
|
47
53
|
open: false,
|
|
48
54
|
});
|
|
49
55
|
await server.start();
|
package/dist/config/config.d.ts
CHANGED
|
@@ -16,10 +16,34 @@ export interface ServicesConfig {
|
|
|
16
16
|
export interface ServerConfig {
|
|
17
17
|
port?: number;
|
|
18
18
|
host?: string;
|
|
19
|
+
/** Port for the HMR WebSocket server. Defaults to 24678. */
|
|
20
|
+
hmrPort?: number;
|
|
21
|
+
/** Host for the HMR WebSocket server. Defaults to server.host. */
|
|
22
|
+
hmrHost?: string;
|
|
19
23
|
}
|
|
20
24
|
export interface SwiteUserConfig {
|
|
21
25
|
server?: ServerConfig;
|
|
22
26
|
services?: ServicesConfig;
|
|
27
|
+
/**
|
|
28
|
+
* Directory to serve static assets from. Defaults to "public".
|
|
29
|
+
* Path is relative to the project root.
|
|
30
|
+
*/
|
|
31
|
+
publicDir?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Application entry file for CSS extraction. Defaults to "src/index.ui".
|
|
34
|
+
* Path is relative to the project root.
|
|
35
|
+
*/
|
|
36
|
+
entry?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Module aliases resolved during bare import resolution.
|
|
39
|
+
* e.g. { "@/": "src/" } maps @/ imports to the src/ directory.
|
|
40
|
+
*/
|
|
41
|
+
aliases?: Record<string, string>;
|
|
42
|
+
/**
|
|
43
|
+
* Glob patterns to exclude from HMR watching in addition to the defaults
|
|
44
|
+
* (node_modules, .git, dist). Useful for generated files or large assets.
|
|
45
|
+
*/
|
|
46
|
+
excludeFromHmr?: string[];
|
|
23
47
|
/**
|
|
24
48
|
* Package scopes that should be treated as "internal" or "private".
|
|
25
49
|
* These scopes prioritize local/monorepo resolution and are forbidden from CDN redirects.
|
|
@@ -27,10 +51,23 @@ export interface SwiteUserConfig {
|
|
|
27
51
|
*/
|
|
28
52
|
internalScopes?: string[];
|
|
29
53
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
54
|
+
* Names of sibling monorepos to search for framework packages.
|
|
55
|
+
* Defaults to ['swiss-lib']. Override when your framework lives in a differently-named repo.
|
|
32
56
|
*/
|
|
33
57
|
siblingRepositories?: string[];
|
|
58
|
+
/**
|
|
59
|
+
* Control the compiler path fixup that rewrites `/swiss-lib/` → `/swiss-packages/`.
|
|
60
|
+
* Disable entirely or supply custom from/to pairs when your project uses different paths.
|
|
61
|
+
*/
|
|
62
|
+
compilerPathFixup?: {
|
|
63
|
+
/** When false, no path fixup is applied. Defaults to true for backward compatibility. */
|
|
64
|
+
enabled?: boolean;
|
|
65
|
+
/** Custom replacement patterns. Defaults to the built-in swiss-lib → swiss-packages pairs. */
|
|
66
|
+
patterns?: Array<{
|
|
67
|
+
from: string;
|
|
68
|
+
to: string;
|
|
69
|
+
}>;
|
|
70
|
+
};
|
|
34
71
|
}
|
|
35
72
|
/**
|
|
36
73
|
* Define swite configuration with full TypeScript validation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,SAAS,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,SAAS,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B;;;OAGG;IACH,iBAAiB,CAAC,EAAE;QAClB,yFAAyF;QACzF,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,8FAA8F;QAC9F,QAAQ,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAChD,CAAC;CACH;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,CAErE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-handler.d.ts","sourceRoot":"","sources":["../../../src/dev-engine/handlers/ui-handler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQxC,OAAO,EACL,WAAW,EAEX,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,SAAU,SAAQ,WAAW;IACxC,OAAO,CAAC,QAAQ,CAAoB;gBAExB,OAAO,EAAE,cAAc;IAI7B,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"ui-handler.d.ts","sourceRoot":"","sources":["../../../src/dev-engine/handlers/ui-handler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQxC,OAAO,EACL,WAAW,EAEX,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,SAAU,SAAQ,WAAW;IACxC,OAAO,CAAC,QAAQ,CAAoB;gBAExB,OAAO,EAAE,cAAc;IAI7B,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAuExD"}
|
|
@@ -26,10 +26,13 @@ export class UIHandler extends BaseHandler {
|
|
|
26
26
|
console.error(chalk.red(`[.ui] File not found: ${filePath}`));
|
|
27
27
|
throw new Error(`File not found: ${url} (resolved to: ${filePath})`);
|
|
28
28
|
}
|
|
29
|
+
const pathFixupEnabled = this.context.userConfig?.compilerPathFixup?.enabled !== false;
|
|
30
|
+
const pathFixupPatterns = this.context.userConfig?.compilerPathFixup?.patterns;
|
|
31
|
+
const applyPathFixup = (code) => pathFixupEnabled ? fixSwissLibPaths(code, pathFixupPatterns) : code;
|
|
29
32
|
// Cache hit
|
|
30
33
|
const cached = await compilationCache.get(filePath, (compiled) => this.getDependencies(compiled));
|
|
31
34
|
if (cached) {
|
|
32
|
-
const fixed =
|
|
35
|
+
const fixed = applyPathFixup(cached);
|
|
33
36
|
setDevHeaders(res);
|
|
34
37
|
res.setHeader("Content-Type", "application/javascript; charset=utf-8");
|
|
35
38
|
res.setHeader("Content-Length", Buffer.byteLength(fixed, "utf-8"));
|
|
@@ -48,7 +51,7 @@ export class UIHandler extends BaseHandler {
|
|
|
48
51
|
});
|
|
49
52
|
compiled = tsResult.code;
|
|
50
53
|
// Fix compiler-emitted wrong paths before import rewriting
|
|
51
|
-
compiled =
|
|
54
|
+
compiled = applyPathFixup(compiled);
|
|
52
55
|
// Inline import.meta.env references before import rewriting
|
|
53
56
|
compiled = inlineEnvReferences(compiled, this.context.env);
|
|
54
57
|
// Strip CSS static-asset imports — they are not ES modules
|
|
@@ -58,7 +61,7 @@ export class UIHandler extends BaseHandler {
|
|
|
58
61
|
console.warn(`[.ui] Compiled output contains bare imports: ${url}`);
|
|
59
62
|
}
|
|
60
63
|
const rewritten = await rewriteImports(compiled, filePath, this.context.resolver);
|
|
61
|
-
const finalCode =
|
|
64
|
+
const finalCode = applyPathFixup(rewritten);
|
|
62
65
|
await compilationCache.set(filePath, compiled, finalCode, (c) => this.getDependencies(c));
|
|
63
66
|
if (bareImportPattern.test(finalCode)) {
|
|
64
67
|
console.error(`[.ui] Bare imports still present after rewriting: ${url}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uix-handler.d.ts","sourceRoot":"","sources":["../../../src/dev-engine/handlers/uix-handler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQxC,OAAO,EACL,WAAW,EAEX,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,UAAW,SAAQ,WAAW;IACzC,OAAO,CAAC,QAAQ,CAAoB;gBAExB,OAAO,EAAE,cAAc;IAI7B,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"uix-handler.d.ts","sourceRoot":"","sources":["../../../src/dev-engine/handlers/uix-handler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQxC,OAAO,EACL,WAAW,EAEX,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,UAAW,SAAQ,WAAW;IACzC,OAAO,CAAC,QAAQ,CAAoB;gBAExB,OAAO,EAAE,cAAc;IAI7B,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAmExD"}
|
|
@@ -19,10 +19,13 @@ export class UIXHandler extends BaseHandler {
|
|
|
19
19
|
async handle(url, res) {
|
|
20
20
|
const filePath = await this.resolveFilePath(url);
|
|
21
21
|
console.log(chalk.blue(`[.uix] ${url}`));
|
|
22
|
+
const pathFixupEnabled = this.context.userConfig?.compilerPathFixup?.enabled !== false;
|
|
23
|
+
const pathFixupPatterns = this.context.userConfig?.compilerPathFixup?.patterns;
|
|
24
|
+
const applyPathFixup = (code) => pathFixupEnabled ? fixSwissLibPaths(code, pathFixupPatterns) : code;
|
|
22
25
|
// Cache hit
|
|
23
26
|
const cached = await compilationCache.get(filePath, (compiled) => this.getDependencies(compiled));
|
|
24
27
|
if (cached) {
|
|
25
|
-
const fixed =
|
|
28
|
+
const fixed = applyPathFixup(cached);
|
|
26
29
|
setDevHeaders(res);
|
|
27
30
|
res.setHeader("Content-Type", "application/javascript; charset=utf-8");
|
|
28
31
|
res.send(fixed);
|
|
@@ -40,7 +43,7 @@ export class UIXHandler extends BaseHandler {
|
|
|
40
43
|
});
|
|
41
44
|
compiled = tsResult.code;
|
|
42
45
|
// Fix compiler-emitted wrong paths before import rewriting
|
|
43
|
-
compiled =
|
|
46
|
+
compiled = applyPathFixup(compiled);
|
|
44
47
|
// Inline import.meta.env references before import rewriting
|
|
45
48
|
compiled = inlineEnvReferences(compiled, this.context.env);
|
|
46
49
|
// Strip CSS static-asset imports — they are not ES modules
|
|
@@ -55,7 +58,7 @@ export class UIXHandler extends BaseHandler {
|
|
|
55
58
|
console.warn(`[.uix] Compiled output contains bare imports: ${url}`);
|
|
56
59
|
}
|
|
57
60
|
const rewritten = await rewriteImports(compiled, filePath, this.context.resolver);
|
|
58
|
-
const finalCode =
|
|
61
|
+
const finalCode = applyPathFixup(rewritten);
|
|
59
62
|
await compilationCache.set(filePath, compiled, finalCode, (c) => this.getDependencies(c));
|
|
60
63
|
if (bareImportPattern.test(finalCode)) {
|
|
61
64
|
console.error(`[.uix] Bare imports still present after rewriting: ${url}`);
|
|
@@ -10,7 +10,7 @@ export declare class HMREngine {
|
|
|
10
10
|
private setupWebSocket;
|
|
11
11
|
private findFreePort;
|
|
12
12
|
getPort(): number;
|
|
13
|
-
start(): Promise<void>;
|
|
13
|
+
start(excludeFromHmr?: string[]): Promise<void>;
|
|
14
14
|
notifyChange(filePath: string): void;
|
|
15
15
|
getClientScript(): string;
|
|
16
16
|
private getUpdateType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../../../src/dev-engine/hmr/hmr.ts"],"names":[],"mappings":"AAUA,qBAAa,SAAS;IAOlB,OAAO,CAAC,IAAI;IANd,OAAO,CAAC,GAAG,CAAmB;IAC9B,OAAO,CAAC,OAAO,CAAC,CAAqB;IACrC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,IAAI,CAAS;gBAGX,IAAI,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM;IAOZ,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAiBnB,kBAAkB;IAUhC,OAAO,CAAC,cAAc;YAYR,YAAY;IAmB1B,OAAO,IAAI,MAAM;IAIX,KAAK;
|
|
1
|
+
{"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../../../src/dev-engine/hmr/hmr.ts"],"names":[],"mappings":"AAUA,qBAAa,SAAS;IAOlB,OAAO,CAAC,IAAI;IANd,OAAO,CAAC,GAAG,CAAmB;IAC9B,OAAO,CAAC,OAAO,CAAC,CAAqB;IACrC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,IAAI,CAAS;gBAGX,IAAI,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM;IAOZ,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAiBnB,kBAAkB;IAUhC,OAAO,CAAC,cAAc;YAYR,YAAY;IAmB1B,OAAO,IAAI,MAAM;IAIX,KAAK,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE;IA2CrC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAYpC,eAAe,IAAI,MAAM;IAIzB,OAAO,CAAC,aAAa;IAuBrB,OAAO,CAAC,SAAS;IAeX,IAAI;CAIX"}
|
|
@@ -65,9 +65,11 @@ export class HMREngine {
|
|
|
65
65
|
getPort() {
|
|
66
66
|
return this.port;
|
|
67
67
|
}
|
|
68
|
-
async start() {
|
|
68
|
+
async start(excludeFromHmr) {
|
|
69
|
+
const baseIgnored = ["**/node_modules/**", "**/.git/**", "**/dist/**"];
|
|
70
|
+
const ignored = excludeFromHmr ? [...baseIgnored, ...excludeFromHmr] : baseIgnored;
|
|
69
71
|
this.watcher = chokidar.watch(this.root, {
|
|
70
|
-
ignored
|
|
72
|
+
ignored,
|
|
71
73
|
ignoreInitial: true,
|
|
72
74
|
awaitWriteFinish: {
|
|
73
75
|
stabilityThreshold: 100,
|
|
@@ -86,6 +88,16 @@ export class HMREngine {
|
|
|
86
88
|
timestamp: Date.now(),
|
|
87
89
|
});
|
|
88
90
|
});
|
|
91
|
+
this.watcher.on("add", (filePath) => {
|
|
92
|
+
console.log(chalk.yellow(`[HMR] File added: ${filePath}`));
|
|
93
|
+
// New file — dependents are unknown, trigger a full reload
|
|
94
|
+
this.broadcast({ type: "reload", path: filePath, reason: "file-added" });
|
|
95
|
+
});
|
|
96
|
+
this.watcher.on("unlink", (filePath) => {
|
|
97
|
+
console.log(chalk.yellow(`[HMR] File deleted: ${filePath}`));
|
|
98
|
+
// Deleted file — its dependents will 404 on next import, trigger reload
|
|
99
|
+
this.broadcast({ type: "reload", path: filePath, reason: "file-deleted" });
|
|
100
|
+
});
|
|
89
101
|
console.log(chalk.green("[HMR] Watching for file changes..."));
|
|
90
102
|
}
|
|
91
103
|
notifyChange(filePath) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware-setup.d.ts","sourceRoot":"","sources":["../../../src/dev-engine/middleware/middleware-setup.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAmC,MAAM,SAAS,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAIpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAa9D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAK1C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,EAAE,SAAS,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,wBAAwB,EAAE,eAAe,CAAC;CAC/D;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,YAAY,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,GAAG,IAAI,CAAC;CACpE;AAuBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"middleware-setup.d.ts","sourceRoot":"","sources":["../../../src/dev-engine/middleware/middleware-setup.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAmC,MAAM,SAAS,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAIpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAa9D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAK1C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,EAAE,SAAS,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,wBAAwB,EAAE,eAAe,CAAC;CAC/D;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,YAAY,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,GAAG,IAAI,CAAC;CACpE;AAuBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA6Q3B"}
|
|
@@ -83,6 +83,7 @@ export async function setupMiddleware(app, config) {
|
|
|
83
83
|
root: config.root,
|
|
84
84
|
workspaceRoot,
|
|
85
85
|
env,
|
|
86
|
+
userConfig: config.userConfig,
|
|
86
87
|
};
|
|
87
88
|
const uiHandler = new UIHandler(handlerContext);
|
|
88
89
|
const uixHandler = new UIXHandler(handlerContext);
|
|
@@ -318,6 +319,7 @@ export async function setupMiddleware(app, config) {
|
|
|
318
319
|
await setupSPAFallback(app, {
|
|
319
320
|
root: config.root,
|
|
320
321
|
publicDir: config.publicDir,
|
|
322
|
+
entry: config.userConfig?.entry,
|
|
321
323
|
});
|
|
322
324
|
return {
|
|
323
325
|
routes: fileRouterResult.routes,
|
|
@@ -3,6 +3,8 @@ export interface StaticFilesConfig {
|
|
|
3
3
|
root: string;
|
|
4
4
|
publicDir: string;
|
|
5
5
|
workspaceRoot?: string | null;
|
|
6
|
+
/** Entry file for CSS extraction, relative to root. Defaults to "src/index.ui". */
|
|
7
|
+
entry?: string;
|
|
6
8
|
}
|
|
7
9
|
/**
|
|
8
10
|
* Setup static file serving for public directory, node_modules, and workspace packages
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-files.d.ts","sourceRoot":"","sources":["../../../src/dev-engine/middleware/static-files.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAMvC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"static-files.d.ts","sourceRoot":"","sources":["../../../src/dev-engine/middleware/static-files.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAMvC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,IAAI,CAAC,CAuYf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,IAAI,CAAC,CAgTf"}
|
|
@@ -412,7 +412,8 @@ export async function setupSPAFallback(app, config) {
|
|
|
412
412
|
console.log(chalk.magenta(`[SWITE CSS] ========== CSS EXTRACTION START (VERSION 3.0.0) ==========`));
|
|
413
413
|
console.log(chalk.magenta(`[SWITE CSS] App root: ${config.root}`));
|
|
414
414
|
try {
|
|
415
|
-
const
|
|
415
|
+
const entryFile = config.entry ?? "src/index.ui";
|
|
416
|
+
const entryPointPath = path.join(config.root, entryFile);
|
|
416
417
|
console.log(chalk.blue(`[SWITE CSS] Checking entry point: ${entryPointPath}`));
|
|
417
418
|
const entryPointContent = await fs.readFile(entryPointPath, "utf-8");
|
|
418
419
|
// Extract CSS imports using regex
|
|
@@ -61,6 +61,8 @@ export class SwiteServer {
|
|
|
61
61
|
const startTime = Date.now();
|
|
62
62
|
console.log(chalk.cyan("\n⚡ SWITE - SWISS Development Server\n"));
|
|
63
63
|
console.time("Startup");
|
|
64
|
+
// Load user config (swiss.config.ts) so internalScopes etc. flow into handlers
|
|
65
|
+
const userConfig = await loadUserConfig(this.config.root);
|
|
64
66
|
// CG-03: Build symlink registry before serving any requests.
|
|
65
67
|
// Maps realpath(node_modules/pkg symlink) → /node_modules/pkg browser URL
|
|
66
68
|
// so toUrl() can map absolute filesystem paths back to browser URLs.
|
|
@@ -77,7 +79,7 @@ export class SwiteServer {
|
|
|
77
79
|
if (workspaceRoot) {
|
|
78
80
|
nodeModulesDirs.push(path.join(workspaceRoot, "node_modules"));
|
|
79
81
|
}
|
|
80
|
-
const swissLib = await findSwissLibMonorepo(this.config.root);
|
|
82
|
+
const swissLib = await findSwissLibMonorepo(this.config.root, userConfig?.siblingRepositories);
|
|
81
83
|
if (swissLib) {
|
|
82
84
|
nodeModulesDirs.push(path.join(swissLib, "node_modules"));
|
|
83
85
|
}
|
|
@@ -87,8 +89,6 @@ export class SwiteServer {
|
|
|
87
89
|
console.warn(`[SWITE] Symlink registry build failed: ${err.message}`);
|
|
88
90
|
}
|
|
89
91
|
console.timeEnd("Symlink Registry");
|
|
90
|
-
// Load user config (swiss.config.ts) so internalScopes etc. flow into handlers
|
|
91
|
-
const userConfig = await loadUserConfig(this.config.root);
|
|
92
92
|
// Setup middleware
|
|
93
93
|
console.time("Middleware Setup");
|
|
94
94
|
const workspaceRoot = await this.findWorkspaceRoot(this.config.root);
|
|
@@ -107,7 +107,7 @@ export class SwiteServer {
|
|
|
107
107
|
// Start HMR
|
|
108
108
|
console.time("HMR Start");
|
|
109
109
|
await this.hmr.initialize();
|
|
110
|
-
await this.hmr.start();
|
|
110
|
+
await this.hmr.start(userConfig?.excludeFromHmr);
|
|
111
111
|
console.timeEnd("HMR Start");
|
|
112
112
|
// Start HTTP server
|
|
113
113
|
// Use 0.0.0.0 to bind to all interfaces (IPv4 and IPv6)
|
|
@@ -11,9 +11,12 @@ export interface PackageLocation {
|
|
|
11
11
|
*/
|
|
12
12
|
export declare function findSiblingRepository(startPath: string, repoName: string): Promise<string | null>;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Find the co-located framework monorepo. Tries each name in `fallbackNames`
|
|
15
|
+
* in order and returns the first match. The default list is ['swiss-lib'] for
|
|
16
|
+
* backward compatibility; callers that have a user config should forward
|
|
17
|
+
* `userConfig.siblingRepositories` here to make the lookup configurable.
|
|
15
18
|
*/
|
|
16
|
-
export declare function findSwissLibMonorepo(startPath: string): Promise<string | null>;
|
|
19
|
+
export declare function findSwissLibMonorepo(startPath: string, fallbackNames?: string[]): Promise<string | null>;
|
|
17
20
|
/**
|
|
18
21
|
* Find a specific package by name, with priority given based on environment.
|
|
19
22
|
* In development, we prioritize local sibling source code.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-finder.d.ts","sourceRoot":"","sources":["../../src/kernel/package-finder.ts"],"names":[],"mappings":"AASA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,WAAW,GAAG,cAAc,CAAC;CAClD;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBvG;AAED
|
|
1
|
+
{"version":3,"file":"package-finder.d.ts","sourceRoot":"","sources":["../../src/kernel/package-finder.ts"],"names":[],"mappings":"AASA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,WAAW,GAAG,cAAc,CAAC;CAClD;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBvG;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,aAAa,GAAE,MAAM,EAAkB,GACtC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMxB;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAC5B,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAuEjC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA2B7E"}
|
|
@@ -35,10 +35,18 @@ export async function findSiblingRepository(startPath, repoName) {
|
|
|
35
35
|
return null;
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
38
|
+
* Find the co-located framework monorepo. Tries each name in `fallbackNames`
|
|
39
|
+
* in order and returns the first match. The default list is ['swiss-lib'] for
|
|
40
|
+
* backward compatibility; callers that have a user config should forward
|
|
41
|
+
* `userConfig.siblingRepositories` here to make the lookup configurable.
|
|
39
42
|
*/
|
|
40
|
-
export async function findSwissLibMonorepo(startPath) {
|
|
41
|
-
|
|
43
|
+
export async function findSwissLibMonorepo(startPath, fallbackNames = ['swiss-lib']) {
|
|
44
|
+
for (const name of fallbackNames) {
|
|
45
|
+
const result = await findSiblingRepository(startPath, name);
|
|
46
|
+
if (result)
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
42
50
|
}
|
|
43
51
|
/**
|
|
44
52
|
* Find a specific package by name, with priority given based on environment.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bare-import-resolver.d.ts","sourceRoot":"","sources":["../../src/resolution/bare-import-resolver.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,kBAAkB,EAAmC,MAAM,mBAAmB,CAAC;AAI7F,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACtE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"bare-import-resolver.d.ts","sourceRoot":"","sources":["../../src/resolution/bare-import-resolver.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,kBAAkB,EAAmC,MAAM,mBAAmB,CAAC;AAI7F,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACtE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CAqOjB"}
|
|
@@ -13,6 +13,7 @@ import { toUrl } from "./url-resolver.js";
|
|
|
13
13
|
* Resolve bare import specifier (e.g., @swissjs/core, react, etc.)
|
|
14
14
|
*/
|
|
15
15
|
export async function resolveBareImport(specifier, context) {
|
|
16
|
+
const debug = process.env["SWITE_DEBUG"] === "1";
|
|
16
17
|
// Extract package name outside the try/catch so fallback logic can reference it.
|
|
17
18
|
// This must stay project-agnostic: works for both scoped and unscoped packages.
|
|
18
19
|
const parts = specifier.split("/");
|
|
@@ -40,6 +41,9 @@ export async function resolveBareImport(specifier, context) {
|
|
|
40
41
|
nodeModulesLocations.push(swissNodeModules);
|
|
41
42
|
}
|
|
42
43
|
}
|
|
44
|
+
if (debug) {
|
|
45
|
+
console.log(`[swite:resolve] Trying "${specifier}" in:`, nodeModulesLocations);
|
|
46
|
+
}
|
|
43
47
|
// Try each location
|
|
44
48
|
for (const nodeModulesPath of nodeModulesLocations) {
|
|
45
49
|
const testPkgDir = path.join(nodeModulesPath, pkgName);
|
|
@@ -56,10 +60,14 @@ export async function resolveBareImport(specifier, context) {
|
|
|
56
60
|
return await resolveWorkspacePackageEntry(workspacePkg, pkgName, subPath, specifier, context);
|
|
57
61
|
}
|
|
58
62
|
if (!shouldUseCdnFallback(pkgName)) {
|
|
59
|
-
console.warn(`[SWITE]
|
|
63
|
+
console.warn(`[SWITE] Cannot resolve "${pkgName}"\n` +
|
|
64
|
+
` Searched:\n${nodeModulesLocations.map(p => ` - ${p}`).join('\n')}\n` +
|
|
65
|
+
` CDN fallback is disabled. To enable for a scope, set:\n` +
|
|
66
|
+
` SWITE_CDN_FALLBACK_SCOPES=@scope1,@scope2\n` +
|
|
67
|
+
` Run with --verbose for full resolution trace.`);
|
|
60
68
|
return `/node_modules/${specifier}`;
|
|
61
69
|
}
|
|
62
|
-
console.warn(`[SWITE] Package ${pkgName} not found
|
|
70
|
+
console.warn(`[SWITE] Package ${pkgName} not found in any local location, using CDN fallback`);
|
|
63
71
|
return `https://cdn.jsdelivr.net/npm/${specifier}/+esm`;
|
|
64
72
|
}
|
|
65
73
|
// Continue with normal resolution if we found it
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdn-fallback.d.ts","sourceRoot":"","sources":["../../../src/resolution/cdn/cdn-fallback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAmBH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"cdn-fallback.d.ts","sourceRoot":"","sources":["../../../src/resolution/cdn/cdn-fallback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAmBH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAQpE"}
|
|
@@ -29,8 +29,11 @@ function parseAllowList() {
|
|
|
29
29
|
}
|
|
30
30
|
export function shouldUseCdnFallback(specifierOrPkg) {
|
|
31
31
|
const scope = getScope(specifierOrPkg);
|
|
32
|
+
// Unscoped packages (e.g. "react") are not automatically CDN-eligible; require
|
|
33
|
+
// explicit opt-in via SWITE_CDN_FALLBACK_SCOPES to prevent accidental exfiltration
|
|
34
|
+
// of package requests for private-registry or unscoped internal packages.
|
|
32
35
|
if (!scope)
|
|
33
|
-
return
|
|
36
|
+
return false;
|
|
34
37
|
const allow = parseAllowList();
|
|
35
38
|
return allow.has(scope);
|
|
36
39
|
}
|
|
@@ -6,8 +6,11 @@
|
|
|
6
6
|
* compiler is fixed at source this single function is the authoritative fixup.
|
|
7
7
|
* Apply it once per compilation, before passing code to the import rewriter.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* Pass `patterns` from `userConfig.compilerPathFixup.patterns` to override the
|
|
10
|
+
* defaults. Pass an empty array to disable all fixups.
|
|
11
11
|
*/
|
|
12
|
-
export declare function fixSwissLibPaths(code: string
|
|
12
|
+
export declare function fixSwissLibPaths(code: string, patterns?: Array<{
|
|
13
|
+
from: string;
|
|
14
|
+
to: string;
|
|
15
|
+
}>): string;
|
|
13
16
|
//# sourceMappingURL=path-fixup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path-fixup.d.ts","sourceRoot":"","sources":["../../../src/resolution/path/path-fixup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"path-fixup.d.ts","sourceRoot":"","sources":["../../../src/resolution/path/path-fixup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7C,MAAM,CAYR"}
|
|
@@ -6,15 +6,19 @@
|
|
|
6
6
|
* compiler is fixed at source this single function is the authoritative fixup.
|
|
7
7
|
* Apply it once per compilation, before passing code to the import rewriter.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* Pass `patterns` from `userConfig.compilerPathFixup.patterns` to override the
|
|
10
|
+
* defaults. Pass an empty array to disable all fixups.
|
|
11
11
|
*/
|
|
12
|
-
export function fixSwissLibPaths(code) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
.
|
|
12
|
+
export function fixSwissLibPaths(code, patterns) {
|
|
13
|
+
const activePatterns = patterns ?? [
|
|
14
|
+
{ from: '/swiss-lib/packages/', to: '/swiss-packages/' },
|
|
15
|
+
{ from: '/swiss-lib/', to: '/swiss-packages/' },
|
|
16
|
+
];
|
|
17
|
+
let result = code;
|
|
18
|
+
for (const { from, to } of activePatterns) {
|
|
19
|
+
if (result.includes(from)) {
|
|
20
|
+
result = result.split(from).join(to);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
20
24
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swissjs/swite",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "SWITE - SWISS Development Server (Vite replacement)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"swite": "dist/cli.js"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@swissjs/core": "0.1.
|
|
12
|
+
"@swissjs/core": "0.1.11",
|
|
13
13
|
"@swissjs/compiler": "0.1.5",
|
|
14
14
|
"@swissjs/plugin-file-router": "1.0.2",
|
|
15
15
|
"chalk": "^5.3.0",
|
package/src/cli.ts
CHANGED
|
@@ -12,6 +12,11 @@ import { setProductionMode } from "./adapters/proxy/proxyToPython.js";
|
|
|
12
12
|
const [, , command, ...args] = process.argv;
|
|
13
13
|
const root = resolve(process.cwd());
|
|
14
14
|
|
|
15
|
+
// --verbose / -v enables full resolver diagnostic output
|
|
16
|
+
if (args.includes("--verbose") || args.includes("-v")) {
|
|
17
|
+
process.env["SWITE_DEBUG"] = "1";
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
async function dev(): Promise<void> {
|
|
16
21
|
const config = await loadUserConfig(root);
|
|
17
22
|
const python = config.services?.python;
|
|
@@ -35,7 +40,8 @@ async function dev(): Promise<void> {
|
|
|
35
40
|
root,
|
|
36
41
|
port: config.server?.port ?? 3000,
|
|
37
42
|
host: config.server?.host ?? "localhost",
|
|
38
|
-
|
|
43
|
+
hmrPort: config.server?.hmrPort,
|
|
44
|
+
publicDir: config.publicDir ?? "public",
|
|
39
45
|
open: false,
|
|
40
46
|
});
|
|
41
47
|
|
|
@@ -61,7 +67,8 @@ async function start(): Promise<void> {
|
|
|
61
67
|
root,
|
|
62
68
|
port: config.server?.port ?? 3000,
|
|
63
69
|
host: config.server?.host ?? "localhost",
|
|
64
|
-
|
|
70
|
+
hmrPort: config.server?.hmrPort,
|
|
71
|
+
publicDir: config.publicDir ?? "public",
|
|
65
72
|
open: false,
|
|
66
73
|
});
|
|
67
74
|
|
package/src/config/config.ts
CHANGED
|
@@ -18,11 +18,35 @@ export interface ServicesConfig {
|
|
|
18
18
|
export interface ServerConfig {
|
|
19
19
|
port?: number;
|
|
20
20
|
host?: string;
|
|
21
|
+
/** Port for the HMR WebSocket server. Defaults to 24678. */
|
|
22
|
+
hmrPort?: number;
|
|
23
|
+
/** Host for the HMR WebSocket server. Defaults to server.host. */
|
|
24
|
+
hmrHost?: string;
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
export interface SwiteUserConfig {
|
|
24
28
|
server?: ServerConfig;
|
|
25
29
|
services?: ServicesConfig;
|
|
30
|
+
/**
|
|
31
|
+
* Directory to serve static assets from. Defaults to "public".
|
|
32
|
+
* Path is relative to the project root.
|
|
33
|
+
*/
|
|
34
|
+
publicDir?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Application entry file for CSS extraction. Defaults to "src/index.ui".
|
|
37
|
+
* Path is relative to the project root.
|
|
38
|
+
*/
|
|
39
|
+
entry?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Module aliases resolved during bare import resolution.
|
|
42
|
+
* e.g. { "@/": "src/" } maps @/ imports to the src/ directory.
|
|
43
|
+
*/
|
|
44
|
+
aliases?: Record<string, string>;
|
|
45
|
+
/**
|
|
46
|
+
* Glob patterns to exclude from HMR watching in addition to the defaults
|
|
47
|
+
* (node_modules, .git, dist). Useful for generated files or large assets.
|
|
48
|
+
*/
|
|
49
|
+
excludeFromHmr?: string[];
|
|
26
50
|
/**
|
|
27
51
|
* Package scopes that should be treated as "internal" or "private".
|
|
28
52
|
* These scopes prioritize local/monorepo resolution and are forbidden from CDN redirects.
|
|
@@ -30,10 +54,20 @@ export interface SwiteUserConfig {
|
|
|
30
54
|
*/
|
|
31
55
|
internalScopes?: string[];
|
|
32
56
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
57
|
+
* Names of sibling monorepos to search for framework packages.
|
|
58
|
+
* Defaults to ['swiss-lib']. Override when your framework lives in a differently-named repo.
|
|
35
59
|
*/
|
|
36
60
|
siblingRepositories?: string[];
|
|
61
|
+
/**
|
|
62
|
+
* Control the compiler path fixup that rewrites `/swiss-lib/` → `/swiss-packages/`.
|
|
63
|
+
* Disable entirely or supply custom from/to pairs when your project uses different paths.
|
|
64
|
+
*/
|
|
65
|
+
compilerPathFixup?: {
|
|
66
|
+
/** When false, no path fixup is applied. Defaults to true for backward compatibility. */
|
|
67
|
+
enabled?: boolean;
|
|
68
|
+
/** Custom replacement patterns. Defaults to the built-in swiss-lib → swiss-packages pairs. */
|
|
69
|
+
patterns?: Array<{ from: string; to: string }>;
|
|
70
|
+
};
|
|
37
71
|
}
|
|
38
72
|
|
|
39
73
|
/**
|
|
@@ -36,10 +36,15 @@ export class UIHandler extends BaseHandler {
|
|
|
36
36
|
throw new Error(`File not found: ${url} (resolved to: ${filePath})`);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
const pathFixupEnabled = this.context.userConfig?.compilerPathFixup?.enabled !== false;
|
|
40
|
+
const pathFixupPatterns = this.context.userConfig?.compilerPathFixup?.patterns;
|
|
41
|
+
const applyPathFixup = (code: string) =>
|
|
42
|
+
pathFixupEnabled ? fixSwissLibPaths(code, pathFixupPatterns) : code;
|
|
43
|
+
|
|
39
44
|
// Cache hit
|
|
40
45
|
const cached = await compilationCache.get(filePath, (compiled) => this.getDependencies(compiled));
|
|
41
46
|
if (cached) {
|
|
42
|
-
const fixed =
|
|
47
|
+
const fixed = applyPathFixup(cached);
|
|
43
48
|
setDevHeaders(res);
|
|
44
49
|
res.setHeader("Content-Type", "application/javascript; charset=utf-8");
|
|
45
50
|
res.setHeader("Content-Length", Buffer.byteLength(fixed, "utf-8"));
|
|
@@ -61,7 +66,7 @@ export class UIHandler extends BaseHandler {
|
|
|
61
66
|
compiled = tsResult.code;
|
|
62
67
|
|
|
63
68
|
// Fix compiler-emitted wrong paths before import rewriting
|
|
64
|
-
compiled =
|
|
69
|
+
compiled = applyPathFixup(compiled);
|
|
65
70
|
|
|
66
71
|
// Inline import.meta.env references before import rewriting
|
|
67
72
|
compiled = inlineEnvReferences(compiled, this.context.env);
|
|
@@ -75,7 +80,7 @@ export class UIHandler extends BaseHandler {
|
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
const rewritten = await rewriteImports(compiled, filePath, this.context.resolver);
|
|
78
|
-
const finalCode =
|
|
83
|
+
const finalCode = applyPathFixup(rewritten);
|
|
79
84
|
|
|
80
85
|
await compilationCache.set(filePath, compiled, finalCode, (c) => this.getDependencies(c));
|
|
81
86
|
|
|
@@ -29,10 +29,15 @@ export class UIXHandler extends BaseHandler {
|
|
|
29
29
|
const filePath = await this.resolveFilePath(url);
|
|
30
30
|
console.log(chalk.blue(`[.uix] ${url}`));
|
|
31
31
|
|
|
32
|
+
const pathFixupEnabled = this.context.userConfig?.compilerPathFixup?.enabled !== false;
|
|
33
|
+
const pathFixupPatterns = this.context.userConfig?.compilerPathFixup?.patterns;
|
|
34
|
+
const applyPathFixup = (code: string) =>
|
|
35
|
+
pathFixupEnabled ? fixSwissLibPaths(code, pathFixupPatterns) : code;
|
|
36
|
+
|
|
32
37
|
// Cache hit
|
|
33
38
|
const cached = await compilationCache.get(filePath, (compiled) => this.getDependencies(compiled));
|
|
34
39
|
if (cached) {
|
|
35
|
-
const fixed =
|
|
40
|
+
const fixed = applyPathFixup(cached);
|
|
36
41
|
setDevHeaders(res);
|
|
37
42
|
res.setHeader("Content-Type", "application/javascript; charset=utf-8");
|
|
38
43
|
res.send(fixed);
|
|
@@ -53,7 +58,7 @@ export class UIXHandler extends BaseHandler {
|
|
|
53
58
|
compiled = tsResult.code;
|
|
54
59
|
|
|
55
60
|
// Fix compiler-emitted wrong paths before import rewriting
|
|
56
|
-
compiled =
|
|
61
|
+
compiled = applyPathFixup(compiled);
|
|
57
62
|
|
|
58
63
|
// Inline import.meta.env references before import rewriting
|
|
59
64
|
compiled = inlineEnvReferences(compiled, this.context.env);
|
|
@@ -72,7 +77,7 @@ export class UIXHandler extends BaseHandler {
|
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
const rewritten = await rewriteImports(compiled, filePath, this.context.resolver);
|
|
75
|
-
const finalCode =
|
|
80
|
+
const finalCode = applyPathFixup(rewritten);
|
|
76
81
|
|
|
77
82
|
await compilationCache.set(filePath, compiled, finalCode, (c) => this.getDependencies(c));
|
|
78
83
|
|
|
@@ -85,9 +85,12 @@ export class HMREngine {
|
|
|
85
85
|
return this.port;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
async start() {
|
|
88
|
+
async start(excludeFromHmr?: string[]) {
|
|
89
|
+
const baseIgnored = ["**/node_modules/**", "**/.git/**", "**/dist/**"];
|
|
90
|
+
const ignored = excludeFromHmr ? [...baseIgnored, ...excludeFromHmr] : baseIgnored;
|
|
91
|
+
|
|
89
92
|
this.watcher = chokidar.watch(this.root, {
|
|
90
|
-
ignored
|
|
93
|
+
ignored,
|
|
91
94
|
ignoreInitial: true,
|
|
92
95
|
awaitWriteFinish: {
|
|
93
96
|
stabilityThreshold: 100,
|
|
@@ -110,6 +113,18 @@ export class HMREngine {
|
|
|
110
113
|
});
|
|
111
114
|
});
|
|
112
115
|
|
|
116
|
+
this.watcher.on("add", (filePath) => {
|
|
117
|
+
console.log(chalk.yellow(`[HMR] File added: ${filePath}`));
|
|
118
|
+
// New file — dependents are unknown, trigger a full reload
|
|
119
|
+
this.broadcast({ type: "reload", path: filePath, reason: "file-added" });
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
this.watcher.on("unlink", (filePath) => {
|
|
123
|
+
console.log(chalk.yellow(`[HMR] File deleted: ${filePath}`));
|
|
124
|
+
// Deleted file — its dependents will 404 on next import, trigger reload
|
|
125
|
+
this.broadcast({ type: "reload", path: filePath, reason: "file-deleted" });
|
|
126
|
+
});
|
|
127
|
+
|
|
113
128
|
console.log(chalk.green("[HMR] Watching for file changes..."));
|
|
114
129
|
}
|
|
115
130
|
|
|
@@ -156,7 +171,8 @@ export class HMREngine {
|
|
|
156
171
|
type: string;
|
|
157
172
|
path: string;
|
|
158
173
|
updateType?: string;
|
|
159
|
-
|
|
174
|
+
reason?: string;
|
|
175
|
+
timestamp?: number;
|
|
160
176
|
}) {
|
|
161
177
|
const payload = JSON.stringify(message);
|
|
162
178
|
this.clients.forEach((client) => {
|
|
@@ -118,6 +118,7 @@ export async function setupMiddleware(
|
|
|
118
118
|
root: config.root,
|
|
119
119
|
workspaceRoot,
|
|
120
120
|
env,
|
|
121
|
+
userConfig: config.userConfig,
|
|
121
122
|
};
|
|
122
123
|
|
|
123
124
|
const uiHandler = new UIHandler(handlerContext);
|
|
@@ -342,6 +343,7 @@ export async function setupMiddleware(
|
|
|
342
343
|
await setupSPAFallback(app, {
|
|
343
344
|
root: config.root,
|
|
344
345
|
publicDir: config.publicDir,
|
|
346
|
+
entry: config.userConfig?.entry,
|
|
345
347
|
});
|
|
346
348
|
|
|
347
349
|
return {
|
|
@@ -15,6 +15,8 @@ export interface StaticFilesConfig {
|
|
|
15
15
|
root: string;
|
|
16
16
|
publicDir: string;
|
|
17
17
|
workspaceRoot?: string | null;
|
|
18
|
+
/** Entry file for CSS extraction, relative to root. Defaults to "src/index.ui". */
|
|
19
|
+
entry?: string;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
/**
|
|
@@ -549,7 +551,8 @@ export async function setupSPAFallback(
|
|
|
549
551
|
console.log(chalk.magenta(`[SWITE CSS] ========== CSS EXTRACTION START (VERSION 3.0.0) ==========`));
|
|
550
552
|
console.log(chalk.magenta(`[SWITE CSS] App root: ${config.root}`));
|
|
551
553
|
try {
|
|
552
|
-
const
|
|
554
|
+
const entryFile = config.entry ?? "src/index.ui";
|
|
555
|
+
const entryPointPath = path.join(config.root, entryFile);
|
|
553
556
|
console.log(chalk.blue(`[SWITE CSS] Checking entry point: ${entryPointPath}`));
|
|
554
557
|
const entryPointContent = await fs.readFile(entryPointPath, "utf-8");
|
|
555
558
|
|
package/src/dev-engine/server.ts
CHANGED
|
@@ -85,6 +85,9 @@ export class SwiteServer {
|
|
|
85
85
|
console.log(chalk.cyan("\n⚡ SWITE - SWISS Development Server\n"));
|
|
86
86
|
console.time("Startup");
|
|
87
87
|
|
|
88
|
+
// Load user config (swiss.config.ts) so internalScopes etc. flow into handlers
|
|
89
|
+
const userConfig = await loadUserConfig(this.config.root);
|
|
90
|
+
|
|
88
91
|
// CG-03: Build symlink registry before serving any requests.
|
|
89
92
|
// Maps realpath(node_modules/pkg symlink) → /node_modules/pkg browser URL
|
|
90
93
|
// so toUrl() can map absolute filesystem paths back to browser URLs.
|
|
@@ -101,7 +104,7 @@ export class SwiteServer {
|
|
|
101
104
|
if (workspaceRoot) {
|
|
102
105
|
nodeModulesDirs.push(path.join(workspaceRoot, "node_modules"));
|
|
103
106
|
}
|
|
104
|
-
const swissLib = await findSwissLibMonorepo(this.config.root);
|
|
107
|
+
const swissLib = await findSwissLibMonorepo(this.config.root, userConfig?.siblingRepositories);
|
|
105
108
|
if (swissLib) {
|
|
106
109
|
nodeModulesDirs.push(path.join(swissLib, "node_modules"));
|
|
107
110
|
}
|
|
@@ -111,9 +114,6 @@ export class SwiteServer {
|
|
|
111
114
|
}
|
|
112
115
|
console.timeEnd("Symlink Registry");
|
|
113
116
|
|
|
114
|
-
// Load user config (swiss.config.ts) so internalScopes etc. flow into handlers
|
|
115
|
-
const userConfig = await loadUserConfig(this.config.root);
|
|
116
|
-
|
|
117
117
|
// Setup middleware
|
|
118
118
|
console.time("Middleware Setup");
|
|
119
119
|
const workspaceRoot = await this.findWorkspaceRoot(this.config.root);
|
|
@@ -133,7 +133,7 @@ export class SwiteServer {
|
|
|
133
133
|
// Start HMR
|
|
134
134
|
console.time("HMR Start");
|
|
135
135
|
await this.hmr.initialize();
|
|
136
|
-
await this.hmr.start();
|
|
136
|
+
await this.hmr.start(userConfig?.excludeFromHmr);
|
|
137
137
|
console.timeEnd("HMR Start");
|
|
138
138
|
|
|
139
139
|
// Start HTTP server
|
|
@@ -48,10 +48,20 @@ export async function findSiblingRepository(startPath: string, repoName: string)
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
51
|
+
* Find the co-located framework monorepo. Tries each name in `fallbackNames`
|
|
52
|
+
* in order and returns the first match. The default list is ['swiss-lib'] for
|
|
53
|
+
* backward compatibility; callers that have a user config should forward
|
|
54
|
+
* `userConfig.siblingRepositories` here to make the lookup configurable.
|
|
52
55
|
*/
|
|
53
|
-
export async function findSwissLibMonorepo(
|
|
54
|
-
|
|
56
|
+
export async function findSwissLibMonorepo(
|
|
57
|
+
startPath: string,
|
|
58
|
+
fallbackNames: string[] = ['swiss-lib'],
|
|
59
|
+
): Promise<string | null> {
|
|
60
|
+
for (const name of fallbackNames) {
|
|
61
|
+
const result = await findSiblingRepository(startPath, name);
|
|
62
|
+
if (result) return result;
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
55
65
|
}
|
|
56
66
|
|
|
57
67
|
/**
|
|
@@ -23,6 +23,7 @@ export async function resolveBareImport(
|
|
|
23
23
|
specifier: string,
|
|
24
24
|
context: BareImportResolverContext
|
|
25
25
|
): Promise<string> {
|
|
26
|
+
const debug = process.env["SWITE_DEBUG"] === "1";
|
|
26
27
|
|
|
27
28
|
// Extract package name outside the try/catch so fallback logic can reference it.
|
|
28
29
|
// This must stay project-agnostic: works for both scoped and unscoped packages.
|
|
@@ -56,6 +57,10 @@ export async function resolveBareImport(
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
if (debug) {
|
|
61
|
+
console.log(`[swite:resolve] Trying "${specifier}" in:`, nodeModulesLocations);
|
|
62
|
+
}
|
|
63
|
+
|
|
59
64
|
// Try each location
|
|
60
65
|
for (const nodeModulesPath of nodeModulesLocations) {
|
|
61
66
|
const testPkgDir = path.join(nodeModulesPath, pkgName);
|
|
@@ -81,12 +86,16 @@ export async function resolveBareImport(
|
|
|
81
86
|
|
|
82
87
|
if (!shouldUseCdnFallback(pkgName)) {
|
|
83
88
|
console.warn(
|
|
84
|
-
`[SWITE]
|
|
89
|
+
`[SWITE] Cannot resolve "${pkgName}"\n` +
|
|
90
|
+
` Searched:\n${nodeModulesLocations.map(p => ` - ${p}`).join('\n')}\n` +
|
|
91
|
+
` CDN fallback is disabled. To enable for a scope, set:\n` +
|
|
92
|
+
` SWITE_CDN_FALLBACK_SCOPES=@scope1,@scope2\n` +
|
|
93
|
+
` Run with --verbose for full resolution trace.`,
|
|
85
94
|
);
|
|
86
95
|
return `/node_modules/${specifier}`;
|
|
87
96
|
}
|
|
88
97
|
|
|
89
|
-
console.warn(`[SWITE] Package ${pkgName} not found
|
|
98
|
+
console.warn(`[SWITE] Package ${pkgName} not found in any local location, using CDN fallback`);
|
|
90
99
|
return `https://cdn.jsdelivr.net/npm/${specifier}/+esm`;
|
|
91
100
|
}
|
|
92
101
|
|
|
@@ -30,7 +30,10 @@ function parseAllowList(): Set<string> {
|
|
|
30
30
|
|
|
31
31
|
export function shouldUseCdnFallback(specifierOrPkg: string): boolean {
|
|
32
32
|
const scope = getScope(specifierOrPkg);
|
|
33
|
-
|
|
33
|
+
// Unscoped packages (e.g. "react") are not automatically CDN-eligible; require
|
|
34
|
+
// explicit opt-in via SWITE_CDN_FALLBACK_SCOPES to prevent accidental exfiltration
|
|
35
|
+
// of package requests for private-registry or unscoped internal packages.
|
|
36
|
+
if (!scope) return false;
|
|
34
37
|
const allow = parseAllowList();
|
|
35
38
|
return allow.has(scope);
|
|
36
39
|
}
|
|
@@ -6,14 +6,22 @@
|
|
|
6
6
|
* compiler is fixed at source this single function is the authoritative fixup.
|
|
7
7
|
* Apply it once per compilation, before passing code to the import rewriter.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* Pass `patterns` from `userConfig.compilerPathFixup.patterns` to override the
|
|
10
|
+
* defaults. Pass an empty array to disable all fixups.
|
|
11
11
|
*/
|
|
12
|
-
export function fixSwissLibPaths(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
export function fixSwissLibPaths(
|
|
13
|
+
code: string,
|
|
14
|
+
patterns?: Array<{ from: string; to: string }>,
|
|
15
|
+
): string {
|
|
16
|
+
const activePatterns = patterns ?? [
|
|
17
|
+
{ from: '/swiss-lib/packages/', to: '/swiss-packages/' },
|
|
18
|
+
{ from: '/swiss-lib/', to: '/swiss-packages/' },
|
|
19
|
+
];
|
|
20
|
+
let result = code;
|
|
21
|
+
for (const { from, to } of activePatterns) {
|
|
22
|
+
if (result.includes(from)) {
|
|
23
|
+
result = result.split(from).join(to);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
19
27
|
}
|