@powerhousedao/builder-tools 6.0.0-dev.105 → 6.0.0-dev.106

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.
Files changed (41) hide show
  1. package/dist/index.d.mts +193 -0
  2. package/dist/index.d.mts.map +1 -0
  3. package/dist/index.mjs +696 -0
  4. package/dist/index.mjs.map +1 -0
  5. package/package.json +20 -17
  6. package/dist/bundle.d.ts +0 -2
  7. package/dist/bundle.d.ts.map +0 -1
  8. package/dist/connect-utils/build.d.ts +0 -3
  9. package/dist/connect-utils/build.d.ts.map +0 -1
  10. package/dist/connect-utils/constants.d.ts +0 -5
  11. package/dist/connect-utils/constants.d.ts.map +0 -1
  12. package/dist/connect-utils/helpers.d.ts +0 -48
  13. package/dist/connect-utils/helpers.d.ts.map +0 -1
  14. package/dist/connect-utils/index.d.ts +0 -15
  15. package/dist/connect-utils/index.d.ts.map +0 -1
  16. package/dist/connect-utils/preview.d.ts +0 -3
  17. package/dist/connect-utils/preview.d.ts.map +0 -1
  18. package/dist/connect-utils/studio.d.ts +0 -7
  19. package/dist/connect-utils/studio.d.ts.map +0 -1
  20. package/dist/connect-utils/types.d.ts +0 -37
  21. package/dist/connect-utils/types.d.ts.map +0 -1
  22. package/dist/connect-utils/vite-config.d.ts +0 -61
  23. package/dist/connect-utils/vite-config.d.ts.map +0 -1
  24. package/dist/connect-utils/vite-plugins/base.d.ts +0 -10
  25. package/dist/connect-utils/vite-plugins/base.d.ts.map +0 -1
  26. package/dist/connect-utils/vite-plugins/document-models-hmr.d.ts +0 -3
  27. package/dist/connect-utils/vite-plugins/document-models-hmr.d.ts.map +0 -1
  28. package/dist/connect-utils/vite-plugins/editors-hmr.d.ts +0 -3
  29. package/dist/connect-utils/vite-plugins/editors-hmr.d.ts.map +0 -1
  30. package/dist/connect-utils/vite-plugins/external-packages.d.ts +0 -3
  31. package/dist/connect-utils/vite-plugins/external-packages.d.ts.map +0 -1
  32. package/dist/connect-utils/vite-plugins/importmap.d.ts +0 -23
  33. package/dist/connect-utils/vite-plugins/importmap.d.ts.map +0 -1
  34. package/dist/connect-utils/vite-plugins/ph-external-packages.d.ts +0 -2
  35. package/dist/connect-utils/vite-plugins/ph-external-packages.d.ts.map +0 -1
  36. package/dist/connect-utils/vite-plugins/studio.d.ts +0 -3
  37. package/dist/connect-utils/vite-plugins/studio.d.ts.map +0 -1
  38. package/dist/index.d.ts +0 -2
  39. package/dist/index.d.ts.map +0 -1
  40. package/dist/index.js +0 -111943
  41. package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/index.mjs ADDED
