@ahmedrowaihi/8n 6.0.56 → 6.0.58

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.mjs CHANGED
@@ -590,7 +590,6 @@ const string$1 = (params) => {
590
590
  const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
591
591
  return new RegExp(`^${regex}$`);
592
592
  };
593
- const number = /^-?\d+(?:\.\d+)?$/;
594
593
  const boolean$1 = /^(?:true|false)$/i;
595
594
  const lowercase = /^[^A-Z]*$/;
596
595
  const uppercase = /^[^a-z]*$/;
@@ -1629,97 +1628,6 @@ function handleIntersectionResults(result, left, right) {
1629
1628
  result.value = merged.data;
1630
1629
  return result;
1631
1630
  }
1632
- const $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
1633
- $ZodType.init(inst, def);
1634
- inst._zod.parse = (payload, ctx) => {
1635
- const input = payload.value;
1636
- if (!isPlainObject(input)) {
1637
- payload.issues.push({
1638
- expected: "record",
1639
- code: "invalid_type",
1640
- input,
1641
- inst
1642
- });
1643
- return payload;
1644
- }
1645
- const proms = [];
1646
- const values = def.keyType._zod.values;
1647
- if (values) {
1648
- payload.value = {};
1649
- const recordKeys = /* @__PURE__ */ new Set();
1650
- for (const key of values) if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
1651
- recordKeys.add(typeof key === "number" ? key.toString() : key);
1652
- const result = def.valueType._zod.run({
1653
- value: input[key],
1654
- issues: []
1655
- }, ctx);
1656
- if (result instanceof Promise) proms.push(result.then((result) => {
1657
- if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
1658
- payload.value[key] = result.value;
1659
- }));
1660
- else {
1661
- if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
1662
- payload.value[key] = result.value;
1663
- }
1664
- }
1665
- let unrecognized;
1666
- for (const key in input) if (!recordKeys.has(key)) {
1667
- unrecognized = unrecognized ?? [];
1668
- unrecognized.push(key);
1669
- }
1670
- if (unrecognized && unrecognized.length > 0) payload.issues.push({
1671
- code: "unrecognized_keys",
1672
- input,
1673
- inst,
1674
- keys: unrecognized
1675
- });
1676
- } else {
1677
- payload.value = {};
1678
- for (const key of Reflect.ownKeys(input)) {
1679
- if (key === "__proto__") continue;
1680
- let keyResult = def.keyType._zod.run({
1681
- value: key,
1682
- issues: []
1683
- }, ctx);
1684
- if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
1685
- if (typeof key === "string" && number.test(key) && keyResult.issues.length) {
1686
- const retryResult = def.keyType._zod.run({
1687
- value: Number(key),
1688
- issues: []
1689
- }, ctx);
1690
- if (retryResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
1691
- if (retryResult.issues.length === 0) keyResult = retryResult;
1692
- }
1693
- if (keyResult.issues.length) {
1694
- if (def.mode === "loose") payload.value[key] = input[key];
1695
- else payload.issues.push({
1696
- code: "invalid_key",
1697
- origin: "record",
1698
- issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
1699
- input: key,
1700
- path: [key],
1701
- inst
1702
- });
1703
- continue;
1704
- }
1705
- const result = def.valueType._zod.run({
1706
- value: input[key],
1707
- issues: []
1708
- }, ctx);
1709
- if (result instanceof Promise) proms.push(result.then((result) => {
1710
- if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
1711
- payload.value[keyResult.value] = result.value;
1712
- }));
1713
- else {
1714
- if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
1715
- payload.value[keyResult.value] = result.value;
1716
- }
1717
- }
1718
- }
1719
- if (proms.length) return Promise.all(proms).then(() => payload);
1720
- return payload;
1721
- };
1722
- });
1723
1631
  const $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
1724
1632
  $ZodType.init(inst, def);
1725
1633
  const values = getEnumValues(def.entries);
@@ -1738,24 +1646,6 @@ const $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
1738
1646
  return payload;
1739
1647
  };
1740
1648
  });
