@riebeckite/honox 0.0.2 → 0.0.4
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 +573 -474
- 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 fs6 from "node:fs/promises";
|
|
255
|
+
import path7 from "node:path";
|
|
314
256
|
|
|
315
|
-
// src/
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
);
|
|
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";
|
|
328
276
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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`;
|
|
334
285
|
}
|
|
335
|
-
function
|
|
336
|
-
return
|
|
337
|
-
(plugin) => (plugin.assets ?? []).filter((asset) => asset.kind === "style").map((asset) => asset.moduleSpecifier)
|
|
338
|
-
);
|
|
286
|
+
function themeReadmeUrl(slug) {
|
|
287
|
+
return `https://github.com/Rerurate514/riebeckite/blob/main/packages/themes/${slug}/README.md`;
|
|
339
288
|
}
|
|
340
|
-
function
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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;
|
|
348
307
|
}
|
|
349
|
-
function
|
|
350
|
-
|
|
351
|
-
fs3.writeFileSync(filePath, contents);
|
|
308
|
+
function read(text, language) {
|
|
309
|
+
return text[language];
|
|
352
310
|
}
|
|
353
|
-
|
|
354
|
-
|
|
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}`;
|
|
@@ -1500,6 +1182,427 @@ function pluginsContent(language) {
|
|
|
1500
1182
|
return lines.join("\n");
|
|
1501
1183
|
}
|
|
1502
1184
|
|
|
1185
|
+
// src/vite_plugin.ts
|
|
1186
|
+
import path6 from "node:path";
|
|
1187
|
+
|
|
1188
|
+
// src/asset_entries.ts
|
|
1189
|
+
import fs4 from "node:fs";
|
|
1190
|
+
import path4 from "node:path";
|
|
1191
|
+
import { uniqueStrings } from "@riebeckite/core";
|
|
1192
|
+
function writeRiebeckiteAssetEntries(config, paths2) {
|
|
1193
|
+
writeGeneratedFile(paths2.pluginStyles, createPluginStylesEntry(config));
|
|
1194
|
+
writeGeneratedFile(paths2.themeStyles, createThemeStylesEntry(config));
|
|
1195
|
+
}
|
|
1196
|
+
function createPluginStylesEntry(config) {
|
|
1197
|
+
return createStylesheetEntry(
|
|
1198
|
+
collectPluginStyleSpecifiers(config),
|
|
1199
|
+
"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."
|
|
1200
|
+
);
|
|
1201
|
+
}
|
|
1202
|
+
function createThemeStylesEntry(config) {
|
|
1203
|
+
return createStylesheetEntry(
|
|
1204
|
+
config.theme.styles.map((style2) => style2.moduleSpecifier),
|
|
1205
|
+
"Theme styles. Generated by @riebeckite/honox; do not edit. Import this after the plugin stylesheet so the theme wins the plugin/theme cascade."
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
function collectPluginStyleSpecifiers(config) {
|
|
1209
|
+
return config.plugins.flatMap(
|
|
1210
|
+
(plugin) => (plugin.assets ?? []).filter((asset) => asset.kind === "style").map((asset) => asset.moduleSpecifier)
|
|
1211
|
+
);
|
|
1212
|
+
}
|
|
1213
|
+
function createStylesheetEntry(moduleSpecifiers, banner) {
|
|
1214
|
+
const imports = uniqueStrings(moduleSpecifiers).map((specifier) => `@import ${JSON.stringify(specifier)};`).join("\n");
|
|
1215
|
+
if (!banner) return imports;
|
|
1216
|
+
const header = `/* ${banner.replace(/\*\//g, "* /")} */`;
|
|
1217
|
+
return imports ? `${header}
|
|
1218
|
+
${imports}
|
|
1219
|
+
` : `${header}
|
|
1220
|
+
`;
|
|
1221
|
+
}
|
|
1222
|
+
function writeGeneratedFile(filePath, contents) {
|
|
1223
|
+
fs4.mkdirSync(path4.dirname(filePath), { recursive: true });
|
|
1224
|
+
fs4.writeFileSync(filePath, contents);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
// src/client_module.ts
|
|
1228
|
+
import {
|
|
1229
|
+
serializePublicClientConfig
|
|
1230
|
+
} from "@riebeckite/core";
|
|
1231
|
+
var clientModuleId = "virtual:riebeckite/client";
|
|
1232
|
+
var resolvedClientModuleId = `\0${clientModuleId}`;
|
|
1233
|
+
function riebeckiteClientModule(getConfig) {
|
|
1234
|
+
return {
|
|
1235
|
+
name: "riebeckite-client-module",
|
|
1236
|
+
resolveId(id) {
|
|
1237
|
+
if (id === clientModuleId) return resolvedClientModuleId;
|
|
1238
|
+
return null;
|
|
1239
|
+
},
|
|
1240
|
+
load(id) {
|
|
1241
|
+
if (id !== resolvedClientModuleId) return null;
|
|
1242
|
+
return createClientModule(getConfig());
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1246
|
+
function createClientModule(config) {
|
|
1247
|
+
const imports = [];
|
|
1248
|
+
const initializers = [];
|
|
1249
|
+
for (const [index, entry] of config.plugins.flatMap((plugin) => plugin.clientEntries ?? []).entries()) {
|
|
1250
|
+
const localName = `pluginClientInitializer${index}`;
|
|
1251
|
+
const importTarget = entry.exportName ? `{ ${entry.exportName} as ${localName} }` : localName;
|
|
1252
|
+
imports.push(
|
|
1253
|
+
`import ${importTarget} from ${JSON.stringify(entry.moduleSpecifier)};`
|
|
1254
|
+
);
|
|
1255
|
+
const publicConfig = entry.publicConfig;
|
|
1256
|
+
initializers.push(
|
|
1257
|
+
publicConfig === void 0 ? `${localName}()` : `${localName}(${serializePublicClientConfig(publicConfig)})`
|
|
1258
|
+
);
|
|
1259
|
+
}
|
|
1260
|
+
return `${imports.join("\n")}
|
|
1261
|
+
|
|
1262
|
+
export function initRiebeckiteClient() {
|
|
1263
|
+
${initializers.map((initializer) => ` ${initializer};`).join("\n")}
|
|
1264
|
+
}
|
|
1265
|
+
`;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
// src/ssg_plugin.ts
|
|
1269
|
+
import { defaultExtensionMap, toSSG } from "hono/ssg";
|
|
1270
|
+
import { relative } from "node:path";
|
|
1271
|
+
import { createServer } from "vite";
|
|
1272
|
+
var defaultEntry = "./src/index.tsx";
|
|
1273
|
+
function riebeckiteSsg(options = {}) {
|
|
1274
|
+
const virtualId = "virtual:riebeckite-ssg-void-entry";
|
|
1275
|
+
const resolvedVirtualId = `\0${virtualId}`;
|
|
1276
|
+
const entry = options.entry ?? defaultEntry;
|
|
1277
|
+
let resolvedConfig;
|
|
1278
|
+
return {
|
|
1279
|
+
name: "riebeckite-ssg",
|
|
1280
|
+
apply: "build",
|
|
1281
|
+
enforce: "post",
|
|
1282
|
+
config() {
|
|
1283
|
+
return {
|
|
1284
|
+
build: {
|
|
1285
|
+
rollupOptions: {
|
|
1286
|
+
input: [virtualId]
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
};
|
|
1290
|
+
},
|
|
1291
|
+
configResolved(config) {
|
|
1292
|
+
resolvedConfig = config;
|
|
1293
|
+
},
|
|
1294
|
+
resolveId(id) {
|
|
1295
|
+
return id === virtualId ? resolvedVirtualId : void 0;
|
|
1296
|
+
},
|
|
1297
|
+
load(id) {
|
|
1298
|
+
return id === resolvedVirtualId ? 'console.log("suppress empty chunk message")' : void 0;
|
|
1299
|
+
},
|
|
1300
|
+
async generateBundle(_outputOptions, bundle) {
|
|
1301
|
+
const config = resolvedConfig;
|
|
1302
|
+
if (!config) {
|
|
1303
|
+
throw new Error("Riebeckite SSG could not resolve the Vite configuration.");
|
|
1304
|
+
}
|
|
1305
|
+
removeVirtualEntryChunk(bundle, resolvedVirtualId);
|
|
1306
|
+
const server2 = await createServer({
|
|
1307
|
+
root: config.root,
|
|
1308
|
+
define: config.define,
|
|
1309
|
+
resolve: {
|
|
1310
|
+
...config.resolve,
|
|
1311
|
+
builtins: [...config.resolve.builtins, /^node:/]
|
|
1312
|
+
},
|
|
1313
|
+
plugins: [],
|
|
1314
|
+
build: { ssr: true },
|
|
1315
|
+
mode: config.mode
|
|
1316
|
+
});
|
|
1317
|
+
try {
|
|
1318
|
+
const module = await server2.ssrLoadModule(entry);
|
|
1319
|
+
const app = module.default;
|
|
1320
|
+
if (!app) {
|
|
1321
|
+
throw new Error(`Failed to find a default export from ${entry}.`);
|
|
1322
|
+
}
|
|
1323
|
+
const generatedHtml = [];
|
|
1324
|
+
const result = await toSSG(
|
|
1325
|
+
app,
|
|
1326
|
+
{
|
|
1327
|
+
writeFile: async (filePath, data) => {
|
|
1328
|
+
const fileName = relative(config.build.outDir, filePath).replaceAll(
|
|
1329
|
+
"\\",
|
|
1330
|
+
"/"
|
|
1331
|
+
);
|
|
1332
|
+
if (fileName.endsWith(".html") && typeof data === "string") {
|
|
1333
|
+
generatedHtml.push({ path: fileName, html: data });
|
|
1334
|
+
}
|
|
1335
|
+
this.emitFile({
|
|
1336
|
+
type: "asset",
|
|
1337
|
+
fileName,
|
|
1338
|
+
source: data
|
|
1339
|
+
});
|
|
1340
|
+
},
|
|
1341
|
+
async mkdir() {
|
|
1342
|
+
}
|
|
1343
|
+
},
|
|
1344
|
+
{
|
|
1345
|
+
dir: config.build.outDir,
|
|
1346
|
+
plugins: options.plugins ?? [],
|
|
1347
|
+
extensionMap: options.extensionMap ?? defaultExtensionMap
|
|
1348
|
+
}
|
|
1349
|
+
);
|
|
1350
|
+
if (!result.success) throw result.error;
|
|
1351
|
+
await emitGeneratedOutputs(
|
|
1352
|
+
module,
|
|
1353
|
+
(asset) => this.emitFile(asset)
|
|
1354
|
+
);
|
|
1355
|
+
inspectGeneratedHtmlPages(module, generatedHtml, {
|
|
1356
|
+
warn: (message) => this.warn(message),
|
|
1357
|
+
info: (message) => this.info(message)
|
|
1358
|
+
});
|
|
1359
|
+
} finally {
|
|
1360
|
+
await server2.close();
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
async function emitGeneratedOutputs(module, emit) {
|
|
1366
|
+
const content = module.content;
|
|
1367
|
+
if (!content) return;
|
|
1368
|
+
const manifest = await content.getManifest();
|
|
1369
|
+
for (const output of manifest.generatedOutputs ?? []) {
|
|
1370
|
+
emit({
|
|
1371
|
+
type: "asset",
|
|
1372
|
+
fileName: output.path,
|
|
1373
|
+
source: output.content
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
function inspectGeneratedHtmlPages(module, pages, log) {
|
|
1378
|
+
const plugins = module.config?.plugins ?? [];
|
|
1379
|
+
for (const plugin of plugins) {
|
|
1380
|
+
const inspector = plugin.inspectGeneratedHtml;
|
|
1381
|
+
if (typeof inspector !== "function") continue;
|
|
1382
|
+
for (const page of pages) {
|
|
1383
|
+
for (const diagnostic of inspector(page) ?? []) {
|
|
1384
|
+
const label = `[${plugin.name ?? "plugin"}] ${page.path}: ${diagnostic.message}`;
|
|
1385
|
+
if (diagnostic.severity === "info") log.info(label);
|
|
1386
|
+
else log.warn(label);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
function removeVirtualEntryChunk(bundle, virtualEntryId) {
|
|
1392
|
+
for (const chunk of Object.values(bundle)) {
|
|
1393
|
+
if (chunk.type === "chunk" && chunk.moduleIds?.includes(virtualEntryId)) {
|
|
1394
|
+
delete bundle[chunk.fileName];
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
// src/ssg.ts
|
|
1400
|
+
var defaultSsgEntry = "./app/server.ts";
|
|
1401
|
+
function riebeckiteSsgExtensionMap() {
|
|
1402
|
+
return {
|
|
1403
|
+
"application/atom+xml": "xml",
|
|
1404
|
+
"application/json": "json",
|
|
1405
|
+
"application/rss+xml": "xml",
|
|
1406
|
+
"application/xml": "xml",
|
|
1407
|
+
"text/html": "html",
|
|
1408
|
+
"text/plain": "txt",
|
|
1409
|
+
"text/xml": "xml"
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
function createRiebeckiteSsg(options = {}) {
|
|
1413
|
+
return riebeckiteSsg({
|
|
1414
|
+
...options,
|
|
1415
|
+
entry: options.entry ?? defaultSsgEntry,
|
|
1416
|
+
extensionMap: {
|
|
1417
|
+
...riebeckiteSsgExtensionMap(),
|
|
1418
|
+
...options.extensionMap
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
// src/vite_runner.ts
|
|
1424
|
+
import fs5 from "node:fs/promises";
|
|
1425
|
+
import path5 from "node:path";
|
|
1426
|
+
import { build, createServer as createServer2 } from "vite";
|
|
1427
|
+
var viteConfigFileNames = [
|
|
1428
|
+
"vite.config.ts",
|
|
1429
|
+
"vite.config.js",
|
|
1430
|
+
"vite.config.mjs"
|
|
1431
|
+
];
|
|
1432
|
+
async function resolveHonoxApplicationRoot(configRoot) {
|
|
1433
|
+
const roots = await findViteApplicationRoots(configRoot);
|
|
1434
|
+
if (roots.length === 1) return roots[0];
|
|
1435
|
+
if (roots.length === 0) {
|
|
1436
|
+
throw new HonoxApplicationRootError(
|
|
1437
|
+
`Could not find a Vite application under ${configRoot}.`
|
|
1438
|
+
);
|
|
1439
|
+
}
|
|
1440
|
+
throw new HonoxApplicationRootError(
|
|
1441
|
+
`Found multiple Vite applications under ${configRoot}: ${roots.join(", ")}.`
|
|
1442
|
+
);
|
|
1443
|
+
}
|
|
1444
|
+
var HonoxApplicationRootError = class extends Error {
|
|
1445
|
+
constructor(message) {
|
|
1446
|
+
super(message);
|
|
1447
|
+
this.name = "HonoxApplicationRootError";
|
|
1448
|
+
}
|
|
1449
|
+
};
|
|
1450
|
+
async function resolveHonoxApplication(options) {
|
|
1451
|
+
const configRoot = path5.resolve(options.configRoot);
|
|
1452
|
+
const appRoot = options.appRoot ? path5.resolve(options.appRoot) : await resolveHonoxApplicationRoot(configRoot);
|
|
1453
|
+
const workspaceRoot = options.workspaceRoot ?? await findWorkspaceRoot(configRoot);
|
|
1454
|
+
const rawConfig = await loadRiebeckiteConfig({
|
|
1455
|
+
configRoot,
|
|
1456
|
+
configFile: options.configFile,
|
|
1457
|
+
workspaceRoot
|
|
1458
|
+
});
|
|
1459
|
+
const config = resolveHonoxConfig(rawConfig, appRoot);
|
|
1460
|
+
return {
|
|
1461
|
+
config,
|
|
1462
|
+
configRoot,
|
|
1463
|
+
appRoot,
|
|
1464
|
+
contentRoot: config.content.directory
|
|
1465
|
+
};
|
|
1466
|
+
}
|
|
1467
|
+
async function findWorkspaceRoot(configRoot) {
|
|
1468
|
+
try {
|
|
1469
|
+
const workspaceConfig = path5.join(configRoot, "pnpm-workspace.yaml");
|
|
1470
|
+
return (await fs5.stat(workspaceConfig)).isFile() ? configRoot : void 0;
|
|
1471
|
+
} catch {
|
|
1472
|
+
return void 0;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
async function startHonoxDevServer(options) {
|
|
1476
|
+
const server2 = await createServer2({ root: options.root });
|
|
1477
|
+
await server2.listen();
|
|
1478
|
+
server2.printUrls();
|
|
1479
|
+
await waitForShutdown(server2);
|
|
1480
|
+
}
|
|
1481
|
+
async function buildHonoxApplication(options) {
|
|
1482
|
+
await runTraced(
|
|
1483
|
+
options.tracer,
|
|
1484
|
+
"integration.honox.client_build",
|
|
1485
|
+
() => build({ root: options.root, mode: "client" })
|
|
1486
|
+
);
|
|
1487
|
+
await runTraced(
|
|
1488
|
+
options.tracer,
|
|
1489
|
+
"integration.honox.server_build",
|
|
1490
|
+
() => build({ root: options.root })
|
|
1491
|
+
);
|
|
1492
|
+
}
|
|
1493
|
+
async function runTraced(tracer, name, buildTask) {
|
|
1494
|
+
return tracer ? await tracer.span(name, {}, buildTask) : await buildTask();
|
|
1495
|
+
}
|
|
1496
|
+
async function waitForShutdown(server2) {
|
|
1497
|
+
await new Promise((resolve) => {
|
|
1498
|
+
const close = () => {
|
|
1499
|
+
void server2.close().finally(resolve);
|
|
1500
|
+
};
|
|
1501
|
+
process.once("SIGINT", close);
|
|
1502
|
+
process.once("SIGTERM", close);
|
|
1503
|
+
});
|
|
1504
|
+
}
|
|
1505
|
+
async function findViteApplicationRoots(root) {
|
|
1506
|
+
const directories = [root];
|
|
1507
|
+
const applicationRoots = [];
|
|
1508
|
+
while (directories.length > 0) {
|
|
1509
|
+
const directory = directories.pop();
|
|
1510
|
+
if (!directory) continue;
|
|
1511
|
+
if (await hasViteConfig(directory)) applicationRoots.push(directory);
|
|
1512
|
+
const entries = await fs5.readdir(directory, { withFileTypes: true });
|
|
1513
|
+
for (const entry of entries) {
|
|
1514
|
+
if (!entry.isDirectory() || entry.name === "node_modules" || entry.name === ".git" || entry.name === "tests") {
|
|
1515
|
+
continue;
|
|
1516
|
+
}
|
|
1517
|
+
directories.push(path5.join(directory, entry.name));
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
return applicationRoots;
|
|
1521
|
+
}
|
|
1522
|
+
async function hasViteConfig(directory) {
|
|
1523
|
+
for (const fileName of viteConfigFileNames) {
|
|
1524
|
+
try {
|
|
1525
|
+
if ((await fs5.stat(path5.join(directory, fileName))).isFile()) return true;
|
|
1526
|
+
} catch {
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
return false;
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
// src/vite_plugin.ts
|
|
1533
|
+
var defaultSsrExternals = [
|
|
1534
|
+
"extend",
|
|
1535
|
+
"debug",
|
|
1536
|
+
"node:fs/promises",
|
|
1537
|
+
"node:path",
|
|
1538
|
+
"parse-numeric-range",
|
|
1539
|
+
"slugify",
|
|
1540
|
+
"vfile-matter",
|
|
1541
|
+
"yaml"
|
|
1542
|
+
];
|
|
1543
|
+
function riebeckite(options = {}) {
|
|
1544
|
+
let resolvedConfig;
|
|
1545
|
+
const getConfig = () => {
|
|
1546
|
+
if (!resolvedConfig) {
|
|
1547
|
+
throw new Error("Riebeckite config has not been loaded yet.");
|
|
1548
|
+
}
|
|
1549
|
+
return resolvedConfig;
|
|
1550
|
+
};
|
|
1551
|
+
return [
|
|
1552
|
+
{
|
|
1553
|
+
name: "riebeckite-host-integration",
|
|
1554
|
+
async config(userConfig) {
|
|
1555
|
+
const root = userConfig.root ? path6.resolve(userConfig.root) : process.cwd();
|
|
1556
|
+
const appRoot = options.appRoot ?? root;
|
|
1557
|
+
const application = await resolveHonoxApplication({
|
|
1558
|
+
configRoot: options.configRoot ?? appRoot,
|
|
1559
|
+
configFile: options.configFile,
|
|
1560
|
+
appRoot,
|
|
1561
|
+
workspaceRoot: options.workspaceRoot
|
|
1562
|
+
});
|
|
1563
|
+
resolvedConfig = application.config;
|
|
1564
|
+
writeRiebeckiteAssetEntries(resolvedConfig, {
|
|
1565
|
+
pluginStyles: path6.join(appRoot, "app/.riebeckite/plugin-styles.css"),
|
|
1566
|
+
themeStyles: path6.join(appRoot, "app/.riebeckite/theme-styles.css")
|
|
1567
|
+
});
|
|
1568
|
+
return {
|
|
1569
|
+
define: {
|
|
1570
|
+
"process.env.RIEBECKITE_APP_ROOT": JSON.stringify(appRoot)
|
|
1571
|
+
},
|
|
1572
|
+
resolve: {
|
|
1573
|
+
alias: options.workspaceRoot ? createWorkspacePackageAliases(options.workspaceRoot) : []
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
},
|
|
1578
|
+
riebeckiteClientModule(getConfig)
|
|
1579
|
+
];
|
|
1580
|
+
}
|
|
1581
|
+
function riebeckiteVite(options = {}) {
|
|
1582
|
+
const { ssg, ssrExternals, ...integration } = options;
|
|
1583
|
+
return [
|
|
1584
|
+
...riebeckite(integration),
|
|
1585
|
+
riebeckiteSsrExternals([...defaultSsrExternals, ...ssrExternals ?? []]),
|
|
1586
|
+
createRiebeckiteSsg(ssg)
|
|
1587
|
+
];
|
|
1588
|
+
}
|
|
1589
|
+
function riebeckiteSsrExternals(externals) {
|
|
1590
|
+
return {
|
|
1591
|
+
name: "riebeckite-ssr-externals",
|
|
1592
|
+
config() {
|
|
1593
|
+
return {
|
|
1594
|
+
environments: {
|
|
1595
|
+
ssr: {
|
|
1596
|
+
resolve: {
|
|
1597
|
+
external: [...externals]
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1603
|
+
};
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1503
1606
|
// src/scaffold/templates.ts
|
|
1504
1607
|
function siteTemplateFiles(variables) {
|
|
1505
1608
|
return [
|
|
@@ -1539,18 +1642,18 @@ function packageJson(variables) {
|
|
|
1539
1642
|
inspect: "riebeckite inspect"
|
|
1540
1643
|
},
|
|
1541
1644
|
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.
|
|
1645
|
+
"@riebeckite/core": "^0.0.3",
|
|
1646
|
+
"@riebeckite/honox": "^0.0.3",
|
|
1647
|
+
"@riebeckite/plugin-color-mode": "^0.0.3",
|
|
1648
|
+
"@riebeckite/plugin-l10n": "^0.0.3",
|
|
1649
|
+
"@riebeckite/plugin-obsidian-markdown": "^0.0.3",
|
|
1650
|
+
"@riebeckite/theme-default": "^0.0.3",
|
|
1548
1651
|
hono: "^4.12.25",
|
|
1549
1652
|
honox: "0.1.56"
|
|
1550
1653
|
},
|
|
1551
1654
|
devDependencies: {
|
|
1552
1655
|
"@hono/vite-build": "^1.11.1",
|
|
1553
|
-
"@riebeckite/cli": "^0.0.
|
|
1656
|
+
"@riebeckite/cli": "^0.0.3",
|
|
1554
1657
|
"@types/node": "^24.5.2",
|
|
1555
1658
|
typescript: "^5.0.0",
|
|
1556
1659
|
vite: "^8.0.9"
|
|
@@ -1593,6 +1696,7 @@ plugins: [
|
|
|
1593
1696
|
`;
|
|
1594
1697
|
}
|
|
1595
1698
|
function viteConfig() {
|
|
1699
|
+
const ssrExternals = [...defaultSsrExternals].map((name) => ` "${name}",`).join("\n");
|
|
1596
1700
|
return `import path from "node:path";
|
|
1597
1701
|
import { fileURLToPath } from "node:url";
|
|
1598
1702
|
import build from "@hono/vite-build/node";
|
|
@@ -1622,13 +1726,7 @@ export default defineConfig({
|
|
|
1622
1726
|
ssr: {
|
|
1623
1727
|
resolve: {
|
|
1624
1728
|
external: [
|
|
1625
|
-
|
|
1626
|
-
"debug",
|
|
1627
|
-
"node:fs/promises",
|
|
1628
|
-
"node:path",
|
|
1629
|
-
"parse-numeric-range",
|
|
1630
|
-
"slugify",
|
|
1631
|
-
"vfile-matter",
|
|
1729
|
+
${ssrExternals}
|
|
1632
1730
|
],
|
|
1633
1731
|
},
|
|
1634
1732
|
},
|
|
@@ -2102,7 +2200,7 @@ var ScaffoldSiteError = class extends Error {
|
|
|
2102
2200
|
}
|
|
2103
2201
|
};
|
|
2104
2202
|
async function scaffoldRiebeckiteSite(options) {
|
|
2105
|
-
const targetDirectory =
|
|
2203
|
+
const targetDirectory = path7.resolve(options.targetDirectory);
|
|
2106
2204
|
const files = siteTemplateFiles(templateVariables(options, targetDirectory));
|
|
2107
2205
|
await assertTargetWritable(
|
|
2108
2206
|
targetDirectory,
|
|
@@ -2110,15 +2208,15 @@ async function scaffoldRiebeckiteSite(options) {
|
|
|
2110
2208
|
options.overwrite ?? false
|
|
2111
2209
|
);
|
|
2112
2210
|
for (const file of files) {
|
|
2113
|
-
const filePath =
|
|
2114
|
-
await
|
|
2115
|
-
await
|
|
2211
|
+
const filePath = path7.join(targetDirectory, file.path);
|
|
2212
|
+
await fs6.mkdir(path7.dirname(filePath), { recursive: true });
|
|
2213
|
+
await fs6.writeFile(filePath, file.content, "utf8");
|
|
2116
2214
|
}
|
|
2117
2215
|
return { targetDirectory, files: files.map((file) => file.path) };
|
|
2118
2216
|
}
|
|
2119
2217
|
function templateVariables(options, targetDirectory) {
|
|
2120
2218
|
const name = normalizePackageName(
|
|
2121
|
-
options.name ??
|
|
2219
|
+
options.name ?? path7.basename(targetDirectory)
|
|
2122
2220
|
);
|
|
2123
2221
|
return {
|
|
2124
2222
|
name,
|
|
@@ -2131,7 +2229,7 @@ function templateVariables(options, targetDirectory) {
|
|
|
2131
2229
|
async function assertTargetWritable(targetDirectory, files, overwrite) {
|
|
2132
2230
|
let entries;
|
|
2133
2231
|
try {
|
|
2134
|
-
entries = await
|
|
2232
|
+
entries = await fs6.readdir(targetDirectory);
|
|
2135
2233
|
} catch (error) {
|
|
2136
2234
|
if (isNotFoundError(error)) return;
|
|
2137
2235
|
throw error;
|
|
@@ -2161,6 +2259,7 @@ export {
|
|
|
2161
2259
|
defaultSsgEntry,
|
|
2162
2260
|
defaultSsrExternals,
|
|
2163
2261
|
loadRiebeckiteConfig,
|
|
2262
|
+
replaceHonoxIslandDependencyPlugin,
|
|
2164
2263
|
resolveHonoxApplication,
|
|
2165
2264
|
resolveHonoxApplicationRoot,
|
|
2166
2265
|
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.4",
|
|
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"
|