@xyd-js/documan 0.1.0-build.189
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/LICENSE +21 -0
- package/README.md +3 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +1943 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1943 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
19
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
20
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
21
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
22
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
23
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
24
|
+
mod
|
|
25
|
+
));
|
|
26
|
+
|
|
27
|
+
// ../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js
|
|
28
|
+
var require_picocolors = __commonJS({
|
|
29
|
+
"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js"(exports, module) {
|
|
30
|
+
var p = process || {};
|
|
31
|
+
var argv = p.argv || [];
|
|
32
|
+
var env = p.env || {};
|
|
33
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
34
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
35
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
36
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
37
|
+
};
|
|
38
|
+
var replaceClose = (string, close, replace, index) => {
|
|
39
|
+
let result = "", cursor = 0;
|
|
40
|
+
do {
|
|
41
|
+
result += string.substring(cursor, index) + replace;
|
|
42
|
+
cursor = index + close.length;
|
|
43
|
+
index = string.indexOf(close, cursor);
|
|
44
|
+
} while (~index);
|
|
45
|
+
return result + string.substring(cursor);
|
|
46
|
+
};
|
|
47
|
+
var createColors = (enabled = isColorSupported) => {
|
|
48
|
+
let f = enabled ? formatter : () => String;
|
|
49
|
+
return {
|
|
50
|
+
isColorSupported: enabled,
|
|
51
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
52
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
53
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
54
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
55
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
56
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
57
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
58
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
59
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
60
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
61
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
62
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
63
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
64
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
65
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
66
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
67
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
68
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
69
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
70
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
71
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
72
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
73
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
74
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
75
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
76
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
77
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
78
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
79
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
80
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
81
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
82
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
83
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
84
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
85
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
86
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
87
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
88
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
89
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
90
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
91
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
module.exports = createColors();
|
|
95
|
+
module.exports.createColors = createColors;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// src/build.ts
|
|
100
|
+
import path3 from "path";
|
|
101
|
+
import fs2 from "fs";
|
|
102
|
+
import { build as viteBuild } from "vite";
|
|
103
|
+
import tsconfigPaths from "vite-tsconfig-paths";
|
|
104
|
+
|
|
105
|
+
// src/utils.ts
|
|
106
|
+
import path2 from "path";
|
|
107
|
+
import fs from "fs";
|
|
108
|
+
import { fileURLToPath } from "url";
|
|
109
|
+
import { execSync as execSync2 } from "child_process";
|
|
110
|
+
import crypto from "crypto";
|
|
111
|
+
import { realpathSync } from "fs";
|
|
112
|
+
import { createServer } from "vite";
|
|
113
|
+
import { reactRouter } from "@react-router/dev/vite";
|
|
114
|
+
import { IconSet } from "@iconify/tools";
|
|
115
|
+
import { readSettings, pluginDocs } from "@xyd-js/plugin-docs";
|
|
116
|
+
import { vitePlugins as xydContentVitePlugins } from "@xyd-js/content/vite";
|
|
117
|
+
|
|
118
|
+
// src/const.ts
|
|
119
|
+
var XYD_FOLDER_PATH = ".xyd";
|
|
120
|
+
var HOST_FOLDER_PATH = `${XYD_FOLDER_PATH}/host`;
|
|
121
|
+
var CACHE_FOLDER_PATH = `${XYD_FOLDER_PATH}/.cache`;
|
|
122
|
+
var BUILD_FOLDER_PATH = `${XYD_FOLDER_PATH}/build`;
|
|
123
|
+
var SUPPORTED_SETTINGS_FILES = [
|
|
124
|
+
"docs.json",
|
|
125
|
+
"docs.ts",
|
|
126
|
+
"docs.tsx"
|
|
127
|
+
];
|
|
128
|
+
var SUPPORTED_CONTENT_FILES = [
|
|
129
|
+
".md",
|
|
130
|
+
".mdx"
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
// src/cli.ts
|
|
134
|
+
import readline from "readline";
|
|
135
|
+
import cliSpinners from "cli-spinners";
|
|
136
|
+
var CLI = class {
|
|
137
|
+
spinner;
|
|
138
|
+
spinnerInterval = null;
|
|
139
|
+
currentFrame = 0;
|
|
140
|
+
currentMessage = "";
|
|
141
|
+
isSpinning = false;
|
|
142
|
+
constructor(spinnerType = "dots") {
|
|
143
|
+
this.spinner = cliSpinners[spinnerType];
|
|
144
|
+
}
|
|
145
|
+
startSpinner(message) {
|
|
146
|
+
if (this.isSpinning) {
|
|
147
|
+
this.stopSpinner();
|
|
148
|
+
}
|
|
149
|
+
this.currentMessage = message;
|
|
150
|
+
this.isSpinning = true;
|
|
151
|
+
this.currentFrame = 0;
|
|
152
|
+
this.write(`${this.spinner.frames[0]} ${this.currentMessage}`);
|
|
153
|
+
this.spinnerInterval = setInterval(() => {
|
|
154
|
+
const frame = this.spinner.frames[this.currentFrame];
|
|
155
|
+
this.write(`${frame} ${this.currentMessage}`);
|
|
156
|
+
this.currentFrame = (this.currentFrame + 1) % this.spinner.frames.length;
|
|
157
|
+
}, this.spinner.interval);
|
|
158
|
+
}
|
|
159
|
+
stopSpinner() {
|
|
160
|
+
if (this.spinnerInterval) {
|
|
161
|
+
clearInterval(this.spinnerInterval);
|
|
162
|
+
this.spinnerInterval = null;
|
|
163
|
+
}
|
|
164
|
+
this.isSpinning = false;
|
|
165
|
+
this.clearLine();
|
|
166
|
+
}
|
|
167
|
+
clearLine() {
|
|
168
|
+
readline.clearLine(process.stdout, 0);
|
|
169
|
+
readline.cursorTo(process.stdout, 0);
|
|
170
|
+
}
|
|
171
|
+
write(message) {
|
|
172
|
+
this.clearLine();
|
|
173
|
+
process.stdout.write(message);
|
|
174
|
+
}
|
|
175
|
+
log(message) {
|
|
176
|
+
if (this.isSpinning) {
|
|
177
|
+
this.stopSpinner();
|
|
178
|
+
}
|
|
179
|
+
console.log(message);
|
|
180
|
+
}
|
|
181
|
+
error(message) {
|
|
182
|
+
if (this.isSpinning) {
|
|
183
|
+
this.stopSpinner();
|
|
184
|
+
}
|
|
185
|
+
console.error(message);
|
|
186
|
+
}
|
|
187
|
+
updateMessage(message) {
|
|
188
|
+
this.currentMessage = message;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
var cli = new CLI();
|
|
192
|
+
|
|
193
|
+
// src/componentsInstall.ts
|
|
194
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
195
|
+
import { execSync } from "child_process";
|
|
196
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
197
|
+
import path, { join } from "path";
|
|
198
|
+
import { createRequire } from "module";
|
|
199
|
+
function resolveModuleV2(fromDir, pkgName) {
|
|
200
|
+
const req = createRequire(import.meta.url);
|
|
201
|
+
let entry;
|
|
202
|
+
try {
|
|
203
|
+
entry = req.resolve(pkgName, { paths: [fromDir] });
|
|
204
|
+
} catch {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
let dir = path.dirname(entry);
|
|
208
|
+
while (true) {
|
|
209
|
+
const pj = path.join(dir, "package.json");
|
|
210
|
+
if (existsSync(pj)) {
|
|
211
|
+
try {
|
|
212
|
+
const json = JSON.parse(readFileSync(pj, "utf8"));
|
|
213
|
+
if (json && json.name === pkgName) return dir;
|
|
214
|
+
} catch {
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const parent = path.dirname(dir);
|
|
218
|
+
if (parent === dir) break;
|
|
219
|
+
dir = parent;
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
var xydContentPath = resolveModuleV2(getCLIRoot(), "@xyd-js/content");
|
|
224
|
+
var COMPONENTS = {
|
|
225
|
+
diagrams: {
|
|
226
|
+
packages: ["rehype-mermaid@^3.0.0", "playwright@^1.54.2"],
|
|
227
|
+
postInstall: ["npx playwright install --with-deps chromium"],
|
|
228
|
+
xydModules: [
|
|
229
|
+
xydContentPath || ""
|
|
230
|
+
]
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
async function componentsInstall(component, host) {
|
|
234
|
+
const config = resolveComponent(component, host);
|
|
235
|
+
if (!config) {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
await installComponent(config, component);
|
|
239
|
+
if (!host) {
|
|
240
|
+
saveComponent(component);
|
|
241
|
+
}
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
function saveComponent(component) {
|
|
245
|
+
const cliComponentsJson = getCLIComponentsJsonPath();
|
|
246
|
+
let shouldWriteJson = true;
|
|
247
|
+
try {
|
|
248
|
+
const existingComponents = JSON.parse(readFileSync(cliComponentsJson, "utf8"));
|
|
249
|
+
if (existingComponents.diagrams === true) {
|
|
250
|
+
shouldWriteJson = false;
|
|
251
|
+
}
|
|
252
|
+
} catch (error) {
|
|
253
|
+
shouldWriteJson = true;
|
|
254
|
+
}
|
|
255
|
+
const componentsConfig = { [component]: true };
|
|
256
|
+
writeFileSync(cliComponentsJson, JSON.stringify(componentsConfig, null, 2));
|
|
257
|
+
console.debug(import_picocolors.default.green(`\u2705 Components configuration written to ${cliComponentsJson}`));
|
|
258
|
+
}
|
|
259
|
+
function resolveComponent(component, host) {
|
|
260
|
+
if (!component) {
|
|
261
|
+
console.error(import_picocolors.default.red("Error: Component name is required"));
|
|
262
|
+
console.log(`Usage: xyd components install <component-name>`);
|
|
263
|
+
console.log(`Available components: ${Object.keys(COMPONENTS).join(", ")}`);
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
if (!COMPONENTS[component]) {
|
|
267
|
+
console.error(import_picocolors.default.red(`Error: Unknown component '${component}'`));
|
|
268
|
+
console.log(`Available components: ${Object.keys(COMPONENTS).join(", ")}`);
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
const config = COMPONENTS[component];
|
|
272
|
+
if (host) {
|
|
273
|
+
config.xydModules = [
|
|
274
|
+
path.resolve(getHostPath(), "node_modules/@xyd-js/content"),
|
|
275
|
+
getHostPath()
|
|
276
|
+
];
|
|
277
|
+
}
|
|
278
|
+
return config;
|
|
279
|
+
}
|
|
280
|
+
function componentDependencies(config, host) {
|
|
281
|
+
const deps = {};
|
|
282
|
+
if (typeof config === "string") {
|
|
283
|
+
const resolvedConfig = resolveComponent(config, host);
|
|
284
|
+
if (!resolvedConfig) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
config = resolvedConfig;
|
|
288
|
+
}
|
|
289
|
+
for (const pkg of config.packages) {
|
|
290
|
+
const [pkgName, version] = pkg.includes("@") && !pkg.startsWith("@") ? pkg.split("@") : [pkg, "latest"];
|
|
291
|
+
deps[pkgName] = version;
|
|
292
|
+
}
|
|
293
|
+
return deps;
|
|
294
|
+
}
|
|
295
|
+
async function installComponent(config, componentName) {
|
|
296
|
+
function install2(pathname) {
|
|
297
|
+
if (!config) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
console.log("\n", import_picocolors.default.gray(`Installing ${componentName} component...`));
|
|
301
|
+
try {
|
|
302
|
+
if (config.packages.length > 0) {
|
|
303
|
+
console.log(import_picocolors.default.gray(`Installing packages: ${config.packages.join(", ")}`));
|
|
304
|
+
const packageJsonPath = join(pathname, "package.json");
|
|
305
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
306
|
+
const packageJsonOriginal = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
307
|
+
for (const pkg of config.packages) {
|
|
308
|
+
const [pkgName, version] = pkg.includes("@") && !pkg.startsWith("@") ? pkg.split("@") : [pkg, "latest"];
|
|
309
|
+
packageJson.dependencies = packageJson.dependencies || {};
|
|
310
|
+
packageJson.dependencies[pkgName] = version;
|
|
311
|
+
}
|
|
312
|
+
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
313
|
+
nodeInstallPackages(pathname);
|
|
314
|
+
if (process.env.XYD_DEV_MODE) {
|
|
315
|
+
writeFileSync(packageJsonPath, JSON.stringify(packageJsonOriginal, null, 2));
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (config.postInstall) {
|
|
319
|
+
for (const cmd of config.postInstall) {
|
|
320
|
+
console.log(import_picocolors.default.gray(`Running: ${cmd}`));
|
|
321
|
+
execSync(cmd, {
|
|
322
|
+
cwd: pathname,
|
|
323
|
+
stdio: "inherit",
|
|
324
|
+
encoding: "utf8"
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
console.log(import_picocolors.default.green(`\u2705 ${componentName} component installed successfully!`));
|
|
329
|
+
} catch (error) {
|
|
330
|
+
console.error(import_picocolors.default.red(`\u274C Failed to install ${componentName} component:`));
|
|
331
|
+
console.error(error);
|
|
332
|
+
process.exit(1);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
for (const module of config.xydModules || []) {
|
|
336
|
+
install2(module);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// src/utils.ts
|
|
341
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
342
|
+
var __dirname = path2.dirname(__filename);
|
|
343
|
+
var ANALYTICS_INTEGRATION_DEPENDENCIES = {
|
|
344
|
+
livesession: {
|
|
345
|
+
"@pluganalytics/provider-livesession": "0.0.0-pre.7"
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
var EXTERNAL_XYD_PLUGINS = {
|
|
349
|
+
"@xyd-js/plugin-supademo": "0.0.0",
|
|
350
|
+
"@xyd-js/plugin-chatwoot": "0.0.0",
|
|
351
|
+
"@xyd-js/plugin-intercom": "0.0.0",
|
|
352
|
+
"@xyd-js/plugin-livechat": "0.0.0"
|
|
353
|
+
};
|
|
354
|
+
async function appInit(options) {
|
|
355
|
+
const readPreloadSettings = await readSettings();
|
|
356
|
+
if (!readPreloadSettings) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
const preloadSettings = typeof readPreloadSettings === "string" ? JSON.parse(readPreloadSettings) : readPreloadSettings;
|
|
360
|
+
{
|
|
361
|
+
if (!preloadSettings.integrations?.search) {
|
|
362
|
+
preloadSettings.integrations = {
|
|
363
|
+
...preloadSettings.integrations || {},
|
|
364
|
+
search: {
|
|
365
|
+
orama: true
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
const plugins = integrationsToPlugins(preloadSettings.integrations);
|
|
370
|
+
if (preloadSettings.plugins) {
|
|
371
|
+
preloadSettings.plugins = [...plugins, ...preloadSettings.plugins];
|
|
372
|
+
} else {
|
|
373
|
+
preloadSettings.plugins = plugins;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
let resolvedPlugins = [];
|
|
377
|
+
{
|
|
378
|
+
resolvedPlugins = await loadPlugins(preloadSettings, options) || [];
|
|
379
|
+
const userUniformVitePlugins = [];
|
|
380
|
+
const componentPlugins = [];
|
|
381
|
+
resolvedPlugins?.forEach((p) => {
|
|
382
|
+
if (p.uniform) {
|
|
383
|
+
userUniformVitePlugins.push(...p.uniform);
|
|
384
|
+
}
|
|
385
|
+
if (p.components) {
|
|
386
|
+
const components = [];
|
|
387
|
+
if (!Array.isArray(p.components) && typeof p.components === "object") {
|
|
388
|
+
const mapComponents = [];
|
|
389
|
+
Object.keys(p.components).forEach((key) => {
|
|
390
|
+
if (!p?.components?.[key]) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const component = p.components[key];
|
|
394
|
+
mapComponents.push({
|
|
395
|
+
component,
|
|
396
|
+
name: key
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
p.components = mapComponents;
|
|
400
|
+
}
|
|
401
|
+
if (Array.isArray(p.components)) {
|
|
402
|
+
for (const component of p.components) {
|
|
403
|
+
if (!component.component) {
|
|
404
|
+
console.error("No component function");
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
if (!component.name) {
|
|
408
|
+
component.name = component.component.name;
|
|
409
|
+
}
|
|
410
|
+
if (!component.dist) {
|
|
411
|
+
component.dist = p._pluginPkg + "/" + component.name;
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
if (!component.name) {
|
|
415
|
+
console.error("No component name");
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
components.push(...p.components);
|
|
420
|
+
}
|
|
421
|
+
componentPlugins.push(...components);
|
|
422
|
+
}
|
|
423
|
+
const head = p.head;
|
|
424
|
+
if (head?.length && preloadSettings?.theme?.head) {
|
|
425
|
+
preloadSettings.theme.head.push(
|
|
426
|
+
...head
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
globalThis.__xydUserUniformVitePlugins = userUniformVitePlugins;
|
|
431
|
+
globalThis.__xydUserComponents = componentPlugins;
|
|
432
|
+
}
|
|
433
|
+
const respPluginDocs = await pluginDocs({
|
|
434
|
+
...options,
|
|
435
|
+
appInit
|
|
436
|
+
});
|
|
437
|
+
if (!respPluginDocs) {
|
|
438
|
+
throw new Error("PluginDocs not found");
|
|
439
|
+
}
|
|
440
|
+
if (!respPluginDocs.settings) {
|
|
441
|
+
throw new Error("Settings not found in respPluginDocs");
|
|
442
|
+
}
|
|
443
|
+
respPluginDocs.settings.plugins = [
|
|
444
|
+
...respPluginDocs.settings?.plugins || [],
|
|
445
|
+
...preloadSettings.plugins || []
|
|
446
|
+
];
|
|
447
|
+
if (respPluginDocs.settings?.theme) {
|
|
448
|
+
respPluginDocs.settings.theme.head = [
|
|
449
|
+
...respPluginDocs.settings?.theme?.head || [],
|
|
450
|
+
...preloadSettings.theme?.head || []
|
|
451
|
+
];
|
|
452
|
+
}
|
|
453
|
+
globalThis.__xydBasePath = respPluginDocs.basePath;
|
|
454
|
+
globalThis.__xydSettings = respPluginDocs.settings;
|
|
455
|
+
globalThis.__xydPagePathMapping = respPluginDocs.pagePathMapping;
|
|
456
|
+
globalThis.__xydHasIndexPage = respPluginDocs.hasIndexPage;
|
|
457
|
+
globalThis.__xydSettingsClone = JSON.parse(JSON.stringify(respPluginDocs.settings));
|
|
458
|
+
if (respPluginDocs.settings.integrations?.diagrams) {
|
|
459
|
+
if (!componentExists("diagrams")) {
|
|
460
|
+
await componentsInstall("diagrams");
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return {
|
|
464
|
+
respPluginDocs,
|
|
465
|
+
resolvedPlugins
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
function virtualComponentsPlugin() {
|
|
469
|
+
return {
|
|
470
|
+
name: "xyd-plugin-virtual-components",
|
|
471
|
+
resolveId(id) {
|
|
472
|
+
if (id === "virtual:xyd-user-components") {
|
|
473
|
+
return id + ".jsx";
|
|
474
|
+
}
|
|
475
|
+
return null;
|
|
476
|
+
},
|
|
477
|
+
async load(id) {
|
|
478
|
+
if (id === "virtual:xyd-user-components.jsx") {
|
|
479
|
+
const userComponents = globalThis.__xydUserComponents || [];
|
|
480
|
+
if (userComponents.length > 0 && userComponents[0]?.component) {
|
|
481
|
+
const imports = userComponents.map(
|
|
482
|
+
(component, index) => `import Component${index} from '${component.dist}';`
|
|
483
|
+
).join("\n");
|
|
484
|
+
const componentObjects = userComponents.map(
|
|
485
|
+
(component, index) => `{
|
|
486
|
+
component: Component${index},
|
|
487
|
+
name: '${component.name}',
|
|
488
|
+
dist: '${component.dist}'
|
|
489
|
+
}`
|
|
490
|
+
).join(",\n ");
|
|
491
|
+
return `
|
|
492
|
+
// Pre-bundled at build time - no async loading needed
|
|
493
|
+
${imports}
|
|
494
|
+
|
|
495
|
+
export const components = [
|
|
496
|
+
${componentObjects}
|
|
497
|
+
];
|
|
498
|
+
`;
|
|
499
|
+
}
|
|
500
|
+
return `
|
|
501
|
+
export const components = globalThis.__xydUserComponents || []
|
|
502
|
+
`;
|
|
503
|
+
}
|
|
504
|
+
return null;
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
function virtualProvidersPlugin(settings) {
|
|
509
|
+
return {
|
|
510
|
+
name: "xyd-plugin-virtual-providers",
|
|
511
|
+
enforce: "pre",
|
|
512
|
+
resolveId(id) {
|
|
513
|
+
if (id === "virtual:xyd-analytics-providers") {
|
|
514
|
+
return id;
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
async load(id) {
|
|
518
|
+
if (id === "virtual:xyd-analytics-providers") {
|
|
519
|
+
const providers = Object.keys(settings?.integrations?.analytics || {});
|
|
520
|
+
const imports = providers.map(
|
|
521
|
+
(provider) => `import { default as ${provider}Provider } from '@pluganalytics/provider-${provider}'`
|
|
522
|
+
).join("\n");
|
|
523
|
+
const cases = providers.map(
|
|
524
|
+
(provider) => `case '${provider}': return ${provider}Provider`
|
|
525
|
+
).join("\n");
|
|
526
|
+
return `
|
|
527
|
+
${imports}
|
|
528
|
+
|
|
529
|
+
export const loadProvider = async (provider) => {
|
|
530
|
+
switch (provider) {
|
|
531
|
+
${cases}
|
|
532
|
+
default:
|
|
533
|
+
console.error(\`Provider \${provider} not found\`)
|
|
534
|
+
return null
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
`;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
async function commonVitePlugins(respPluginDocs, resolvedPlugins) {
|
|
543
|
+
const userVitePlugins = resolvedPlugins.map((p) => p.vite).flat() || [];
|
|
544
|
+
return [
|
|
545
|
+
...await xydContentVitePlugins({
|
|
546
|
+
toc: {
|
|
547
|
+
maxDepth: respPluginDocs.settings.theme?.writer?.maxTocDepth || 2
|
|
548
|
+
},
|
|
549
|
+
settings: respPluginDocs.settings
|
|
550
|
+
}),
|
|
551
|
+
...respPluginDocs.vitePlugins,
|
|
552
|
+
reactRouter(),
|
|
553
|
+
virtualComponentsPlugin(),
|
|
554
|
+
virtualProvidersPlugin(respPluginDocs.settings),
|
|
555
|
+
pluginIconSet(respPluginDocs.settings),
|
|
556
|
+
...userVitePlugins
|
|
557
|
+
];
|
|
558
|
+
}
|
|
559
|
+
function commonPostInstallVitePlugins(respPluginDocs, resolvedPlugins) {
|
|
560
|
+
return [
|
|
561
|
+
vitePluginThemePresets(respPluginDocs.settings)
|
|
562
|
+
];
|
|
563
|
+
}
|
|
564
|
+
async function vitePluginThemePresets(settings) {
|
|
565
|
+
const themeName = settings.theme?.name;
|
|
566
|
+
const VIRTUAL_ID = "virtual:xyd-theme-presets";
|
|
567
|
+
const RESOLVED_ID = "\0" + VIRTUAL_ID;
|
|
568
|
+
const __filename2 = fileURLToPath(import.meta.url);
|
|
569
|
+
const __dirname2 = path2.dirname(__filename2);
|
|
570
|
+
let themeRoot = "";
|
|
571
|
+
if (process.env.XYD_CLI) {
|
|
572
|
+
themeRoot = path2.join(getHostPath(), `node_modules/@xyd-js/theme-${themeName}/dist`);
|
|
573
|
+
} else {
|
|
574
|
+
themeRoot = path2.join(path2.resolve(__dirname2, "../../"), `xyd-theme-${themeName}/dist`);
|
|
575
|
+
}
|
|
576
|
+
const presetsDir = path2.join(themeRoot, "presets");
|
|
577
|
+
let cssFiles = [];
|
|
578
|
+
try {
|
|
579
|
+
const files = fs.readdirSync(presetsDir);
|
|
580
|
+
cssFiles = files.filter((f) => f.endsWith(".css"));
|
|
581
|
+
} catch (err) {
|
|
582
|
+
}
|
|
583
|
+
const importStmts = [];
|
|
584
|
+
const mapEntries = [];
|
|
585
|
+
cssFiles.forEach((file, index) => {
|
|
586
|
+
const name = file.replace(/\.css$/, "");
|
|
587
|
+
const varName = `preset${index}`;
|
|
588
|
+
const pkgPath = `@xyd-js/theme-${themeName}/presets/${file}`;
|
|
589
|
+
importStmts.push(`import ${varName} from '${pkgPath}?url';`);
|
|
590
|
+
mapEntries.push(` '${name}': ${varName}`);
|
|
591
|
+
});
|
|
592
|
+
return {
|
|
593
|
+
name: "xyd:virtual-theme-presets",
|
|
594
|
+
resolveId(id) {
|
|
595
|
+
return id === VIRTUAL_ID ? RESOLVED_ID : null;
|
|
596
|
+
},
|
|
597
|
+
load(id) {
|
|
598
|
+
if (id !== RESOLVED_ID) return null;
|
|
599
|
+
return `
|
|
600
|
+
${importStmts.join("\n")}
|
|
601
|
+
|
|
602
|
+
export const presetUrls = {
|
|
603
|
+
${mapEntries.join(",\n")}
|
|
604
|
+
};
|
|
605
|
+
`;
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
function pluginIconSet(settings) {
|
|
610
|
+
const DEFAULT_ICON_SET = "lucide";
|
|
611
|
+
async function fetchIconSet(name, version) {
|
|
612
|
+
if (name.startsWith("http://") || name.startsWith("https://")) {
|
|
613
|
+
try {
|
|
614
|
+
const iconsResp = await fetch(name);
|
|
615
|
+
const iconsData = await iconsResp.json();
|
|
616
|
+
const iconSet = new IconSet(iconsData);
|
|
617
|
+
return { icons: iconsData, iconSet };
|
|
618
|
+
} catch (error) {
|
|
619
|
+
console.warn(`Failed to fetch from URL ${name}:`, error);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
const tryReadFile = (filePath) => {
|
|
623
|
+
try {
|
|
624
|
+
if (!fs.existsSync(filePath)) {
|
|
625
|
+
console.warn(`File does not exist: ${filePath}`);
|
|
626
|
+
return null;
|
|
627
|
+
}
|
|
628
|
+
const fileContent = fs.readFileSync(filePath, "utf-8");
|
|
629
|
+
try {
|
|
630
|
+
const iconsData = JSON.parse(fileContent);
|
|
631
|
+
const iconSet = new IconSet(iconsData);
|
|
632
|
+
return { icons: iconsData, iconSet };
|
|
633
|
+
} catch (parseError) {
|
|
634
|
+
console.warn(`Invalid JSON in file ${filePath}:`, parseError);
|
|
635
|
+
return null;
|
|
636
|
+
}
|
|
637
|
+
} catch (error) {
|
|
638
|
+
console.warn(`Failed to read file ${filePath}:`, error);
|
|
639
|
+
return null;
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
if (path2.isAbsolute(name)) {
|
|
643
|
+
const result = tryReadFile(name);
|
|
644
|
+
if (result) return result;
|
|
645
|
+
}
|
|
646
|
+
if (name.startsWith(".")) {
|
|
647
|
+
const fullPath = path2.join(process.cwd(), name);
|
|
648
|
+
const result = tryReadFile(fullPath);
|
|
649
|
+
if (result) return result;
|
|
650
|
+
}
|
|
651
|
+
const cdnUrl = version ? `https://cdn.jsdelivr.net/npm/@iconify-json/${name}@${version}/icons.json` : `https://cdn.jsdelivr.net/npm/@iconify-json/${name}/icons.json`;
|
|
652
|
+
try {
|
|
653
|
+
const iconsResp = await fetch(cdnUrl);
|
|
654
|
+
const iconsData = await iconsResp.json();
|
|
655
|
+
const iconSet = new IconSet(iconsData);
|
|
656
|
+
return { icons: iconsData, iconSet };
|
|
657
|
+
} catch (error) {
|
|
658
|
+
throw new Error(`Failed to load icon set from any source (file or CDN): ${name}`);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
async function processIconSet(iconSet, icons, noPrefix) {
|
|
662
|
+
const resp = /* @__PURE__ */ new Map();
|
|
663
|
+
for (const icon of Object.keys(icons.icons)) {
|
|
664
|
+
const svg = iconSet.toSVG(icon);
|
|
665
|
+
if (!svg) continue;
|
|
666
|
+
let prefix = noPrefix ? void 0 : iconSet.prefix;
|
|
667
|
+
const iconName = prefix ? `${prefix}:${icon}` : icon;
|
|
668
|
+
resp.set(iconName, { svg: svg.toString() });
|
|
669
|
+
}
|
|
670
|
+
return resp;
|
|
671
|
+
}
|
|
672
|
+
async function addIconsToMap(resp, name, version, noPrefix) {
|
|
673
|
+
const { icons, iconSet } = await fetchIconSet(name, version);
|
|
674
|
+
const newIcons = await processIconSet(iconSet, icons, noPrefix);
|
|
675
|
+
newIcons.forEach((value, key) => resp.set(key, value));
|
|
676
|
+
}
|
|
677
|
+
async function processIconLibrary(library) {
|
|
678
|
+
const resp = /* @__PURE__ */ new Map();
|
|
679
|
+
if (typeof library === "string") {
|
|
680
|
+
await addIconsToMap(resp, library);
|
|
681
|
+
} else if (Array.isArray(library)) {
|
|
682
|
+
for (const item of library) {
|
|
683
|
+
if (typeof item === "string") {
|
|
684
|
+
await addIconsToMap(resp, item);
|
|
685
|
+
} else {
|
|
686
|
+
const { name, version, default: isDefault, noprefix } = item;
|
|
687
|
+
const noPrefix = isDefault || noprefix === true;
|
|
688
|
+
await addIconsToMap(resp, name, version, noPrefix);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
} else {
|
|
692
|
+
const { name, version, default: isDefault, noprefix } = library;
|
|
693
|
+
const noPrefix = isDefault || noprefix === true;
|
|
694
|
+
await addIconsToMap(resp, name, version, noPrefix);
|
|
695
|
+
}
|
|
696
|
+
return resp;
|
|
697
|
+
}
|
|
698
|
+
return {
|
|
699
|
+
name: "xyd-plugin-icon-set",
|
|
700
|
+
enforce: "pre",
|
|
701
|
+
resolveId(id) {
|
|
702
|
+
if (id === "virtual:xyd-icon-set") {
|
|
703
|
+
return id;
|
|
704
|
+
}
|
|
705
|
+
},
|
|
706
|
+
async load(id) {
|
|
707
|
+
if (id === "virtual:xyd-icon-set") {
|
|
708
|
+
let resp;
|
|
709
|
+
if (settings.theme?.icons?.library) {
|
|
710
|
+
resp = await processIconLibrary(settings.theme.icons.library);
|
|
711
|
+
} else {
|
|
712
|
+
resp = await processIconLibrary([
|
|
713
|
+
{
|
|
714
|
+
name: DEFAULT_ICON_SET,
|
|
715
|
+
default: true
|
|
716
|
+
}
|
|
717
|
+
]);
|
|
718
|
+
}
|
|
719
|
+
return `
|
|
720
|
+
export const iconSet = ${JSON.stringify(Object.fromEntries(resp))};
|
|
721
|
+
`;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
function getXydFolderPath() {
|
|
727
|
+
return path2.join(
|
|
728
|
+
process.cwd(),
|
|
729
|
+
XYD_FOLDER_PATH
|
|
730
|
+
);
|
|
731
|
+
}
|
|
732
|
+
function getCLIRoot() {
|
|
733
|
+
const cliPath = realpathSync(process.argv[1]);
|
|
734
|
+
return path2.dirname(path2.dirname(cliPath));
|
|
735
|
+
}
|
|
736
|
+
function getCLIComponentsJsonPath() {
|
|
737
|
+
return path2.join(getCLIRoot(), "cliComponents.json");
|
|
738
|
+
}
|
|
739
|
+
function componentExists(component) {
|
|
740
|
+
const cliComponentsJson = getCLIComponentsJsonPath();
|
|
741
|
+
try {
|
|
742
|
+
const components = JSON.parse(fs.readFileSync(cliComponentsJson, "utf8"));
|
|
743
|
+
return components[component] === true;
|
|
744
|
+
} catch (error) {
|
|
745
|
+
return false;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
function getHostPath() {
|
|
749
|
+
if (process.env.XYD_DEV_MODE) {
|
|
750
|
+
if (process.env.XYD_HOST) {
|
|
751
|
+
return path2.resolve(process.env.XYD_HOST);
|
|
752
|
+
}
|
|
753
|
+
return path2.join(__dirname, "../../../", HOST_FOLDER_PATH);
|
|
754
|
+
}
|
|
755
|
+
return path2.join(process.cwd(), HOST_FOLDER_PATH);
|
|
756
|
+
}
|
|
757
|
+
function getAppRoot() {
|
|
758
|
+
return getHostPath();
|
|
759
|
+
}
|
|
760
|
+
function getPublicPath() {
|
|
761
|
+
return path2.join(process.cwd(), "public");
|
|
762
|
+
}
|
|
763
|
+
function getBuildPath() {
|
|
764
|
+
return path2.join(
|
|
765
|
+
process.cwd(),
|
|
766
|
+
BUILD_FOLDER_PATH
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
function getDocsPluginBasePath() {
|
|
770
|
+
return path2.join(getHostPath(), "./plugins/xyd-plugin-docs");
|
|
771
|
+
}
|
|
772
|
+
async function loadPlugins(settings, options) {
|
|
773
|
+
const resolvedPlugins = [];
|
|
774
|
+
if (settings.plugins?.length && !options?.doNotInstallPluginDependencies) {
|
|
775
|
+
await setupPluginDependencies(settings, true);
|
|
776
|
+
}
|
|
777
|
+
const pluginSettingsFreeze = deepCloneAndFreeze(settings);
|
|
778
|
+
for (const plugin of settings.plugins || []) {
|
|
779
|
+
let pluginName;
|
|
780
|
+
let pluginArgs = [];
|
|
781
|
+
if (typeof plugin === "string") {
|
|
782
|
+
pluginName = plugin;
|
|
783
|
+
pluginArgs = [];
|
|
784
|
+
} else if (Array.isArray(plugin)) {
|
|
785
|
+
pluginName = plugin[0];
|
|
786
|
+
pluginArgs = plugin.slice(1);
|
|
787
|
+
} else {
|
|
788
|
+
console.error(`Currently only string and array plugins are supported, got: ${plugin}`);
|
|
789
|
+
return [];
|
|
790
|
+
}
|
|
791
|
+
let mod;
|
|
792
|
+
try {
|
|
793
|
+
mod = await import(pluginName);
|
|
794
|
+
} catch (e) {
|
|
795
|
+
pluginName = path2.join(process.cwd(), pluginName);
|
|
796
|
+
const pluginPreview = await createServer({
|
|
797
|
+
optimizeDeps: {
|
|
798
|
+
include: []
|
|
799
|
+
}
|
|
800
|
+
});
|
|
801
|
+
mod = await pluginPreview.ssrLoadModule(pluginName);
|
|
802
|
+
}
|
|
803
|
+
if (!mod.default) {
|
|
804
|
+
console.error(`Plugin ${plugin} has no default export`);
|
|
805
|
+
continue;
|
|
806
|
+
}
|
|
807
|
+
let pluginInstance = mod.default(...pluginArgs);
|
|
808
|
+
if (typeof pluginInstance === "function") {
|
|
809
|
+
const plug = pluginInstance(pluginSettingsFreeze);
|
|
810
|
+
resolvedPlugins.push({
|
|
811
|
+
...plug,
|
|
812
|
+
_pluginPkg: pluginName
|
|
813
|
+
});
|
|
814
|
+
continue;
|
|
815
|
+
}
|
|
816
|
+
resolvedPlugins.push({
|
|
817
|
+
...pluginInstance,
|
|
818
|
+
_pluginPkg: pluginName
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
return resolvedPlugins;
|
|
822
|
+
}
|
|
823
|
+
function deepCloneAndFreeze(obj) {
|
|
824
|
+
if (obj === null || typeof obj !== "object") return obj;
|
|
825
|
+
const clone = Array.isArray(obj) ? [] : {};
|
|
826
|
+
for (const key in obj) {
|
|
827
|
+
if (Object.hasOwn(obj, key)) {
|
|
828
|
+
clone[key] = deepCloneAndFreeze(obj[key]);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
return Object.freeze(clone);
|
|
832
|
+
}
|
|
833
|
+
function integrationsToPlugins(integrations) {
|
|
834
|
+
const plugins = [];
|
|
835
|
+
let foundSearchIntegation = 0;
|
|
836
|
+
if (integrations?.search?.orama) {
|
|
837
|
+
if (typeof integrations.search.orama === "boolean") {
|
|
838
|
+
plugins.push("@xyd-js/plugin-orama");
|
|
839
|
+
} else {
|
|
840
|
+
plugins.push(["@xyd-js/plugin-orama", integrations.search.orama]);
|
|
841
|
+
}
|
|
842
|
+
foundSearchIntegation++;
|
|
843
|
+
}
|
|
844
|
+
if (integrations?.search?.algolia) {
|
|
845
|
+
plugins.push(["@xyd-js/plugin-algolia", integrations.search.algolia]);
|
|
846
|
+
foundSearchIntegation++;
|
|
847
|
+
}
|
|
848
|
+
if (foundSearchIntegation > 1) {
|
|
849
|
+
throw new Error("Only one search integration is allowed");
|
|
850
|
+
}
|
|
851
|
+
if (integrations?.[".apps"]?.supademo) {
|
|
852
|
+
plugins.push(["@xyd-js/plugin-supademo", integrations[".apps"].supademo]);
|
|
853
|
+
}
|
|
854
|
+
if (integrations?.support?.chatwoot) {
|
|
855
|
+
plugins.push([
|
|
856
|
+
"@xyd-js/plugin-chatwoot",
|
|
857
|
+
integrations.support.chatwoot
|
|
858
|
+
]);
|
|
859
|
+
}
|
|
860
|
+
if (integrations?.support?.intercom) {
|
|
861
|
+
plugins.push([
|
|
862
|
+
"@xyd-js/plugin-intercom",
|
|
863
|
+
integrations.support.intercom
|
|
864
|
+
]);
|
|
865
|
+
}
|
|
866
|
+
if (integrations?.support?.livechat) {
|
|
867
|
+
plugins.push([
|
|
868
|
+
"@xyd-js/plugin-livechat",
|
|
869
|
+
integrations.support.livechat
|
|
870
|
+
]);
|
|
871
|
+
}
|
|
872
|
+
return plugins;
|
|
873
|
+
}
|
|
874
|
+
async function preWorkspaceSetup(options = {}) {
|
|
875
|
+
await ensureFoldersExist();
|
|
876
|
+
if (!options.force) {
|
|
877
|
+
if (await shouldSkipHostSetup()) {
|
|
878
|
+
return true;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
const hostTemplate = process.env.XYD_DEV_MODE ? path2.resolve(__dirname, "../../xyd-host") : path2.resolve(__dirname, "../../host");
|
|
882
|
+
const hostPath = getHostPath();
|
|
883
|
+
await copyHostTemplate(hostTemplate, hostPath);
|
|
884
|
+
let pluginDocsPath;
|
|
885
|
+
if (process.env.XYD_DEV_MODE) {
|
|
886
|
+
pluginDocsPath = path2.resolve(__dirname, "../../xyd-plugin-docs");
|
|
887
|
+
} else {
|
|
888
|
+
pluginDocsPath = path2.resolve(__dirname, "../../plugin-docs");
|
|
889
|
+
}
|
|
890
|
+
const pagesSourcePath = path2.join(pluginDocsPath, "src/pages");
|
|
891
|
+
const pagesTargetPath = path2.join(hostPath, "plugins/xyd-plugin-docs/src/pages");
|
|
892
|
+
if (fs.existsSync(pagesSourcePath)) {
|
|
893
|
+
await copyHostTemplate(pagesSourcePath, pagesTargetPath);
|
|
894
|
+
} else {
|
|
895
|
+
console.warn(`Pages source path does not exist: ${pagesSourcePath}`);
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
function calculateFolderChecksum(folderPath) {
|
|
899
|
+
const hash = crypto.createHash("sha256");
|
|
900
|
+
const ignorePatterns = [...getGitignorePatterns(folderPath), ".xydchecksum", "node_modules", "dist", ".react-router", "package-lock.json", "pnpm-lock.yaml", "cliComponents.json"];
|
|
901
|
+
function processFile(filePath) {
|
|
902
|
+
const relativePath = path2.relative(folderPath, filePath);
|
|
903
|
+
const content = fs.readFileSync(filePath);
|
|
904
|
+
hash.update(relativePath);
|
|
905
|
+
hash.update(content);
|
|
906
|
+
}
|
|
907
|
+
function processDirectory(dirPath) {
|
|
908
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
909
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
910
|
+
for (const entry of entries) {
|
|
911
|
+
const sourceEntry = path2.join(dirPath, entry.name);
|
|
912
|
+
if (shouldIgnoreEntry(entry.name, ignorePatterns)) {
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
if (entry.name === ".git") {
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
918
|
+
if (entry.isDirectory()) {
|
|
919
|
+
processDirectory(sourceEntry);
|
|
920
|
+
} else {
|
|
921
|
+
processFile(sourceEntry);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
processDirectory(folderPath);
|
|
926
|
+
return hash.digest("hex");
|
|
927
|
+
}
|
|
928
|
+
function getGitignorePatterns(folderPath) {
|
|
929
|
+
const gitignorePath = path2.join(folderPath, ".gitignore");
|
|
930
|
+
if (fs.existsSync(gitignorePath)) {
|
|
931
|
+
const gitignoreContent = fs.readFileSync(gitignorePath, "utf-8");
|
|
932
|
+
return gitignoreContent.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
933
|
+
}
|
|
934
|
+
return [];
|
|
935
|
+
}
|
|
936
|
+
function shouldIgnoreEntry(entryName, ignorePatterns) {
|
|
937
|
+
return ignorePatterns.some((pattern) => {
|
|
938
|
+
const regex = new RegExp(pattern.replace(/\*/g, ".*"));
|
|
939
|
+
return regex.test(entryName);
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
async function copyHostTemplate(sourcePath, targetPath) {
|
|
943
|
+
if (!fs.existsSync(sourcePath)) {
|
|
944
|
+
throw new Error(`Host template source path does not exist: ${sourcePath}`);
|
|
945
|
+
}
|
|
946
|
+
if (fs.existsSync(targetPath)) {
|
|
947
|
+
fs.rmSync(targetPath, { recursive: true, force: true });
|
|
948
|
+
}
|
|
949
|
+
fs.mkdirSync(targetPath, { recursive: true });
|
|
950
|
+
const ignorePatterns = getGitignorePatterns(sourcePath);
|
|
951
|
+
const entries = fs.readdirSync(sourcePath, { withFileTypes: true });
|
|
952
|
+
for (const entry of entries) {
|
|
953
|
+
const sourceEntry = path2.join(sourcePath, entry.name);
|
|
954
|
+
const targetEntry = path2.join(targetPath, entry.name);
|
|
955
|
+
if (shouldIgnoreEntry(entry.name, ignorePatterns)) {
|
|
956
|
+
continue;
|
|
957
|
+
}
|
|
958
|
+
if (entry.name === ".git") {
|
|
959
|
+
continue;
|
|
960
|
+
}
|
|
961
|
+
if (entry.isDirectory()) {
|
|
962
|
+
await copyHostTemplate(sourceEntry, targetEntry);
|
|
963
|
+
} else {
|
|
964
|
+
fs.copyFileSync(sourceEntry, targetEntry);
|
|
965
|
+
if (entry.name === "package.json" && process.env.XYD_DEV_MODE) {
|
|
966
|
+
const packageJsonPath = targetEntry;
|
|
967
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
968
|
+
packageJson.name = "xyd-host-dev";
|
|
969
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
async function ensureFoldersExist() {
|
|
975
|
+
const folders = [CACHE_FOLDER_PATH];
|
|
976
|
+
for (const folder of folders) {
|
|
977
|
+
const fullPath = path2.resolve(process.cwd(), folder);
|
|
978
|
+
if (!fs.existsSync(fullPath)) {
|
|
979
|
+
fs.mkdirSync(fullPath, { recursive: true });
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
async function postWorkspaceSetup(settings) {
|
|
984
|
+
const spinner = new CLI("dots");
|
|
985
|
+
try {
|
|
986
|
+
spinner.startSpinner("Installing xyd framework...");
|
|
987
|
+
const hostPath = getHostPath();
|
|
988
|
+
const packageJsonPath = path2.join(hostPath, "package.json");
|
|
989
|
+
const packageJson = await hostPackageJson();
|
|
990
|
+
const integrationDeps = await setupIntegationDependencies(settings);
|
|
991
|
+
const pluginDeps = await setupPluginDependencies(settings);
|
|
992
|
+
packageJson.dependencies = {
|
|
993
|
+
...integrationDeps,
|
|
994
|
+
...packageJson.dependencies,
|
|
995
|
+
...pluginDeps
|
|
996
|
+
};
|
|
997
|
+
if (settings.integrations?.diagrams) {
|
|
998
|
+
const componentDeps = componentDependencies("diagrams", true);
|
|
999
|
+
if (componentDeps) {
|
|
1000
|
+
packageJson.dependencies = {
|
|
1001
|
+
...packageJson.dependencies,
|
|
1002
|
+
...componentDeps
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
1007
|
+
await nodeInstallPackages(hostPath);
|
|
1008
|
+
spinner.stopSpinner();
|
|
1009
|
+
spinner.log("\u2714 Local xyd framework installed successfully");
|
|
1010
|
+
} catch (error) {
|
|
1011
|
+
spinner.stopSpinner();
|
|
1012
|
+
spinner.error("\u274C Failed to install xyd framework");
|
|
1013
|
+
throw error;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
async function hostPackageJson() {
|
|
1017
|
+
const hostPath = getHostPath();
|
|
1018
|
+
const packageJsonPath = path2.join(hostPath, "package.json");
|
|
1019
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
1020
|
+
console.warn("No package.json found in host path");
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
let packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
1024
|
+
if (!packageJson.dependencies) {
|
|
1025
|
+
packageJson.dependencies = {};
|
|
1026
|
+
}
|
|
1027
|
+
return packageJson;
|
|
1028
|
+
}
|
|
1029
|
+
async function setupIntegationDependencies(settings) {
|
|
1030
|
+
const dependencies = {};
|
|
1031
|
+
for (const [key, value] of Object.entries(ANALYTICS_INTEGRATION_DEPENDENCIES)) {
|
|
1032
|
+
const analytics = settings.integrations?.analytics?.[key];
|
|
1033
|
+
if (analytics) {
|
|
1034
|
+
for (const [depName, depVersion] of Object.entries(value)) {
|
|
1035
|
+
dependencies[depName] = depVersion;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
return dependencies;
|
|
1040
|
+
}
|
|
1041
|
+
async function setupPluginDependencies(settings, install2 = false) {
|
|
1042
|
+
const spinner = new CLI("dots");
|
|
1043
|
+
const hostPath = getHostPath();
|
|
1044
|
+
const dependencies = {};
|
|
1045
|
+
for (const plugin of settings.plugins || []) {
|
|
1046
|
+
let pluginName;
|
|
1047
|
+
if (typeof plugin === "string") {
|
|
1048
|
+
pluginName = plugin;
|
|
1049
|
+
} else if (Array.isArray(plugin)) {
|
|
1050
|
+
pluginName = plugin[0];
|
|
1051
|
+
} else {
|
|
1052
|
+
continue;
|
|
1053
|
+
}
|
|
1054
|
+
if (pluginName.startsWith("@xyd-js/") && (!EXTERNAL_XYD_PLUGINS[pluginName] || process.env.XYD_DEV_MODE === "2")) {
|
|
1055
|
+
continue;
|
|
1056
|
+
}
|
|
1057
|
+
const isValidNpmPackage = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(pluginName);
|
|
1058
|
+
if (isValidNpmPackage) {
|
|
1059
|
+
const xydPluginVersion = EXTERNAL_XYD_PLUGINS[pluginName];
|
|
1060
|
+
const hostPackageJsonPath = path2.join(hostPath, "package.json");
|
|
1061
|
+
const cwdPackageJsonPath = path2.join(process.cwd(), "package.json");
|
|
1062
|
+
let userDeps = {};
|
|
1063
|
+
if (fs.existsSync(cwdPackageJsonPath)) {
|
|
1064
|
+
const cwdPackageJson = JSON.parse(fs.readFileSync(cwdPackageJsonPath, "utf-8"));
|
|
1065
|
+
userDeps = cwdPackageJson.dependencies || {};
|
|
1066
|
+
}
|
|
1067
|
+
if (fs.existsSync(hostPackageJsonPath)) {
|
|
1068
|
+
const hostPackageJson2 = JSON.parse(fs.readFileSync(hostPackageJsonPath, "utf-8"));
|
|
1069
|
+
const deps = hostPackageJson2.dependencies || {};
|
|
1070
|
+
const matchingUserDep = Object.entries(userDeps).find(([depName]) => {
|
|
1071
|
+
return depName === pluginName;
|
|
1072
|
+
});
|
|
1073
|
+
if (matchingUserDep) {
|
|
1074
|
+
dependencies[pluginName] = matchingUserDep[1];
|
|
1075
|
+
} else {
|
|
1076
|
+
const matchingHostDep = Object.entries(deps).find(([depName]) => {
|
|
1077
|
+
return depName === pluginName;
|
|
1078
|
+
});
|
|
1079
|
+
if (matchingHostDep) {
|
|
1080
|
+
dependencies[pluginName] = matchingHostDep[1];
|
|
1081
|
+
} else if (xydPluginVersion) {
|
|
1082
|
+
dependencies[pluginName] = xydPluginVersion;
|
|
1083
|
+
} else {
|
|
1084
|
+
dependencies[pluginName] = "latest";
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
} else {
|
|
1088
|
+
console.warn(`no host package.json found in: ${hostPath}`);
|
|
1089
|
+
}
|
|
1090
|
+
} else if (!pluginName.startsWith(".") && !pluginName.startsWith("/")) {
|
|
1091
|
+
console.warn(`invalid plugin name: ${pluginName}`);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
if (install2) {
|
|
1095
|
+
spinner.startSpinner("Installing plugin dependencies...");
|
|
1096
|
+
const packageJson = await hostPackageJson();
|
|
1097
|
+
const packageJsonPath = path2.join(hostPath, "package.json");
|
|
1098
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
1099
|
+
await nodeInstallPackages(hostPath);
|
|
1100
|
+
spinner.stopSpinner();
|
|
1101
|
+
spinner.log("\u2714 Plugin dependencies installed successfully");
|
|
1102
|
+
}
|
|
1103
|
+
return dependencies;
|
|
1104
|
+
}
|
|
1105
|
+
function nodeInstallPackages(hostPath) {
|
|
1106
|
+
const cmdInstall = pmInstall();
|
|
1107
|
+
const execOptions = {
|
|
1108
|
+
cwd: hostPath,
|
|
1109
|
+
env: {
|
|
1110
|
+
...process.env,
|
|
1111
|
+
NODE_ENV: ""
|
|
1112
|
+
// since 'production' does not install it well,
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1115
|
+
const customRegistry = process.env.XYD_NPM_REGISTRY || process.env.npm_config_registry;
|
|
1116
|
+
if (customRegistry) {
|
|
1117
|
+
if (!execOptions.env) {
|
|
1118
|
+
execOptions.env = {};
|
|
1119
|
+
}
|
|
1120
|
+
execOptions.env["npm_config_registry"] = customRegistry;
|
|
1121
|
+
}
|
|
1122
|
+
if (process.env.XYD_VERBOSE) {
|
|
1123
|
+
execOptions.stdio = "inherit";
|
|
1124
|
+
}
|
|
1125
|
+
execSync2(cmdInstall, execOptions);
|
|
1126
|
+
}
|
|
1127
|
+
function pmInstall() {
|
|
1128
|
+
if (process.env.XYD_NODE_PM) {
|
|
1129
|
+
switch (process.env.XYD_NODE_PM) {
|
|
1130
|
+
case "npm": {
|
|
1131
|
+
return npmInstall();
|
|
1132
|
+
}
|
|
1133
|
+
case "pnpm": {
|
|
1134
|
+
return pnpmInstall();
|
|
1135
|
+
}
|
|
1136
|
+
case "bun": {
|
|
1137
|
+
return bunInstall();
|
|
1138
|
+
}
|
|
1139
|
+
default: {
|
|
1140
|
+
console.warn(`Unknown package manager: ${process.env.XYD_NODE_PM}, falling back to npm`);
|
|
1141
|
+
return npmInstall();
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
if (hasBun()) {
|
|
1146
|
+
return bunInstall();
|
|
1147
|
+
}
|
|
1148
|
+
const { pnpm } = runningPm();
|
|
1149
|
+
console.log("\u2139\uFE0F consider install `bun` for better performance \n");
|
|
1150
|
+
if (pnpm) {
|
|
1151
|
+
return pnpmInstall();
|
|
1152
|
+
}
|
|
1153
|
+
return npmInstall();
|
|
1154
|
+
}
|
|
1155
|
+
function hasBun() {
|
|
1156
|
+
try {
|
|
1157
|
+
execSync2("bun --version", { stdio: "ignore" });
|
|
1158
|
+
return true;
|
|
1159
|
+
} catch {
|
|
1160
|
+
return false;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
function runningPm() {
|
|
1164
|
+
let pnpm = false;
|
|
1165
|
+
let bun = false;
|
|
1166
|
+
if (process.env.npm_execpath) {
|
|
1167
|
+
if (process.env.npm_execpath.includes("pnpm")) {
|
|
1168
|
+
pnpm = true;
|
|
1169
|
+
} else if (process.env.npm_execpath.includes("bun")) {
|
|
1170
|
+
bun = true;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
if (process.env.NODE_PATH) {
|
|
1174
|
+
const nodePath = process.env.NODE_PATH;
|
|
1175
|
+
if (nodePath.includes(".pnpm")) {
|
|
1176
|
+
pnpm = true;
|
|
1177
|
+
} else if (nodePath.includes(".bun")) {
|
|
1178
|
+
bun = true;
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
if (process.execPath.includes("bun") || path2.dirname(process.argv?.[1] || "").includes("bun")) {
|
|
1182
|
+
bun = true;
|
|
1183
|
+
}
|
|
1184
|
+
return {
|
|
1185
|
+
pnpm,
|
|
1186
|
+
bun
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
function pnpmInstall() {
|
|
1190
|
+
return "pnpm install";
|
|
1191
|
+
}
|
|
1192
|
+
function bunInstall() {
|
|
1193
|
+
return "bun install";
|
|
1194
|
+
}
|
|
1195
|
+
function npmInstall() {
|
|
1196
|
+
return "npm install";
|
|
1197
|
+
}
|
|
1198
|
+
async function shouldSkipHostSetup() {
|
|
1199
|
+
const hostPath = getHostPath();
|
|
1200
|
+
if (!fs.existsSync(hostPath)) {
|
|
1201
|
+
return false;
|
|
1202
|
+
}
|
|
1203
|
+
const currentChecksum = calculateFolderChecksum(hostPath);
|
|
1204
|
+
const storedChecksum = getStoredChecksum();
|
|
1205
|
+
if (!storedChecksum || storedChecksum !== currentChecksum) {
|
|
1206
|
+
return false;
|
|
1207
|
+
}
|
|
1208
|
+
return true;
|
|
1209
|
+
}
|
|
1210
|
+
function getStoredChecksum() {
|
|
1211
|
+
const checksumPath = path2.join(getHostPath(), ".xydchecksum");
|
|
1212
|
+
if (!fs.existsSync(checksumPath)) {
|
|
1213
|
+
return null;
|
|
1214
|
+
}
|
|
1215
|
+
try {
|
|
1216
|
+
return fs.readFileSync(checksumPath, "utf-8").trim();
|
|
1217
|
+
} catch (error) {
|
|
1218
|
+
console.error("Error reading checksum file:", error);
|
|
1219
|
+
return null;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
function storeChecksum(checksum) {
|
|
1223
|
+
const checksumPath = path2.join(getHostPath(), ".xydchecksum");
|
|
1224
|
+
try {
|
|
1225
|
+
fs.writeFileSync(checksumPath, checksum);
|
|
1226
|
+
} catch (error) {
|
|
1227
|
+
console.error("Error writing checksum file:", error);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
// src/build.ts
|
|
1232
|
+
async function build() {
|
|
1233
|
+
const skip = await preWorkspaceSetup({
|
|
1234
|
+
force: true
|
|
1235
|
+
});
|
|
1236
|
+
const inited = await appInit();
|
|
1237
|
+
if (!inited) {
|
|
1238
|
+
return;
|
|
1239
|
+
}
|
|
1240
|
+
const { respPluginDocs, resolvedPlugins } = inited;
|
|
1241
|
+
const commonRunVitePlugins = await commonVitePlugins(respPluginDocs, resolvedPlugins);
|
|
1242
|
+
const appRoot = getAppRoot();
|
|
1243
|
+
if (!skip) {
|
|
1244
|
+
await postWorkspaceSetup(respPluginDocs.settings);
|
|
1245
|
+
const newChecksum = calculateFolderChecksum(getHostPath());
|
|
1246
|
+
storeChecksum(newChecksum);
|
|
1247
|
+
}
|
|
1248
|
+
const postInstallVitePlugins = commonPostInstallVitePlugins(respPluginDocs, resolvedPlugins);
|
|
1249
|
+
{
|
|
1250
|
+
await setupInstallableEnvironmentV2();
|
|
1251
|
+
}
|
|
1252
|
+
const enableMermaid = !!respPluginDocs?.settings?.integrations?.diagrams;
|
|
1253
|
+
const externalPackages = enableMermaid ? [] : ["rehype-mermaid"];
|
|
1254
|
+
try {
|
|
1255
|
+
await viteBuild({
|
|
1256
|
+
mode: "production",
|
|
1257
|
+
root: appRoot,
|
|
1258
|
+
plugins: [
|
|
1259
|
+
...commonRunVitePlugins,
|
|
1260
|
+
...postInstallVitePlugins,
|
|
1261
|
+
tsconfigPaths()
|
|
1262
|
+
],
|
|
1263
|
+
optimizeDeps: {
|
|
1264
|
+
include: ["react/jsx-runtime"]
|
|
1265
|
+
},
|
|
1266
|
+
define: {
|
|
1267
|
+
"process.env.NODE_ENV": JSON.stringify("production"),
|
|
1268
|
+
"process.env": {}
|
|
1269
|
+
},
|
|
1270
|
+
resolve: {
|
|
1271
|
+
alias: {
|
|
1272
|
+
process: "process/browser",
|
|
1273
|
+
// When rehype-mermaid is externalized, resolve it from CLI's node_modules
|
|
1274
|
+
...enableMermaid ? {} : { "rehype-mermaid": path3.resolve(getHostPath(), "./node_modules/rehype-mermaid") }
|
|
1275
|
+
}
|
|
1276
|
+
},
|
|
1277
|
+
build: {
|
|
1278
|
+
rollupOptions: {
|
|
1279
|
+
external: externalPackages
|
|
1280
|
+
}
|
|
1281
|
+
},
|
|
1282
|
+
ssr: {
|
|
1283
|
+
external: externalPackages
|
|
1284
|
+
}
|
|
1285
|
+
// ssr: {
|
|
1286
|
+
// noExternal: ["react", "react-dom", "react-router"]
|
|
1287
|
+
// }
|
|
1288
|
+
});
|
|
1289
|
+
await viteBuild({
|
|
1290
|
+
mode: "production",
|
|
1291
|
+
root: appRoot,
|
|
1292
|
+
build: {
|
|
1293
|
+
ssr: true,
|
|
1294
|
+
rollupOptions: {
|
|
1295
|
+
external: externalPackages
|
|
1296
|
+
}
|
|
1297
|
+
// rollupOptions: {
|
|
1298
|
+
// external: ["@xyd-js/framework/hydration", "fs"]
|
|
1299
|
+
// }
|
|
1300
|
+
},
|
|
1301
|
+
plugins: [
|
|
1302
|
+
fixManifestPlugin(appRoot),
|
|
1303
|
+
...commonRunVitePlugins,
|
|
1304
|
+
...postInstallVitePlugins,
|
|
1305
|
+
tsconfigPaths()
|
|
1306
|
+
],
|
|
1307
|
+
optimizeDeps: {
|
|
1308
|
+
include: ["react/jsx-runtime"]
|
|
1309
|
+
// include: ["react", "react-dom", "react/jsx-runtime", "react-router"],
|
|
1310
|
+
// force: true
|
|
1311
|
+
},
|
|
1312
|
+
define: {
|
|
1313
|
+
"process.env.NODE_ENV": JSON.stringify("production"),
|
|
1314
|
+
"process.env": {}
|
|
1315
|
+
},
|
|
1316
|
+
resolve: {
|
|
1317
|
+
alias: {
|
|
1318
|
+
process: "process/browser",
|
|
1319
|
+
// When rehype-mermaid is externalized, resolve it from CLI's node_modules
|
|
1320
|
+
...enableMermaid ? {} : { "rehype-mermaid": path3.resolve(getHostPath(), "./node_modules/rehype-mermaid") }
|
|
1321
|
+
// react: path.resolve(workspaceNodeModulesPath, "react"),
|
|
1322
|
+
// "react-dom": path.resolve(workspaceNodeModulesPath, "react-dom")
|
|
1323
|
+
}
|
|
1324
|
+
},
|
|
1325
|
+
ssr: {
|
|
1326
|
+
external: externalPackages
|
|
1327
|
+
}
|
|
1328
|
+
// ssr: {
|
|
1329
|
+
// noExternal: ["react", "react-dom", "react-router"]
|
|
1330
|
+
// }
|
|
1331
|
+
});
|
|
1332
|
+
} catch (error) {
|
|
1333
|
+
console.error("Build failed:", error);
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
function setupInstallableEnvironmentV2() {
|
|
1337
|
+
const symbolicXydNodeModules = path3.join(getXydFolderPath(), "node_modules");
|
|
1338
|
+
const hostNodeModules = path3.join(getHostPath(), "node_modules");
|
|
1339
|
+
if (fs2.existsSync(symbolicXydNodeModules)) {
|
|
1340
|
+
if (fs2.lstatSync(symbolicXydNodeModules).isSymbolicLink()) {
|
|
1341
|
+
fs2.unlinkSync(symbolicXydNodeModules);
|
|
1342
|
+
} else {
|
|
1343
|
+
fs2.rmSync(symbolicXydNodeModules, { recursive: true, force: true });
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
fs2.symlinkSync(hostNodeModules, symbolicXydNodeModules, "dir");
|
|
1347
|
+
}
|
|
1348
|
+
function fixManifestPlugin(appRoot) {
|
|
1349
|
+
const manifestPath = path3.join(
|
|
1350
|
+
getBuildPath(),
|
|
1351
|
+
// getAppRoot(),
|
|
1352
|
+
"./server/.vite/manifest.json"
|
|
1353
|
+
);
|
|
1354
|
+
return {
|
|
1355
|
+
name: "xyd-fix-rr-manifest",
|
|
1356
|
+
apply: "build",
|
|
1357
|
+
// run after manifest is generated
|
|
1358
|
+
// 2) after bundle is written, compute prefix and strip it
|
|
1359
|
+
writeBundle(_, bundle) {
|
|
1360
|
+
const cwdDir = process.cwd();
|
|
1361
|
+
let prefix = path3.relative(appRoot, cwdDir).replace(/\\/g, "/");
|
|
1362
|
+
if (prefix) prefix += "/";
|
|
1363
|
+
const esc = prefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1364
|
+
const stripRe = new RegExp(`^${esc}`);
|
|
1365
|
+
for (const fileName in bundle) {
|
|
1366
|
+
const asset = bundle[fileName];
|
|
1367
|
+
if (asset.type !== "asset") continue;
|
|
1368
|
+
if (fileName.endsWith("manifest.json")) {
|
|
1369
|
+
const manifest = JSON.parse(asset.source.toString());
|
|
1370
|
+
const fixed = {};
|
|
1371
|
+
for (const key of Object.keys(manifest)) {
|
|
1372
|
+
const entry = manifest[key];
|
|
1373
|
+
const newKey = key.replace(stripRe, "");
|
|
1374
|
+
if (typeof entry.src === "string") {
|
|
1375
|
+
entry.src = entry.src.replace(stripRe, "");
|
|
1376
|
+
}
|
|
1377
|
+
fixed[newKey] = entry;
|
|
1378
|
+
}
|
|
1379
|
+
asset.source = JSON.stringify(fixed, null, 2);
|
|
1380
|
+
fs2.writeFileSync(manifestPath, asset.source, "utf8");
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
// src/dev.ts
|
|
1388
|
+
import path4 from "path";
|
|
1389
|
+
import fs3 from "fs";
|
|
1390
|
+
import { createServer as createServer2, searchForWorkspaceRoot } from "vite";
|
|
1391
|
+
if (!process.env.ENABLE_TIMERS) {
|
|
1392
|
+
["time", "timeLog", "timeEnd"].forEach((method) => {
|
|
1393
|
+
console[method] = () => {
|
|
1394
|
+
};
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
var fullReloadOptions = {
|
|
1398
|
+
"theme.name": true,
|
|
1399
|
+
"plugins": true
|
|
1400
|
+
// TODO: in the future better
|
|
1401
|
+
};
|
|
1402
|
+
function extractNestedProperty(obj, path5) {
|
|
1403
|
+
const keys = path5.split(".");
|
|
1404
|
+
let current = obj;
|
|
1405
|
+
for (const key of keys) {
|
|
1406
|
+
if (current && typeof current === "object" && key in current) {
|
|
1407
|
+
current = current[key];
|
|
1408
|
+
} else {
|
|
1409
|
+
return null;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
return current;
|
|
1413
|
+
}
|
|
1414
|
+
function hasValueChanged(oldValue, newValue) {
|
|
1415
|
+
if (!oldValue && newValue) return true;
|
|
1416
|
+
if (oldValue && !newValue) return true;
|
|
1417
|
+
if (!oldValue && !newValue) return false;
|
|
1418
|
+
const oldStr = JSON.stringify(oldValue);
|
|
1419
|
+
const newStr = JSON.stringify(newValue);
|
|
1420
|
+
return oldStr !== newStr;
|
|
1421
|
+
}
|
|
1422
|
+
function hasFullReloadPropertiesChanged(oldSettings, newSettings) {
|
|
1423
|
+
if (!oldSettings || !newSettings) {
|
|
1424
|
+
return oldSettings !== newSettings;
|
|
1425
|
+
}
|
|
1426
|
+
for (const [propertyPath, shouldCheck] of Object.entries(fullReloadOptions)) {
|
|
1427
|
+
if (shouldCheck) {
|
|
1428
|
+
const oldValue = extractNestedProperty(oldSettings, propertyPath);
|
|
1429
|
+
const newValue = extractNestedProperty(newSettings, propertyPath);
|
|
1430
|
+
if (hasValueChanged(oldValue, newValue)) {
|
|
1431
|
+
return true;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
return false;
|
|
1436
|
+
}
|
|
1437
|
+
var RELOADING = false;
|
|
1438
|
+
async function dev(options) {
|
|
1439
|
+
const spinner = new CLI("dots");
|
|
1440
|
+
spinner.startSpinner("Preparing local xyd instance...");
|
|
1441
|
+
const skip = await preWorkspaceSetup();
|
|
1442
|
+
let onUpdateCallback = () => {
|
|
1443
|
+
};
|
|
1444
|
+
const inited = await appInit({
|
|
1445
|
+
onUpdate: (callback) => {
|
|
1446
|
+
onUpdateCallback = callback;
|
|
1447
|
+
}
|
|
1448
|
+
});
|
|
1449
|
+
if (!inited) {
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
const { respPluginDocs, resolvedPlugins } = inited;
|
|
1453
|
+
const allowCwd = searchForWorkspaceRoot(process.cwd());
|
|
1454
|
+
const watchAllow = process.cwd();
|
|
1455
|
+
const appRoot = getAppRoot();
|
|
1456
|
+
const commonRunVitePlugins = await commonVitePlugins(respPluginDocs, resolvedPlugins);
|
|
1457
|
+
spinner.stopSpinner();
|
|
1458
|
+
if (!skip) {
|
|
1459
|
+
await postWorkspaceSetup(respPluginDocs.settings);
|
|
1460
|
+
const newChecksum = calculateFolderChecksum(getHostPath());
|
|
1461
|
+
storeChecksum(newChecksum);
|
|
1462
|
+
}
|
|
1463
|
+
const postInstallVitePlugins = commonPostInstallVitePlugins(respPluginDocs, resolvedPlugins);
|
|
1464
|
+
spinner.log("\u2714 Local xyd instance is ready");
|
|
1465
|
+
spinner.log("\u{1F504} Starting server...");
|
|
1466
|
+
let server = null;
|
|
1467
|
+
const port = options?.port ?? parseInt(process.env.XYD_PORT ?? "5175");
|
|
1468
|
+
const enableMermaid = !!respPluginDocs?.settings?.integrations?.diagrams;
|
|
1469
|
+
const externalPackages = enableMermaid ? [] : ["rehype-mermaid"];
|
|
1470
|
+
const optimizeDepsExclude = enableMermaid ? [] : ["rehype-mermaid"];
|
|
1471
|
+
let initialSettings = respPluginDocs.settings || {};
|
|
1472
|
+
let USE_CONTEXT_ISSUE_PACKAGES = [];
|
|
1473
|
+
{
|
|
1474
|
+
if (process.env.XYD_DEV_MODE) {
|
|
1475
|
+
USE_CONTEXT_ISSUE_PACKAGES = [
|
|
1476
|
+
"react-github-btn",
|
|
1477
|
+
"radix-ui",
|
|
1478
|
+
"@code-hike/lighter",
|
|
1479
|
+
"lucide-react",
|
|
1480
|
+
"openux-js",
|
|
1481
|
+
"pluganalytics",
|
|
1482
|
+
"@orama/orama",
|
|
1483
|
+
"@orama/react-components"
|
|
1484
|
+
// TODO: optimize plugin deps only if loaded
|
|
1485
|
+
// "@pluganalytics/provider-livesession"
|
|
1486
|
+
];
|
|
1487
|
+
} else {
|
|
1488
|
+
USE_CONTEXT_ISSUE_PACKAGES = [
|
|
1489
|
+
"@xyd-js/theme-cosmo",
|
|
1490
|
+
"@xyd-js/theme-gusto",
|
|
1491
|
+
"@xyd-js/theme-opener",
|
|
1492
|
+
"@xyd-js/theme-picasso",
|
|
1493
|
+
"@xyd-js/theme-poetry",
|
|
1494
|
+
"@xyd-js/theme-solar"
|
|
1495
|
+
// TODO: optimize plugin deps only if loaded
|
|
1496
|
+
// "@pluganalytics/provider-livesession"
|
|
1497
|
+
];
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
const preview = await createServer2({
|
|
1501
|
+
root: appRoot,
|
|
1502
|
+
publicDir: "/public",
|
|
1503
|
+
server: {
|
|
1504
|
+
allowedHosts: [],
|
|
1505
|
+
port,
|
|
1506
|
+
fs: {
|
|
1507
|
+
allow: [
|
|
1508
|
+
allowCwd,
|
|
1509
|
+
appRoot
|
|
1510
|
+
]
|
|
1511
|
+
}
|
|
1512
|
+
},
|
|
1513
|
+
define: {
|
|
1514
|
+
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
|
|
1515
|
+
"process.env": {}
|
|
1516
|
+
},
|
|
1517
|
+
resolve: {
|
|
1518
|
+
alias: {
|
|
1519
|
+
process: "process/browser",
|
|
1520
|
+
// When rehype-mermaid is externalized, resolve it from CLI's node_modules
|
|
1521
|
+
...enableMermaid ? {} : { "rehype-mermaid": path4.resolve(getHostPath(), "./node_modules/rehype-mermaid") }
|
|
1522
|
+
}
|
|
1523
|
+
// preserveSymlinks: true
|
|
1524
|
+
},
|
|
1525
|
+
build: {
|
|
1526
|
+
rollupOptions: {
|
|
1527
|
+
external: externalPackages
|
|
1528
|
+
}
|
|
1529
|
+
},
|
|
1530
|
+
ssr: {
|
|
1531
|
+
external: externalPackages
|
|
1532
|
+
},
|
|
1533
|
+
optimizeDeps: {
|
|
1534
|
+
include: [
|
|
1535
|
+
"react/jsx-runtime",
|
|
1536
|
+
...USE_CONTEXT_ISSUE_PACKAGES
|
|
1537
|
+
],
|
|
1538
|
+
exclude: optimizeDepsExclude
|
|
1539
|
+
// exclude: ["react", "react-dom"]
|
|
1540
|
+
},
|
|
1541
|
+
plugins: [
|
|
1542
|
+
...commonRunVitePlugins,
|
|
1543
|
+
...postInstallVitePlugins,
|
|
1544
|
+
{
|
|
1545
|
+
name: "xyd-configureServer",
|
|
1546
|
+
configureServer(s) {
|
|
1547
|
+
server = s;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
]
|
|
1551
|
+
});
|
|
1552
|
+
const watcher = fs3.watch(watchAllow, { recursive: true }, async (eventType, filename) => {
|
|
1553
|
+
if (RELOADING) {
|
|
1554
|
+
return;
|
|
1555
|
+
}
|
|
1556
|
+
if (!filename) {
|
|
1557
|
+
console.log("[xyd:dev-watcher] Received empty filename");
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1560
|
+
if (!server) {
|
|
1561
|
+
console.log("[xyd:dev-watcher] Server not ready");
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1564
|
+
const filePath = path4.join(watchAllow, filename);
|
|
1565
|
+
if (filePath.includes(CACHE_FOLDER_PATH)) {
|
|
1566
|
+
return;
|
|
1567
|
+
}
|
|
1568
|
+
let apiPaths = {};
|
|
1569
|
+
if (respPluginDocs?.settings?.api) {
|
|
1570
|
+
apiPaths = resolveApiFilePaths(process.cwd(), respPluginDocs.settings.api);
|
|
1571
|
+
}
|
|
1572
|
+
let iconPaths = {};
|
|
1573
|
+
if (respPluginDocs?.settings) {
|
|
1574
|
+
iconPaths = resolveIconFilePaths(process.cwd(), respPluginDocs.settings);
|
|
1575
|
+
}
|
|
1576
|
+
let syntaxHighlightPaths = {};
|
|
1577
|
+
if (respPluginDocs?.settings) {
|
|
1578
|
+
syntaxHighlightPaths = resolveSyntaxHighlightFilePaths(process.cwd(), respPluginDocs.settings);
|
|
1579
|
+
}
|
|
1580
|
+
const apiChanged = !!apiPaths[filePath];
|
|
1581
|
+
const iconChanged = !!iconPaths[filePath];
|
|
1582
|
+
const syntaxHighlightChanged = !!syntaxHighlightPaths[filePath];
|
|
1583
|
+
const isSettingsFile = SUPPORTED_SETTINGS_FILES.some((ext) => filePath.endsWith(ext));
|
|
1584
|
+
const isContentFile = SUPPORTED_CONTENT_FILES.some((ext) => filePath.endsWith(ext));
|
|
1585
|
+
const isPublicPathReload = filePath.includes(getPublicPath());
|
|
1586
|
+
const isEnvFile = isEnvFilePath(filePath);
|
|
1587
|
+
const isWatchFile = isSettingsFile || isContentFile || apiChanged || iconChanged || syntaxHighlightChanged || isPublicPathReload || isEnvFile;
|
|
1588
|
+
if (!isWatchFile) {
|
|
1589
|
+
return;
|
|
1590
|
+
}
|
|
1591
|
+
const renameContentFile = isContentFile && eventType === "rename";
|
|
1592
|
+
if (isContentFile && !renameContentFile) {
|
|
1593
|
+
console.log("\u{1F504} Content file changed, refresh...");
|
|
1594
|
+
invalidateSettings(server);
|
|
1595
|
+
await touchLayoutPage();
|
|
1596
|
+
console.log("\u2714 xyd content file changed\n");
|
|
1597
|
+
return;
|
|
1598
|
+
}
|
|
1599
|
+
const isReloadFile = isSettingsFile || renameContentFile || isPublicPathReload || iconChanged || apiChanged || syntaxHighlightChanged || isEnvFile;
|
|
1600
|
+
if (isReloadFile) {
|
|
1601
|
+
if (renameContentFile) {
|
|
1602
|
+
console.log("\u{1F504} Content file renamed, refresh...");
|
|
1603
|
+
} else if (isPublicPathReload) {
|
|
1604
|
+
console.log("\u{1F504} Public path changed, refresh...");
|
|
1605
|
+
} else if (iconChanged) {
|
|
1606
|
+
console.log("\u{1F504} Icon file changed, refresh...");
|
|
1607
|
+
invalidateIconSet(server);
|
|
1608
|
+
} else if (syntaxHighlightChanged) {
|
|
1609
|
+
console.log("\u{1F504} Syntax highlight theme file changed, refresh...");
|
|
1610
|
+
} else if (apiChanged) {
|
|
1611
|
+
console.log("\u{1F504} API file changed, refresh...");
|
|
1612
|
+
} else if (syntaxHighlightChanged) {
|
|
1613
|
+
console.log("\u{1F504} Syntax highlight theme file changed, refresh...");
|
|
1614
|
+
} else if (isEnvFile) {
|
|
1615
|
+
console.log("\u{1F504} Environment file changed, refresh...");
|
|
1616
|
+
await reloadServer(watcher, preview, options);
|
|
1617
|
+
return;
|
|
1618
|
+
} else {
|
|
1619
|
+
console.log("\u{1F504} Settings file changed, refresh...");
|
|
1620
|
+
}
|
|
1621
|
+
let newSettings = null;
|
|
1622
|
+
if (respPluginDocs?.settings.engine?.uniform?.store) {
|
|
1623
|
+
const resp = await appInit({
|
|
1624
|
+
disableFSWrite: true,
|
|
1625
|
+
doNotInstallPluginDependencies: true
|
|
1626
|
+
});
|
|
1627
|
+
const respSettings = resp?.respPluginDocs?.settings;
|
|
1628
|
+
if (respSettings) {
|
|
1629
|
+
newSettings = respSettings;
|
|
1630
|
+
}
|
|
1631
|
+
} else {
|
|
1632
|
+
const resp = await appInit({
|
|
1633
|
+
doNotInstallPluginDependencies: true
|
|
1634
|
+
});
|
|
1635
|
+
const respSettings = resp?.respPluginDocs?.settings;
|
|
1636
|
+
if (respSettings) {
|
|
1637
|
+
newSettings = respSettings;
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
if (!newSettings) {
|
|
1641
|
+
console.log("[xyd:dev-watcher] Settings is not an object or is null");
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1644
|
+
{
|
|
1645
|
+
const needsFullReload = hasFullReloadPropertiesChanged(initialSettings, newSettings);
|
|
1646
|
+
if (needsFullReload) {
|
|
1647
|
+
console.log("\u{1F504} Full reload properties changed, restarting server...");
|
|
1648
|
+
await reloadServer(watcher, preview, options);
|
|
1649
|
+
return;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
{
|
|
1653
|
+
invalidateSettings(server);
|
|
1654
|
+
onUpdateCallback(newSettings);
|
|
1655
|
+
await touchReactRouterConfig();
|
|
1656
|
+
await touchRootPage();
|
|
1657
|
+
await touchLayoutPage();
|
|
1658
|
+
server.ws.send({ type: "full-reload" });
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
});
|
|
1662
|
+
watcher.on("error", (error) => {
|
|
1663
|
+
console.error("[xyd:dev] File watcher error:", error);
|
|
1664
|
+
});
|
|
1665
|
+
await preview.listen(port);
|
|
1666
|
+
await optimizeDepsFix(port, respPluginDocs.settings.navigation);
|
|
1667
|
+
preview.printUrls();
|
|
1668
|
+
preview.bindCLIShortcuts({ print: true });
|
|
1669
|
+
preview.httpServer?.once("close", () => {
|
|
1670
|
+
watcher.close();
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
async function reloadServer(watcher, preview, options) {
|
|
1674
|
+
RELOADING = true;
|
|
1675
|
+
watcher.close();
|
|
1676
|
+
await preview.close();
|
|
1677
|
+
RELOADING = false;
|
|
1678
|
+
await dev(options);
|
|
1679
|
+
}
|
|
1680
|
+
function resolveApiFilePaths(basePath, api) {
|
|
1681
|
+
const result = {};
|
|
1682
|
+
const apis = [api.openapi, api.graphql, api.sources].filter((s) => s !== void 0);
|
|
1683
|
+
apis.forEach((section) => {
|
|
1684
|
+
flattenApiFile(section).forEach((p) => {
|
|
1685
|
+
const apiAbsPath = path4.resolve(basePath, p);
|
|
1686
|
+
result[apiAbsPath] = true;
|
|
1687
|
+
});
|
|
1688
|
+
});
|
|
1689
|
+
return result;
|
|
1690
|
+
}
|
|
1691
|
+
function resolveIconFilePaths(basePath, settings) {
|
|
1692
|
+
const result = {};
|
|
1693
|
+
const icons = settings?.theme?.icons?.library;
|
|
1694
|
+
if (!icons) {
|
|
1695
|
+
return result;
|
|
1696
|
+
}
|
|
1697
|
+
const isLocalPath = (path5) => {
|
|
1698
|
+
return path5.startsWith("./") || path5.startsWith("/");
|
|
1699
|
+
};
|
|
1700
|
+
if (typeof icons === "string") {
|
|
1701
|
+
if (isLocalPath(icons)) {
|
|
1702
|
+
const iconAbsPath = path4.resolve(basePath, icons);
|
|
1703
|
+
result[iconAbsPath] = true;
|
|
1704
|
+
}
|
|
1705
|
+
return result;
|
|
1706
|
+
}
|
|
1707
|
+
if (Array.isArray(icons)) {
|
|
1708
|
+
icons.forEach((library) => {
|
|
1709
|
+
if (typeof library === "string") {
|
|
1710
|
+
if (isLocalPath(library)) {
|
|
1711
|
+
const iconAbsPath = path4.resolve(basePath, library);
|
|
1712
|
+
result[iconAbsPath] = true;
|
|
1713
|
+
}
|
|
1714
|
+
} else if (typeof library === "object" && library.name) {
|
|
1715
|
+
if (isLocalPath(library.name)) {
|
|
1716
|
+
const iconAbsPath = path4.resolve(basePath, library.name);
|
|
1717
|
+
result[iconAbsPath] = true;
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
});
|
|
1721
|
+
} else if (typeof icons === "object" && icons.name) {
|
|
1722
|
+
if (isLocalPath(icons.name)) {
|
|
1723
|
+
const iconAbsPath = path4.resolve(basePath, icons.name);
|
|
1724
|
+
result[iconAbsPath] = true;
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
return result;
|
|
1728
|
+
}
|
|
1729
|
+
function resolveSyntaxHighlightFilePaths(basePath, settings) {
|
|
1730
|
+
const result = {};
|
|
1731
|
+
const syntaxHighlight = settings?.theme?.coder?.syntaxHighlight;
|
|
1732
|
+
if (!syntaxHighlight) {
|
|
1733
|
+
return result;
|
|
1734
|
+
}
|
|
1735
|
+
const isLocalPath = (path5) => {
|
|
1736
|
+
return path5.startsWith("./") || path5.startsWith("/");
|
|
1737
|
+
};
|
|
1738
|
+
if (typeof syntaxHighlight === "string") {
|
|
1739
|
+
if (isLocalPath(syntaxHighlight)) {
|
|
1740
|
+
const syntaxHighlightAbsPath = path4.resolve(basePath, syntaxHighlight);
|
|
1741
|
+
result[syntaxHighlightAbsPath] = true;
|
|
1742
|
+
}
|
|
1743
|
+
return result;
|
|
1744
|
+
}
|
|
1745
|
+
if (Array.isArray(syntaxHighlight)) {
|
|
1746
|
+
syntaxHighlight.forEach((theme) => {
|
|
1747
|
+
if (typeof theme === "string") {
|
|
1748
|
+
if (isLocalPath(theme)) {
|
|
1749
|
+
const syntaxHighlightAbsPath = path4.resolve(basePath, theme);
|
|
1750
|
+
result[syntaxHighlightAbsPath] = true;
|
|
1751
|
+
}
|
|
1752
|
+
} else if (typeof theme === "object" && theme.name) {
|
|
1753
|
+
if (isLocalPath(theme.name)) {
|
|
1754
|
+
const syntaxHighlightAbsPath = path4.resolve(basePath, theme.name);
|
|
1755
|
+
result[syntaxHighlightAbsPath] = true;
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
});
|
|
1759
|
+
} else if (typeof syntaxHighlight === "object" && syntaxHighlight.name) {
|
|
1760
|
+
if (isLocalPath(syntaxHighlight.name)) {
|
|
1761
|
+
const syntaxHighlightAbsPath = path4.resolve(basePath, syntaxHighlight.name);
|
|
1762
|
+
result[syntaxHighlightAbsPath] = true;
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
return result;
|
|
1766
|
+
}
|
|
1767
|
+
function flattenApiFile(file) {
|
|
1768
|
+
if (!file) return [];
|
|
1769
|
+
if (typeof file === "string") {
|
|
1770
|
+
return [file];
|
|
1771
|
+
}
|
|
1772
|
+
if (Array.isArray(file)) {
|
|
1773
|
+
return file.flatMap(flattenApiFile);
|
|
1774
|
+
}
|
|
1775
|
+
if (typeof file === "object") {
|
|
1776
|
+
const obj = file;
|
|
1777
|
+
if (typeof obj.source === "string") {
|
|
1778
|
+
return [obj.source];
|
|
1779
|
+
}
|
|
1780
|
+
return Object.values(obj).flatMap(flattenApiFile);
|
|
1781
|
+
}
|
|
1782
|
+
return [];
|
|
1783
|
+
}
|
|
1784
|
+
function isEnvFilePath(filePath) {
|
|
1785
|
+
return filePath.endsWith(".env") || filePath.endsWith(".env.local") || filePath.endsWith(".env.development") || filePath.endsWith(".env.production");
|
|
1786
|
+
}
|
|
1787
|
+
function getFirstPageFromNavigation(navigation) {
|
|
1788
|
+
if (!navigation?.sidebar?.length) {
|
|
1789
|
+
return null;
|
|
1790
|
+
}
|
|
1791
|
+
function extractFirstPage(pages) {
|
|
1792
|
+
for (const page of pages) {
|
|
1793
|
+
if (typeof page === "string") {
|
|
1794
|
+
return normalizePagePath(page);
|
|
1795
|
+
}
|
|
1796
|
+
if (typeof page === "object") {
|
|
1797
|
+
if ("route" in page && page.pages) {
|
|
1798
|
+
const firstPage = extractFirstPage(page.pages);
|
|
1799
|
+
if (firstPage) return firstPage;
|
|
1800
|
+
}
|
|
1801
|
+
if ("pages" in page && page.pages) {
|
|
1802
|
+
const firstPage = extractFirstPage(page.pages);
|
|
1803
|
+
if (firstPage) return firstPage;
|
|
1804
|
+
}
|
|
1805
|
+
if ("page" in page && typeof page.page === "string") {
|
|
1806
|
+
return normalizePagePath(page.page);
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
return null;
|
|
1811
|
+
}
|
|
1812
|
+
return extractFirstPage(navigation.sidebar || []);
|
|
1813
|
+
}
|
|
1814
|
+
function normalizePagePath(pagePath) {
|
|
1815
|
+
let normalized = pagePath.replace(/\.(md|mdx)$/, "");
|
|
1816
|
+
if (normalized.endsWith("/index") || normalized === "index") {
|
|
1817
|
+
normalized = normalized.replace(/\/?index$/, "");
|
|
1818
|
+
}
|
|
1819
|
+
if (normalized.startsWith("/")) {
|
|
1820
|
+
normalized = normalized.slice(1);
|
|
1821
|
+
}
|
|
1822
|
+
return normalized;
|
|
1823
|
+
}
|
|
1824
|
+
async function fetchFirstPage(firstPage, port) {
|
|
1825
|
+
const urlsToTry = [
|
|
1826
|
+
`http://localhost:${port}/${firstPage}`,
|
|
1827
|
+
`http://localhost:${port}/${firstPage}/`,
|
|
1828
|
+
`http://localhost:${port}/${firstPage}.html`,
|
|
1829
|
+
`http://localhost:${port}/${firstPage}/index.html`
|
|
1830
|
+
];
|
|
1831
|
+
for (const url of urlsToTry) {
|
|
1832
|
+
try {
|
|
1833
|
+
const response = await fetch(url);
|
|
1834
|
+
if (response.ok) {
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
} catch (error) {
|
|
1838
|
+
continue;
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
function invalidateSettings(server) {
|
|
1843
|
+
const resolvedId = invalidateSettingsOnly(server);
|
|
1844
|
+
server.ws.send({
|
|
1845
|
+
type: "update",
|
|
1846
|
+
updates: [
|
|
1847
|
+
{
|
|
1848
|
+
type: "js-update",
|
|
1849
|
+
path: `/@id/${resolvedId}`,
|
|
1850
|
+
acceptedPath: `/@id/${resolvedId}`,
|
|
1851
|
+
timestamp: Date.now()
|
|
1852
|
+
}
|
|
1853
|
+
]
|
|
1854
|
+
});
|
|
1855
|
+
console.debug("\u2705 [xyd:dev-watcher] Settings module invalidated and HMR update sent");
|
|
1856
|
+
}
|
|
1857
|
+
function invalidateSettingsOnly(server) {
|
|
1858
|
+
const virtualId = "virtual:xyd-settings";
|
|
1859
|
+
const resolvedId = virtualId + ".jsx";
|
|
1860
|
+
const mod = server.moduleGraph.getModuleById(resolvedId);
|
|
1861
|
+
if (!mod) {
|
|
1862
|
+
console.log("[xyd:dev-watcher] Settings module not found");
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1865
|
+
server.moduleGraph.invalidateModule(mod);
|
|
1866
|
+
return resolvedId;
|
|
1867
|
+
}
|
|
1868
|
+
function invalidateIconSet(server) {
|
|
1869
|
+
const virtualId = "virtual:xyd-icon-set";
|
|
1870
|
+
const mod = server.moduleGraph.getModuleById(virtualId);
|
|
1871
|
+
if (!mod) {
|
|
1872
|
+
console.log("[xyd:dev-watcher] Icon set module not found");
|
|
1873
|
+
return;
|
|
1874
|
+
}
|
|
1875
|
+
console.debug("\u{1F504} [xyd:dev-watcher] Invalidating icon set module...");
|
|
1876
|
+
server.moduleGraph.invalidateModule(mod);
|
|
1877
|
+
server.ws.send({
|
|
1878
|
+
type: "update",
|
|
1879
|
+
updates: [
|
|
1880
|
+
{
|
|
1881
|
+
type: "js-update",
|
|
1882
|
+
path: `/@id/${virtualId}`,
|
|
1883
|
+
acceptedPath: `/@id/${virtualId}`,
|
|
1884
|
+
timestamp: Date.now()
|
|
1885
|
+
}
|
|
1886
|
+
]
|
|
1887
|
+
});
|
|
1888
|
+
console.debug("\u2705 [xyd:dev-watcher] Icon set module invalidated and HMR update sent");
|
|
1889
|
+
}
|
|
1890
|
+
async function touchReactRouterConfig() {
|
|
1891
|
+
const hostPath = getHostPath();
|
|
1892
|
+
const hostReactRouterConfig = path4.join(hostPath, "react-router.config.ts");
|
|
1893
|
+
await fs3.promises.utimes(hostReactRouterConfig, /* @__PURE__ */ new Date(), /* @__PURE__ */ new Date());
|
|
1894
|
+
}
|
|
1895
|
+
async function touchLayoutPage() {
|
|
1896
|
+
const docsPluginBasePath = getDocsPluginBasePath();
|
|
1897
|
+
const layoutPath = path4.join(docsPluginBasePath, "./src/pages/layout.tsx");
|
|
1898
|
+
await fs3.promises.utimes(layoutPath, /* @__PURE__ */ new Date(), /* @__PURE__ */ new Date());
|
|
1899
|
+
}
|
|
1900
|
+
async function touchRootPage() {
|
|
1901
|
+
const hostPath = getHostPath();
|
|
1902
|
+
const hostReactRouterConfig = path4.join(hostPath, "./app/root.tsx");
|
|
1903
|
+
await fs3.promises.utimes(hostReactRouterConfig, /* @__PURE__ */ new Date(), /* @__PURE__ */ new Date());
|
|
1904
|
+
}
|
|
1905
|
+
async function optimizeDepsFix(port, navigation) {
|
|
1906
|
+
let firstPage = "";
|
|
1907
|
+
if (navigation) {
|
|
1908
|
+
firstPage = getFirstPageFromNavigation(navigation);
|
|
1909
|
+
}
|
|
1910
|
+
await fetchFirstPage(firstPage || "", port);
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
// src/install.ts
|
|
1914
|
+
import fs4 from "fs";
|
|
1915
|
+
import { readSettings as readSettings2 } from "@xyd-js/plugin-docs";
|
|
1916
|
+
async function install() {
|
|
1917
|
+
const settings = await readSettings2();
|
|
1918
|
+
if (!settings) {
|
|
1919
|
+
throw new Error("cannot preload settings");
|
|
1920
|
+
}
|
|
1921
|
+
if (typeof settings === "string") {
|
|
1922
|
+
throw new Error("install does not support string settings");
|
|
1923
|
+
}
|
|
1924
|
+
const hostPath = getHostPath();
|
|
1925
|
+
if (fs4.existsSync(hostPath)) {
|
|
1926
|
+
fs4.rmSync(hostPath, { recursive: true, force: true });
|
|
1927
|
+
}
|
|
1928
|
+
await preWorkspaceSetup({
|
|
1929
|
+
force: true
|
|
1930
|
+
});
|
|
1931
|
+
await postWorkspaceSetup(settings);
|
|
1932
|
+
}
|
|
1933
|
+
export {
|
|
1934
|
+
build,
|
|
1935
|
+
componentsInstall,
|
|
1936
|
+
dev,
|
|
1937
|
+
getCLIComponentsJsonPath,
|
|
1938
|
+
getHostPath,
|
|
1939
|
+
install,
|
|
1940
|
+
nodeInstallPackages,
|
|
1941
|
+
pmInstall
|
|
1942
|
+
};
|
|
1943
|
+
//# sourceMappingURL=index.js.map
|