@nordcraft/ssr 1.0.21 → 1.0.23

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,6 +1,6 @@
1
1
  import type { PageComponent, PageRoute } from '@nordcraft/core/dist/component/component.types';
2
2
  import type { FormulaContext, ToddleServerEnv } from '@nordcraft/core/dist/formula/formula';
3
- import type { ProjectFiles } from '../ssr.types';
3
+ import type { InstalledPackage, ProjectFiles } from '../ssr.types';
4
4
  /**
5
5
  * Builds a FormulaContext that can be used to evaluate formulas for a page component
6
6
  * It also initializes data->Variables with their initial values based on the FormulaContext
@@ -14,7 +14,9 @@ export declare const getPageFormulaContext: ({ branchName, component, req, logEr
14
14
  }) => FormulaContext & {
15
15
  env: ToddleServerEnv;
16
16
  };
17
- export declare const getServerToddleObject: (files: ProjectFiles) => FormulaContext["toddle"];
17
+ export declare const getServerToddleObject: (files: Pick<ProjectFiles, "formulas" | "packages"> & {
18
+ packages?: Record<string, Pick<InstalledPackage, "formulas">>;
19
+ }) => FormulaContext["toddle"];
18
20
  export declare const getDataUrlParameters: ({ route, req, }: {
19
21
  route: Pick<PageRoute, "path" | "query">;
20
22
  req: Request;
@@ -1 +1 @@
1
- {"version":3,"file":"formulaContext.js","sourceRoot":"","sources":["../../src/rendering/formulaContext.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"formulaContext.js","sourceRoot":"","sources":["../../src/rendering/formulaContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AASrE,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAA;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAA;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAA;AAC3D,OAAO,KAAK,WAAW,MAAM,kCAAkC,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAA;AAElD;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,EACpC,UAAU,EACV,SAAS,EACT,GAAG,EACH,SAAS,EACT,KAAK,GAON,EAA6C,EAAE;IAC9C,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAA;IACrD,MAAM,EAAE,wBAAwB,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,aAAa,CAC3E,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,CAChC,CAAA;IACD,MAAM,cAAc,GAA8C;QAChE,IAAI,EAAE;YACJ,QAAQ,EAAE;gBACR,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,EAAE;gBAC1B,IAAI,EAAE,GAAG,CAAC,QAAQ;gBAClB,MAAM,EAAE,cAAc;gBACtB,KAAK,EAAE,wBAAwB;gBAC/B,IAAI;aACL;YACD,UAAU,EAAE,cAAc;YAC1B,2EAA2E;YAC3E,gFAAgF;YAChF,+BAA+B;YAC/B,gBAAgB,EAAE,oBAAoB,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;YACvE,IAAI,EAAE,EAAyB;SAChC;QACD,SAAS;QACT,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,SAAS;QAClB,GAAG;QACH,MAAM,EAAE,qBAAqB,CAAC,KAAK,CAAC;KACrC,CAAA;IACD,cAAc,CAAC,IAAI,CAAC,SAAS,GAAG,SAAS,CACvC,SAAS,CAAC,SAAS,EACnB,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE;QACnB,OAAO,YAAY,CAAC,YAAY,EAAE,cAAc,CAAC,CAAA;IACnD,CAAC,CACF,CAAA;IACD,OAAO,cAAc,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,KAEC,EACyB,EAAE;IAC5B,MAAM,YAAY,GAAG,MAAM,CAAC,WAAW,CACrC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;QAClD,UAAU,GAAG,IAAI;QACjB,MAAM,CAAC,OAAc;KACtB,CAAC,CACH,CAAA;IACD,OAAO;QACL,UAAU,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;QAChD,gBAAgB,EAAE,CAAC,IAAY,EAAE,WAA+B,EAAE,EAAE;YAClE,IAAI,OAA0C,CAAA;YAE9C,IAAI,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC3B,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAA;YAC3D,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAA;YAClC,CAAC;YAED,IAAI,OAAO,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxC,OAAO,OAAO,CAAA;YAChB,CAAC;QACH,CAAC;QACD,MAAM,EAAE,EAAE;KACX,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,EACnC,KAAK,EACL,GAAG,GAIJ,EAAE,EAAE;IACH,MAAM,EAAE,wBAAwB,EAAE,cAAc,EAAE,GAAG,aAAa,CAAC;QACjE,KAAK;QACL,GAAG;KACJ,CAAC,CAAA;IACF,OAAO;QACL,GAAG,wBAAwB;QAC3B,GAAG,cAAc;KAClB,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAC5B,KAAK,EACL,GAAG,GAIJ,EAAE,EAAE;IACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,MAAM,YAAY,GAAG;QACnB,GAAG,sBAAsB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE;KACtD,CAAC,MAAM,CAIN,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QACvB,GAAG,MAAM;QACT,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,IAAI;KACnB,CAAC,EACF,EAAE,CACH,CAAA;IACD,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IACzC,MAAM,UAAU,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAC3D,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,IACE,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC9B,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,QAAQ,EACvC,CAAC;gBACD,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAA;YACvD,CAAC;iBAAM,CAAC;gBACN,oDAAoD;gBACpD,6DAA6D;gBAC7D,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAA;YACxC,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,qDAAqD;IACrD,2CAA2C;IAC3C,MAAM,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CAE/D,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;IACpD,OAAO;QACL,UAAU;QACV,wBAAwB,EAAE,EAAE,GAAG,kBAAkB,EAAE,GAAG,YAAY,EAAE;QACpE,cAAc,EAAE,EAAE,GAAG,YAAY,EAAE,GAAG,UAAU,EAAE;QAClD,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACvB,GAAG;KACJ,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EACxB,UAAU,EACV,GAAG,EACH,SAAS,GAKV,EAAE,EAAE,CACH,CAAC;IACC,UAAU,EAAE,UAAU;IACtB,mDAAmD;IACnD,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE;QACP,OAAO,EAAE,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC;QACxC,OAAO,EAAE,iBAAiB,CAAC,GAAG,CAAC;QAC/B,GAAG,EAAE,GAAG,CAAC,GAAG;KACb;IACD,SAAS;CACV,CAAoB,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import type { PageComponent, PageRoute, RouteDeclaration } from '@nordcraft/core/dist/component/component.types';
2
- import type { ToddleEnv } from '@nordcraft/core/dist/formula/formula';
2
+ import type { FormulaContext, ToddleEnv } from '@nordcraft/core/dist/formula/formula';
3
3
  import type { ProjectFiles, Route } from '../ssr.types';
4
4
  export declare const matchPageForUrl: ({ url, components, }: {
5
5
  url: URL;
@@ -7,19 +7,20 @@ export declare const matchPageForUrl: ({ url, components, }: {
7
7
  route?: RouteDeclaration | null;
8
8
  }>>;
9
9
  }) => PageComponent | undefined;
10
- export declare const matchRouteForUrl: <T extends {
11
- source: RouteDeclaration;
12
- }>({ url, routes, }: {
10
+ export declare const matchRouteForUrl: ({ env, req, routes, serverContext, url, }: {
11
+ env: ToddleEnv;
12
+ req: Request;
13
+ routes?: Record<string, Route>;
14
+ serverContext: FormulaContext["toddle"];
13
15
  url: URL;
14
- routes?: Record<string, T>;
15
- }) => T | undefined;
16
+ }) => Route | undefined;
16
17
  export declare const matchRoutes: <T>({ url, entries, getRoute, }: {
17
18
  url: URL;
18
19
  entries: T[];
19
20
  getRoute: (entry: T) => Pick<PageRoute, "path" | "query">;
20
21
  }) => T | undefined;
21
- export declare const getRouteDestination: ({ files, req, route, env, }: {
22
- files: ProjectFiles;
22
+ export declare const getRouteDestination: ({ serverContext, req, route, env, }: {
23
+ serverContext: FormulaContext["toddle"];
23
24
  req: Request;
24
25
  route: Route;
25
26
  env: ToddleEnv;
@@ -1,14 +1,28 @@
1
1
  import { getUrl } from '@nordcraft/core/dist/api/api';
2
- import { isDefined } from '@nordcraft/core/dist/utils/util';
3
- import { getParameters, getServerToddleObject, } from '../rendering/formulaContext';
2
+ import { applyFormula } from '@nordcraft/core/dist/formula/formula';
3
+ import { isDefined, toBoolean } from '@nordcraft/core/dist/utils/util';
4
+ import { getParameters } from '../rendering/formulaContext';
4
5
  export const matchPageForUrl = ({ url, components, }) => matchRoutes({
5
6
  url,
6
7
  entries: getPages(components),
7
8
  getRoute: (route) => route.route,
8
9
  });
9
- export const matchRouteForUrl = ({ url, routes, }) => matchRoutes({
10
+ export const matchRouteForUrl = ({ env, req, routes, serverContext, url, }) => matchRoutes({
10
11
  url,
11
- entries: Object.values(routes ?? {}),
12
+ entries: Object.values(routes ?? {}).filter((route) => {
13
+ if (!isDefined(route.enabled)) {
14
+ // If the route does not have an explicit enabled property, we assume it is enabled
15
+ return true;
16
+ }
17
+ // Only include routes that are enabled
18
+ const formulaContext = getRouteFormulaContext({
19
+ env,
20
+ req,
21
+ route,
22
+ serverContext,
23
+ });
24
+ return toBoolean(applyFormula(route.enabled.formula, formulaContext));
25
+ }),
12
26
  getRoute: (route) => route.source,
13
27
  });
14
28
  export const matchRoutes = ({ url, entries, getRoute, }) => {
@@ -35,27 +49,16 @@ export const matchRoutes = ({ url, entries, getRoute, }) => {
35
49
  });
36
50
  return matches[0];
37
51
  };
38
- export const getRouteDestination = ({ files, req, route, env, }) => {
52
+ export const getRouteDestination = ({ serverContext, req, route, env, }) => {
39
53
  try {
40
54
  const requestUrl = new URL(req.url);
41
- const { searchParamsWithDefaults, pathParams } = getParameters({
42
- route: route.source,
55
+ const formulaContext = getRouteFormulaContext({
56
+ env,
43
57
  req,
58
+ route,
59
+ serverContext,
44
60
  });
45
- const url = getUrl(route.destination,
46
- // destination formulas should only have access to URL parameters from
47
- // the route's source definition + global formulas.
48
- {
49
- data: {
50
- Attributes: {},
51
- 'Route parameters': {
52
- path: pathParams,
53
- query: searchParamsWithDefaults,
54
- },
55
- },
56
- toddle: getServerToddleObject(files),
57
- env,
58
- },
61
+ const url = getUrl(route.destination, formulaContext,
59
62
  // Redirects can redirect to relative URLs - rewrites can't
60
63
  route.type === 'redirect' ? requestUrl.origin : undefined);
61
64
  if (route.type === 'redirect' &&
@@ -74,6 +77,27 @@ export const getRouteDestination = ({ files, req, route, env, }) => {
74
77
  }
75
78
  catch { }
76
79
  };
80
+ const getRouteFormulaContext = ({ env, req, route, serverContext, }) => {
81
+ const { searchParamsWithDefaults, pathParams } = getParameters({
82
+ route: route.source,
83
+ req,
84
+ });
85
+ return {
86
+ component: undefined,
87
+ // destination formulas should only have access to URL parameters from
88
+ // the route's source definition + global formulas.
89
+ data: {
90
+ Attributes: {},
91
+ 'Route parameters': {
92
+ path: pathParams ?? {},
93
+ query: searchParamsWithDefaults,
94
+ },
95
+ },
96
+ env,
97
+ package: undefined,
98
+ toddle: serverContext,
99
+ };
100
+ };
77
101
  export const get404Page = (components) => getPages(components).find((page) => page.name === '404');
78
102
  const getPages = (components) => Object.values(components).filter((c) => isDefined(c.route));
79
103
  export const getPathSegments = (url) => url.pathname
@@ -1 +1 @@
1
- {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../src/routing/routing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../src/routing/routing.ts"],"names":[],"mappings":"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"}
@@ -89,6 +89,9 @@ export interface PluginAction {
89
89
  interface BaseRoute {
90
90
  source: RouteDeclaration;
91
91
  destination: ApiBase;
92
+ enabled?: {
93
+ formula: Formula;
94
+ };
92
95
  }
93
96
  export interface RewriteRoute extends BaseRoute {
94
97
  type: 'rewrite';
package/package.json CHANGED
@@ -13,10 +13,10 @@
13
13
  "main": "dist/index.js",
14
14
  "types": "dist/index.d.ts",
15
15
  "dependencies": {
16
- "@nordcraft/core": "1.0.21",
17
- "@nordcraft/std-lib": "1.0.21",
16
+ "@nordcraft/core": "1.0.23",
17
+ "@nordcraft/std-lib": "1.0.23",
18
18
  "cookie": "1.0.2",
19
19
  "xss": "1.0.15"
20
20
  },
21
- "version": "1.0.21"
21
+ "version": "1.0.23"
22
22
  }
@@ -14,7 +14,7 @@ import { mapValues } from '@nordcraft/core/dist/utils/collections'
14
14
  import { isDefined } from '@nordcraft/core/dist/utils/util'
15
15
  import * as libFormulas from '@nordcraft/std-lib/dist/formulas'
16
16
  import { getPathSegments } from '../routing/routing'
17
- import type { ProjectFiles } from '../ssr.types'
17
+ import type { InstalledPackage, ProjectFiles } from '../ssr.types'
18
18
  import { getRequestCookies } from './cookies'
19
19
  import { escapeSearchParameters } from './request'
20
20
 
@@ -71,7 +71,9 @@ export const getPageFormulaContext = ({
71
71
  }
72
72
 
73
73
  export const getServerToddleObject = (
74
- files: ProjectFiles,
74
+ files: Pick<ProjectFiles, 'formulas' | 'packages'> & {
75
+ packages?: Record<string, Pick<InstalledPackage, 'formulas'>>
76
+ },
75
77
  ): FormulaContext['toddle'] => {
76
78
  const coreFormulas = Object.fromEntries(
77
79
  Object.entries(libFormulas).map(([name, module]) => [
@@ -1,6 +1,9 @@
1
1
  import type { RouteDeclaration } from '@nordcraft/core/dist/component/component.types'
2
+ import { valueFormula } from '@nordcraft/core/dist/formula/formulaUtils'
2
3
  import { describe, expect, test } from 'bun:test'
3
- import { matchPageForUrl } from './routing'
4
+ import { serverEnv } from '../rendering/formulaContext'
5
+ import type { Route } from '../ssr.types'
6
+ import { matchPageForUrl, matchRouteForUrl } from './routing'
4
7
 
5
8
  describe('matchPageForUrl', () => {
6
9
  test('it finds the correct page for a url', () => {
@@ -151,3 +154,125 @@ describe('matchPageForUrl', () => {
151
154
  expect(matchPageForUrl({ url: docsUrl, components: pages })).toBeUndefined()
152
155
  })
153
156
  })
157
+ describe('matchRouteForUrl', () => {
158
+ test('it finds the correct route for a url', () => {
159
+ const routes: Record<string, Route> = {
160
+ testRedirect: {
161
+ type: 'redirect',
162
+ source: {
163
+ path: [
164
+ { type: 'static', name: 'not-docs' },
165
+ { type: 'param', testValue: '', name: 'slug' },
166
+ ],
167
+ query: {},
168
+ },
169
+ destination: {
170
+ url: { type: 'value', value: 'https://google.com' },
171
+ path: {},
172
+ },
173
+ },
174
+ docsRedirect: {
175
+ type: 'redirect',
176
+ source: {
177
+ path: [
178
+ { type: 'static', name: 'docs' },
179
+ { type: 'param', testValue: '', name: 'slug' },
180
+ ],
181
+ query: {},
182
+ },
183
+ destination: {
184
+ url: { type: 'value', value: 'https://docs.nordcraft.com' },
185
+ path: {
186
+ first: {
187
+ index: 0,
188
+ formula: valueFormula('slug'),
189
+ },
190
+ },
191
+ },
192
+ },
193
+ }
194
+
195
+ const docsUrl = new URL('http://localhost:3000/docs/intro')
196
+ const request = new Request(docsUrl)
197
+ expect(
198
+ matchRouteForUrl({
199
+ url: docsUrl,
200
+ routes,
201
+ env: serverEnv({
202
+ branchName: 'main',
203
+ req: request,
204
+ logErrors: false,
205
+ }),
206
+ req: request,
207
+ serverContext: {
208
+ errors: [],
209
+ getFormula: () => undefined,
210
+ getCustomFormula: () => undefined,
211
+ },
212
+ }),
213
+ ).toEqual(routes['docsRedirect'])
214
+ })
215
+ test('it ignores disabled routes', () => {
216
+ const routes: Record<string, Route> = {
217
+ disabledRedirect: {
218
+ type: 'redirect',
219
+ enabled: { formula: valueFormula(false) },
220
+ source: {
221
+ path: [
222
+ { type: 'static', name: 'docs' },
223
+ { type: 'param', testValue: '', name: 'slug' },
224
+ ],
225
+ query: {},
226
+ },
227
+ destination: {
228
+ url: { type: 'value', value: 'https://docs.nordcraft.com' },
229
+ path: {
230
+ first: {
231
+ index: 0,
232
+ formula: valueFormula('slug'),
233
+ },
234
+ },
235
+ },
236
+ },
237
+ docsRedirect: {
238
+ type: 'redirect',
239
+ source: {
240
+ path: [
241
+ { type: 'param', testValue: 'docs', name: 'docs' },
242
+ { type: 'param', testValue: '', name: 'slug' },
243
+ ],
244
+ query: {},
245
+ },
246
+ destination: {
247
+ url: { type: 'value', value: 'https://docs.nordcraft.com' },
248
+ path: {
249
+ first: {
250
+ index: 0,
251
+ formula: valueFormula('slug'),
252
+ },
253
+ },
254
+ },
255
+ },
256
+ }
257
+
258
+ const docsUrl = new URL('http://localhost:3000/docs/intro')
259
+ const request = new Request(docsUrl)
260
+ expect(
261
+ matchRouteForUrl({
262
+ url: docsUrl,
263
+ routes,
264
+ env: serverEnv({
265
+ branchName: 'main',
266
+ req: request,
267
+ logErrors: false,
268
+ }),
269
+ req: request,
270
+ serverContext: {
271
+ errors: [],
272
+ getFormula: () => undefined,
273
+ getCustomFormula: () => undefined,
274
+ },
275
+ }),
276
+ ).toEqual(routes['docsRedirect'])
277
+ })
278
+ })
@@ -4,12 +4,13 @@ import type {
4
4
  PageRoute,
5
5
  RouteDeclaration,
6
6
  } from '@nordcraft/core/dist/component/component.types'
7
- import type { ToddleEnv } from '@nordcraft/core/dist/formula/formula'
8
- import { isDefined } from '@nordcraft/core/dist/utils/util'
9
- import {
10
- getParameters,
11
- getServerToddleObject,
12
- } from '../rendering/formulaContext'
7
+ import type {
8
+ FormulaContext,
9
+ ToddleEnv,
10
+ } from '@nordcraft/core/dist/formula/formula'
11
+ import { applyFormula } from '@nordcraft/core/dist/formula/formula'
12
+ import { isDefined, toBoolean } from '@nordcraft/core/dist/utils/util'
13
+ import { getParameters } from '../rendering/formulaContext'
13
14
  import type { ProjectFiles, Route } from '../ssr.types'
14
15
 
15
16
  export const matchPageForUrl = ({
@@ -25,16 +26,35 @@ export const matchPageForUrl = ({
25
26
  getRoute: (route) => route.route,
26
27
  })
27
28
 
28
- export const matchRouteForUrl = <T extends { source: RouteDeclaration }>({
29
- url,
29
+ export const matchRouteForUrl = ({
30
+ env,
31
+ req,
30
32
  routes,
33
+ serverContext,
34
+ url,
31
35
  }: {
36
+ env: ToddleEnv
37
+ req: Request
38
+ routes?: Record<string, Route>
39
+ serverContext: FormulaContext['toddle']
32
40
  url: URL
33
- routes?: Record<string, T>
34
41
  }) =>
35
42
  matchRoutes({
36
43
  url,
37
- entries: Object.values(routes ?? {}),
44
+ entries: Object.values(routes ?? {}).filter((route) => {
45
+ if (!isDefined(route.enabled)) {
46
+ // If the route does not have an explicit enabled property, we assume it is enabled
47
+ return true
48
+ }
49
+ // Only include routes that are enabled
50
+ const formulaContext = getRouteFormulaContext({
51
+ env,
52
+ req,
53
+ route,
54
+ serverContext,
55
+ })
56
+ return toBoolean(applyFormula(route.enabled.formula, formulaContext))
57
+ }),
38
58
  getRoute: (route) => route.source,
39
59
  })
40
60
 
@@ -78,12 +98,12 @@ export const matchRoutes = <T>({
78
98
  }
79
99
 
80
100
  export const getRouteDestination = ({
81
- files,
101
+ serverContext,
82
102
  req,
83
103
  route,
84
104
  env,
85
105
  }: {
86
- files: ProjectFiles
106
+ serverContext: FormulaContext['toddle']
87
107
  req: Request
88
108
  route: Route
89
109
  env: ToddleEnv
@@ -91,26 +111,16 @@ export const getRouteDestination = ({
91
111
  try {
92
112
  const requestUrl = new URL(req.url)
93
113
 
94
- const { searchParamsWithDefaults, pathParams } = getParameters({
95
- route: route.source,
114
+ const formulaContext = getRouteFormulaContext({
115
+ env,
96
116
  req,
117
+ route,
118
+ serverContext,
97
119
  })
98
120
 
99
121
  const url = getUrl(
100
122
  route.destination,
101
- // destination formulas should only have access to URL parameters from
102
- // the route's source definition + global formulas.
103
- {
104
- data: {
105
- Attributes: {},
106
- 'Route parameters': {
107
- path: pathParams,
108
- query: searchParamsWithDefaults,
109
- },
110
- },
111
- toddle: getServerToddleObject(files),
112
- env,
113
- } as any,
123
+ formulaContext,
114
124
  // Redirects can redirect to relative URLs - rewrites can't
115
125
  route.type === 'redirect' ? requestUrl.origin : undefined,
116
126
  )
@@ -132,6 +142,38 @@ export const getRouteDestination = ({
132
142
  } catch {}
133
143
  }
134
144
 
145
+ const getRouteFormulaContext = ({
146
+ env,
147
+ req,
148
+ route,
149
+ serverContext,
150
+ }: {
151
+ env: ToddleEnv
152
+ req: Request
153
+ route: Route
154
+ serverContext: FormulaContext['toddle']
155
+ }): FormulaContext => {
156
+ const { searchParamsWithDefaults, pathParams } = getParameters({
157
+ route: route.source,
158
+ req,
159
+ })
160
+ return {
161
+ component: undefined,
162
+ // destination formulas should only have access to URL parameters from
163
+ // the route's source definition + global formulas.
164
+ data: {
165
+ Attributes: {},
166
+ 'Route parameters': {
167
+ path: pathParams ?? {},
168
+ query: searchParamsWithDefaults,
169
+ },
170
+ },
171
+ env,
172
+ package: undefined,
173
+ toddle: serverContext,
174
+ }
175
+ }
176
+
135
177
  export const get404Page = (components: ProjectFiles['components']) =>
136
178
  getPages(components).find((page) => page.name === '404')
137
179
 
package/src/ssr.types.ts CHANGED
@@ -103,6 +103,7 @@ export interface PluginAction {
103
103
  interface BaseRoute {
104
104
  source: RouteDeclaration
105
105
  destination: ApiBase
106
+ enabled?: { formula: Formula }
106
107
  }
107
108
 
108
109
  export interface RewriteRoute extends BaseRoute {