@silicajs/next 0.1.1 → 0.1.2
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/google-sign-in-button.d.ts +10 -0
- package/dist/google-sign-in-button.js +48 -0
- package/dist/google-sign-in-button.js.map +1 -0
- package/dist/proxy.d.ts +2 -1
- package/dist/proxy.js +19 -4
- package/dist/proxy.js.map +1 -1
- package/dist/routes/layout.d.ts +1 -0
- package/dist/routes/layout.js +1 -0
- package/dist/routes/layout.js.map +1 -1
- package/dist/routes/not-allowed.js +1 -1
- package/dist/routes/not-allowed.js.map +1 -1
- package/dist/routes/page.js +2 -1
- package/dist/routes/page.js.map +1 -1
- package/dist/routes/sign-in.js +17 -17
- package/dist/routes/sign-in.js.map +1 -1
- package/dist/template-files/generated-app/app/{[[...slug]] → (site)/[[...slug]]}/page.tsx +1 -1
- package/dist/template-files/generated-app/app/(site)/layout.tsx +12 -0
- package/dist/template-files/generated-app/app/layout.tsx +3 -3
- package/dist/template-files/package.json +0 -4
- package/dist/template-files/silica-theme.ts +2 -1
- package/dist/templates.js +2 -1
- package/dist/templates.js.map +1 -1
- package/package.json +5 -5
- /package/dist/template-files/generated-app/app/{tags → (site)/tags}/[...tag]/page.tsx +0 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type GoogleSignInButtonProps = {
|
|
4
|
+
callbackURL?: string;
|
|
5
|
+
errorCallbackURL?: string;
|
|
6
|
+
};
|
|
7
|
+
declare function resolveCallbackURL(explicit?: string): string;
|
|
8
|
+
declare function GoogleSignInButton({ callbackURL, errorCallbackURL, }: GoogleSignInButtonProps): react_jsx_runtime.JSX.Element;
|
|
9
|
+
|
|
10
|
+
export { GoogleSignInButton, type GoogleSignInButtonProps, resolveCallbackURL };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { createAuthClient } from "better-auth/react";
|
|
4
|
+
import { GoogleIcon } from "@silicajs/components";
|
|
5
|
+
import { Button } from "@silicajs/ui/components/button";
|
|
6
|
+
const authClient = createAuthClient();
|
|
7
|
+
function resolveCallbackURL(explicit) {
|
|
8
|
+
if (isInternalCallbackPath(explicit)) return explicit;
|
|
9
|
+
if (typeof window === "undefined") return "/";
|
|
10
|
+
const fromQuery = new URLSearchParams(window.location.search).get(
|
|
11
|
+
"callbackUrl"
|
|
12
|
+
);
|
|
13
|
+
return isInternalCallbackPath(fromQuery) ? fromQuery : "/";
|
|
14
|
+
}
|
|
15
|
+
function isInternalCallbackPath(value) {
|
|
16
|
+
return Boolean(
|
|
17
|
+
value && value.startsWith("/") && !value.startsWith("//") && !value.includes("\\")
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
function GoogleSignInButton({
|
|
21
|
+
callbackURL,
|
|
22
|
+
errorCallbackURL = "/not-allowed"
|
|
23
|
+
}) {
|
|
24
|
+
return /* @__PURE__ */ jsxs(
|
|
25
|
+
Button,
|
|
26
|
+
{
|
|
27
|
+
type: "button",
|
|
28
|
+
variant: "outline",
|
|
29
|
+
className: "w-full",
|
|
30
|
+
onClick: () => {
|
|
31
|
+
void authClient.signIn.social({
|
|
32
|
+
provider: "google",
|
|
33
|
+
callbackURL: resolveCallbackURL(callbackURL),
|
|
34
|
+
errorCallbackURL
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
children: [
|
|
38
|
+
/* @__PURE__ */ jsx(GoogleIcon, { className: "size-4" }),
|
|
39
|
+
"Continue with Google"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
GoogleSignInButton,
|
|
46
|
+
resolveCallbackURL
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=google-sign-in-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/google-sign-in-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { createAuthClient } from \"better-auth/react\";\nimport { GoogleIcon } from \"@silicajs/components\";\nimport { Button } from \"@silicajs/ui/components/button\";\n\nconst authClient = createAuthClient();\n\nexport type GoogleSignInButtonProps = {\n callbackURL?: string;\n errorCallbackURL?: string;\n};\n\nexport function resolveCallbackURL(explicit?: string): string {\n if (isInternalCallbackPath(explicit)) return explicit;\n if (typeof window === \"undefined\") return \"/\";\n const fromQuery = new URLSearchParams(window.location.search).get(\n \"callbackUrl\",\n );\n return isInternalCallbackPath(fromQuery) ? fromQuery : \"/\";\n}\n\nfunction isInternalCallbackPath(value?: string | null): value is string {\n return Boolean(\n value &&\n value.startsWith(\"/\") &&\n !value.startsWith(\"//\") &&\n !value.includes(\"\\\\\"),\n );\n}\n\nexport function GoogleSignInButton({\n callbackURL,\n errorCallbackURL = \"/not-allowed\",\n}: GoogleSignInButtonProps) {\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"w-full\"\n onClick={() => {\n void authClient.signIn.social({\n provider: \"google\",\n callbackURL: resolveCallbackURL(callbackURL),\n errorCallbackURL,\n });\n }}\n >\n <GoogleIcon className=\"size-4\" />\n Continue with Google\n </Button>\n );\n}\n"],"mappings":";AAoCI,SAYE,KAZF;AAlCJ,SAAS,wBAAwB;AACjC,SAAS,kBAAkB;AAC3B,SAAS,cAAc;AAEvB,MAAM,aAAa,iBAAiB;AAO7B,SAAS,mBAAmB,UAA2B;AAC5D,MAAI,uBAAuB,QAAQ,EAAG,QAAO;AAC7C,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAAE;AAAA,IAC5D;AAAA,EACF;AACA,SAAO,uBAAuB,SAAS,IAAI,YAAY;AACzD;AAEA,SAAS,uBAAuB,OAAwC;AACtE,SAAO;AAAA,IACL,SACA,MAAM,WAAW,GAAG,KACpB,CAAC,MAAM,WAAW,IAAI,KACtB,CAAC,MAAM,SAAS,IAAI;AAAA,EACtB;AACF;AAEO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA,mBAAmB;AACrB,GAA4B;AAC1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,WAAU;AAAA,MACV,SAAS,MAAM;AACb,aAAK,WAAW,OAAO,OAAO;AAAA,UAC5B,UAAU;AAAA,UACV,aAAa,mBAAmB,WAAW;AAAA,UAC3C;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA;AAAA,4BAAC,cAAW,WAAU,UAAS;AAAA,QAAE;AAAA;AAAA;AAAA,EAEnC;AAEJ;","names":[]}
|
package/dist/proxy.d.ts
CHANGED
|
@@ -4,11 +4,12 @@ type SilicaProxyOptions = {
|
|
|
4
4
|
authEnabled?: boolean;
|
|
5
5
|
allowedDomains?: readonly string[];
|
|
6
6
|
allowedEmails?: readonly string[];
|
|
7
|
+
publicPaths?: readonly string[];
|
|
7
8
|
};
|
|
8
9
|
declare function silicaProxy(request: NextRequest, options?: SilicaProxyOptions): Promise<NextResponse<unknown>>;
|
|
9
10
|
declare const config: {
|
|
10
11
|
matcher: string[];
|
|
11
12
|
};
|
|
12
|
-
declare function isSilicaPublicPath(pathname: string): boolean;
|
|
13
|
+
declare function isSilicaPublicPath(pathname: string, publicPaths?: readonly string[]): boolean;
|
|
13
14
|
|
|
14
15
|
export { type SilicaProxyOptions, config, isSilicaPublicPath, silicaProxy };
|
package/dist/proxy.js
CHANGED
|
@@ -6,12 +6,20 @@ const PUBLIC_PREFIXES = [
|
|
|
6
6
|
"/api/silica/revalidate",
|
|
7
7
|
"/api/silica/dev-events"
|
|
8
8
|
];
|
|
9
|
-
const PUBLIC_PATHS = [
|
|
9
|
+
const PUBLIC_PATHS = [
|
|
10
|
+
"/sign-in",
|
|
11
|
+
"/not-allowed",
|
|
12
|
+
"/favicon.ico",
|
|
13
|
+
"/robots.txt",
|
|
14
|
+
"/sitemap.xml"
|
|
15
|
+
];
|
|
10
16
|
async function silicaProxy(request, options = {}) {
|
|
11
17
|
const { pathname } = request.nextUrl;
|
|
12
18
|
const authEnabled = options.authEnabled === true || process.env.SILICA_AUTH_ENABLED === "true";
|
|
13
19
|
if (!authEnabled) return NextResponse.next();
|
|
14
|
-
if (isSilicaPublicPath(pathname))
|
|
20
|
+
if (isSilicaPublicPath(pathname, options.publicPaths)) {
|
|
21
|
+
return NextResponse.next();
|
|
22
|
+
}
|
|
15
23
|
const allowedDomains = uniqueList([
|
|
16
24
|
...options.allowedDomains ?? [],
|
|
17
25
|
...parseList(process.env.SILICA_ALLOWED_DOMAINS)
|
|
@@ -37,8 +45,12 @@ async function silicaProxy(request, options = {}) {
|
|
|
37
45
|
const config = {
|
|
38
46
|
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"]
|
|
39
47
|
};
|
|
40
|
-
function isSilicaPublicPath(pathname) {
|
|
41
|
-
|
|
48
|
+
function isSilicaPublicPath(pathname, publicPaths = []) {
|
|
49
|
+
const allowedPublicPaths = /* @__PURE__ */ new Set([
|
|
50
|
+
...PUBLIC_PATHS,
|
|
51
|
+
...publicPaths.filter(isPublicPath)
|
|
52
|
+
]);
|
|
53
|
+
return allowedPublicPaths.has(pathname) || PUBLIC_PREFIXES.some(
|
|
42
54
|
(prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`)
|
|
43
55
|
);
|
|
44
56
|
}
|
|
@@ -48,6 +60,9 @@ function parseList(value) {
|
|
|
48
60
|
function uniqueList(values) {
|
|
49
61
|
return [...new Set(values.map((item) => item.trim()).filter(Boolean))];
|
|
50
62
|
}
|
|
63
|
+
function isPublicPath(pathname) {
|
|
64
|
+
return pathname.startsWith("/") && !pathname.startsWith("//");
|
|
65
|
+
}
|
|
51
66
|
export {
|
|
52
67
|
config,
|
|
53
68
|
isSilicaPublicPath,
|
package/dist/proxy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["import { NextRequest, NextResponse } from \"next/server\";\nimport { isSilicaRequestAllowed } from \"@silicajs/auth\";\n\nexport type SilicaProxyOptions = {\n authEnabled?: boolean;\n allowedDomains?: readonly string[];\n allowedEmails?: readonly string[];\n};\n\nconst PUBLIC_PREFIXES = [\n \"/_next\",\n \"/api/auth\",\n \"/api/silica/revalidate\",\n \"/api/silica/dev-events\",\n];\nconst PUBLIC_PATHS = [\"/sign-in\"
|
|
1
|
+
{"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["import { NextRequest, NextResponse } from \"next/server\";\nimport { isSilicaRequestAllowed } from \"@silicajs/auth\";\n\nexport type SilicaProxyOptions = {\n authEnabled?: boolean;\n allowedDomains?: readonly string[];\n allowedEmails?: readonly string[];\n publicPaths?: readonly string[];\n};\n\nconst PUBLIC_PREFIXES = [\n \"/_next\",\n \"/api/auth\",\n \"/api/silica/revalidate\",\n \"/api/silica/dev-events\",\n];\nconst PUBLIC_PATHS = [\n \"/sign-in\",\n \"/not-allowed\",\n \"/favicon.ico\",\n \"/robots.txt\",\n \"/sitemap.xml\",\n];\n\nexport async function silicaProxy(\n request: NextRequest,\n options: SilicaProxyOptions = {},\n) {\n const { pathname } = request.nextUrl;\n\n const authEnabled =\n options.authEnabled === true || process.env.SILICA_AUTH_ENABLED === \"true\";\n if (!authEnabled) return NextResponse.next();\n if (isSilicaPublicPath(pathname, options.publicPaths)) {\n return NextResponse.next();\n }\n\n const allowedDomains = uniqueList([\n ...(options.allowedDomains ?? []),\n ...parseList(process.env.SILICA_ALLOWED_DOMAINS),\n ]);\n const allowedEmails = uniqueList([\n ...(options.allowedEmails ?? []),\n ...parseList(process.env.SILICA_ALLOWED_EMAILS),\n ]);\n const secret = process.env.BETTER_AUTH_SECRET;\n const hasValidatedSession = secret\n ? await isSilicaRequestAllowed(request, {\n secret: process.env.BETTER_AUTH_SECRET,\n allowedDomains,\n allowedEmails,\n })\n : false;\n\n if (!hasValidatedSession) {\n const signInUrl = request.nextUrl.clone();\n signInUrl.pathname = \"/sign-in\";\n signInUrl.searchParams.set(\"callbackUrl\", request.nextUrl.pathname);\n return NextResponse.redirect(signInUrl);\n }\n\n return NextResponse.next();\n}\n\nexport const config = {\n matcher: [\"/((?!_next/static|_next/image|favicon.ico).*)\"],\n};\n\nexport function isSilicaPublicPath(\n pathname: string,\n publicPaths: readonly string[] = [],\n): boolean {\n const allowedPublicPaths = new Set([\n ...PUBLIC_PATHS,\n ...publicPaths.filter(isPublicPath),\n ]);\n\n return (\n allowedPublicPaths.has(pathname) ||\n PUBLIC_PREFIXES.some(\n (prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`),\n )\n );\n}\n\nfunction parseList(value: string | undefined): string[] {\n return value\n ? value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean)\n : [];\n}\n\nfunction uniqueList(values: readonly string[]): string[] {\n return [...new Set(values.map((item) => item.trim()).filter(Boolean))];\n}\n\nfunction isPublicPath(pathname: string): boolean {\n return pathname.startsWith(\"/\") && !pathname.startsWith(\"//\");\n}\n"],"mappings":"AAAA,SAAsB,oBAAoB;AAC1C,SAAS,8BAA8B;AASvC,MAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,MAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,eAAsB,YACpB,SACA,UAA8B,CAAC,GAC/B;AACA,QAAM,EAAE,SAAS,IAAI,QAAQ;AAE7B,QAAM,cACJ,QAAQ,gBAAgB,QAAQ,QAAQ,IAAI,wBAAwB;AACtE,MAAI,CAAC,YAAa,QAAO,aAAa,KAAK;AAC3C,MAAI,mBAAmB,UAAU,QAAQ,WAAW,GAAG;AACrD,WAAO,aAAa,KAAK;AAAA,EAC3B;AAEA,QAAM,iBAAiB,WAAW;AAAA,IAChC,GAAI,QAAQ,kBAAkB,CAAC;AAAA,IAC/B,GAAG,UAAU,QAAQ,IAAI,sBAAsB;AAAA,EACjD,CAAC;AACD,QAAM,gBAAgB,WAAW;AAAA,IAC/B,GAAI,QAAQ,iBAAiB,CAAC;AAAA,IAC9B,GAAG,UAAU,QAAQ,IAAI,qBAAqB;AAAA,EAChD,CAAC;AACD,QAAM,SAAS,QAAQ,IAAI;AAC3B,QAAM,sBAAsB,SACxB,MAAM,uBAAuB,SAAS;AAAA,IACpC,QAAQ,QAAQ,IAAI;AAAA,IACpB;AAAA,IACA;AAAA,EACF,CAAC,IACD;AAEJ,MAAI,CAAC,qBAAqB;AACxB,UAAM,YAAY,QAAQ,QAAQ,MAAM;AACxC,cAAU,WAAW;AACrB,cAAU,aAAa,IAAI,eAAe,QAAQ,QAAQ,QAAQ;AAClE,WAAO,aAAa,SAAS,SAAS;AAAA,EACxC;AAEA,SAAO,aAAa,KAAK;AAC3B;AAEO,MAAM,SAAS;AAAA,EACpB,SAAS,CAAC,+CAA+C;AAC3D;AAEO,SAAS,mBACd,UACA,cAAiC,CAAC,GACzB;AACT,QAAM,qBAAqB,oBAAI,IAAI;AAAA,IACjC,GAAG;AAAA,IACH,GAAG,YAAY,OAAO,YAAY;AAAA,EACpC,CAAC;AAED,SACE,mBAAmB,IAAI,QAAQ,KAC/B,gBAAgB;AAAA,IACd,CAAC,WAAW,aAAa,UAAU,SAAS,WAAW,GAAG,MAAM,GAAG;AAAA,EACrE;AAEJ;AAEA,SAAS,UAAU,OAAqC;AACtD,SAAO,QACH,MACG,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,OAAO,IACjB,CAAC;AACP;AAEA,SAAS,WAAW,QAAqC;AACvD,SAAO,CAAC,GAAG,IAAI,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AACvE;AAEA,SAAS,aAAa,UAA2B;AAC/C,SAAO,SAAS,WAAW,GAAG,KAAK,CAAC,SAAS,WAAW,IAAI;AAC9D;","names":[]}
|
package/dist/routes/layout.d.ts
CHANGED
package/dist/routes/layout.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/routes/layout.tsx"],"sourcesContent":["import { cacheLife, cacheTag } from \"next/cache\";\nimport { resolveRuntimeAuthConfig } from \"../auth-config.js\";\nimport {\n loadBuildId,\n loadManifest,\n loadResolvedConfig,\n} from \"../server-data.js\";\n\nexport async function generateMetadata() {\n const { config } = await getLayoutProps();\n return {\n title: {\n default: config.title,\n template: `%s · ${config.title}`,\n },\n description: config.description,\n };\n}\n\nexport async function getLayoutProps() {\n \"use cache\";\n cacheLife(\"max\");\n const buildId = await loadBuildId();\n cacheTag(\"build\", `build:${buildId}`);\n const [manifest, config] = await Promise.all([\n loadManifest(),\n loadResolvedConfig(),\n ]);\n const auth = resolveRuntimeAuthConfig(config);\n return {\n navigation: {\n entries: manifest.entries\n .filter((entry) => entry.frontmatter.listed !== false)\n .map((entry) => ({\n slug: entry.slug,\n title: entry.menuLabel ?? entry.title,\n sortKey: entry.sortKey,\n })),\n },\n config: {\n title: config.title,\n description: config.description,\n baseUrl: config.baseUrl,\n authEnabled: auth.authEnabled,\n },\n };\n}\n"],"mappings":"AAAA,SAAS,WAAW,gBAAgB;AACpC,SAAS,gCAAgC;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,eAAsB,mBAAmB;AACvC,QAAM,EAAE,OAAO,IAAI,MAAM,eAAe;AACxC,SAAO;AAAA,IACL,OAAO;AAAA,MACL,SAAS,OAAO;AAAA,MAChB,UAAU,WAAQ,OAAO,KAAK;AAAA,IAChC;AAAA,IACA,aAAa,OAAO;AAAA,EACtB;AACF;AAEA,eAAsB,iBAAiB;AACrC;AACA,YAAU,KAAK;AACf,QAAM,UAAU,MAAM,YAAY;AAClC,WAAS,SAAS,SAAS,OAAO,EAAE;AACpC,QAAM,CAAC,UAAU,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC3C,aAAa;AAAA,IACb,mBAAmB;AAAA,EACrB,CAAC;AACD,QAAM,OAAO,yBAAyB,MAAM;AAC5C,SAAO;AAAA,IACL,YAAY;AAAA,MACV,SAAS,SAAS,QACf,OAAO,CAAC,UAAU,MAAM,YAAY,WAAW,KAAK,EACpD,IAAI,CAAC,WAAW;AAAA,QACf,MAAM,MAAM;AAAA,QACZ,OAAO,MAAM,aAAa,MAAM;AAAA,QAChC,SAAS,MAAM;AAAA,MACjB,EAAE;AAAA,IACN;AAAA,IACA,QAAQ;AAAA,MACN,OAAO,OAAO;AAAA,MACd,aAAa,OAAO;AAAA,MACpB,SAAS,OAAO;AAAA,MAChB,aAAa,KAAK;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/routes/layout.tsx"],"sourcesContent":["import { cacheLife, cacheTag } from \"next/cache\";\nimport { resolveRuntimeAuthConfig } from \"../auth-config.js\";\nimport {\n loadBuildId,\n loadManifest,\n loadResolvedConfig,\n} from \"../server-data.js\";\n\nexport async function generateMetadata() {\n const { config } = await getLayoutProps();\n return {\n title: {\n default: config.title,\n template: `%s · ${config.title}`,\n },\n description: config.description,\n };\n}\n\nexport async function getLayoutProps() {\n \"use cache\";\n cacheLife(\"max\");\n const buildId = await loadBuildId();\n cacheTag(\"build\", `build:${buildId}`);\n const [manifest, config] = await Promise.all([\n loadManifest(),\n loadResolvedConfig(),\n ]);\n const auth = resolveRuntimeAuthConfig(config);\n return {\n navigation: {\n entries: manifest.entries\n .filter((entry) => entry.frontmatter.listed !== false)\n .map((entry) => ({\n slug: entry.slug,\n title: entry.menuLabel ?? entry.title,\n sortKey: entry.sortKey,\n })),\n },\n config: {\n title: config.title,\n description: config.description,\n logo: config.logo,\n baseUrl: config.baseUrl,\n authEnabled: auth.authEnabled,\n },\n };\n}\n"],"mappings":"AAAA,SAAS,WAAW,gBAAgB;AACpC,SAAS,gCAAgC;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,eAAsB,mBAAmB;AACvC,QAAM,EAAE,OAAO,IAAI,MAAM,eAAe;AACxC,SAAO;AAAA,IACL,OAAO;AAAA,MACL,SAAS,OAAO;AAAA,MAChB,UAAU,WAAQ,OAAO,KAAK;AAAA,IAChC;AAAA,IACA,aAAa,OAAO;AAAA,EACtB;AACF;AAEA,eAAsB,iBAAiB;AACrC;AACA,YAAU,KAAK;AACf,QAAM,UAAU,MAAM,YAAY;AAClC,WAAS,SAAS,SAAS,OAAO,EAAE;AACpC,QAAM,CAAC,UAAU,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC3C,aAAa;AAAA,IACb,mBAAmB;AAAA,EACrB,CAAC;AACD,QAAM,OAAO,yBAAyB,MAAM;AAC5C,SAAO;AAAA,IACL,YAAY;AAAA,MACV,SAAS,SAAS,QACf,OAAO,CAAC,UAAU,MAAM,YAAY,WAAW,KAAK,EACpD,IAAI,CAAC,WAAW;AAAA,QACf,MAAM,MAAM;AAAA,QACZ,OAAO,MAAM,aAAa,MAAM;AAAA,QAChC,SAAS,MAAM;AAAA,MACjB,EAAE;AAAA,IACN;AAAA,IACA,QAAQ;AAAA,MACN,OAAO,OAAO;AAAA,MACd,aAAa,OAAO;AAAA,MACpB,MAAM,OAAO;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,aAAa,KAAK;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { NotAllowed } from "@silicajs/components";
|
|
3
3
|
function NotAllowedPage() {
|
|
4
|
-
return /* @__PURE__ */ jsx(NotAllowed, {});
|
|
4
|
+
return /* @__PURE__ */ jsx("div", { className: "flex min-h-svh items-center justify-center p-6", children: /* @__PURE__ */ jsx(NotAllowed, {}) });
|
|
5
5
|
}
|
|
6
6
|
export {
|
|
7
7
|
NotAllowedPage as default
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/routes/not-allowed.tsx"],"sourcesContent":["import { NotAllowed } from \"@silicajs/components\";\n\nexport default function NotAllowedPage() {\n return <NotAllowed
|
|
1
|
+
{"version":3,"sources":["../../src/routes/not-allowed.tsx"],"sourcesContent":["import { NotAllowed } from \"@silicajs/components\";\n\nexport default function NotAllowedPage() {\n return (\n <div className=\"flex min-h-svh items-center justify-center p-6\">\n <NotAllowed />\n </div>\n );\n}\n"],"mappings":"AAKM;AALN,SAAS,kBAAkB;AAEZ,SAAR,iBAAkC;AACvC,SACE,oBAAC,SAAI,WAAU,kDACb,8BAAC,cAAW,GACd;AAEJ;","names":[]}
|
package/dist/routes/page.js
CHANGED
|
@@ -3,6 +3,7 @@ import fs from "node:fs/promises";
|
|
|
3
3
|
import { cacheLife, cacheTag } from "next/cache";
|
|
4
4
|
import { notFound } from "next/navigation";
|
|
5
5
|
import {
|
|
6
|
+
getMetaDescription,
|
|
6
7
|
renderMarkdown,
|
|
7
8
|
renderMarkdownHtml,
|
|
8
9
|
resolveWikiLink
|
|
@@ -38,7 +39,7 @@ async function generateMetadata({ params }) {
|
|
|
38
39
|
if (!entry) return {};
|
|
39
40
|
return {
|
|
40
41
|
title: entry.title,
|
|
41
|
-
description: entry
|
|
42
|
+
description: getMetaDescription(entry)
|
|
42
43
|
};
|
|
43
44
|
}
|
|
44
45
|
async function getPageManifest() {
|
package/dist/routes/page.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/routes/page.tsx"],"sourcesContent":["import fs from \"node:fs/promises\";\nimport type { AnchorHTMLAttributes } from \"react\";\nimport { cacheLife, cacheTag } from \"next/cache\";\nimport { notFound } from \"next/navigation\";\nimport {\n renderMarkdown,\n renderMarkdownHtml,\n resolveWikiLink,\n type RenderContext,\n} from \"@silicajs/core/runtime\";\nimport { SilicaLink } from \"@silicajs/components/routing\";\nimport {\n loadBuildId,\n loadGraph,\n loadManifest,\n loadResolvedConfig,\n normalizeRouteSlug,\n} from \"../server-data.js\";\nimport type { SilicaTheme } from \"@silicajs/core/theme\";\n\nfunction MarkdownLink({\n href,\n ...props\n}: AnchorHTMLAttributes<HTMLAnchorElement>) {\n if (href && href.startsWith(\"/\") && !href.startsWith(\"/silica/\")) {\n return <SilicaLink href={href} {...props} />;\n }\n\n return <a href={href} {...props} />;\n}\n\nexport async function generateStaticParams() {\n const manifest = await getPageManifest();\n return manifest.entries.map((entry) => ({\n slug: entry.slug === \"index\" ? [] : entry.slug.split(\"/\"),\n }));\n}\n\nexport async function generateMetadata({ params }: PageProps) {\n const resolvedParams = await params;\n const slug = normalizeRouteSlug(resolvedParams?.slug);\n const manifest = await getPageManifest();\n const entry = manifest.bySlug[slug];\n if (!entry) return {};\n return {\n title: entry.title,\n description: entry
|
|
1
|
+
{"version":3,"sources":["../../src/routes/page.tsx"],"sourcesContent":["import fs from \"node:fs/promises\";\nimport type { AnchorHTMLAttributes } from \"react\";\nimport { cacheLife, cacheTag } from \"next/cache\";\nimport { notFound } from \"next/navigation\";\nimport {\n getMetaDescription,\n renderMarkdown,\n renderMarkdownHtml,\n resolveWikiLink,\n type RenderContext,\n} from \"@silicajs/core/runtime\";\nimport { SilicaLink } from \"@silicajs/components/routing\";\nimport {\n loadBuildId,\n loadGraph,\n loadManifest,\n loadResolvedConfig,\n normalizeRouteSlug,\n} from \"../server-data.js\";\nimport type { SilicaTheme } from \"@silicajs/core/theme\";\n\nfunction MarkdownLink({\n href,\n ...props\n}: AnchorHTMLAttributes<HTMLAnchorElement>) {\n if (href && href.startsWith(\"/\") && !href.startsWith(\"/silica/\")) {\n return <SilicaLink href={href} {...props} />;\n }\n\n return <a href={href} {...props} />;\n}\n\nexport async function generateStaticParams() {\n const manifest = await getPageManifest();\n return manifest.entries.map((entry) => ({\n slug: entry.slug === \"index\" ? [] : entry.slug.split(\"/\"),\n }));\n}\n\nexport async function generateMetadata({ params }: PageProps) {\n const resolvedParams = await params;\n const slug = normalizeRouteSlug(resolvedParams?.slug);\n const manifest = await getPageManifest();\n const entry = manifest.bySlug[slug];\n if (!entry) return {};\n return {\n title: entry.title,\n description: getMetaDescription(entry),\n };\n}\n\nasync function getPageManifest() {\n \"use cache\";\n cacheLife(\"max\");\n const buildId = await loadBuildId();\n cacheTag(\"build\", `build:${buildId}`);\n return loadManifest();\n}\n\nexport type PageProps = {\n params: Promise<{ slug?: string[] }> | { slug?: string[] };\n};\n\nexport async function VaultContent({\n slug,\n theme,\n}: {\n slug: string;\n theme: SilicaTheme;\n}) {\n \"use cache\";\n cacheLife(\"max\");\n const buildId = await loadBuildId();\n cacheTag(\"build\", `build:${buildId}`, `page:${slug}`);\n\n const [manifest, graph, config] = await Promise.all([\n loadManifest(),\n loadGraph(),\n loadResolvedConfig(),\n ]);\n const entry = manifest.bySlug[slug];\n if (!entry) notFound();\n\n const renderContext = (\n currentSlug: string,\n embedDepth = 0,\n ): RenderContext => ({\n slug: currentSlug,\n allSlugs: manifest.allSlugs,\n assetBaseUrl: \"/silica\",\n wikilinkStrategy: config.wikilinks.strategy,\n tags: config.tags,\n ordering: config.ordering,\n embedDepth,\n maxEmbedDepth: 3,\n components: {\n ...theme.components,\n a: MarkdownLink,\n },\n resolveEmbed: async (target) => {\n const resolved = resolveWikiLink(\n currentSlug,\n target.path || currentSlug,\n manifest.allSlugs,\n config.wikilinks.strategy,\n config.ordering,\n );\n if (!resolved || embedDepth >= 3) return;\n const embeddedEntry = manifest.bySlug[resolved];\n if (!embeddedEntry) return;\n const embeddedRaw = await fs.readFile(embeddedEntry.file, \"utf8\");\n const scopedRaw = scopeEmbedMarkdown(embeddedRaw, target);\n return renderMarkdownHtml(\n scopedRaw,\n renderContext(resolved, embedDepth + 1),\n );\n },\n });\n\n const raw = await fs.readFile(entry.file, \"utf8\");\n const rendered = await renderMarkdown(raw, renderContext(slug));\n\n return (\n <theme.PageRenderer\n config={config}\n graph={graph}\n manifest={manifest}\n page={{\n slug,\n title: rendered.title ?? entry.title,\n description: rendered.description ?? entry.description,\n content: rendered.content,\n frontmatter: rendered.frontmatter,\n toc: rendered.toc,\n entry,\n }}\n />\n );\n}\n\nfunction scopeEmbedMarkdown(\n raw: string,\n target: Parameters<NonNullable<RenderContext[\"resolveEmbed\"]>>[0],\n): string {\n if (target.blockId) return extractBlock(raw, target.blockId) ?? raw;\n if (target.heading) return extractHeadingSection(raw, target.heading) ?? raw;\n return raw;\n}\n\nfunction extractHeadingSection(\n raw: string,\n heading: string,\n): string | undefined {\n const lines = raw.split(/\\r?\\n/);\n const expected = normalizeHeading(heading);\n const start = lines.findIndex((line) => {\n const parsed = parseHeading(line);\n return parsed ? normalizeHeading(parsed.text) === expected : false;\n });\n if (start === -1) return;\n\n const startHeading = parseHeading(lines[start] ?? \"\");\n if (!startHeading) return;\n let end = lines.length;\n for (let index = start + 1; index < lines.length; index += 1) {\n const nextHeading = parseHeading(lines[index] ?? \"\");\n if (nextHeading && nextHeading.depth <= startHeading.depth) {\n end = index;\n break;\n }\n }\n\n return lines.slice(start, end).join(\"\\n\").trim();\n}\n\nfunction extractBlock(raw: string, blockId: string): string | undefined {\n const lines = raw.split(/\\r?\\n/);\n const blockIdPattern = new RegExp(\n `(^|\\\\s)\\\\^${escapeRegExp(blockId)}(?=\\\\s|$)`,\n );\n const matchIndex = lines.findIndex((line) => blockIdPattern.test(line));\n if (matchIndex === -1) return;\n\n let start = matchIndex;\n while (start > 0 && lines[start - 1]?.trim()) start -= 1;\n\n let end = matchIndex + 1;\n while (end < lines.length && lines[end]?.trim()) end += 1;\n\n return lines.slice(start, end).join(\"\\n\").replace(blockIdPattern, \"\").trim();\n}\n\nfunction parseHeading(\n line: string,\n): { depth: number; text: string } | undefined {\n const match = /^(#{1,6})\\s+(.+?)\\s*#*\\s*$/.exec(line);\n if (!match) return;\n return {\n depth: match[1]!.length,\n text: match[2]!,\n };\n}\n\nfunction normalizeHeading(value: string): string {\n return value.trim().replace(/\\s+/g, \" \").toLowerCase();\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":"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","names":[]}
|
package/dist/routes/sign-in.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { jsx
|
|
2
|
-
import { cacheLife } from "next/cache";
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cacheLife, cacheTag } from "next/cache";
|
|
3
|
+
import { SignInShell } from "@silicajs/components";
|
|
4
|
+
import { GoogleSignInButton } from "../google-sign-in-button.js";
|
|
3
5
|
import { resolveRuntimeAuthConfig } from "../auth-config.js";
|
|
4
|
-
import { loadResolvedConfig } from "../server-data.js";
|
|
6
|
+
import { loadBuildId, loadResolvedConfig } from "../server-data.js";
|
|
5
7
|
async function SignInPage() {
|
|
6
8
|
const config = await getSignInConfig();
|
|
7
9
|
const authEnabled = resolveRuntimeAuthConfig(config).authEnabled;
|
|
8
|
-
return /* @__PURE__ */
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
config.
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
/* @__PURE__ */ jsx("input", { type: "hidden", name: "errorCallbackURL", value: "/not-allowed" }),
|
|
19
|
-
/* @__PURE__ */ jsx("button", { className: "silica-primary-link", type: "submit", children: "Continue with Google" })
|
|
20
|
-
] }) : /* @__PURE__ */ jsx("p", { children: "Authentication is not enabled for this site." })
|
|
21
|
-
] });
|
|
10
|
+
return /* @__PURE__ */ jsx(
|
|
11
|
+
SignInShell,
|
|
12
|
+
{
|
|
13
|
+
title: config.title,
|
|
14
|
+
logo: config.logo,
|
|
15
|
+
headline: "Sign in required",
|
|
16
|
+
subheadline: authEnabled ? `${config.title} is private. Sign in with Google to access.` : void 0,
|
|
17
|
+
children: authEnabled ? /* @__PURE__ */ jsx(GoogleSignInButton, { errorCallbackURL: "/not-allowed" }) : /* @__PURE__ */ jsx("p", { className: "text-center text-sm text-muted-foreground", children: "Authentication is not enabled for this site." })
|
|
18
|
+
}
|
|
19
|
+
);
|
|
22
20
|
}
|
|
23
21
|
async function getSignInConfig() {
|
|
24
22
|
"use cache";
|
|
25
23
|
cacheLife("max");
|
|
24
|
+
const buildId = await loadBuildId();
|
|
25
|
+
cacheTag("build", `build:${buildId}`);
|
|
26
26
|
return loadResolvedConfig();
|
|
27
27
|
}
|
|
28
28
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/routes/sign-in.tsx"],"sourcesContent":["import { cacheLife } from \"next/cache\";\nimport { resolveRuntimeAuthConfig } from \"../auth-config.js\";\nimport { loadResolvedConfig } from \"../server-data.js\";\n\nexport default async function SignInPage() {\n const config = await getSignInConfig();\n const authEnabled = resolveRuntimeAuthConfig(config).authEnabled;\n return (\n <
|
|
1
|
+
{"version":3,"sources":["../../src/routes/sign-in.tsx"],"sourcesContent":["import { cacheLife, cacheTag } from \"next/cache\";\nimport { SignInShell } from \"@silicajs/components\";\nimport { GoogleSignInButton } from \"../google-sign-in-button.js\";\nimport { resolveRuntimeAuthConfig } from \"../auth-config.js\";\nimport { loadBuildId, loadResolvedConfig } from \"../server-data.js\";\n\nexport default async function SignInPage() {\n const config = await getSignInConfig();\n const authEnabled = resolveRuntimeAuthConfig(config).authEnabled;\n\n return (\n <SignInShell\n title={config.title}\n logo={config.logo}\n headline=\"Sign in required\"\n subheadline={\n authEnabled\n ? `${config.title} is private. Sign in with Google to access.`\n : undefined\n }\n >\n {authEnabled ? (\n <GoogleSignInButton errorCallbackURL=\"/not-allowed\" />\n ) : (\n <p className=\"text-center text-sm text-muted-foreground\">\n Authentication is not enabled for this site.\n </p>\n )}\n </SignInShell>\n );\n}\n\nasync function getSignInConfig() {\n \"use cache\";\n cacheLife(\"max\");\n const buildId = await loadBuildId();\n cacheTag(\"build\", `build:${buildId}`);\n return loadResolvedConfig();\n}\n"],"mappings":"AAsBQ;AAtBR,SAAS,WAAW,gBAAgB;AACpC,SAAS,mBAAmB;AAC5B,SAAS,0BAA0B;AACnC,SAAS,gCAAgC;AACzC,SAAS,aAAa,0BAA0B;AAEhD,eAAO,aAAoC;AACzC,QAAM,SAAS,MAAM,gBAAgB;AACrC,QAAM,cAAc,yBAAyB,MAAM,EAAE;AAErD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,OAAO;AAAA,MACd,MAAM,OAAO;AAAA,MACb,UAAS;AAAA,MACT,aACE,cACI,GAAG,OAAO,KAAK,gDACf;AAAA,MAGL,wBACC,oBAAC,sBAAmB,kBAAiB,gBAAe,IAEpD,oBAAC,OAAE,WAAU,6CAA4C,0DAEzD;AAAA;AAAA,EAEJ;AAEJ;AAEA,eAAe,kBAAkB;AAC/B;AACA,YAAU,KAAK;AACf,QAAM,UAAU,MAAM,YAAY;AAClC,WAAS,SAAS,SAAS,OAAO,EAAE;AACpC,SAAO,mBAAmB;AAC5B;","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import theme from "../../silica-theme";
|
|
3
|
+
import { getLayoutProps } from "@silicajs/next/routes/layout";
|
|
4
|
+
|
|
5
|
+
export default async function SiteLayout({
|
|
6
|
+
children,
|
|
7
|
+
}: {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
}) {
|
|
10
|
+
const props = await getLayoutProps();
|
|
11
|
+
return <theme.SiteLayout {...props}>{children}</theme.SiteLayout>;
|
|
12
|
+
}
|
|
@@ -12,11 +12,11 @@ export default async function RootLayout({
|
|
|
12
12
|
}: {
|
|
13
13
|
children: ReactNode;
|
|
14
14
|
}) {
|
|
15
|
-
const
|
|
15
|
+
const { config } = await getLayoutProps();
|
|
16
16
|
return (
|
|
17
|
-
<theme.
|
|
17
|
+
<theme.RootLayout config={config} Provider={SilicaNextRoutingProvider}>
|
|
18
18
|
<SilicaDevReload />
|
|
19
19
|
{children}
|
|
20
|
-
</theme.
|
|
20
|
+
</theme.RootLayout>
|
|
21
21
|
);
|
|
22
22
|
}
|
|
@@ -2,6 +2,7 @@ import * as themeModule from "{{themeSpecifier}}";
|
|
|
2
2
|
|
|
3
3
|
const theme = (themeModule.default ?? themeModule) as typeof themeModule;
|
|
4
4
|
|
|
5
|
-
export const
|
|
5
|
+
export const RootLayout = theme.RootLayout;
|
|
6
|
+
export const SiteLayout = theme.SiteLayout;
|
|
6
7
|
export const PageRenderer = theme.PageRenderer;
|
|
7
8
|
export default theme;
|
package/dist/templates.js
CHANGED
|
@@ -24,7 +24,8 @@ const silicaProxyConfig = ${JSON.stringify(
|
|
|
24
24
|
{
|
|
25
25
|
authEnabled: Boolean(config.auth),
|
|
26
26
|
allowedDomains: config.auth?.allowedDomains ?? [],
|
|
27
|
-
allowedEmails: config.auth?.allowedEmails ?? []
|
|
27
|
+
allowedEmails: config.auth?.allowedEmails ?? [],
|
|
28
|
+
publicPaths: config.logo ? [config.logo] : []
|
|
28
29
|
},
|
|
29
30
|
null,
|
|
30
31
|
2
|
package/dist/templates.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/templates.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ResolvedSilicaConfig } from \"@silicajs/core/runtime\";\n\nexport type TemplateFile = {\n path: string;\n content: string;\n};\n\nconst templateFilesRoot = fileURLToPath(\n new URL(\"./template-files\", import.meta.url),\n);\n\nexport function getSilicaTemplates(): TemplateFile[] {\n return readTemplateDirectory(path.join(templateFilesRoot, \"generated-app\"));\n}\n\nexport function nextConfigTemplate(): string {\n return readTemplateFile(\"next.config.ts\");\n}\n\nexport function themeModuleTemplate(themeValue: unknown): string {\n return readTemplateFile(\"silica-theme.ts\").replace(\n '\"{{themeSpecifier}}\"',\n JSON.stringify(resolveThemeSpecifier(themeValue)),\n );\n}\n\nexport function proxyTemplate(config: ResolvedSilicaConfig): string {\n return `import type { NextRequest } from \"next/server\";\nimport { silicaProxy } from \"@silicajs/next/proxy\";\n\nconst silicaProxyConfig = ${JSON.stringify(\n {\n authEnabled: Boolean(config.auth),\n allowedDomains: config.auth?.allowedDomains ?? [],\n allowedEmails: config.auth?.allowedEmails ?? [],\n },\n null,\n 2,\n )} as const;\n\nexport function proxy(request: NextRequest) {\n return silicaProxy(request, silicaProxyConfig);\n}\n\nexport const config = {\n matcher: [\"/((?!_next/static|_next/image|favicon.ico).*)\"],\n};\n`;\n}\n\nexport function tsconfigTemplate(hasUserTsconfig: boolean): string {\n const template = readTemplateFile(\"tsconfig.json\");\n const rendered = hasUserTsconfig\n ? template.replaceAll(\"{{extends}}\", \"../../tsconfig.json\")\n : template.replace(' \"extends\": \"{{extends}}\",\\n', \"\");\n return rendered.trimEnd();\n}\n\nexport function packageJsonTemplate(): string {\n return readTemplateFile(\"package.json\");\n}\n\nfunction readTemplateFile(filename: string): string {\n return fs.readFileSync(path.join(templateFilesRoot, filename), \"utf8\");\n}\n\nfunction resolveThemeSpecifier(themeValue: unknown): string {\n const themeName =\n typeof themeValue === \"object\" &&\n themeValue !== null &&\n \"name\" in themeValue\n ? String((themeValue as { name?: string }).name ?? \"default\")\n : typeof themeValue === \"string\"\n ? themeValue\n : \"default\";\n\n if (!themeName || themeName === \"default\") return \"@silicajs/theme-amethyst\";\n if (themeName.startsWith(\".\"))\n return `../../${themeName.replace(/^\\.\\//, \"\")}`;\n return themeName;\n}\n\nfunction readTemplateDirectory(root: string, current = root): TemplateFile[] {\n const entries = fs\n .readdirSync(current, { withFileTypes: true })\n .sort((left, right) => left.name.localeCompare(right.name));\n\n return entries.flatMap((entry) => {\n const absolutePath = path.join(current, entry.name);\n if (entry.isDirectory()) return readTemplateDirectory(root, absolutePath);\n if (!entry.isFile()) return [];\n\n return {\n path: path.relative(root, absolutePath).split(path.sep).join(\"/\"),\n content: fs.readFileSync(absolutePath, \"utf8\"),\n };\n });\n}\n"],"mappings":"AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAQ9B,MAAM,oBAAoB;AAAA,EACxB,IAAI,IAAI,oBAAoB,YAAY,GAAG;AAC7C;AAEO,SAAS,qBAAqC;AACnD,SAAO,sBAAsB,KAAK,KAAK,mBAAmB,eAAe,CAAC;AAC5E;AAEO,SAAS,qBAA6B;AAC3C,SAAO,iBAAiB,gBAAgB;AAC1C;AAEO,SAAS,oBAAoB,YAA6B;AAC/D,SAAO,iBAAiB,iBAAiB,EAAE;AAAA,IACzC;AAAA,IACA,KAAK,UAAU,sBAAsB,UAAU,CAAC;AAAA,EAClD;AACF;AAEO,SAAS,cAAc,QAAsC;AAClE,SAAO;AAAA;AAAA;AAAA,4BAGmB,KAAK;AAAA,IAC7B;AAAA,MACE,aAAa,QAAQ,OAAO,IAAI;AAAA,MAChC,gBAAgB,OAAO,MAAM,kBAAkB,CAAC;AAAA,MAChD,eAAe,OAAO,MAAM,iBAAiB,CAAC;AAAA,
|
|
1
|
+
{"version":3,"sources":["../src/templates.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ResolvedSilicaConfig } from \"@silicajs/core/runtime\";\n\nexport type TemplateFile = {\n path: string;\n content: string;\n};\n\nconst templateFilesRoot = fileURLToPath(\n new URL(\"./template-files\", import.meta.url),\n);\n\nexport function getSilicaTemplates(): TemplateFile[] {\n return readTemplateDirectory(path.join(templateFilesRoot, \"generated-app\"));\n}\n\nexport function nextConfigTemplate(): string {\n return readTemplateFile(\"next.config.ts\");\n}\n\nexport function themeModuleTemplate(themeValue: unknown): string {\n return readTemplateFile(\"silica-theme.ts\").replace(\n '\"{{themeSpecifier}}\"',\n JSON.stringify(resolveThemeSpecifier(themeValue)),\n );\n}\n\nexport function proxyTemplate(config: ResolvedSilicaConfig): string {\n return `import type { NextRequest } from \"next/server\";\nimport { silicaProxy } from \"@silicajs/next/proxy\";\n\nconst silicaProxyConfig = ${JSON.stringify(\n {\n authEnabled: Boolean(config.auth),\n allowedDomains: config.auth?.allowedDomains ?? [],\n allowedEmails: config.auth?.allowedEmails ?? [],\n publicPaths: config.logo ? [config.logo] : [],\n },\n null,\n 2,\n )} as const;\n\nexport function proxy(request: NextRequest) {\n return silicaProxy(request, silicaProxyConfig);\n}\n\nexport const config = {\n matcher: [\"/((?!_next/static|_next/image|favicon.ico).*)\"],\n};\n`;\n}\n\nexport function tsconfigTemplate(hasUserTsconfig: boolean): string {\n const template = readTemplateFile(\"tsconfig.json\");\n const rendered = hasUserTsconfig\n ? template.replaceAll(\"{{extends}}\", \"../../tsconfig.json\")\n : template.replace(' \"extends\": \"{{extends}}\",\\n', \"\");\n return rendered.trimEnd();\n}\n\nexport function packageJsonTemplate(): string {\n return readTemplateFile(\"package.json\");\n}\n\nfunction readTemplateFile(filename: string): string {\n return fs.readFileSync(path.join(templateFilesRoot, filename), \"utf8\");\n}\n\nfunction resolveThemeSpecifier(themeValue: unknown): string {\n const themeName =\n typeof themeValue === \"object\" &&\n themeValue !== null &&\n \"name\" in themeValue\n ? String((themeValue as { name?: string }).name ?? \"default\")\n : typeof themeValue === \"string\"\n ? themeValue\n : \"default\";\n\n if (!themeName || themeName === \"default\") return \"@silicajs/theme-amethyst\";\n if (themeName.startsWith(\".\"))\n return `../../${themeName.replace(/^\\.\\//, \"\")}`;\n return themeName;\n}\n\nfunction readTemplateDirectory(root: string, current = root): TemplateFile[] {\n const entries = fs\n .readdirSync(current, { withFileTypes: true })\n .sort((left, right) => left.name.localeCompare(right.name));\n\n return entries.flatMap((entry) => {\n const absolutePath = path.join(current, entry.name);\n if (entry.isDirectory()) return readTemplateDirectory(root, absolutePath);\n if (!entry.isFile()) return [];\n\n return {\n path: path.relative(root, absolutePath).split(path.sep).join(\"/\"),\n content: fs.readFileSync(absolutePath, \"utf8\"),\n };\n });\n}\n"],"mappings":"AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAQ9B,MAAM,oBAAoB;AAAA,EACxB,IAAI,IAAI,oBAAoB,YAAY,GAAG;AAC7C;AAEO,SAAS,qBAAqC;AACnD,SAAO,sBAAsB,KAAK,KAAK,mBAAmB,eAAe,CAAC;AAC5E;AAEO,SAAS,qBAA6B;AAC3C,SAAO,iBAAiB,gBAAgB;AAC1C;AAEO,SAAS,oBAAoB,YAA6B;AAC/D,SAAO,iBAAiB,iBAAiB,EAAE;AAAA,IACzC;AAAA,IACA,KAAK,UAAU,sBAAsB,UAAU,CAAC;AAAA,EAClD;AACF;AAEO,SAAS,cAAc,QAAsC;AAClE,SAAO;AAAA;AAAA;AAAA,4BAGmB,KAAK;AAAA,IAC7B;AAAA,MACE,aAAa,QAAQ,OAAO,IAAI;AAAA,MAChC,gBAAgB,OAAO,MAAM,kBAAkB,CAAC;AAAA,MAChD,eAAe,OAAO,MAAM,iBAAiB,CAAC;AAAA,MAC9C,aAAa,OAAO,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUH;AAEO,SAAS,iBAAiB,iBAAkC;AACjE,QAAM,WAAW,iBAAiB,eAAe;AACjD,QAAM,WAAW,kBACb,SAAS,WAAW,eAAe,qBAAqB,IACxD,SAAS,QAAQ,iCAAiC,EAAE;AACxD,SAAO,SAAS,QAAQ;AAC1B;AAEO,SAAS,sBAA8B;AAC5C,SAAO,iBAAiB,cAAc;AACxC;AAEA,SAAS,iBAAiB,UAA0B;AAClD,SAAO,GAAG,aAAa,KAAK,KAAK,mBAAmB,QAAQ,GAAG,MAAM;AACvE;AAEA,SAAS,sBAAsB,YAA6B;AAC1D,QAAM,YACJ,OAAO,eAAe,YACtB,eAAe,QACf,UAAU,aACN,OAAQ,WAAiC,QAAQ,SAAS,IAC1D,OAAO,eAAe,WACpB,aACA;AAER,MAAI,CAAC,aAAa,cAAc,UAAW,QAAO;AAClD,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO,SAAS,UAAU,QAAQ,SAAS,EAAE,CAAC;AAChD,SAAO;AACT;AAEA,SAAS,sBAAsB,MAAc,UAAU,MAAsB;AAC3E,QAAM,UAAU,GACb,YAAY,SAAS,EAAE,eAAe,KAAK,CAAC,EAC5C,KAAK,CAAC,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC;AAE5D,SAAO,QAAQ,QAAQ,CAAC,UAAU;AAChC,UAAM,eAAe,KAAK,KAAK,SAAS,MAAM,IAAI;AAClD,QAAI,MAAM,YAAY,EAAG,QAAO,sBAAsB,MAAM,YAAY;AACxE,QAAI,CAAC,MAAM,OAAO,EAAG,QAAO,CAAC;AAE7B,WAAO;AAAA,MACL,MAAM,KAAK,SAAS,MAAM,YAAY,EAAE,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AAAA,MAChE,SAAS,GAAG,aAAa,cAAc,MAAM;AAAA,IAC/C;AAAA,EACF,CAAC;AACH;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silicajs/next",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Next.js runtime, routes, templates, and proxy for Silica.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -84,8 +84,8 @@
|
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
86
|
"@silicajs/auth": "^0.1.1",
|
|
87
|
-
"@silicajs/components": "^0.1.
|
|
88
|
-
"@silicajs/core": "^0.1.
|
|
87
|
+
"@silicajs/components": "^0.1.2",
|
|
88
|
+
"@silicajs/core": "^0.1.1",
|
|
89
89
|
"@silicajs/remark-obsidian": "^0.1.0",
|
|
90
90
|
"@silicajs/search": "^0.1.0",
|
|
91
91
|
"better-auth": "1.6.11",
|
|
@@ -97,9 +97,9 @@
|
|
|
97
97
|
"react-dom": "^19.2.0"
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|
|
100
|
-
"next": "^16.2.
|
|
100
|
+
"next": "^16.2.7",
|
|
101
101
|
"react": "^19.2.6",
|
|
102
|
-
"react-dom": "^19.2.
|
|
102
|
+
"react-dom": "^19.2.7"
|
|
103
103
|
},
|
|
104
104
|
"homepage": "https://github.com/agdevhq/silica/tree/main/packages/next#readme",
|
|
105
105
|
"repository": {
|
|
File without changes
|