1741
- const $ZodLiteral = /* @__PURE__ */ $constructor("$ZodLiteral", (inst, def) => {
1742
- $ZodType.init(inst, def);
1743
- if (def.values.length === 0) throw new Error("Cannot create literal schema with no valid values");
1744
- const values = new Set(def.values);
1745
- inst._zod.values = values;
1746
- inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex(o) : o ? escapeRegex(o.toString()) : String(o)).join("|")})$`);
1747
- inst._zod.parse = (payload, _ctx) => {
1748
- const input = payload.value;
1749
- if (values.has(input)) return payload;
1750
- payload.issues.push({
1751
- code: "invalid_value",
1752
- values: def.values,
1753
- input,
1754
- inst
1755
- });
1756
- return payload;
1757
- };
1758
- });
1759
1649
  const $ZodTransform = /* @__PURE__ */ $constructor("$ZodTransform", (inst, def) => {
1760
1650
  $ZodType.init(inst, def);
1761
1651
  inst._zod.parse = (payload, ctx) => {
@@ -2821,27 +2711,6 @@ const enumProcessor = (schema, _ctx, json, _params) => {
2821
2711
  if (values.every((v) => typeof v === "string")) json.type = "string";
2822
2712
  json.enum = values;
2823
2713
  };
2824
- const literalProcessor = (schema, ctx, json, _params) => {
2825
- const def = schema._zod.def;
2826
- const vals = [];
2827
- for (const val of def.values) if (val === void 0) {
2828
- if (ctx.unrepresentable === "throw") throw new Error("Literal `undefined` cannot be represented in JSON Schema");
2829
- } else if (typeof val === "bigint") if (ctx.unrepresentable === "throw") throw new Error("BigInt literals cannot be represented in JSON Schema");
2830
- else vals.push(Number(val));
2831
- else vals.push(val);
2832
- if (vals.length === 0) {} else if (vals.length === 1) {
2833
- const val = vals[0];
2834
- json.type = val === null ? "null" : typeof val;
2835
- if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") json.enum = [val];
2836
- else json.const = val;
2837
- } else {
2838
- if (vals.every((v) => typeof v === "number")) json.type = "number";
2839
- if (vals.every((v) => typeof v === "string")) json.type = "string";
2840
- if (vals.every((v) => typeof v === "boolean")) json.type = "boolean";
2841
- if (vals.every((v) => v === null)) json.type = "null";
2842
- json.enum = vals;
2843
- }
2844
- };
2845
2714
  const customProcessor = (_schema, ctx, _json, _params) => {
2846
2715
  if (ctx.unrepresentable === "throw") throw new Error("Custom types cannot be represented in JSON Schema");
2847
2716
  };
@@ -2924,39 +2793,6 @@ const intersectionProcessor = (schema, ctx, json, params) => {
2924
2793
  const isSimpleIntersection = (val) => "allOf" in val && Object.keys(val).length === 1;
2925
2794
  json.allOf = [...isSimpleIntersection(a) ? a.allOf : [a], ...isSimpleIntersection(b) ? b.allOf : [b]];
2926
2795
  };
2927
- const recordProcessor = (schema, ctx, _json, params) => {
2928
- const json = _json;
2929
- const def = schema._zod.def;
2930
- json.type = "object";
2931
- const keyType = def.keyType;
2932
- const patterns = keyType._zod.bag?.patterns;
2933
- if (def.mode === "loose" && patterns && patterns.size > 0) {
2934
- const valueSchema = process$1(def.valueType, ctx, {
2935
- ...params,
2936
- path: [
2937
- ...params.path,
2938
- "patternProperties",
2939
- "*"
2940
- ]
2941
- });
2942
- json.patternProperties = {};
2943
- for (const pattern of patterns) json.patternProperties[pattern.source] = valueSchema;
2944
- } else {
2945
- if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process$1(def.keyType, ctx, {
2946
- ...params,
2947
- path: [...params.path, "propertyNames"]
2948
- });
2949
- json.additionalProperties = process$1(def.valueType, ctx, {
2950
- ...params,
2951
- path: [...params.path, "additionalProperties"]
2952
- });
2953
- }
2954
- const keyValues = keyType._zod.values;
2955
- if (keyValues) {
2956
- const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
2957
- if (validKeyValues.length > 0) json.required = validKeyValues;
2958
- }
2959
- };
2960
2796
  const nullableProcessor = (schema, ctx, json, params) => {
2961
2797
  const def = schema._zod.def;
2962
2798
  const inner = process$1(def.innerType, ctx, params);
@@ -3417,21 +3253,6 @@ function intersection(left, right) {
3417
3253
  right
3418
3254
  });
3419
3255
  }
3420
- const ZodRecord = /* @__PURE__ */ $constructor("ZodRecord", (inst, def) => {
3421
- $ZodRecord.init(inst, def);
3422
- ZodType.init(inst, def);
3423
- inst._zod.processJSONSchema = (ctx, json, params) => recordProcessor(inst, ctx, json, params);
3424
- inst.keyType = def.keyType;
3425
- inst.valueType = def.valueType;
3426
- });
3427
- function record(keyType, valueType, params) {
3428
- return new ZodRecord({
3429
- type: "record",
3430
- keyType,
3431
- valueType,
3432
- ...normalizeParams(params)
3433
- });
3434
- }
3435
3256
  const ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
3436
3257
  $ZodEnum.init(inst, def);
3437
3258
  ZodType.init(inst, def);
@@ -3469,23 +3290,6 @@ function _enum(values, params) {
3469
3290
  ...normalizeParams(params)
3470
3291
  });
3471
3292
  }
3472
- const ZodLiteral = /* @__PURE__ */ $constructor("ZodLiteral", (inst, def) => {
3473
- $ZodLiteral.init(inst, def);
3474
- ZodType.init(inst, def);
3475
- inst._zod.processJSONSchema = (ctx, json, params) => literalProcessor(inst, ctx, json, params);
3476
- inst.values = new Set(def.values);
3477
- Object.defineProperty(inst, "value", { get() {
3478
- if (def.values.length > 1) throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");
3479
- return def.values[0];
3480
- } });
3481
- });
3482
- function literal(value, params) {
3483
- return new ZodLiteral({
3484
- type: "literal",
3485
- values: Array.isArray(value) ? value : [value],
3486
- ...normalizeParams(params)
3487
- });
3488
- }
3489
3293
  const ZodTransform = /* @__PURE__ */ $constructor("ZodTransform", (inst, def) => {
3490
3294
  $ZodTransform.init(inst, def);
3491
3295
  ZodType.init(inst, def);
@@ -3657,22 +3461,13 @@ const meta = meta$1;
3657
3461
  const configSchema = object({
3658
3462
  content: string().default("./content"),
3659
3463
  locales: array(string()).min(1).default(["en"]),
3660
- github: object({ repo: string() }).optional(),
3464
+ github: string().optional(),
3661
3465
  siteName: string().optional(),
3662
- version: string().optional(),
3663
- sections: record(string(), boolean()).optional(),
3664
- nav: object({ links: array(object({
3665
- text: string(),
3666
- url: string()
3667
- })).default([]) }).default({ links: [] }),
3668
- animations: boolean().default(true),
3669
- basePath: string().optional(),
3670
- auth: object({
3671
- provider: literal("github"),
3672
- repo: string().optional(),
3673
- protect: union([boolean(), array(string())]).default(true),
3674
- sessionDuration: string().default("7d")
3675
- }).optional()
3466
+ auth: union([boolean(), array(string())]).optional(),
3467
+ upstream: array(object({
3468
+ url: string(),
3469
+ label: string()
3470
+ })).optional()
3676
3471
  });
3677
3472
  async function resolveConfig() {
3678
3473
  const { config } = await loadConfig({
@@ -3738,7 +3533,7 @@ async function checkSelfUpdate() {
3738
3533
  });
3739
3534
  if (!res.ok) return;
3740
3535
  const { version: latest } = await res.json();
3741
- const current = "6.0.56";
3536
+ const current = "6.0.58";
3742
3537
  if (latest !== current) console.log(pc.yellow("⚠") + pc.dim(` new version available: `) + pc.cyan(latest) + pc.dim(` (current: ${current}) — run `) + pc.cyan("npm i -g @ahmedrowaihi/8n") + pc.dim(" to update"));
3743
3538
  } catch {}
3744
3539
  }
@@ -3809,17 +3604,14 @@ function buildEnv({ config, contentDir, staticExport = false }) {
3809
3604
  CONTENT_DIR: contentDir,
3810
3605
  LOCALES: (config.locales ?? ["en"]).join(","),
3811
3606
  NEXT_PUBLIC_SITE_NAME: config.siteName ?? "Docs",
3812
- NEXT_PUBLIC_GITHUB_REPO: config.github?.repo ?? process.env.NEXT_PUBLIC_GITHUB_REPO ?? ghPagesUrl ?? vercelGithubUrl,
3813
- SECTIONS: JSON.stringify(config.sections ?? {}),
3814
- NEXT_PUBLIC_NAV_LINKS: JSON.stringify(config.nav?.links ?? []),
3815
- NEXT_PUBLIC_ANIMATIONS: config.animations === false ? "false" : "true",
3816
- NEXT_BASE_PATH: config.basePath ?? ghPagesBasePath ?? "",
3607
+ NEXT_PUBLIC_GITHUB_REPO: config.github ?? process.env.NEXT_PUBLIC_GITHUB_REPO ?? ghPagesUrl ?? vercelGithubUrl,
3608
+ NEXT_PUBLIC_UPSTREAM_SOURCES: JSON.stringify(config.upstream ?? []),
3609
+ NEXT_BASE_PATH: ghPagesBasePath ?? "",
3817
3610
  NEXT_STATIC_EXPORT: staticExport ? "true" : "false",
3818
- ...config.auth ? {
3611
+ ...config.auth !== void 0 ? {
3819
3612
  AUTH_ENABLED: "true",
3820
- AUTH_REPO: config.auth.repo ?? config.github?.repo ?? ghPagesUrl,
3821
- AUTH_PROTECT: JSON.stringify(config.auth.protect),
3822
- AUTH_SESSION_DURATION: config.auth.sessionDuration
3613
+ AUTH_REPO: config.github ?? ghPagesUrl,
3614
+ AUTH_PROTECT: JSON.stringify(config.auth)
3823
3615
  } : {}
3824
3616
  };
3825
3617
  }
@@ -3851,7 +3643,7 @@ async function dev() {
3851
3643
  async function build({ server = false } = {}) {
3852
3644
  const { config, contentDir } = await resolveProject();
3853
3645
  const projectDir = process.cwd();
3854
- console.log(pc.cyan("8n") + pc.dim(` v6.0.56 build → ${contentDir}`));
3646
+ console.log(pc.cyan("8n") + pc.dim(` v6.0.58 build → ${contentDir}`));
3855
3647
  if (server) await runNextFlat(projectDir, "build", buildEnv({
3856
3648
  config,
3857
3649
  contentDir,
@@ -3912,16 +3704,6 @@ const SCAFFOLD = {
3912
3704
  locales: ["en"],
3913
3705
  siteName: "Docs",
3914
3706
 
3915
- // Pin to a specific starter version (git tag or commit SHA).
3916
- // Remove this line to always track the latest release.
3917
- // version: "v1.0.0",
3918
-
3919
- // Sections auto-show when content exists, auto-hide when empty.
3920
- // Set a section to false to hide it even if content is present.
3921
- // sections: { api: false },
3922
-
3923
- // Add links to the top navigation bar.
3924
- // nav: { links: [{ text: "Blog", url: "https://example.com/blog" }] },
3925
3707
  };
3926
3708
  `,
