@riebeckite/honox 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -2
- package/dist/index.js +571 -467
- package/dist/src/client_module.d.ts +1 -1
- package/dist/src/honox_islands.d.ts +10 -0
- package/dist/src/vite_plugin.d.ts +1 -1
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export { loadRiebeckiteConfig, resolveHonoxConfig, } from "./src/config_loader.js";
|
|
2
|
+
export { replaceHonoxIslandDependencyPlugin } from "./src/honox_islands.js";
|
|
3
|
+
export type { ScaffoldSiteOptions, ScaffoldSiteResult, } from "./src/scaffold/index.js";
|
|
4
|
+
export { ScaffoldSiteError, scaffoldRiebeckiteSite, } from "./src/scaffold/index.js";
|
|
2
5
|
export { createRiebeckiteSsg, defaultSsgEntry, riebeckiteSsgExtensionMap, } from "./src/ssg.js";
|
|
3
6
|
export type { RiebeckiteSsgOptions } from "./src/ssg_plugin.js";
|
|
4
7
|
export { riebeckiteSsg } from "./src/ssg_plugin.js";
|
|
5
8
|
export type { RiebeckiteIntegrationOptions, RiebeckiteViteOptions, } from "./src/vite_plugin.js";
|
|
6
9
|
export { defaultSsrExternals, riebeckite, riebeckiteVite, } from "./src/vite_plugin.js";
|
|
7
|
-
export type { ScaffoldSiteOptions, ScaffoldSiteResult, } from "./src/scaffold/index.js";
|
|
8
|
-
export { ScaffoldSiteError, scaffoldRiebeckiteSite, } from "./src/scaffold/index.js";
|
|
9
10
|
export type { ResolvedHonoxApplication, ResolveHonoxApplicationOptions, } from "./src/vite_runner.js";
|
|
10
11
|
export { buildHonoxApplication, resolveHonoxApplication, resolveHonoxApplicationRoot, startHonoxDevServer, } from "./src/vite_runner.js";
|
package/dist/index.js
CHANGED
|
@@ -154,480 +154,162 @@ function pathToFileUrl(filePath) {
|
|
|
154
154
|
return `file:///${filePath.replace(/\\/g, "/").replace(/^([A-Za-z]):/, "$1:")}`;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
// src/
|
|
158
|
-
import
|
|
159
|
-
import
|
|
160
|
-
import {
|
|
161
|
-
var
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
157
|
+
// src/honox_islands.ts
|
|
158
|
+
import fs3 from "node:fs/promises";
|
|
159
|
+
import path3 from "node:path";
|
|
160
|
+
import { parse } from "@babel/parser";
|
|
161
|
+
var honoxIslandDependencyPluginName = "inject-importing-islands";
|
|
162
|
+
var importingIslandsExport = "__importing_islands";
|
|
163
|
+
function replaceHonoxIslandDependencyPlugin(plugins) {
|
|
164
|
+
return [
|
|
165
|
+
...plugins.map(disableHonoxIslandDependencyPlugin),
|
|
166
|
+
scopedIslandDependencyPlugin()
|
|
167
|
+
];
|
|
168
|
+
}
|
|
169
|
+
function disableHonoxIslandDependencyPlugin(plugin) {
|
|
170
|
+
if (plugin instanceof Promise) {
|
|
171
|
+
return plugin.then(disableHonoxIslandDependencyPlugin);
|
|
172
|
+
}
|
|
173
|
+
if (plugin.name !== honoxIslandDependencyPluginName) return plugin;
|
|
174
|
+
return { ...plugin, transform: void 0 };
|
|
175
|
+
}
|
|
176
|
+
function scopedIslandDependencyPlugin() {
|
|
177
|
+
let appDirectory = "";
|
|
178
|
+
let islandDirectory = "";
|
|
167
179
|
return {
|
|
168
|
-
name: "riebeckite-
|
|
169
|
-
apply: "build",
|
|
170
|
-
enforce: "post",
|
|
171
|
-
config() {
|
|
172
|
-
return {
|
|
173
|
-
build: {
|
|
174
|
-
rollupOptions: {
|
|
175
|
-
input: [virtualId]
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
},
|
|
180
|
+
name: "riebeckite-inject-importing-islands",
|
|
180
181
|
configResolved(config) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
resolveId(id) {
|
|
184
|
-
return id === virtualId ? resolvedVirtualId : void 0;
|
|
182
|
+
appDirectory = path3.resolve(config.root, "app");
|
|
183
|
+
islandDirectory = path3.join(appDirectory, "islands");
|
|
185
184
|
},
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const config = resolvedConfig;
|
|
191
|
-
if (!config) {
|
|
192
|
-
throw new Error("Riebeckite SSG could not resolve the Vite configuration.");
|
|
193
|
-
}
|
|
194
|
-
removeVirtualEntryChunk(bundle, resolvedVirtualId);
|
|
195
|
-
const server2 = await createServer({
|
|
196
|
-
root: config.root,
|
|
197
|
-
define: config.define,
|
|
198
|
-
resolve: {
|
|
199
|
-
...config.resolve,
|
|
200
|
-
builtins: [...config.resolve.builtins, /^node:/]
|
|
201
|
-
},
|
|
202
|
-
plugins: [],
|
|
203
|
-
build: { ssr: true },
|
|
204
|
-
mode: config.mode
|
|
205
|
-
});
|
|
206
|
-
try {
|
|
207
|
-
const module = await server2.ssrLoadModule(entry);
|
|
208
|
-
const app = module.default;
|
|
209
|
-
if (!app) {
|
|
210
|
-
throw new Error(`Failed to find a default export from ${entry}.`);
|
|
211
|
-
}
|
|
212
|
-
const generatedHtml = [];
|
|
213
|
-
const result = await toSSG(
|
|
214
|
-
app,
|
|
215
|
-
{
|
|
216
|
-
writeFile: async (filePath, data) => {
|
|
217
|
-
const fileName = relative(config.build.outDir, filePath).replaceAll(
|
|
218
|
-
"\\",
|
|
219
|
-
"/"
|
|
220
|
-
);
|
|
221
|
-
if (fileName.endsWith(".html") && typeof data === "string") {
|
|
222
|
-
generatedHtml.push({ path: fileName, html: data });
|
|
223
|
-
}
|
|
224
|
-
this.emitFile({
|
|
225
|
-
type: "asset",
|
|
226
|
-
fileName,
|
|
227
|
-
source: data
|
|
228
|
-
});
|
|
229
|
-
},
|
|
230
|
-
async mkdir() {
|
|
231
|
-
}
|
|
232
|
-
},
|
|
233
|
-
{
|
|
234
|
-
dir: config.build.outDir,
|
|
235
|
-
plugins: options.plugins ?? [],
|
|
236
|
-
extensionMap: options.extensionMap ?? defaultExtensionMap
|
|
237
|
-
}
|
|
238
|
-
);
|
|
239
|
-
if (!result.success) throw result.error;
|
|
240
|
-
await emitGeneratedOutputs(
|
|
241
|
-
module,
|
|
242
|
-
(asset) => this.emitFile(asset)
|
|
243
|
-
);
|
|
244
|
-
inspectGeneratedHtmlPages(module, generatedHtml, {
|
|
245
|
-
warn: (message) => this.warn(message),
|
|
246
|
-
info: (message) => this.info(message)
|
|
247
|
-
});
|
|
248
|
-
} finally {
|
|
249
|
-
await server2.close();
|
|
185
|
+
async transform(sourceCode, id) {
|
|
186
|
+
const modulePath = toFilePath(id);
|
|
187
|
+
if (!isInDirectory(modulePath, appDirectory) || !isJavaScriptModule(modulePath)) {
|
|
188
|
+
return;
|
|
250
189
|
}
|
|
190
|
+
if (!await importsIsland(modulePath, sourceCode, this)) return;
|
|
191
|
+
return {
|
|
192
|
+
code: `${sourceCode}
|
|
193
|
+
export const ${importingIslandsExport} = true;
|
|
194
|
+
`,
|
|
195
|
+
map: null
|
|
196
|
+
};
|
|
251
197
|
}
|
|
252
198
|
};
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
199
|
+
async function importsIsland(modulePath, sourceCode, pluginContext) {
|
|
200
|
+
const visited = /* @__PURE__ */ new Set();
|
|
201
|
+
const visit = async (currentModulePath, currentSourceCode) => {
|
|
202
|
+
if (visited.has(currentModulePath)) return false;
|
|
203
|
+
visited.add(currentModulePath);
|
|
204
|
+
if (isInDirectory(currentModulePath, islandDirectory)) return true;
|
|
205
|
+
const importSources = getStaticImportSources(currentSourceCode);
|
|
206
|
+
for (const importSource of importSources) {
|
|
207
|
+
const resolved = await pluginContext.resolve(
|
|
208
|
+
importSource,
|
|
209
|
+
currentModulePath
|
|
210
|
+
);
|
|
211
|
+
if (!resolved) continue;
|
|
212
|
+
const dependencyPath = toFilePath(resolved.id);
|
|
213
|
+
if (!isInDirectory(dependencyPath, appDirectory) || !isJavaScriptModule(dependencyPath)) {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
try {
|
|
217
|
+
const dependencySourceCode = await fs3.readFile(
|
|
218
|
+
dependencyPath,
|
|
219
|
+
"utf8"
|
|
220
|
+
);
|
|
221
|
+
if (await visit(dependencyPath, dependencySourceCode)) return true;
|
|
222
|
+
} catch {
|
|
223
|
+
}
|
|
276
224
|
}
|
|
277
|
-
|
|
225
|
+
return false;
|
|
226
|
+
};
|
|
227
|
+
return visit(modulePath, sourceCode);
|
|
278
228
|
}
|
|
279
229
|
}
|
|
280
|
-
function
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
230
|
+
function getStaticImportSources(sourceCode) {
|
|
231
|
+
const ast = parse(sourceCode, {
|
|
232
|
+
sourceType: "module",
|
|
233
|
+
plugins: ["typescript", "jsx"]
|
|
234
|
+
});
|
|
235
|
+
return ast.program.body.flatMap((statement) => {
|
|
236
|
+
if (statement.type === "ImportDeclaration" || statement.type === "ExportNamedDeclaration" || statement.type === "ExportAllDeclaration") {
|
|
237
|
+
return statement.source ? [statement.source.value] : [];
|
|
284
238
|
}
|
|
285
|
-
|
|
239
|
+
return [];
|
|
240
|
+
});
|
|
286
241
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
var defaultSsgEntry = "./app/server.ts";
|
|
290
|
-
function riebeckiteSsgExtensionMap() {
|
|
291
|
-
return {
|
|
292
|
-
"application/atom+xml": "xml",
|
|
293
|
-
"application/json": "json",
|
|
294
|
-
"application/rss+xml": "xml",
|
|
295
|
-
"application/xml": "xml",
|
|
296
|
-
"text/html": "html",
|
|
297
|
-
"text/plain": "txt",
|
|
298
|
-
"text/xml": "xml"
|
|
299
|
-
};
|
|
242
|
+
function toFilePath(id) {
|
|
243
|
+
return id.split("?", 1)[0] ?? id;
|
|
300
244
|
}
|
|
301
|
-
function
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
...options.extensionMap
|
|
308
|
-
}
|
|
309
|
-
});
|
|
245
|
+
function isInDirectory(filePath, directory) {
|
|
246
|
+
const relativePath = path3.relative(directory, filePath);
|
|
247
|
+
return relativePath !== "" && !relativePath.startsWith(`..${path3.sep}`) && !path3.isAbsolute(relativePath);
|
|
248
|
+
}
|
|
249
|
+
function isJavaScriptModule(filePath) {
|
|
250
|
+
return /\.[cm]?[jt]sx?$/.test(filePath);
|
|
310
251
|
}
|
|
311
252
|
|
|
312
|
-
// src/
|
|
313
|
-
import
|
|
253
|
+
// src/scaffold/index.ts
|
|
254
|
+
import fs4 from "node:fs/promises";
|
|
255
|
+
import path4 from "node:path";
|
|
314
256
|
|
|
315
|
-
// src/
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
257
|
+
// src/scaffold/localized-content.ts
|
|
258
|
+
var SCAFFOLD_LANGUAGES = [
|
|
259
|
+
"en",
|
|
260
|
+
"ja",
|
|
261
|
+
"zh-CN",
|
|
262
|
+
"es",
|
|
263
|
+
"de",
|
|
264
|
+
"fr",
|
|
265
|
+
"ko"
|
|
266
|
+
];
|
|
267
|
+
function defaultLanguageForLocale(locale) {
|
|
268
|
+
const normalized = locale.toLowerCase();
|
|
269
|
+
if (normalized.startsWith("ja")) return "ja";
|
|
270
|
+
if (normalized.startsWith("zh")) return "zh-CN";
|
|
271
|
+
if (normalized.startsWith("es")) return "es";
|
|
272
|
+
if (normalized.startsWith("de")) return "de";
|
|
273
|
+
if (normalized.startsWith("fr")) return "fr";
|
|
274
|
+
if (normalized.startsWith("ko")) return "ko";
|
|
275
|
+
return "en";
|
|
322
276
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
277
|
+
var HELPERS = {
|
|
278
|
+
en: "https://github.com/Rerurate514/riebeckite/blob/main/docs/en/README.md",
|
|
279
|
+
ja: "https://github.com/Rerurate514/riebeckite/blob/main/docs/ja/README.md"
|
|
280
|
+
};
|
|
281
|
+
var PLUGIN_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/plugins";
|
|
282
|
+
var THEMES_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/themes";
|
|
283
|
+
function pluginReadmeUrl(slug) {
|
|
284
|
+
return `https://github.com/Rerurate514/riebeckite/blob/main/packages/plugins/${slug}/README.md`;
|
|
328
285
|
}
|
|
329
|
-
function
|
|
330
|
-
return
|
|
331
|
-
config.theme.styles.map((style2) => style2.moduleSpecifier),
|
|
332
|
-
"Theme styles. Generated by @riebeckite/honox; do not edit. Import this after the plugin stylesheet so the theme wins the plugin/theme cascade."
|
|
333
|
-
);
|
|
286
|
+
function themeReadmeUrl(slug) {
|
|
287
|
+
return `https://github.com/Rerurate514/riebeckite/blob/main/packages/themes/${slug}/README.md`;
|
|
334
288
|
}
|
|
335
|
-
function
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
289
|
+
function localizedContentFiles(variables) {
|
|
290
|
+
const defaultLang = defaultLanguageForLocale(variables.locale);
|
|
291
|
+
const pages = [
|
|
292
|
+
{ basePath: "index", build: (language) => indexContent(variables, language) },
|
|
293
|
+
{ basePath: "framework/plugins", build: (language) => pluginsContent(language) },
|
|
294
|
+
{ basePath: "framework/themes", build: (language) => themesContent(language) }
|
|
295
|
+
];
|
|
296
|
+
const files = [];
|
|
297
|
+
for (const page of pages) {
|
|
298
|
+
for (const language of SCAFFOLD_LANGUAGES) {
|
|
299
|
+
const suffix = language === defaultLang ? "" : `.${language}`;
|
|
300
|
+
files.push({
|
|
301
|
+
path: `content/${page.basePath}${suffix}.md`,
|
|
302
|
+
content: page.build(language)
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return files;
|
|
339
307
|
}
|
|
340
|
-
function
|
|
341
|
-
|
|
342
|
-
if (!banner) return imports;
|
|
343
|
-
const header = `/* ${banner.replace(/\*\//g, "* /")} */`;
|
|
344
|
-
return imports ? `${header}
|
|
345
|
-
${imports}
|
|
346
|
-
` : `${header}
|
|
347
|
-
`;
|
|
308
|
+
function read(text, language) {
|
|
309
|
+
return text[language];
|
|
348
310
|
}
|
|
349
|
-
function
|
|
350
|
-
|
|
351
|
-
fs3.writeFileSync(filePath, contents);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// src/client_module.ts
|
|
355
|
-
var clientModuleId = "virtual:riebeckite/client";
|
|
356
|
-
var resolvedClientModuleId = `\0${clientModuleId}`;
|
|
357
|
-
function riebeckiteClientModule(getConfig) {
|
|
358
|
-
return {
|
|
359
|
-
name: "riebeckite-client-module",
|
|
360
|
-
resolveId(id) {
|
|
361
|
-
if (id === clientModuleId) return resolvedClientModuleId;
|
|
362
|
-
return null;
|
|
363
|
-
},
|
|
364
|
-
load(id) {
|
|
365
|
-
if (id !== resolvedClientModuleId) return null;
|
|
366
|
-
return createClientModule(getConfig());
|
|
367
|
-
}
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
function createClientModule(config) {
|
|
371
|
-
const imports = [];
|
|
372
|
-
const initializers = [];
|
|
373
|
-
for (const [index, entry] of config.plugins.flatMap((plugin) => plugin.clientEntries ?? []).entries()) {
|
|
374
|
-
const localName = `pluginClientInitializer${index}`;
|
|
375
|
-
const importTarget = entry.exportName ? `{ ${entry.exportName} as ${localName} }` : localName;
|
|
376
|
-
imports.push(
|
|
377
|
-
`import ${importTarget} from ${JSON.stringify(entry.moduleSpecifier)};`
|
|
378
|
-
);
|
|
379
|
-
initializers.push(localName);
|
|
380
|
-
}
|
|
381
|
-
return `${imports.join("\n")}
|
|
382
|
-
|
|
383
|
-
export function initRiebeckiteClient() {
|
|
384
|
-
${initializers.map((name) => ` ${name}();`).join("\n")}
|
|
385
|
-
}
|
|
386
|
-
`;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
// src/vite_runner.ts
|
|
390
|
-
import fs4 from "node:fs/promises";
|
|
391
|
-
import path4 from "node:path";
|
|
392
|
-
import { build, createServer as createServer2 } from "vite";
|
|
393
|
-
var viteConfigFileNames = [
|
|
394
|
-
"vite.config.ts",
|
|
395
|
-
"vite.config.js",
|
|
396
|
-
"vite.config.mjs"
|
|
397
|
-
];
|
|
398
|
-
async function resolveHonoxApplicationRoot(configRoot) {
|
|
399
|
-
const roots = await findViteApplicationRoots(configRoot);
|
|
400
|
-
if (roots.length === 1) return roots[0];
|
|
401
|
-
if (roots.length === 0) {
|
|
402
|
-
throw new HonoxApplicationRootError(
|
|
403
|
-
`Could not find a Vite application under ${configRoot}.`
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
throw new HonoxApplicationRootError(
|
|
407
|
-
`Found multiple Vite applications under ${configRoot}: ${roots.join(", ")}.`
|
|
408
|
-
);
|
|
409
|
-
}
|
|
410
|
-
var HonoxApplicationRootError = class extends Error {
|
|
411
|
-
constructor(message) {
|
|
412
|
-
super(message);
|
|
413
|
-
this.name = "HonoxApplicationRootError";
|
|
414
|
-
}
|
|
415
|
-
};
|
|
416
|
-
async function resolveHonoxApplication(options) {
|
|
417
|
-
const configRoot = path4.resolve(options.configRoot);
|
|
418
|
-
const appRoot = options.appRoot ? path4.resolve(options.appRoot) : await resolveHonoxApplicationRoot(configRoot);
|
|
419
|
-
const workspaceRoot = options.workspaceRoot ?? await findWorkspaceRoot(configRoot);
|
|
420
|
-
const rawConfig = await loadRiebeckiteConfig({
|
|
421
|
-
configRoot,
|
|
422
|
-
configFile: options.configFile,
|
|
423
|
-
workspaceRoot
|
|
424
|
-
});
|
|
425
|
-
const config = resolveHonoxConfig(rawConfig, appRoot);
|
|
426
|
-
return {
|
|
427
|
-
config,
|
|
428
|
-
configRoot,
|
|
429
|
-
appRoot,
|
|
430
|
-
contentRoot: config.content.directory
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
async function findWorkspaceRoot(configRoot) {
|
|
434
|
-
try {
|
|
435
|
-
const workspaceConfig = path4.join(configRoot, "pnpm-workspace.yaml");
|
|
436
|
-
return (await fs4.stat(workspaceConfig)).isFile() ? configRoot : void 0;
|
|
437
|
-
} catch {
|
|
438
|
-
return void 0;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
async function startHonoxDevServer(options) {
|
|
442
|
-
const server2 = await createServer2({ root: options.root });
|
|
443
|
-
await server2.listen();
|
|
444
|
-
server2.printUrls();
|
|
445
|
-
await waitForShutdown(server2);
|
|
446
|
-
}
|
|
447
|
-
async function buildHonoxApplication(options) {
|
|
448
|
-
await runTraced(
|
|
449
|
-
options.tracer,
|
|
450
|
-
"integration.honox.client_build",
|
|
451
|
-
() => build({ root: options.root, mode: "client" })
|
|
452
|
-
);
|
|
453
|
-
await runTraced(
|
|
454
|
-
options.tracer,
|
|
455
|
-
"integration.honox.server_build",
|
|
456
|
-
() => build({ root: options.root })
|
|
457
|
-
);
|
|
458
|
-
}
|
|
459
|
-
async function runTraced(tracer, name, buildTask) {
|
|
460
|
-
return tracer ? await tracer.span(name, {}, buildTask) : await buildTask();
|
|
461
|
-
}
|
|
462
|
-
async function waitForShutdown(server2) {
|
|
463
|
-
await new Promise((resolve) => {
|
|
464
|
-
const close = () => {
|
|
465
|
-
void server2.close().finally(resolve);
|
|
466
|
-
};
|
|
467
|
-
process.once("SIGINT", close);
|
|
468
|
-
process.once("SIGTERM", close);
|
|
469
|
-
});
|
|
470
|
-
}
|
|
471
|
-
async function findViteApplicationRoots(root) {
|
|
472
|
-
const directories = [root];
|
|
473
|
-
const applicationRoots = [];
|
|
474
|
-
while (directories.length > 0) {
|
|
475
|
-
const directory = directories.pop();
|
|
476
|
-
if (!directory) continue;
|
|
477
|
-
if (await hasViteConfig(directory)) applicationRoots.push(directory);
|
|
478
|
-
const entries = await fs4.readdir(directory, { withFileTypes: true });
|
|
479
|
-
for (const entry of entries) {
|
|
480
|
-
if (!entry.isDirectory() || entry.name === "node_modules" || entry.name === ".git" || entry.name === "tests") {
|
|
481
|
-
continue;
|
|
482
|
-
}
|
|
483
|
-
directories.push(path4.join(directory, entry.name));
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
return applicationRoots;
|
|
487
|
-
}
|
|
488
|
-
async function hasViteConfig(directory) {
|
|
489
|
-
for (const fileName of viteConfigFileNames) {
|
|
490
|
-
try {
|
|
491
|
-
if ((await fs4.stat(path4.join(directory, fileName))).isFile()) return true;
|
|
492
|
-
} catch {
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
return false;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// src/vite_plugin.ts
|
|
499
|
-
var defaultSsrExternals = [
|
|
500
|
-
"extend",
|
|
501
|
-
"debug",
|
|
502
|
-
"node:fs/promises",
|
|
503
|
-
"node:path",
|
|
504
|
-
"parse-numeric-range",
|
|
505
|
-
"slugify",
|
|
506
|
-
"vfile-matter"
|
|
507
|
-
];
|
|
508
|
-
function riebeckite(options = {}) {
|
|
509
|
-
let resolvedConfig;
|
|
510
|
-
const getConfig = () => {
|
|
511
|
-
if (!resolvedConfig) {
|
|
512
|
-
throw new Error("Riebeckite config has not been loaded yet.");
|
|
513
|
-
}
|
|
514
|
-
return resolvedConfig;
|
|
515
|
-
};
|
|
516
|
-
return [
|
|
517
|
-
{
|
|
518
|
-
name: "riebeckite-host-integration",
|
|
519
|
-
async config(userConfig) {
|
|
520
|
-
const root = userConfig.root ? path5.resolve(userConfig.root) : process.cwd();
|
|
521
|
-
const appRoot = options.appRoot ?? root;
|
|
522
|
-
const application = await resolveHonoxApplication({
|
|
523
|
-
configRoot: options.configRoot ?? appRoot,
|
|
524
|
-
configFile: options.configFile,
|
|
525
|
-
appRoot,
|
|
526
|
-
workspaceRoot: options.workspaceRoot
|
|
527
|
-
});
|
|
528
|
-
resolvedConfig = application.config;
|
|
529
|
-
writeRiebeckiteAssetEntries(resolvedConfig, {
|
|
530
|
-
pluginStyles: path5.join(appRoot, "app/.riebeckite/plugin-styles.css"),
|
|
531
|
-
themeStyles: path5.join(appRoot, "app/.riebeckite/theme-styles.css")
|
|
532
|
-
});
|
|
533
|
-
return {
|
|
534
|
-
define: {
|
|
535
|
-
"process.env.RIEBECKITE_APP_ROOT": JSON.stringify(appRoot)
|
|
536
|
-
},
|
|
537
|
-
resolve: {
|
|
538
|
-
alias: options.workspaceRoot ? createWorkspacePackageAliases(options.workspaceRoot) : []
|
|
539
|
-
}
|
|
540
|
-
};
|
|
541
|
-
}
|
|
542
|
-
},
|
|
543
|
-
riebeckiteClientModule(getConfig)
|
|
544
|
-
];
|
|
545
|
-
}
|
|
546
|
-
function riebeckiteVite(options = {}) {
|
|
547
|
-
const { ssg, ssrExternals, ...integration } = options;
|
|
548
|
-
return [
|
|
549
|
-
...riebeckite(integration),
|
|
550
|
-
riebeckiteSsrExternals([...defaultSsrExternals, ...ssrExternals ?? []]),
|
|
551
|
-
createRiebeckiteSsg(ssg)
|
|
552
|
-
];
|
|
553
|
-
}
|
|
554
|
-
function riebeckiteSsrExternals(externals) {
|
|
555
|
-
return {
|
|
556
|
-
name: "riebeckite-ssr-externals",
|
|
557
|
-
config() {
|
|
558
|
-
return {
|
|
559
|
-
environments: {
|
|
560
|
-
ssr: {
|
|
561
|
-
resolve: {
|
|
562
|
-
external: [...externals]
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
};
|
|
567
|
-
}
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// src/scaffold/index.ts
|
|
572
|
-
import fs5 from "node:fs/promises";
|
|
573
|
-
import path6 from "node:path";
|
|
574
|
-
|
|
575
|
-
// src/scaffold/localized-content.ts
|
|
576
|
-
var SCAFFOLD_LANGUAGES = [
|
|
577
|
-
"en",
|
|
578
|
-
"ja",
|
|
579
|
-
"zh-CN",
|
|
580
|
-
"es",
|
|
581
|
-
"de",
|
|
582
|
-
"fr",
|
|
583
|
-
"ko"
|
|
584
|
-
];
|
|
585
|
-
function defaultLanguageForLocale(locale) {
|
|
586
|
-
const normalized = locale.toLowerCase();
|
|
587
|
-
if (normalized.startsWith("ja")) return "ja";
|
|
588
|
-
if (normalized.startsWith("zh")) return "zh-CN";
|
|
589
|
-
if (normalized.startsWith("es")) return "es";
|
|
590
|
-
if (normalized.startsWith("de")) return "de";
|
|
591
|
-
if (normalized.startsWith("fr")) return "fr";
|
|
592
|
-
if (normalized.startsWith("ko")) return "ko";
|
|
593
|
-
return "en";
|
|
594
|
-
}
|
|
595
|
-
var HELPERS = {
|
|
596
|
-
en: "https://github.com/Rerurate514/riebeckite/blob/main/docs/en/README.md",
|
|
597
|
-
ja: "https://github.com/Rerurate514/riebeckite/blob/main/docs/ja/README.md"
|
|
598
|
-
};
|
|
599
|
-
var PLUGIN_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/plugins";
|
|
600
|
-
var THEMES_INDEX_URL = "https://github.com/Rerurate514/riebeckite/tree/main/packages/themes";
|
|
601
|
-
function pluginReadmeUrl(slug) {
|
|
602
|
-
return `https://github.com/Rerurate514/riebeckite/blob/main/packages/plugins/${slug}/README.md`;
|
|
603
|
-
}
|
|
604
|
-
function themeReadmeUrl(slug) {
|
|
605
|
-
return `https://github.com/Rerurate514/riebeckite/blob/main/packages/themes/${slug}/README.md`;
|
|
606
|
-
}
|
|
607
|
-
function localizedContentFiles(variables) {
|
|
608
|
-
const defaultLang = defaultLanguageForLocale(variables.locale);
|
|
609
|
-
const pages = [
|
|
610
|
-
{ basePath: "index", build: (language) => indexContent(variables, language) },
|
|
611
|
-
{ basePath: "framework/plugins", build: (language) => pluginsContent(language) },
|
|
612
|
-
{ basePath: "framework/themes", build: (language) => themesContent(language) }
|
|
613
|
-
];
|
|
614
|
-
const files = [];
|
|
615
|
-
for (const page of pages) {
|
|
616
|
-
for (const language of SCAFFOLD_LANGUAGES) {
|
|
617
|
-
const suffix = language === defaultLang ? "" : `.${language}`;
|
|
618
|
-
files.push({
|
|
619
|
-
path: `content/${page.basePath}${suffix}.md`,
|
|
620
|
-
content: page.build(language)
|
|
621
|
-
});
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
return files;
|
|
625
|
-
}
|
|
626
|
-
function read(text, language) {
|
|
627
|
-
return text[language];
|
|
628
|
-
}
|
|
629
|
-
function frontmatter() {
|
|
630
|
-
return ["---", "publish: true", "---", ""].join("\n");
|
|
311
|
+
function frontmatter() {
|
|
312
|
+
return ["---", "publish: true", "---", ""].join("\n");
|
|
631
313
|
}
|
|
632
314
|
function heading(level, text) {
|
|
633
315
|
return `${"#".repeat(level)} ${text}`;
|
|
@@ -1539,18 +1221,18 @@ function packageJson(variables) {
|
|
|
1539
1221
|
inspect: "riebeckite inspect"
|
|
1540
1222
|
},
|
|
1541
1223
|
dependencies: {
|
|
1542
|
-
"@riebeckite/core": "^0.0.
|
|
1543
|
-
"@riebeckite/honox": "^0.0.
|
|
1544
|
-
"@riebeckite/plugin-color-mode": "^0.0.
|
|
1545
|
-
"@riebeckite/plugin-l10n": "^0.0.
|
|
1546
|
-
"@riebeckite/plugin-obsidian-markdown": "^0.0.
|
|
1547
|
-
"@riebeckite/theme-default": "^0.0.
|
|
1224
|
+
"@riebeckite/core": "^0.0.3",
|
|
1225
|
+
"@riebeckite/honox": "^0.0.3",
|
|
1226
|
+
"@riebeckite/plugin-color-mode": "^0.0.3",
|
|
1227
|
+
"@riebeckite/plugin-l10n": "^0.0.3",
|
|
1228
|
+
"@riebeckite/plugin-obsidian-markdown": "^0.0.3",
|
|
1229
|
+
"@riebeckite/theme-default": "^0.0.3",
|
|
1548
1230
|
hono: "^4.12.25",
|
|
1549
1231
|
honox: "0.1.56"
|
|
1550
1232
|
},
|
|
1551
1233
|
devDependencies: {
|
|
1552
1234
|
"@hono/vite-build": "^1.11.1",
|
|
1553
|
-
"@riebeckite/cli": "^0.0.
|
|
1235
|
+
"@riebeckite/cli": "^0.0.3",
|
|
1554
1236
|
"@types/node": "^24.5.2",
|
|
1555
1237
|
typescript: "^5.0.0",
|
|
1556
1238
|
vite: "^8.0.9"
|
|
@@ -2102,7 +1784,7 @@ var ScaffoldSiteError = class extends Error {
|
|
|
2102
1784
|
}
|
|
2103
1785
|
};
|
|
2104
1786
|
async function scaffoldRiebeckiteSite(options) {
|
|
2105
|
-
const targetDirectory =
|
|
1787
|
+
const targetDirectory = path4.resolve(options.targetDirectory);
|
|
2106
1788
|
const files = siteTemplateFiles(templateVariables(options, targetDirectory));
|
|
2107
1789
|
await assertTargetWritable(
|
|
2108
1790
|
targetDirectory,
|
|
@@ -2110,15 +1792,15 @@ async function scaffoldRiebeckiteSite(options) {
|
|
|
2110
1792
|
options.overwrite ?? false
|
|
2111
1793
|
);
|
|
2112
1794
|
for (const file of files) {
|
|
2113
|
-
const filePath =
|
|
2114
|
-
await
|
|
2115
|
-
await
|
|
1795
|
+
const filePath = path4.join(targetDirectory, file.path);
|
|
1796
|
+
await fs4.mkdir(path4.dirname(filePath), { recursive: true });
|
|
1797
|
+
await fs4.writeFile(filePath, file.content, "utf8");
|
|
2116
1798
|
}
|
|
2117
1799
|
return { targetDirectory, files: files.map((file) => file.path) };
|
|
2118
1800
|
}
|
|
2119
1801
|
function templateVariables(options, targetDirectory) {
|
|
2120
1802
|
const name = normalizePackageName(
|
|
2121
|
-
options.name ??
|
|
1803
|
+
options.name ?? path4.basename(targetDirectory)
|
|
2122
1804
|
);
|
|
2123
1805
|
return {
|
|
2124
1806
|
name,
|
|
@@ -2131,7 +1813,7 @@ function templateVariables(options, targetDirectory) {
|
|
|
2131
1813
|
async function assertTargetWritable(targetDirectory, files, overwrite) {
|
|
2132
1814
|
let entries;
|
|
2133
1815
|
try {
|
|
2134
|
-
entries = await
|
|
1816
|
+
entries = await fs4.readdir(targetDirectory);
|
|
2135
1817
|
} catch (error) {
|
|
2136
1818
|
if (isNotFoundError(error)) return;
|
|
2137
1819
|
throw error;
|
|
@@ -2154,6 +1836,427 @@ function normalizePackageName(value) {
|
|
|
2154
1836
|
function isNotFoundError(error) {
|
|
2155
1837
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
2156
1838
|
}
|
|
1839
|
+
|
|
1840
|
+
// src/ssg_plugin.ts
|
|
1841
|
+
import { defaultExtensionMap, toSSG } from "hono/ssg";
|
|
1842
|
+
import { relative } from "node:path";
|
|
1843
|
+
import { createServer } from "vite";
|
|
1844
|
+
var defaultEntry = "./src/index.tsx";
|
|
1845
|
+
function riebeckiteSsg(options = {}) {
|
|
1846
|
+
const virtualId = "virtual:riebeckite-ssg-void-entry";
|
|
1847
|
+
const resolvedVirtualId = `\0${virtualId}`;
|
|
1848
|
+
const entry = options.entry ?? defaultEntry;
|
|
1849
|
+
let resolvedConfig;
|
|
1850
|
+
return {
|
|
1851
|
+
name: "riebeckite-ssg",
|
|
1852
|
+
apply: "build",
|
|
1853
|
+
enforce: "post",
|
|
1854
|
+
config() {
|
|
1855
|
+
return {
|
|
1856
|
+
build: {
|
|
1857
|
+
rollupOptions: {
|
|
1858
|
+
input: [virtualId]
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
};
|
|
1862
|
+
},
|
|
1863
|
+
configResolved(config) {
|
|
1864
|
+
resolvedConfig = config;
|
|
1865
|
+
},
|
|
1866
|
+
resolveId(id) {
|
|
1867
|
+
return id === virtualId ? resolvedVirtualId : void 0;
|
|
1868
|
+
},
|
|
1869
|
+
load(id) {
|
|
1870
|
+
return id === resolvedVirtualId ? 'console.log("suppress empty chunk message")' : void 0;
|
|
1871
|
+
},
|
|
1872
|
+
async generateBundle(_outputOptions, bundle) {
|
|
1873
|
+
const config = resolvedConfig;
|
|
1874
|
+
if (!config) {
|
|
1875
|
+
throw new Error("Riebeckite SSG could not resolve the Vite configuration.");
|
|
1876
|
+
}
|
|
1877
|
+
removeVirtualEntryChunk(bundle, resolvedVirtualId);
|
|
1878
|
+
const server2 = await createServer({
|
|
1879
|
+
root: config.root,
|
|
1880
|
+
define: config.define,
|
|
1881
|
+
resolve: {
|
|
1882
|
+
...config.resolve,
|
|
1883
|
+
builtins: [...config.resolve.builtins, /^node:/]
|
|
1884
|
+
},
|
|
1885
|
+
plugins: [],
|
|
1886
|
+
build: { ssr: true },
|
|
1887
|
+
mode: config.mode
|
|
1888
|
+
});
|
|
1889
|
+
try {
|
|
1890
|
+
const module = await server2.ssrLoadModule(entry);
|
|
1891
|
+
const app = module.default;
|
|
1892
|
+
if (!app) {
|
|
1893
|
+
throw new Error(`Failed to find a default export from ${entry}.`);
|
|
1894
|
+
}
|
|
1895
|
+
const generatedHtml = [];
|
|
1896
|
+
const result = await toSSG(
|
|
1897
|
+
app,
|
|
1898
|
+
{
|
|
1899
|
+
writeFile: async (filePath, data) => {
|
|
1900
|
+
const fileName = relative(config.build.outDir, filePath).replaceAll(
|
|
1901
|
+
"\\",
|
|
1902
|
+
"/"
|
|
1903
|
+
);
|
|
1904
|
+
if (fileName.endsWith(".html") && typeof data === "string") {
|
|
1905
|
+
generatedHtml.push({ path: fileName, html: data });
|
|
1906
|
+
}
|
|
1907
|
+
this.emitFile({
|
|
1908
|
+
type: "asset",
|
|
1909
|
+
fileName,
|
|
1910
|
+
source: data
|
|
1911
|
+
});
|
|
1912
|
+
},
|
|
1913
|
+
async mkdir() {
|
|
1914
|
+
}
|
|
1915
|
+
},
|
|
1916
|
+
{
|
|
1917
|
+
dir: config.build.outDir,
|
|
1918
|
+
plugins: options.plugins ?? [],
|
|
1919
|
+
extensionMap: options.extensionMap ?? defaultExtensionMap
|
|
1920
|
+
}
|
|
1921
|
+
);
|
|
1922
|
+
if (!result.success) throw result.error;
|
|
1923
|
+
await emitGeneratedOutputs(
|
|
1924
|
+
module,
|
|
1925
|
+
(asset) => this.emitFile(asset)
|
|
1926
|
+
);
|
|
1927
|
+
inspectGeneratedHtmlPages(module, generatedHtml, {
|
|
1928
|
+
warn: (message) => this.warn(message),
|
|
1929
|
+
info: (message) => this.info(message)
|
|
1930
|
+
});
|
|
1931
|
+
} finally {
|
|
1932
|
+
await server2.close();
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
};
|
|
1936
|
+
}
|
|
1937
|
+
async function emitGeneratedOutputs(module, emit) {
|
|
1938
|
+
const content = module.content;
|
|
1939
|
+
if (!content) return;
|
|
1940
|
+
const manifest = await content.getManifest();
|
|
1941
|
+
for (const output of manifest.generatedOutputs ?? []) {
|
|
1942
|
+
emit({
|
|
1943
|
+
type: "asset",
|
|
1944
|
+
fileName: output.path,
|
|
1945
|
+
source: output.content
|
|
1946
|
+
});
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
function inspectGeneratedHtmlPages(module, pages, log) {
|
|
1950
|
+
const plugins = module.config?.plugins ?? [];
|
|
1951
|
+
for (const plugin of plugins) {
|
|
1952
|
+
const inspector = plugin.inspectGeneratedHtml;
|
|
1953
|
+
if (typeof inspector !== "function") continue;
|
|
1954
|
+
for (const page of pages) {
|
|
1955
|
+
for (const diagnostic of inspector(page) ?? []) {
|
|
1956
|
+
const label = `[${plugin.name ?? "plugin"}] ${page.path}: ${diagnostic.message}`;
|
|
1957
|
+
if (diagnostic.severity === "info") log.info(label);
|
|
1958
|
+
else log.warn(label);
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
function removeVirtualEntryChunk(bundle, virtualEntryId) {
|
|
1964
|
+
for (const chunk of Object.values(bundle)) {
|
|
1965
|
+
if (chunk.type === "chunk" && chunk.moduleIds?.includes(virtualEntryId)) {
|
|
1966
|
+
delete bundle[chunk.fileName];
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
// src/ssg.ts
|
|
1972
|
+
var defaultSsgEntry = "./app/server.ts";
|
|
1973
|
+
function riebeckiteSsgExtensionMap() {
|
|
1974
|
+
return {
|
|
1975
|
+
"application/atom+xml": "xml",
|
|
1976
|
+
"application/json": "json",
|
|
1977
|
+
"application/rss+xml": "xml",
|
|
1978
|
+
"application/xml": "xml",
|
|
1979
|
+
"text/html": "html",
|
|
1980
|
+
"text/plain": "txt",
|
|
1981
|
+
"text/xml": "xml"
|
|
1982
|
+
};
|
|
1983
|
+
}
|
|
1984
|
+
function createRiebeckiteSsg(options = {}) {
|
|
1985
|
+
return riebeckiteSsg({
|
|
1986
|
+
...options,
|
|
1987
|
+
entry: options.entry ?? defaultSsgEntry,
|
|
1988
|
+
extensionMap: {
|
|
1989
|
+
...riebeckiteSsgExtensionMap(),
|
|
1990
|
+
...options.extensionMap
|
|
1991
|
+
}
|
|
1992
|
+
});
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
// src/vite_plugin.ts
|
|
1996
|
+
import path7 from "node:path";
|
|
1997
|
+
|
|
1998
|
+
// src/asset_entries.ts
|
|
1999
|
+
import fs5 from "node:fs";
|
|
2000
|
+
import path5 from "node:path";
|
|
2001
|
+
import { uniqueStrings } from "@riebeckite/core";
|
|
2002
|
+
function writeRiebeckiteAssetEntries(config, paths2) {
|
|
2003
|
+
writeGeneratedFile(paths2.pluginStyles, createPluginStylesEntry(config));
|
|
2004
|
+
writeGeneratedFile(paths2.themeStyles, createThemeStylesEntry(config));
|
|
2005
|
+
}
|
|
2006
|
+
function createPluginStylesEntry(config) {
|
|
2007
|
+
return createStylesheetEntry(
|
|
2008
|
+
collectPluginStyleSpecifiers(config),
|
|
2009
|
+
"Plugin default styles, in resolved plugin order. Generated by @riebeckite/honox; do not edit. Import this before the theme stylesheet so a theme can override plugin defaults."
|
|
2010
|
+
);
|
|
2011
|
+
}
|
|
2012
|
+
function createThemeStylesEntry(config) {
|
|
2013
|
+
return createStylesheetEntry(
|
|
2014
|
+
config.theme.styles.map((style2) => style2.moduleSpecifier),
|
|
2015
|
+
"Theme styles. Generated by @riebeckite/honox; do not edit. Import this after the plugin stylesheet so the theme wins the plugin/theme cascade."
|
|
2016
|
+
);
|
|
2017
|
+
}
|
|
2018
|
+
function collectPluginStyleSpecifiers(config) {
|
|
2019
|
+
return config.plugins.flatMap(
|
|
2020
|
+
(plugin) => (plugin.assets ?? []).filter((asset) => asset.kind === "style").map((asset) => asset.moduleSpecifier)
|
|
2021
|
+
);
|
|
2022
|
+
}
|
|
2023
|
+
function createStylesheetEntry(moduleSpecifiers, banner) {
|
|
2024
|
+
const imports = uniqueStrings(moduleSpecifiers).map((specifier) => `@import ${JSON.stringify(specifier)};`).join("\n");
|
|
2025
|
+
if (!banner) return imports;
|
|
2026
|
+
const header = `/* ${banner.replace(/\*\//g, "* /")} */`;
|
|
2027
|
+
return imports ? `${header}
|
|
2028
|
+
${imports}
|
|
2029
|
+
` : `${header}
|
|
2030
|
+
`;
|
|
2031
|
+
}
|
|
2032
|
+
function writeGeneratedFile(filePath, contents) {
|
|
2033
|
+
fs5.mkdirSync(path5.dirname(filePath), { recursive: true });
|
|
2034
|
+
fs5.writeFileSync(filePath, contents);
|
|
2035
|
+
}
|
|
2036
|
+
|
|
2037
|
+
// src/client_module.ts
|
|
2038
|
+
import {
|
|
2039
|
+
serializePublicClientConfig
|
|
2040
|
+
} from "@riebeckite/core";
|
|
2041
|
+
var clientModuleId = "virtual:riebeckite/client";
|
|
2042
|
+
var resolvedClientModuleId = `\0${clientModuleId}`;
|
|
2043
|
+
function riebeckiteClientModule(getConfig) {
|
|
2044
|
+
return {
|
|
2045
|
+
name: "riebeckite-client-module",
|
|
2046
|
+
resolveId(id) {
|
|
2047
|
+
if (id === clientModuleId) return resolvedClientModuleId;
|
|
2048
|
+
return null;
|
|
2049
|
+
},
|
|
2050
|
+
load(id) {
|
|
2051
|
+
if (id !== resolvedClientModuleId) return null;
|
|
2052
|
+
return createClientModule(getConfig());
|
|
2053
|
+
}
|
|
2054
|
+
};
|
|
2055
|
+
}
|
|
2056
|
+
function createClientModule(config) {
|
|
2057
|
+
const imports = [];
|
|
2058
|
+
const initializers = [];
|
|
2059
|
+
for (const [index, entry] of config.plugins.flatMap((plugin) => plugin.clientEntries ?? []).entries()) {
|
|
2060
|
+
const localName = `pluginClientInitializer${index}`;
|
|
2061
|
+
const importTarget = entry.exportName ? `{ ${entry.exportName} as ${localName} }` : localName;
|
|
2062
|
+
imports.push(
|
|
2063
|
+
`import ${importTarget} from ${JSON.stringify(entry.moduleSpecifier)};`
|
|
2064
|
+
);
|
|
2065
|
+
const publicConfig = entry.publicConfig;
|
|
2066
|
+
initializers.push(
|
|
2067
|
+
publicConfig === void 0 ? `${localName}()` : `${localName}(${serializePublicClientConfig(publicConfig)})`
|
|
2068
|
+
);
|
|
2069
|
+
}
|
|
2070
|
+
return `${imports.join("\n")}
|
|
2071
|
+
|
|
2072
|
+
export function initRiebeckiteClient() {
|
|
2073
|
+
${initializers.map((initializer) => ` ${initializer};`).join("\n")}
|
|
2074
|
+
}
|
|
2075
|
+
`;
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
// src/vite_runner.ts
|
|
2079
|
+
import fs6 from "node:fs/promises";
|
|
2080
|
+
import path6 from "node:path";
|
|
2081
|
+
import { build, createServer as createServer2 } from "vite";
|
|
2082
|
+
var viteConfigFileNames = [
|
|
2083
|
+
"vite.config.ts",
|
|
2084
|
+
"vite.config.js",
|
|
2085
|
+
"vite.config.mjs"
|
|
2086
|
+
];
|
|
2087
|
+
async function resolveHonoxApplicationRoot(configRoot) {
|
|
2088
|
+
const roots = await findViteApplicationRoots(configRoot);
|
|
2089
|
+
if (roots.length === 1) return roots[0];
|
|
2090
|
+
if (roots.length === 0) {
|
|
2091
|
+
throw new HonoxApplicationRootError(
|
|
2092
|
+
`Could not find a Vite application under ${configRoot}.`
|
|
2093
|
+
);
|
|
2094
|
+
}
|
|
2095
|
+
throw new HonoxApplicationRootError(
|
|
2096
|
+
`Found multiple Vite applications under ${configRoot}: ${roots.join(", ")}.`
|
|
2097
|
+
);
|
|
2098
|
+
}
|
|
2099
|
+
var HonoxApplicationRootError = class extends Error {
|
|
2100
|
+
constructor(message) {
|
|
2101
|
+
super(message);
|
|
2102
|
+
this.name = "HonoxApplicationRootError";
|
|
2103
|
+
}
|
|
2104
|
+
};
|
|
2105
|
+
async function resolveHonoxApplication(options) {
|
|
2106
|
+
const configRoot = path6.resolve(options.configRoot);
|
|
2107
|
+
const appRoot = options.appRoot ? path6.resolve(options.appRoot) : await resolveHonoxApplicationRoot(configRoot);
|
|
2108
|
+
const workspaceRoot = options.workspaceRoot ?? await findWorkspaceRoot(configRoot);
|
|
2109
|
+
const rawConfig = await loadRiebeckiteConfig({
|
|
2110
|
+
configRoot,
|
|
2111
|
+
configFile: options.configFile,
|
|
2112
|
+
workspaceRoot
|
|
2113
|
+
});
|
|
2114
|
+
const config = resolveHonoxConfig(rawConfig, appRoot);
|
|
2115
|
+
return {
|
|
2116
|
+
config,
|
|
2117
|
+
configRoot,
|
|
2118
|
+
appRoot,
|
|
2119
|
+
contentRoot: config.content.directory
|
|
2120
|
+
};
|
|
2121
|
+
}
|
|
2122
|
+
async function findWorkspaceRoot(configRoot) {
|
|
2123
|
+
try {
|
|
2124
|
+
const workspaceConfig = path6.join(configRoot, "pnpm-workspace.yaml");
|
|
2125
|
+
return (await fs6.stat(workspaceConfig)).isFile() ? configRoot : void 0;
|
|
2126
|
+
} catch {
|
|
2127
|
+
return void 0;
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
async function startHonoxDevServer(options) {
|
|
2131
|
+
const server2 = await createServer2({ root: options.root });
|
|
2132
|
+
await server2.listen();
|
|
2133
|
+
server2.printUrls();
|
|
2134
|
+
await waitForShutdown(server2);
|
|
2135
|
+
}
|
|
2136
|
+
async function buildHonoxApplication(options) {
|
|
2137
|
+
await runTraced(
|
|
2138
|
+
options.tracer,
|
|
2139
|
+
"integration.honox.client_build",
|
|
2140
|
+
() => build({ root: options.root, mode: "client" })
|
|
2141
|
+
);
|
|
2142
|
+
await runTraced(
|
|
2143
|
+
options.tracer,
|
|
2144
|
+
"integration.honox.server_build",
|
|
2145
|
+
() => build({ root: options.root })
|
|
2146
|
+
);
|
|
2147
|
+
}
|
|
2148
|
+
async function runTraced(tracer, name, buildTask) {
|
|
2149
|
+
return tracer ? await tracer.span(name, {}, buildTask) : await buildTask();
|
|
2150
|
+
}
|
|
2151
|
+
async function waitForShutdown(server2) {
|
|
2152
|
+
await new Promise((resolve) => {
|
|
2153
|
+
const close = () => {
|
|
2154
|
+
void server2.close().finally(resolve);
|
|
2155
|
+
};
|
|
2156
|
+
process.once("SIGINT", close);
|
|
2157
|
+
process.once("SIGTERM", close);
|
|
2158
|
+
});
|
|
2159
|
+
}
|
|
2160
|
+
async function findViteApplicationRoots(root) {
|
|
2161
|
+
const directories = [root];
|
|
2162
|
+
const applicationRoots = [];
|
|
2163
|
+
while (directories.length > 0) {
|
|
2164
|
+
const directory = directories.pop();
|
|
2165
|
+
if (!directory) continue;
|
|
2166
|
+
if (await hasViteConfig(directory)) applicationRoots.push(directory);
|
|
2167
|
+
const entries = await fs6.readdir(directory, { withFileTypes: true });
|
|
2168
|
+
for (const entry of entries) {
|
|
2169
|
+
if (!entry.isDirectory() || entry.name === "node_modules" || entry.name === ".git" || entry.name === "tests") {
|
|
2170
|
+
continue;
|
|
2171
|
+
}
|
|
2172
|
+
directories.push(path6.join(directory, entry.name));
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
return applicationRoots;
|
|
2176
|
+
}
|
|
2177
|
+
async function hasViteConfig(directory) {
|
|
2178
|
+
for (const fileName of viteConfigFileNames) {
|
|
2179
|
+
try {
|
|
2180
|
+
if ((await fs6.stat(path6.join(directory, fileName))).isFile()) return true;
|
|
2181
|
+
} catch {
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
return false;
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
// src/vite_plugin.ts
|
|
2188
|
+
var defaultSsrExternals = [
|
|
2189
|
+
"extend",
|
|
2190
|
+
"debug",
|
|
2191
|
+
"node:fs/promises",
|
|
2192
|
+
"node:path",
|
|
2193
|
+
"parse-numeric-range",
|
|
2194
|
+
"slugify",
|
|
2195
|
+
"vfile-matter",
|
|
2196
|
+
"yaml"
|
|
2197
|
+
];
|
|
2198
|
+
function riebeckite(options = {}) {
|
|
2199
|
+
let resolvedConfig;
|
|
2200
|
+
const getConfig = () => {
|
|
2201
|
+
if (!resolvedConfig) {
|
|
2202
|
+
throw new Error("Riebeckite config has not been loaded yet.");
|
|
2203
|
+
}
|
|
2204
|
+
return resolvedConfig;
|
|
2205
|
+
};
|
|
2206
|
+
return [
|
|
2207
|
+
{
|
|
2208
|
+
name: "riebeckite-host-integration",
|
|
2209
|
+
async config(userConfig) {
|
|
2210
|
+
const root = userConfig.root ? path7.resolve(userConfig.root) : process.cwd();
|
|
2211
|
+
const appRoot = options.appRoot ?? root;
|
|
2212
|
+
const application = await resolveHonoxApplication({
|
|
2213
|
+
configRoot: options.configRoot ?? appRoot,
|
|
2214
|
+
configFile: options.configFile,
|
|
2215
|
+
appRoot,
|
|
2216
|
+
workspaceRoot: options.workspaceRoot
|
|
2217
|
+
});
|
|
2218
|
+
resolvedConfig = application.config;
|
|
2219
|
+
writeRiebeckiteAssetEntries(resolvedConfig, {
|
|
2220
|
+
pluginStyles: path7.join(appRoot, "app/.riebeckite/plugin-styles.css"),
|
|
2221
|
+
themeStyles: path7.join(appRoot, "app/.riebeckite/theme-styles.css")
|
|
2222
|
+
});
|
|
2223
|
+
return {
|
|
2224
|
+
define: {
|
|
2225
|
+
"process.env.RIEBECKITE_APP_ROOT": JSON.stringify(appRoot)
|
|
2226
|
+
},
|
|
2227
|
+
resolve: {
|
|
2228
|
+
alias: options.workspaceRoot ? createWorkspacePackageAliases(options.workspaceRoot) : []
|
|
2229
|
+
}
|
|
2230
|
+
};
|
|
2231
|
+
}
|
|
2232
|
+
},
|
|
2233
|
+
riebeckiteClientModule(getConfig)
|
|
2234
|
+
];
|
|
2235
|
+
}
|
|
2236
|
+
function riebeckiteVite(options = {}) {
|
|
2237
|
+
const { ssg, ssrExternals, ...integration } = options;
|
|
2238
|
+
return [
|
|
2239
|
+
...riebeckite(integration),
|
|
2240
|
+
riebeckiteSsrExternals([...defaultSsrExternals, ...ssrExternals ?? []]),
|
|
2241
|
+
createRiebeckiteSsg(ssg)
|
|
2242
|
+
];
|
|
2243
|
+
}
|
|
2244
|
+
function riebeckiteSsrExternals(externals) {
|
|
2245
|
+
return {
|
|
2246
|
+
name: "riebeckite-ssr-externals",
|
|
2247
|
+
config() {
|
|
2248
|
+
return {
|
|
2249
|
+
environments: {
|
|
2250
|
+
ssr: {
|
|
2251
|
+
resolve: {
|
|
2252
|
+
external: [...externals]
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
};
|
|
2257
|
+
}
|
|
2258
|
+
};
|
|
2259
|
+
}
|
|
2157
2260
|
export {
|
|
2158
2261
|
ScaffoldSiteError,
|
|
2159
2262
|
buildHonoxApplication,
|
|
@@ -2161,6 +2264,7 @@ export {
|
|
|
2161
2264
|
defaultSsgEntry,
|
|
2162
2265
|
defaultSsrExternals,
|
|
2163
2266
|
loadRiebeckiteConfig,
|
|
2267
|
+
replaceHonoxIslandDependencyPlugin,
|
|
2164
2268
|
resolveHonoxApplication,
|
|
2165
2269
|
resolveHonoxApplicationRoot,
|
|
2166
2270
|
resolveHonoxConfig,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
type HonoxPlugin = Plugin | Promise<Plugin>;
|
|
3
|
+
/**
|
|
4
|
+
* Replaces HonoX's dependency walker with one that remains inside the app
|
|
5
|
+
* directory. Riebeckite configurations import plugins with large dependency
|
|
6
|
+
* graphs, which must not be traversed merely to determine whether a route
|
|
7
|
+
* imports an island.
|
|
8
|
+
*/
|
|
9
|
+
export declare function replaceHonoxIslandDependencyPlugin(plugins: HonoxPlugin[]): HonoxPlugin[];
|
|
10
|
+
export {};
|
|
@@ -11,7 +11,7 @@ export type RiebeckiteIntegrationOptions = {
|
|
|
11
11
|
* external. These are internal to the integration: sites should not have to
|
|
12
12
|
* restate the Vite `environments.ssr.resolve.external` list.
|
|
13
13
|
*/
|
|
14
|
-
export declare const defaultSsrExternals: readonly ["extend", "debug", "node:fs/promises", "node:path", "parse-numeric-range", "slugify", "vfile-matter"];
|
|
14
|
+
export declare const defaultSsrExternals: readonly ["extend", "debug", "node:fs/promises", "node:path", "parse-numeric-range", "slugify", "vfile-matter", "yaml"];
|
|
15
15
|
export type RiebeckiteViteOptions = RiebeckiteIntegrationOptions & {
|
|
16
16
|
/** Extra SSR externals appended after Riebeckite's defaults. */
|
|
17
17
|
ssrExternals?: readonly string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riebeckite/honox",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -26,10 +26,11 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
+
"@babel/parser": "^7.29.3",
|
|
29
30
|
"esbuild": "^0.28.2",
|
|
30
31
|
"hono": "^4.12.25",
|
|
31
32
|
"vite": "^8.0.9",
|
|
32
|
-
"@riebeckite/core": "0.0.
|
|
33
|
+
"@riebeckite/core": "0.0.3"
|
|
33
34
|
},
|
|
34
35
|
"publishConfig": {
|
|
35
36
|
"access": "public"
|