create-riebeckite 0.0.17 → 0.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +31 -8
  2. package/README_ja.md +27 -3
  3. package/dist/src/arguments.d.ts +5 -5
  4. package/dist/src/index.js +3276 -40
  5. package/dist/src/interactive.d.ts +11 -9
  6. package/dist/src/scaffold/content-pages.d.ts +16 -0
  7. package/dist/src/scaffold/deployment.d.ts +7 -0
  8. package/dist/src/scaffold/index.d.ts +8 -0
  9. package/dist/src/scaffold/index.js +3224 -0
  10. package/dist/src/scaffold/next-steps.d.ts +7 -0
  11. package/dist/src/scaffold/options.d.ts +45 -0
  12. package/dist/src/scaffold/presets.d.ts +102 -0
  13. package/dist/src/scaffold/template-loader.d.ts +4 -0
  14. package/dist/src/scaffold/templates.d.ts +55 -0
  15. package/dist/src/scaffold/utilities.d.ts +14 -0
  16. package/dist/src/scaffold/version.d.ts +1 -0
  17. package/dist/src/scaffold/wrangler-defaults.d.ts +46 -0
  18. package/package.json +16 -5
  19. package/templates/scaffold/base/app/client.ts +14 -0
  20. package/templates/scaffold/base/app/config.ts +18 -0
  21. package/templates/scaffold/base/app/constants/paths.ts +10 -0
  22. package/templates/scaffold/base/app/content.ts +12 -0
  23. package/templates/scaffold/base/app/global.d.ts +15 -0
  24. package/templates/scaffold/base/app/server.ts +13 -0
  25. package/templates/scaffold/base/public/favicon.ico +0 -0
  26. package/templates/scaffold/base/public/riebeckite-logo.png +0 -0
  27. package/templates/scaffold/base/tsconfig.json +30 -0
  28. package/templates/scaffold/base/vite.config.ts +34 -0
  29. package/templates/scaffold/biome.json +6 -0
  30. package/templates/scaffold/deployment/github-actions/content-checkout.yml +6 -0
  31. package/templates/scaffold/deployment/github-actions/deploy.yml +54 -0
  32. package/templates/scaffold/deployment/github-actions/notify-site.yml +31 -0
  33. package/templates/scaffold/presets/empty/app/routes/_renderer.tsx +21 -0
  34. package/templates/scaffold/presets/empty/app/routes/index.tsx +11 -0
  35. package/templates/scaffold/presets/empty/app/style.css +17 -0
  36. package/templates/scaffold/presets/minimal/app/components/article.tsx +48 -0
  37. package/templates/scaffold/presets/minimal/app/routes/[slug{.+}].tsx +48 -0
  38. package/templates/scaffold/presets/minimal/app/routes/_renderer.tsx +59 -0
  39. package/templates/scaffold/presets/minimal/app/routes/index.tsx +29 -0
  40. package/templates/scaffold/presets/minimal/app/style.css +81 -0
  41. package/templates/scaffold/presets/minimal/content/index.en.md +12 -0
  42. package/templates/scaffold/presets/showcase/app/components/article.tsx +57 -0
  43. package/templates/scaffold/presets/showcase/app/components/site-header.tsx +113 -0
  44. package/templates/scaffold/presets/showcase/app/routes/[slug{.+}].tsx +52 -0
  45. package/templates/scaffold/presets/showcase/app/routes/_renderer.tsx +69 -0
  46. package/templates/scaffold/presets/showcase/app/routes/index.tsx +39 -0
  47. package/templates/scaffold/presets/showcase/app/style.css +224 -0
  48. package/templates/scaffold/presets/showcase/content/attachments/project-brief.pdf +5 -0
  49. package/templates/scaffold/presets/showcase/content/demo/planning.md +16 -0
  50. package/templates/scaffold/presets/showcase/content/demo/writing.md +15 -0
  51. package/templates/scaffold/presets/showcase/content/drawings/Architecture.excalidraw +1 -0
  52. package/templates/scaffold/presets/showcase/content/drawings/site.canvas +1 -0
  53. package/templates/scaffold/presets/showcase/content/guide.en.md +46 -0
  54. package/templates/scaffold/presets/showcase/content/images/demo.svg +1 -0
  55. package/templates/scaffold/presets/showcase/content/index.de.md +17 -0
  56. package/templates/scaffold/presets/showcase/content/index.en.md +17 -0
  57. package/templates/scaffold/presets/showcase/content/index.es.md +17 -0
  58. package/templates/scaffold/presets/showcase/content/index.fr.md +17 -0
  59. package/templates/scaffold/presets/showcase/content/index.ja.md +17 -0
  60. package/templates/scaffold/presets/showcase/content/index.ko.md +17 -0
  61. package/templates/scaffold/presets/showcase/content/index.zh-CN.md +17 -0
  62. package/templates/scaffold/presets/starter/app/components/article.tsx +57 -0
  63. package/templates/scaffold/presets/starter/app/components/site-header.tsx +113 -0
  64. package/templates/scaffold/presets/starter/app/routes/[slug{.+}].tsx +52 -0
  65. package/templates/scaffold/presets/starter/app/routes/_renderer.tsx +69 -0
  66. package/templates/scaffold/presets/starter/app/routes/index.tsx +37 -0
  67. package/templates/scaffold/presets/starter/app/style.css +224 -0
  68. package/templates/scaffold/presets/starter/content/guide.en.md +60 -0
  69. package/templates/scaffold/presets/starter/content/index.de.md +19 -0
  70. package/templates/scaffold/presets/starter/content/index.en.md +19 -0
  71. package/templates/scaffold/presets/starter/content/index.es.md +19 -0
  72. package/templates/scaffold/presets/starter/content/index.fr.md +19 -0
  73. package/templates/scaffold/presets/starter/content/index.ja.md +19 -0
  74. package/templates/scaffold/presets/starter/content/index.ko.md +19 -0
  75. package/templates/scaffold/presets/starter/content/index.zh-CN.md +19 -0
  76. package/templates/scaffold/presets/starter/content/notes/planning.md +16 -0
  77. package/templates/scaffold/presets/starter/content/notes/writing.md +15 -0
  78. package/templates/scaffold/utilities/biome/biome.json +22 -0
  79. package/templates/scaffold/utilities/editorconfig/.editorconfig +12 -0
  80. package/templates/scaffold/utilities/gitattributes/.gitattributes +5 -0
  81. package/templates/scaffold/utilities/vscode/.vscode/settings.json +6 -0
