zudoku 0.78.0 → 0.78.1
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/cli/cli.js +601 -160
- package/dist/cli/worker.js +6 -4
- package/dist/declarations/app/adapter.d.ts +12 -0
- package/dist/declarations/app/adapters/cloudflare.d.ts +8 -0
- package/dist/declarations/app/adapters/lambda.d.ts +13 -0
- package/dist/declarations/app/adapters/node.d.ts +12 -0
- package/dist/declarations/app/adapters/vercel.d.ts +14 -0
- package/dist/declarations/app/entry.client.d.ts +2 -0
- package/dist/declarations/app/entry.server.d.ts +13 -0
- package/dist/declarations/app/protectChunks.d.ts +17 -0
- package/dist/declarations/app/wrapProtectedRoutes.d.ts +4 -0
- package/dist/declarations/config/validators/HeaderNavigationSchema.d.ts +216 -80
- package/dist/declarations/config/validators/ZudokuConfig.d.ts +81 -30
- package/dist/declarations/config/validators/icon-types.d.ts +1 -1
- package/dist/declarations/lib/authentication/authentication.d.ts +7 -0
- package/dist/declarations/lib/authentication/cookie-sync.d.ts +3 -0
- package/dist/declarations/lib/authentication/cookies.d.ts +10 -0
- package/dist/declarations/lib/authentication/providers/azureb2c.d.ts +6 -1
- package/dist/declarations/lib/authentication/providers/clerk.d.ts +1 -0
- package/dist/declarations/lib/authentication/providers/openid.d.ts +2 -1
- package/dist/declarations/lib/authentication/providers/supabase.d.ts +2 -0
- package/dist/declarations/lib/authentication/session-handler.d.ts +81 -0
- package/dist/declarations/lib/authentication/state.d.ts +7 -0
- package/dist/declarations/lib/authentication/verify-cache.d.ts +2 -0
- package/dist/declarations/lib/components/Bootstrap.d.ts +2 -2
- package/dist/declarations/lib/components/Heading.d.ts +1 -1
- package/dist/declarations/lib/components/context/RenderContext.d.ts +6 -0
- package/dist/declarations/lib/core/RouteGuard.d.ts +11 -0
- package/dist/declarations/lib/core/ZudokuContext.d.ts +5 -2
- package/dist/declarations/lib/manifest.d.ts +25 -0
- package/dist/declarations/lib/util/url.d.ts +2 -0
- package/dist/flat-config.d.ts +1 -1
- package/docs/configuration/protected-routes.md +21 -4
- package/docs/guides/server-side-content-protection.md +207 -0
- package/package.json +26 -4
- package/src/app/adapter.ts +16 -0
- package/src/app/adapters/cloudflare.ts +18 -0
- package/src/app/adapters/lambda.ts +36 -0
- package/src/app/adapters/node.ts +32 -0
- package/src/app/adapters/vercel.ts +39 -0
- package/src/app/demo.tsx +2 -2
- package/src/app/entry.client.tsx +17 -7
- package/src/app/entry.server.tsx +128 -9
- package/src/app/main.tsx +20 -3
- package/src/app/protectChunks.ts +64 -0
- package/src/app/standalone.tsx +2 -2
- package/src/app/wrapProtectedRoutes.ts +82 -0
- package/src/config/validators/icon-types.ts +17 -0
- package/src/lib/authentication/authentication.ts +15 -0
- package/src/lib/authentication/cookie-sync.ts +90 -0
- package/src/lib/authentication/cookies.ts +54 -0
- package/src/lib/authentication/hook.ts +13 -0
- package/src/lib/authentication/providers/azureb2c.tsx +70 -2
- package/src/lib/authentication/providers/clerk.tsx +49 -0
- package/src/lib/authentication/providers/openid.tsx +46 -0
- package/src/lib/authentication/providers/supabase.tsx +30 -2
- package/src/lib/authentication/session-handler.ts +164 -0
- package/src/lib/authentication/state.ts +36 -5
- package/src/lib/authentication/verify-cache.ts +32 -0
- package/src/lib/components/Bootstrap.tsx +20 -14
- package/src/lib/components/Header.tsx +56 -57
- package/src/lib/components/MobileTopNavigation.tsx +66 -67
- package/src/lib/components/Zudoku.tsx +14 -1
- package/src/lib/components/context/RenderContext.ts +8 -0
- package/src/lib/components/context/ZudokuContext.ts +2 -1
- package/src/lib/core/RouteGuard.tsx +50 -29
- package/src/lib/core/ZudokuContext.ts +39 -6
- package/src/lib/errors/RouterError.tsx +43 -1
- package/src/lib/manifest.ts +62 -0
- package/src/lib/oas/parser/dereference/index.ts +2 -1
- package/src/lib/oas/parser/dereference/resolveRef.ts +2 -1
- package/src/lib/oas/parser/index.ts +1 -1
- package/src/lib/plugins/openapi/client/createServer.ts +13 -4
- package/src/lib/plugins/search-pagefind/index.tsx +1 -4
- package/src/lib/util/os.ts +1 -0
- package/src/lib/util/url.ts +13 -0
- package/src/vite/build.ts +84 -24
- package/src/vite/config.ts +50 -5
- package/src/vite/dev-server.ts +61 -8
- package/src/vite/manifest.ts +15 -0
- package/src/vite/plugin-api.ts +3 -1
- package/src/vite/plugin-markdown-export.ts +3 -9
- package/src/vite/prerender/worker.ts +2 -4
- package/src/vite/protected/annotator.ts +136 -0
- package/src/vite/protected/build.ts +151 -0
- package/src/vite/protected/registry.ts +82 -0
- package/src/vite/ssr-templates/cloudflare.ts +5 -18
- package/src/vite/ssr-templates/lambda.ts +4 -0
- package/src/vite/ssr-templates/node.ts +7 -22
- package/src/vite/ssr-templates/vercel.ts +6 -20
package/dist/cli/cli.js
CHANGED
|
@@ -131,7 +131,7 @@ import { stat } from "node:fs/promises";
|
|
|
131
131
|
var fileExists;
|
|
132
132
|
var init_file_exists = __esm({
|
|
133
133
|
"src/config/file-exists.ts"() {
|
|
134
|
-
fileExists = (
|
|
134
|
+
fileExists = (path30) => stat(path30).then(() => true).catch(() => false);
|
|
135
135
|
}
|
|
136
136
|
});
|
|
137
137
|
|
|
@@ -815,6 +815,7 @@ var init_icon_types = __esm({
|
|
|
815
815
|
"arrows-up-from-line",
|
|
816
816
|
"asterisk",
|
|
817
817
|
"asterisk-square",
|
|
818
|
+
"astroid",
|
|
818
819
|
"at-sign",
|
|
819
820
|
"atom",
|
|
820
821
|
"audio-lines",
|
|
@@ -882,6 +883,7 @@ var init_icon_types = __esm({
|
|
|
882
883
|
"beer",
|
|
883
884
|
"beer-off",
|
|
884
885
|
"bell",
|
|
886
|
+
"bell-check",
|
|
885
887
|
"bell-dot",
|
|
886
888
|
"bell-electric",
|
|
887
889
|
"bell-minus",
|
|
@@ -903,6 +905,7 @@ var init_icon_types = __esm({
|
|
|
903
905
|
"birdhouse",
|
|
904
906
|
"bitcoin",
|
|
905
907
|
"blend",
|
|
908
|
+
"blender",
|
|
906
909
|
"blinds",
|
|
907
910
|
"blocks",
|
|
908
911
|
"bluetooth",
|
|
@@ -968,6 +971,7 @@ var init_icon_types = __esm({
|
|
|
968
971
|
"briefcase-conveyor-belt",
|
|
969
972
|
"briefcase-medical",
|
|
970
973
|
"bring-to-front",
|
|
974
|
+
"broccoli",
|
|
971
975
|
"brush",
|
|
972
976
|
"brush-cleaning",
|
|
973
977
|
"bubbles",
|
|
@@ -1460,6 +1464,7 @@ var init_icon_types = __esm({
|
|
|
1460
1464
|
"fold-vertical",
|
|
1461
1465
|
"folder",
|
|
1462
1466
|
"folder-archive",
|
|
1467
|
+
"folder-bookmark",
|
|
1463
1468
|
"folder-check",
|
|
1464
1469
|
"folder-clock",
|
|
1465
1470
|
"folder-closed",
|
|
@@ -1609,6 +1614,7 @@ var init_icon_types = __esm({
|
|
|
1609
1614
|
"heart-off",
|
|
1610
1615
|
"heart-plus",
|
|
1611
1616
|
"heart-pulse",
|
|
1617
|
+
"heart-x",
|
|
1612
1618
|
"heater",
|
|
1613
1619
|
"helicopter",
|
|
1614
1620
|
"help-circle",
|
|
@@ -1686,6 +1692,7 @@ var init_icon_types = __esm({
|
|
|
1686
1692
|
"layers",
|
|
1687
1693
|
"layers-2",
|
|
1688
1694
|
"layers-3",
|
|
1695
|
+
"layers-minus",
|
|
1689
1696
|
"layers-plus",
|
|
1690
1697
|
"layout",
|
|
1691
1698
|
"layout-dashboard",
|
|
@@ -2094,6 +2101,7 @@ var init_icon_types = __esm({
|
|
|
2094
2101
|
"repeat",
|
|
2095
2102
|
"repeat-1",
|
|
2096
2103
|
"repeat-2",
|
|
2104
|
+
"repeat-off",
|
|
2097
2105
|
"replace",
|
|
2098
2106
|
"replace-all",
|
|
2099
2107
|
"reply",
|
|
@@ -2353,6 +2361,12 @@ var init_icon_types = __esm({
|
|
|
2353
2361
|
"stethoscope",
|
|
2354
2362
|
"sticker",
|
|
2355
2363
|
"sticky-note",
|
|
2364
|
+
"sticky-note-check",
|
|
2365
|
+
"sticky-note-minus",
|
|
2366
|
+
"sticky-note-off",
|
|
2367
|
+
"sticky-note-plus",
|
|
2368
|
+
"sticky-note-x",
|
|
2369
|
+
"sticky-notes",
|
|
2356
2370
|
"stone",
|
|
2357
2371
|
"stop-circle",
|
|
2358
2372
|
"store",
|
|
@@ -2433,6 +2447,7 @@ var init_icon_types = __esm({
|
|
|
2433
2447
|
"ticket-x",
|
|
2434
2448
|
"tickets",
|
|
2435
2449
|
"tickets-plane",
|
|
2450
|
+
"timeline",
|
|
2436
2451
|
"timer",
|
|
2437
2452
|
"timer-off",
|
|
2438
2453
|
"timer-reset",
|
|
@@ -2572,7 +2587,9 @@ var init_icon_types = __esm({
|
|
|
2572
2587
|
"waves",
|
|
2573
2588
|
"waves-arrow-down",
|
|
2574
2589
|
"waves-arrow-up",
|
|
2590
|
+
"waves-horizontal",
|
|
2575
2591
|
"waves-ladder",
|
|
2592
|
+
"waves-vertical",
|
|
2576
2593
|
"waypoints",
|
|
2577
2594
|
"webcam",
|
|
2578
2595
|
"webhook",
|
|
@@ -2836,6 +2853,16 @@ var init_joinUrl = __esm({
|
|
|
2836
2853
|
}
|
|
2837
2854
|
});
|
|
2838
2855
|
|
|
2856
|
+
// src/lib/util/url.ts
|
|
2857
|
+
import { matchPath } from "react-router";
|
|
2858
|
+
var matchesProtectedPattern, matchesAnyProtectedPattern;
|
|
2859
|
+
var init_url = __esm({
|
|
2860
|
+
"src/lib/util/url.ts"() {
|
|
2861
|
+
matchesProtectedPattern = (pattern, path30) => matchPath({ path: pattern, end: true }, path30) != null;
|
|
2862
|
+
matchesAnyProtectedPattern = (patterns, path30) => patterns.some((p) => matchesProtectedPattern(p, path30));
|
|
2863
|
+
}
|
|
2864
|
+
});
|
|
2865
|
+
|
|
2839
2866
|
// src/lib/core/ZudokuContext.ts
|
|
2840
2867
|
import { createNanoEvents } from "nanoevents";
|
|
2841
2868
|
var normalizeProtectedRoutes;
|
|
@@ -3596,8 +3623,8 @@ var llms_exports = {};
|
|
|
3596
3623
|
__export(llms_exports, {
|
|
3597
3624
|
generateLlmsTxtFiles: () => generateLlmsTxtFiles
|
|
3598
3625
|
});
|
|
3599
|
-
import { writeFile as
|
|
3600
|
-
import
|
|
3626
|
+
import { writeFile as writeFile5 } from "node:fs/promises";
|
|
3627
|
+
import path20 from "node:path";
|
|
3601
3628
|
import colors6 from "picocolors";
|
|
3602
3629
|
async function generateLlmsTxtFiles({
|
|
3603
3630
|
markdownFileInfos,
|
|
@@ -3632,7 +3659,7 @@ async function generateLlmsTxtFiles({
|
|
|
3632
3659
|
}
|
|
3633
3660
|
}
|
|
3634
3661
|
const llmsTxt2 = llmsTxtParts.join("\n");
|
|
3635
|
-
await
|
|
3662
|
+
await writeFile5(path20.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
|
|
3636
3663
|
console.log(colors6.blue("\u2713 generated llms.txt"));
|
|
3637
3664
|
}
|
|
3638
3665
|
if (llmsTxtFull) {
|
|
@@ -3657,8 +3684,8 @@ ${info.content}
|
|
|
3657
3684
|
`);
|
|
3658
3685
|
}
|
|
3659
3686
|
const llmsFull = llmsFullParts.join("\n");
|
|
3660
|
-
await
|
|
3661
|
-
|
|
3687
|
+
await writeFile5(
|
|
3688
|
+
path20.join(baseOutputDir, "llms-full.txt"),
|
|
3662
3689
|
llmsFull,
|
|
3663
3690
|
"utf-8"
|
|
3664
3691
|
);
|
|
@@ -3677,11 +3704,12 @@ import { hideBin } from "yargs/helpers";
|
|
|
3677
3704
|
import yargs from "yargs/yargs";
|
|
3678
3705
|
|
|
3679
3706
|
// src/cli/build/handler.ts
|
|
3680
|
-
import
|
|
3707
|
+
import path25 from "node:path";
|
|
3681
3708
|
|
|
3682
3709
|
// src/vite/build.ts
|
|
3683
|
-
import {
|
|
3684
|
-
import
|
|
3710
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
3711
|
+
import { mkdir as mkdir6, readFile as readFile4, rename as rename2, rm as rm3, writeFile as writeFile6 } from "node:fs/promises";
|
|
3712
|
+
import path23 from "node:path";
|
|
3685
3713
|
import { build as esbuild } from "esbuild";
|
|
3686
3714
|
import { createBuilder } from "vite";
|
|
3687
3715
|
|
|
@@ -3825,7 +3853,7 @@ import {
|
|
|
3825
3853
|
// package.json
|
|
3826
3854
|
var package_default = {
|
|
3827
3855
|
name: "zudoku",
|
|
3828
|
-
version: "0.
|
|
3856
|
+
version: "0.78.0",
|
|
3829
3857
|
type: "module",
|
|
3830
3858
|
sideEffects: [
|
|
3831
3859
|
"**/*.css",
|
|
@@ -3884,6 +3912,11 @@ var package_default = {
|
|
|
3884
3912
|
"./react-query": "./src/lib/core/react-query.ts",
|
|
3885
3913
|
"./icons": "./src/lib/icons.ts",
|
|
3886
3914
|
"./vite": "./src/vite/index.ts",
|
|
3915
|
+
"./server": "./src/app/entry.server.tsx",
|
|
3916
|
+
"./server/adapters/lambda": "./src/app/adapters/lambda.ts",
|
|
3917
|
+
"./server/adapters/node": "./src/app/adapters/node.ts",
|
|
3918
|
+
"./server/adapters/vercel": "./src/app/adapters/vercel.ts",
|
|
3919
|
+
"./server/adapters/cloudflare": "./src/app/adapters/cloudflare.ts",
|
|
3887
3920
|
"./app/*": "./src/app/*",
|
|
3888
3921
|
"./hooks": "./src/lib/hooks/index.ts",
|
|
3889
3922
|
"./processors/*": "./src/lib/plugins/openapi/processors/*.ts",
|
|
@@ -3974,9 +4007,10 @@ var package_default = {
|
|
|
3974
4007
|
hono: "4.12.18",
|
|
3975
4008
|
"http-terminator": "3.2.0",
|
|
3976
4009
|
"javascript-stringify": "2.1.0",
|
|
4010
|
+
jose: "6.2.2",
|
|
3977
4011
|
"json-schema-to-typescript-lite": "15.0.0",
|
|
3978
4012
|
loglevel: "1.9.2",
|
|
3979
|
-
"lucide-react": "1.
|
|
4013
|
+
"lucide-react": "1.16.0",
|
|
3980
4014
|
"mdast-util-from-markdown": "2.0.2",
|
|
3981
4015
|
"mdast-util-mdx": "3.0.0",
|
|
3982
4016
|
"mdast-util-mdx-jsx": "3.2.0",
|
|
@@ -3990,6 +4024,7 @@ var package_default = {
|
|
|
3990
4024
|
picocolors: "1.1.1",
|
|
3991
4025
|
piscina: "5.1.4",
|
|
3992
4026
|
"posthog-node": "5.33.4",
|
|
4027
|
+
"quick-lru": "7.3.0",
|
|
3993
4028
|
"react-error-boundary": "6.1.1",
|
|
3994
4029
|
"react-hook-form": "7.75.0",
|
|
3995
4030
|
"react-is": "catalog:",
|
|
@@ -4009,13 +4044,13 @@ var package_default = {
|
|
|
4009
4044
|
sitemap: "9.0.1",
|
|
4010
4045
|
"strip-ansi": "7.2.0",
|
|
4011
4046
|
"tailwind-merge": "3.6.0",
|
|
4012
|
-
tailwindcss: "4.
|
|
4047
|
+
tailwindcss: "4.3.0",
|
|
4013
4048
|
"tw-animate-css": "1.4.0",
|
|
4014
4049
|
unified: "11.0.5",
|
|
4015
4050
|
"unist-util-visit": "5.1.0",
|
|
4016
4051
|
vaul: "1.1.2",
|
|
4017
4052
|
vfile: "6.0.3",
|
|
4018
|
-
vite: "8.0.
|
|
4053
|
+
vite: "8.0.13",
|
|
4019
4054
|
yaml: "2.8.4",
|
|
4020
4055
|
yargs: "18.0.0",
|
|
4021
4056
|
zod: "4.3.6",
|
|
@@ -4081,6 +4116,46 @@ init_logger();
|
|
|
4081
4116
|
init_package_json();
|
|
4082
4117
|
init_loader();
|
|
4083
4118
|
init_ZudokuConfig();
|
|
4119
|
+
|
|
4120
|
+
// src/lib/manifest.ts
|
|
4121
|
+
init_ProtectedRoutesSchema();
|
|
4122
|
+
|
|
4123
|
+
// src/lib/authentication/cookies.ts
|
|
4124
|
+
var ACCESS_TOKEN_COOKIE = "zudoku-access-token";
|
|
4125
|
+
var REFRESH_TOKEN_COOKIE = "zudoku-refresh-token";
|
|
4126
|
+
var AUTH_PROFILE_COOKIE = "zudoku-auth-profile";
|
|
4127
|
+
|
|
4128
|
+
// src/lib/manifest.ts
|
|
4129
|
+
init_joinUrl();
|
|
4130
|
+
var PROTECTED_CHUNK_DIR = "_protected";
|
|
4131
|
+
var MANIFEST_VERSION = 1;
|
|
4132
|
+
var MANIFEST_FILENAME = "zudoku-manifest.json";
|
|
4133
|
+
var buildManifest = (config2) => {
|
|
4134
|
+
const protectedRoutes = ProtectedRoutesSchema.parse(config2.protectedRoutes);
|
|
4135
|
+
const routePatterns = protectedRoutes ? Object.keys(protectedRoutes) : [];
|
|
4136
|
+
return {
|
|
4137
|
+
version: MANIFEST_VERSION,
|
|
4138
|
+
basePath: config2.basePath ?? "/",
|
|
4139
|
+
ssrEntry: "server/entry.js",
|
|
4140
|
+
static: {
|
|
4141
|
+
prefixes: [joinUrl(config2.basePath, "assets")]
|
|
4142
|
+
},
|
|
4143
|
+
protected: {
|
|
4144
|
+
chunkPrefix: joinUrl(config2.basePath, PROTECTED_CHUNK_DIR),
|
|
4145
|
+
routePatterns
|
|
4146
|
+
},
|
|
4147
|
+
auth: {
|
|
4148
|
+
sessionEndpoint: joinUrl(config2.basePath, "/__z/auth/session"),
|
|
4149
|
+
cookies: {
|
|
4150
|
+
access: ACCESS_TOKEN_COOKIE,
|
|
4151
|
+
refresh: REFRESH_TOKEN_COOKIE,
|
|
4152
|
+
profile: AUTH_PROFILE_COOKIE
|
|
4153
|
+
}
|
|
4154
|
+
}
|
|
4155
|
+
};
|
|
4156
|
+
};
|
|
4157
|
+
|
|
4158
|
+
// src/vite/config.ts
|
|
4084
4159
|
init_joinUrl();
|
|
4085
4160
|
|
|
4086
4161
|
// src/vite/package-root.ts
|
|
@@ -4426,14 +4501,14 @@ var flattenAllOf = (schema2) => {
|
|
|
4426
4501
|
};
|
|
4427
4502
|
|
|
4428
4503
|
// src/lib/util/traverse.ts
|
|
4429
|
-
var traverse = (specification, transform,
|
|
4430
|
-
const transformed = transform(specification,
|
|
4504
|
+
var traverse = (specification, transform, path30 = []) => {
|
|
4505
|
+
const transformed = transform(specification, path30);
|
|
4431
4506
|
if (typeof transformed !== "object" || transformed === null) {
|
|
4432
4507
|
return transformed;
|
|
4433
4508
|
}
|
|
4434
4509
|
const result = Array.isArray(transformed) ? [] : {};
|
|
4435
4510
|
for (const [key, value] of Object.entries(transformed)) {
|
|
4436
|
-
const currentPath = [...
|
|
4511
|
+
const currentPath = [...path30, key];
|
|
4437
4512
|
if (Array.isArray(value)) {
|
|
4438
4513
|
result[key] = value.map(
|
|
4439
4514
|
(item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
|
|
@@ -4452,7 +4527,7 @@ var CIRCULAR_REF = "$[Circular Reference]";
|
|
|
4452
4527
|
var SCHEMA_REF_PREFIX = "$ref:";
|
|
4453
4528
|
|
|
4454
4529
|
// src/lib/oas/parser/dereference/resolveRef.ts
|
|
4455
|
-
var cache = /* @__PURE__ */ new
|
|
4530
|
+
var cache = /* @__PURE__ */ new WeakMap();
|
|
4456
4531
|
var resolveLocalRef = (schema2, ref) => {
|
|
4457
4532
|
if (!cache.has(schema2)) {
|
|
4458
4533
|
cache.set(schema2, /* @__PURE__ */ new Map());
|
|
@@ -4461,9 +4536,9 @@ var resolveLocalRef = (schema2, ref) => {
|
|
|
4461
4536
|
if (schemaCache?.has(ref)) {
|
|
4462
4537
|
return schemaCache.get(ref);
|
|
4463
4538
|
}
|
|
4464
|
-
const
|
|
4539
|
+
const path30 = ref.split("/").slice(1);
|
|
4465
4540
|
let current = schema2;
|
|
4466
|
-
for (const segment of
|
|
4541
|
+
for (const segment of path30) {
|
|
4467
4542
|
if (!current || typeof current !== "object") {
|
|
4468
4543
|
current = null;
|
|
4469
4544
|
}
|
|
@@ -4474,7 +4549,7 @@ var resolveLocalRef = (schema2, ref) => {
|
|
|
4474
4549
|
};
|
|
4475
4550
|
|
|
4476
4551
|
// src/lib/oas/parser/dereference/index.ts
|
|
4477
|
-
var cache2 = /* @__PURE__ */ new
|
|
4552
|
+
var cache2 = /* @__PURE__ */ new WeakMap();
|
|
4478
4553
|
var isIndexableObject = (obj) => obj !== null && typeof obj === "object";
|
|
4479
4554
|
var dereference = async (schema2, resolvers = []) => {
|
|
4480
4555
|
if (cache2.has(schema2)) {
|
|
@@ -4482,7 +4557,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
4482
4557
|
}
|
|
4483
4558
|
const cloned = structuredClone(schema2);
|
|
4484
4559
|
const visited = /* @__PURE__ */ new Set();
|
|
4485
|
-
const resolve = async (current,
|
|
4560
|
+
const resolve = async (current, path30) => {
|
|
4486
4561
|
if (isIndexableObject(current)) {
|
|
4487
4562
|
if (visited.has(current)) {
|
|
4488
4563
|
return CIRCULAR_REF;
|
|
@@ -4490,7 +4565,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
4490
4565
|
visited.add(current);
|
|
4491
4566
|
if (Array.isArray(current)) {
|
|
4492
4567
|
for (let index = 0; index < current.length; index++) {
|
|
4493
|
-
current[index] = await resolve(current[index], `${
|
|
4568
|
+
current[index] = await resolve(current[index], `${path30}/${index}`);
|
|
4494
4569
|
}
|
|
4495
4570
|
} else {
|
|
4496
4571
|
if ("$ref" in current && typeof current.$ref === "string") {
|
|
@@ -4501,13 +4576,13 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
4501
4576
|
for (const resolver of resolvers) {
|
|
4502
4577
|
const resolved = await resolver($ref);
|
|
4503
4578
|
if (resolved) {
|
|
4504
|
-
result2 = await resolve(resolved,
|
|
4579
|
+
result2 = await resolve(resolved, path30);
|
|
4505
4580
|
break;
|
|
4506
4581
|
}
|
|
4507
4582
|
}
|
|
4508
4583
|
if (result2 === void 0) {
|
|
4509
4584
|
const resolved = await resolveLocalRef(cloned, $ref);
|
|
4510
|
-
result2 = await resolve(resolved,
|
|
4585
|
+
result2 = await resolve(resolved, path30);
|
|
4511
4586
|
}
|
|
4512
4587
|
if (hasSiblings) {
|
|
4513
4588
|
if (result2 === CIRCULAR_REF) {
|
|
@@ -4520,7 +4595,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
4520
4595
|
return result2;
|
|
4521
4596
|
}
|
|
4522
4597
|
for (const key in current) {
|
|
4523
|
-
current[key] = await resolve(current[key], `${
|
|
4598
|
+
current[key] = await resolve(current[key], `${path30}/${key}`);
|
|
4524
4599
|
}
|
|
4525
4600
|
}
|
|
4526
4601
|
visited.delete(current);
|
|
@@ -4559,9 +4634,9 @@ var upgradeSchema = (schema2) => {
|
|
|
4559
4634
|
}
|
|
4560
4635
|
return sub;
|
|
4561
4636
|
});
|
|
4562
|
-
schema2 = traverse(schema2, (sub,
|
|
4637
|
+
schema2 = traverse(schema2, (sub, path30) => {
|
|
4563
4638
|
if (sub.example !== void 0) {
|
|
4564
|
-
if (isSchemaPath(
|
|
4639
|
+
if (isSchemaPath(path30 ?? [])) {
|
|
4565
4640
|
sub.examples = [sub.example];
|
|
4566
4641
|
} else {
|
|
4567
4642
|
sub.examples = {
|
|
@@ -4574,11 +4649,11 @@ var upgradeSchema = (schema2) => {
|
|
|
4574
4649
|
}
|
|
4575
4650
|
return sub;
|
|
4576
4651
|
});
|
|
4577
|
-
schema2 = traverse(schema2, (schema3,
|
|
4652
|
+
schema2 = traverse(schema2, (schema3, path30) => {
|
|
4578
4653
|
if (schema3.type === "object" && schema3.properties !== void 0) {
|
|
4579
|
-
const parentPath =
|
|
4654
|
+
const parentPath = path30?.slice(0, -1);
|
|
4580
4655
|
const isMultipart = parentPath?.some((segment, index) => {
|
|
4581
|
-
return segment === "content" &&
|
|
4656
|
+
return segment === "content" && path30?.[index + 1] === "multipart/form-data";
|
|
4582
4657
|
});
|
|
4583
4658
|
if (isMultipart) {
|
|
4584
4659
|
const entries = Object.entries(schema3.properties);
|
|
@@ -4592,8 +4667,8 @@ var upgradeSchema = (schema2) => {
|
|
|
4592
4667
|
}
|
|
4593
4668
|
return schema3;
|
|
4594
4669
|
});
|
|
4595
|
-
schema2 = traverse(schema2, (schema3,
|
|
4596
|
-
if (
|
|
4670
|
+
schema2 = traverse(schema2, (schema3, path30) => {
|
|
4671
|
+
if (path30?.includes("content") && path30.includes("application/octet-stream")) {
|
|
4597
4672
|
return {};
|
|
4598
4673
|
}
|
|
4599
4674
|
if (schema3.type === "string" && schema3.format === "binary") {
|
|
@@ -4619,11 +4694,11 @@ var upgradeSchema = (schema2) => {
|
|
|
4619
4694
|
}
|
|
4620
4695
|
return sub;
|
|
4621
4696
|
});
|
|
4622
|
-
schema2 = traverse(schema2, (schema3,
|
|
4697
|
+
schema2 = traverse(schema2, (schema3, path30) => {
|
|
4623
4698
|
if (schema3.type === "string" && schema3.format === "byte") {
|
|
4624
|
-
const parentPath =
|
|
4699
|
+
const parentPath = path30?.slice(0, -1);
|
|
4625
4700
|
const contentMediaType = parentPath?.find(
|
|
4626
|
-
(_, index) =>
|
|
4701
|
+
(_, index) => path30?.[index - 1] === "content"
|
|
4627
4702
|
);
|
|
4628
4703
|
return {
|
|
4629
4704
|
type: "string",
|
|
@@ -4635,7 +4710,7 @@ var upgradeSchema = (schema2) => {
|
|
|
4635
4710
|
});
|
|
4636
4711
|
return schema2;
|
|
4637
4712
|
};
|
|
4638
|
-
function isSchemaPath(
|
|
4713
|
+
function isSchemaPath(path30) {
|
|
4639
4714
|
const schemaLocations = [
|
|
4640
4715
|
["components", "schemas"],
|
|
4641
4716
|
"properties",
|
|
@@ -4648,10 +4723,10 @@ function isSchemaPath(path28) {
|
|
|
4648
4723
|
];
|
|
4649
4724
|
return schemaLocations.some((location) => {
|
|
4650
4725
|
if (Array.isArray(location)) {
|
|
4651
|
-
return location.every((segment, index) =>
|
|
4726
|
+
return location.every((segment, index) => path30[index] === segment);
|
|
4652
4727
|
}
|
|
4653
|
-
return
|
|
4654
|
-
}) ||
|
|
4728
|
+
return path30.includes(location);
|
|
4729
|
+
}) || path30.includes("schema") || path30.some((segment) => segment.endsWith("Schema"));
|
|
4655
4730
|
}
|
|
4656
4731
|
|
|
4657
4732
|
// src/lib/oas/parser/index.ts
|
|
@@ -4671,7 +4746,7 @@ var parseSchemaInput = async (schemaInput) => {
|
|
|
4671
4746
|
let response;
|
|
4672
4747
|
try {
|
|
4673
4748
|
response = await fetch(schemaInput, {
|
|
4674
|
-
cache: "force-cache"
|
|
4749
|
+
cache: typeof window !== "undefined" ? "force-cache" : void 0
|
|
4675
4750
|
});
|
|
4676
4751
|
} catch (err) {
|
|
4677
4752
|
throw new GraphQLError("Failed to fetch schema", {
|
|
@@ -4733,13 +4808,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
|
|
|
4733
4808
|
"anyOf",
|
|
4734
4809
|
"oneOf"
|
|
4735
4810
|
]);
|
|
4736
|
-
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(),
|
|
4811
|
+
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path30 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
|
|
4737
4812
|
if (obj === null || typeof obj !== "object") return obj;
|
|
4738
4813
|
const refPath = obj.__$ref;
|
|
4739
4814
|
const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
|
|
4740
4815
|
if (isCircular) {
|
|
4741
4816
|
if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
|
|
4742
|
-
const circularProp =
|
|
4817
|
+
const circularProp = path30.find((p) => !OPENAPI_PROPS.has(p)) || path30[0];
|
|
4743
4818
|
return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
|
|
4744
4819
|
}
|
|
4745
4820
|
if (refs.has(obj)) return refs.get(obj);
|
|
@@ -4749,7 +4824,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
|
|
|
4749
4824
|
value,
|
|
4750
4825
|
currentPath,
|
|
4751
4826
|
refs,
|
|
4752
|
-
[...
|
|
4827
|
+
[...path30, key],
|
|
4753
4828
|
currentRefPaths
|
|
4754
4829
|
);
|
|
4755
4830
|
const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
|
|
@@ -4787,7 +4862,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
|
|
|
4787
4862
|
var getAllTags = (schema2) => {
|
|
4788
4863
|
const rootTags = schema2.tags ?? [];
|
|
4789
4864
|
const operations = Object.values(schema2.paths ?? {}).flatMap(
|
|
4790
|
-
(
|
|
4865
|
+
(path30) => HttpMethods.map((k) => path30?.[k]).filter((op) => op != null)
|
|
4791
4866
|
);
|
|
4792
4867
|
const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
|
|
4793
4868
|
const hasUntaggedOperations = operations.some(
|
|
@@ -4842,7 +4917,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
|
|
|
4842
4917
|
var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
|
|
4843
4918
|
var getAllOperations = (paths) => {
|
|
4844
4919
|
const operations = Object.entries(paths ?? {}).flatMap(
|
|
4845
|
-
([
|
|
4920
|
+
([path30, value]) => HttpMethods.flatMap((method) => {
|
|
4846
4921
|
if (!value?.[method]) return [];
|
|
4847
4922
|
const operation = value[method];
|
|
4848
4923
|
const pathParameters = value.parameters ?? [];
|
|
@@ -4862,7 +4937,7 @@ var getAllOperations = (paths) => {
|
|
|
4862
4937
|
return {
|
|
4863
4938
|
...operation,
|
|
4864
4939
|
method,
|
|
4865
|
-
path:
|
|
4940
|
+
path: path30,
|
|
4866
4941
|
parameters,
|
|
4867
4942
|
servers,
|
|
4868
4943
|
tags: operation.tags ?? []
|
|
@@ -5064,10 +5139,10 @@ var resolveSecuritySchemes = (schema2) => {
|
|
|
5064
5139
|
var resolveSecurityRequirements = (securityArray, securitySchemes) => {
|
|
5065
5140
|
if (!securityArray) return [];
|
|
5066
5141
|
return securityArray.map((req) => ({
|
|
5067
|
-
schemes: Object.entries(req).filter(([key]) => !key.startsWith("__")).flatMap(([schemeName,
|
|
5142
|
+
schemes: Object.entries(req).filter(([key]) => !key.startsWith("__")).flatMap(([schemeName, scopes2]) => {
|
|
5068
5143
|
const scheme = securitySchemes.find((s) => s.name === schemeName);
|
|
5069
5144
|
if (!scheme) return [];
|
|
5070
|
-
return [{ scheme, scopes }];
|
|
5145
|
+
return [{ scheme, scopes: scopes2 }];
|
|
5071
5146
|
})
|
|
5072
5147
|
}));
|
|
5073
5148
|
};
|
|
@@ -5360,8 +5435,8 @@ var Schema = builder.objectRef("Schema").implement({
|
|
|
5360
5435
|
}),
|
|
5361
5436
|
paths: t.field({
|
|
5362
5437
|
type: [PathItem],
|
|
5363
|
-
resolve: (root) => Object.entries(root.paths ?? {}).map(([
|
|
5364
|
-
path:
|
|
5438
|
+
resolve: (root) => Object.entries(root.paths ?? {}).map(([path30, value]) => ({
|
|
5439
|
+
path: path30,
|
|
5365
5440
|
// biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
|
|
5366
5441
|
methods: Object.keys(value)
|
|
5367
5442
|
}))
|
|
@@ -5517,7 +5592,7 @@ init_joinUrl();
|
|
|
5517
5592
|
|
|
5518
5593
|
// src/vite/api/schema-codegen.ts
|
|
5519
5594
|
var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
5520
|
-
var getSegmentsFromPath = (
|
|
5595
|
+
var getSegmentsFromPath = (path30) => path30.split("/").slice(1).map(unescapeJsonPointer);
|
|
5521
5596
|
var createLocalRefMap = (obj) => {
|
|
5522
5597
|
const refMap = /* @__PURE__ */ new Map();
|
|
5523
5598
|
const siblingsMap = /* @__PURE__ */ new Map();
|
|
@@ -5548,16 +5623,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
|
|
|
5548
5623
|
/"__refMap\+Siblings:(.*?)"/g,
|
|
5549
5624
|
(_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
|
|
5550
5625
|
);
|
|
5551
|
-
var lookup = (schema2,
|
|
5552
|
-
const parts = getSegmentsFromPath(
|
|
5626
|
+
var lookup = (schema2, path30, filePath) => {
|
|
5627
|
+
const parts = getSegmentsFromPath(path30);
|
|
5553
5628
|
let val = schema2;
|
|
5554
5629
|
for (const part of parts) {
|
|
5555
5630
|
while (val.$ref?.startsWith("#/")) {
|
|
5556
|
-
val = val.$ref ===
|
|
5631
|
+
val = val.$ref === path30 ? val : lookup(schema2, val.$ref, filePath);
|
|
5557
5632
|
}
|
|
5558
5633
|
if (val[part] === void 0) {
|
|
5559
5634
|
throw new Error(
|
|
5560
|
-
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${
|
|
5635
|
+
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path30}`
|
|
5561
5636
|
);
|
|
5562
5637
|
}
|
|
5563
5638
|
val = val[part];
|
|
@@ -5806,8 +5881,8 @@ var SchemaManager = class {
|
|
|
5806
5881
|
}
|
|
5807
5882
|
}
|
|
5808
5883
|
};
|
|
5809
|
-
getLatestSchema = (
|
|
5810
|
-
getSchemasForPath = (
|
|
5884
|
+
getLatestSchema = (path30) => this.processedSchemas[path30]?.at(0);
|
|
5885
|
+
getSchemasForPath = (path30) => this.processedSchemas[path30];
|
|
5811
5886
|
getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
|
|
5812
5887
|
getUrlToFilePathMap = () => {
|
|
5813
5888
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -6173,6 +6248,7 @@ var viteConfigReloadPlugin = () => ({
|
|
|
6173
6248
|
});
|
|
6174
6249
|
|
|
6175
6250
|
// src/vite/plugin-api.ts
|
|
6251
|
+
var PROCESSED_STORE_SUBPATH = "node_modules/.zudoku/processed";
|
|
6176
6252
|
var viteApiPlugin = async () => {
|
|
6177
6253
|
const virtualModuleId4 = "virtual:zudoku-api-plugins";
|
|
6178
6254
|
const resolvedVirtualModuleId4 = `\0${virtualModuleId4}`;
|
|
@@ -6184,7 +6260,7 @@ var viteApiPlugin = async () => {
|
|
|
6184
6260
|
const buildProcessors = buildConfig?.processors ?? [];
|
|
6185
6261
|
const tmpStoreDir = path11.posix.join(
|
|
6186
6262
|
initialConfig.__meta.rootDir,
|
|
6187
|
-
|
|
6263
|
+
PROCESSED_STORE_SUBPATH
|
|
6188
6264
|
);
|
|
6189
6265
|
const processors = [...buildProcessors, ...zuploProcessors];
|
|
6190
6266
|
const schemaManager = new SchemaManager({
|
|
@@ -6764,7 +6840,7 @@ init_ProtectedRoutesSchema();
|
|
|
6764
6840
|
init_joinUrl();
|
|
6765
6841
|
import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
|
|
6766
6842
|
import path13 from "node:path";
|
|
6767
|
-
|
|
6843
|
+
init_url();
|
|
6768
6844
|
var processMarkdownFile = async (filePath) => {
|
|
6769
6845
|
const { content: markdownContent, data: frontmatter } = await readFrontmatter(filePath);
|
|
6770
6846
|
let finalMarkdown = markdownContent;
|
|
@@ -6816,13 +6892,9 @@ var viteMarkdownExportPlugin = () => {
|
|
|
6816
6892
|
config2.protectedRoutes
|
|
6817
6893
|
);
|
|
6818
6894
|
if (protectedRoutes) {
|
|
6819
|
-
const
|
|
6820
|
-
return Object.keys(protectedRoutes).some(
|
|
6821
|
-
(route) => matchPath({ path: route, end: true }, routePath)
|
|
6822
|
-
);
|
|
6823
|
-
};
|
|
6895
|
+
const patterns = Object.keys(protectedRoutes);
|
|
6824
6896
|
for (const routePath of Object.keys(markdownFiles)) {
|
|
6825
|
-
if (
|
|
6897
|
+
if (matchesAnyProtectedPattern(patterns, routePath)) {
|
|
6826
6898
|
delete markdownFiles[routePath];
|
|
6827
6899
|
}
|
|
6828
6900
|
}
|
|
@@ -7501,6 +7573,155 @@ function vitePlugin() {
|
|
|
7501
7573
|
];
|
|
7502
7574
|
}
|
|
7503
7575
|
|
|
7576
|
+
// src/vite/protected/registry.ts
|
|
7577
|
+
init_ProtectedRoutesSchema();
|
|
7578
|
+
init_joinUrl();
|
|
7579
|
+
init_url();
|
|
7580
|
+
import { matchPath as matchPath2 } from "react-router";
|
|
7581
|
+
var scopes = /* @__PURE__ */ new Map();
|
|
7582
|
+
var clearProtectedRegistry = () => scopes.clear();
|
|
7583
|
+
var registerProtectedScope = (moduleId, scope) => {
|
|
7584
|
+
const list = scopes.get(moduleId);
|
|
7585
|
+
if (list) list.push(scope);
|
|
7586
|
+
else scopes.set(moduleId, [scope]);
|
|
7587
|
+
};
|
|
7588
|
+
var scopeMatchesPattern = (scope, pattern) => {
|
|
7589
|
+
if (scope.type === "route") {
|
|
7590
|
+
return matchesProtectedPattern(pattern, joinUrl(scope.path));
|
|
7591
|
+
}
|
|
7592
|
+
const root = joinUrl(scope.root);
|
|
7593
|
+
if (!pattern.includes("*")) {
|
|
7594
|
+
return matchesProtectedPattern(pattern, root);
|
|
7595
|
+
}
|
|
7596
|
+
return matchPath2({ path: pattern, end: false }, root) != null;
|
|
7597
|
+
};
|
|
7598
|
+
var getProtectedSourceMatcher = (config2) => {
|
|
7599
|
+
const protectedRoutes = ProtectedRoutesSchema.parse(config2.protectedRoutes);
|
|
7600
|
+
const patterns = protectedRoutes ? Object.keys(protectedRoutes) : [];
|
|
7601
|
+
if (patterns.length === 0) {
|
|
7602
|
+
return { match: () => false, enabled: false, patterns };
|
|
7603
|
+
}
|
|
7604
|
+
return {
|
|
7605
|
+
enabled: true,
|
|
7606
|
+
patterns,
|
|
7607
|
+
match: (id) => {
|
|
7608
|
+
const pathOnly = id.split("?")[0] ?? id;
|
|
7609
|
+
const moduleScopes = scopes.get(pathOnly);
|
|
7610
|
+
if (!moduleScopes) return false;
|
|
7611
|
+
return moduleScopes.some(
|
|
7612
|
+
(s) => patterns.some((p) => scopeMatchesPattern(s, p))
|
|
7613
|
+
);
|
|
7614
|
+
}
|
|
7615
|
+
};
|
|
7616
|
+
};
|
|
7617
|
+
var findUnmatchedProtectedPatterns = (patterns) => patterns.filter(
|
|
7618
|
+
(p) => ![...scopes.values()].some(
|
|
7619
|
+
(scopeList) => scopeList.some((s) => scopeMatchesPattern(s, p))
|
|
7620
|
+
)
|
|
7621
|
+
);
|
|
7622
|
+
|
|
7623
|
+
// src/vite/protected/annotator.ts
|
|
7624
|
+
var walk = (node, visit9) => {
|
|
7625
|
+
if (!node || typeof node !== "object") return;
|
|
7626
|
+
if (typeof node.type === "string") visit9(node);
|
|
7627
|
+
for (const key of Object.keys(node)) {
|
|
7628
|
+
if (key === "loc" || key === "start" || key === "end" || key === "range") {
|
|
7629
|
+
continue;
|
|
7630
|
+
}
|
|
7631
|
+
const val = node[key];
|
|
7632
|
+
if (Array.isArray(val)) {
|
|
7633
|
+
for (const v of val) walk(v, visit9);
|
|
7634
|
+
} else if (val && typeof val === "object") {
|
|
7635
|
+
walk(val, visit9);
|
|
7636
|
+
}
|
|
7637
|
+
}
|
|
7638
|
+
};
|
|
7639
|
+
var literalString = (node) => node?.type === "Literal" && typeof node.value === "string" ? node.value : void 0;
|
|
7640
|
+
var propKey = (prop) => prop.key?.type === "Identifier" ? prop.key.name : literalString(prop.key);
|
|
7641
|
+
var collectImportSpecs = (node) => {
|
|
7642
|
+
const out = [];
|
|
7643
|
+
walk(node, (n) => {
|
|
7644
|
+
if (n.type === "ImportExpression") {
|
|
7645
|
+
const spec = literalString(n.source);
|
|
7646
|
+
if (spec) out.push(spec);
|
|
7647
|
+
}
|
|
7648
|
+
});
|
|
7649
|
+
return out;
|
|
7650
|
+
};
|
|
7651
|
+
var matchPathObject = (node) => {
|
|
7652
|
+
if (node.type !== "ObjectExpression") return;
|
|
7653
|
+
let root;
|
|
7654
|
+
const siblingValues = [];
|
|
7655
|
+
for (const prop of node.properties ?? []) {
|
|
7656
|
+
if (prop.type !== "Property") continue;
|
|
7657
|
+
const name = propKey(prop);
|
|
7658
|
+
const strValue = literalString(prop.value);
|
|
7659
|
+
if (name === "path" && strValue) root = strValue;
|
|
7660
|
+
else siblingValues.push(prop.value);
|
|
7661
|
+
}
|
|
7662
|
+
if (!root) return;
|
|
7663
|
+
const specs = siblingValues.flatMap(collectImportSpecs);
|
|
7664
|
+
if (specs.length === 0) return;
|
|
7665
|
+
return { root, specs };
|
|
7666
|
+
};
|
|
7667
|
+
var matchRouteDict = (node) => {
|
|
7668
|
+
if (node.type !== "ObjectExpression") return;
|
|
7669
|
+
const props = node.properties ?? [];
|
|
7670
|
+
if (props.length === 0) return;
|
|
7671
|
+
const pairs = [];
|
|
7672
|
+
for (const prop of props) {
|
|
7673
|
+
if (prop.type !== "Property") return;
|
|
7674
|
+
const key = literalString(prop.key);
|
|
7675
|
+
if (!key?.startsWith("/") || key.includes(".")) return;
|
|
7676
|
+
if (prop.value?.type !== "ArrowFunctionExpression" || prop.value.body?.type !== "ImportExpression") {
|
|
7677
|
+
return;
|
|
7678
|
+
}
|
|
7679
|
+
const spec = literalString(prop.value.body.source);
|
|
7680
|
+
if (!spec) return;
|
|
7681
|
+
pairs.push({ root: key, spec });
|
|
7682
|
+
}
|
|
7683
|
+
return pairs;
|
|
7684
|
+
};
|
|
7685
|
+
var protectedAnnotatorPlugin = () => ({
|
|
7686
|
+
name: "zudoku:protected-annotator",
|
|
7687
|
+
buildStart() {
|
|
7688
|
+
clearProtectedRegistry();
|
|
7689
|
+
},
|
|
7690
|
+
async transform(code, id) {
|
|
7691
|
+
if (id.includes("/node_modules/")) return;
|
|
7692
|
+
if (!code.includes("import(")) return;
|
|
7693
|
+
let ast;
|
|
7694
|
+
try {
|
|
7695
|
+
ast = this.parse(code);
|
|
7696
|
+
} catch (err) {
|
|
7697
|
+
this.warn(
|
|
7698
|
+
`protected-annotator: failed to parse ${id}: ${err instanceof Error ? err.message : String(err)}. Protected gating will NOT apply to this module.`
|
|
7699
|
+
);
|
|
7700
|
+
return;
|
|
7701
|
+
}
|
|
7702
|
+
const tasks = [];
|
|
7703
|
+
walk(ast, (node) => {
|
|
7704
|
+
const a = matchPathObject(node);
|
|
7705
|
+
if (a) for (const spec of a.specs) tasks.push({ spec, root: a.root });
|
|
7706
|
+
const b = matchRouteDict(node);
|
|
7707
|
+
if (b) for (const { spec, root } of b) tasks.push({ spec, root });
|
|
7708
|
+
});
|
|
7709
|
+
for (const { spec, root } of tasks) {
|
|
7710
|
+
const resolved = await this.resolve(spec, id);
|
|
7711
|
+
if (!resolved || resolved.external) {
|
|
7712
|
+
this.warn(
|
|
7713
|
+
`Route-shaped import "${spec}" in ${id} did not resolve to a first-party module; protected gating will not apply.`
|
|
7714
|
+
);
|
|
7715
|
+
continue;
|
|
7716
|
+
}
|
|
7717
|
+
registerProtectedScope(resolved.id.split("?")[0] ?? resolved.id, {
|
|
7718
|
+
type: "subtree",
|
|
7719
|
+
root
|
|
7720
|
+
});
|
|
7721
|
+
}
|
|
7722
|
+
}
|
|
7723
|
+
});
|
|
7724
|
+
|
|
7504
7725
|
// src/vite/config.ts
|
|
7505
7726
|
var getAppClientEntryPath = () => path16.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
|
|
7506
7727
|
var getAppServerEntryPath = () => path16.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
|
|
@@ -7512,11 +7733,15 @@ var defineEnvVars = (vars) => Object.fromEntries(
|
|
|
7512
7733
|
[`import.meta.env.${v}`, JSON.stringify(process.env[v])]
|
|
7513
7734
|
])
|
|
7514
7735
|
);
|
|
7515
|
-
async function getViteConfig(dir, configEnv) {
|
|
7736
|
+
async function getViteConfig(dir, configEnv, options = {}) {
|
|
7516
7737
|
const { config: config2, publicEnv: publicEnv2, envPrefix: envPrefix2 } = await loadZudokuConfig(
|
|
7517
7738
|
configEnv,
|
|
7518
7739
|
dir
|
|
7519
7740
|
);
|
|
7741
|
+
const { match: isProtectedSource, enabled: hasProtectedSources } = getProtectedSourceMatcher(config2);
|
|
7742
|
+
const shouldProtectChunks = hasProtectedSources && options.ssr === true;
|
|
7743
|
+
const isProtectedChunk = (chunk) => chunk.facadeModuleId && isProtectedSource(chunk.facadeModuleId) || chunk.moduleIds.some(isProtectedSource);
|
|
7744
|
+
const isWorker = options.adapter === "cloudflare";
|
|
7520
7745
|
const cdnUrl = CdnUrlSchema.parse(config2.cdnUrl);
|
|
7521
7746
|
const base = cdnUrl?.base ? joinUrl(cdnUrl.base, config2.basePath) : config2.basePath;
|
|
7522
7747
|
if (cdnUrl && !hasLoggedCdnInfo) {
|
|
@@ -7542,6 +7767,10 @@ async function getViteConfig(dir, configEnv) {
|
|
|
7542
7767
|
root: dir,
|
|
7543
7768
|
base,
|
|
7544
7769
|
appType: "custom",
|
|
7770
|
+
// Cloudflare Workers: `webworker` makes Vite pick the browser platform
|
|
7771
|
+
// for rolldown and avoids emitting `createRequire(import.meta.url)`,
|
|
7772
|
+
// which is undefined in Workers. See vitejs/vite#21969 (fix in 8.0.4+).
|
|
7773
|
+
ssr: isWorker ? { target: "webworker" } : void 0,
|
|
7545
7774
|
configFile: false,
|
|
7546
7775
|
clearScreen: false,
|
|
7547
7776
|
logLevel: process.env.LOG_LEVEL ?? "info",
|
|
@@ -7599,13 +7828,19 @@ async function getViteConfig(dir, configEnv) {
|
|
|
7599
7828
|
environments: {
|
|
7600
7829
|
client: {
|
|
7601
7830
|
build: {
|
|
7831
|
+
manifest: true,
|
|
7602
7832
|
rolldownOptions: {
|
|
7603
|
-
input: "zudoku/app/entry.client.tsx"
|
|
7833
|
+
input: "zudoku/app/entry.client.tsx",
|
|
7834
|
+
output: shouldProtectChunks ? {
|
|
7835
|
+
entryFileNames: (chunk) => isProtectedChunk(chunk) ? `${PROTECTED_CHUNK_DIR}/[name]-[hash].js` : "assets/[name]-[hash].js",
|
|
7836
|
+
chunkFileNames: (chunk) => isProtectedChunk(chunk) ? `${PROTECTED_CHUNK_DIR}/[name]-[hash].js` : "assets/[name]-[hash].js"
|
|
7837
|
+
} : void 0
|
|
7604
7838
|
}
|
|
7605
7839
|
}
|
|
7606
7840
|
},
|
|
7607
7841
|
ssr: {
|
|
7608
|
-
|
|
7842
|
+
// Build: bundle all for self-contained SSR output; dev uses minimal externals for speed.
|
|
7843
|
+
resolve: configEnv.command === "build" ? { noExternal: true } : {
|
|
7609
7844
|
noExternal: [/zudoku/, "@mdx-js/react"],
|
|
7610
7845
|
external: ["@shikijs/themes", "@shikijs/langs"]
|
|
7611
7846
|
},
|
|
@@ -7613,7 +7848,9 @@ async function getViteConfig(dir, configEnv) {
|
|
|
7613
7848
|
outDir: path16.resolve(
|
|
7614
7849
|
path16.join(dir, "dist", config2.basePath ?? "", "server")
|
|
7615
7850
|
),
|
|
7851
|
+
copyPublicDir: false,
|
|
7616
7852
|
rolldownOptions: {
|
|
7853
|
+
logLevel: "warn",
|
|
7617
7854
|
input: ["zudoku/app/entry.server.tsx", config2.__meta.configPath]
|
|
7618
7855
|
}
|
|
7619
7856
|
}
|
|
@@ -7621,6 +7858,9 @@ async function getViteConfig(dir, configEnv) {
|
|
|
7621
7858
|
},
|
|
7622
7859
|
experimental: {
|
|
7623
7860
|
renderBuiltUrl(filename) {
|
|
7861
|
+
if (filename.startsWith(`${PROTECTED_CHUNK_DIR}/`)) {
|
|
7862
|
+
return joinUrl(config2.basePath, `/${filename}`);
|
|
7863
|
+
}
|
|
7624
7864
|
if (cdnUrl?.base && [".js", ".css"].includes(path16.extname(filename))) {
|
|
7625
7865
|
return joinUrl(cdnUrl.base, filename);
|
|
7626
7866
|
}
|
|
@@ -7645,7 +7885,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
7645
7885
|
"/__z/entry.client.tsx",
|
|
7646
7886
|
"**/pagefind.js"
|
|
7647
7887
|
],
|
|
7648
|
-
plugins: [vitePlugin()],
|
|
7888
|
+
plugins: [protectedAnnotatorPlugin(), vitePlugin()],
|
|
7649
7889
|
future: {
|
|
7650
7890
|
removeServerModuleGraph: "warn",
|
|
7651
7891
|
removeSsrLoadModule: "warn",
|
|
@@ -7728,12 +7968,24 @@ ${cssLinks}
|
|
|
7728
7968
|
`.trim();
|
|
7729
7969
|
}
|
|
7730
7970
|
|
|
7971
|
+
// src/vite/manifest.ts
|
|
7972
|
+
import { writeFile as writeFile3 } from "node:fs/promises";
|
|
7973
|
+
import path17 from "node:path";
|
|
7974
|
+
var writeManifest = async (distDir, config2) => {
|
|
7975
|
+
await writeFile3(
|
|
7976
|
+
path17.join(distDir, MANIFEST_FILENAME),
|
|
7977
|
+
`${JSON.stringify(buildManifest(config2), null, 2)}
|
|
7978
|
+
`,
|
|
7979
|
+
"utf-8"
|
|
7980
|
+
);
|
|
7981
|
+
};
|
|
7982
|
+
|
|
7731
7983
|
// src/vite/output.ts
|
|
7732
7984
|
init_package_json();
|
|
7733
7985
|
init_joinUrl();
|
|
7734
7986
|
import assert from "node:assert";
|
|
7735
|
-
import { cp, mkdir as mkdir3, writeFile as
|
|
7736
|
-
import
|
|
7987
|
+
import { cp, mkdir as mkdir3, writeFile as writeFile4 } from "node:fs/promises";
|
|
7988
|
+
import path18 from "node:path";
|
|
7737
7989
|
var pkgJson = getZudokuPackageJson();
|
|
7738
7990
|
function generateOutput({
|
|
7739
7991
|
config: config2,
|
|
@@ -7790,10 +8042,10 @@ async function writeOutput(dir, {
|
|
|
7790
8042
|
rewrites
|
|
7791
8043
|
}) {
|
|
7792
8044
|
const output = generateOutput({ config: config2, redirects, rewrites });
|
|
7793
|
-
const outputDir = process.env.VERCEL ?
|
|
8045
|
+
const outputDir = process.env.VERCEL ? path18.join(dir, ".vercel/output") : path18.join(dir, "dist/.output");
|
|
7794
8046
|
await mkdir3(outputDir, { recursive: true });
|
|
7795
|
-
const outputFile =
|
|
7796
|
-
await
|
|
8047
|
+
const outputFile = path18.join(outputDir, "config.json");
|
|
8048
|
+
await writeFile4(outputFile, JSON.stringify(output, null, 2), "utf-8");
|
|
7797
8049
|
if (process.env.VERCEL) {
|
|
7798
8050
|
console.log("Wrote Vercel output to", outputDir);
|
|
7799
8051
|
}
|
|
@@ -7805,7 +8057,7 @@ init_file_exists();
|
|
|
7805
8057
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
7806
8058
|
import { readFile as readFile2, rm } from "node:fs/promises";
|
|
7807
8059
|
import os from "node:os";
|
|
7808
|
-
import
|
|
8060
|
+
import path21 from "node:path";
|
|
7809
8061
|
import { pathToFileURL } from "node:url";
|
|
7810
8062
|
import { createIndex } from "pagefind";
|
|
7811
8063
|
import colors7 from "picocolors";
|
|
@@ -7847,7 +8099,7 @@ function throttle(fn) {
|
|
|
7847
8099
|
init_joinUrl();
|
|
7848
8100
|
import { createWriteStream, existsSync } from "node:fs";
|
|
7849
8101
|
import { mkdir as mkdir4 } from "node:fs/promises";
|
|
7850
|
-
import
|
|
8102
|
+
import path19 from "node:path";
|
|
7851
8103
|
import colors5 from "picocolors";
|
|
7852
8104
|
import { SitemapStream } from "sitemap";
|
|
7853
8105
|
async function generateSitemap({
|
|
@@ -7861,11 +8113,11 @@ async function generateSitemap({
|
|
|
7861
8113
|
return;
|
|
7862
8114
|
}
|
|
7863
8115
|
const sitemap = new SitemapStream({ hostname: config2.siteUrl });
|
|
7864
|
-
const outputDir =
|
|
8116
|
+
const outputDir = path19.resolve(baseOutputDir, config2.outDir ?? "");
|
|
7865
8117
|
if (!existsSync(outputDir)) {
|
|
7866
8118
|
await mkdir4(outputDir, { recursive: true });
|
|
7867
8119
|
}
|
|
7868
|
-
const sitemapOutputPath =
|
|
8120
|
+
const sitemapOutputPath = path19.join(outputDir, "sitemap.xml");
|
|
7869
8121
|
const writeStream = createWriteStream(sitemapOutputPath);
|
|
7870
8122
|
sitemap.pipe(writeStream);
|
|
7871
8123
|
let lastmod;
|
|
@@ -7895,14 +8147,14 @@ async function generateSitemap({
|
|
|
7895
8147
|
|
|
7896
8148
|
// src/vite/prerender/utils.ts
|
|
7897
8149
|
init_joinUrl();
|
|
7898
|
-
var resolveRoutePath = (
|
|
7899
|
-
const segments =
|
|
8150
|
+
var resolveRoutePath = (path30) => {
|
|
8151
|
+
const segments = path30.split("/");
|
|
7900
8152
|
if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
|
|
7901
8153
|
return void 0;
|
|
7902
8154
|
}
|
|
7903
8155
|
return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
|
|
7904
8156
|
};
|
|
7905
|
-
var isSkipped = (
|
|
8157
|
+
var isSkipped = (path30) => path30.includes("*") || /^\d+$/.test(path30);
|
|
7906
8158
|
var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
|
|
7907
8159
|
if (route.path && isSkipped(route.path)) return [];
|
|
7908
8160
|
const routePath = route.path ? resolveRoutePath(route.path) : void 0;
|
|
@@ -7951,12 +8203,12 @@ var prerender = async ({
|
|
|
7951
8203
|
serverConfigFilename,
|
|
7952
8204
|
writeRedirects = true
|
|
7953
8205
|
}) => {
|
|
7954
|
-
const distDir =
|
|
8206
|
+
const distDir = path21.join(dir, "dist", basePath);
|
|
7955
8207
|
const serverConfigPath = pathToFileURL(
|
|
7956
|
-
|
|
8208
|
+
path21.join(distDir, "server", serverConfigFilename)
|
|
7957
8209
|
).href;
|
|
7958
8210
|
const entryServerPath = pathToFileURL(
|
|
7959
|
-
|
|
8211
|
+
path21.join(distDir, "server/entry.server.js")
|
|
7960
8212
|
).href;
|
|
7961
8213
|
const rawConfig = await import(serverConfigPath).then(
|
|
7962
8214
|
(m) => m.default
|
|
@@ -8068,7 +8320,7 @@ var prerender = async ({
|
|
|
8068
8320
|
}
|
|
8069
8321
|
if (isTTY()) writeLine("");
|
|
8070
8322
|
const { outputPath } = await pagefindIndex.writeFiles({
|
|
8071
|
-
outputPath:
|
|
8323
|
+
outputPath: path21.join(distDir, "pagefind")
|
|
8072
8324
|
});
|
|
8073
8325
|
if (outputPath) {
|
|
8074
8326
|
const duration = (performance.now() - pagefindStart) / 1e3;
|
|
@@ -8092,7 +8344,7 @@ var prerender = async ({
|
|
|
8092
8344
|
const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
|
|
8093
8345
|
const docsConfig = DocsConfigSchema2.parse(config2.docs);
|
|
8094
8346
|
const llmsConfig = docsConfig.llms ?? {};
|
|
8095
|
-
const markdownInfoPath =
|
|
8347
|
+
const markdownInfoPath = path21.join(
|
|
8096
8348
|
dir,
|
|
8097
8349
|
"node_modules/.zudoku/markdown-info.json"
|
|
8098
8350
|
);
|
|
@@ -8117,7 +8369,7 @@ var prerender = async ({
|
|
|
8117
8369
|
await Promise.all(
|
|
8118
8370
|
markdownFileInfos.map((info) => {
|
|
8119
8371
|
const outputPath = getMarkdownOutputPath(distDir, info.routePath);
|
|
8120
|
-
if (!
|
|
8372
|
+
if (!path21.resolve(outputPath).startsWith(path21.resolve(distDir))) {
|
|
8121
8373
|
return;
|
|
8122
8374
|
}
|
|
8123
8375
|
return rm(outputPath).catch(() => {
|
|
@@ -8175,19 +8427,123 @@ var getContainerMemoryLimitMb = () => {
|
|
|
8175
8427
|
return void 0;
|
|
8176
8428
|
};
|
|
8177
8429
|
|
|
8430
|
+
// src/vite/protected/build.ts
|
|
8431
|
+
import { mkdir as mkdir5, readdir, readFile as readFile3, rename, rm as rm2 } from "node:fs/promises";
|
|
8432
|
+
import path22 from "node:path";
|
|
8433
|
+
init_joinUrl();
|
|
8434
|
+
var assertProtectedPatternsCovered = (config2) => {
|
|
8435
|
+
const { patterns } = getProtectedSourceMatcher(config2);
|
|
8436
|
+
const unmatched = findUnmatchedProtectedPatterns(patterns);
|
|
8437
|
+
if (unmatched.length === 0) return;
|
|
8438
|
+
throw new Error(
|
|
8439
|
+
`[zudoku] protectedRoutes patterns with no matching content: ${unmatched.map((p) => `"${p}"`).join(", ")}.
|
|
8440
|
+
Either the pattern is a typo, or the route uses an inline element / dynamic path that isn't code-split. Load the route via dynamic import so it gets its own chunk, otherwise its JS ships in the public bundle.`
|
|
8441
|
+
);
|
|
8442
|
+
};
|
|
8443
|
+
var findProtectedLeaks = (output) => {
|
|
8444
|
+
const isProtected = (fileName) => fileName.startsWith(`${PROTECTED_CHUNK_DIR}/`);
|
|
8445
|
+
const chunks = output.filter((o) => o.type === "chunk");
|
|
8446
|
+
const byFileName = new Map(chunks.map((c) => [c.fileName, c]));
|
|
8447
|
+
const leaks = [];
|
|
8448
|
+
for (const entry of chunks.filter(
|
|
8449
|
+
(c) => c.isEntry && !isProtected(c.fileName)
|
|
8450
|
+
)) {
|
|
8451
|
+
const visited = /* @__PURE__ */ new Set();
|
|
8452
|
+
const stack = [{ fileName: entry.fileName, path: [entry.fileName] }];
|
|
8453
|
+
while (stack.length > 0) {
|
|
8454
|
+
const { fileName, path: path30 } = stack.pop();
|
|
8455
|
+
if (visited.has(fileName)) continue;
|
|
8456
|
+
visited.add(fileName);
|
|
8457
|
+
for (const imp of byFileName.get(fileName)?.imports ?? []) {
|
|
8458
|
+
const next = [...path30, imp];
|
|
8459
|
+
if (isProtected(imp)) {
|
|
8460
|
+
leaks.push(next.join(" -> "));
|
|
8461
|
+
continue;
|
|
8462
|
+
}
|
|
8463
|
+
stack.push({ fileName: imp, path: next });
|
|
8464
|
+
}
|
|
8465
|
+
}
|
|
8466
|
+
}
|
|
8467
|
+
return leaks;
|
|
8468
|
+
};
|
|
8469
|
+
var assertNoProtectedLeaks = (output) => {
|
|
8470
|
+
const protectedEntries = output.filter((o) => o.type === "chunk").filter(
|
|
8471
|
+
(c) => c.isEntry && c.fileName.startsWith(`${PROTECTED_CHUNK_DIR}/`)
|
|
8472
|
+
).map((c) => c.fileName);
|
|
8473
|
+
if (protectedEntries.length > 0) {
|
|
8474
|
+
throw new Error(
|
|
8475
|
+
`Protected chunk(s) marked as entries:
|
|
8476
|
+
${protectedEntries.join("\n ")}
|
|
8477
|
+
Entry chunks are loaded outside the gated import path. Move the entry to a public chunk that dynamically imports the protected one.`
|
|
8478
|
+
);
|
|
8479
|
+
}
|
|
8480
|
+
const leaks = findProtectedLeaks(output);
|
|
8481
|
+
if (leaks.length === 0) return;
|
|
8482
|
+
throw new Error(
|
|
8483
|
+
`Protected chunk(s) statically reachable from public entry:
|
|
8484
|
+
${leaks.join("\n ")}
|
|
8485
|
+
This eagerly pulls gated content into the public bundle. Check that nothing in non-protected entry code statically imports the protected module.`
|
|
8486
|
+
);
|
|
8487
|
+
};
|
|
8488
|
+
var moveProtectedChunks = async (clientOutDir, serverOutDir) => {
|
|
8489
|
+
const srcDir = path22.join(clientOutDir, PROTECTED_CHUNK_DIR);
|
|
8490
|
+
const files = await readdir(srcDir).catch((err) => {
|
|
8491
|
+
if (err.code === "ENOENT") return null;
|
|
8492
|
+
throw err;
|
|
8493
|
+
});
|
|
8494
|
+
if (!files) return;
|
|
8495
|
+
const destDir = path22.join(serverOutDir, PROTECTED_CHUNK_DIR);
|
|
8496
|
+
await mkdir5(destDir, { recursive: true });
|
|
8497
|
+
await Promise.all(
|
|
8498
|
+
files.map(
|
|
8499
|
+
(file) => rename(path22.join(srcDir, file), path22.join(destDir, file))
|
|
8500
|
+
)
|
|
8501
|
+
);
|
|
8502
|
+
const leftover = await readdir(srcDir).catch(() => []);
|
|
8503
|
+
if (leftover.length > 0) {
|
|
8504
|
+
throw new Error(
|
|
8505
|
+
`moveProtectedChunks left ${leftover.length} file(s) in ${srcDir}: ${leftover.join(", ")}.
|
|
8506
|
+
These would be served publicly. Aborting build.`
|
|
8507
|
+
);
|
|
8508
|
+
}
|
|
8509
|
+
await rm2(srcDir, { recursive: true, force: true });
|
|
8510
|
+
};
|
|
8511
|
+
var assertCloudflareWranglerGatesProtected = async (dir, config2) => {
|
|
8512
|
+
const { enabled } = getProtectedSourceMatcher(config2);
|
|
8513
|
+
if (!enabled) return;
|
|
8514
|
+
const protectedPrefix = `${joinUrl(config2.basePath, PROTECTED_CHUNK_DIR)}/`;
|
|
8515
|
+
const candidates = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
|
|
8516
|
+
for (const name of candidates) {
|
|
8517
|
+
const file = await readFile3(path22.join(dir, name), "utf-8").catch(
|
|
8518
|
+
() => void 0
|
|
8519
|
+
);
|
|
8520
|
+
if (file === void 0) continue;
|
|
8521
|
+
if (file.includes("run_worker_first") && file.includes(protectedPrefix)) {
|
|
8522
|
+
return;
|
|
8523
|
+
}
|
|
8524
|
+
throw new Error(
|
|
8525
|
+
`[zudoku] ${name} must configure \`run_worker_first\` to include \`${protectedPrefix}*\` so the auth gate runs before the assets binding serves protected chunks. Without it, ${protectedPrefix}* is publicly readable. See https://developers.cloudflare.com/workers/static-assets/binding/#run_worker_first.`
|
|
8526
|
+
);
|
|
8527
|
+
}
|
|
8528
|
+
throw new Error(
|
|
8529
|
+
`[zudoku] No wrangler config found in ${dir} (looked for ${candidates.join(", ")}). Cloudflare adapter requires wrangler config with \`run_worker_first\` covering \`${protectedPrefix}*\`.`
|
|
8530
|
+
);
|
|
8531
|
+
};
|
|
8532
|
+
|
|
8178
8533
|
// src/vite/build.ts
|
|
8179
8534
|
var DIST_DIR = "dist";
|
|
8180
8535
|
async function runBuild(options) {
|
|
8181
8536
|
const { dir, ssr, adapter = "node" } = options;
|
|
8182
|
-
const viteConfig = await getViteConfig(
|
|
8183
|
-
|
|
8184
|
-
command: "build"
|
|
8185
|
-
|
|
8537
|
+
const viteConfig = await getViteConfig(
|
|
8538
|
+
dir,
|
|
8539
|
+
{ mode: "production", command: "build" },
|
|
8540
|
+
{ adapter, ssr }
|
|
8541
|
+
);
|
|
8186
8542
|
const builder2 = await createBuilder(viteConfig);
|
|
8187
8543
|
invariant(builder2.environments.client, "Client environment is missing");
|
|
8188
8544
|
invariant(builder2.environments.ssr, "SSR environment is missing");
|
|
8189
|
-
const distDir =
|
|
8190
|
-
await
|
|
8545
|
+
const distDir = path23.resolve(path23.join(dir, "dist"));
|
|
8546
|
+
await rm3(distDir, { recursive: true, force: true });
|
|
8191
8547
|
const [clientResult, serverResult] = await Promise.all([
|
|
8192
8548
|
builder2.build(builder2.environments.client),
|
|
8193
8549
|
builder2.build(builder2.environments.ssr)
|
|
@@ -8226,10 +8582,23 @@ async function runBuild(options) {
|
|
|
8226
8582
|
dir,
|
|
8227
8583
|
adapter,
|
|
8228
8584
|
serverOutDir,
|
|
8229
|
-
html
|
|
8230
|
-
basePath: config2.basePath
|
|
8585
|
+
html
|
|
8231
8586
|
});
|
|
8232
|
-
|
|
8587
|
+
assertProtectedPatternsCovered(config2);
|
|
8588
|
+
assertNoProtectedLeaks(clientResult.output);
|
|
8589
|
+
if (adapter !== "cloudflare") {
|
|
8590
|
+
await moveProtectedChunks(clientOutDir, serverOutDir);
|
|
8591
|
+
} else {
|
|
8592
|
+
await assertCloudflareWranglerGatesProtected(dir, config2);
|
|
8593
|
+
}
|
|
8594
|
+
await writeFile6(
|
|
8595
|
+
path23.join(distDir, "package.json"),
|
|
8596
|
+
`${JSON.stringify({ type: "module" }, null, 2)}
|
|
8597
|
+
`,
|
|
8598
|
+
"utf-8"
|
|
8599
|
+
);
|
|
8600
|
+
await writeManifest(distDir, config2);
|
|
8601
|
+
await rm3(path23.join(clientOutDir, "index.html"), { force: true });
|
|
8233
8602
|
} else {
|
|
8234
8603
|
await runPrerender({
|
|
8235
8604
|
dir,
|
|
@@ -8260,25 +8629,25 @@ var runPrerender = async (options) => {
|
|
|
8260
8629
|
serverConfigFilename,
|
|
8261
8630
|
writeRedirects: process.env.VERCEL === void 0
|
|
8262
8631
|
});
|
|
8263
|
-
const indexHtml =
|
|
8632
|
+
const indexHtml = path23.join(clientOutDir, "index.html");
|
|
8264
8633
|
if (!workerResults.find((r) => r.outputPath === indexHtml)) {
|
|
8265
|
-
await
|
|
8634
|
+
await writeFile6(indexHtml, html, "utf-8");
|
|
8266
8635
|
}
|
|
8267
8636
|
const statusPages = workerResults.flatMap(
|
|
8268
|
-
(r) => /^(400|404|500)\.html$/.test(
|
|
8637
|
+
(r) => /^(400|404|500)\.html$/.test(path23.basename(r.outputPath)) ? r.outputPath : []
|
|
8269
8638
|
);
|
|
8270
8639
|
for (const statusPage of statusPages) {
|
|
8271
|
-
await
|
|
8640
|
+
await rename2(
|
|
8272
8641
|
statusPage,
|
|
8273
|
-
|
|
8642
|
+
path23.join(dir, DIST_DIR, path23.basename(statusPage))
|
|
8274
8643
|
);
|
|
8275
8644
|
}
|
|
8276
|
-
await
|
|
8645
|
+
await rm3(serverOutDir, { recursive: true, force: true });
|
|
8277
8646
|
if (process.env.VERCEL) {
|
|
8278
|
-
await
|
|
8279
|
-
await
|
|
8280
|
-
|
|
8281
|
-
|
|
8647
|
+
await mkdir6(path23.join(dir, ".vercel/output/static"), { recursive: true });
|
|
8648
|
+
await rename2(
|
|
8649
|
+
path23.join(dir, DIST_DIR),
|
|
8650
|
+
path23.join(dir, ".vercel/output/static")
|
|
8282
8651
|
);
|
|
8283
8652
|
}
|
|
8284
8653
|
await writeOutput(dir, {
|
|
@@ -8288,8 +8657,8 @@ var runPrerender = async (options) => {
|
|
|
8288
8657
|
});
|
|
8289
8658
|
if (ZuploEnv.isZuplo && issuer) {
|
|
8290
8659
|
const provider = config2.authentication?.type;
|
|
8291
|
-
await
|
|
8292
|
-
|
|
8660
|
+
await writeFile6(
|
|
8661
|
+
path23.join(dir, DIST_DIR, ".output/zuplo.json"),
|
|
8293
8662
|
JSON.stringify({ issuer, provider }, null, 2),
|
|
8294
8663
|
"utf-8"
|
|
8295
8664
|
);
|
|
@@ -8299,33 +8668,63 @@ var runPrerender = async (options) => {
|
|
|
8299
8668
|
throw e;
|
|
8300
8669
|
}
|
|
8301
8670
|
};
|
|
8671
|
+
var findUserEntry = (dir) => {
|
|
8672
|
+
for (const ext of ["ts", "tsx", "js", "mjs"]) {
|
|
8673
|
+
const candidate = path23.join(dir, `zudoku.server.${ext}`);
|
|
8674
|
+
if (existsSync2(candidate)) return candidate;
|
|
8675
|
+
}
|
|
8676
|
+
};
|
|
8302
8677
|
var bundleSSREntry = async (options) => {
|
|
8303
|
-
const { dir, adapter, serverOutDir, html
|
|
8304
|
-
const tempEntryPath = path21.join(dir, "__ssr-entry.ts");
|
|
8678
|
+
const { dir, adapter, serverOutDir, html } = options;
|
|
8305
8679
|
const packageRoot = getZudokuRootDir();
|
|
8306
|
-
const
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
)
|
|
8310
|
-
|
|
8311
|
-
|
|
8312
|
-
|
|
8313
|
-
|
|
8314
|
-
|
|
8680
|
+
const userEntry = findUserEntry(dir);
|
|
8681
|
+
let entryPoint = userEntry;
|
|
8682
|
+
let tempEntryPath;
|
|
8683
|
+
if (!entryPoint) {
|
|
8684
|
+
tempEntryPath = path23.join(dir, "__ssr-entry.ts");
|
|
8685
|
+
const templateContent = await readFile4(
|
|
8686
|
+
path23.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
|
|
8687
|
+
"utf-8"
|
|
8688
|
+
);
|
|
8689
|
+
await writeFile6(tempEntryPath, templateContent, "utf-8");
|
|
8690
|
+
entryPoint = tempEntryPath;
|
|
8691
|
+
}
|
|
8692
|
+
const frameworkPath = path23.join(serverOutDir, "entry.server.js");
|
|
8315
8693
|
try {
|
|
8316
8694
|
await esbuild({
|
|
8317
|
-
entryPoints: [
|
|
8695
|
+
entryPoints: [entryPoint],
|
|
8318
8696
|
bundle: true,
|
|
8319
|
-
platform:
|
|
8697
|
+
platform: ["node", "lambda"].includes(adapter) ? "node" : "neutral",
|
|
8320
8698
|
target: "es2022",
|
|
8321
8699
|
format: "esm",
|
|
8322
|
-
outfile:
|
|
8323
|
-
external: ["./
|
|
8324
|
-
nodePaths: [
|
|
8325
|
-
banner: { js: "// Bundled SSR entry" }
|
|
8700
|
+
outfile: path23.join(serverOutDir, "entry.js"),
|
|
8701
|
+
external: ["./zudoku.config.js"],
|
|
8702
|
+
nodePaths: [path23.join(packageRoot, "node_modules")],
|
|
8703
|
+
banner: { js: "// Bundled SSR entry" },
|
|
8704
|
+
define: {
|
|
8705
|
+
__ZUDOKU_TEMPLATE__: JSON.stringify(html)
|
|
8706
|
+
},
|
|
8707
|
+
plugins: [
|
|
8708
|
+
{
|
|
8709
|
+
name: "zudoku-ssr-entry",
|
|
8710
|
+
setup(build2) {
|
|
8711
|
+
build2.onResolve({ filter: /^zudoku\/server$/ }, () => ({
|
|
8712
|
+
path: frameworkPath
|
|
8713
|
+
}));
|
|
8714
|
+
}
|
|
8715
|
+
}
|
|
8716
|
+
]
|
|
8326
8717
|
});
|
|
8718
|
+
await Promise.all([
|
|
8719
|
+
rm3(frameworkPath, { force: true }),
|
|
8720
|
+
rm3(`${frameworkPath}.map`, { force: true }),
|
|
8721
|
+
rm3(path23.join(serverOutDir, "assets"), {
|
|
8722
|
+
recursive: true,
|
|
8723
|
+
force: true
|
|
8724
|
+
})
|
|
8725
|
+
]);
|
|
8327
8726
|
} finally {
|
|
8328
|
-
await
|
|
8727
|
+
if (tempEntryPath) await rm3(tempEntryPath, { force: true });
|
|
8329
8728
|
}
|
|
8330
8729
|
};
|
|
8331
8730
|
|
|
@@ -8355,11 +8754,11 @@ function printWarningToConsole(message) {
|
|
|
8355
8754
|
init_package_json();
|
|
8356
8755
|
|
|
8357
8756
|
// src/cli/preview/handler.ts
|
|
8358
|
-
import
|
|
8757
|
+
import path24 from "node:path";
|
|
8359
8758
|
import { preview as vitePreview } from "vite";
|
|
8360
8759
|
var DEFAULT_PREVIEW_PORT = 4e3;
|
|
8361
8760
|
async function preview(argv) {
|
|
8362
|
-
const dir =
|
|
8761
|
+
const dir = path24.resolve(process.cwd(), argv.dir);
|
|
8363
8762
|
const viteConfig = await getViteConfig(dir, {
|
|
8364
8763
|
command: "serve",
|
|
8365
8764
|
mode: "production",
|
|
@@ -8397,7 +8796,7 @@ async function build(argv) {
|
|
|
8397
8796
|
printDiagnosticsToConsole(`Starting Zudoku build v${packageJson2.version}`);
|
|
8398
8797
|
printDiagnosticsToConsole("");
|
|
8399
8798
|
printDiagnosticsToConsole("");
|
|
8400
|
-
const dir =
|
|
8799
|
+
const dir = path25.resolve(process.cwd(), argv.dir);
|
|
8401
8800
|
try {
|
|
8402
8801
|
await runBuild({
|
|
8403
8802
|
dir,
|
|
@@ -8538,8 +8937,8 @@ var build_default = {
|
|
|
8538
8937
|
default: false
|
|
8539
8938
|
}).option("adapter", {
|
|
8540
8939
|
type: "string",
|
|
8541
|
-
describe: "SSR adapter (node, cloudflare, vercel)",
|
|
8542
|
-
choices: ["node", "cloudflare", "vercel"],
|
|
8940
|
+
describe: "SSR adapter (node, cloudflare, vercel, lambda)",
|
|
8941
|
+
choices: ["node", "cloudflare", "vercel", "lambda"],
|
|
8543
8942
|
default: "node"
|
|
8544
8943
|
}),
|
|
8545
8944
|
handler: async (argv) => {
|
|
@@ -8551,14 +8950,14 @@ var build_default = {
|
|
|
8551
8950
|
|
|
8552
8951
|
// src/cli/dev/handler.ts
|
|
8553
8952
|
init_joinUrl();
|
|
8554
|
-
import
|
|
8953
|
+
import path28 from "node:path";
|
|
8555
8954
|
|
|
8556
8955
|
// src/vite/dev-server.ts
|
|
8557
8956
|
init_logger();
|
|
8558
8957
|
import fs3 from "node:fs/promises";
|
|
8559
8958
|
import http from "node:http";
|
|
8560
8959
|
import https from "node:https";
|
|
8561
|
-
import
|
|
8960
|
+
import path27 from "node:path";
|
|
8562
8961
|
import { createHttpTerminator } from "http-terminator";
|
|
8563
8962
|
import {
|
|
8564
8963
|
createServer as createViteServer,
|
|
@@ -8587,11 +8986,12 @@ async function findAvailablePort(startPort) {
|
|
|
8587
8986
|
|
|
8588
8987
|
// src/vite/dev-server.ts
|
|
8589
8988
|
init_loader();
|
|
8989
|
+
init_joinUrl();
|
|
8590
8990
|
|
|
8591
8991
|
// src/vite/pagefind-dev-index.ts
|
|
8592
8992
|
init_invariant();
|
|
8593
8993
|
init_joinUrl();
|
|
8594
|
-
import
|
|
8994
|
+
import path26 from "node:path";
|
|
8595
8995
|
import { createIndex as createIndex2 } from "pagefind";
|
|
8596
8996
|
import { isRunnableDevEnvironment } from "vite";
|
|
8597
8997
|
async function* buildPagefindDevIndex(vite, config2) {
|
|
@@ -8644,7 +9044,7 @@ async function* buildPagefindDevIndex(vite, config2) {
|
|
|
8644
9044
|
path: urlPath
|
|
8645
9045
|
};
|
|
8646
9046
|
}
|
|
8647
|
-
const outputPath =
|
|
9047
|
+
const outputPath = path26.join(vite.config.publicDir, "pagefind");
|
|
8648
9048
|
await pagefindIndex.writeFiles({ outputPath });
|
|
8649
9049
|
yield { type: "complete", success: true, indexed };
|
|
8650
9050
|
}
|
|
@@ -8664,9 +9064,9 @@ var DevServer = class {
|
|
|
8664
9064
|
this.protocol = "https";
|
|
8665
9065
|
const { dir } = this.#options;
|
|
8666
9066
|
const [key, cert, ca] = await Promise.all([
|
|
8667
|
-
fs3.readFile(
|
|
8668
|
-
fs3.readFile(
|
|
8669
|
-
config2.https.ca ? fs3.readFile(
|
|
9067
|
+
fs3.readFile(path27.resolve(dir, config2.https.key)),
|
|
9068
|
+
fs3.readFile(path27.resolve(dir, config2.https.cert)),
|
|
9069
|
+
config2.https.ca ? fs3.readFile(path27.resolve(dir, config2.https.ca)) : void 0
|
|
8670
9070
|
]);
|
|
8671
9071
|
return https.createServer({ key, cert, ca });
|
|
8672
9072
|
}
|
|
@@ -8692,7 +9092,7 @@ var DevServer = class {
|
|
|
8692
9092
|
// built-in transform middleware which would treat the path as a static asset.
|
|
8693
9093
|
name: "zudoku:entry-client",
|
|
8694
9094
|
configureServer(server2) {
|
|
8695
|
-
const entryPath =
|
|
9095
|
+
const entryPath = path27.posix.join(
|
|
8696
9096
|
server2.config.base,
|
|
8697
9097
|
"/__z/entry.client.tsx"
|
|
8698
9098
|
);
|
|
@@ -8723,6 +9123,46 @@ var DevServer = class {
|
|
|
8723
9123
|
next();
|
|
8724
9124
|
});
|
|
8725
9125
|
vite.middlewares.use(graphql.graphqlEndpoint, graphql);
|
|
9126
|
+
const sessionEndpoint = joinUrl(config2.basePath, "/__z/auth/session");
|
|
9127
|
+
vite.middlewares.use(sessionEndpoint, async (req, res) => {
|
|
9128
|
+
if (req.method !== "POST" && req.method !== "DELETE") {
|
|
9129
|
+
res.writeHead(405, { Allow: "POST, DELETE" });
|
|
9130
|
+
res.end();
|
|
9131
|
+
return;
|
|
9132
|
+
}
|
|
9133
|
+
const ssrEnvironment = vite.environments.ssr;
|
|
9134
|
+
if (!isRunnableDevEnvironment2(ssrEnvironment)) {
|
|
9135
|
+
res.writeHead(500);
|
|
9136
|
+
res.end("SSR environment not available");
|
|
9137
|
+
return;
|
|
9138
|
+
}
|
|
9139
|
+
const entryServer = await ssrEnvironment.runner.import(
|
|
9140
|
+
getAppServerEntryPath()
|
|
9141
|
+
);
|
|
9142
|
+
const url = `${this.protocol}://${req.headers.host}${req.originalUrl ?? req.url}`;
|
|
9143
|
+
const body = req.method === "POST" ? await new Promise((resolve) => {
|
|
9144
|
+
let data = "";
|
|
9145
|
+
req.on("data", (chunk) => data += chunk);
|
|
9146
|
+
req.on("end", () => resolve(data));
|
|
9147
|
+
}) : void 0;
|
|
9148
|
+
const request = new Request(url, {
|
|
9149
|
+
method: req.method,
|
|
9150
|
+
headers: req.headers,
|
|
9151
|
+
body
|
|
9152
|
+
});
|
|
9153
|
+
const app = entryServer.createServer({ template: "" });
|
|
9154
|
+
const response = await app.fetch(request);
|
|
9155
|
+
for (const [name, value] of response.headers) {
|
|
9156
|
+
if (name.toLowerCase() === "set-cookie") continue;
|
|
9157
|
+
res.setHeader(name, value);
|
|
9158
|
+
}
|
|
9159
|
+
for (const cookie of response.headers.getSetCookie()) {
|
|
9160
|
+
res.appendHeader("Set-Cookie", cookie);
|
|
9161
|
+
}
|
|
9162
|
+
res.writeHead(response.status);
|
|
9163
|
+
const text = await response.text();
|
|
9164
|
+
res.end(text);
|
|
9165
|
+
});
|
|
8726
9166
|
vite.middlewares.use("/__z/pagefind-reindex", async (_req, res) => {
|
|
8727
9167
|
res.writeHead(200, {
|
|
8728
9168
|
"Content-Type": "text/event-stream",
|
|
@@ -8765,13 +9205,13 @@ var DevServer = class {
|
|
|
8765
9205
|
`Server-side rendering ${this.#options.ssr ? "enabled" : "disabled"}`
|
|
8766
9206
|
);
|
|
8767
9207
|
if (config2.search?.type === "pagefind") {
|
|
8768
|
-
const pagefindPath =
|
|
9208
|
+
const pagefindPath = path27.join(
|
|
8769
9209
|
vite.config.publicDir,
|
|
8770
9210
|
"pagefind/pagefind.js"
|
|
8771
9211
|
);
|
|
8772
9212
|
const exists = await fs3.stat(pagefindPath).catch(() => false);
|
|
8773
9213
|
if (!exists) {
|
|
8774
|
-
await fs3.mkdir(
|
|
9214
|
+
await fs3.mkdir(path27.dirname(pagefindPath), { recursive: true });
|
|
8775
9215
|
await fs3.writeFile(pagefindPath, 'throw new Error("NOT_BUILT_YET");');
|
|
8776
9216
|
}
|
|
8777
9217
|
}
|
|
@@ -8813,14 +9253,15 @@ var DevServer = class {
|
|
|
8813
9253
|
duplex: hasBody ? "half" : void 0
|
|
8814
9254
|
}
|
|
8815
9255
|
);
|
|
8816
|
-
const
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
|
|
8820
|
-
|
|
9256
|
+
const app = entryServer.createServer({ template });
|
|
9257
|
+
const response = await app.fetch(request);
|
|
9258
|
+
response.headers.forEach((value, key) => {
|
|
9259
|
+
if (key.toLowerCase() !== "set-cookie") {
|
|
9260
|
+
res.setHeader(key, value);
|
|
9261
|
+
}
|
|
8821
9262
|
});
|
|
8822
|
-
for (const
|
|
8823
|
-
res.appendHeader(
|
|
9263
|
+
for (const cookie of response.headers.getSetCookie()) {
|
|
9264
|
+
res.appendHeader("Set-Cookie", cookie);
|
|
8824
9265
|
}
|
|
8825
9266
|
res.writeHead(response.status);
|
|
8826
9267
|
for await (const chunk of response.body ?? []) {
|
|
@@ -8869,7 +9310,7 @@ init_package_json();
|
|
|
8869
9310
|
async function dev(argv) {
|
|
8870
9311
|
const packageJson2 = getZudokuPackageJson();
|
|
8871
9312
|
process.env.NODE_ENV = "development";
|
|
8872
|
-
const dir =
|
|
9313
|
+
const dir = path28.resolve(process.cwd(), argv.dir);
|
|
8873
9314
|
const server = new DevServer({
|
|
8874
9315
|
dir,
|
|
8875
9316
|
argPort: argv.port,
|
|
@@ -8974,8 +9415,8 @@ var previewCommand = {
|
|
|
8974
9415
|
var preview_default = previewCommand;
|
|
8975
9416
|
|
|
8976
9417
|
// src/cli/common/outdated.ts
|
|
8977
|
-
import { existsSync as
|
|
8978
|
-
import { readFile as
|
|
9418
|
+
import { existsSync as existsSync3, mkdirSync } from "node:fs";
|
|
9419
|
+
import { readFile as readFile5, writeFile as writeFile7 } from "node:fs/promises";
|
|
8979
9420
|
import { join } from "node:path";
|
|
8980
9421
|
import colors10 from "picocolors";
|
|
8981
9422
|
import { gt } from "semver";
|
|
@@ -9025,12 +9466,12 @@ function box(message, {
|
|
|
9025
9466
|
|
|
9026
9467
|
// src/cli/common/xdg/lib.ts
|
|
9027
9468
|
import { homedir } from "node:os";
|
|
9028
|
-
import
|
|
9469
|
+
import path29 from "node:path";
|
|
9029
9470
|
function defineDirectoryWithFallback(xdgName, fallback) {
|
|
9030
9471
|
if (process.env[xdgName]) {
|
|
9031
9472
|
return process.env[xdgName];
|
|
9032
9473
|
} else {
|
|
9033
|
-
return
|
|
9474
|
+
return path29.join(homedir(), fallback);
|
|
9034
9475
|
}
|
|
9035
9476
|
}
|
|
9036
9477
|
var XDG_CONFIG_HOME = defineDirectoryWithFallback(
|
|
@@ -9045,15 +9486,15 @@ var XDG_STATE_HOME = defineDirectoryWithFallback(
|
|
|
9045
9486
|
"XDG_DATA_HOME",
|
|
9046
9487
|
".local/state"
|
|
9047
9488
|
);
|
|
9048
|
-
var ZUDOKU_XDG_CONFIG_HOME =
|
|
9489
|
+
var ZUDOKU_XDG_CONFIG_HOME = path29.join(
|
|
9049
9490
|
XDG_CONFIG_HOME,
|
|
9050
9491
|
CLI_XDG_FOLDER_NAME
|
|
9051
9492
|
);
|
|
9052
|
-
var ZUDOKU_XDG_DATA_HOME =
|
|
9493
|
+
var ZUDOKU_XDG_DATA_HOME = path29.join(
|
|
9053
9494
|
XDG_DATA_HOME,
|
|
9054
9495
|
CLI_XDG_FOLDER_NAME
|
|
9055
9496
|
);
|
|
9056
|
-
var ZUDOKU_XDG_STATE_HOME =
|
|
9497
|
+
var ZUDOKU_XDG_STATE_HOME = path29.join(
|
|
9057
9498
|
XDG_STATE_HOME,
|
|
9058
9499
|
CLI_XDG_FOLDER_NAME
|
|
9059
9500
|
);
|
|
@@ -9095,14 +9536,14 @@ async function getLatestVersion() {
|
|
|
9095
9536
|
return void 0;
|
|
9096
9537
|
}
|
|
9097
9538
|
async function getVersionCheckInfo() {
|
|
9098
|
-
if (!
|
|
9539
|
+
if (!existsSync3(ZUDOKU_XDG_STATE_HOME)) {
|
|
9099
9540
|
mkdirSync(ZUDOKU_XDG_STATE_HOME, { recursive: true });
|
|
9100
9541
|
}
|
|
9101
9542
|
const versionCheckPath = join(ZUDOKU_XDG_STATE_HOME, VERSION_CHECK_FILE);
|
|
9102
9543
|
let versionCheckInfo;
|
|
9103
|
-
if (
|
|
9544
|
+
if (existsSync3(versionCheckPath)) {
|
|
9104
9545
|
try {
|
|
9105
|
-
versionCheckInfo = await
|
|
9546
|
+
versionCheckInfo = await readFile5(versionCheckPath, "utf-8").then(
|
|
9106
9547
|
JSON.parse
|
|
9107
9548
|
);
|
|
9108
9549
|
} catch {
|
|
@@ -9127,7 +9568,7 @@ async function getVersionCheckInfo() {
|
|
|
9127
9568
|
lastCheck: Date.now(),
|
|
9128
9569
|
latestVersion
|
|
9129
9570
|
};
|
|
9130
|
-
await
|
|
9571
|
+
await writeFile7(
|
|
9131
9572
|
versionCheckPath,
|
|
9132
9573
|
JSON.stringify(versionCheckInfo),
|
|
9133
9574
|
"utf-8"
|