@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.
@@ -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 should pin a client to this
8
- * deploy before expiring. Netlify's own guidance is to keep this short to
9
- * minimize the window where a client could end up pinned to a deploy
10
- * that's since been cleaned up — but long enough to outlast a normal
11
- * session. Defaults to 4 hours.
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
- * Generates Netlify's `.netlify/v1/skew-protection.json` build output and
17
- * stamps the current deploy's skew token into the SSR bundle.
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
- * The UD wrapper above only covers requests that actually reach the UD
38
- * Fetchable, though — a visitor's very first request, for the static HTML
39
- * document itself, is served straight out of Netlify's CDN from `web/dist`
40
- * and never reaches it. Netlify's own `_headers`-based custom headers
41
- * explicitly warn that `Set-Cookie` there "may be overridden by Netlify
42
- * cookie handling", so this also emits a small framework-authored Edge
43
- * Function (via `.netlify/v1/edge-functions/`, auto-registered, no
44
- * `netlify.toml` entry needed) that runs on every request, calls
45
- * `context.next()`, and stamps the same cookie using the genuinely
46
- * runtime-provided `context.deploy.skewProtectionToken` — which Edge
47
- * Functions, unlike UD's Fetchables, do have access to. It skips responses
48
- * that already carry our cookie (set by the UD wrapper above) so the two
49
- * layers don't double-stamp the same request.
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;AAIlC,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;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,uCAA4C,GACpD,MAAM,CAgOR"}
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 * 4
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 runtime skew-token cookie propagation. This likely means @universal-deploy/vite changed how it generates the catch-all entry.'
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
- " // No token (e.g. a local `cedar build --ud` run outside a",
44
- " // Netlify build) or no response (an unmatched route) \u2014 nothing",
45
- " // to stamp. Statuses outside 200-599 (e.g. 101 for a WebSocket",
46
- " // upgrade) make the Response constructor below throw, and 204/304",
47
- " // responses have no body semantics worth re-wrapping \u2014 leave all",
48
- " // of those untouched. Also skip if a `Set-Cookie` for our cookie",
49
- " // name is already present (e.g. set further up the handler chain,",
50
- " // or by the edge function below) to avoid sending a duplicate.",
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
- // Match every path: Cedar can't assume a fixed static-asset
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 \u2014 stamps the skew-protection cookie",
131
- "// on requests that don't reach Universal Deploy's catch-all",
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
- " // Statuses outside 200-599 (e.g. 101 for a WebSocket upgrade)",
141
- " // make the Response constructor below throw, and 204/304",
142
- " // responses have no body semantics worth re-wrapping. Also skip",
143
- " // if already stamped \u2014 either by the UD wrapper further down the",
144
- " // chain, or (if this ran twice somehow) by this function itself.",
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;AAgBlC,MAAM,WAAW,iCAAiC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AA6GD,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,iCAAsC,GAC9C,MAAM,CA0GR"}
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: "cedar-universal-deploy",
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.3324",
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.3324",
58
- "@cedarjs/api-server": "8.0.0-canary.3324",
59
- "@cedarjs/babel-config": "8.0.0-canary.3324",
60
- "@cedarjs/context": "8.0.0-canary.3324",
61
- "@cedarjs/graphql-server": "8.0.0-canary.3324",
62
- "@cedarjs/internal": "8.0.0-canary.3324",
63
- "@cedarjs/jobs": "8.0.0-canary.3324",
64
- "@cedarjs/project-config": "8.0.0-canary.3324",
65
- "@cedarjs/server-store": "8.0.0-canary.3324",
66
- "@cedarjs/structure": "8.0.0-canary.3324",
67
- "@cedarjs/testing": "8.0.0-canary.3324",
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.3324",
98
- "@cedarjs/framework-tools": "8.0.0-canary.3324",
99
- "@cedarjs/router": "8.0.0-canary.3324",
100
- "@cedarjs/web": "8.0.0-canary.3324",
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.3324",
123
- "@cedarjs/router": "8.0.0-canary.3324",
124
- "@cedarjs/web": "8.0.0-canary.3324",
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
  },