@@ -0,0 +1,7 @@
1
+ export type ScaffoldNextStepsOptions = {
2
+ /** First Markdown file to edit, when the scaffold wrote one. */
3
+ readonly editFile?: string;
4
+ /** The site keeps its content in a separate repository. */
5
+ readonly externalContent?: boolean;
6
+ };
7
+ export declare function formatScaffoldNextSteps(relativeDirectory: string, options?: ScaffoldNextStepsOptions): string;
@@ -0,0 +1,45 @@
1
+ import type { ScaffoldPresetName } from "./presets.js";
2
+ import type { ScaffoldUtilityName } from "./utilities.js";
3
+ export type ScaffoldSiteMetadata = {
4
+ readonly title?: string;
5
+ readonly description?: string;
6
+ readonly baseUrl?: string;
7
+ readonly locale?: string;
8
+ };
9
+ export type ScaffoldContentSource = {
10
+ readonly type: "local";
11
+ } | {
12
+ readonly type: "external";
13
+ readonly contentRepository: string;
14
+ readonly siteRepository: string;
15
+ };
16
+ export type ScaffoldDeployment = {
17
+ readonly type: "none";
18
+ } | {
19
+ readonly type: "cloudflare-workers";
20
+ } | {
21
+ readonly type: "github-actions";
22
+ readonly content: ScaffoldContentSource;
23
+ };
24
+ export type ScaffoldSiteOptions = {
25
+ readonly targetDirectory: string;
26
+ readonly name?: string;
27
+ readonly site?: ScaffoldSiteMetadata;
28
+ readonly preset?: ScaffoldPresetName;
29
+ readonly utilities?: readonly ScaffoldUtilityName[];
30
+ readonly deployment?: ScaffoldDeployment;
31
+ readonly overwrite?: boolean;
32
+ };
33
+ export type ScaffoldSiteResult = {
34
+ readonly targetDirectory: string;
35
+ readonly files: readonly string[];
36
+ };
37
+ export type ScaffoldDeploymentFlags = {
38
+ readonly githubActions?: boolean;
39
+ readonly cloudflareWorkers?: boolean;
40
+ readonly contentRepository?: string;
41
+ readonly siteRepository?: string;
42
+ };
43
+ export declare class ScaffoldSiteError extends Error {
44
+ constructor(message: string);
45
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Scaffold presets.
3
+ *
4
+ * A preset is the declarative description of one starter template. The
5
+ * scaffolder consumes a preset to decide which files it generates:
6
+ *
7
+ * - which plugins are registered in `riebeckite.config.ts`
8
+ * - which theme is applied
9
+ * - which content pages are emitted (localized, or English-only extras)
10
+ * - which `app/` shell files are written
11
+ *
12
+ * Presets are cumulative in spirit but defined explicitly so each tier is
13
+ * self-contained and can be selected by name:
14
+ *
15
+ * import { scaffoldRiebeckiteSite } from "create-riebeckite/scaffold";
16
+ *
17
+ * await scaffoldRiebeckiteSite({ targetDirectory: "./site", preset: "showcase" });
18
+ */
19
+ export declare const SCAFFOLD_LANGUAGES: readonly ["en", "ja", "zh-CN", "es", "de", "fr", "ko"];
20
+ export type ScaffoldLanguage = (typeof SCAFFOLD_LANGUAGES)[number];
21
+ export declare function defaultLanguageForLocale(locale: string): string;
22
+ export type ScaffoldPresetName = "starter" | "minimal" | "showcase" | "empty";
23
+ export declare const SCAFFOLD_PRESET_NAMES: readonly ScaffoldPresetName[];
24
+ export declare function isScaffoldPresetName(value: string): value is ScaffoldPresetName;
25
+ /** How a theme factory is referenced in the generated config file. */
26
+ export type ScaffoldThemeSpec = {
27
+ /** Npm package, for example `@riebeckite/theme-minimal`. */
28
+ readonly package: string;
29
+ /** Factory/import name, for example `minimalTheme`. */
30
+ readonly factory: string;
31
+ /** Optional literal source for the factory call arguments, e.g. `{ colorMode: "light" }`. */
32
+ readonly options?: string;
33
+ };
34
+ /** How a plugin factory is referenced in the generated config file. */
35
+ export type ScaffoldPluginSpec = {
36
+ /** Npm package, for example `@riebeckite/plugin-seo`. */
37
+ readonly package: string;
38
+ /** Factory/import name, for example `seo`. */
39
+ readonly factory: string;
40
+ /** Options source for the factory call; see {@link ScaffoldOptions}. */
41
+ readonly options?: ScaffoldOptions;
42
+ };
43
+ /**
44
+ * Context passed to option sources. `variables` are the user-supplied site
45
+ * values (`title`, `baseUrl`, ...), `languages` the preset's configured
46
+ * languages, and configuration detail depth. `showcase` uses depth 3 so its
47
+ * generated config is a complete options reference; the other presets keep
48
+ * their configuration intentionally small.
49
+ */
50
+ export type ScaffoldOptionContext = {
51
+ readonly variables: {
52
+ readonly name: string;
53
+ readonly title: string;
54
+ readonly description: string;
55
+ readonly baseUrl: string;
56
+ readonly locale: string;
57
+ };
58
+ readonly languages: readonly ScaffoldLanguage[];
59
+ readonly depth: number;
60
+ };
61
+ /** A single option value: a literal, or a function of the scaffold context. */
62
+ export type ScaffoldOptionValue = string | ((context: ScaffoldOptionContext) => string);
63
+ /** A config field gated to a minimum preset depth. */
64
+ export type ScaffoldOptionField = {
65
+ /** The lowest `ScaffoldOptionContext.depth` that includes this field. */
66
+ readonly depth: number;
67
+ readonly value: ScaffoldOptionValue;
68
+ };
69
+ /**
70
+ * Options for a generated plugin call: a literal source string, a function
71
+ * producing one, or a field map whose fields appear from a minimum depth.
72
+ * The field map form lets each preset tier demonstrate the configuration
73
+ * surface step by step while keeping one source of truth per plugin.
74
+ */
75
+ export type ScaffoldOptions = string | ((context: ScaffoldOptionContext) => string) | Readonly<Record<string, ScaffoldOptionField>>;
76
+ /** Content pages the scaffold can emit. */
77
+ export type ScaffoldPageKey = "index" | "framework/plugins" | "framework/themes" | "guide" | "examples" | "reference/plugins" | "reference/themes";
78
+ /** README verbosity. */
79
+ export type ScaffoldReadmeLevel = "short" | "standard" | "rich";
80
+ export type ScaffoldPreset = {
81
+ readonly name: ScaffoldPresetName;
82
+ /** One-line human description, shown by `--list-presets`. */
83
+ readonly description: string;
84
+ /** Languages the l10n plugin is configured with. A single entry means no l10n. */
85
+ readonly languages: readonly ScaffoldLanguage[];
86
+ readonly theme: ScaffoldThemeSpec | null;
87
+ readonly plugins: readonly ScaffoldPluginSpec[];
88
+ readonly contentPages: readonly ScaffoldPageKey[];
89
+ readonly readme: ScaffoldReadmeLevel;
90
+ };
91
+ export declare const empty: ScaffoldPreset;
92
+ export declare const minimal: ScaffoldPreset;
93
+ export declare const starter: ScaffoldPreset;
94
+ export declare const showcase: ScaffoldPreset;
95
+ export declare const scaffoldPresets: Readonly<Record<ScaffoldPresetName, ScaffoldPreset>>;
96
+ export declare const SCAFFOLD_DEFAULT_PRESET: ScaffoldPresetName;
97
+ export type ScaffoldPresetSummary = {
98
+ readonly name: ScaffoldPresetName;
99
+ readonly description: string;
100
+ };
101
+ export declare const SCAFFOLD_PRESETS: readonly ScaffoldPresetSummary[];
102
+ export declare function resolveScaffoldPreset(value: ScaffoldPresetName | undefined): ScaffoldPreset;
@@ -0,0 +1,4 @@
1
+ import type { SiteTemplateFile } from "./templates.js";
2
+ export declare function resolveTemplateRoot(): string;
3
+ export declare function readTemplate(relativePath: string): Uint8Array;
4
+ export declare function copyTemplateTree(relativeDirectory: string, replacements?: Readonly<Record<string, string>>, include?: (relativePath: string) => boolean): SiteTemplateFile[];
@@ -0,0 +1,55 @@
1
+ import { type ScaffoldOptionContext, type ScaffoldOptions, type ScaffoldPreset } from "./presets.js";
2
+ import { type ScaffoldUtilityName } from "./utilities.js";
3
+ export type SiteTemplateVariables = {
4
+ readonly name: string;
5
+ readonly title: string;
6
+ readonly description: string;
7
+ readonly baseUrl: string;
8
+ readonly locale: string;
9
+ readonly externalContent?: boolean;
10
+ };
11
+ export type SiteTemplateOptions = {
12
+ readonly cloudflareWorkers?: boolean;
13
+ readonly utilities?: readonly ScaffoldUtilityName[];
14
+ };
15
+ export type SiteTemplateFile = {
16
+ readonly path: string;
17
+ readonly content: string | Uint8Array;
18
+ };
19
+ export declare function siteTemplateFiles(preset: ScaffoldPreset, variables: SiteTemplateVariables, options?: SiteTemplateOptions): readonly SiteTemplateFile[];
20
+ /**
21
+ * Resolve a plugin's options literal for the preset's depth, or `null` when
22
+ * the plugin takes no options at that depth (and should be called bare).
23
+ */
24
+ export declare function renderOptions(options: ScaffoldOptions | undefined, context: ScaffoldOptionContext): string | null;
25
+ export type ReadmeDemo = {
26
+ readonly title: {
27
+ readonly en: string;
28
+ readonly ja: string;
29
+ };
30
+ readonly intro: {
31
+ readonly en: string;
32
+ readonly ja: string;
33
+ };
34
+ readonly markdown: string;
35
+ };
36
+ export declare const README_DEMOS: Readonly<Record<string, ReadmeDemo>>;
37
+ /**
38
+ * English-only content pages keep a `.en` suffix unless `en` is the default
39
+ * language. `examples` is intentionally absent: it is localized like the
40
+ * tour pages, with English as the fallback for untranslated languages.
41
+ */
42
+ export declare const ENGLISH_ONLY_PAGES: Set<string>;
43
+ export declare function fence(language: string, body: string): string;
44
+ export declare function hasPlugin(preset: ScaffoldPreset, packageName: string): boolean;
45
+ /**
46
+ * A demo key is either `@scope/package` or `@scope/package/topic`. Recover the
47
+ * package name: the first two `/`-separated segments form the scoped name.
48
+ */
49
+ export declare function demoPackage(key: string): string;
50
+ /**
51
+ * The options object literal used for a plugin at this preset's depth, or
52
+ * `null` when it takes no options at that depth.
53
+ */
54
+ export declare function readmePluginOptions(variables: SiteTemplateVariables, preset: ScaffoldPreset, plugin: ScaffoldPreset["plugins"][number]): string | null;
55
+ export declare const README_DEMO_ORDER: string[];
@@ -0,0 +1,14 @@
1
+ import type { SiteTemplateFile } from "./templates.js";
2
+ export declare const SCAFFOLD_UTILITY_NAMES: readonly ["editorconfig", "gitattributes", "biome", "npmrc", "vscode"];
3
+ export type ScaffoldUtilityName = (typeof SCAFFOLD_UTILITY_NAMES)[number];
4
+ export type ScaffoldUtilitySummary = {
5
+ readonly name: ScaffoldUtilityName;
6
+ readonly label: string;
7
+ readonly description: string;
8
+ };
9
+ export declare const SCAFFOLD_UTILITIES: readonly ScaffoldUtilitySummary[];
10
+ export declare const SCAFFOLD_DEFAULT_UTILITIES: readonly ScaffoldUtilityName[];
11
+ export declare const SCAFFOLD_NO_UTILITIES = "none";
12
+ export declare function isScaffoldUtilityName(value: string): value is ScaffoldUtilityName;
13
+ export declare function parseScaffoldUtilities(value: string): readonly ScaffoldUtilityName[];
14
+ export declare function utilityTemplateFiles(utilities: readonly ScaffoldUtilityName[]): readonly SiteTemplateFile[];
@@ -0,0 +1 @@
1
+ export declare const RIEBECKITE_VERSION = "^0.0.19";
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Static defaults for the Cloudflare Workers config that the scaffold generates.
3
+ */
4
+ export declare const CLOUDFLARE_WORKERS_DEFAULTS: {
5
+ /** JSON schema for IDE support and validation */
6
+ readonly $schema: "node_modules/wrangler/config-schema.json";
7
+ /** Compatibility date - update when Workers runtime changes require it */
8
+ readonly compatibility_date: "2026-06-09";
9
+ /** Required for Node.js APIs used by Riebeckite */
10
+ readonly compatibility_flags: readonly ["nodejs_compat"];
11
+ /** Static assets directory - Riebeckite builds to ./dist */
12
+ readonly assets: {
13
+ readonly directory: "./dist";
14
+ };
15
+ };
16
+ /** Type for the wrangler config object */
17
+ export type CloudflareWorkersDefaults = typeof CLOUDFLARE_WORKERS_DEFAULTS;
18
+ export declare const WRANGLER_VERSION = "^4.83.0";
19
+ export declare const DEFAULT_WORKER_NAME = "riebeckite-site";
20
+ export declare const WORKER_NAME_MAX_LENGTH = 63;
21
+ export declare function workerNameFromDirectory(directoryName: string): string;
22
+ export declare function buildWranglerConfig(workerName: string): string;
23
+ export declare function wranglerConfigForDirectory(directory: string): string;
24
+ /** Expected secret names in GitHub Actions workflow */
25
+ export declare const GITHUB_ACTIONS_SECRETS: {
26
+ /** Cloudflare API token with Workers Scripts: Edit permission */
27
+ readonly CLOUDFLARE_API_TOKEN: "CLOUDFLARE_API_TOKEN";
28
+ /** Cloudflare Account ID (found in Workers & Pages dashboard URL) */
29
+ readonly CLOUDFLARE_ACCOUNT_ID: "CLOUDFLARE_ACCOUNT_ID";
30
+ /** Optional: Token for content repo to dispatch to site repo */
31
+ readonly SITE_DISPATCH_TOKEN: "SITE_DISPATCH_TOKEN";
32
+ /** Optional: Token for site repo to read content repo */
33
+ readonly RIEBECKITE_CONTENT_READ_TOKEN: "RIEBECKITE_CONTENT_READ_TOKEN";
34
+ };
35
+ /** Package manager used by generated sites and workflows */
36
+ export declare const PACKAGE_MANAGER: "npm";
37
+ /** Lockfile name that must be committed */
38
+ export declare const LOCKFILE_NAME: "package-lock.json";
39
+ /** Files/directories that must be in .gitignore */
40
+ export declare const GITIGNORE_REQUIRED: readonly ["node_modules/", "dist/", ".riebeckite/", "app/.riebeckite/"];
41
+ /** Files that must NOT be in .gitignore */
42
+ export declare const GITIGNORE_FORBIDDEN: readonly ["package-lock.json"];
43
+ /** Starter preset content pages (base names without language suffixes) */
44
+ export declare const STARTER_CONTENT_PAGES: readonly ["index", "guide", "examples", "notes/planning", "notes/writing"];
45
+ /** Starter preset languages */
46
+ export declare const STARTER_LANGUAGES: readonly ["en", "ja", "zh-CN", "es", "de", "fr", "ko"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-riebeckite",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -14,21 +14,32 @@
14
14
  "import": "./dist/src/index.js",
15
15
  "source": "./src/index.ts",
16
16
  "default": "./dist/src/index.js"
17
- }
17
+ },
18
+ "./scaffold": {
19
+ "types": "./dist/src/scaffold/index.d.ts",
20
+ "import": "./dist/src/scaffold/index.js",
21
+ "source": "./src/scaffold/index.ts",
22
+ "default": "./dist/src/scaffold/index.js"
23
+ },
24
+ "./package.json": "./package.json"
18
25
  },
