@cedarjs/vite 8.0.0-canary.3324 → 8.0.0-canary.3326
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/plugins/vite-plugin-cedar-netlify-skew-protection.d.ts +58 -37
- package/dist/plugins/vite-plugin-cedar-netlify-skew-protection.d.ts.map +1 -1
- package/dist/plugins/vite-plugin-cedar-netlify-skew-protection.js +72 -24
- package/dist/plugins/vite-plugin-cedar-universal-deploy.d.ts +10 -0
- package/dist/plugins/vite-plugin-cedar-universal-deploy.d.ts.map +1 -1
- package/dist/plugins/vite-plugin-cedar-universal-deploy.js +5 -1
- package/package.json +19 -19
|
@@ -1,52 +1,73 @@
|
|
|
1
|
-
import type { Plugin } from 'vite';
|
|
1
|
+
import type { Plugin, ResolvedConfig } from 'vite';
|
|
2
2
|
export interface CedarNetlifySkewProtectionPluginOptions {
|
|
3
3
|
headerName?: string;
|
|
4
4
|
queryName?: string;
|
|
5
5
|
cookieName?: string;
|
|
6
6
|
/**
|
|
7
|
-
* How long (in seconds) the skew-token cookie
|
|
8
|
-
* deploy
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* How long (in seconds) the skew-token cookie pins a client's asset and API
|
|
8
|
+
* requests to the deploy it last loaded a page from. Page loads are never
|
|
9
|
+
* pinned and always refresh the cookie, so a long value can't keep anyone
|
|
10
|
+
* on an old version; it only bounds how long an open tab can keep loading
|
|
11
|
+
* lazy chunks from the deploy it started on. Defaults to 24 hours.
|
|
12
12
|
*/
|
|
13
13
|
cookieMaxAge?: number;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* The paths Netlify should route to a client's pinned deploy, and the paths
|
|
17
|
+
* the edge function doesn't need to run on.
|
|
18
|
+
*/
|
|
19
|
+
export interface SkewProtectionPaths {
|
|
20
|
+
/** Regexes for Netlify's `skew-protection.json` `patterns` */
|
|
21
|
+
patterns: string[];
|
|
22
|
+
/** Globs for the edge function's `excludedPath` */
|
|
23
|
+
excludedPaths: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Pins hashed build assets (the lazy-loaded chunks an already-open tab
|
|
27
|
+
* requests after a new deploy) and Cedar's API routes (so an old client keeps
|
|
28
|
+
* talking to the API it was built against). Page loads are not pinned, so a
|
|
29
|
+
* reload or a fresh visit always gets the latest deploy.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getSkewProtectionPaths(config: Pick<ResolvedConfig, 'base' | 'build' | 'plugins'>): SkewProtectionPaths;
|
|
32
|
+
/**
|
|
33
|
+
* Generates Netlify's `.netlify/v1/skew-protection.json` build output, an
|
|
34
|
+
* edge function that stamps the skew-token cookie on static HTML, and wraps
|
|
35
|
+
* Universal Deploy's catch-all Fetchable so server-rendered HTML gets the
|
|
36
|
+
* same cookie.
|
|
18
37
|
*
|
|
19
38
|
* Background: https://docs.netlify.com/build/frameworks/frameworks-api/#netlifyv1skew-protectionjson
|
|
20
|
-
* Netlify exposes the current deploy's unique fingerprint at build time via
|
|
21
|
-
* `NETLIFY_SKEW_PROTECTION_TOKEN`, and at runtime via `context.deploy.skewProtectionToken`
|
|
22
|
-
* on the Functions/Edge Functions `context` object. Cedar's universal-deploy
|
|
23
|
-
* entries are plain `(request: Request) => Response` Fetchables with no
|
|
24
|
-
* platform-specific `context` forwarded through, so we can't read the
|
|
25
|
-
* runtime-provided token there. Instead we stamp the build-time value
|
|
26
|
-
* (identical to the runtime one — both describe the same deploy) into the
|
|
27
|
-
* bundle as a virtual module, then wrap Universal Deploy's catch-all
|
|
28
|
-
* Fetchable so every response pins the client to this deploy via a
|
|
29
|
-
* `Set-Cookie`. Cookies are the only one of Netlify's three skew-protection
|
|
30
|
-
* sources (cookie, header, query) that propagates for free — the browser
|
|
31
|
-
* resends them on every same-origin request without any client-side code
|
|
32
|
-
* having to attach anything, so that's the only mechanism this phase
|
|
33
|
-
* implements. Header/query propagation would only matter for requests that
|
|
34
|
-
* don't carry cookies (e.g. cross-origin calls), which is a narrower,
|
|
35
|
-
* separate follow-up.
|
|
36
39
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* `
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
40
|
+
* How it works:
|
|
41
|
+
* - Every HTML response sets `Set-Cookie: <cookieName>=<deploy token>`.
|
|
42
|
+
* Netlify exposes the token at build time as `NETLIFY_SKEW_PROTECTION_TOKEN`
|
|
43
|
+
* and at runtime as `context.deploy.skewProtectionToken`.
|
|
44
|
+
* - Requests matching `patterns` (build assets and API routes, see
|
|
45
|
+
* `getSkewProtectionPaths`) that carry the cookie are served by the deploy
|
|
46
|
+
* the token belongs to. A tab that loaded an old build keeps loading its
|
|
47
|
+
* own lazy chunks after a new deploy, instead of getting 404s.
|
|
48
|
+
* - Page loads don't match `patterns`, so they're always served by the
|
|
49
|
+
* latest deploy, and its HTML sets the latest token. Reloading is therefore
|
|
50
|
+
* always enough to get the newest version.
|
|
51
|
+
* - Only HTML responses to page loads set the cookie. Responses to pinned
|
|
52
|
+
* asset and API requests can come from an old deploy and would otherwise
|
|
53
|
+
* renew the old token.
|
|
54
|
+
*
|
|
55
|
+
* The cookie is set in two places:
|
|
56
|
+
* - Static HTML (prerendered pages and the SPA shell) is served from
|
|
57
|
+
* Netlify's CDN and never reaches Cedar's server code. A framework-authored
|
|
58
|
+
* edge function (`.netlify/v1/edge-functions/`, registered automatically)
|
|
59
|
+
* stamps it using `context.deploy.skewProtectionToken`.
|
|
60
|
+
* - Server-rendered HTML comes from Universal Deploy's catch-all Fetchable.
|
|
61
|
+
* Fetchables are plain `(request: Request) => Response` functions that
|
|
62
|
+
* don't get Netlify's `context`, so the build-time token (identical to the
|
|
63
|
+
* runtime one, both describe the same deploy) is stamped into the SSR
|
|
64
|
+
* bundle as a virtual module, and the Fetchable is wrapped to set the
|
|
65
|
+
* cookie.
|
|
66
|
+
*
|
|
67
|
+
* Cookies are the only one of Netlify's three token sources (cookie, header,
|
|
68
|
+
* query) that browsers send automatically, so they're the only one Cedar
|
|
69
|
+
* sets. The header and query sources are registered so clients that can't
|
|
70
|
+
* use cookies can still pin requests by sending the token themselves.
|
|
50
71
|
*/
|
|
51
72
|
export declare function cedarNetlifySkewProtectionPlugin(options?: CedarNetlifySkewProtectionPluginOptions): Plugin;
|
|
52
73
|
//# sourceMappingURL=vite-plugin-cedar-netlify-skew-protection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin-cedar-netlify-skew-protection.d.ts","sourceRoot":"","sources":["../../src/plugins/vite-plugin-cedar-netlify-skew-protection.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"vite-plugin-cedar-netlify-skew-protection.d.ts","sourceRoot":"","sources":["../../src/plugins/vite-plugin-cedar-netlify-skew-protection.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAOlD,MAAM,WAAW,uCAAuC;IACtD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,mDAAmD;IACnD,aAAa,EAAE,MAAM,EAAE,CAAA;CACxB;AAoBD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,GACzD,mBAAmB,CAgCrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,uCAA4C,GACpD,MAAM,CAwOR"}
|
|
@@ -2,19 +2,57 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { catchAllEntry } from "@universal-deploy/store";
|
|
4
4
|
import { getPaths } from "@cedarjs/project-config";
|
|
5
|
+
import { CEDAR_UNIVERSAL_DEPLOY_PLUGIN_NAME } from "./vite-plugin-cedar-universal-deploy.js";
|
|
5
6
|
const VIRTUAL_SKEW_TOKEN_ID = "virtual:cedar-netlify-skew-token";
|
|
6
7
|
const RESOLVED_SKEW_TOKEN_ID = "\0" + VIRTUAL_SKEW_TOKEN_ID;
|
|
8
|
+
function escapeRegExp(value) {
|
|
9
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
10
|
+
}
|
|
11
|
+
function isUniversalDeployPluginApi(api) {
|
|
12
|
+
return typeof api === "object" && api !== null && "routes" in api && Array.isArray(api.routes);
|
|
13
|
+
}
|
|
14
|
+
function getSkewProtectionPaths(config) {
|
|
15
|
+
const patterns = [];
|
|
16
|
+
const excludedPaths = [];
|
|
17
|
+
const baseIsUrl = /^([a-z][a-z\d+.-]*:)?\/\//i.test(config.base);
|
|
18
|
+
if (!baseIsUrl) {
|
|
19
|
+
const basePath = config.base.startsWith("/") ? config.base : "/";
|
|
20
|
+
const assetsPath = path.posix.join(basePath, config.build.assetsDir);
|
|
21
|
+
patterns.push(`^${escapeRegExp(assetsPath)}/`);
|
|
22
|
+
excludedPaths.push(`${assetsPath}/*`);
|
|
23
|
+
}
|
|
24
|
+
const udApi = config.plugins.find(
|
|
25
|
+
(plugin) => plugin.name === CEDAR_UNIVERSAL_DEPLOY_PLUGIN_NAME
|
|
26
|
+
)?.api;
|
|
27
|
+
if (isUniversalDeployPluginApi(udApi)) {
|
|
28
|
+
for (const route of udApi.routes) {
|
|
29
|
+
if (route.path.includes("*")) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
patterns.push(`^${escapeRegExp(route.path)}(/.*)?$`);
|
|
33
|
+
excludedPaths.push(route.path, `${route.path}/*`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { patterns, excludedPaths };
|
|
37
|
+
}
|
|
7
38
|
function cedarNetlifySkewProtectionPlugin(options = {}) {
|
|
8
39
|
const {
|
|
9
40
|
headerName = "cedar-skew-token",
|
|
10
41
|
queryName = "skew",
|
|
11
42
|
cookieName = "cedar-skew-token",
|
|
12
|
-
cookieMaxAge = 60 * 60 *
|
|
43
|
+
cookieMaxAge = 60 * 60 * 24
|
|
13
44
|
} = options;
|
|
14
45
|
const skewToken = process.env.NETLIFY_SKEW_PROTECTION_TOKEN ?? "";
|
|
46
|
+
let skewProtectionPaths = {
|
|
47
|
+
patterns: [],
|
|
48
|
+
excludedPaths: []
|
|
49
|
+
};
|
|
15
50
|
return {
|
|
16
51
|
name: "cedar-netlify-skew-protection",
|
|
17
52
|
apply: "build",
|
|
53
|
+
configResolved(config) {
|
|
54
|
+
skewProtectionPaths = getSkewProtectionPaths(config);
|
|
55
|
+
},
|
|
18
56
|
transform(code, id) {
|
|
19
57
|
if (this.environment?.name !== "ssr" || id !== catchAllEntry) {
|
|
20
58
|
return void 0;
|
|
@@ -25,7 +63,7 @@ function cedarNetlifySkewProtectionPlugin(options = {}) {
|
|
|
25
63
|
);
|
|
26
64
|
if (wrappedCode === code) {
|
|
27
65
|
this.warn(
|
|
28
|
-
'cedar-netlify-skew-protection: expected "export default {" in the Universal Deploy catch-all entry but did not find it \u2014 skipping
|
|
66
|
+
'cedar-netlify-skew-protection: expected "export default {" in the Universal Deploy catch-all entry but did not find it \u2014 skipping skew-token cookie stamping on server-rendered HTML. This likely means @universal-deploy/vite changed how it generates the catch-all entry.'
|
|
29
67
|
);
|
|
30
68
|
return void 0;
|
|
31
69
|
}
|
|
@@ -34,20 +72,28 @@ function cedarNetlifySkewProtectionPlugin(options = {}) {
|
|
|
34
72
|
`import { CEDAR_SKEW_TOKEN, CEDAR_SKEW_COOKIE_NAME } from ${JSON.stringify(VIRTUAL_SKEW_TOKEN_ID)}`,
|
|
35
73
|
wrappedCode,
|
|
36
74
|
"",
|
|
75
|
+
"const __cedarSkewPinnedPatterns = [",
|
|
76
|
+
...skewProtectionPaths.patterns.map(
|
|
77
|
+
(pattern) => ` new RegExp(${JSON.stringify(pattern)}),`
|
|
78
|
+
),
|
|
79
|
+
"]",
|
|
80
|
+
"",
|
|
37
81
|
"const __cedarSkewOriginalFetch =",
|
|
38
82
|
" __cedarSkewCatchAllHandler.fetch.bind(__cedarSkewCatchAllHandler)",
|
|
39
83
|
"",
|
|
40
84
|
"__cedarSkewCatchAllHandler.fetch = async (request, ...args) => {",
|
|
41
85
|
" const response = await __cedarSkewOriginalFetch(request, ...args)",
|
|
42
86
|
"",
|
|
43
|
-
" //
|
|
44
|
-
" //
|
|
45
|
-
" //
|
|
46
|
-
" //
|
|
47
|
-
" //
|
|
48
|
-
" //
|
|
49
|
-
" //
|
|
50
|
-
" //
|
|
87
|
+
" // Only HTML responses to page loads set the cookie (see",
|
|
88
|
+
" // vite-plugin-cedar-netlify-skew-protection.ts). Requests to pinned",
|
|
89
|
+
" // paths are never page loads, even if an API function returns",
|
|
90
|
+
" // HTML, and may be served by an old deploy. Nothing to stamp",
|
|
91
|
+
" // without a token (e.g. a local `cedar build --ud` run outside a",
|
|
92
|
+
" // Netlify build) or a response (an unmatched route). Statuses",
|
|
93
|
+
" // outside 200-599 (e.g. 101 for a WebSocket upgrade) make the",
|
|
94
|
+
" // Response constructor below throw, and 204/304 responses have no",
|
|
95
|
+
" // body worth re-wrapping. Responses that already set our cookie",
|
|
96
|
+
" // are left alone to avoid a duplicate.",
|
|
51
97
|
" if (",
|
|
52
98
|
" !CEDAR_SKEW_TOKEN ||",
|
|
53
99
|
" !response ||",
|
|
@@ -55,6 +101,10 @@ function cedarNetlifySkewProtectionPlugin(options = {}) {
|
|
|
55
101
|
" response.status > 599 ||",
|
|
56
102
|
" response.status === 204 ||",
|
|
57
103
|
" response.status === 304 ||",
|
|
104
|
+
' !(response.headers.get("content-type") ?? "").includes("text/html") ||',
|
|
105
|
+
" __cedarSkewPinnedPatterns.some((pattern) =>",
|
|
106
|
+
" pattern.test(new URL(request.url).pathname),",
|
|
107
|
+
" ) ||",
|
|
58
108
|
' (response.headers.get("set-cookie") ?? "").includes(',
|
|
59
109
|
" `${CEDAR_SKEW_COOKIE_NAME}=`,",
|
|
60
110
|
" )",
|
|
@@ -108,10 +158,7 @@ function cedarNetlifySkewProtectionPlugin(options = {}) {
|
|
|
108
158
|
const netlifyV1Dir = path.join(getPaths().web.base, ".netlify", "v1");
|
|
109
159
|
fs.mkdirSync(netlifyV1Dir, { recursive: true });
|
|
110
160
|
const manifest = {
|
|
111
|
-
|
|
112
|
-
// directory convention, and Netlify's own docs example matches
|
|
113
|
-
// assets too, so there's no correctness reason to narrow this.
|
|
114
|
-
patterns: [".*"],
|
|
161
|
+
patterns: skewProtectionPaths.patterns,
|
|
115
162
|
sources: [
|
|
116
163
|
{ type: "header", name: headerName },
|
|
117
164
|
{ type: "query", name: queryName },
|
|
@@ -127,26 +174,25 @@ function cedarNetlifySkewProtectionPlugin(options = {}) {
|
|
|
127
174
|
fs.writeFileSync(
|
|
128
175
|
path.join(edgeFunctionsDir, "cedar-skew-cookie.js"),
|
|
129
176
|
[
|
|
130
|
-
"// Generated by @cedarjs/vite
|
|
131
|
-
"//
|
|
132
|
-
"// Fetchable (most notably the initial HTML document load, served",
|
|
133
|
-
"// directly from Netlify's CDN). See",
|
|
177
|
+
"// Generated by @cedarjs/vite. Stamps the skew-protection cookie on",
|
|
178
|
+
"// static HTML served from Netlify's CDN. See",
|
|
134
179
|
"// vite-plugin-cedar-netlify-skew-protection.ts for the full picture.",
|
|
135
180
|
"export default async (request, context) => {",
|
|
136
181
|
" const response = await context.next()",
|
|
137
182
|
"",
|
|
138
183
|
` const cookieName = ${JSON.stringify(cookieName)}`,
|
|
139
184
|
"",
|
|
140
|
-
" //
|
|
141
|
-
" //
|
|
142
|
-
" //
|
|
143
|
-
" //
|
|
144
|
-
" //
|
|
185
|
+
" // Only HTML responses set the cookie. Statuses outside 200-599",
|
|
186
|
+
" // (e.g. 101 for a WebSocket upgrade) make the Response",
|
|
187
|
+
" // constructor below throw, and 204/304 responses have no body",
|
|
188
|
+
" // worth re-wrapping. Responses that already set our cookie (from",
|
|
189
|
+
" // the Universal Deploy wrapper) are left alone.",
|
|
145
190
|
" if (",
|
|
146
191
|
" response.status < 200 ||",
|
|
147
192
|
" response.status > 599 ||",
|
|
148
193
|
" response.status === 204 ||",
|
|
149
194
|
" response.status === 304 ||",
|
|
195
|
+
' !(response.headers.get("content-type") ?? "").includes("text/html") ||',
|
|
150
196
|
' (response.headers.get("set-cookie") ?? "").includes(`${cookieName}=`)',
|
|
151
197
|
" ) {",
|
|
152
198
|
" return response",
|
|
@@ -172,6 +218,7 @@ function cedarNetlifySkewProtectionPlugin(options = {}) {
|
|
|
172
218
|
"",
|
|
173
219
|
"export const config = {",
|
|
174
220
|
' path: "/*",',
|
|
221
|
+
` excludedPath: ${JSON.stringify(skewProtectionPaths.excludedPaths)},`,
|
|
175
222
|
"}",
|
|
176
223
|
""
|
|
177
224
|
].join("\n")
|
|
@@ -180,5 +227,6 @@ function cedarNetlifySkewProtectionPlugin(options = {}) {
|
|
|
180
227
|
};
|
|
181
228
|
}
|
|
182
229
|
export {
|
|
183
|
-
cedarNetlifySkewProtectionPlugin
|
|
230
|
+
cedarNetlifySkewProtectionPlugin,
|
|
231
|
+
getSkewProtectionPaths
|
|
184
232
|
};
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import type { Plugin } from 'vite';
|
|
2
|
+
import type { CedarRouteRecord } from '@cedarjs/api/runtime';
|
|
2
3
|
export interface CedarUniversalDeployPluginOptions {
|
|
3
4
|
apiRootPath?: string;
|
|
4
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Exposed as the plugin's `api` property so other plugins (e.g.
|
|
8
|
+
* `cedarNetlifySkewProtectionPlugin`) can find the API routes this plugin
|
|
9
|
+
* registers.
|
|
10
|
+
*/
|
|
11
|
+
export interface CedarUniversalDeployPluginApi {
|
|
12
|
+
routes: CedarRouteRecord[];
|
|
13
|
+
}
|
|
14
|
+
export declare const CEDAR_UNIVERSAL_DEPLOY_PLUGIN_NAME = "cedar-universal-deploy";
|
|
5
15
|
export declare function cedarUniversalDeployPlugin(options?: CedarUniversalDeployPluginOptions): Plugin;
|
|
6
16
|
//# sourceMappingURL=vite-plugin-cedar-universal-deploy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin-cedar-universal-deploy.d.ts","sourceRoot":"","sources":["../../src/plugins/vite-plugin-cedar-universal-deploy.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"vite-plugin-cedar-universal-deploy.d.ts","sourceRoot":"","sources":["../../src/plugins/vite-plugin-cedar-universal-deploy.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAGlC,OAAO,KAAK,EAEV,gBAAgB,EAEjB,MAAM,sBAAsB,CAAA;AAS7B,MAAM,WAAW,iCAAiC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,gBAAgB,EAAE,CAAA;CAC3B;AAED,eAAO,MAAM,kCAAkC,2BAA2B,CAAA;AA6G1E,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,iCAAsC,GAC9C,MAAM,CA6GR"}
|
|
@@ -2,6 +2,7 @@ import path from "node:path";
|
|
|
2
2
|
import { addEntry } from "@universal-deploy/store";
|
|
3
3
|
import { findApiServerFunctions } from "@cedarjs/internal/dist/files.js";
|
|
4
4
|
import { getPaths } from "@cedarjs/project-config";
|
|
5
|
+
const CEDAR_UNIVERSAL_DEPLOY_PLUGIN_NAME = "cedar-universal-deploy";
|
|
5
6
|
const VIRTUAL_CEDAR_FN_PREFIX = "virtual:cedar-api:fn:";
|
|
6
7
|
const RESOLVED_CEDAR_FN_PREFIX = "\0virtual:cedar-api:fn:";
|
|
7
8
|
const GRAPHQL_METHODS = ["GET", "POST", "OPTIONS"];
|
|
@@ -66,9 +67,11 @@ function toEntryMeta(route) {
|
|
|
66
67
|
function cedarUniversalDeployPlugin(options = {}) {
|
|
67
68
|
const effectiveApiRootPath = process.env.CEDAR_API_ROOT_PATH ?? options.apiRootPath;
|
|
68
69
|
const routes = discoverCedarRoutes(effectiveApiRootPath ?? "/");
|
|
70
|
+
const api = { routes };
|
|
69
71
|
return {
|
|
70
|
-
name:
|
|
72
|
+
name: CEDAR_UNIVERSAL_DEPLOY_PLUGIN_NAME,
|
|
71
73
|
apply: "build",
|
|
74
|
+
api,
|
|
72
75
|
config: {
|
|
73
76
|
order: "pre",
|
|
74
77
|
handler() {
|
|
@@ -308,5 +311,6 @@ function createGraphQLFetch(graphqlOptions) {
|
|
|
308
311
|
};
|
|
309
312
|
}
|
|
310
313
|
export {
|
|
314
|
+
CEDAR_UNIVERSAL_DEPLOY_PLUGIN_NAME,
|
|
311
315
|
cedarUniversalDeployPlugin
|
|
312
316
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/vite",
|
|
3
|
-
"version": "8.0.0-canary.
|
|
3
|
+
"version": "8.0.0-canary.3326",
|
|
4
4
|
"description": "Vite configuration package for CedarJS",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -54,17 +54,17 @@
|
|
|
54
54
|
"@babel/preset-typescript": "7.29.7",
|
|
55
55
|
"@babel/traverse": "7.29.8",
|
|
56
56
|
"@babel/types": "7.29.8",
|
|
57
|
-
"@cedarjs/api": "8.0.0-canary.
|
|
58
|
-
"@cedarjs/api-server": "8.0.0-canary.
|
|
59
|
-
"@cedarjs/babel-config": "8.0.0-canary.
|
|
60
|
-
"@cedarjs/context": "8.0.0-canary.
|
|
61
|
-
"@cedarjs/graphql-server": "8.0.0-canary.
|
|
62
|
-
"@cedarjs/internal": "8.0.0-canary.
|
|
63
|
-
"@cedarjs/jobs": "8.0.0-canary.
|
|
64
|
-
"@cedarjs/project-config": "8.0.0-canary.
|
|
65
|
-
"@cedarjs/server-store": "8.0.0-canary.
|
|
66
|
-
"@cedarjs/structure": "8.0.0-canary.
|
|
67
|
-
"@cedarjs/testing": "8.0.0-canary.
|
|
57
|
+
"@cedarjs/api": "8.0.0-canary.3326",
|
|
58
|
+
"@cedarjs/api-server": "8.0.0-canary.3326",
|
|
59
|
+
"@cedarjs/babel-config": "8.0.0-canary.3326",
|
|
60
|
+
"@cedarjs/context": "8.0.0-canary.3326",
|
|
61
|
+
"@cedarjs/graphql-server": "8.0.0-canary.3326",
|
|
62
|
+
"@cedarjs/internal": "8.0.0-canary.3326",
|
|
63
|
+
"@cedarjs/jobs": "8.0.0-canary.3326",
|
|
64
|
+
"@cedarjs/project-config": "8.0.0-canary.3326",
|
|
65
|
+
"@cedarjs/server-store": "8.0.0-canary.3326",
|
|
66
|
+
"@cedarjs/structure": "8.0.0-canary.3326",
|
|
67
|
+
"@cedarjs/testing": "8.0.0-canary.3326",
|
|
68
68
|
"@swc/core": "1.16.13",
|
|
69
69
|
"@universal-deploy/store": "^0.2.1",
|
|
70
70
|
"@universal-deploy/vite": "^0.1.9",
|
|
@@ -94,10 +94,10 @@
|
|
|
94
94
|
"yargs-parser": "21.1.1"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
|
-
"@cedarjs/auth": "8.0.0-canary.
|
|
98
|
-
"@cedarjs/framework-tools": "8.0.0-canary.
|
|
99
|
-
"@cedarjs/router": "8.0.0-canary.
|
|
100
|
-
"@cedarjs/web": "8.0.0-canary.
|
|
97
|
+
"@cedarjs/auth": "8.0.0-canary.3326",
|
|
98
|
+
"@cedarjs/framework-tools": "8.0.0-canary.3326",
|
|
99
|
+
"@cedarjs/router": "8.0.0-canary.3326",
|
|
100
|
+
"@cedarjs/web": "8.0.0-canary.3326",
|
|
101
101
|
"@dr.pogodin/react-helmet": "2.0.4",
|
|
102
102
|
"@hyrious/esbuild-plugin-commonjs": "0.2.6",
|
|
103
103
|
"@jridgewell/trace-mapping": "0.3.31",
|
|
@@ -119,9 +119,9 @@
|
|
|
119
119
|
"vitest": "4.1.11"
|
|
120
120
|
},
|
|
121
121
|
"peerDependencies": {
|
|
122
|
-
"@cedarjs/auth": "8.0.0-canary.
|
|
123
|
-
"@cedarjs/router": "8.0.0-canary.
|
|
124
|
-
"@cedarjs/web": "8.0.0-canary.
|
|
122
|
+
"@cedarjs/auth": "8.0.0-canary.3326",
|
|
123
|
+
"@cedarjs/router": "8.0.0-canary.3326",
|
|
124
|
+
"@cedarjs/web": "8.0.0-canary.3326",
|
|
125
125
|
"react": "19.3.0",
|
|
126
126
|
"react-dom": "19.3.0"
|
|
127
127
|
},
|