3927
3709
  ["content/docs/index.mdx"]: `---
@@ -4007,6 +3789,19 @@ No folder restructuring needed. Files without a locale suffix belong to the defa
4007
3789
  | \`icon\` | any index.mdx | sidebar group icon |
4008
3790
  | \`redirect\` | any | immediately redirects to another URL |
4009
3791
 
3792
+ ## Config options
3793
+
3794
+ \`\`\`ts
3795
+ export default {
3796
+ siteName: "Docs",
3797
+ locales: ["en", "ar"], // first is default
3798
+ nav: [{ text: "Blog", url: "https://example.com/blog" }],
3799
+ upstream: [{ url: "https://example.com/feed.xml", label: "Blog" }],
3800
+ sections: { api: false }, // force-hide a section
3801
+ github: { repo: "org/repo" }, // enables Edit on GitHub links
3802
+ };
3803
+ \`\`\`
3804
+
4010
3805
  ## CLI commands
4011
3806
 
4012
3807
  \`\`\`bash
@@ -4223,7 +4018,7 @@ async function mcp() {
4223
4018
  const mcpDir = join(getStarterDir(), "content", "mcp");
4224
4019
  const server = new McpServer({
4225
4020
  name: "8n",
4226
- version: "6.0.56"
4021
+ version: "6.0.58"
4227
4022
  });
4228
4023
  server.registerTool("read_me", {
4229
4024
  description: "Returns how to use the 8n MCP tools. Call this BEFORE documenting anything with 8n.",
@@ -4341,7 +4136,7 @@ async function generateApi({ input, output }) {
4341
4136
 
4342
4137
  //#endregion
4343
4138
  //#region src/index.ts
4344
- const program = new Command().name("8n").description("Run your 8n docs site").version("6.0.56").addOption(new Option("--debug").hideHelp()).hook("preAction", (cmd) => {
4139
+ const program = new Command().name("8n").description("Run your 8n docs site").version("6.0.58").addOption(new Option("--debug").hideHelp()).hook("preAction", (cmd) => {
4345
4140
  if (cmd.opts().debug) process.env.DEBUG_8N = "1";
4346
4141
  });
4347
4142
  program.command("init").description("Scaffold a new docs project in the current directory").action(init);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ahmedrowaihi/8n",
3
- "version": "6.0.56",
3
+ "version": "6.0.58",
4
4
  "description": "8n docs — run your docs site from your content directory",
5
5
  "bin": {
6
6
  "8n": "./dist/index.mjs"
@@ -0,0 +1 @@
1
+ import{jsx as r}from"react/jsx-runtime";import{UpstreamPage as t}from"../../../../src/features/upstream/upstream-page";import{redirect as a}from"next/navigation";import{env as o}from"../../../../src/config";import{defaultLocale as e}from"../../../../src/locale.config";export default async function i({params:m}){if(0===o.NEXT_PUBLIC_UPSTREAM_SOURCES.length){let{lang:r}=await m;a(`/${r??e}`)}let{lang:n}=await m;return r(t,{lang:n})}
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e,jsxs as r,Fragment as a}from"react/jsx-runtime";import t from"next/dynamic";import{AISearchTrigger as s}from"../../../src/features/ai/chat";import{MessageCircleIcon as i}from"lucide-react";import{Transition as o}from"../../../src/components/page-transition";let n=t(()=>import("../../../src/features/ai/chat").then(e=>({default:e.AISearchPanel})),{ssr:!1});export default function c({children:t}){return r(a,{children:[e(n,{}),e(o,{className:"flex flex-col flex-1",children:t}),e(s,{position:"float","aria-label":"Ask AI",variant:"secondary",size:"icon",className:"rounded-full text-muted-foreground size-12",children:e(i,{className:"size-5"})})]})}
2
+ import{jsx as e,jsxs as r,Fragment as a}from"react/jsx-runtime";import t from"next/dynamic";import{AISearchTrigger as s}from"../../../src/features/ai/chat";import{MessageCircleIcon as i}from"lucide-react";let l=t(()=>import("../../../src/features/ai/chat").then(e=>({default:e.AISearchPanel})),{ssr:!1});export default function o({children:t}){return r(a,{children:[e(l,{}),e("div",{className:"flex flex-col flex-1",children:t}),e(s,{position:"float","aria-label":"Ask AI",variant:"secondary",size:"icon",className:"rounded-full text-muted-foreground size-12",children:e(i,{className:"size-5"})})]})}
@@ -10,16 +10,12 @@ export default {
10
10
  content: "./content", // content directory (default: "./content")
11
11
  locales: ["en"], // supported locales — first entry is the default
12
12
  siteName: "Docs", // site name shown in the header
13
- version: "v1.0.0", // pin a specific starter version omit to track latest
14
- github: {
15
- repo: "https://github.com/org/repo", // enables "Edit on GitHub" links on every page
16
- },
13
+ github: "org/repo", // enables "Edit on GitHub" links on every page
17
14
  sections: {
18
15
  api: false, // false hides a section even when content exists
19
16
  },
20
- nav: {
21
- links: [{ text: "Blog", url: "https://example.com/blog" }],
22
- },
17
+ nav: [{ text: "Blog", url: "https://example.com/blog" }],
18
+ upstream: [{ url: "https://example.com/feed.xml", label: "Blog" }],
23
19
  };
24
20
  ```
25
21
 