@@ -0,0 +1,696 @@
1
+ import { builtinModules, createRequire } from "node:module";
2
+ import { exec, execSync } from "node:child_process";
3
+ import fs, { existsSync } from "node:fs";
4
+ import fs$1, { readFile, writeFile } from "node:fs/promises";
5
+ import path, { basename, dirname, 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, loadEnv } from "vite";
13
+ import { createHtmlPlugin } from "vite-plugin-html";
14
+ import tsconfigPaths from "vite-tsconfig-paths";
15
+ import fs$2 from "fs/promises";
16
+ import MagicString from "magic-string";
17
+ import { build } from "esbuild";
18
+ import fg from "fast-glob";
19
+ import { exports } from "resolve.exports";
20
+ //#region connect-utils/constants.ts
21
+ const EXTERNAL_PACKAGES_IMPORT = "PH:EXTERNAL_PACKAGES";
22
+ const IMPORT_SCRIPT_FILE = "external-packages.js";
23
+ const LOCAL_PACKAGE_ID = "ph:local-package";
24
+ const PH_DIR_NAME = ".ph";
25
+ //#endregion
26
+ //#region connect-utils/helpers.ts
27
+ const DEFAULT_CONNECT_OUTDIR = ".ph/connect-build/dist/";
28
+ function commonConnectOptionsToEnv(options) {
29
+ const { base, configFile, defaultDrivesUrl, drivesPreserveStrategy, disableLocalPackage } = options;
30
+ if (base) setConnectEnv({ PH_CONNECT_BASE_PATH: base });
31
+ if (configFile) setConnectEnv({ PH_CONFIG_PATH: configFile });
32
+ if (defaultDrivesUrl) setConnectEnv({ PH_CONNECT_DEFAULT_DRIVES_URL: defaultDrivesUrl.join(",") });
33
+ if (drivesPreserveStrategy) setConnectEnv({ PH_CONNECT_DRIVES_PRESERVE_STRATEGY: drivesPreserveStrategy });
34
+ if (disableLocalPackage) setConnectEnv({ PH_DISABLE_LOCAL_PACKAGE: true });
35
+ }
36
+ function resolveViteConfigPath(options) {
37
+ const { projectRoot = cwd(), viteConfigFile } = options;
38
+ return viteConfigFile || join(projectRoot, "vite.config.ts");
39
+ }
40
+ function resolvePackage(packageName, root = process.cwd()) {
41
+ return createRequire(root).resolve(packageName, { paths: [root] });
42
+ }
43
+ function resolveConnectPackageJson(root = process.cwd()) {
44
+ try {
45
+ const connectPackageJsonPath = resolvePackage("@powerhousedao/connect/package.json", root);
46
+ const fileContents = fs.readFileSync(connectPackageJsonPath, "utf-8");
47
+ return JSON.parse(fileContents);
48
+ } catch (error) {
49
+ console.error(`Error reading Connect package.json:`, error);
50
+ return null;
51
+ }
52
+ }
53
+ /**
54
+ * Finds the dist dir of Connect on the local machine
55
+ */
56
+ function resolveConnectBundle(root = process.cwd()) {
57
+ const connectIndexPath = resolvePackage("@powerhousedao/connect", root);
58
+ return join(connectIndexPath.substring(0, connectIndexPath.indexOf("connect") + 7), "dist/");
59
+ }
60
+ function resolveConnectPublicDir(root = process.cwd()) {
61
+ const connectIconPath = resolvePackage("@powerhousedao/connect/public/icon.ico", root);
62
+ return path.join(connectIconPath, "../");
63
+ }
64
+ /**
65
+ * Copies the Connect dist dir to the target path
66
+ */
67
+ function copyConnect(sourcePath, targetPath) {
68
+ try {
69
+ fs.rmSync(targetPath, {
70
+ recursive: true,
71
+ force: true
72
+ });
73
+ fs.cpSync(sourcePath, targetPath, { recursive: true });
74
+ } catch (error) {
75
+ console.error(`❌ Error copying ${sourcePath} to ${targetPath}:`, error);
76
+ }
77
+ }
78
+ /**
79
+ * Backs up the index.html file
80
+ *
81
+ * Needed when running the Connect Studio dev server on Windows
82
+ */
83
+ function backupIndexHtml(appPath, restore = false) {
84
+ const filePath = join(appPath, "index.html");
85
+ const backupPath = join(appPath, "index.html.bak");
86
+ const paths = restore ? [backupPath, filePath] : [filePath, backupPath];
87
+ if (fs.existsSync(paths[0])) fs.copyFileSync(paths[0], paths[1]);
88
+ }
89
+ function removeBase64EnvValues(appPath) {
90
+ backupIndexHtml(appPath);
91
+ const filePath = join(appPath, "index.html");
92
+ fs.readFile(filePath, "utf-8", (err, data) => {
93
+ if (err) {
94
+ console.error("Error reading file:", err);
95
+ return;
96
+ }
97
+ const modifiedData = data.replace(/"LOCAL_DOCUMENT_MODELS":\s*".*?",/, `"LOCAL_DOCUMENT_MODELS": "",`).replace(/"LOCAL_DOCUMENT_EDITORS":\s*".*?"/, `"LOCAL_DOCUMENT_EDITORS": ""`);
98
+ console.log("Modified data:", modifiedData);
99
+ fs.writeFile(filePath, modifiedData, "utf-8", (err) => {
100
+ if (err) {
101
+ console.error("Error writing file:", err);
102
+ return;
103
+ }
104
+ });
105
+ });
106
+ }
107
+ function readJsonFile(filePath) {
108
+ try {
109
+ const absolutePath = resolve(filePath);
110
+ const fileContents = fs.readFileSync(absolutePath, "utf-8");
111
+ return JSON.parse(fileContents);
112
+ } catch (error) {
113
+ console.error(`Error reading file: ${filePath}`);
114
+ return null;
115
+ }
116
+ }
117
+ /**
118
+ * 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.
119
+ */
120
+ function makeImportScriptFromPackages(args) {
121
+ const { packages, localJsPath, localCssPath, importStyles = true } = args;
122
+ const imports = [];
123
+ const moduleNames = [];
124
+ let counter = 0;
125
+ for (const packageName of packages) {
126
+ const moduleName = `module${counter}`;
127
+ moduleNames.push(moduleName);
128
+ imports.push(`import * as ${moduleName} from '${packageName}';`);
129
+ if (importStyles) imports.push(`import '${packageName}/style.css';`);
130
+ counter++;
131
+ }
132
+ const exports = moduleNames.map((name, index) => `{
133
+ id: "${packages[index]}",
134
+ ...${name},
135
+ }`);
136
+ const hasModule = localJsPath !== void 0;
137
+ const hasStyles = importStyles && localCssPath !== void 0;
138
+ if (hasModule || hasStyles) {
139
+ if (hasStyles) imports.push(`import '${localCssPath}';`);
140
+ if (hasModule) {
141
+ const moduleName = `module${counter}`;
142
+ imports.push(`import * as ${moduleName} from '${localJsPath}';`);
143
+ exports.push(`{
144
+ id: "${LOCAL_PACKAGE_ID}",
145
+ ...${moduleName},
146
+ }`);
147
+ }
148
+ }
149
+ const exportStatement = `export default [${exports.length ? `
150
+ ${exports.join(",\n")}
151
+ ` : ""}];`;
152
+ return `${imports.join("\n")}\n\n${exportStatement}`;
153
+ }
154
+ function ensureNodeVersion(minVersion = "24") {
155
+ const version = process.versions.node;
156
+ if (!version) return;
157
+ if (version < minVersion) {
158
+ console.error(`Node version ${minVersion} or higher is required. Current version: ${version}`);
159
+ process.exit(1);
160
+ }
161
+ }
162
+ function runShellScriptPlugin(scriptName, connectPath) {
163
+ return {
164
+ name: "vite-plugin-run-shell-script",
165
+ buildStart() {
166
+ const scriptPath = join(connectPath, scriptName);
167
+ if (fs.existsSync(scriptPath)) exec(`sh ${scriptPath}`, (error, stdout, stderr) => {
168
+ if (error) {
169
+ console.error(`Error executing the script: ${error.message}`);
170
+ removeBase64EnvValues(connectPath);
171
+ return;
172
+ }
173
+ if (stderr) console.error(stderr);
174
+ });
175
+ }
176
+ };
177
+ }
178
+ /**
179
+ * Shared helper to modify the <head> tag of an HTML file by transforming its contents.
180
+ */
181
+ async function modifyHtmlHead(pathToHtml, contents, transform) {
182
+ if (!existsSync(pathToHtml)) throw new Error(`File ${pathToHtml} does not exist.`);
183
+ let html = await readFile(pathToHtml, "utf8");
184
+ html = transform(html, contents);
185
+ await writeFile(pathToHtml, html, "utf8");
186
+ }
187
+ /**
188
+ * Appends the contents to the <head> tag of the index.html file
189
+ */
190
+ async function appendToHtmlHead(pathToHtml, contents) {
191
+ return modifyHtmlHead(pathToHtml, contents, (html, contents) => {
192
+ if (!html.includes("</head>")) throw new Error("No </head> tag found in the HTML file.");
193
+ return html.replace("</head>", `\n${contents}\n</head>`);
194
+ });
195
+ }
196
+ /**
197
+ * Prepends the contents to the <head> tag of the index.html file
198
+ */
199
+ async function prependToHtmlHead(pathToHtml, contents) {
200
+ return modifyHtmlHead(pathToHtml, contents, (html, contents) => {
201
+ if (!html.includes("</head>")) throw new Error("No </head> tag found in the HTML file.");
202
+ return html.replace("<head>", `<head>\n${contents}\n`);
203
+ });
204
+ }
205
+ function runTsc(outDir) {
206
+ execSync(`npx tsc --outDir ${outDir}`, { stdio: "inherit" });
207
+ }
208
+ function stripVersionFromPackage(packageName) {
209
+ const trimmed = packageName.trim();
210
+ if (!trimmed) return "";
211
+ const lastAtIndex = trimmed.lastIndexOf("@");
212
+ if (lastAtIndex > 0) return trimmed.substring(0, lastAtIndex);
213
+ return trimmed;
214
+ }
215
+ //#endregion
216
+ //#region connect-utils/vite-config.ts
217
+ const connectClientConfig = { meta: [
218
+ {
219
+ tag: "meta",
220
+ attrs: {
221
+ "http-equiv": "Content-Security-Policy",
222
+ content: "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://esm.sh http://localhost:8080; object-src 'none'; base-uri 'self';"
223
+ }
224
+ },
225
+ {
226
+ tag: "meta",
227
+ attrs: {
228
+ property: "og:title",
229
+ content: "Connect"
230
+ }
231
+ },
232
+ {
233
+ tag: "meta",
234
+ attrs: {
235
+ property: "og:type",
236
+ content: "website"
237
+ }
238
+ },
239
+ {
240
+ tag: "meta",
241
+ attrs: {
242
+ property: "og:url",
243
+ content: "https://apps.powerhouse.io/powerhouse/connect/"
244
+ }
245
+ },
246
+ {
247
+ tag: "meta",
248
+ attrs: {
249
+ property: "og:description",
250
+ 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."
251
+ }
252
+ },
253
+ {
254
+ tag: "meta",
255
+ attrs: {
256
+ property: "og:image",
257
+ content: "https://cf-ipfs.com/ipfs/bafkreigrmclndf2jpbolaq22535q2sw5t44uad3az3dpvkzrnt4lpjt63e"
258
+ }
259
+ },
260
+ {
261
+ tag: "meta",
262
+ attrs: {
263
+ name: "twitter:card",
264
+ content: "summary_large_image"
265
+ }
266
+ },
267
+ {
268
+ tag: "meta",
269
+ attrs: {
270
+ name: "twitter:image",
271
+ content: "https://cf-ipfs.com/ipfs/bafkreigrmclndf2jpbolaq22535q2sw5t44uad3az3dpvkzrnt4lpjt63e"
272
+ }
273
+ },
274
+ {
275
+ tag: "meta",
276
+ attrs: {
277
+ name: "twitter:title",
278
+ content: "Connect"
279
+ }
280
+ },
281
+ {
282
+ tag: "meta",
283
+ attrs: {
284
+ name: "twitter:description",
285
+ 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."
286
+ }
287
+ }
288
+ ] };
289
+ function viteLogger({ silence }) {
290
+ const logger = createLogger();
291
+ const loggerWarn = logger.warn.bind(logger);
292
+ const loggerError = logger.error.bind(logger);
293
+ logger.warn = (msg, options) => {
294
+ if (silence?.warnings?.some((warning) => msg.includes(warning))) return;
295
+ loggerWarn(msg, options);
296
+ };
297
+ logger.error = (msg, options) => {
298
+ if (silence?.errors?.some((error) => msg.includes(error))) return;
299
+ loggerError(msg, options);
300
+ };
301
+ return logger;
302
+ }
303
+ function getPackageNamesFromPowerhouseConfig({ packages }) {
304
+ if (!packages) return [];
305
+ return packages.map((p) => p.packageName);
306
+ }
307
+ function getConnectBaseViteConfig(options) {
308
+ const mode = options.mode;
309
+ const fileEnv = loadEnv(mode, options.envDir ?? options.dirname, "PH_");
310
+ const env = loadConnectEnv({
311
+ processEnv: process.env,
312
+ fileEnv
313
+ });
314
+ setConnectEnv(env);
315
+ const phConfigPath = env.PH_CONFIG_PATH ?? join(options.dirname, "powerhouse.config.json");
316
+ const phConfig = options.powerhouseConfig ?? getConfig(phConfigPath);
317
+ const packagesFromConfig = getPackageNamesFromPowerhouseConfig(phConfig);
318
+ const phPackages = env.PH_PACKAGES?.split(",") ?? packagesFromConfig;
319
+ const phPackageRegistryUrl = env.PH_CONNECT_PACKAGES_REGISTRY ?? phConfig.packageRegistryUrl ?? null;
320
+ const authToken = env.PH_SENTRY_AUTH_TOKEN;
321
+ const org = env.PH_SENTRY_ORG;
322
+ const project = env.PH_SENTRY_PROJECT;
323
+ const release = env.PH_CONNECT_SENTRY_RELEASE || env.PH_CONNECT_VERSION;
324
+ const uploadSentrySourcemaps = authToken && org && project;
325
+ const plugins = [
326
+ tsconfigPaths(),
327
+ tailwind(),
328
+ react(),
329
+ createHtmlPlugin({
330
+ minify: false,
331
+ inject: { tags: [...connectClientConfig.meta.map((meta) => ({
332
+ ...meta,
333
+ injectTo: "head"
334
+ })), {
335
+ tag: "script",
336
+ attrs: { type: "importmap" },
337
+ children: JSON.stringify({ imports: {
338
+ react: "https://esm.sh/react@19.2.0",
339
+ "react/": "https://esm.sh/react@19.2.0/",
340
+ "react-dom": "https://esm.sh/react-dom@19.2.0",
341
+ "react-dom/": "https://esm.sh/react-dom@19.2.0/"
342
+ } }, null, 2),
343
+ injectTo: "head-prepend"
344
+ }] }
345
+ })
346
+ ];
347
+ if (uploadSentrySourcemaps) plugins.push(sentryVitePlugin({
348
+ release: {
349
+ name: release ?? "unknown",
350
+ inject: false
351
+ },
352
+ authToken,
353
+ org,
354
+ project,
355
+ bundleSizeOptimizations: { excludeDebugStatements: true },
356
+ reactComponentAnnotation: { enabled: true }
357
+ }));
358
+ const customLogger = process.env.LOG_LEVEL === "debug" || env.PH_CONNECT_LOG_LEVEL === "debug" ? void 0 : viteLogger({ silence: {
359
+ warnings: ["@import must precede all other statements (besides @charset or empty @layer)"],
360
+ errors: ["Unterminated string literal"]
361
+ } });
362
+ return {
363
+ configFile: false,
364
+ mode,
365
+ define: {
366
+ PH_PACKAGES: phPackages,
367
+ PH_PACKAGE_REGISTRY_URL: `"${phPackageRegistryUrl}"`
368
+ },
369
+ customLogger,
370
+ envPrefix: ["PH_CONNECT_"],
371
+ optimizeDeps: { exclude: ["@electric-sql/pglite", "@electric-sql/pglite-tools"] },
372
+ build: { rollupOptions: { external: [
373
+ "react",
374
+ "react-dom",
375
+ "react/jsx-runtime",
376
+ "react-dom/client"
377
+ ] } },
378
+ plugins,
379
+ worker: { format: "es" }
380
+ };
381
+ }
382
+ //#endregion
383
+ //#region connect-utils/vite-plugins/base.ts
384
+ const externalIds = [/^react(-dom)?(\/.*)?$/, /^node:.*$/];
385
+ function viteIgnoreStaticImport(_importKeys) {
386
+ const importKeys = _importKeys.filter((key) => typeof key === "string" || key instanceof RegExp);
387
+ return {
388
+ name: "vite-plugin-ignore-static-import",
389
+ enforce: "pre",
390
+ configResolved(resolvedConfig) {
391
+ const values = importKeys.map((key) => typeof key === "string" ? key : key.source);
392
+ const reg = new RegExp(`("|')\\/@id\\/(${values.join("|")})(\\/[^"'\\\\]*)?\\1`, "g");
393
+ resolvedConfig.plugins.push({
394
+ name: "vite-plugin-ignore-static-import-replace-idprefix",
395
+ transform: (code) => {
396
+ const s = new MagicString(code);
397
+ const matches = code.matchAll(reg);
398
+ let modified = false;
399
+ for (const match of matches) {
400
+ s.overwrite(match.index, match.index + match[0].length, match[0].replace("/@id/", ""));
401
+ modified = true;
402
+ }
403
+ if (!modified) return null;
404
+ return {
405
+ code: s.toString(),
406
+ map: s.generateMap({ hires: true })
407
+ };
408
+ }
409
+ });
410
+ },
411
+ resolveId: (id) => {
412
+ if (importKeys.some((key) => typeof key === "string" ? key === id : key.test(id))) return {
413
+ id,
414
+ external: true
415
+ };
416
+ },
417
+ load(id) {
418
+ if (importKeys.some((key) => typeof key === "string" ? key === id : key.test(id))) return "";
419
+ }
420
+ };
421
+ }
422
+ function viteReplaceImports(imports) {
423
+ const importKeys = Object.keys(imports);
424
+ return {
425
+ name: "vite-plugin-connect-replace-imports",
426
+ enforce: "pre",
427
+ config(config) {
428
+ const resolve = config.resolve ?? {};
429
+ const alias = resolve.alias;
430
+ let resolvedAlias;
431
+ if (Array.isArray(alias)) {
432
+ const arrayAlias = [...alias];
433
+ arrayAlias.push(...Object.entries(imports).map(([find, replacement]) => ({
434
+ find,
435
+ replacement
436
+ })));
437
+ resolvedAlias = arrayAlias;
438
+ } else if (typeof alias === "object") resolvedAlias = {
439
+ ...alias,
440
+ ...imports
441
+ };
442
+ else if (typeof alias === "undefined") resolvedAlias = { ...imports };
443
+ else console.error("resolve.alias was not recognized");
444
+ if (resolvedAlias) {
445
+ resolve.alias = resolvedAlias;
446
+ config.resolve = resolve;
447
+ }
448
+ },
449
+ resolveId: (id) => {
450
+ if (importKeys.includes(id)) return {
451
+ id,
452
+ external: true
453
+ };
454
+ }
455
+ };
456
+ }
457
+ async function findPackageJson(packageName) {
458
+ let packagePath;
459
+ try {
460
+ packagePath = createRequire(process.cwd()).resolve(packageName, { paths: [process.cwd()] });
461
+ } catch (err) {
462
+ throw new Error(`Failed to resolve package: ${packageName}`, { cause: err });
463
+ }
464
+ let dir = dirname(packagePath);
465
+ while (dir !== "/" && dir !== "." && dir !== "node_modules") {
466
+ if (basename(dir) === "dist") dir = dirname(dir);
467
+ const pkgJsonPath = `${dir}/package.json`;
468
+ try {
469
+ await fs$2.access(pkgJsonPath);
470
+ const file = await fs$2.readFile(pkgJsonPath, "utf-8");
471
+ return {
472
+ packageJson: JSON.parse(file),
473
+ path: dir
474
+ };
475
+ } catch {
476
+ dir = dirname(dir);
477
+ }
478
+ }
479
+ throw new Error(`package.json not found for ${packageName}`);
480
+ }
481
+ //#endregion
482
+ //#region connect-utils/vite-plugins/importmap.ts
483
+ const nodeModules = builtinModules.concat(builtinModules.map((m) => `node:${m}`));
484
+ /**
485
+ * Resolves glob exports like `"./*": "./dist/*.js"` and `"./utils/*": "./dist/utils/*.js"`
486
+ * into actual file mappings.
487
+ *
488
+ * @param {string} exportName - The export pattern (e.g., `"./*"` or `"./utils/*"`).
489
+ * @param {string} exportPath - The actual path pattern (e.g., `"./dist/*.js"`).
490
+ * @param {string} srcPath - The package root directory where the exports are located.
491
+ * @returns {Promise<Record<string, string>>} - A mapping of export names to resolved paths.
492
+ */
493
+ async function resolveGlobExport(exportName, exportPath, srcPath) {
494
+ const resolvedExports = /* @__PURE__ */ new Map();
495
+ const hasGloblExport = exportName.endsWith("/*");
496
+ const globPath = hasGloblExport ? exportPath.replace("*", "**/*") : exportPath;
497
+ const distPath = exportPath.substring(0, exportPath.lastIndexOf("/*"));
498
+ const resolvedSrcPath = hasGloblExport ? path.join(srcPath.replace("*", ""), distPath) : srcPath;
499
+ const files = await fg(path.join(srcPath, globPath));
500
+ for (const file of files) {
501
+ const relativeSrcFilePath = path.relative(resolvedSrcPath, file);
502
+ const exportFilePath = path.relative(srcPath, file);
503
+ const exportKey = relativeSrcFilePath.replace(path.extname(file), "");
504
+ const mappedExport = exportName.replace("*", exportKey);
505
+ resolvedExports.set(mappedExport, {
506
+ export: `./${relativeSrcFilePath}`,
507
+ file: exportFilePath
508
+ });
509
+ }
510
+ return resolvedExports;
511
+ }
512
+ async function addExportToMap(exportName, exportPath, srcPath, map) {
513
+ if (exportName.includes("*")) (await resolveGlobExport(exportName, exportPath, srcPath)).forEach((value, key) => map.set(key, value));
514
+ else map.set(exportName, {
515
+ export: exportPath,
516
+ file: exportPath
517
+ });
518
+ }
519
+ async function getPackageExports(name, packageJson, srcPath) {
520
+ const entries = /* @__PURE__ */ new Map();
521
+ const mainExport = exports(packageJson, ".", { browser: true });
522
+ if (mainExport) for (const entry of mainExport) await addExportToMap(".", entry, srcPath, entries);
523
+ if (!packageJson.exports) return entries;
524
+ if (typeof packageJson.exports === "string") {
525
+ await addExportToMap(name, packageJson.exports, srcPath, entries);
526
+ return entries;
527
+ }
528
+ for (const [key, entry] of Object.entries(packageJson.exports)) if (typeof entry === "string") await addExportToMap(key, entry, srcPath, entries);
529
+ else {
530
+ const exportResult = exports(packageJson, key, { browser: true })?.at(0);
531
+ if (exportResult) await addExportToMap(key, exportResult, srcPath, entries);
532
+ else console.warn(`No browser exports found for ${name}/${key}`);
533
+ }
534
+ const main = entries.get(".");
535
+ const resolvedExport = (main ? Array.from(entries.entries()).find(([key, entry]) => key != "." && [entry.file, `./${entry.file}`].includes(main.file)) : void 0)?.at(1);
536
+ if (resolvedExport) entries.set(".", {
537
+ export: resolvedExport.export,
538
+ file: resolvedExport.file
539
+ });
540
+ return entries;
541
+ }
542
+ function importFromEsmSh(name, version, dependencies) {
543
+ const lib = `${name}${version ? `@${version}` : ""}`;
544
+ const query = dependencies?.length ? `&deps=${dependencies.join(",")}` : "";
545
+ return {
546
+ [name]: `https://esm.sh/${lib}${query}`,
547
+ [`${name}/`]: `https://esm.sh/${lib}${query}/`
548
+ };
549
+ }
550
+ async function importFromNodeModules(name, modulesDir, importMapDeps, baseUrl) {
551
+ const importMap = {};
552
+ const { packageJson, path: srcPath } = await findPackageJson(name);
553
+ const entries = await getPackageExports(name, packageJson, srcPath);
554
+ if (!entries.size) throw new Error(`No browser exports found for ${name}`);
555
+ const indexFile = entries.get("")?.export || "index";
556
+ const fileName = path.basename(entries.get("")?.export || "index", path.extname(indexFile));
557
+ const outputPath = path.join(modulesDir, name);
558
+ const buildModule = () => {
559
+ console.log(`Bundling dependency: ${name}`);
560
+ return build({
561
+ entryPoints: Array.from(entries.values()).map((value) => path.join(srcPath, value.file)),
562
+ outdir: outputPath,
563
+ bundle: true,
564
+ format: "esm",
565
+ platform: "browser",
566
+ target: "esnext",
567
+ splitting: true,
568
+ external: nodeModules.concat(Array.from(importMapDeps)),
569
+ sourcemap: true,
570
+ minify: false
571
+ });
572
+ };
573
+ importMap[name] = `./modules/${name}/${fileName}.js`;
574
+ entries.forEach((entry, key) => {
575
+ importMap[path.join(name, key)] = path.join(baseUrl, `./modules/${path.join(name, entry.export)}`);
576
+ });
577
+ return {
578
+ importMap,
579
+ buildModule
580
+ };
581
+ }
582
+ async function generateImportMap(outputDir, dependencies, baseUrl) {
583
+ const modulesDir = path.join(outputDir, "/modules");
584
+ await fs$1.mkdir(modulesDir, { recursive: true });
585
+ const importMapDeps = new Set(dependencies.map((dep) => typeof dep === "string" ? dep : dep.name));
586
+ let importMap = {};
587
+ const buildModules = [];
588
+ for (const dependency of dependencies) {
589
+ const isString = typeof dependency === "string";
590
+ const name = isString ? dependency : dependency.name;
591
+ const version = isString ? void 0 : dependency.version;
592
+ const provider = isString ? "node_modules" : dependency.provider;
593
+ const subDependencies = isString ? void 0 : dependency.dependencies;
594
+ if (provider === "esm.sh") {
595
+ const imports = importFromEsmSh(name, version, subDependencies);
596
+ importMap = {
597
+ ...importMap,
598
+ ...imports
599
+ };
600
+ } else if (provider.toString() === "node_modules") {
601
+ const { importMap: imports, buildModule } = await importFromNodeModules(name, modulesDir, importMapDeps, baseUrl);
602
+ importMap = {
603
+ ...importMap,
604
+ ...imports
605
+ };
606
+ buildModules.push(buildModule);
607
+ } else throw new Error(`Unsupported provider: ${provider}`);
608
+ }
609
+ return {
610
+ importMap,
611
+ buildModules: async () => {
612
+ await Promise.all(buildModules.map((build) => build()));
613
+ }
614
+ };
615
+ }
616
+ function addImportMapToHTML(importMap, html) {
617
+ let newHtml = "";
618
+ const importMapRegex = /<script type="importmap">(.*?)<\/script>/s;
619
+ const match = importMapRegex.exec(html);
620
+ if (match) try {
621
+ const existingImportMap = JSON.parse(match[1]);
622
+ existingImportMap.imports = {
623
+ ...existingImportMap.imports,
624
+ ...importMap
625
+ };
626
+ const mergedImportMapString = JSON.stringify(existingImportMap, null, 2);
627
+ newHtml = html.replace(importMapRegex, `<script type="importmap">${mergedImportMapString}<\/script>`);
628
+ } catch (error) {
629
+ console.error("⚠️ Error parsing existing import map:", error);
630
+ }
631
+ else {
632
+ const importMapScript = `<script type="importmap">${JSON.stringify({ imports: importMap }, null, 2)}<\/script>`;
633
+ newHtml = html.replace("</head>", `${importMapScript}\n</head>`);
634
+ }
635
+ return newHtml;
636
+ }
637
+ /**
638
+ * Vite plugin to bundle or copy dependencies and inject an import map into `index.html`.
639
+ *
640
+ * @param {string} outputDir - The directory where the modules should be placed.
641
+ * @param {(string | { name: string; provider: string })[]} dependencies -
642
+ * List of dependencies to process. Can be:
643
+ * - A string (dependency is copied as is).
644
+ * - An object `{ name, provide }` where:
645
+ * - `name` (string): The module name.
646
+ * - `provider` (string): Where to retrieve the module bundle. Defaults to node_modules.
647
+ *
648
+ * @returns {Plugin} A Vite plugin that processes dependencies and injects an import map.
649
+ */
650
+ function generateImportMapPlugin(outputDir, dependencies) {
651
+ let buildModules = void 0;
652
+ let importMap = {};
653
+ return [{
654
+ name: "vite-plugin-importmap",
655
+ enforce: "post",
656
+ async configResolved(config) {
657
+ const result = await generateImportMap(outputDir, dependencies, config.base);
658
+ importMap = result.importMap;
659
+ buildModules = result.buildModules;
660
+ },
661
+ closeBundle() {
662
+ return buildModules?.();
663
+ },
664
+ configureServer() {
665
+ return buildModules?.();
666
+ },
667
+ transformIndexHtml(html) {
668
+ return addImportMapToHTML(importMap, html) || html;
669
+ }
670
+ }];
671
+ }
672
+ //#endregion
673
+ //#region connect-utils/vite-plugins/studio.ts
674
+ function viteConnectDevStudioPlugin(enabled = false, connectPath, env) {
675
+ return [enabled && viteIgnoreStaticImport([
676
+ "react",
677
+ "react-dom",
678
+ ...externalIds
679
+ ]), {
680
+ name: "vite-plugin-connect-dev-studio",
681
+ enforce: "pre",
682
+ config(config) {
683
+ if (!config.build) config.build = {};
684
+ if (!config.build.rollupOptions) config.build.rollupOptions = {};
685
+ if (!Array.isArray(config.build.rollupOptions.external)) config.build.rollupOptions.external = [];
686
+ if (enabled) config.build.rollupOptions.external.push(...externalIds);
687
+ },
688
+ closeBundle() {
689
+ if (!enabled) fs.copyFileSync(join(connectPath, "../.env"), join(connectPath, ".env"));
690
+ }
691
+ }];
692
+ }
693
+ //#endregion
694
+ export { DEFAULT_CONNECT_OUTDIR, EXTERNAL_PACKAGES_IMPORT, IMPORT_SCRIPT_FILE, LOCAL_PACKAGE_ID, PH_DIR_NAME, appendToHtmlHead, backupIndexHtml, commonConnectOptionsToEnv, connectClientConfig, copyConnect, ensureNodeVersion, externalIds, findPackageJson, generateImportMapPlugin, getConnectBaseViteConfig, makeImportScriptFromPackages, prependToHtmlHead, readJsonFile, removeBase64EnvValues, resolveConnectBundle, resolveConnectPackageJson, resolveConnectPublicDir, resolvePackage, resolveViteConfigPath, runShellScriptPlugin, runTsc, stripVersionFromPackage, viteConnectDevStudioPlugin, viteIgnoreStaticImport, viteReplaceImports };
695
+
696
+ //# sourceMappingURL=index.mjs.map