19
26
  "files": [
20
27
  "LICENSE",
21
28
  "README.md",
22
29
  "README_ja.md",
23
30
  "bin",
24
- "dist"
31
+ "dist",
32
+ "templates"
25
33
  ],
26
34
  "publishConfig": {
27
35
  "access": "public"
28
36
  },
29
37
  "dependencies": {
30
- "@clack/prompts": "^1.8.1",
31
- "@riebeckite/honox": "0.0.17"
38
+ "@clack/prompts": "^1.8.1"
39
+ },
40
+ "devDependencies": {
41
+ "esbuild": "^0.28.2",
42
+ "@riebeckite/test": "0.0.19"
32
43
  },
33
44
  "repository": {
34
45
  "type": "git",
@@ -0,0 +1,14 @@
1
+ import { initRiebeckiteClient } from "virtual:riebeckite/client";
2
+ import { createClient } from "honox/client";
3
+
4
+ createClient();
5
+
6
+ if (document.readyState === "loading") {
7
+ document.addEventListener("DOMContentLoaded", initPage, { once: true });
8
+ } else {
9
+ initPage();
10
+ }
11
+
12
+ function initPage() {
13
+ initRiebeckiteClient();
14
+ }
@@ -0,0 +1,18 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { resolveConfigModule } from "@riebeckite/core";
4
+ import * as rawConfigModule from "../riebeckite.config";
5
+
6
+ const appRoot =
7
+ process.env.RIEBECKITE_APP_ROOT ??
8
+ fileURLToPath(new URL("../", import.meta.url));
9
+ const resolvedConfig = resolveConfigModule(rawConfigModule);
10
+
11
+ export const config = {
12
+ ...resolvedConfig,
13
+ buildDirectory: path.join(appRoot, ".riebeckite"),
14
+ content: {
15
+ ...resolvedConfig.content,
16
+ directory: path.resolve(appRoot, resolvedConfig.content.directory),
17
+ },
18
+ };
@@ -0,0 +1,10 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { config } from "../config";
4
+
5
+ const appRoot =
6
+ process.env.RIEBECKITE_APP_ROOT ??
7
+ fileURLToPath(new URL("../../", import.meta.url));
8
+
9
+ export const CONTENT_DIR = path.resolve(appRoot, config.content.directory);
10
+ export const ASSETS_ROOT = "public/";
@@ -0,0 +1,12 @@
1
+ import { ContentManager } from "@riebeckite/core";
2
+ import { config } from "./config";
3
+ import { CONTENT_DIR } from "./constants/paths";
4
+
5
+ export const content = new ContentManager(
6
+ CONTENT_DIR,
7
+ config.content.exclude,
8
+ {
9
+ config,
10
+ plugins: config.plugins,
11
+ },
12
+ );
@@ -0,0 +1,15 @@
1
+ import type { PluginHeadTag } from "@riebeckite/core";
2
+
3
+ declare module "virtual:riebeckite/client" {
4
+ export function initRiebeckiteClient(): void;
5
+ }
6
+
7
+ declare module "hono" {
8
+ interface Env {
9
+ Variables: {
10
+ headTags?: readonly PluginHeadTag[];
11
+ htmlLanguage?: string;
12
+ };
13
+ Bindings: Record<string, never>;
14
+ }
15
+ }
@@ -0,0 +1,13 @@
1
+ import { mountRiebeckiteEndpoints } from "@riebeckite/honox/server";
2
+ import { createApp } from "honox/server";
3
+ import { config } from "./config";
4
+ import { content } from "./content";
5
+
6
+ const app = createApp({
7
+ init: (app) => {
8
+ mountRiebeckiteEndpoints(app, { config, content });
9
+ },
10
+ });
11
+
12
+ export default app;
13
+ export { config, content };
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+ "lib": [
7
+ "ES2022",
8
+ "DOM",
9
+ "DOM.Iterable"
10
+ ],
11
+ "jsx": "react-jsx",
12
+ "jsxImportSource": "hono/jsx",
13
+ "types": [
14
+ "node",
15
+ "vite/client"
16
+ ],
17
+ "strict": true,
18
+ "noEmit": true,
19
+ "esModuleInterop": true,
20
+ "allowSyntheticDefaultImports": true,
21
+ "resolveJsonModule": true,
22
+ "skipLibCheck": true
23
+ },
24
+ "include": [
25
+ "app/**/*.ts",
26
+ "app/**/*.tsx",
27
+ "riebeckite.config.ts",
28
+ "vite.config.ts"
29
+ ]
30
+ }
@@ -0,0 +1,34 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import build from "@hono/vite-build/node";
4
+ import {
5
+ defaultSsrExternals,
6
+ riebeckite,
7
+ riebeckiteSsg,
8
+ riebeckiteSsgExtensionMap,
9
+ } from "@riebeckite/honox";
10
+ import honox from "honox/vite";
11
+ import { defineConfig } from "vite";
12
+
13
+ const appRoot = fileURLToPath(new URL(".", import.meta.url));
14
+
15
+ export default defineConfig({
16
+ plugins: [
17
+ honox({
18
+ client: { input: ["/app/client.ts", "/app/style.css"] },
19
+ }),
20
+ riebeckite({ appRoot }),
21
+ build(),
22
+ riebeckiteSsg({
23
+ entry: path.join(appRoot, "app/server.ts"),
24
+ extensionMap: riebeckiteSsgExtensionMap(),
25
+ }),
26
+ ],
27
+ environments: {
28
+ ssr: {
29
+ resolve: {
30
+ external: [...defaultSsrExternals],
31
+ },
32
+ },
33
+ },
34
+ });
@@ -0,0 +1,6 @@
1
+ {
2
+ "root": false,
3
+ "formatter": { "enabled": false },
4
+ "linter": { "enabled": false },
5
+ "assist": { "enabled": false }
6
+ }
@@ -0,0 +1,6 @@
1
+ - name: Check out the external content repository
2
+ uses: actions/checkout@v4
3
+ with:
4
+ repository: {{contentRepository}}
5
+ token: ${{ secrets.{{contentReadToken}} || github.token }}
6
+ path: content
@@ -0,0 +1,54 @@
1
+ name: Deploy to Cloudflare Workers
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+ repository_dispatch:
8
+ types: [content-updated]
9
+
10
+ concurrency:
11
+ group: riebeckite-deploy
12
+ cancel-in-progress: true
13
+
14
+ jobs:
15
+ deploy:
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ contents: read
19
+ steps:
20
+ - name: Check out the site repository
21
+ uses: actions/checkout@v4
22
+ {{contentCheckout}}
23
+ - name: Set up Node.js
24
+ uses: actions/setup-node@v4
25
+ with:
26
+ node-version: 22
27
+ cache: npm
28
+
29
+ - name: Install dependencies
30
+ run: npm ci
31
+
32
+ - name: Restore Riebeckite build state
33
+ uses: actions/cache@v4
34
+ with:
35
+ path: |
36
+ .riebeckite/cache
37
+ .riebeckite/build/content-state.json
38
+ key: riebeckite-build-v1-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-${{ github.run_id }}-${{ github.run_attempt }}
39
+ restore-keys: |
40
+ riebeckite-build-v1-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-
41
+ riebeckite-content-v3-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
42
+
43
+ - name: Validate configuration and plugins
44
+ run: npm exec riebeckite check
45
+
46
+ - name: Build the site
47
+ run: npm exec riebeckite build
48
+
49
+ - name: Deploy the built assets
50
+ uses: cloudflare/wrangler-action@v3
51
+ with:
52
+ apiToken: ${{ secrets.{{cloudflareApiToken}} }}
53
+ accountId: ${{ secrets.{{cloudflareAccountId}} }}
54
+ command: deploy
@@ -0,0 +1,31 @@
1
+ name: Notify Riebeckite site
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ permissions: {}
8
+
9
+ jobs:
10
+ notify:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Validate dispatch configuration
14
+ env:
15
+ SITE_DISPATCH_TOKEN: ${{ secrets.{{siteDispatchToken}} }}
16
+ run: |
17
+ if [ -z "$SITE_DISPATCH_TOKEN" ]; then
18
+ echo "::error::{{siteDispatchToken}} is not configured. Add a token that can dispatch to {{owner}}/{{repository}}."
19
+ exit 1
20
+ fi
21
+
22
+ - name: Notify the site repository
23
+ uses: actions/github-script@v7
24
+ with:
25
+ github-token: ${{ secrets.{{siteDispatchToken}} }}
26
+ script: |
27
+ await github.rest.repos.createDispatchEvent({
28
+ owner: "{{owner}}",
29
+ repo: "{{repository}}",
30
+ event_type: "content-updated",
31
+ });
@@ -0,0 +1,21 @@
1
+ import { jsxRenderer } from "hono/jsx-renderer";
2
+ import { Link, Script } from "honox/server";
3
+ import { config } from "../config";
4
+
5
+ // Riebeckite plugin client entries need the HonoX client bundle even without
6
+ // an island component.
7
+ export const __importing_islands = true;
8
+
9
+ export default jsxRenderer(({ children }, c) => (
10
+ <html lang={c.get("htmlLanguage") ?? config.site.locale}>
11
+ <head>
12
+ <meta charset="utf-8" />
13
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
14
+ <title>{config.site.title}</title>
15
+ <link rel="icon" href="/favicon.ico" />
16
+ <Link href="/app/style.css" rel="stylesheet" />
17
+ <Script src="/app/client.ts" async />
18
+ </head>
19
+ <body class="riebeckite-page rb-site">{children}</body>
20
+ </html>
21
+ ));
@@ -0,0 +1,11 @@
1
+ import { createRoute } from "honox/factory";
2
+ import { config } from "../config";
3
+
4
+ export default createRoute((c) =>
5
+ c.render(
6
+ <main class="riebeckite-empty">
7
+ <h1>{config.site.title}</h1>
8
+ <p>This is a blank Riebeckite site. Add Markdown files under content/ to get started.</p>
9
+ </main>,
10
+ ),
11
+ );
@@ -0,0 +1,17 @@
1
+
2
+ *,
3
+ *::before,
4
+ *::after {
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ body {
9
+ margin: 0;
10
+ font-family: system-ui, sans-serif;
11
+ }
12
+
13
+ .riebeckite-empty {
14
+ max-width: 48rem;
15
+ padding: 4rem 1rem;
16
+ margin: 0 auto;
17
+ }