@@ -32,6 +28,7 @@ export default {
32
28
  | `ui` | `content/ui/` | UI component showcase |
33
29
  | `changelog` | `content/changelog/` | Versioned release notes, sorted newest first |
34
30
  | `home` | `content/home/` | Replaces the default landing page |
31
+ | `upstream` | — | RSS feed aggregator — configured via `upstream: [...]` |
35
32
 
36
33
  Sections **auto-show** when their content directory exists and contains pages.
37
34
  Sections **auto-hide** when the directory is missing or empty.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ahmedrowaihi/8n-starter",
3
- "version": "6.0.56",
3
+ "version": "6.0.58",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "exports": {
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as t,jsxs as e}from"react/jsx-runtime";import{AnimatePresence as r,motion as i}from"motion/react";import{useEffect as n,useState as o}from"react";import{usePathname as a}from"next/navigation";import{cn as s}from"../lib/cn";let c="M9.8339 17.7084C11.1402 16.073 11.6679 14.4352 11.8974 12.7433H12.1101C12.3396 14.4352 12.8673 16.073 14.1736 17.7084H14.3023L16.5019 13.3224C13.9398 11.8729 12.9035 9.87848 12.1716 7.29163H11.836C11.104 9.87848 10.0677 11.8729 7.50558 13.3224L9.70519 17.7084H9.8339Z";export function LogoLoader({className:r,...n}){return e("svg",{viewBox:"0 0 24 25",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:s("size-4",r),...n,children:[t(i.path,{d:c,fill:"currentColor",animate:{opacity:[.08,.25,.08]},transition:{duration:1.6,repeat:1/0,ease:"easeInOut"}}),t(i.path,{d:c,fill:"none",stroke:"currentColor",strokeWidth:.6,strokeLinecap:"round",strokeLinejoin:"round",initial:{pathLength:0,opacity:0},animate:{pathLength:[0,1,1,0],opacity:[0,1,1,0]},transition:{duration:2,times:[0,.45,.7,1],repeat:1/0,ease:"easeInOut"}})]})}export function NavigationLoader(){let e=a(),[s,c]=o(!1);return n(()=>{let t=setTimeout(()=>c(!1),350);return()=>clearTimeout(t)},[e]),n(()=>{let t=t=>{let r=t.target.closest("a[href]");if(!r)return;let i=r.getAttribute("href")??"";i.startsWith("/")&&i!==e&&c(!0)};return document.addEventListener("click",t),()=>document.removeEventListener("click",t)},[e]),t(r,{children:s&&t(i.div,{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/60 backdrop-blur-sm pointer-events-none",initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.15},children:t(LogoLoader,{className:"size-14"})},"nav-loader")})}
2
+ import{jsx as t,jsxs as e}from"react/jsx-runtime";import{motion as o}from"motion/react";import{cn as r}from"../lib/cn";let i="M9.8339 17.7084C11.1402 16.073 11.6679 14.4352 11.8974 12.7433H12.1101C12.3396 14.4352 12.8673 16.073 14.1736 17.7084H14.3023L16.5019 13.3224C13.9398 11.8729 12.9035 9.87848 12.1716 7.29163H11.836C11.104 9.87848 10.0677 11.8729 7.50558 13.3224L9.70519 17.7084H9.8339Z";export function LogoLoader({className:n,...a}){return e("svg",{viewBox:"0 0 24 25",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:r("size-4",n),...a,children:[t(o.path,{d:i,fill:"currentColor",animate:{opacity:[.08,.25,.08]},transition:{duration:1.6,repeat:1/0,ease:"easeInOut"}}),t(o.path,{d:i,fill:"none",stroke:"currentColor",strokeWidth:.6,strokeLinecap:"round",strokeLinejoin:"round",initial:{pathLength:0,opacity:0},animate:{pathLength:[0,1,1,0],opacity:[0,1,1,0]},transition:{duration:2,times:[0,.45,.7,1],repeat:1/0,ease:"easeInOut"}})]})}
@@ -1 +1 @@
1
- import{createEnv as e}from"@t3-oss/env-nextjs";import{z as T}from"zod";let _=T.string().default("[]").transform(e=>JSON.parse(e)),E=T.string().default("{}").transform(e=>JSON.parse(e));export const env=e({server:{SITE_URL:T.string().default("http://localhost:3000"),CONTENT_DIR:T.string().default("./content"),SECTIONS:E,AUTH_ENABLED:T.enum(["true"]).optional(),AUTH_REPO:T.string().optional(),AUTH_PROTECT:T.string().default("true"),AUTH_SESSION_DURATION:T.string().default("7d"),GITHUB_CLIENT_ID:T.string().optional(),GITHUB_CLIENT_SECRET:T.string().optional(),AUTH_SECRET:T.string().optional()},client:{NEXT_PUBLIC_SITE_NAME:T.string().default("Docs"),NEXT_PUBLIC_GITHUB_REPO:T.string().optional(),NEXT_PUBLIC_NAV_LINKS:_,NEXT_PUBLIC_ANIMATIONS:T.enum(["true","false"]).default("true").transform(e=>"true"===e)},runtimeEnv:{SITE_URL:process.env.SITE_URL??(process.env.VERCEL_PROJECT_PRODUCTION_URL?`https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`:process.env.VERCEL_URL?`https://${process.env.VERCEL_URL}`:void 0),CONTENT_DIR:process.env.CONTENT_DIR,SECTIONS:process.env.SECTIONS,AUTH_ENABLED:process.env.AUTH_ENABLED,AUTH_REPO:process.env.AUTH_REPO,AUTH_PROTECT:process.env.AUTH_PROTECT,AUTH_SESSION_DURATION:process.env.AUTH_SESSION_DURATION,GITHUB_CLIENT_ID:process.env.GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET:process.env.GITHUB_CLIENT_SECRET,AUTH_SECRET:process.env.AUTH_SECRET,NEXT_PUBLIC_SITE_NAME:process.env.NEXT_PUBLIC_SITE_NAME,NEXT_PUBLIC_GITHUB_REPO:process.env.NEXT_PUBLIC_GITHUB_REPO,NEXT_PUBLIC_NAV_LINKS:process.env.NEXT_PUBLIC_NAV_LINKS,NEXT_PUBLIC_ANIMATIONS:process.env.NEXT_PUBLIC_ANIMATIONS}});export function isSectionHidden(e){return!1===env.SECTIONS[e]}"development"===process.env.NODE_ENV&&env.NEXT_PUBLIC_GITHUB_REPO?.includes("your-org/your-repo")&&console.warn("[8n-starter] ⚠ NEXT_PUBLIC_GITHUB_REPO is still the placeholder value.\n Set github.repo in 8n.config.ts to enable Edit on GitHub links.");
1
+ import{createEnv as E}from"@t3-oss/env-nextjs";import{z as _}from"zod";export const env=E({server:{SITE_URL:_.string().default("http://localhost:3000"),CONTENT_DIR:_.string().default("./content"),AUTH_ENABLED:_.enum(["true"]).optional(),AUTH_REPO:_.string().optional(),AUTH_PROTECT:_.string().default("true"),GITHUB_CLIENT_ID:_.string().optional(),GITHUB_CLIENT_SECRET:_.string().optional(),AUTH_SECRET:_.string().optional()},client:{NEXT_PUBLIC_SITE_NAME:_.string().default("Docs"),NEXT_PUBLIC_GITHUB_REPO:_.string().optional(),NEXT_PUBLIC_UPSTREAM_SOURCES:_.string().default("[]").transform(E=>JSON.parse(E))},runtimeEnv:{SITE_URL:process.env.SITE_URL??(process.env.VERCEL_PROJECT_PRODUCTION_URL?`https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`:process.env.VERCEL_URL?`https://${process.env.VERCEL_URL}`:void 0),CONTENT_DIR:process.env.CONTENT_DIR,AUTH_ENABLED:process.env.AUTH_ENABLED,AUTH_REPO:process.env.AUTH_REPO,AUTH_PROTECT:process.env.AUTH_PROTECT,GITHUB_CLIENT_ID:process.env.GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET:process.env.GITHUB_CLIENT_SECRET,AUTH_SECRET:process.env.AUTH_SECRET,NEXT_PUBLIC_SITE_NAME:process.env.NEXT_PUBLIC_SITE_NAME,NEXT_PUBLIC_GITHUB_REPO:process.env.NEXT_PUBLIC_GITHUB_REPO,NEXT_PUBLIC_UPSTREAM_SOURCES:process.env.NEXT_PUBLIC_UPSTREAM_SOURCES}});"development"===process.env.NODE_ENV&&env.NEXT_PUBLIC_GITHUB_REPO?.includes("your-org/your-repo")&&console.warn("[8n-starter] ⚠ NEXT_PUBLIC_GITHUB_REPO is still the placeholder value.\n Set github.repo in 8n.config.ts to enable Edit on GitHub links.");
@@ -1 +1 @@
1
- import{cookies as e}from"next/headers";import{env as t}from"../../config";import{signJWT as n,verifyJWT as o}from"./jwt.js";let r="8n_session";export function parseDuration(e){let t=/^(\d+)([smhd])$/.exec(e);return t?parseInt(t[1])*({s:1,m:60,h:3600,d:86400})[t[2]]:604800}export async function getSession(){if(!t.AUTH_ENABLED||!t.AUTH_SECRET)return null;let n=(await e()).get(r)?.value;return n?o(n,t.AUTH_SECRET):null}export async function setSession(o){let a=t.AUTH_SECRET,s=parseDuration(t.AUTH_SESSION_DURATION),i=await n({...o,exp:Math.floor(Date.now()/1e3)+s},a);(await e()).set(r,i,{httpOnly:!0,secure:"production"===process.env.NODE_ENV,sameSite:"lax",path:"/",maxAge:s})}export async function clearSession(){(await e()).delete(r)}
1
+ import{cookies as e}from"next/headers";import{env as t}from"../../config";import{signJWT as n,verifyJWT as o}from"./jwt.js";let r="8n_session";export function parseDuration(e){let t=/^(\d+)([smhd])$/.exec(e);return t?parseInt(t[1])*({s:1,m:60,h:3600,d:86400})[t[2]]:604800}export async function getSession(){if(!t.AUTH_ENABLED||!t.AUTH_SECRET)return null;let n=(await e()).get(r)?.value;return n?o(n,t.AUTH_SECRET):null}export async function setSession(o){let a=t.AUTH_SECRET,s=parseDuration("7d"),i=await n({...o,exp:Math.floor(Date.now()/1e3)+s},a);(await e()).set(r,i,{httpOnly:!0,secure:"production"===process.env.NODE_ENV,sameSite:"lax",path:"/",maxAge:s})}export async function clearSession(){(await e()).delete(r)}
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e,jsxs as o}from"react/jsx-runtime";import{DocsBody as t,DocsDescription as a,DocsPage as r,DocsTitle as i,EditOnGitHub as n,PageLastUpdate as l,MarkdownCopyButton as c,ViewOptionsPopover as d}from"../../../components/fumadocs/layout/docs/page";import{DocsTOC as s}from"../../../components/fumadocs/layout/docs/page/docs-toc";import{Feedback as f,createGitHubFeedbackAction as m}from"../../feedback";import{localeConfig as b}from"../../../locale.config";import{Transition as p}from"../../../components/page-transition";export function DocsPageContent({toc:u,frontmatter:k,children:h,markdownUrl:g,github:U,path:w,lang:x,lastModified:C,neighbours:y,full:O}){let j=(b[x]??b.en).translations;return e(r,{asChild:!0,toc:u,full:O,tableOfContent:{enabled:!0,component:e(s,{toc:u,style:"clerk",translations:{toc:j.toc,aiChatTrigger:j.aiChatTrigger}})},tableOfContentPopover:{style:"clerk"},footer:{items:y},children:o(p,{animationKey:w,children:[e(i,{children:k.title}),e(a,{children:k.description}),!O&&(g||U?.fileUrl)&&o("div",{className:"flex flex-row gap-2 items-center border-b -mt-4 pb-6",children:[g&&e(c,{markdownUrl:g}),g&&U?.fileUrl&&e(d,{markdownUrl:g,githubUrl:U.fileUrl}),U?.fileUrl&&e(n,{href:U.fileUrl})]}),e(t,{children:h}),!O&&C&&e(l,{date:new Date(C)}),!O&&U?.repo&&e(f,{onSendAction:m(k.title,U.repo),translations:{question:j.feedbackQuestion,feedbackLabel:j.feedbackLabel,good:j.feedbackGood,bad:j.feedbackBad,placeholder:j.feedbackPlaceholder,submit:j.feedbackSubmit,thankYou:j.feedbackThankYou,viewOnGitHub:j.feedbackViewOnGitHub,submitAgain:j.feedbackSubmitAgain}})]})})}
2
+ import{jsx as e,jsxs as o}from"react/jsx-runtime";import{DocsBody as t,DocsDescription as a,DocsPage as r,DocsTitle as i,EditOnGitHub as l,PageLastUpdate as n,MarkdownCopyButton as c,ViewOptionsPopover as d}from"../../../components/fumadocs/layout/docs/page";import{DocsTOC as f}from"../../../components/fumadocs/layout/docs/page/docs-toc";import{Feedback as s,createGitHubFeedbackAction as b}from"../../feedback";import{localeConfig as m}from"../../../locale.config";export function DocsPageContent({toc:u,frontmatter:p,children:k,markdownUrl:h,github:g,path:U,lang:w,lastModified:x,neighbours:C,full:v}){let y=(m[w]??m.en).translations;return e(r,{asChild:!0,toc:u,full:v,tableOfContent:{enabled:!0,component:e(f,{toc:u,style:"clerk",translations:{toc:y.toc,aiChatTrigger:y.aiChatTrigger}})},tableOfContentPopover:{style:"clerk"},footer:{items:C},children:o("div",{children:[e(i,{children:p.title}),e(a,{children:p.description}),!v&&(h||g?.fileUrl)&&o("div",{className:"flex flex-row gap-2 items-center border-b -mt-4 pb-6",children:[h&&e(c,{markdownUrl:h}),h&&g?.fileUrl&&e(d,{markdownUrl:h,githubUrl:g.fileUrl}),g?.fileUrl&&e(l,{href:g.fileUrl})]}),e(t,{children:k}),!v&&x&&e(n,{date:new Date(x)}),!v&&g?.repo&&e(s,{onSendAction:b(p.title,g.repo),translations:{question:y.feedbackQuestion,feedbackLabel:y.feedbackLabel,good:y.feedbackGood,bad:y.feedbackBad,placeholder:y.feedbackPlaceholder,submit:y.feedbackSubmit,thankYou:y.feedbackThankYou,viewOnGitHub:y.feedbackViewOnGitHub,submitAgain:y.feedbackSubmitAgain}})]})})}
@@ -0,0 +1 @@
1
+ function e(e){if(!e)return null;let t=new Date(e.trim());return isNaN(t.getTime())?null:t}export async function fetchFeed(t,r){try{var n,l;let o=await fetch(t),u=await o.text(),i=new DOMParser().parseFromString(u,"text/xml");if(i.querySelector("parsererror"))return{status:"error",source:r,message:"Invalid XML"};return{status:"ok",items:(n=i,l=r,null!==n.querySelector("feed")?Array.from(n.querySelectorAll("entry")).map(t=>({title:t.querySelector("title")?.textContent?.trim()??"(no title)",url:t.querySelector("link[rel='alternate']")?.getAttribute("href")??t.querySelector("link")?.getAttribute("href")??"",date:e(t.querySelector("published")?.textContent??t.querySelector("updated")?.textContent),summary:t.querySelector("summary")?.textContent?.trim()??t.querySelector("content")?.textContent?.slice(0,200)?.trim()??"",source:l})):Array.from(n.querySelectorAll("item")).map(t=>({title:t.querySelector("title")?.textContent?.trim()??"(no title)",url:t.querySelector("link")?.textContent?.trim()??t.querySelector("guid")?.textContent?.trim()??"",date:e(t.querySelector("pubDate")?.textContent),summary:t.querySelector("description")?.textContent?.slice(0,200)?.trim()??"",source:l})))}}catch(t){let e=t instanceof TypeError?t.message:String(t);if(e.includes("Failed to fetch")||e.includes("NetworkError")||e.includes("CORS"))return{status:"cors",source:r};return{status:"error",source:r,message:e}}}
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{jsx as e,jsxs as r,Fragment as a}from"react/jsx-runtime";import{env as t}from"../../config";import{localeConfig as s,defaultLocale as l}from"../../locale.config";import{LogoLoader as n}from"../../components/logo-loader";import{useUpstreamFeeds as o}from"./use-upstream-feeds";import{ExternalLink as i,AlertTriangle as m}from"lucide-react";export function UpstreamPage({lang:c}){var d;let p=(d=c,s[d]?.translations??s[l].translations),{loading:u,results:x,items:f}=o(t.NEXT_PUBLIC_UPSTREAM_SOURCES),h=x.filter(e=>"ok"!==e.status);return r("div",{className:"container max-w-3xl py-12 px-4",children:[e("h1",{className:"text-2xl font-bold mb-8",children:p.upstream}),u&&e("div",{className:"flex justify-center py-24",children:e(n,{className:"size-12"})}),!u&&h.length>0&&e("div",{className:"mb-8 flex flex-col gap-3",children:h.map((a,t)=>r("div",{className:"flex gap-3 rounded-lg border border-amber-500/30 bg-amber-500/10 px-4 py-3 text-sm text-amber-700 dark:text-amber-400",children:[e(m,{className:"mt-0.5 size-4 shrink-0"}),r("div",{children:[e("span",{className:"font-medium",children:a.source})," — ","cors"===a.status?p.upstreamCorsHint:p.upstreamError]})]},t))}),!u&&0===f.length&&0===h.length&&e("p",{className:"text-muted-foreground",children:p.upstreamEmpty}),!u&&f.length>0&&e("div",{className:"flex flex-col divide-y divide-border",children:f.map((t,l)=>r("a",{href:t.url,target:"_blank",rel:"noopener noreferrer",className:"group flex flex-col gap-1 py-5 hover:bg-muted/40 -mx-4 px-4 rounded-lg transition-colors",children:[r("div",{className:"flex items-start justify-between gap-4",children:[e("span",{className:"font-medium group-hover:text-primary transition-colors line-clamp-2",children:t.title}),e(i,{className:"mt-1 size-3.5 shrink-0 opacity-40 group-hover:opacity-70 transition-opacity"})]}),t.summary&&e("p",{className:"text-sm text-muted-foreground line-clamp-2",children:t.summary}),r("div",{className:"flex gap-2 text-xs text-muted-foreground/70 mt-1",children:[e("span",{children:t.source}),t.date&&r(a,{children:[e("span",{children:"·"}),e("span",{children:t.date.toLocaleDateString(s[c]?.translations.dateLocale??"en-US",{year:"numeric",month:"short",day:"numeric"})})]})]})]},l))})]})}
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{useEffect as e,useState as t}from"react";import{fetchFeed as s}from"./rss-parser.js";export function useUpstreamFeeds(a){let[r,l]=t({loading:a.length>0,results:[],items:[]});return e(()=>{0!==a.length&&(l({loading:!0,results:[],items:[]}),Promise.allSettled(a.map(e=>s(e.url,e.label))).then(e=>{let t=e.map(e=>"fulfilled"===e.status?e.value:{status:"error",source:"unknown",message:String(e.reason)}),s=t.flatMap(e=>"ok"===e.status?e.items:[]).sort((e,t)=>e.date||t.date?e.date?t.date?t.date.getTime()-e.date.getTime():-1:1:0);l({loading:!1,results:t,items:s})}))},[a.map(e=>e.url).join(",")]),r}
@@ -1 +1 @@
1
- import{readdir as t,readFile as e,stat as a}from"node:fs/promises";import{join as n,relative as i}from"node:path";import l from"gray-matter";import{locales as r}from"../locale.config";let m=new Set(["home"]);export async function discoverSections(e){let a;try{a=await t(e,{withFileTypes:!0})}catch{return[]}return a.filter(t=>t.isDirectory()&&!m.has(t.name)).map(t=>t.name)}let o=/^(\d+)-(.+)$/;function s(t){let e=t.match(o);return e?[parseInt(e[1],10),e[2]]:[1/0,t]}function f(t){return t.replace(o,"$2")}function c(t){return[...t].sort((t,e)=>{let[a,n]=s(t.name),[i,l]=s(e.name);return a!==i?a-i:n.localeCompare(l)})}function d(t){let e=t.endsWith(".mdx")?".mdx":t.endsWith(".md")?".md":"",a=e?t.slice(0,-e.length):t,n=a.lastIndexOf(".");if(n>=0){let t=a.slice(n+1);if(r.includes(t))return{base:a.slice(0,n),lang:t}}return{base:a,lang:null}}async function p(r,m,o){let s;try{s=await t(r,{withFileTypes:!0})}catch{return}let h=s.filter(t=>t.isFile()&&(t.name.endsWith(".mdx")||t.name.endsWith(".md"))),u=s.filter(t=>t.isDirectory()),y=i(m,r),g=h.filter(t=>"index"===d(t.name).base),w=c(h.filter(t=>"index"!==d(t.name).base));for(let t of g){let{lang:i}=d(t.name),m=n(r,t.name);try{let r=await e(m,"utf8"),s=await a(m),{data:f,content:c}=l(r),d=f.label??f.title??void 0,p={};d&&(p.title=d),f.icon&&(p.icon=f.icon);let h=i?`meta.${i}.json`:"meta.json",u=y?n(y,h):h;if(o.push({type:"meta",path:u,data:p}),c.trim().length>0){let e=y?n(y,t.name):t.name;o.push({type:"page",path:e,data:{...f,title:f.title??"Untitled",filePath:m,lastModified:s.mtime}})}}catch{}}let x=w.filter(t=>null===d(t.name).lang);if(x.length>0){let t=[...x.map(t=>f(d(t.name).base)),"..."],e=y?n(y,"meta.json"):"meta.json",a=o.find(t=>"meta"===t.type&&t.path===e);a&&"meta"===a.type?a.data={...a.data,pages:t}:o.push({type:"meta",path:e,data:{pages:t}})}for(let t of w){let{base:i,lang:m}=d(t.name),s=f(i),c=t.name.endsWith(".md")?".md":".mdx",p=m?`${s}.${m}${c}`:`${s}${c}`,h=y?n(y,p):p,u=n(r,t.name);try{let t=await e(u,"utf8"),n=await a(u),{data:i}=l(t);o.push({type:"page",path:h,data:{...i,title:i.title??"Untitled",filePath:u,lastModified:n.mtime}})}catch{}}for(let t of c(u))await p(n(r,t.name),m,o)}export async function createFsSource(t){let e=[];return await p(t,t,e),{files:e}}
1
+ import{readdir as t,readFile as e,stat as a}from"node:fs/promises";import{join as n,relative as i}from"node:path";import l from"gray-matter";import{locales as r}from"../locale.config";let m=new Set(["home","upstream"]);export async function discoverSections(e){let a;try{a=await t(e,{withFileTypes:!0})}catch{return[]}return a.filter(t=>t.isDirectory()&&!m.has(t.name)).map(t=>t.name)}let o=/^(\d+)-(.+)$/;function s(t){let e=t.match(o);return e?[parseInt(e[1],10),e[2]]:[1/0,t]}function f(t){return t.replace(o,"$2")}function c(t){return[...t].sort((t,e)=>{let[a,n]=s(t.name),[i,l]=s(e.name);return a!==i?a-i:n.localeCompare(l)})}function d(t){let e=t.endsWith(".mdx")?".mdx":t.endsWith(".md")?".md":"",a=e?t.slice(0,-e.length):t,n=a.lastIndexOf(".");if(n>=0){let t=a.slice(n+1);if(r.includes(t))return{base:a.slice(0,n),lang:t}}return{base:a,lang:null}}async function p(r,m,o){let s;try{s=await t(r,{withFileTypes:!0})}catch{return}let h=s.filter(t=>t.isFile()&&(t.name.endsWith(".mdx")||t.name.endsWith(".md"))),u=s.filter(t=>t.isDirectory()),y=i(m,r),g=h.filter(t=>"index"===d(t.name).base),w=c(h.filter(t=>"index"!==d(t.name).base));for(let t of g){let{lang:i}=d(t.name),m=n(r,t.name);try{let r=await e(m,"utf8"),s=await a(m),{data:f,content:c}=l(r),d=f.label??f.title??void 0,p={};d&&(p.title=d),f.icon&&(p.icon=f.icon);let h=i?`meta.${i}.json`:"meta.json",u=y?n(y,h):h;if(o.push({type:"meta",path:u,data:p}),c.trim().length>0){let e=y?n(y,t.name):t.name;o.push({type:"page",path:e,data:{...f,title:f.title??"Untitled",filePath:m,lastModified:s.mtime}})}}catch{}}let x=w.filter(t=>null===d(t.name).lang);if(x.length>0){let t=[...x.map(t=>f(d(t.name).base)),"..."],e=y?n(y,"meta.json"):"meta.json",a=o.find(t=>"meta"===t.type&&t.path===e);a&&"meta"===a.type?a.data={...a.data,pages:t}:o.push({type:"meta",path:e,data:{pages:t}})}for(let t of w){let{base:i,lang:m}=d(t.name),s=f(i),c=t.name.endsWith(".md")?".md":".mdx",p=m?`${s}.${m}${c}`:`${s}${c}`,h=y?n(y,p):p,u=n(r,t.name);try{let t=await e(u,"utf8"),n=await a(u),{data:i}=l(t);o.push({type:"page",path:h,data:{...i,title:i.title??"Untitled",filePath:u,lastModified:n.mtime}})}catch{}}for(let t of c(u))await p(n(r,t.name),m,o)}export async function createFsSource(t){let e=[];return await p(t,t,e),{files:e}}
@@ -1 +1 @@
1
- import{jsx as o,jsxs as t,Fragment as n}from"react/jsx-runtime";import{CompactSearchToggle as e}from"../components/fumadocs/search-toggle";import{SidebarBackButton as r}from"../components/fumadocs/layout/sidebar-back-button";import{EditorButton as s}from"../components/fumadocs/layout/editor-button";import{Logo as a}from"../components/logo";import{env as i}from"../config";export const githubRepo=i.NEXT_PUBLIC_GITHUB_REPO;export function baseOptions(t="en"){return{nav:{title:o(a,{className:"h-5 w-auto"}),url:`/${t}`},githubUrl:githubRepo,i18n:void 0,searchToggle:{components:{lg:o(e,{})}},links:i.NEXT_PUBLIC_NAV_LINKS.map(o=>({text:o.text,url:o.url}))}}export function docsOptions(e="en"){let a=baseOptions(e);return{...a,nav:{...a.nav,children:t(n,{children:[o(r,{}),o(s,{lang:e})]})}}}
1
+ import{jsx as o,jsxs as t,Fragment as n}from"react/jsx-runtime";import{CompactSearchToggle as e}from"../components/fumadocs/search-toggle";import{SidebarBackButton as r}from"../components/fumadocs/layout/sidebar-back-button";import{EditorButton as s}from"../components/fumadocs/layout/editor-button";import{Logo as a}from"../components/logo";import{env as i}from"../config";export const githubRepo=i.NEXT_PUBLIC_GITHUB_REPO;export function baseOptions(t="en"){return{nav:{title:o(a,{className:"h-5 w-auto"}),url:`/${t}`},githubUrl:githubRepo,i18n:void 0,searchToggle:{components:{lg:o(e,{})}}}}export function docsOptions(e="en"){let a=baseOptions(e);return{...a,nav:{...a.nav,children:t(n,{children:[o(r,{}),o(s,{lang:e})]})}}}
@@ -1,3 +1,3 @@
1
- import{loader as e}from"fumadocs-core/source";import{lucideIconsPlugin as t}from"fumadocs-core/source/lucide-icons";import{openapiPlugin as r}from"fumadocs-openapi/server";import{createSearchAPI as a}from"fumadocs-core/search/server";import{i18n as o}from"./i18n";import{join as n}from"node:path";import{existsSync as i,watch as s}from"node:fs";import{readFile as c}from"node:fs/promises";import l from"gray-matter";import{env as m,isSectionHidden as u}from"../config";import{createFsSource as f,discoverSections as p}from"./content-source.js";let g=[t(),r()];async function d(){let t=await p(m.CONTENT_DIR),r=Object.fromEntries(await Promise.all(t.map(async t=>{let r=e({source:await f(n(m.CONTENT_DIR,t)),baseUrl:`/${t}`,i18n:o,plugins:g});return[t,r]}))),i=a("simple",{indexes:await Promise.all(Object.entries(r).filter(([e])=>!u(e)).flatMap(([,e])=>e.getLanguages().flatMap(({language:e,pages:t})=>t.map(async t=>{let{content:r}=l(await c(t.data.filePath,"utf-8"));return{id:t.url,url:t.url,locale:e,title:t.data.title,content:r}}))))});return{sections:r,searchServer:i}}let O=null;export function getSources(){return O||(O=d(),"development"===process.env.NODE_ENV&&O.then(()=>{i(m.CONTENT_DIR)&&s(m.CONTENT_DIR,{recursive:!0},()=>{O=null})})),O}export async function getSections(){let{sections:e}=await getSources();return Object.fromEntries(Object.entries(e).filter(([e])=>!u(e)))}export async function getAllPages(){return Object.values(await getSections()).flatMap(e=>e.getPages())}export async function getUnifiedPageTree(e){let t=await getSections(),r=[];for(let a of Object.values(t)){let t=a.getPageTree(e);0!==t.children.length&&r.push({type:"folder",name:t.name,children:t.children})}return{name:"",children:r}}export async function getNavLinks(e){return Object.entries(await getSections()).map(([t,r])=>({text:r.getPageTree(e).name??t,url:`/${e}/${t}`,active:"nested-url"}))}export async function getLLMText(e){let{content:t}=l(await c(e.data.filePath,"utf-8"));return`# ${e.data.title}
1
+ import{loader as e}from"fumadocs-core/source";import{lucideIconsPlugin as t}from"fumadocs-core/source/lucide-icons";import{openapiPlugin as r}from"fumadocs-openapi/server";import{createSearchAPI as a}from"fumadocs-core/search/server";import{i18n as o}from"./i18n";import{join as n}from"node:path";import{existsSync as i,watch as s}from"node:fs";import{readFile as l}from"node:fs/promises";import c from"gray-matter";import{env as u}from"../config";import{createFsSource as m,discoverSections as f}from"./content-source.js";let p=[t(),r()];async function g(){let t=await f(u.CONTENT_DIR),r=Object.fromEntries(await Promise.all(t.map(async t=>{let r=e({source:await m(n(u.CONTENT_DIR,t)),baseUrl:`/${t}`,i18n:o,plugins:p});return[t,r]}))),i=a("simple",{indexes:await Promise.all(Object.entries(r).flatMap(([,e])=>e.getLanguages().flatMap(({language:e,pages:t})=>t.map(async t=>{let{content:r}=c(await l(t.data.filePath,"utf-8"));return{id:t.url,url:t.url,locale:e,title:t.data.title,content:r}}))))});return{sections:r,searchServer:i}}let d=null;export function getSources(){return d||(d=g(),"development"===process.env.NODE_ENV&&d.then(()=>{i(u.CONTENT_DIR)&&s(u.CONTENT_DIR,{recursive:!0},()=>{d=null})})),d}export async function getSections(){let{sections:e}=await getSources();return e}export async function getAllPages(){return Object.values(await getSections()).flatMap(e=>e.getPages())}export async function getUnifiedPageTree(e){let t=await getSections(),r=[];for(let a of Object.values(t)){let t=a.getPageTree(e);0!==t.children.length&&r.push({type:"folder",name:t.name,children:t.children})}return{name:"",children:r}}export async function getNavLinks(e){let t=Object.entries(await getSections()).map(([t,r])=>({text:r.getPageTree(e).name??t,url:`/${e}/${t}`,active:"nested-url"})),{env:r}=await import("../config");if(r.NEXT_PUBLIC_UPSTREAM_SOURCES.length>0){let{localeConfig:r,defaultLocale:a}=await import("../locale.config"),o=r[e]?.translations??r[a].translations;t.push({text:o.upstream,url:`/${e}/upstream`,active:"nested-url"})}return t}export async function getLLMText(e){let{content:t}=c(await l(e.data.filePath,"utf-8"));return`# ${e.data.title}
2
2
 
3
3
  ${t}`}
@@ -1 +1 @@
1
- import{env as e}from"./config";let a=e.NEXT_PUBLIC_SITE_NAME;export const localeConfig={en:{displayName:"English",dir:"ltr",siteName:a,siteDescription:"A docs starter built with Fumadocs, TanStack Start, and Thmanyah fonts — i18n, RTL, local search, and more.",translations:{search:"Search documentation...",searchNoResult:"No results found",toc:"On this page",tocNoHeadings:"No headings found",lastUpdate:"Last updated",chooseLanguage:"Choose language",nextPage:"Next",previousPage:"Previous",chooseTheme:"Theme",editOnGithub:"Edit on GitHub",copyMarkdown:"Copy Markdown",copyCode:"Copy",copied:"Copied",openMenu:"Open",openInGithub:"Open in GitHub",viewAsMarkdown:"View as Markdown",openInScira:"Open in Scira AI",openInChatGPT:"Open in ChatGPT",openInClaude:"Open in Claude",openInCursor:"Open in Cursor",toggleTheme:"Toggle theme",themeLight:"Light",themeDark:"Dark",themeSystem:"System",openSearch:"Open search",openSidebar:"Open sidebar",collapseSidebar:"Collapse sidebar",switchLanguage:"Switch language",toggleMenu:"Toggle menu",notFoundTitle:"Page not found",notFoundDescription:"The page you're looking for doesn't exist or has been moved.",notFoundBack:"Back to home",feedbackQuestion:"How is this page?",feedbackLabel:"Feedback",feedbackGood:"Good",feedbackBad:"Bad",feedbackPlaceholder:"Leave your feedback...",feedbackSubmit:"Submit",feedbackThankYou:"Thank you for your feedback!",feedbackViewOnGitHub:"View on GitHub",feedbackSubmitAgain:"Submit Again",changelog:"Changelog",changelogTitle:"What's new?",changelogDescription:"Latest updates and changes to this project.",changelogReadMore:"Read more →",docs:"Docs",dateLocale:"en-US",aiChat:"AI Chat",aiChatDisclaimer:"AI can be inaccurate, please verify the answers.",aiChatPlaceholder:"Ask a question",aiChatAnswering:"AI is answering...",aiChatAbort:"Abort Answer",aiChatRetry:"Retry",aiChatClear:"Clear Chat",aiChatEmpty:"Start a new chat below.",aiChatTrigger:"Ask AI",aiChatRoleUser:"you",aiChatRoleAssistant:"assistant",aiChatCopy:"Copy",aiChatCopied:"Copied!",aiChatSources:"Sources",aiChatSearching:"Searching…",aiChatStarters:["What features does this docs starter include?","How does search work?","How do I add a new language?"],aiChatApiKeyTitle:"Enter your Anthropic API key",aiChatApiKeyDescription:"Your key is stored in your browser and never sent to our servers.",aiChatApiKeyPlaceholder:"sk-ant-...",aiChatApiKeySave:"Start chatting",aiChatApiKeyChange:"Change API key",aiChatModelLabel:"Model",aiChatThinking:"Thinking",aiChatPages:"Pages",aiChatBrowsingPages:"Browsing pages…",aiChatSearchFailed:"Search failed",aiChatPageLoadFailed:"Failed to load page"}},ar:{displayName:"العربية",dir:"rtl",siteName:a,siteDescription:"قالب توثيق مبني بـ Fumadocs وTanStack Start وخطوط ثمانية — مع دعم i18n والعربية والبحث المحلي.",translations:{search:"ابحث في التوثيق...",searchNoResult:"لا توجد نتائج",toc:"في هذه الصفحة",tocNoHeadings:"لا توجد عناوين",lastUpdate:"آخر تحديث",chooseLanguage:"اختر اللغة",nextPage:"التالي",previousPage:"السابق",chooseTheme:"المظهر",editOnGithub:"عدّل على GitHub",copyMarkdown:"نسخ Markdown",copyCode:"نسخ",copied:"تم النسخ",openMenu:"فتح",openInGithub:"فتح في GitHub",viewAsMarkdown:"عرض كـ Markdown",openInScira:"فتح في Scira AI",openInChatGPT:"فتح في ChatGPT",openInClaude:"فتح في Claude",openInCursor:"فتح في Cursor",toggleTheme:"تبديل المظهر",themeLight:"فاتح",themeDark:"داكن",themeSystem:"النظام",openSearch:"فتح البحث",openSidebar:"فتح الشريط الجانبي",collapseSidebar:"طي الشريط الجانبي",switchLanguage:"تغيير اللغة",toggleMenu:"فتح القائمة",notFoundTitle:"الصفحة غير موجودة",notFoundDescription:"الصفحة التي تبحث عنها غير موجودة أو تم نقلها.",notFoundBack:"العودة إلى الرئيسية",feedbackQuestion:"ما رأيك في هذه الصفحة؟",feedbackLabel:"ملاحظة",feedbackGood:"جيدة",feedbackBad:"تحتاج تحسين",feedbackPlaceholder:"اكتب ملاحظاتك...",feedbackSubmit:"إرسال",feedbackThankYou:"شكراً على ملاحظاتك!",feedbackViewOnGitHub:"عرض على GitHub",feedbackSubmitAgain:"إرسال مجدداً",changelog:"سجل التغييرات",changelogTitle:"ما الجديد؟",changelogDescription:"أحدث التحديثات والتغييرات في هذا المشروع.",changelogReadMore:"قراءة التفاصيل ←",docs:"التوثيق",dateLocale:"ar-SA",aiChat:"محادثة الذكاء الاصطناعي",aiChatDisclaimer:"قد يكون الذكاء الاصطناعي غير دقيق، يرجى التحقق من الإجابات.",aiChatPlaceholder:"اطرح سؤالاً",aiChatAnswering:"الذكاء الاصطناعي يجيب...",aiChatAbort:"إيقاف الإجابة",aiChatRetry:"إعادة المحاولة",aiChatClear:"مسح المحادثة",aiChatEmpty:"ابدأ محادثة جديدة أدناه.",aiChatTrigger:"إسأل الذكالي",aiChatRoleUser:"أنت",aiChatRoleAssistant:"المساعد",aiChatCopy:"نسخ",aiChatCopied:"تم النسخ!",aiChatSources:"المصادر",aiChatSearching:"جارٍ البحث...",aiChatStarters:["ما المميزات التي يتضمنها هذا القالب؟","كيف يعمل البحث؟","كيف أضيف لغة جديدة؟"],aiChatApiKeyTitle:"أدخل مفتاح Anthropic API",aiChatApiKeyDescription:"يُحفظ مفتاحك في متصفحك ولا يُرسل إلى خوادمنا.",aiChatApiKeyPlaceholder:"sk-ant-...",aiChatApiKeySave:"ابدأ المحادثة",aiChatApiKeyChange:"تغيير مفتاح API",aiChatModelLabel:"النموذج",aiChatThinking:"التفكير",aiChatPages:"الصفحات",aiChatBrowsingPages:"جارٍ تصفح الصفحات…",aiChatSearchFailed:"فشل البحث",aiChatPageLoadFailed:"تعذّر تحميل الصفحة"}}};export const defaultLocale="en";export const locales=Object.keys(localeConfig);
1
+ import{env as e}from"./config";let a=e.NEXT_PUBLIC_SITE_NAME;export const localeConfig={en:{displayName:"English",dir:"ltr",siteName:a,siteDescription:"A docs starter built with Fumadocs, TanStack Start, and Thmanyah fonts — i18n, RTL, local search, and more.",translations:{search:"Search documentation...",searchNoResult:"No results found",toc:"On this page",tocNoHeadings:"No headings found",lastUpdate:"Last updated",chooseLanguage:"Choose language",nextPage:"Next",previousPage:"Previous",chooseTheme:"Theme",editOnGithub:"Edit on GitHub",copyMarkdown:"Copy Markdown",copyCode:"Copy",copied:"Copied",openMenu:"Open",openInGithub:"Open in GitHub",viewAsMarkdown:"View as Markdown",openInScira:"Open in Scira AI",openInChatGPT:"Open in ChatGPT",openInClaude:"Open in Claude",openInCursor:"Open in Cursor",toggleTheme:"Toggle theme",themeLight:"Light",themeDark:"Dark",themeSystem:"System",openSearch:"Open search",openSidebar:"Open sidebar",collapseSidebar:"Collapse sidebar",switchLanguage:"Switch language",toggleMenu:"Toggle menu",notFoundTitle:"Page not found",notFoundDescription:"The page you're looking for doesn't exist or has been moved.",notFoundBack:"Back to home",feedbackQuestion:"How is this page?",feedbackLabel:"Feedback",feedbackGood:"Good",feedbackBad:"Bad",feedbackPlaceholder:"Leave your feedback...",feedbackSubmit:"Submit",feedbackThankYou:"Thank you for your feedback!",feedbackViewOnGitHub:"View on GitHub",feedbackSubmitAgain:"Submit Again",changelog:"Changelog",changelogTitle:"What's new?",changelogDescription:"Latest updates and changes to this project.",changelogReadMore:"Read more →",docs:"Docs",dateLocale:"en-US",aiChat:"AI Chat",aiChatDisclaimer:"AI can be inaccurate, please verify the answers.",aiChatPlaceholder:"Ask a question",aiChatAnswering:"AI is answering...",aiChatAbort:"Abort Answer",aiChatRetry:"Retry",aiChatClear:"Clear Chat",aiChatEmpty:"Start a new chat below.",aiChatTrigger:"Ask AI",aiChatRoleUser:"you",aiChatRoleAssistant:"assistant",aiChatCopy:"Copy",aiChatCopied:"Copied!",aiChatSources:"Sources",aiChatSearching:"Searching…",aiChatStarters:["What features does this docs starter include?","How does search work?","How do I add a new language?"],aiChatApiKeyTitle:"Enter your Anthropic API key",aiChatApiKeyDescription:"Your key is stored in your browser and never sent to our servers.",aiChatApiKeyPlaceholder:"sk-ant-...",aiChatApiKeySave:"Start chatting",aiChatApiKeyChange:"Change API key",aiChatModelLabel:"Model",aiChatThinking:"Thinking",aiChatPages:"Pages",aiChatBrowsingPages:"Browsing pages…",aiChatSearchFailed:"Search failed",aiChatPageLoadFailed:"Failed to load page",upstream:"Upstream",upstreamEmpty:"No items found.",upstreamCorsHint:'This feed couldn\'t be loaded due to CORS restrictions. Try a browser extension like "CORS Unblock" to enable cross-origin requests.',upstreamError:"Failed to load"}},ar:{displayName:"العربية",dir:"rtl",siteName:a,siteDescription:"قالب توثيق مبني بـ Fumadocs وTanStack Start وخطوط ثمانية — مع دعم i18n والعربية والبحث المحلي.",translations:{search:"ابحث في التوثيق...",searchNoResult:"لا توجد نتائج",toc:"في هذه الصفحة",tocNoHeadings:"لا توجد عناوين",lastUpdate:"آخر تحديث",chooseLanguage:"اختر اللغة",nextPage:"التالي",previousPage:"السابق",chooseTheme:"المظهر",editOnGithub:"عدّل على GitHub",copyMarkdown:"نسخ Markdown",copyCode:"نسخ",copied:"تم النسخ",openMenu:"فتح",openInGithub:"فتح في GitHub",viewAsMarkdown:"عرض كـ Markdown",openInScira:"فتح في Scira AI",openInChatGPT:"فتح في ChatGPT",openInClaude:"فتح في Claude",openInCursor:"فتح في Cursor",toggleTheme:"تبديل المظهر",themeLight:"فاتح",themeDark:"داكن",themeSystem:"النظام",openSearch:"فتح البحث",openSidebar:"فتح الشريط الجانبي",collapseSidebar:"طي الشريط الجانبي",switchLanguage:"تغيير اللغة",toggleMenu:"فتح القائمة",notFoundTitle:"الصفحة غير موجودة",notFoundDescription:"الصفحة التي تبحث عنها غير موجودة أو تم نقلها.",notFoundBack:"العودة إلى الرئيسية",feedbackQuestion:"ما رأيك في هذه الصفحة؟",feedbackLabel:"ملاحظة",feedbackGood:"جيدة",feedbackBad:"تحتاج تحسين",feedbackPlaceholder:"اكتب ملاحظاتك...",feedbackSubmit:"إرسال",feedbackThankYou:"شكراً على ملاحظاتك!",feedbackViewOnGitHub:"عرض على GitHub",feedbackSubmitAgain:"إرسال مجدداً",changelog:"سجل التغييرات",changelogTitle:"ما الجديد؟",changelogDescription:"أحدث التحديثات والتغييرات في هذا المشروع.",changelogReadMore:"قراءة التفاصيل ←",docs:"التوثيق",dateLocale:"ar-SA",aiChat:"محادثة الذكاء الاصطناعي",aiChatDisclaimer:"قد يكون الذكاء الاصطناعي غير دقيق، يرجى التحقق من الإجابات.",aiChatPlaceholder:"اطرح سؤالاً",aiChatAnswering:"الذكاء الاصطناعي يجيب...",aiChatAbort:"إيقاف الإجابة",aiChatRetry:"إعادة المحاولة",aiChatClear:"مسح المحادثة",aiChatEmpty:"ابدأ محادثة جديدة أدناه.",aiChatTrigger:"إسأل الذكالي",aiChatRoleUser:"أنت",aiChatRoleAssistant:"المساعد",aiChatCopy:"نسخ",aiChatCopied:"تم النسخ!",aiChatSources:"المصادر",aiChatSearching:"جارٍ البحث...",aiChatStarters:["ما المميزات التي يتضمنها هذا القالب؟","كيف يعمل البحث؟","كيف أضيف لغة جديدة؟"],aiChatApiKeyTitle:"أدخل مفتاح Anthropic API",aiChatApiKeyDescription:"يُحفظ مفتاحك في متصفحك ولا يُرسل إلى خوادمنا.",aiChatApiKeyPlaceholder:"sk-ant-...",aiChatApiKeySave:"ابدأ المحادثة",aiChatApiKeyChange:"تغيير مفتاح API",aiChatModelLabel:"النموذج",aiChatThinking:"التفكير",aiChatPages:"الصفحات",aiChatBrowsingPages:"جارٍ تصفح الصفحات…",aiChatSearchFailed:"فشل البحث",aiChatPageLoadFailed:"تعذّر تحميل الصفحة",upstream:"المصادر",upstreamEmpty:"لا توجد عناصر.",upstreamCorsHint:'تعذّر تحميل هذا المصدر بسبب قيود CORS. جرّب إضافة متصفح مثل "CORS Unblock" لتفعيل الطلبات عبر النطاقات.',upstreamError:"فشل التحميل"}}};export const defaultLocale="en";export const locales=Object.keys(localeConfig);
@@ -1,2 +0,0 @@
1
- "use client";
2
- import{jsx as i}from"react/jsx-runtime";import{createElement as t}from"react";import{AnimatePresence as e,motion as r}from"motion/react";import{usePathname as a}from"next/navigation";import{locales as o}from"../locale.config";import{env as n}from"../config";let m=RegExp(`^/(${o.join("|")})(/|$)`),l={duration:.3,ease:"easeOut"},p={initial:{filter:"blur(8px)",opacity:.2},animate:{filter:"blur(0px)",opacity:1},exit:{filter:"blur(8px)",opacity:.2}};export function Transition({animationKey:o,children:c,...f}){let x=a(),s=o??(x.replace(m,"/")||"/");return n.NEXT_PUBLIC_ANIMATIONS?i(e,{mode:"wait",children:t(r.div,{...f,key:s,variants:p,initial:"initial",animate:"animate",exit:"exit",transition:l},c)}):i("div",{...f,children:c})}