@powerhousedao/builder-tools 6.0.2-staging.2 → 6.0.2-staging.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +175 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +628 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +14 -23
- package/dist/bundle.d.ts +0 -2
- package/dist/bundle.d.ts.map +0 -1
- package/dist/connect-utils/build.d.ts +0 -3
- package/dist/connect-utils/build.d.ts.map +0 -1
- package/dist/connect-utils/constants.d.ts +0 -5
- package/dist/connect-utils/constants.d.ts.map +0 -1
- package/dist/connect-utils/helpers.d.ts +0 -48
- package/dist/connect-utils/helpers.d.ts.map +0 -1
- package/dist/connect-utils/index.d.ts +0 -15
- package/dist/connect-utils/index.d.ts.map +0 -1
- package/dist/connect-utils/preview.d.ts +0 -3
- package/dist/connect-utils/preview.d.ts.map +0 -1
- package/dist/connect-utils/studio.d.ts +0 -7
- package/dist/connect-utils/studio.d.ts.map +0 -1
- package/dist/connect-utils/types.d.ts +0 -37
- package/dist/connect-utils/types.d.ts.map +0 -1
- package/dist/connect-utils/vite-config.d.ts +0 -61
- package/dist/connect-utils/vite-config.d.ts.map +0 -1
- package/dist/connect-utils/vite-plugins/base.d.ts +0 -10
- package/dist/connect-utils/vite-plugins/base.d.ts.map +0 -1
- package/dist/connect-utils/vite-plugins/document-models-hmr.d.ts +0 -3
- package/dist/connect-utils/vite-plugins/document-models-hmr.d.ts.map +0 -1
- package/dist/connect-utils/vite-plugins/editors-hmr.d.ts +0 -3
- package/dist/connect-utils/vite-plugins/editors-hmr.d.ts.map +0 -1
- package/dist/connect-utils/vite-plugins/external-packages.d.ts +0 -3
- package/dist/connect-utils/vite-plugins/external-packages.d.ts.map +0 -1
- package/dist/connect-utils/vite-plugins/importmap.d.ts +0 -23
- package/dist/connect-utils/vite-plugins/importmap.d.ts.map +0 -1
- package/dist/connect-utils/vite-plugins/ph-external-packages.d.ts +0 -2
- package/dist/connect-utils/vite-plugins/ph-external-packages.d.ts.map +0 -1
- package/dist/connect-utils/vite-plugins/studio.d.ts +0 -3
- package/dist/connect-utils/vite-plugins/studio.d.ts.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -111943
- package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,628 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { exec, execSync } from "node:child_process";
|
|
3
|
+
import fs, { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
5
|
+
import path, { join, resolve } from "node:path";
|
|
6
|
+
import { cwd } from "node:process";
|
|
7
|
+
import { loadConnectEnv, setConnectEnv } from "@powerhousedao/shared/connect";
|
|
8
|
+
import { getConfig } from "@powerhousedao/config/node";
|
|
9
|
+
import { sentryVitePlugin } from "@sentry/vite-plugin";
|
|
10
|
+
import tailwind from "@tailwindcss/vite";
|
|
11
|
+
import react from "@vitejs/plugin-react";
|
|
12
|
+
import { createLogger, esmExternalRequirePlugin, loadEnv } from "vite";
|
|
13
|
+
import { createHtmlPlugin } from "vite-plugin-html";
|
|
14
|
+
//#region connect-utils/constants.ts
|
|
15
|
+
const EXTERNAL_PACKAGES_IMPORT = "PH:EXTERNAL_PACKAGES";
|
|
16
|
+
const IMPORT_SCRIPT_FILE = "external-packages.js";
|
|
17
|
+
const LOCAL_PACKAGE_ID = "ph:local-package";
|
|
18
|
+
const PH_DIR_NAME = ".ph";
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region connect-utils/helpers.ts
|
|
21
|
+
const DEFAULT_CONNECT_OUTDIR = ".ph/connect-build/dist/";
|
|
22
|
+
function commonConnectOptionsToEnv(options) {
|
|
23
|
+
const { base, configFile, defaultDrivesUrl, drivesPreserveStrategy, disableLocalPackage } = options;
|
|
24
|
+
if (base) setConnectEnv({ PH_CONNECT_BASE_PATH: base });
|
|
25
|
+
if (configFile) setConnectEnv({ PH_CONFIG_PATH: configFile });
|
|
26
|
+
if (defaultDrivesUrl) setConnectEnv({ PH_CONNECT_DEFAULT_DRIVES_URL: defaultDrivesUrl.join(",") });
|
|
27
|
+
if (drivesPreserveStrategy) setConnectEnv({ PH_CONNECT_DRIVES_PRESERVE_STRATEGY: drivesPreserveStrategy });
|
|
28
|
+
if (disableLocalPackage) setConnectEnv({ PH_DISABLE_LOCAL_PACKAGE: true });
|
|
29
|
+
}
|
|
30
|
+
function resolveViteConfigPath(options) {
|
|
31
|
+
const { projectRoot = cwd(), viteConfigFile } = options;
|
|
32
|
+
return viteConfigFile || join(projectRoot, "vite.config.ts");
|
|
33
|
+
}
|
|
34
|
+
function resolvePackage(packageName, root = process.cwd()) {
|
|
35
|
+
return createRequire(root).resolve(packageName, { paths: [root] });
|
|
36
|
+
}
|
|
37
|
+
function resolveConnectPackageJson(root = process.cwd()) {
|
|
38
|
+
try {
|
|
39
|
+
const connectPackageJsonPath = resolvePackage("@powerhousedao/connect/package.json", root);
|
|
40
|
+
const fileContents = fs.readFileSync(connectPackageJsonPath, "utf-8");
|
|
41
|
+
return JSON.parse(fileContents);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error(`Error reading Connect package.json:`, error);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Finds the dist dir of Connect on the local machine
|
|
49
|
+
*/
|
|
50
|
+
function resolveConnectBundle(root = process.cwd()) {
|
|
51
|
+
const connectIndexPath = resolvePackage("@powerhousedao/connect", root);
|
|
52
|
+
return join(connectIndexPath.substring(0, connectIndexPath.indexOf("connect") + 7), "dist/");
|
|
53
|
+
}
|
|
54
|
+
function resolveConnectPublicDir(root = process.cwd()) {
|
|
55
|
+
const connectIconPath = resolvePackage("@powerhousedao/connect/public/icon.ico", root);
|
|
56
|
+
return path.join(connectIconPath, "../");
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Copies the Connect dist dir to the target path
|
|
60
|
+
*/
|
|
61
|
+
function copyConnect(sourcePath, targetPath) {
|
|
62
|
+
try {
|
|
63
|
+
fs.rmSync(targetPath, {
|
|
64
|
+
recursive: true,
|
|
65
|
+
force: true
|
|
66
|
+
});
|
|
67
|
+
fs.cpSync(sourcePath, targetPath, { recursive: true });
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error(`❌ Error copying ${sourcePath} to ${targetPath}:`, error);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Backs up the index.html file
|
|
74
|
+
*
|
|
75
|
+
* Needed when running the Connect Studio dev server on Windows
|
|
76
|
+
*/
|
|
77
|
+
function backupIndexHtml(appPath, restore = false) {
|
|
78
|
+
const filePath = join(appPath, "index.html");
|
|
79
|
+
const backupPath = join(appPath, "index.html.bak");
|
|
80
|
+
const paths = restore ? [backupPath, filePath] : [filePath, backupPath];
|
|
81
|
+
if (fs.existsSync(paths[0])) fs.copyFileSync(paths[0], paths[1]);
|
|
82
|
+
}
|
|
83
|
+
function removeBase64EnvValues(appPath) {
|
|
84
|
+
backupIndexHtml(appPath);
|
|
85
|
+
const filePath = join(appPath, "index.html");
|
|
86
|
+
fs.readFile(filePath, "utf-8", (err, data) => {
|
|
87
|
+
if (err) {
|
|
88
|
+
console.error("Error reading file:", err);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const modifiedData = data.replace(/"LOCAL_DOCUMENT_MODELS":\s*".*?",/, `"LOCAL_DOCUMENT_MODELS": "",`).replace(/"LOCAL_DOCUMENT_EDITORS":\s*".*?"/, `"LOCAL_DOCUMENT_EDITORS": ""`);
|
|
92
|
+
console.log("Modified data:", modifiedData);
|
|
93
|
+
fs.writeFile(filePath, modifiedData, "utf-8", (err) => {
|
|
94
|
+
if (err) {
|
|
95
|
+
console.error("Error writing file:", err);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function readJsonFile(filePath) {
|
|
102
|
+
try {
|
|
103
|
+
const absolutePath = resolve(filePath);
|
|
104
|
+
const fileContents = fs.readFileSync(absolutePath, "utf-8");
|
|
105
|
+
return JSON.parse(fileContents);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error(`Error reading file: ${filePath}`);
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Takes a list of Powerhouse project packages and optionally local Powerhouse packages and outputs a js file which exports those packages for use in Connect Studio.
|
|
113
|
+
*/
|
|
114
|
+
function makeImportScriptFromPackages(args) {
|
|
115
|
+
const { packages, localJsPath, localCssPath, importStyles = true } = args;
|
|
116
|
+
const imports = [];
|
|
117
|
+
const moduleNames = [];
|
|
118
|
+
let counter = 0;
|
|
119
|
+
for (const packageName of packages) {
|
|
120
|
+
const moduleName = `module${counter}`;
|
|
121
|
+
moduleNames.push(moduleName);
|
|
122
|
+
imports.push(`import * as ${moduleName} from '${packageName}';`);
|
|
123
|
+
if (importStyles) imports.push(`import '${packageName}/style.css';`);
|
|
124
|
+
counter++;
|
|
125
|
+
}
|
|
126
|
+
const exports = moduleNames.map((name, index) => `{
|
|
127
|
+
id: "${packages[index]}",
|
|
128
|
+
...${name},
|
|
129
|
+
}`);
|
|
130
|
+
const hasModule = localJsPath !== void 0;
|
|
131
|
+
const hasStyles = importStyles && localCssPath !== void 0;
|
|
132
|
+
if (hasModule || hasStyles) {
|
|
133
|
+
if (hasStyles) imports.push(`import '${localCssPath}';`);
|
|
134
|
+
if (hasModule) {
|
|
135
|
+
const moduleName = `module${counter}`;
|
|
136
|
+
imports.push(`import * as ${moduleName} from '${localJsPath}';`);
|
|
137
|
+
exports.push(`{
|
|
138
|
+
id: "${LOCAL_PACKAGE_ID}",
|
|
139
|
+
...${moduleName},
|
|
140
|
+
}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const exportStatement = `export default [${exports.length ? `
|
|
144
|
+
${exports.join(",\n")}
|
|
145
|
+
` : ""}];`;
|
|
146
|
+
return `${imports.join("\n")}\n\n${exportStatement}`;
|
|
147
|
+
}
|
|
148
|
+
function ensureNodeVersion(minVersion = "24") {
|
|
149
|
+
const version = process.versions.node;
|
|
150
|
+
if (!version) return;
|
|
151
|
+
if (version < minVersion) {
|
|
152
|
+
console.error(`Node version ${minVersion} or higher is required. Current version: ${version}`);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function runShellScriptPlugin(scriptName, connectPath) {
|
|
157
|
+
return {
|
|
158
|
+
name: "vite-plugin-run-shell-script",
|
|
159
|
+
buildStart() {
|
|
160
|
+
const scriptPath = join(connectPath, scriptName);
|
|
161
|
+
if (fs.existsSync(scriptPath)) exec(`sh ${scriptPath}`, (error, stdout, stderr) => {
|
|
162
|
+
if (error) {
|
|
163
|
+
console.error(`Error executing the script: ${error.message}`);
|
|
164
|
+
removeBase64EnvValues(connectPath);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (stderr) console.error(stderr);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Shared helper to modify the <head> tag of an HTML file by transforming its contents.
|
|
174
|
+
*/
|
|
175
|
+
async function modifyHtmlHead(pathToHtml, contents, transform) {
|
|
176
|
+
if (!existsSync(pathToHtml)) throw new Error(`File ${pathToHtml} does not exist.`);
|
|
177
|
+
let html = await readFile(pathToHtml, "utf8");
|
|
178
|
+
html = transform(html, contents);
|
|
179
|
+
await writeFile(pathToHtml, html, "utf8");
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Appends the contents to the <head> tag of the index.html file
|
|
183
|
+
*/
|
|
184
|
+
async function appendToHtmlHead(pathToHtml, contents) {
|
|
185
|
+
return modifyHtmlHead(pathToHtml, contents, (html, contents) => {
|
|
186
|
+
if (!html.includes("</head>")) throw new Error("No </head> tag found in the HTML file.");
|
|
187
|
+
return html.replace("</head>", `\n${contents}\n</head>`);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Prepends the contents to the <head> tag of the index.html file
|
|
192
|
+
*/
|
|
193
|
+
async function prependToHtmlHead(pathToHtml, contents) {
|
|
194
|
+
return modifyHtmlHead(pathToHtml, contents, (html, contents) => {
|
|
195
|
+
if (!html.includes("</head>")) throw new Error("No </head> tag found in the HTML file.");
|
|
196
|
+
return html.replace("<head>", `<head>\n${contents}\n`);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
function runTsc(outDir) {
|
|
200
|
+
execSync(`npx tsc --outDir ${outDir}`, { stdio: "inherit" });
|
|
201
|
+
}
|
|
202
|
+
function stripVersionFromPackage(packageName) {
|
|
203
|
+
const trimmed = packageName.trim();
|
|
204
|
+
if (!trimmed) return "";
|
|
205
|
+
const lastAtIndex = trimmed.lastIndexOf("@");
|
|
206
|
+
if (lastAtIndex > 0) return trimmed.substring(0, lastAtIndex);
|
|
207
|
+
return trimmed;
|
|
208
|
+
}
|
|
209
|
+
//#endregion
|
|
210
|
+
//#region connect-utils/vite-plugins/dev-external-react.ts
|
|
211
|
+
const REACT_DEPS = [
|
|
212
|
+
"react",
|
|
213
|
+
"react-dom",
|
|
214
|
+
"react/jsx-runtime",
|
|
215
|
+
"react/jsx-dev-runtime",
|
|
216
|
+
"react-dom/client"
|
|
217
|
+
];
|
|
218
|
+
const SHIM_PREFIX = "/__ph/dev-react-shim/";
|
|
219
|
+
const VITE_DEPS_PREFIX = "/node_modules/.vite/deps";
|
|
220
|
+
/**
|
|
221
|
+
* Dev-only sibling of `esmExternalRequirePlugin`. The build path externalizes
|
|
222
|
+
* React via Rolldown so an importmap hands the same React instance to both
|
|
223
|
+
* Connect and CDN-served editor packages. Rolldown plugins don't run in
|
|
224
|
+
* `vite createServer`, and Vite's pre-bundled CJS deps only expose a `default`
|
|
225
|
+
* export — so a CDN editor that does `import { lazy } from "react"` would
|
|
226
|
+
* fail with "no named export 'lazy'".
|
|
227
|
+
*
|
|
228
|
+
* This plugin:
|
|
229
|
+
* 1. Forces React into `optimizeDeps.include` so the optimizer always knows
|
|
230
|
+
* about it.
|
|
231
|
+
* 2. Serves a shim per React module at a stable URL. Each shim imports
|
|
232
|
+
* from Vite's live pre-bundled URL (sharing Connect's React instance)
|
|
233
|
+
* and re-exports React's named members so editors importing
|
|
234
|
+
* `{ lazy }`, `{ jsx }`, etc. work.
|
|
235
|
+
* 3. Rewrites the page importmap to point at those shim URLs.
|
|
236
|
+
*/
|
|
237
|
+
function devReactImportmapPlugin() {
|
|
238
|
+
let namedExports = /* @__PURE__ */ new Map();
|
|
239
|
+
return {
|
|
240
|
+
name: "ph-dev-react-importmap",
|
|
241
|
+
apply: "serve",
|
|
242
|
+
config: () => ({ optimizeDeps: { include: REACT_DEPS } }),
|
|
243
|
+
configureServer(server) {
|
|
244
|
+
const requireFromRoot = createRequire(path.join(server.config.root, "package.json"));
|
|
245
|
+
namedExports = new Map(REACT_DEPS.map((id) => {
|
|
246
|
+
try {
|
|
247
|
+
const mod = requireFromRoot(id);
|
|
248
|
+
return [id, Object.keys(mod).filter((k) => k !== "default")];
|
|
249
|
+
} catch {
|
|
250
|
+
return [id, []];
|
|
251
|
+
}
|
|
252
|
+
}));
|
|
253
|
+
server.middlewares.use((req, res, next) => {
|
|
254
|
+
if (!req.url?.startsWith(SHIM_PREFIX)) return next();
|
|
255
|
+
const id = req.url.slice(21).replace(/\.js(\?.*)?$/, "");
|
|
256
|
+
if (!REACT_DEPS.includes(id)) return next();
|
|
257
|
+
const optimizer = server.environments.client.depsOptimizer;
|
|
258
|
+
const info = optimizer?.metadata.optimized[id] ?? optimizer?.metadata.discovered[id];
|
|
259
|
+
if (!optimizer || !info) {
|
|
260
|
+
res.statusCode = 404;
|
|
261
|
+
res.end();
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const browserHash = info.browserHash ?? optimizer.metadata.browserHash;
|
|
265
|
+
const depUrl = `${VITE_DEPS_PREFIX}/${path.basename(info.file)}?v=${browserHash}`;
|
|
266
|
+
const names = namedExports.get(id) ?? [];
|
|
267
|
+
res.setHeader("Content-Type", "application/javascript");
|
|
268
|
+
res.end(`import * as M from ${JSON.stringify(depUrl)};\nconst ns = M.default ?? M;\nexport default ns;\n` + (names.length ? `export const { ${names.join(", ")} } = ns;\n` : ""));
|
|
269
|
+
});
|
|
270
|
+
},
|
|
271
|
+
transformIndexHtml: {
|
|
272
|
+
order: "post",
|
|
273
|
+
handler(html, ctx) {
|
|
274
|
+
const browserHash = ctx.server?.environments.client.depsOptimizer?.metadata.browserHash;
|
|
275
|
+
if (!browserHash) return;
|
|
276
|
+
const imports = Object.fromEntries(REACT_DEPS.map((id) => [id, `${SHIM_PREFIX}${id}.js?v=${browserHash}`]));
|
|
277
|
+
return html.replace(/<script type="importmap">[\s\S]*?<\/script>/, `<script type="importmap">${JSON.stringify({ imports }, null, 2)}<\/script>`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
//#endregion
|
|
283
|
+
//#region connect-utils/vite-plugins/favicon.ts
|
|
284
|
+
/**
|
|
285
|
+
* Vite plugin to serve the Connect favicon (icon.ico) from the connect package.
|
|
286
|
+
* This ensures the favicon is available in development and included in the production build.
|
|
287
|
+
*/
|
|
288
|
+
function connectFaviconPlugin() {
|
|
289
|
+
return {
|
|
290
|
+
name: "copy-connect-favicon",
|
|
291
|
+
configureServer(server) {
|
|
292
|
+
server.middlewares.use("/icon.ico", (_req, res, next) => {
|
|
293
|
+
server.pluginContainer.resolveId("@powerhousedao/connect/assets/icon.ico").then((resolved) => {
|
|
294
|
+
if (!resolved) return next();
|
|
295
|
+
res.setHeader("Content-Type", "image/x-icon");
|
|
296
|
+
res.end(readFileSync(resolved.id));
|
|
297
|
+
}).catch(() => next());
|
|
298
|
+
});
|
|
299
|
+
},
|
|
300
|
+
async generateBundle(_options, bundle) {
|
|
301
|
+
try {
|
|
302
|
+
if ("icon.ico" in bundle) return;
|
|
303
|
+
const resolved = await this.resolve("@powerhousedao/connect/assets/icon.ico");
|
|
304
|
+
if (!resolved) return;
|
|
305
|
+
this.emitFile({
|
|
306
|
+
type: "asset",
|
|
307
|
+
fileName: "icon.ico",
|
|
308
|
+
source: readFileSync(resolved.id)
|
|
309
|
+
});
|
|
310
|
+
} catch {}
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
//#endregion
|
|
315
|
+
//#region connect-utils/vite-plugins/ph-bundled-packages.ts
|
|
316
|
+
const VIRTUAL_ID = "ph-bundled-packages-virtual";
|
|
317
|
+
const RESOLVED_VIRTUAL_ID = "\0virtual:" + VIRTUAL_ID;
|
|
318
|
+
function readBundledPackageVersion(projectRoot, name) {
|
|
319
|
+
try {
|
|
320
|
+
const raw = fs.readFileSync(path.join(projectRoot, "node_modules", name, "package.json"), "utf-8");
|
|
321
|
+
const pkg = JSON.parse(raw);
|
|
322
|
+
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
323
|
+
} catch {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
function makeRegisterModule(packages, projectRoot) {
|
|
328
|
+
if (packages.length === 0) return "export default () => {};\n";
|
|
329
|
+
const imports = [];
|
|
330
|
+
const calls = [];
|
|
331
|
+
packages.forEach((name, i) => {
|
|
332
|
+
const moduleName = `pkg${i}`;
|
|
333
|
+
const version = readBundledPackageVersion(projectRoot, name);
|
|
334
|
+
imports.push(`import * as ${moduleName} from ${JSON.stringify(name)};`);
|
|
335
|
+
imports.push(`import ${JSON.stringify(`${name}/style.css`)};`);
|
|
336
|
+
calls.push(` pm.addLocalPackage(${JSON.stringify(name)}, ${moduleName}, ${JSON.stringify(version)});`);
|
|
337
|
+
});
|
|
338
|
+
return `${imports.join("\n")}\n\nexport default function register(pm) {\n${calls.join("\n")}\n};\n`;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Emits a virtual module `ph-bundled-packages-virtual` whose default export
|
|
342
|
+
* is a `register(packageManager)` function. When called at runtime (from
|
|
343
|
+
* Connect's bootstrap), it registers each bundled package with the package
|
|
344
|
+
* manager the same way Common/Vetra are registered — meaning they work
|
|
345
|
+
* offline without the registry being reachable.
|
|
346
|
+
*
|
|
347
|
+
* When the list is empty, the module exports a no-op function so Connect's
|
|
348
|
+
* bootstrap code can always import it unconditionally.
|
|
349
|
+
*/
|
|
350
|
+
function phBundledPackagesPlugin(options) {
|
|
351
|
+
const projectRoot = options.projectRoot ?? process.cwd();
|
|
352
|
+
const moduleSource = makeRegisterModule(options.packages, projectRoot);
|
|
353
|
+
return {
|
|
354
|
+
name: "vite-plugin-ph-bundled-packages",
|
|
355
|
+
enforce: "pre",
|
|
356
|
+
resolveId(id) {
|
|
357
|
+
if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;
|
|
358
|
+
},
|
|
359
|
+
load(id) {
|
|
360
|
+
if (id === RESOLVED_VIRTUAL_ID) return moduleSource;
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
//#endregion
|
|
365
|
+
//#region connect-utils/vite-plugins/ph-packages.ts
|
|
366
|
+
function readProjectPackageInfo(projectRoot) {
|
|
367
|
+
if (!projectRoot) return null;
|
|
368
|
+
try {
|
|
369
|
+
const raw = fs.readFileSync(path.join(projectRoot, "package.json"), "utf-8");
|
|
370
|
+
const pkg = JSON.parse(raw);
|
|
371
|
+
if (typeof pkg.name !== "string" || typeof pkg.version !== "string") return null;
|
|
372
|
+
return {
|
|
373
|
+
name: pkg.name,
|
|
374
|
+
version: pkg.version
|
|
375
|
+
};
|
|
376
|
+
} catch {
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
function phPackagesPlugin(options) {
|
|
381
|
+
const localPackage = readProjectPackageInfo(options.projectRoot ?? process.cwd());
|
|
382
|
+
const content = JSON.stringify({
|
|
383
|
+
packages: options.packages,
|
|
384
|
+
localPackage
|
|
385
|
+
}, null, 2);
|
|
386
|
+
return {
|
|
387
|
+
name: "vite-plugin-ph-packages",
|
|
388
|
+
configureServer(server) {
|
|
389
|
+
server.middlewares.use((req, res, next) => {
|
|
390
|
+
if (req.url?.endsWith("/ph-packages.json")) {
|
|
391
|
+
res.setHeader("Content-Type", "application/json");
|
|
392
|
+
res.end(content);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
next();
|
|
396
|
+
});
|
|
397
|
+
},
|
|
398
|
+
hotUpdate: {
|
|
399
|
+
order: "pre",
|
|
400
|
+
handler(ctx) {
|
|
401
|
+
return ctx.modules.filter((mod) => {
|
|
402
|
+
if (mod.importers.size > 1) return true;
|
|
403
|
+
return !mod.importers.values().next().value?.file?.endsWith(".css");
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
generateBundle() {
|
|
408
|
+
this.emitFile({
|
|
409
|
+
type: "asset",
|
|
410
|
+
fileName: "ph-packages.json",
|
|
411
|
+
source: content
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
//#endregion
|
|
417
|
+
//#region connect-utils/vite-config.ts
|
|
418
|
+
const REACT_VERSION = "19.2.0";
|
|
419
|
+
const REACT_IMPORTMAP_IMPORTS = {
|
|
420
|
+
react: `https://esm.sh/react@${REACT_VERSION}`,
|
|
421
|
+
"react/": `https://esm.sh/react@${REACT_VERSION}/`,
|
|
422
|
+
"react-dom": `https://esm.sh/react-dom@${REACT_VERSION}`,
|
|
423
|
+
"react-dom/": `https://esm.sh/react-dom@${REACT_VERSION}/`
|
|
424
|
+
};
|
|
425
|
+
function getConnectHtmlTags(options = {}) {
|
|
426
|
+
const { registryUrl, injectTo = "head" } = options;
|
|
427
|
+
return [
|
|
428
|
+
{
|
|
429
|
+
tag: "meta",
|
|
430
|
+
attrs: {
|
|
431
|
+
"http-equiv": "Content-Security-Policy",
|
|
432
|
+
content: `script-src 'self' 'unsafe-inline' 'unsafe-eval' https://esm.sh${registryUrl ? " " + registryUrl : ""}; object-src 'none'; base-uri 'self';`
|
|
433
|
+
},
|
|
434
|
+
injectTo
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
tag: "meta",
|
|
438
|
+
attrs: {
|
|
439
|
+
property: "og:title",
|
|
440
|
+
content: "Connect"
|
|
441
|
+
},
|
|
442
|
+
injectTo
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
tag: "meta",
|
|
446
|
+
attrs: {
|
|
447
|
+
property: "og:type",
|
|
448
|
+
content: "website"
|
|
449
|
+
},
|
|
450
|
+
injectTo
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
tag: "meta",
|
|
454
|
+
attrs: {
|
|
455
|
+
property: "og:url",
|
|
456
|
+
content: "https://apps.powerhouse.io/powerhouse/connect/"
|
|
457
|
+
},
|
|
458
|
+
injectTo
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
tag: "meta",
|
|
462
|
+
attrs: {
|
|
463
|
+
property: "og:description",
|
|
464
|
+
content: "Navigate your organisation’s toughest operational challenges and steer your contributors to success with Connect. A navigation, collaboration and reporting tool for decentralised and open organisation."
|
|
465
|
+
},
|
|
466
|
+
injectTo
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
tag: "meta",
|
|
470
|
+
attrs: {
|
|
471
|
+
property: "og:image",
|
|
472
|
+
content: "https://cf-ipfs.com/ipfs/bafkreigrmclndf2jpbolaq22535q2sw5t44uad3az3dpvkzrnt4lpjt63e"
|
|
473
|
+
},
|
|
474
|
+
injectTo
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
tag: "meta",
|
|
478
|
+
attrs: {
|
|
479
|
+
name: "twitter:card",
|
|
480
|
+
content: "summary_large_image"
|
|
481
|
+
},
|
|
482
|
+
injectTo
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
tag: "meta",
|
|
486
|
+
attrs: {
|
|
487
|
+
name: "twitter:image",
|
|
488
|
+
content: "https://cf-ipfs.com/ipfs/bafkreigrmclndf2jpbolaq22535q2sw5t44uad3az3dpvkzrnt4lpjt63e"
|
|
489
|
+
},
|
|
490
|
+
injectTo
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
tag: "meta",
|
|
494
|
+
attrs: {
|
|
495
|
+
name: "twitter:title",
|
|
496
|
+
content: "Connect"
|
|
497
|
+
},
|
|
498
|
+
injectTo
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
tag: "meta",
|
|
502
|
+
attrs: {
|
|
503
|
+
name: "twitter:description",
|
|
504
|
+
content: "Navigate your organisation’s toughest operational challenges and steer your contributors to success with Connect. A navigation, collaboration and reporting tool for decentralised and open organisation."
|
|
505
|
+
},
|
|
506
|
+
injectTo
|
|
507
|
+
}
|
|
508
|
+
];
|
|
509
|
+
}
|
|
510
|
+
function viteLogger({ silence }) {
|
|
511
|
+
const logger = createLogger();
|
|
512
|
+
const loggerWarn = logger.warn.bind(logger);
|
|
513
|
+
const loggerError = logger.error.bind(logger);
|
|
514
|
+
logger.warn = (msg, options) => {
|
|
515
|
+
if (silence?.warnings?.some((warning) => msg.includes(warning))) return;
|
|
516
|
+
loggerWarn(msg, options);
|
|
517
|
+
};
|
|
518
|
+
logger.error = (msg, options) => {
|
|
519
|
+
if (silence?.errors?.some((error) => msg.includes(error))) return;
|
|
520
|
+
loggerError(msg, options);
|
|
521
|
+
};
|
|
522
|
+
return logger;
|
|
523
|
+
}
|
|
524
|
+
function getPackageNamesFromPowerhouseConfig({ packages }) {
|
|
525
|
+
if (!packages) return [];
|
|
526
|
+
return packages.map((p) => p.version && p.provider !== "local" ? `${p.packageName}@${p.version}` : p.packageName);
|
|
527
|
+
}
|
|
528
|
+
function getLocalPackageNamesFromPowerhouseConfig({ packages }) {
|
|
529
|
+
if (!packages) return [];
|
|
530
|
+
return packages.filter((p) => p.provider === "local").map((p) => p.packageName);
|
|
531
|
+
}
|
|
532
|
+
function getConnectBaseViteConfig(options) {
|
|
533
|
+
const mode = options.mode;
|
|
534
|
+
const fileEnv = loadEnv(mode, options.envDir ?? options.dirname, "PH_");
|
|
535
|
+
const env = loadConnectEnv({
|
|
536
|
+
processEnv: process.env,
|
|
537
|
+
fileEnv
|
|
538
|
+
});
|
|
539
|
+
setConnectEnv(env);
|
|
540
|
+
const phConfigPath = env.PH_CONFIG_PATH ?? join(options.dirname, "powerhouse.config.json");
|
|
541
|
+
const phConfig = options.powerhouseConfig ?? getConfig(phConfigPath);
|
|
542
|
+
const packagesFromConfig = getPackageNamesFromPowerhouseConfig(phConfig);
|
|
543
|
+
const localPackagesFromConfig = getLocalPackageNamesFromPowerhouseConfig(phConfig);
|
|
544
|
+
const phPackages = env.PH_PACKAGES?.split(",") ?? packagesFromConfig;
|
|
545
|
+
const phPackageRegistryUrl = env.PH_CONNECT_PACKAGES_REGISTRY ?? phConfig.packageRegistryUrl ?? null;
|
|
546
|
+
const authToken = env.PH_SENTRY_AUTH_TOKEN;
|
|
547
|
+
const org = env.PH_SENTRY_ORG;
|
|
548
|
+
const project = env.PH_SENTRY_PROJECT;
|
|
549
|
+
const release = env.PH_CONNECT_SENTRY_RELEASE || env.PH_CONNECT_VERSION;
|
|
550
|
+
const uploadSentrySourcemaps = authToken && org && project;
|
|
551
|
+
const connectHtmlTags = getConnectHtmlTags({ registryUrl: phPackageRegistryUrl });
|
|
552
|
+
const plugins = [
|
|
553
|
+
tailwind(),
|
|
554
|
+
react(),
|
|
555
|
+
createHtmlPlugin({
|
|
556
|
+
minify: false,
|
|
557
|
+
inject: { tags: [...connectHtmlTags, {
|
|
558
|
+
tag: "script",
|
|
559
|
+
attrs: { type: "importmap" },
|
|
560
|
+
children: JSON.stringify({ imports: REACT_IMPORTMAP_IMPORTS }, null, 2),
|
|
561
|
+
injectTo: "head-prepend"
|
|
562
|
+
}] }
|
|
563
|
+
})
|
|
564
|
+
];
|
|
565
|
+
if (uploadSentrySourcemaps) plugins.push(sentryVitePlugin({
|
|
566
|
+
release: {
|
|
567
|
+
name: release ?? "unknown",
|
|
568
|
+
inject: false
|
|
569
|
+
},
|
|
570
|
+
authToken,
|
|
571
|
+
org,
|
|
572
|
+
project,
|
|
573
|
+
bundleSizeOptimizations: { excludeDebugStatements: true },
|
|
574
|
+
reactComponentAnnotation: { enabled: true }
|
|
575
|
+
}));
|
|
576
|
+
const customLogger = process.env.LOG_LEVEL === "debug" || env.PH_CONNECT_LOG_LEVEL === "debug" ? void 0 : viteLogger({ silence: {
|
|
577
|
+
warnings: ["@import must precede all other statements (besides @charset or empty @layer)"],
|
|
578
|
+
errors: ["Unterminated string literal"]
|
|
579
|
+
} });
|
|
580
|
+
const reactExternal = [
|
|
581
|
+
"react",
|
|
582
|
+
"react-dom",
|
|
583
|
+
"react/jsx-runtime",
|
|
584
|
+
"react-dom/client"
|
|
585
|
+
];
|
|
586
|
+
return {
|
|
587
|
+
configFile: false,
|
|
588
|
+
mode,
|
|
589
|
+
server: { watch: { ignored: ["**/backup-documents/**", "**/.ph/**"] } },
|
|
590
|
+
resolve: {
|
|
591
|
+
dedupe: ["react", "react-dom"],
|
|
592
|
+
tsconfigPaths: true
|
|
593
|
+
},
|
|
594
|
+
define: { PH_PACKAGE_REGISTRY_URL: `"${phPackageRegistryUrl}"` },
|
|
595
|
+
customLogger,
|
|
596
|
+
envPrefix: ["PH_CONNECT_"],
|
|
597
|
+
optimizeDeps: {
|
|
598
|
+
include: [
|
|
599
|
+
"document-model",
|
|
600
|
+
"zod",
|
|
601
|
+
"@powerhousedao/design-system/connect",
|
|
602
|
+
"@powerhousedao/reactor-browser",
|
|
603
|
+
"@powerhousedao/document-engineering"
|
|
604
|
+
],
|
|
605
|
+
exclude: ["@electric-sql/pglite", "@electric-sql/pglite-tools"]
|
|
606
|
+
},
|
|
607
|
+
plugins: [
|
|
608
|
+
phPackagesPlugin({
|
|
609
|
+
packages: phPackages,
|
|
610
|
+
projectRoot: options.dirname
|
|
611
|
+
}),
|
|
612
|
+
phBundledPackagesPlugin({
|
|
613
|
+
packages: localPackagesFromConfig,
|
|
614
|
+
projectRoot: options.dirname
|
|
615
|
+
}),
|
|
616
|
+
devReactImportmapPlugin(),
|
|
617
|
+
...plugins,
|
|
618
|
+
esmExternalRequirePlugin({ external: reactExternal }),
|
|
619
|
+
connectFaviconPlugin()
|
|
620
|
+
],
|
|
621
|
+
worker: { format: "es" },
|
|
622
|
+
build: { sourcemap: true }
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
//#endregion
|
|
626
|
+
export { DEFAULT_CONNECT_OUTDIR, EXTERNAL_PACKAGES_IMPORT, IMPORT_SCRIPT_FILE, LOCAL_PACKAGE_ID, PH_DIR_NAME, appendToHtmlHead, backupIndexHtml, commonConnectOptionsToEnv, copyConnect, ensureNodeVersion, getConnectBaseViteConfig, getConnectHtmlTags, makeImportScriptFromPackages, phPackagesPlugin, prependToHtmlHead, readJsonFile, removeBase64EnvValues, resolveConnectBundle, resolveConnectPackageJson, resolveConnectPublicDir, resolvePackage, resolveViteConfigPath, runShellScriptPlugin, runTsc, stripVersionFromPackage };
|
|
627
|
+
|
|
628
|
+
//# sourceMappingURL=index.mjs.map
|