@ahmedrowaihi/8n 6.0.30 → 6.0.32

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
@@ -1736,6 +1736,24 @@ const $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
1736
1736
  return payload;
1737
1737
  };
1738
1738
  });
1739
+ const $ZodLiteral = /* @__PURE__ */ $constructor("$ZodLiteral", (inst, def) => {
1740
+ $ZodType.init(inst, def);
1741
+ if (def.values.length === 0) throw new Error("Cannot create literal schema with no valid values");
1742
+ const values = new Set(def.values);
1743
+ inst._zod.values = values;
1744
+ inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex(o) : o ? escapeRegex(o.toString()) : String(o)).join("|")})$`);
1745
+ inst._zod.parse = (payload, _ctx) => {
1746
+ const input = payload.value;
1747
+ if (values.has(input)) return payload;
1748
+ payload.issues.push({
1749
+ code: "invalid_value",
1750
+ values: def.values,
1751
+ input,
1752
+ inst
1753
+ });
1754
+ return payload;
1755
+ };
1756
+ });
1739
1757
  const $ZodTransform = /* @__PURE__ */ $constructor("$ZodTransform", (inst, def) => {
1740
1758
  $ZodType.init(inst, def);
1741
1759
  inst._zod.parse = (payload, ctx) => {
@@ -2801,6 +2819,27 @@ const enumProcessor = (schema, _ctx, json, _params) => {
2801
2819
  if (values.every((v) => typeof v === "string")) json.type = "string";
2802
2820
  json.enum = values;
2803
2821
  };
2822
+ const literalProcessor = (schema, ctx, json, _params) => {
2823
+ const def = schema._zod.def;
2824
+ const vals = [];
2825
+ for (const val of def.values) if (val === void 0) {
2826
+ if (ctx.unrepresentable === "throw") throw new Error("Literal `undefined` cannot be represented in JSON Schema");
2827
+ } else if (typeof val === "bigint") if (ctx.unrepresentable === "throw") throw new Error("BigInt literals cannot be represented in JSON Schema");
2828
+ else vals.push(Number(val));
2829
+ else vals.push(val);
2830
+ if (vals.length === 0) {} else if (vals.length === 1) {
2831
+ const val = vals[0];
2832
+ json.type = val === null ? "null" : typeof val;
2833
+ if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") json.enum = [val];
2834
+ else json.const = val;
2835
+ } else {
2836
+ if (vals.every((v) => typeof v === "number")) json.type = "number";
2837
+ if (vals.every((v) => typeof v === "string")) json.type = "string";
2838
+ if (vals.every((v) => typeof v === "boolean")) json.type = "boolean";
2839
+ if (vals.every((v) => v === null)) json.type = "null";
2840
+ json.enum = vals;
2841
+ }
2842
+ };
2804
2843
  const customProcessor = (_schema, ctx, _json, _params) => {
2805
2844
  if (ctx.unrepresentable === "throw") throw new Error("Custom types cannot be represented in JSON Schema");
2806
2845
  };
@@ -3428,6 +3467,23 @@ function _enum(values, params) {
3428
3467
  ...normalizeParams(params)
3429
3468
  });
3430
3469
  }
3470
+ const ZodLiteral = /* @__PURE__ */ $constructor("ZodLiteral", (inst, def) => {
3471
+ $ZodLiteral.init(inst, def);
3472
+ ZodType.init(inst, def);
3473
+ inst._zod.processJSONSchema = (ctx, json, params) => literalProcessor(inst, ctx, json, params);
3474
+ inst.values = new Set(def.values);
3475
+ Object.defineProperty(inst, "value", { get() {
3476
+ if (def.values.length > 1) throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");
3477
+ return def.values[0];
3478
+ } });
3479
+ });
3480
+ function literal(value, params) {
3481
+ return new ZodLiteral({
3482
+ type: "literal",
3483
+ values: Array.isArray(value) ? value : [value],
3484
+ ...normalizeParams(params)
3485
+ });
3486
+ }
3431
3487
  const ZodTransform = /* @__PURE__ */ $constructor("ZodTransform", (inst, def) => {
3432
3488
  $ZodTransform.init(inst, def);
3433
3489
  ZodType.init(inst, def);
@@ -3608,7 +3664,13 @@ const configSchema = object({
3608
3664
  url: string()
3609
3665
  })).default([]) }).default({ links: [] }),
3610
3666
  animations: boolean().default(true),
3611
- basePath: string().optional()
3667
+ basePath: string().optional(),
3668
+ auth: object({
3669
+ provider: literal("github"),
3670
+ repo: string().optional(),
3671
+ protect: union([boolean(), array(string())]).default(true),
3672
+ sessionDuration: string().default("7d")
3673
+ }).optional()
3612
3674
  });
3613
3675
  async function resolveConfig() {
3614
3676
  const { config } = await loadConfig({
@@ -3674,7 +3736,7 @@ async function checkSelfUpdate() {
3674
3736
  });
3675
3737
  if (!res.ok) return;
3676
3738
  const { version: latest } = await res.json();
3677
- const current = "6.0.30";
3739
+ const current = "6.0.32";
3678
3740
  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"));
3679
3741
  } catch {}
3680
3742
  }
@@ -3742,12 +3804,18 @@ function buildEnv({ config, contentDir, staticExport = false }) {
3742
3804
  CONTENT_DIR: contentDir,
3743
3805
  LOCALES: (config.locales ?? ["en"]).join(","),
3744
3806
  NEXT_PUBLIC_SITE_NAME: config.siteName ?? "Docs",
3745
- NEXT_PUBLIC_GITHUB_REPO: config.github?.repo ?? ghPagesUrl,
3807
+ NEXT_PUBLIC_GITHUB_REPO: config.github?.repo ?? process.env.NEXT_PUBLIC_GITHUB_REPO ?? ghPagesUrl,
3746
3808
  SECTIONS: JSON.stringify(config.sections ?? {}),
3747
3809
  NEXT_PUBLIC_NAV_LINKS: JSON.stringify(config.nav?.links ?? []),
3748
3810
  NEXT_PUBLIC_ANIMATIONS: config.animations === false ? "false" : "true",
3749
3811
  NEXT_BASE_PATH: config.basePath ?? ghPagesBasePath ?? "",
3750
- NEXT_STATIC_EXPORT: staticExport ? "true" : "false"
3812
+ NEXT_STATIC_EXPORT: staticExport ? "true" : "false",
3813
+ ...config.auth ? {
3814
+ AUTH_ENABLED: "true",
3815
+ AUTH_REPO: config.auth.repo ?? config.github?.repo ?? ghPagesUrl,
3816
+ AUTH_PROTECT: JSON.stringify(config.auth.protect),
3817
+ AUTH_SESSION_DURATION: config.auth.sessionDuration
3818
+ } : {}
3751
3819
  };
3752
3820
  }
3753
3821
  async function runNextFlat(projectDir, cmd, env) {
@@ -3778,7 +3846,7 @@ async function dev() {
3778
3846
  async function build({ server = false } = {}) {
3779
3847
  const { config, contentDir } = await resolveProject();
3780
3848
  const projectDir = process.cwd();
3781
- console.log(pc.cyan("8n") + pc.dim(` v6.0.30 build → ${contentDir}`));
3849
+ console.log(pc.cyan("8n") + pc.dim(` v6.0.32 build → ${contentDir}`));
3782
3850
  if (server) await runNextFlat(projectDir, "build", buildEnv({
3783
3851
  config,
3784
3852
  contentDir,
@@ -4096,7 +4164,7 @@ async function mcp() {
4096
4164
  const mcpDir = join(getStarterDir(), "content", "mcp", "en");
4097
4165
  const server = new McpServer({
4098
4166
  name: "8n",
4099
- version: "6.0.30"
4167
+ version: "6.0.32"
4100
4168
  });
4101
4169
  server.registerTool("read_me", {
4102
4170
  description: "Returns how to use the 8n MCP tools. Call this BEFORE documenting anything with 8n.",
@@ -4237,7 +4305,7 @@ Example: get_component({ name: "components" }) returns all available MDX compone
4237
4305
 
4238
4306
  //#endregion
4239
4307
  //#region src/index.ts
4240
- const program = new Command().name("8n").description("Run your 8n docs site").version("6.0.30").addOption(new Option("--debug").hideHelp()).hook("preAction", (cmd) => {
4308
+ const program = new Command().name("8n").description("Run your 8n docs site").version("6.0.32").addOption(new Option("--debug").hideHelp()).hook("preAction", (cmd) => {
4241
4309
  if (cmd.opts().debug) process.env.DEBUG_8N = "1";
4242
4310
  });
4243
4311
  program.command("init").description("Scaffold a new docs project in the current directory").action(init);
package/package.json CHANGED
@@ -30,5 +30,5 @@
30
30
  "typescript": "^5.9.3",
31
31
  "zod": "^4.3.6"
32
32
  },
33
- "version": "6.0.30"
33
+ "version": "6.0.32"
34
34
  }
@@ -0,0 +1 @@
1
+ import{redirect as t}from"next/navigation";import{exchangeCode as r,getGitHubUser as a,hasRepoAccess as e,parseState as i,setSession as o}from"../../../../src/features/auth";import{env as n}from"../../../../src/config";export async function GET(s){if(!n.AUTH_ENABLED)return new Response("Auth not enabled",{status:404});let c=new URL(s.url),g=c.searchParams.get("code"),{returnTo:l}=i(c.searchParams.get("state")??"");g||t("/login?error=missing_code");try{let i=await r(g),s=await a(i);n.AUTH_REPO&&(await e(i,n.AUTH_REPO)||t("/login?error=access_denied")),await o({sub:String(s.id),login:s.login})}catch{t("/login?error=auth_failed")}t(l.startsWith("/")?l:"/")}
@@ -0,0 +1 @@
1
+ import{redirect as r}from"next/navigation";import{buildAuthorizationUrl as t}from"../../../../src/features/auth";import{env as e}from"../../../../src/config";export function GET(n){if(!e.AUTH_ENABLED)return new Response("Auth not enabled",{status:404});r(t(new URL(n.url).searchParams.get("returnTo")??"/"))}
@@ -0,0 +1 @@
1
+ import{redirect as t}from"next/navigation";import{clearSession as n}from"../../../../src/features/auth";import{env as o}from"../../../../src/config";export async function GET(){if(!o.AUTH_ENABLED)return new Response("Auth not enabled",{status:404});await n(),t("/login")}
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import{env as n}from"../../src/config";let i={access_denied:"Your GitHub account does not have access to this documentation.",auth_failed:"Authentication failed. Please try again.",missing_code:"Invalid OAuth response. Please try again."};export default function r({searchParams:t}){return e(a,{searchParamsPromise:t})}async function a({searchParamsPromise:r}){let{returnTo:s="/",error:o}=await r,d=`/api/auth/login?returnTo=${encodeURIComponent(s)}`,l=n.NEXT_PUBLIC_SITE_NAME,u=o?i[o]??"Something went wrong.":null;return e("div",{className:"flex min-h-screen flex-col items-center justify-center bg-background px-6",children:t("div",{className:"flex w-full max-w-sm flex-col gap-6",children:[t("div",{className:"text-center",children:[e("h1",{className:"text-2xl font-bold tracking-tight",children:l}),e("p",{className:"mt-1 text-sm text-muted-foreground",children:"Sign in to access the documentation."})]}),u&&e("p",{className:"rounded-md border border-destructive/30 bg-destructive/10 px-4 py-3 text-sm text-destructive",children:u}),t("a",{href:d,className:"flex items-center justify-center gap-2 rounded-lg bg-primary px-4 py-2.5 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90",children:[e(c,{}),"Continue with GitHub"]})]})})}function c(){return e("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":"true",children:e("path",{d:"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"})})}
@@ -106,5 +106,5 @@
106
106
  "tsx": "^4.21.0",
107
107
  "typescript": "^5.9.3"
108
108
  },
109
- "version": "6.0.30"
109
+ "version": "6.0.32"
110
110
  }
@@ -0,0 +1 @@
1
+ import{NextResponse as e}from"next/server";import{checkAuth as t}from"./src/features/auth";export async function proxy(r){let n=await t(r.nextUrl.pathname,r.cookies.get("8n_session")?.value);return n?e.redirect(new URL(n.redirectTo,r.url)):e.next()}export const config={matcher:["/((?!_next/static|_next/image|favicon\\.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)"]};
@@ -1 +1 @@
1
- import{createEnv as e}from"@t3-oss/env-nextjs";import{z as _}from"zod";let s=_.string().default("[]").transform(e=>JSON.parse(e)),t=_.string().default("{}").transform(e=>JSON.parse(e));export const env=e({server:{SITE_URL:_.string().default("http://localhost:3000"),CONTENT_DIR:_.string().default("./content"),SECTIONS:t},client:{NEXT_PUBLIC_SITE_NAME:_.string().default("Docs"),NEXT_PUBLIC_GITHUB_REPO:_.string().optional(),NEXT_PUBLIC_NAV_LINKS:s,NEXT_PUBLIC_ANIMATIONS:_.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,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 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.");
@@ -0,0 +1 @@
1
+ import{env as t}from"../../config";import{verifyJWT as o}from"./jwt";let e=["/api/auth/","/login"];export async function checkAuth(n,r){if(!t.AUTH_ENABLED||!t.AUTH_SECRET||e.some(t=>n.startsWith(t)))return null;let i=JSON.parse(t.AUTH_PROTECT);return("boolean"==typeof i?i:i.some(t=>n.startsWith(t)))?r&&await o(r,t.AUTH_SECRET)?null:{redirectTo:`/login?returnTo=${encodeURIComponent(n)}`}:null}
@@ -0,0 +1 @@
1
+ import{env as t}from"../../config";export function buildAuthorizationUrl(e){let r=btoa(JSON.stringify({returnTo:e})).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_"),o=new URLSearchParams({client_id:t.GITHUB_CLIENT_ID,scope:"read:user",state:r});return`https://github.com/login/oauth/authorize?${o}`}export function parseState(t){try{let e=t.replace(/-/g,"+").replace(/_/g,"/"),r=e.length%4;return JSON.parse(atob(r?e+"=".repeat(4-r):e))}catch{return{returnTo:"/"}}}export async function exchangeCode(e){let r=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({client_id:t.GITHUB_CLIENT_ID,client_secret:t.GITHUB_CLIENT_SECRET,code:e})}),o=await r.json();if(!o.access_token)throw Error(o.error??"token exchange failed");return o.access_token}export async function getGitHubUser(t){let e=await fetch("https://api.github.com/user",{headers:{Authorization:`Bearer ${t}`,Accept:"application/vnd.github+json"}});if(!e.ok)throw Error("failed to fetch GitHub user");return e.json()}export async function hasRepoAccess(t,e){return(await fetch(`https://api.github.com/repos/${e}`,{headers:{Authorization:`Bearer ${t}`,Accept:"application/vnd.github+json"}})).ok}
@@ -0,0 +1 @@
1
+ export{getSession,setSession,clearSession,parseDuration}from"./session";export{buildAuthorizationUrl,parseState,exchangeCode,getGitHubUser,hasRepoAccess}from"./github.js";export{checkAuth}from"./check.js";
@@ -0,0 +1 @@
1
+ let e=new TextEncoder;function t(e){let t="",n=new Uint8Array(e);for(let e=0;e<n.length;e++)t+=String.fromCharCode(n[e]);return btoa(t).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function n(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),n=t.length%4,r=atob(n?t+"=".repeat(4-n):t),l=new Uint8Array(r.length);for(let e=0;e<r.length;e++)l[e]=r.charCodeAt(e);return l}async function r(t){return crypto.subtle.importKey("raw",e.encode(t),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"])}export async function signJWT(n,l){let a=t(e.encode(JSON.stringify({alg:"HS256",typ:"JWT"}))),c=t(e.encode(JSON.stringify(n))),i=await r(l),o=await crypto.subtle.sign("HMAC",i,e.encode(`${a}.${c}`));return`${a}.${c}.${t(o)}`}export async function verifyJWT(t,l){let a=t.split(".");if(3!==a.length)return null;let[c,i,o]=a;try{let t=await r(l);if(!await crypto.subtle.verify("HMAC",t,n(o),e.encode(`${c}.${i}`)))return null;let a=JSON.parse(new TextDecoder().decode(n(i)));if(a.exp<Date.now()/1e3)return null;return a}catch{return null}}
@@ -0,0 +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)}