irgen 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +113 -0
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +312 -0
- package/dist/cli.js.map +1 -0
- package/dist/dsl/aggregator.d.ts +8 -0
- package/dist/dsl/aggregator.d.ts.map +1 -0
- package/dist/dsl/aggregator.js +64 -0
- package/dist/dsl/aggregator.js.map +1 -0
- package/dist/dsl/frontend-runtime.d.ts +486 -0
- package/dist/dsl/frontend-runtime.d.ts.map +1 -0
- package/dist/dsl/frontend-runtime.js +232 -0
- package/dist/dsl/frontend-runtime.js.map +1 -0
- package/dist/dsl/runtime.d.ts +33 -0
- package/dist/dsl/runtime.d.ts.map +1 -0
- package/dist/dsl/runtime.js +120 -0
- package/dist/dsl/runtime.js.map +1 -0
- package/dist/emit/backend/adapters.d.ts +11 -0
- package/dist/emit/backend/adapters.d.ts.map +1 -0
- package/dist/emit/backend/adapters.js +374 -0
- package/dist/emit/backend/adapters.js.map +1 -0
- package/dist/emit/backend/backend-tsmorph.d.ts +5 -0
- package/dist/emit/backend/backend-tsmorph.d.ts.map +1 -0
- package/dist/emit/backend/backend-tsmorph.js +858 -0
- package/dist/emit/backend/backend-tsmorph.js.map +1 -0
- package/dist/emit/backend/fake-backend.d.ts +2 -0
- package/dist/emit/backend/fake-backend.d.ts.map +1 -0
- package/dist/emit/backend/fake-backend.js +19 -0
- package/dist/emit/backend/fake-backend.js.map +1 -0
- package/dist/emit/backend/packaging.d.ts +3 -0
- package/dist/emit/backend/packaging.d.ts.map +1 -0
- package/dist/emit/backend/packaging.js +71 -0
- package/dist/emit/backend/packaging.js.map +1 -0
- package/dist/emit/backend/server.d.ts +4 -0
- package/dist/emit/backend/server.d.ts.map +1 -0
- package/dist/emit/backend/server.js +169 -0
- package/dist/emit/backend/server.js.map +1 -0
- package/dist/emit/cli/cli-fake.d.ts +2 -0
- package/dist/emit/cli/cli-fake.d.ts.map +1 -0
- package/dist/emit/cli/cli-fake.js +33 -0
- package/dist/emit/cli/cli-fake.js.map +1 -0
- package/dist/emit/electron/electron-shell.d.ts +3 -0
- package/dist/emit/electron/electron-shell.d.ts.map +1 -0
- package/dist/emit/electron/electron-shell.js +454 -0
- package/dist/emit/electron/electron-shell.js.map +1 -0
- package/dist/emit/engine.d.ts +14 -0
- package/dist/emit/engine.d.ts.map +1 -0
- package/dist/emit/engine.js +25 -0
- package/dist/emit/engine.js.map +1 -0
- package/dist/emit/format.d.ts +2 -0
- package/dist/emit/format.d.ts.map +1 -0
- package/dist/emit/format.js +23 -0
- package/dist/emit/format.js.map +1 -0
- package/dist/emit/frontend/frontend-react.d.ts +4 -0
- package/dist/emit/frontend/frontend-react.d.ts.map +1 -0
- package/dist/emit/frontend/frontend-react.js +2021 -0
- package/dist/emit/frontend/frontend-react.js.map +1 -0
- package/dist/emit/frontend/registry.d.ts +20 -0
- package/dist/emit/frontend/registry.d.ts.map +1 -0
- package/dist/emit/frontend/registry.js +46 -0
- package/dist/emit/frontend/registry.js.map +1 -0
- package/dist/emit/frontend/runtime-emitter.d.ts +4 -0
- package/dist/emit/frontend/runtime-emitter.d.ts.map +1 -0
- package/dist/emit/frontend/runtime-emitter.js +435 -0
- package/dist/emit/frontend/runtime-emitter.js.map +1 -0
- package/dist/emit/frontend/runtime-template.d.ts +28 -0
- package/dist/emit/frontend/runtime-template.d.ts.map +1 -0
- package/dist/emit/frontend/runtime-template.js +218 -0
- package/dist/emit/frontend/runtime-template.js.map +1 -0
- package/dist/emit/frontend/ssg.d.ts +8 -0
- package/dist/emit/frontend/ssg.d.ts.map +1 -0
- package/dist/emit/frontend/ssg.js +219 -0
- package/dist/emit/frontend/ssg.js.map +1 -0
- package/dist/emit/registry.d.ts +17 -0
- package/dist/emit/registry.d.ts.map +1 -0
- package/dist/emit/registry.js +38 -0
- package/dist/emit/registry.js.map +1 -0
- package/dist/emit/static-site/css.d.ts +5 -0
- package/dist/emit/static-site/css.d.ts.map +1 -0
- package/dist/emit/static-site/css.js +872 -0
- package/dist/emit/static-site/css.js.map +1 -0
- package/dist/emit/static-site/enhancements.d.ts +11 -0
- package/dist/emit/static-site/enhancements.d.ts.map +1 -0
- package/dist/emit/static-site/enhancements.js +266 -0
- package/dist/emit/static-site/enhancements.js.map +1 -0
- package/dist/emit/static-site/static-site-html.d.ts +3 -0
- package/dist/emit/static-site/static-site-html.d.ts.map +1 -0
- package/dist/emit/static-site/static-site-html.js +1172 -0
- package/dist/emit/static-site/static-site-html.js.map +1 -0
- package/dist/emit/utils/sdk.d.ts +15 -0
- package/dist/emit/utils/sdk.d.ts.map +1 -0
- package/dist/emit/utils/sdk.js +34 -0
- package/dist/emit/utils/sdk.js.map +1 -0
- package/dist/extensions/context.d.ts +23 -0
- package/dist/extensions/context.d.ts.map +1 -0
- package/dist/extensions/context.js +43 -0
- package/dist/extensions/context.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +135 -0
- package/dist/index.js.map +1 -0
- package/dist/ir/decl/backend.raw.schema.d.ts +128 -0
- package/dist/ir/decl/backend.raw.schema.d.ts.map +1 -0
- package/dist/ir/decl/backend.raw.schema.js +24 -0
- package/dist/ir/decl/backend.raw.schema.js.map +1 -0
- package/dist/ir/decl/bundle.d.ts +15 -0
- package/dist/ir/decl/bundle.d.ts.map +1 -0
- package/dist/ir/decl/bundle.js +8 -0
- package/dist/ir/decl/bundle.js.map +1 -0
- package/dist/ir/decl/cli.raw.schema.d.ts +133 -0
- package/dist/ir/decl/cli.raw.schema.d.ts.map +1 -0
- package/dist/ir/decl/cli.raw.schema.js +20 -0
- package/dist/ir/decl/cli.raw.schema.js.map +1 -0
- package/dist/ir/decl/frontend.raw.schema.d.ts +6631 -0
- package/dist/ir/decl/frontend.raw.schema.d.ts.map +1 -0
- package/dist/ir/decl/frontend.raw.schema.js +272 -0
- package/dist/ir/decl/frontend.raw.schema.js.map +1 -0
- package/dist/ir/decl/index.d.ts +6 -0
- package/dist/ir/decl/index.d.ts.map +1 -0
- package/dist/ir/decl/index.js +6 -0
- package/dist/ir/decl/index.js.map +1 -0
- package/dist/ir/decl/normalize.schema.d.ts +9154 -0
- package/dist/ir/decl/normalize.schema.d.ts.map +1 -0
- package/dist/ir/decl/normalize.schema.js +71 -0
- package/dist/ir/decl/normalize.schema.js.map +1 -0
- package/dist/ir/domain/backend.d.ts +19 -0
- package/dist/ir/domain/backend.d.ts.map +1 -0
- package/dist/ir/domain/backend.js +3 -0
- package/dist/ir/domain/backend.js.map +1 -0
- package/dist/ir/domain/cli.d.ts +18 -0
- package/dist/ir/domain/cli.d.ts.map +1 -0
- package/dist/ir/domain/cli.js +2 -0
- package/dist/ir/domain/cli.js.map +1 -0
- package/dist/ir/domain/frontend/index.d.ts +190 -0
- package/dist/ir/domain/frontend/index.d.ts.map +1 -0
- package/dist/ir/domain/frontend/index.js +2 -0
- package/dist/ir/domain/frontend/index.js.map +1 -0
- package/dist/ir/domain/frontend.d.ts +2 -0
- package/dist/ir/domain/frontend.d.ts.map +1 -0
- package/dist/ir/domain/frontend.js +3 -0
- package/dist/ir/domain/frontend.js.map +1 -0
- package/dist/ir/frontend-contract.d.ts +187 -0
- package/dist/ir/frontend-contract.d.ts.map +1 -0
- package/dist/ir/frontend-contract.js +6 -0
- package/dist/ir/frontend-contract.js.map +1 -0
- package/dist/ir/target/backend.d.ts +11 -0
- package/dist/ir/target/backend.d.ts.map +1 -0
- package/dist/ir/target/backend.js +2 -0
- package/dist/ir/target/backend.js.map +1 -0
- package/dist/ir/target/backend.policy.d.ts +896 -0
- package/dist/ir/target/backend.policy.d.ts.map +1 -0
- package/dist/ir/target/backend.policy.js +106 -0
- package/dist/ir/target/backend.policy.js.map +1 -0
- package/dist/ir/target/cli.d.ts +3 -0
- package/dist/ir/target/cli.d.ts.map +1 -0
- package/dist/ir/target/cli.js +2 -0
- package/dist/ir/target/cli.js.map +1 -0
- package/dist/ir/target/electron.d.ts +99 -0
- package/dist/ir/target/electron.d.ts.map +1 -0
- package/dist/ir/target/electron.js +2 -0
- package/dist/ir/target/electron.js.map +1 -0
- package/dist/ir/target/electron.policy.d.ts +7015 -0
- package/dist/ir/target/electron.policy.d.ts.map +1 -0
- package/dist/ir/target/electron.policy.js +119 -0
- package/dist/ir/target/electron.policy.js.map +1 -0
- package/dist/ir/target/frontend.d.ts +12 -0
- package/dist/ir/target/frontend.d.ts.map +1 -0
- package/dist/ir/target/frontend.js +2 -0
- package/dist/ir/target/frontend.js.map +1 -0
- package/dist/ir/target/frontend.policy.d.ts +268 -0
- package/dist/ir/target/frontend.policy.d.ts.map +1 -0
- package/dist/ir/target/frontend.policy.js +33 -0
- package/dist/ir/target/frontend.policy.js.map +1 -0
- package/dist/ir/target/index.d.ts +6 -0
- package/dist/ir/target/index.d.ts.map +1 -0
- package/dist/ir/target/index.js +6 -0
- package/dist/ir/target/index.js.map +1 -0
- package/dist/ir/target/static-site.d.ts +18 -0
- package/dist/ir/target/static-site.d.ts.map +1 -0
- package/dist/ir/target/static-site.js +2 -0
- package/dist/ir/target/static-site.js.map +1 -0
- package/dist/ir/target/static-site.policy.d.ts +2911 -0
- package/dist/ir/target/static-site.policy.d.ts.map +1 -0
- package/dist/ir/target/static-site.policy.js +127 -0
- package/dist/ir/target/static-site.policy.js.map +1 -0
- package/dist/lowering/backend.d.ts +4 -0
- package/dist/lowering/backend.d.ts.map +1 -0
- package/dist/lowering/backend.js +57 -0
- package/dist/lowering/backend.js.map +1 -0
- package/dist/lowering/cli.d.ts +4 -0
- package/dist/lowering/cli.d.ts.map +1 -0
- package/dist/lowering/cli.js +22 -0
- package/dist/lowering/cli.js.map +1 -0
- package/dist/lowering/engine.d.ts +18 -0
- package/dist/lowering/engine.d.ts.map +1 -0
- package/dist/lowering/engine.js +47 -0
- package/dist/lowering/engine.js.map +1 -0
- package/dist/lowering/frontend.d.ts +9 -0
- package/dist/lowering/frontend.d.ts.map +1 -0
- package/dist/lowering/frontend.js +246 -0
- package/dist/lowering/frontend.js.map +1 -0
- package/dist/lowering/targets/to-backend.d.ts +9 -0
- package/dist/lowering/targets/to-backend.d.ts.map +1 -0
- package/dist/lowering/targets/to-backend.js +55 -0
- package/dist/lowering/targets/to-backend.js.map +1 -0
- package/dist/lowering/targets/to-cli.d.ts +4 -0
- package/dist/lowering/targets/to-cli.d.ts.map +1 -0
- package/dist/lowering/targets/to-cli.js +11 -0
- package/dist/lowering/targets/to-cli.js.map +1 -0
- package/dist/lowering/targets/to-electron.d.ts +30 -0
- package/dist/lowering/targets/to-electron.d.ts.map +1 -0
- package/dist/lowering/targets/to-electron.js +87 -0
- package/dist/lowering/targets/to-electron.js.map +1 -0
- package/dist/lowering/targets/to-frontend.d.ts +4 -0
- package/dist/lowering/targets/to-frontend.d.ts.map +1 -0
- package/dist/lowering/targets/to-frontend.js +30 -0
- package/dist/lowering/targets/to-frontend.js.map +1 -0
- package/dist/lowering/targets/to-static-site.d.ts +16 -0
- package/dist/lowering/targets/to-static-site.d.ts.map +1 -0
- package/dist/lowering/targets/to-static-site.js +30 -0
- package/dist/lowering/targets/to-static-site.js.map +1 -0
- package/dist/mappers/index.d.ts +12 -0
- package/dist/mappers/index.d.ts.map +1 -0
- package/dist/mappers/index.js +60 -0
- package/dist/mappers/index.js.map +1 -0
- package/dist/types/extension.d.ts +3 -0
- package/dist/types/extension.d.ts.map +1 -0
- package/dist/types/extension.js +2 -0
- package/dist/types/extension.js.map +1 -0
- package/dist/utils/array.d.ts +2 -0
- package/dist/utils/array.d.ts.map +1 -0
- package/dist/utils/array.js +4 -0
- package/dist/utils/array.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/string.d.ts +13 -0
- package/dist/utils/string.d.ts.map +1 -0
- package/dist/utils/string.js +56 -0
- package/dist/utils/string.js.map +1 -0
- package/package.json +112 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { emitterEngine } from "../engine.js";
|
|
4
|
+
import { registerTargetEmitter } from "../registry.js";
|
|
5
|
+
import { uniq } from "../../utils/array.js";
|
|
6
|
+
function ensureDir(p) {
|
|
7
|
+
fs.mkdirSync(p, { recursive: true });
|
|
8
|
+
}
|
|
9
|
+
function emitMain(outDir, ir) {
|
|
10
|
+
const whitelist = ir.policies.electron.ipc?.whitelist ?? ir.policies.electron.security.ipcWhitelist ?? [];
|
|
11
|
+
const devUrl = ir.policies.electron.loading?.devUrl ?? "http://localhost:3000";
|
|
12
|
+
const prodIndex = ir.policies.electron.loading?.prodIndex ?? "../frontend/dist/index.html";
|
|
13
|
+
const logging = ir.policies.electron.reliability?.logging ?? { enabled: true, level: "info", fileMaxSizeMB: 10, console: true };
|
|
14
|
+
const performance = ir.policies.electron.reliability?.performance ?? { disableBackgroundThrottling: true };
|
|
15
|
+
const crashReporting = ir.policies.electron.reliability?.crashReporting ?? { enabled: false };
|
|
16
|
+
const autoUpdatePolicy = ir.policies.electron.autoUpdate ?? {};
|
|
17
|
+
const autoUpdateRetry = { retryOnFail: autoUpdatePolicy.retryOnFail ?? true, retryDelayMs: autoUpdatePolicy.retryDelayMs ?? 300000 };
|
|
18
|
+
const sessionPolicy = ir.policies.electron.reliability?.session ?? { restoreWindowBounds: true, windowStateFile: "window-state.json", saveOnClose: true };
|
|
19
|
+
const mainTs = `
|
|
20
|
+
import { app, BrowserWindow, ipcMain, dialog, crashReporter } from "electron";
|
|
21
|
+
import path from "node:path";
|
|
22
|
+
import { registerCustomHandlers } from "./ipc-handlers.js";
|
|
23
|
+
import { pathToFileURL } from "node:url";
|
|
24
|
+
import log from "electron-log";
|
|
25
|
+
import fs from "node:fs";
|
|
26
|
+
import { autoUpdater } from "electron-updater";
|
|
27
|
+
|
|
28
|
+
const PROD_INDEX = path.join(__dirname, ${JSON.stringify(prodIndex)});
|
|
29
|
+
const PROD_URL = pathToFileURL(PROD_INDEX).href;
|
|
30
|
+
|
|
31
|
+
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = "true";
|
|
32
|
+
|
|
33
|
+
let mainWindow: BrowserWindow | null = null;
|
|
34
|
+
const STATE_FILE = path.join(app.getPath("userData"), ${JSON.stringify(sessionPolicy.windowStateFile ?? "window-state.json")});
|
|
35
|
+
const sendStatus = (status: string, payload?: unknown) => {
|
|
36
|
+
try {
|
|
37
|
+
mainWindow?.webContents.send("auto-update-status", { status, payload });
|
|
38
|
+
} catch (e) {
|
|
39
|
+
log.warn("Failed to send auto-update status", status, e);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
function loadWindowState() {
|
|
44
|
+
try {
|
|
45
|
+
const raw = fs.readFileSync(STATE_FILE, "utf-8");
|
|
46
|
+
const parsed = JSON.parse(raw);
|
|
47
|
+
if (parsed && typeof parsed === "object" && parsed.width && parsed.height) {
|
|
48
|
+
return parsed;
|
|
49
|
+
}
|
|
50
|
+
} catch (e) {
|
|
51
|
+
// ignore
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function saveWindowState(win: BrowserWindow) {
|
|
57
|
+
if (!${sessionPolicy.saveOnClose ?? true}) return;
|
|
58
|
+
try {
|
|
59
|
+
const bounds = win.getBounds();
|
|
60
|
+
fs.mkdirSync(path.dirname(STATE_FILE), { recursive: true });
|
|
61
|
+
fs.writeFileSync(STATE_FILE, JSON.stringify(bounds), "utf-8");
|
|
62
|
+
} catch (e) {
|
|
63
|
+
log.warn("Failed to save window state", e);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function createWindow() {
|
|
68
|
+
const restored = ${sessionPolicy.restoreWindowBounds ?? true} ? loadWindowState() : null;
|
|
69
|
+
const win = new BrowserWindow({
|
|
70
|
+
width: restored?.width ?? ${ir.policies.electron.window.width},
|
|
71
|
+
height: restored?.height ?? ${ir.policies.electron.window.height},
|
|
72
|
+
resizable: ${ir.policies.electron.window.resizable},
|
|
73
|
+
fullscreen: ${ir.policies.electron.window.fullscreen ?? false},
|
|
74
|
+
webPreferences: {
|
|
75
|
+
preload: path.join(__dirname, "preload.js"),
|
|
76
|
+
contextIsolation: ${ir.policies.electron.security.contextIsolation},
|
|
77
|
+
sandbox: ${ir.policies.electron.security.sandbox},
|
|
78
|
+
nodeIntegration: false,
|
|
79
|
+
backgroundThrottling: ${performance.disableBackgroundThrottling === false ? "true" : "false"},
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const startUrl = process.env.ELECTRON_START_URL || ${JSON.stringify(devUrl)} || PROD_URL;
|
|
84
|
+
win.webContents.setWindowOpenHandler(() => ({ action: "deny" }));
|
|
85
|
+
win.webContents.on("will-navigate", (e, url) => {
|
|
86
|
+
const allow = url.startsWith(startUrl) || url.startsWith("file://");
|
|
87
|
+
if (!allow) {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Dev vs prod: if ELECTRON_START_URL not set, prefer file:// dist
|
|
93
|
+
const resolvedStartUrl = process.env.ELECTRON_START_URL ? startUrl : PROD_URL;
|
|
94
|
+
win.loadURL(resolvedStartUrl);
|
|
95
|
+
|
|
96
|
+
const csp = ${JSON.stringify(ir.policies.electron.security.csp ?? "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; base-uri 'self'; form-action 'self'")};
|
|
97
|
+
const { session } = win.webContents;
|
|
98
|
+
session.webRequest.onHeadersReceived((details, callback) => {
|
|
99
|
+
const headers = {
|
|
100
|
+
...details.responseHeaders,
|
|
101
|
+
"Content-Security-Policy": [csp],
|
|
102
|
+
};
|
|
103
|
+
callback({ responseHeaders: headers });
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
win.webContents.openDevTools({ mode: ${ir.policies.electron.window.devTools ? '"detach"' : '"undocked"'} });
|
|
107
|
+
win.on("closed", () => { mainWindow = null; });
|
|
108
|
+
win.on("close", () => saveWindowState(win));
|
|
109
|
+
mainWindow = win;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const SINGLE_INSTANCE = ${ir.policies.electron.reliability?.singleInstance ?? true};
|
|
113
|
+
|
|
114
|
+
if (${logging.enabled ?? true}) {
|
|
115
|
+
log.transports.file.level = ${JSON.stringify(logging.level ?? "info")};
|
|
116
|
+
log.transports.file.maxSize = ${(logging.fileMaxSizeMB ?? 10) * 1024 * 1024};
|
|
117
|
+
log.transports.console.level = ${logging.console ? JSON.stringify(logging.level ?? "info") : JSON.stringify("error")};
|
|
118
|
+
log.info("Logger initialized");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (${crashReporting.enabled ?? false}) {
|
|
122
|
+
const provider: string = ${JSON.stringify(crashReporting.provider ?? "electron")};
|
|
123
|
+
if (provider === "electron") {
|
|
124
|
+
crashReporter.start({
|
|
125
|
+
productName: ${JSON.stringify(crashReporting.productName ?? ir.policies.electron.packaging.productName ?? "electron-app")},
|
|
126
|
+
companyName: ${JSON.stringify(crashReporting.companyName ?? "ExampleCo")},
|
|
127
|
+
submitURL: ${JSON.stringify(crashReporting.submitURL ?? "")},
|
|
128
|
+
uploadToServer: Boolean(${crashReporting.submitURL ? "true" : "false"}),
|
|
129
|
+
compress: true,
|
|
130
|
+
extra: { environment: ${JSON.stringify(crashReporting.environment ?? "development")} },
|
|
131
|
+
});
|
|
132
|
+
log.info("Crash reporter (electron) initialized");
|
|
133
|
+
} else if (provider === "sentry") {
|
|
134
|
+
log.warn("Crash reporter (sentry) requested but SDK not wired; add @sentry/electron and init here.");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const AUTO_UPDATE_ENABLED = ${ir.policies.electron.autoUpdate?.enabled ?? false};
|
|
139
|
+
if (AUTO_UPDATE_ENABLED) {
|
|
140
|
+
const feedURL = ${JSON.stringify(ir.policies.electron.autoUpdate?.url ?? "")};
|
|
141
|
+
autoUpdater.autoDownload = true;
|
|
142
|
+
autoUpdater.allowPrerelease = Boolean(${ir.policies.electron.autoUpdate?.allowPrerelease ?? false});
|
|
143
|
+
if (feedURL) {
|
|
144
|
+
autoUpdater.setFeedURL({
|
|
145
|
+
provider: ${JSON.stringify(ir.policies.electron.autoUpdate?.provider ?? "generic")},
|
|
146
|
+
url: feedURL,
|
|
147
|
+
channel: ${JSON.stringify(ir.policies.electron.autoUpdate?.channel ?? "latest")},
|
|
148
|
+
requestHeaders: ${JSON.stringify(ir.policies.electron.autoUpdate?.requestHeaders ?? {})},
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
log.info("Auto-updater configured", { feedURL });
|
|
152
|
+
|
|
153
|
+
autoUpdater.on("error", (err) => {
|
|
154
|
+
log.error("Auto-update error", err);
|
|
155
|
+
sendStatus("error", err?.message ?? String(err));
|
|
156
|
+
if (${autoUpdateRetry.retryOnFail}) {
|
|
157
|
+
const delay = ${autoUpdateRetry.retryDelayMs ?? 300000};
|
|
158
|
+
log.warn(\`Retrying update check in \${delay} ms\`);
|
|
159
|
+
setTimeout(() => {
|
|
160
|
+
sendStatus("retrying", { delay });
|
|
161
|
+
autoUpdater.checkForUpdatesAndNotify().catch(e => {
|
|
162
|
+
log.error("Auto-update retry failed", e);
|
|
163
|
+
});
|
|
164
|
+
}, delay);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
autoUpdater.on("checking-for-update", () => {
|
|
168
|
+
log.info("Checking for updates...");
|
|
169
|
+
sendStatus("checking");
|
|
170
|
+
});
|
|
171
|
+
autoUpdater.on("update-available", info => {
|
|
172
|
+
log.info("Update available", info);
|
|
173
|
+
sendStatus("available", info);
|
|
174
|
+
});
|
|
175
|
+
autoUpdater.on("update-not-available", info => {
|
|
176
|
+
log.info("No update", info);
|
|
177
|
+
sendStatus("not-available", info);
|
|
178
|
+
});
|
|
179
|
+
autoUpdater.on("download-progress", progress => {
|
|
180
|
+
log.info("Update download progress", progress);
|
|
181
|
+
sendStatus("downloading", progress);
|
|
182
|
+
});
|
|
183
|
+
autoUpdater.on("update-downloaded", info => {
|
|
184
|
+
log.info("Update downloaded; will quit and install");
|
|
185
|
+
sendStatus("downloaded", info);
|
|
186
|
+
autoUpdater.quitAndInstall();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
app.whenReady().then(() => autoUpdater.checkForUpdatesAndNotify());
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (SINGLE_INSTANCE) {
|
|
193
|
+
const gotLock = app.requestSingleInstanceLock();
|
|
194
|
+
if (!gotLock) {
|
|
195
|
+
app.quit();
|
|
196
|
+
process.exit(0);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
app.on("second-instance", () => {
|
|
200
|
+
if (mainWindow) {
|
|
201
|
+
if (mainWindow.isMinimized()) mainWindow.restore();
|
|
202
|
+
mainWindow.focus();
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
app.whenReady().then(() => {
|
|
208
|
+
createWindow();
|
|
209
|
+
app.on("activate", () => {
|
|
210
|
+
if (BrowserWindow.getAllWindows().length === 0) createWindow();
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
registerCustomHandlers(ipcMain);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
app.on("window-all-closed", () => {
|
|
217
|
+
if (process.platform !== "darwin") app.quit();
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
app.on("will-quit", () => {
|
|
221
|
+
// Guard IPC handlers
|
|
222
|
+
ipcMain.removeHandler("ping");
|
|
223
|
+
ipcMain.removeHandler("open-file-dialog");
|
|
224
|
+
// custom handlers are registered in registerCustomHandlers; simplest is to rely on electron cleanup
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
ipcMain.handle("ping", () => "pong");
|
|
228
|
+
|
|
229
|
+
ipcMain.handle("open-file-dialog", async () => {
|
|
230
|
+
const res = await dialog.showOpenDialog({ properties: ["openFile"] });
|
|
231
|
+
if (res.canceled) return null;
|
|
232
|
+
return res.filePaths[0];
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// generated whitelist for preload: ${whitelist.join(", ")}
|
|
236
|
+
`.trim();
|
|
237
|
+
fs.writeFileSync(path.join(outDir, "main.ts"), mainTs, "utf-8");
|
|
238
|
+
}
|
|
239
|
+
function emitPreload(outDir, ir) {
|
|
240
|
+
const whitelist = uniq([
|
|
241
|
+
...(ir.policies.electron.security.ipcWhitelist ?? []),
|
|
242
|
+
...(ir.policies.electron.ipc?.whitelist ?? []),
|
|
243
|
+
]);
|
|
244
|
+
const preload = `
|
|
245
|
+
import { contextBridge, ipcRenderer } from "electron";
|
|
246
|
+
import log from "electron-log/renderer";
|
|
247
|
+
|
|
248
|
+
const whitelist = ${JSON.stringify(whitelist)};
|
|
249
|
+
|
|
250
|
+
// Simple CSP helper: renderer should set a CSP meta tag or header; we reflect policy here for clarity.
|
|
251
|
+
const CONTENT_SECURITY_POLICY = ${JSON.stringify("default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; base-uri 'self'; form-action 'self'")};
|
|
252
|
+
|
|
253
|
+
contextBridge.exposeInMainWorld("api", {
|
|
254
|
+
invoke: (channel: string, ...args: unknown[]) => {
|
|
255
|
+
if (!whitelist.includes(channel)) throw new Error("IPC channel not allowed");
|
|
256
|
+
return ipcRenderer.invoke(channel, ...args);
|
|
257
|
+
},
|
|
258
|
+
csp: CONTENT_SECURITY_POLICY,
|
|
259
|
+
log: (level: keyof typeof log | "info" | "warn" | "error", ...args: unknown[]) => {
|
|
260
|
+
const fn = (log as any)[level] ?? log.info;
|
|
261
|
+
fn(...args);
|
|
262
|
+
},
|
|
263
|
+
onUpdateStatus: (cb: (payload: { status: string; payload?: unknown }) => void) => {
|
|
264
|
+
const handler = (_event: unknown, data: any) => cb(data);
|
|
265
|
+
ipcRenderer.on("auto-update-status", handler);
|
|
266
|
+
return () => ipcRenderer.removeListener("auto-update-status", handler);
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// Patch global eval/Function to reduce accidental use
|
|
271
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
272
|
+
(globalThis as any).eval = undefined;
|
|
273
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
274
|
+
(globalThis as any).Function = undefined;
|
|
275
|
+
`.trim();
|
|
276
|
+
fs.writeFileSync(path.join(outDir, "preload.ts"), preload, "utf-8");
|
|
277
|
+
}
|
|
278
|
+
function emitPackageJson(outDir, ir) {
|
|
279
|
+
const pkg = {
|
|
280
|
+
name: ir.policies.electron.packaging.productName?.toLowerCase() || "electron-app",
|
|
281
|
+
version: "0.1.0",
|
|
282
|
+
private: true,
|
|
283
|
+
main: "dist/main.js",
|
|
284
|
+
scripts: {
|
|
285
|
+
start: "electron .",
|
|
286
|
+
build: "tsc -p tsconfig.json",
|
|
287
|
+
"start:frontend": "cd ../frontend && npm install && npm run dev",
|
|
288
|
+
"start:electron:dev": "cross-env ELECTRON_START_URL=http://localhost:5173 electron .",
|
|
289
|
+
"start:electron:file": "npm run build && electron ./scripts/load-file.js",
|
|
290
|
+
"package:electron": "npm run build && electron-builder -c electron-builder.config.json",
|
|
291
|
+
},
|
|
292
|
+
devDependencies: {
|
|
293
|
+
electron: "^29.0.0",
|
|
294
|
+
typescript: "^5.6.3",
|
|
295
|
+
"cross-env": "^7.0.3",
|
|
296
|
+
"@types/node": "^22.10.2",
|
|
297
|
+
"electron-builder": "^25.1.8",
|
|
298
|
+
},
|
|
299
|
+
dependencies: {
|
|
300
|
+
"electron-log": "^5.1.2",
|
|
301
|
+
"electron-updater": "^6.3.7",
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
ensureDir(outDir);
|
|
305
|
+
fs.writeFileSync(path.join(outDir, "package.json"), JSON.stringify(pkg, null, 2), "utf-8");
|
|
306
|
+
}
|
|
307
|
+
function emitElectronBuilderConfig(outDir, ir) {
|
|
308
|
+
const packaging = ir.policies.electron.packaging ?? {};
|
|
309
|
+
const autoUpdate = ir.policies.electron.autoUpdate ?? {};
|
|
310
|
+
if (packaging.tool && packaging.tool !== "electron-builder")
|
|
311
|
+
return;
|
|
312
|
+
const config = {
|
|
313
|
+
appId: packaging.appId,
|
|
314
|
+
productName: packaging.productName,
|
|
315
|
+
artifactName: packaging.artifactName ?? "${productName}-${version}-${os}-${arch}",
|
|
316
|
+
directories: {
|
|
317
|
+
output: packaging.outputDir ?? "release",
|
|
318
|
+
buildResources: packaging.buildResources ?? "build",
|
|
319
|
+
},
|
|
320
|
+
files: ["dist/**", "frontend/dist/**", "package.json"],
|
|
321
|
+
asar: packaging.asar ?? true,
|
|
322
|
+
};
|
|
323
|
+
if (packaging.icon)
|
|
324
|
+
config.icon = packaging.icon;
|
|
325
|
+
if (packaging.extraFiles)
|
|
326
|
+
config.extraFiles = packaging.extraFiles;
|
|
327
|
+
if (packaging.extraResources)
|
|
328
|
+
config.extraResources = packaging.extraResources;
|
|
329
|
+
if (packaging.mac)
|
|
330
|
+
config.mac = packaging.mac;
|
|
331
|
+
if (packaging.win)
|
|
332
|
+
config.win = packaging.win;
|
|
333
|
+
if (packaging.linux)
|
|
334
|
+
config.linux = packaging.linux;
|
|
335
|
+
if (autoUpdate.enabled) {
|
|
336
|
+
// electron-builder expects publish config; allow direct override or simple provider/url/channel
|
|
337
|
+
if (autoUpdate.publish) {
|
|
338
|
+
config.publish = autoUpdate.publish;
|
|
339
|
+
}
|
|
340
|
+
else if (autoUpdate.provider && autoUpdate.url) {
|
|
341
|
+
config.publish = [{ provider: autoUpdate.provider, url: autoUpdate.url, channel: autoUpdate.channel ?? "latest" }];
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
fs.writeFileSync(path.join(outDir, "electron-builder.config.json"), JSON.stringify(config, null, 2), "utf-8");
|
|
345
|
+
}
|
|
346
|
+
function emitTsConfig(outDir) {
|
|
347
|
+
const tsconfig = {
|
|
348
|
+
compilerOptions: {
|
|
349
|
+
module: "commonjs",
|
|
350
|
+
target: "es2022",
|
|
351
|
+
outDir: "dist",
|
|
352
|
+
strict: true,
|
|
353
|
+
esModuleInterop: true,
|
|
354
|
+
skipLibCheck: true,
|
|
355
|
+
moduleResolution: "node",
|
|
356
|
+
types: ["node", "electron"],
|
|
357
|
+
},
|
|
358
|
+
include: ["*.ts"],
|
|
359
|
+
};
|
|
360
|
+
fs.writeFileSync(path.join(outDir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2), "utf-8");
|
|
361
|
+
}
|
|
362
|
+
function emitLoadFileScript(outDir) {
|
|
363
|
+
const script = `
|
|
364
|
+
const { app, BrowserWindow, ipcMain, dialog } = require("electron");
|
|
365
|
+
const path = require("path");
|
|
366
|
+
const fs = require("fs");
|
|
367
|
+
const { registerCustomHandlers } = require("../dist/ipc-handlers.js");
|
|
368
|
+
|
|
369
|
+
function createWindow() {
|
|
370
|
+
const win = new BrowserWindow({
|
|
371
|
+
width: 1280,
|
|
372
|
+
height: 800,
|
|
373
|
+
webPreferences: {
|
|
374
|
+
preload: path.join(__dirname, "../dist/preload.js"),
|
|
375
|
+
contextIsolation: true,
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
const index = path.join(__dirname, "../../frontend/dist/index.html");
|
|
380
|
+
if (!fs.existsSync(index)) {
|
|
381
|
+
console.error("frontend/dist/index.html not found. Build frontend first (npm run build in ../frontend).");
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
win.loadFile(index);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
ipcMain.handle("open-file-dialog", async () => {
|
|
388
|
+
const res = await dialog.showOpenDialog({ properties: ["openFile"] });
|
|
389
|
+
if (res.canceled) return null;
|
|
390
|
+
return res.filePaths[0];
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
registerCustomHandlers(ipcMain);
|
|
394
|
+
|
|
395
|
+
if (app && app.whenReady) {
|
|
396
|
+
app.whenReady().then(createWindow);
|
|
397
|
+
} else {
|
|
398
|
+
console.error("Electron app context not available; ensure this script is run via electron .");
|
|
399
|
+
}
|
|
400
|
+
`.trim();
|
|
401
|
+
const scriptsDir = path.join(outDir, "scripts");
|
|
402
|
+
ensureDir(scriptsDir);
|
|
403
|
+
fs.writeFileSync(path.join(scriptsDir, "load-file.js"), script, "utf-8");
|
|
404
|
+
}
|
|
405
|
+
export function emitElectronShell(ir, outDir) {
|
|
406
|
+
ensureDir(outDir);
|
|
407
|
+
emitMain(outDir, ir);
|
|
408
|
+
emitPreload(outDir, ir);
|
|
409
|
+
emitIpcHandlers(outDir, ir);
|
|
410
|
+
emitPackageJson(outDir, ir);
|
|
411
|
+
emitElectronBuilderConfig(outDir, ir);
|
|
412
|
+
emitTsConfig(outDir);
|
|
413
|
+
emitLoadFileScript(outDir);
|
|
414
|
+
}
|
|
415
|
+
try {
|
|
416
|
+
emitterEngine.registerEmitter("electron-shell", async (ir, outDir) => {
|
|
417
|
+
emitElectronShell(ir, outDir);
|
|
418
|
+
}, { force: true });
|
|
419
|
+
}
|
|
420
|
+
catch (e) {
|
|
421
|
+
// ignore double registration
|
|
422
|
+
}
|
|
423
|
+
try {
|
|
424
|
+
registerTargetEmitter("electron", "electron-shell", { force: true });
|
|
425
|
+
}
|
|
426
|
+
catch (e) {
|
|
427
|
+
// ignore
|
|
428
|
+
}
|
|
429
|
+
function emitIpcHandlers(outDir, ir) {
|
|
430
|
+
const handlers = ir.policies.electron.ipc?.handlers ?? [];
|
|
431
|
+
const defaultHandled = new Set(["ping", "open-file-dialog"]);
|
|
432
|
+
const filtered = handlers.filter(h => !defaultHandled.has(h.channel));
|
|
433
|
+
const body = filtered.length
|
|
434
|
+
? filtered.map(h => `
|
|
435
|
+
// ${h.description ?? "TODO implement handler"}
|
|
436
|
+
ipcMain.handle("${h.channel}", async (_event, ...args) => {
|
|
437
|
+
// TODO: replace with real logic
|
|
438
|
+
console.log("IPC '${h.channel}' called with", args);
|
|
439
|
+
return null;
|
|
440
|
+
});
|
|
441
|
+
`).join("\n")
|
|
442
|
+
: `
|
|
443
|
+
// Add custom IPC handlers here. Example:
|
|
444
|
+
// ipcMain.handle("my-channel", async (_event, ...args) => { return "ok"; });
|
|
445
|
+
`;
|
|
446
|
+
const content = `
|
|
447
|
+
import { IpcMain } from "electron";
|
|
448
|
+
|
|
449
|
+
export function registerCustomHandlers(ipcMain: IpcMain) {${body}
|
|
450
|
+
}
|
|
451
|
+
`.trim();
|
|
452
|
+
fs.writeFileSync(path.join(outDir, "ipc-handlers.ts"), content, "utf-8");
|
|
453
|
+
}
|
|
454
|
+
//# sourceMappingURL=electron-shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"electron-shell.js","sourceRoot":"","sources":["../../../src/emit/electron/electron-shell.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type EmitterFn = (ir: any, outDir: string, options?: any) => Promise<void> | void;
|
|
2
|
+
declare class EmitterEngine {
|
|
3
|
+
private emitters;
|
|
4
|
+
registerEmitter(name: string, fn: EmitterFn, options?: {
|
|
5
|
+
force?: boolean;
|
|
6
|
+
}): void;
|
|
7
|
+
unregisterEmitter(name: string): void;
|
|
8
|
+
getEmitter(name: string): EmitterFn | undefined;
|
|
9
|
+
listEmitters(): string[];
|
|
10
|
+
runEmitter(name: string, ir: any, outDir: string, options?: any): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare const emitterEngine: EmitterEngine;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/emit/engine.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzF,cAAM,aAAa;IACjB,OAAO,CAAC,QAAQ,CAAgC;IAEhD,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;IAK1E,iBAAiB,CAAC,IAAI,EAAE,MAAM;IAI9B,UAAU,CAAC,IAAI,EAAE,MAAM;IAIvB,YAAY;IAIN,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG;CAKtE;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class EmitterEngine {
|
|
2
|
+
emitters = new Map();
|
|
3
|
+
registerEmitter(name, fn, options) {
|
|
4
|
+
if (this.emitters.has(name) && !options?.force)
|
|
5
|
+
throw new Error(`emitter already registered: ${name}`);
|
|
6
|
+
this.emitters.set(name, fn);
|
|
7
|
+
}
|
|
8
|
+
unregisterEmitter(name) {
|
|
9
|
+
this.emitters.delete(name);
|
|
10
|
+
}
|
|
11
|
+
getEmitter(name) {
|
|
12
|
+
return this.emitters.get(name);
|
|
13
|
+
}
|
|
14
|
+
listEmitters() {
|
|
15
|
+
return Array.from(this.emitters.keys());
|
|
16
|
+
}
|
|
17
|
+
async runEmitter(name, ir, outDir, options) {
|
|
18
|
+
const fn = this.emitters.get(name);
|
|
19
|
+
if (!fn)
|
|
20
|
+
throw new Error(`emitter not registered: ${name}`);
|
|
21
|
+
return await fn(ir, outDir, options);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export const emitterEngine = new EmitterEngine();
|
|
25
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/emit/engine.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa;IACT,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;IAEhD,eAAe,CAAC,IAAY,EAAE,EAAa,EAAE,OAA6B;QACxE,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;QACvG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,iBAAiB,CAAC,IAAY;QAC5B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,YAAY;QACV,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,EAAO,EAAE,MAAc,EAAE,OAAa;QACnE,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;QAC5D,OAAO,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/emit/format.ts"],"names":[],"mappings":"AAGA,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,QAiB5E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export function formatDirectory(outDir, formatter) {
|
|
4
|
+
const fmt = formatter ?? "prettier";
|
|
5
|
+
if (fmt === "none")
|
|
6
|
+
return;
|
|
7
|
+
if (fmt === "prettier") {
|
|
8
|
+
try {
|
|
9
|
+
// use npx to ensure available even if not installed globally
|
|
10
|
+
// limit files to common extensions to reduce runtime
|
|
11
|
+
const cmd = `npx prettier --write "${path.join(outDir, "**/*.{ts,js,json,md}")}"`;
|
|
12
|
+
console.log("Running formatter:", cmd);
|
|
13
|
+
execSync(cmd, { stdio: "inherit" });
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
console.warn("Formatter failed or not available; continuing without formatting.");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
console.warn(`Unknown formatter '${fmt}', skipping formatting.`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/emit/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,SAA6B;IAC3E,MAAM,GAAG,GAAG,SAAS,IAAI,UAAU,CAAC;IACpC,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO;IAE3B,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,6DAA6D;YAC7D,qDAAqD;YACrD,MAAM,GAAG,GAAG,yBAAyB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,sBAAsB,CAAC,GAAG,CAAC;YAClF,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;YACvC,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,sBAAsB,GAAG,yBAAyB,CAAC,CAAC;IACnE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontend-react.d.ts","sourceRoot":"","sources":["../../../src/emit/frontend/frontend-react.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAA4C,MAAM,UAAU,CAAC;AAE7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AA+XpE,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,gBAAgB,QAmalF"}
|