@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 +75 -7
- package/package.json +1 -1
- package/starter/app/api/auth/callback/route.js +1 -0
- package/starter/app/api/auth/login/route.js +1 -0
- package/starter/app/api/auth/logout/route.js +1 -0
- package/starter/app/login/page.jsx +1 -0
- package/starter/package.json +1 -1
- package/starter/proxy.js +1 -0
- package/starter/src/config.js +1 -1
- package/starter/src/features/auth/check.js +1 -0
- package/starter/src/features/auth/github.js +1 -0
- package/starter/src/features/auth/index.js +1 -0
- package/starter/src/features/auth/jwt.js +1 -0
- package/starter/src/features/auth/session.js +1 -0
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
@@ -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"})})}
|
package/starter/package.json
CHANGED
package/starter/proxy.js
ADDED
|
@@ -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)$).*)"]};
|
package/starter/src/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createEnv as e}from"@t3-oss/env-nextjs";import{z as
|
|
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)}
|