@okam/directus-next 2.0.2 → 2.1.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/CHANGELOG.md CHANGED
@@ -1,3 +1,52 @@
1
+ ## 2.1.1 (2026-03-26)
2
+
3
+ ### 🚀 Features
4
+
5
+ - **directus-next:** getPageSettings props accepts gql client ([a6d983fa](https://github.com/OKAMca/stack/commit/a6d983fa))
6
+
7
+ ### 🩹 Fixes
8
+
9
+ - **directus-next:** getPageSettings also allows custom query fn ([c76c5163](https://github.com/OKAMca/stack/commit/c76c5163))
10
+ - **directus-next:** remove props client memoization to match config arg ([fb169f6a](https://github.com/OKAMca/stack/commit/fb169f6a))
11
+
12
+ ### 🧱 Updated Dependencies
13
+
14
+ - Updated directus-query to 2.0.1
15
+
16
+ ### ❤️ Thank You
17
+
18
+ - poclerson
19
+
20
+ ## 2.1.0 (2026-03-26)
21
+
22
+ ### 🚀 Features
23
+
24
+ - **directus-next:** directus router default locale + display options ([#420](https://github.com/OKAMca/stack/pull/420))
25
+
26
+ ### 🩹 Fixes
27
+
28
+ - resolve dependabot security alerts and clean up published package dependencies ([#441](https://github.com/OKAMca/stack/pull/441))
29
+ - replace use server by server-only in server chunks ([#437](https://github.com/OKAMca/stack/pull/437))
30
+
31
+ ### ❤️ Thank You
32
+
33
+ - Claude Opus 4.6 (1M context)
34
+ - Marie-Maxime Tanguay @marie-maxime
35
+ - Pierre-Olivier Clerson @poclerson
36
+
37
+ ## 2.0.3 (2026-03-20)
38
+
39
+ ### 🩹 Fixes
40
+
41
+ - resolve dependabot security alerts and clean up published package dependencies ([#441](https://github.com/OKAMca/stack/pull/441))
42
+ - replace use server by server-only in server chunks ([#437](https://github.com/OKAMca/stack/pull/437))
43
+
44
+ ### ❤️ Thank You
45
+
46
+ - Claude Opus 4.6 (1M context)
47
+ - Marie-Maxime Tanguay @marie-maxime
48
+ - Pierre-Olivier Clerson @poclerson
49
+
1
50
  ## 2.0.2 (2026-03-17)
2
51
 
3
52
  ### 🧱 Updated Dependencies
package/index.d.ts CHANGED
@@ -4,4 +4,4 @@ export { logger as DirectusNextLogger } from './logger';
4
4
  export * from './redirect';
5
5
  export { getJsonErrorResponse } from './response';
6
6
  export { directusRouteRouter } from './router/router';
7
- export type * from './types';
7
+ export * from './types';
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const router = require("./router-CwzG5Cu9.js");
3
+ const router = require("./router-DorBYKUX.js");
4
4
  const headers = require("next/headers");
5
5
  const navigation = require("next/navigation");
6
6
  const radashi = require("radashi");
@@ -203,6 +203,7 @@ async function handleRedirectsRoute({
203
203
  return new Response(JSON.stringify({ redirects, rewrites }), { status: 200 });
204
204
  }
205
205
  exports.DirectusNextLogger = router.logger;
206
+ exports.DirectusRouteLocalePrefix = router.DirectusRouteLocalePrefix;
206
207
  exports.directusRouteRouter = router.directusRouteRouter;
207
208
  exports.getApiRouteUrlDefault = router.getApiRouteUrlDefault;
208
209
  exports.getRedirectSecretDefault = router.getRedirectSecretDefault;
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { g as getRedirectSecretDefault } from "./router-16XNi-G3.mjs";
2
- import { l, d, a, b, h } from "./router-16XNi-G3.mjs";
1
+ import { g as getRedirectSecretDefault } from "./router-DC6WVUlz.mjs";
2
+ import { l, D, d, a, b, h } from "./router-DC6WVUlz.mjs";
3
3
  import { draftMode } from "next/headers";
4
4
  import { redirect } from "next/navigation";
5
5
  import { template } from "radashi";
@@ -186,6 +186,7 @@ async function handleRedirectsRoute({
186
186
  }
187
187
  export {
188
188
  l as DirectusNextLogger,
189
+ D as DirectusRouteLocalePrefix,
189
190
  d as directusRouteRouter,
190
191
  a as getApiRouteUrlDefault,
191
192
  getDraftSecretDefault,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okam/directus-next",
3
- "version": "2.0.2",
3
+ "version": "2.1.1",
4
4
  "repository": {
5
5
  "url": "https://github.com/OKAMca/stack.git"
6
6
  },
@@ -38,17 +38,16 @@
38
38
  "access": "public"
39
39
  },
40
40
  "peerDependencies": {
41
- "next": "^15.1.0 || ^16.0.0"
41
+ "next": ">=15.5.13 <16.0.0 || ^16.1.7"
42
42
  },
43
43
  "dependencies": {
44
44
  "@graphql-typed-document-node/core": "3.2.0",
45
45
  "@okam/core-lib": "2.0.0",
46
46
  "@okam/directus-node": "1.0.0",
47
- "@okam/directus-query": "2.0.0",
47
+ "@okam/directus-query": "2.0.1",
48
48
  "@okam/logger": "1.1.0",
49
- "@okam/next-component": "2.0.3",
49
+ "@okam/next-component": "2.1.0",
50
50
  "graphql-request": "^7.1.2",
51
- "next": "^15.1.0 || ^16.0.0",
52
51
  "radashi": "^12.3.0",
53
52
  "server-only": "0.0.1",
54
53
  "zod": "^4.3.5"
@@ -1,5 +1,5 @@
1
1
  import { TypedDocumentNode } from '@graphql-typed-document-node/core';
2
- import { Variables } from 'graphql-request';
2
+ import { GraphQLClient, Variables } from 'graphql-request';
3
3
  import { TDirectusRouteConfig } from '../types/directusRouteConfig';
4
4
  import { Fragmentize } from '../types/Fragments';
5
5
  import { TPageSettings, TPageSettingsItemQuery, TPageSettingsQueryItem } from '../types/pageSettings';
@@ -19,6 +19,30 @@ export interface TGetPageSettingsProps<Item extends TPageSettingsQueryItem, Item
19
19
  * Either a directus route config or directly a locale map. Not passing a config while passing a document will result in direct usage of the `locale` variable.
20
20
  */
21
21
  config?: TGetPageSettingsConfig;
22
+ /**
23
+ * GraphQL client to use for the query done via {@link queryGql}. Defaults to `@okam/directus-query` `defaultGraphqlRequestClient`
24
+ * @default defaultGraphqlRequestClient
25
+ */
26
+ client?: GraphQLClient;
27
+ /**
28
+ * Query function to replace the default {@link queryGql}. Note that `document`, `variables` and `client` still get passed to this function, but they can be overriden easily.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const customGqlClient = new GraphQLClient()
33
+ *
34
+ * const product = await getPageSettings({
35
+ * queryGqlFn: async (document, variables) => {
36
+ * // ignore the `client` argument passed in the callback
37
+ * const result = await queryGql(document, variables, customGqlClient)
38
+ * return result
39
+ * }
40
+ * })
41
+ * ```
42
+ *
43
+ * @default queryGql
44
+ */
45
+ queryGqlFn?: (document: TPageSettingsItemDocument<Item, ItemKey, QueryVariables>, queryKey?: QueryVariables | undefined, client?: GraphQLClient) => Promise<TPageSettingsItemQuery<Item, ItemKey>>;
22
46
  }
23
47
  export type TGetPageSettingsReturn<Item extends TPageSettingsQueryItem> = Omit<Item, 'page_settings'> & {
24
48
  page_settings?: Exclude<NonNullable<Item>['page_settings'], Fragmentize<TPageSettings, 'PageSettingsFragment'>> | null | undefined;
@@ -88,6 +88,11 @@ async function handleRedirect(request, options = {}) {
88
88
  log(`${capitalize(type)}ing to ${url.toString()} with status ${status}`);
89
89
  return NextResponse[type](url, { status });
90
90
  }
91
+ var DirectusRouteLocalePrefix = /* @__PURE__ */ ((DirectusRouteLocalePrefix2) => {
92
+ DirectusRouteLocalePrefix2["AsNeeded"] = "as-needed";
93
+ DirectusRouteLocalePrefix2["Always"] = "always";
94
+ return DirectusRouteLocalePrefix2;
95
+ })(DirectusRouteLocalePrefix || {});
91
96
  const query = `
92
97
  query Languages_code($filter: page_settings_translations_filter) {
93
98
  page_settings_translations(filter: $filter) {
@@ -190,14 +195,21 @@ async function directusRouteRouter(request, config, NextResponse$1 = NextRespons
190
195
  log(`PageSettings with id ${id} was found but is not associated with any locale.`, { id }, "warn");
191
196
  return NextResponse$1.next();
192
197
  }
193
- const mappedLocale = config.localeMap?.[directusLocale] || directusLocale;
194
- const idField = config.collectionSettings[collection]?.idField || config.collectionSettings.default.idField;
198
+ const { localeMap, collectionSettings, localePrefix = DirectusRouteLocalePrefix.Always, defaultLocale } = config;
199
+ const mappedLocale = localeMap?.[directusLocale] || directusLocale;
200
+ const isDirectusRouteLocalePrefixedMap = {
201
+ [DirectusRouteLocalePrefix.Always]: true,
202
+ [DirectusRouteLocalePrefix.AsNeeded]: directusLocale !== defaultLocale
203
+ };
204
+ const isDirectusRouteLocalePrefixed = isDirectusRouteLocalePrefixedMap[localePrefix];
205
+ const displayedLocale = isDirectusRouteLocalePrefixed ? `/${mappedLocale}` : "";
206
+ const idField = collectionSettings[collection]?.idField || collectionSettings.default.idField;
195
207
  log("Directus locale:", directusLocale);
196
208
  log("Mapped locale:", mappedLocale);
197
209
  log("Collection:", collection);
198
210
  log("ID Field:", idField);
199
211
  log("ID:", id);
200
- const newPath = `/${mappedLocale}/${collection}/${id}`;
212
+ const newPath = `${displayedLocale}/${collection}/${id}`;
201
213
  log(`Rewriting path: ${pathname} -> ${newPath}`);
202
214
  const url = request.nextUrl.clone();
203
215
  url.pathname = newPath;
@@ -205,6 +217,7 @@ async function directusRouteRouter(request, config, NextResponse$1 = NextRespons
205
217
  return NextResponse$1.rewrite(url);
206
218
  }
207
219
  export {
220
+ DirectusRouteLocalePrefix as D,
208
221
  getApiRouteUrlDefault as a,
209
222
  getRedirectsRoute as b,
210
223
  log as c,
@@ -89,6 +89,11 @@ async function handleRedirect(request, options = {}) {
89
89
  log(`${radashi.capitalize(type)}ing to ${url.toString()} with status ${status}`);
90
90
  return server.NextResponse[type](url, { status });
91
91
  }
92
+ var DirectusRouteLocalePrefix = /* @__PURE__ */ ((DirectusRouteLocalePrefix2) => {
93
+ DirectusRouteLocalePrefix2["AsNeeded"] = "as-needed";
94
+ DirectusRouteLocalePrefix2["Always"] = "always";
95
+ return DirectusRouteLocalePrefix2;
96
+ })(DirectusRouteLocalePrefix || {});
92
97
  const query = `
93
98
  query Languages_code($filter: page_settings_translations_filter) {
94
99
  page_settings_translations(filter: $filter) {
@@ -191,20 +196,28 @@ async function directusRouteRouter(request, config, NextResponse = server.NextRe
191
196
  log(`PageSettings with id ${id} was found but is not associated with any locale.`, { id }, "warn");
192
197
  return NextResponse.next();
193
198
  }
194
- const mappedLocale = config.localeMap?.[directusLocale] || directusLocale;
195
- const idField = config.collectionSettings[collection]?.idField || config.collectionSettings.default.idField;
199
+ const { localeMap, collectionSettings, localePrefix = DirectusRouteLocalePrefix.Always, defaultLocale } = config;
200
+ const mappedLocale = localeMap?.[directusLocale] || directusLocale;
201
+ const isDirectusRouteLocalePrefixedMap = {
202
+ [DirectusRouteLocalePrefix.Always]: true,
203
+ [DirectusRouteLocalePrefix.AsNeeded]: directusLocale !== defaultLocale
204
+ };
205
+ const isDirectusRouteLocalePrefixed = isDirectusRouteLocalePrefixedMap[localePrefix];
206
+ const displayedLocale = isDirectusRouteLocalePrefixed ? `/${mappedLocale}` : "";
207
+ const idField = collectionSettings[collection]?.idField || collectionSettings.default.idField;
196
208
  log("Directus locale:", directusLocale);
197
209
  log("Mapped locale:", mappedLocale);
198
210
  log("Collection:", collection);
199
211
  log("ID Field:", idField);
200
212
  log("ID:", id);
201
- const newPath = `/${mappedLocale}/${collection}/${id}`;
213
+ const newPath = `${displayedLocale}/${collection}/${id}`;
202
214
  log(`Rewriting path: ${pathname} -> ${newPath}`);
203
215
  const url = request.nextUrl.clone();
204
216
  url.pathname = newPath;
205
217
  log("Rewriting to URL:", url.toString());
206
218
  return NextResponse.rewrite(url);
207
219
  }
220
+ exports.DirectusRouteLocalePrefix = DirectusRouteLocalePrefix;
208
221
  exports.directusRouteRouter = directusRouteRouter;
209
222
  exports.getApiRouteUrlDefault = getApiRouteUrlDefault;
210
223
  exports.getRedirectSecretDefault = getRedirectSecretDefault;
package/server.js CHANGED
@@ -1,7 +1,7 @@
1
- "use server";
1
+ require("server-only");
2
2
  "use strict";
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
- const router = require("./router-CwzG5Cu9.js");
4
+ const router = require("./router-DorBYKUX.js");
5
5
  const directusQuery = require("@okam/directus-query");
6
6
  const radashi = require("radashi");
7
7
  const server = require("@okam/next-component/server");
@@ -16,11 +16,11 @@ function pageSettingsVariablesContext(variables) {
16
16
  }
17
17
  const [getPageSettingsContext, setPageSettingsContext] = pageSettingsContext();
18
18
  const [getVariables, setVariables] = pageSettingsVariablesContext();
19
- function isTDirectusRouteConfig(config) {
20
- return config != null && "localeMap" in config;
19
+ function isDirectusRouteConfig(config) {
20
+ return config != null && "collectionSettings" in config;
21
21
  }
22
22
  function getDirectusVariables(variables, config) {
23
- const localeMap = isTDirectusRouteConfig(config) ? config.localeMap : config;
23
+ const localeMap = isDirectusRouteConfig(config) ? config.localeMap : config;
24
24
  if (localeMap == null) {
25
25
  return variables;
26
26
  }
@@ -29,7 +29,7 @@ function getDirectusVariables(variables, config) {
29
29
  return { ...variables, locale: directusLocale };
30
30
  }
31
31
  async function getPageSettings(props, itemKey) {
32
- const { variables, config } = props ?? {};
32
+ const { variables, config, client = directusQuery.defaultGraphqlRequestClient, queryGqlFn = directusQuery.queryGql } = props ?? {};
33
33
  const directusVariables = getDirectusVariables(variables, config);
34
34
  const defaultReturn = getPageSettingsContext();
35
35
  if (props == null || radashi.isEqual(getVariables(), directusVariables)) {
@@ -39,7 +39,7 @@ async function getPageSettings(props, itemKey) {
39
39
  const { document } = props;
40
40
  const key = itemKey ?? radashi.get(document, "definitions[0].selectionSet.selections[0].name.value");
41
41
  router.log("Querying new page settings", directusVariables);
42
- const result = await directusQuery.queryGql(document, directusVariables);
42
+ const result = await queryGqlFn(document, directusVariables, client);
43
43
  const items = result?.[key];
44
44
  const currentItem = Array.isArray(items) ? items?.[0] : items;
45
45
  const currentPageSettings = currentItem?.page_settings;
package/server.mjs CHANGED
@@ -1,7 +1,7 @@
1
- "use server";
2
- import { c as log } from "./router-16XNi-G3.mjs";
3
- import { d } from "./router-16XNi-G3.mjs";
4
- import { queryGql } from "@okam/directus-query";
1
+ import "server-only";
2
+ import { c as log } from "./router-DC6WVUlz.mjs";
3
+ import { d } from "./router-DC6WVUlz.mjs";
4
+ import { queryGql, defaultGraphqlRequestClient } from "@okam/directus-query";
5
5
  import { isEqual, get, invert } from "radashi";
6
6
  import { createServerContext } from "@okam/next-component/server";
7
7
  import "server-only";
@@ -15,11 +15,11 @@ function pageSettingsVariablesContext(variables) {
15
15
  }
16
16
  const [getPageSettingsContext, setPageSettingsContext] = pageSettingsContext();
17
17
  const [getVariables, setVariables] = pageSettingsVariablesContext();
18
- function isTDirectusRouteConfig(config) {
19
- return config != null && "localeMap" in config;
18
+ function isDirectusRouteConfig(config) {
19
+ return config != null && "collectionSettings" in config;
20
20
  }
21
21
  function getDirectusVariables(variables, config) {
22
- const localeMap = isTDirectusRouteConfig(config) ? config.localeMap : config;
22
+ const localeMap = isDirectusRouteConfig(config) ? config.localeMap : config;
23
23
  if (localeMap == null) {
24
24
  return variables;
25
25
  }
@@ -28,7 +28,7 @@ function getDirectusVariables(variables, config) {
28
28
  return { ...variables, locale: directusLocale };
29
29
  }
30
30
  async function getPageSettings(props, itemKey) {
31
- const { variables, config } = props ?? {};
31
+ const { variables, config, client = defaultGraphqlRequestClient, queryGqlFn = queryGql } = props ?? {};
32
32
  const directusVariables = getDirectusVariables(variables, config);
33
33
  const defaultReturn = getPageSettingsContext();
34
34
  if (props == null || isEqual(getVariables(), directusVariables)) {
@@ -38,7 +38,7 @@ async function getPageSettings(props, itemKey) {
38
38
  const { document } = props;
39
39
  const key = itemKey ?? get(document, "definitions[0].selectionSet.selections[0].name.value");
40
40
  log("Querying new page settings", directusVariables);
41
- const result = await queryGql(document, directusVariables);
41
+ const result = await queryGqlFn(document, directusVariables, client);
42
42
  const items = result?.[key];
43
43
  const currentItem = Array.isArray(items) ? items?.[0] : items;
44
44
  const currentPageSettings = currentItem?.page_settings;
@@ -12,8 +12,73 @@ export interface TDirectusRouteRedirectsModule {
12
12
  */
13
13
  apiRoute?: string;
14
14
  }
15
- export interface TDirectusRouteConfig {
16
- localeMap?: Record<string, string>;
15
+ export declare enum DirectusRouteLocalePrefix {
16
+ /**
17
+ * The pathname will be prefixed with the locale only when it is not the default locale
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const directusConfig = {
22
+ * localePrefix: 'as-needed',
23
+ * defaultLocale: 'en-CA',
24
+ * localeMap: {
25
+ * 'fr-CA': 'fr',
26
+ * 'en-CA': 'en',
27
+ * }
28
+ * }
29
+ *
30
+ * // navigate to /en/products/1
31
+ * // output: /products/1 with english language
32
+ *
33
+ * // navigate to /products/1
34
+ * // output: /products/1 with english language
35
+ *
36
+ * // navigate to /fr/produits/1
37
+ * // output: /fr/produits/1 with french language
38
+ * ```
39
+ */
40
+ AsNeeded = "as-needed",
41
+ /**
42
+ * The pathname will always be prefixed by the locale
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * const directusConfig = {
47
+ * localePrefix: 'always',
48
+ * defaultLocale: 'en-CA',
49
+ * localeMap: {
50
+ * 'fr-CA': 'fr',
51
+ * 'en-CA': 'en',
52
+ * }
53
+ * }
54
+ *
55
+ * // navigate to /en/products/1
56
+ * // output: /en/products/1 with english language
57
+ *
58
+ * // navigate to /products/1
59
+ * // output: /en/products/1 with english language
60
+ *
61
+ * // navigate to /fr/produits/1
62
+ * // output: /fr/produits/1 with french language
63
+ * ```
64
+ */
65
+ Always = "always"
66
+ }
67
+ export type TDirectusRouteI18n<Locales extends string> = {
68
+ defaultLocale: Locales;
69
+ /**
70
+ * {@link DirectusRouteLocalePrefix}
71
+ */
72
+ localePrefix: `${DirectusRouteLocalePrefix.AsNeeded}`;
73
+ } | {
74
+ defaultLocale?: Locales;
75
+ /**
76
+ * {@link DirectusRouteLocalePrefix}
77
+ */
78
+ localePrefix?: `${DirectusRouteLocalePrefix.Always}` | undefined;
79
+ };
80
+ export type TDirectusRouteConfig<Locales extends string = string> = {
81
+ localeMap?: Record<Locales, string>;
17
82
  collectionSettings: {
18
83
  [collection: string]: {
19
84
  idField: string;
@@ -26,4 +91,4 @@ export interface TDirectusRouteConfig {
26
91
  modules?: {
27
92
  redirects?: TDirectusRouteRedirectsModule;
28
93
  };
29
- }
94
+ } & TDirectusRouteI18n<Locales>;
package/types/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
+ export { DirectusRouteLocalePrefix } from './directusRouteConfig';
1
2
  export type { TDirectusRouteConfig, TDirectusRouteRedirectsModule } from './directusRouteConfig';
2
3
  export type { TPageSettings, TPageSettingsItemQuery, TPageSettingsQueryItem, TPageSettingsTranslation, } from './pageSettings';