@okam/directus-next 1.2.1 → 1.2.3

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/{directus-next/src/lib/directusRouteRouter.mjs → directusRouteRouter-Bt3bEq4S.mjs} +93 -3
  3. package/directusRouteRouter-CfK0xrh0.js +191 -0
  4. package/index.js +291 -0
  5. package/index.mjs +292 -0
  6. package/package.json +4 -4
  7. package/{directus-next/src/pageSettings/usePageSettings.js → server.js} +22 -9
  8. package/{directus-next/src/pageSettings/usePageSettings.mjs → server.mjs} +16 -2
  9. package/directus-next/src/draft/env.js +0 -6
  10. package/directus-next/src/draft/env.mjs +0 -6
  11. package/directus-next/src/draft/route.js +0 -141
  12. package/directus-next/src/draft/route.mjs +0 -141
  13. package/directus-next/src/index.js +0 -24
  14. package/directus-next/src/index.mjs +0 -24
  15. package/directus-next/src/lib/directusRouteRouter.js +0 -102
  16. package/directus-next/src/logger.js +0 -11
  17. package/directus-next/src/logger.mjs +0 -11
  18. package/directus-next/src/pageSettings/context.js +0 -14
  19. package/directus-next/src/pageSettings/context.mjs +0 -14
  20. package/directus-next/src/redirect/env.js +0 -20
  21. package/directus-next/src/redirect/env.mjs +0 -20
  22. package/directus-next/src/redirect/route.js +0 -31
  23. package/directus-next/src/redirect/route.mjs +0 -31
  24. package/directus-next/src/redirect/utils/getRedirectsRoute.js +0 -27
  25. package/directus-next/src/redirect/utils/getRedirectsRoute.mjs +0 -27
  26. package/directus-next/src/redirect/utils/handleRedirect.js +0 -48
  27. package/directus-next/src/redirect/utils/handleRedirect.mjs +0 -48
  28. package/directus-next/src/response.js +0 -14
  29. package/directus-next/src/response.mjs +0 -14
  30. package/directus-next/src/server.js +0 -9
  31. package/directus-next/src/server.mjs +0 -9
  32. package/directus-node/src/lib/redirection/fetchRedirectsData.js +0 -92
  33. package/directus-node/src/lib/redirection/fetchRedirectsData.mjs +0 -92
  34. package/directus-node/src/lib/redirection/utils/validateRedirects.js +0 -22
  35. package/directus-node/src/lib/redirection/utils/validateRedirects.mjs +0 -22
package/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## 1.2.3 (2025-07-24)
2
+
3
+ ### 🧱 Updated Dependencies
4
+
5
+ - Updated core-lib to 1.17.0
6
+ - Updated directus-node to 0.6.2
7
+ - Updated directus-query to 1.4.2
8
+
9
+ ## 1.2.2 (2025-07-23)
10
+
11
+ ### 🩹 Fixes
12
+
13
+ - issue with vite config for directus next ([#318](https://github.com/OKAMca/stack/pull/318))
14
+
15
+ ### 🧱 Updated Dependencies
16
+
17
+ - Updated directus-node to 0.6.1
18
+
19
+ ### ❤️ Thank You
20
+
21
+ - Marie-Maxime Tanguay @marie-maxime
22
+
1
23
  ## 1.2.1 (2025-07-22)
2
24
 
3
25
  ### 🩹 Fixes
@@ -1,6 +1,90 @@
1
1
  import { NextResponse } from "next/server";
2
- import { log } from "../logger.mjs";
3
- import { handleRedirect } from "../redirect/utils/handleRedirect.mjs";
2
+ import { createLogger } from "@okam/logger";
3
+ import { normalizePath } from "@okam/core-lib";
4
+ import { capitalize } from "radashi";
5
+ const logger = createLogger("[DirectusNext]");
6
+ function log(msg, context, severity = "log") {
7
+ if (process.env.NODE_ENV === "development") {
8
+ logger.log(msg, severity, { context });
9
+ }
10
+ }
11
+ const defaultInternalUrl = "http://localhost:3000";
12
+ function getRedirectSecretDefault() {
13
+ return process.env.NEXT_API_REDIRECT_SECRET || "";
14
+ }
15
+ function getVercelUrl() {
16
+ const url = process.env.VERCEL_URL;
17
+ if (!url) return null;
18
+ return `https://${url}`;
19
+ }
20
+ function getApiRouteUrlDefault() {
21
+ const url = process.env.NEXT_MIDDLEWARE_REDIRECT_URL ?? getVercelUrl() ?? defaultInternalUrl;
22
+ if (URL.canParse(url)) return url;
23
+ log(`Invalid URL ${url}. Falling back to default`, { url }, "warn");
24
+ return defaultInternalUrl;
25
+ }
26
+ const defaultApiRoute = "/api/redirect";
27
+ async function getRedirectsRoute({
28
+ apiRoute = defaultApiRoute,
29
+ getApiRouteUrl = getApiRouteUrlDefault,
30
+ getRedirectSecret = getRedirectSecretDefault
31
+ } = {}) {
32
+ const secret = getRedirectSecret();
33
+ try {
34
+ const url = new URL(apiRoute, getApiRouteUrl());
35
+ url.searchParams.set("secret", encodeURIComponent(secret));
36
+ const response = await fetch(url);
37
+ if (!response.ok) {
38
+ log(`${apiRoute} not ok. Returned`, { status: response.status }, "error");
39
+ return { redirects: [], rewrites: [] };
40
+ }
41
+ const data = await response.json();
42
+ return data;
43
+ } catch (error) {
44
+ log(`Error fetching redirects from ${apiRoute}.`, { error }, "error");
45
+ return { redirects: [], rewrites: [] };
46
+ }
47
+ }
48
+ function splitDestination(destination) {
49
+ const [pathname, search] = destination.split("?");
50
+ if (!search) {
51
+ return [pathname];
52
+ }
53
+ return [pathname, `?${search}`];
54
+ }
55
+ function validateExternalRedirect(redirect) {
56
+ if (!URL.canParse(redirect.destination)) {
57
+ return null;
58
+ }
59
+ return redirect.destination;
60
+ }
61
+ async function handleRedirect(request, options = {}) {
62
+ const url = request.nextUrl.clone();
63
+ const { pathname } = request.nextUrl;
64
+ const normalizedPathname = normalizePath(pathname);
65
+ const { redirects, rewrites } = await getRedirectsRoute(options);
66
+ const redirect = redirects.find(({ source }) => source === normalizedPathname);
67
+ const rewrite = rewrites.find(({ source }) => source === normalizedPathname);
68
+ const type = redirect ? "redirect" : "rewrite";
69
+ const reroute = redirect ?? rewrite;
70
+ if (!reroute) {
71
+ return null;
72
+ }
73
+ const { permanent } = reroute;
74
+ const status = permanent ? 308 : 307;
75
+ const externalRedirect = validateExternalRedirect(reroute);
76
+ if (externalRedirect) {
77
+ log(`External ${type} found`, { [type]: externalRedirect, permanent });
78
+ return NextResponse.redirect(externalRedirect, { status });
79
+ }
80
+ log(`${capitalize(type)} found`, { [type]: reroute, permanent });
81
+ const { destination } = reroute;
82
+ const [destinationPathname, search] = splitDestination(destination);
83
+ if (search) url.search = search;
84
+ url.pathname = destinationPathname;
85
+ log(`${capitalize(type)}ing to ${url.toString()} with status ${status}`);
86
+ return NextResponse[type](url, { status });
87
+ }
4
88
  async function fetchPageSettingsTranslation(path) {
5
89
  const graphqlEndpoint = process.env.NEXT_SERVER_GRAPHQL_URL || process.env.NEXT_PUBLIC_GRAPHQL_URL;
6
90
  const graphqlApiKey = process.env.NEXT_PUBLIC_API_TOKEN;
@@ -98,5 +182,11 @@ async function directusRouteRouter(request, config, NextResponse$1 = NextRespons
98
182
  return NextResponse$1.rewrite(url);
99
183
  }
100
184
  export {
101
- directusRouteRouter
185
+ getRedirectsRoute as a,
186
+ getApiRouteUrlDefault as b,
187
+ log as c,
188
+ directusRouteRouter as d,
189
+ getRedirectSecretDefault as g,
190
+ handleRedirect as h,
191
+ logger as l
102
192
  };
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ const server = require("next/server");
3
+ const logger$1 = require("@okam/logger");
4
+ const coreLib = require("@okam/core-lib");
5
+ const radashi = require("radashi");
6
+ const logger = logger$1.createLogger("[DirectusNext]");
7
+ function log(msg, context, severity = "log") {
8
+ if (process.env.NODE_ENV === "development") {
9
+ logger.log(msg, severity, { context });
10
+ }
11
+ }
12
+ const defaultInternalUrl = "http://localhost:3000";
13
+ function getRedirectSecretDefault() {
14
+ return process.env.NEXT_API_REDIRECT_SECRET || "";
15
+ }
16
+ function getVercelUrl() {
17
+ const url = process.env.VERCEL_URL;
18
+ if (!url) return null;
19
+ return `https://${url}`;
20
+ }
21
+ function getApiRouteUrlDefault() {
22
+ const url = process.env.NEXT_MIDDLEWARE_REDIRECT_URL ?? getVercelUrl() ?? defaultInternalUrl;
23
+ if (URL.canParse(url)) return url;
24
+ log(`Invalid URL ${url}. Falling back to default`, { url }, "warn");
25
+ return defaultInternalUrl;
26
+ }
27
+ const defaultApiRoute = "/api/redirect";
28
+ async function getRedirectsRoute({
29
+ apiRoute = defaultApiRoute,
30
+ getApiRouteUrl = getApiRouteUrlDefault,
31
+ getRedirectSecret = getRedirectSecretDefault
32
+ } = {}) {
33
+ const secret = getRedirectSecret();
34
+ try {
35
+ const url = new URL(apiRoute, getApiRouteUrl());
36
+ url.searchParams.set("secret", encodeURIComponent(secret));
37
+ const response = await fetch(url);
38
+ if (!response.ok) {
39
+ log(`${apiRoute} not ok. Returned`, { status: response.status }, "error");
40
+ return { redirects: [], rewrites: [] };
41
+ }
42
+ const data = await response.json();
43
+ return data;
44
+ } catch (error) {
45
+ log(`Error fetching redirects from ${apiRoute}.`, { error }, "error");
46
+ return { redirects: [], rewrites: [] };
47
+ }
48
+ }
49
+ function splitDestination(destination) {
50
+ const [pathname, search] = destination.split("?");
51
+ if (!search) {
52
+ return [pathname];
53
+ }
54
+ return [pathname, `?${search}`];
55
+ }
56
+ function validateExternalRedirect(redirect) {
57
+ if (!URL.canParse(redirect.destination)) {
58
+ return null;
59
+ }
60
+ return redirect.destination;
61
+ }
62
+ async function handleRedirect(request, options = {}) {
63
+ const url = request.nextUrl.clone();
64
+ const { pathname } = request.nextUrl;
65
+ const normalizedPathname = coreLib.normalizePath(pathname);
66
+ const { redirects, rewrites } = await getRedirectsRoute(options);
67
+ const redirect = redirects.find(({ source }) => source === normalizedPathname);
68
+ const rewrite = rewrites.find(({ source }) => source === normalizedPathname);
69
+ const type = redirect ? "redirect" : "rewrite";
70
+ const reroute = redirect ?? rewrite;
71
+ if (!reroute) {
72
+ return null;
73
+ }
74
+ const { permanent } = reroute;
75
+ const status = permanent ? 308 : 307;
76
+ const externalRedirect = validateExternalRedirect(reroute);
77
+ if (externalRedirect) {
78
+ log(`External ${type} found`, { [type]: externalRedirect, permanent });
79
+ return server.NextResponse.redirect(externalRedirect, { status });
80
+ }
81
+ log(`${radashi.capitalize(type)} found`, { [type]: reroute, permanent });
82
+ const { destination } = reroute;
83
+ const [destinationPathname, search] = splitDestination(destination);
84
+ if (search) url.search = search;
85
+ url.pathname = destinationPathname;
86
+ log(`${radashi.capitalize(type)}ing to ${url.toString()} with status ${status}`);
87
+ return server.NextResponse[type](url, { status });
88
+ }
89
+ async function fetchPageSettingsTranslation(path) {
90
+ const graphqlEndpoint = process.env.NEXT_SERVER_GRAPHQL_URL || process.env.NEXT_PUBLIC_GRAPHQL_URL;
91
+ const graphqlApiKey = process.env.NEXT_PUBLIC_API_TOKEN;
92
+ if (!graphqlEndpoint) {
93
+ throw new Error("Missing GraphQL configuration `graphqlEndpoint`");
94
+ }
95
+ if (!graphqlApiKey) {
96
+ throw new Error("Missing GraphQL configuration `graphqlApiKey`");
97
+ }
98
+ const query = `
99
+ query Languages_code($filter: page_settings_translations_filter) {
100
+ page_settings_translations(filter: $filter) {
101
+ languages_code {
102
+ code
103
+ }
104
+ id
105
+ page_settings_id {
106
+ belongs_to_collection
107
+ belongs_to_key
108
+ }
109
+ title
110
+ slug
111
+ path
112
+ }
113
+ }
114
+ `;
115
+ const variables = {
116
+ filter: {
117
+ path: { _eq: path },
118
+ _and: [{ page_settings_id: { belongs_to_key: { _nempty: true } } }]
119
+ }
120
+ };
121
+ try {
122
+ log("Executing GraphQL query:", query);
123
+ log("Query variables:", variables);
124
+ const response = await fetch(graphqlEndpoint, {
125
+ method: "POST",
126
+ headers: {
127
+ "Content-Type": "application/json",
128
+ Authorization: `Bearer ${graphqlApiKey}`
129
+ },
130
+ body: JSON.stringify({ query, variables })
131
+ });
132
+ const { data } = await response.json();
133
+ log("GraphQL response:", data);
134
+ return data.page_settings_translations;
135
+ } catch (error) {
136
+ log("GraphQL Error:", error);
137
+ return null;
138
+ }
139
+ }
140
+ function removeLocaleFromPathname(pathname, config) {
141
+ const currentLocale = Object.values(config.localeMap ?? {}).find((locale) => pathname.startsWith(`/${locale}/`));
142
+ return { locale: currentLocale, pathname: currentLocale ? pathname.replace(`/${currentLocale}/`, "/") : pathname };
143
+ }
144
+ async function directusRouteRouter(request, config, NextResponse = server.NextResponse) {
145
+ var _a, _b, _c;
146
+ const { pathname: localizedPathname } = request.nextUrl;
147
+ const { locale, pathname } = removeLocaleFromPathname(localizedPathname, config);
148
+ log("Processing request for pathname:", { locale, pathname });
149
+ const redirect = await handleRedirect(request, (_a = config.modules) == null ? void 0 : _a.redirects);
150
+ if (redirect) {
151
+ return redirect;
152
+ }
153
+ const translations = await fetchPageSettingsTranslation(pathname);
154
+ if (!translations || translations.length === 0) {
155
+ log("No translation found for path:", pathname);
156
+ return NextResponse.next();
157
+ }
158
+ const translation = translations[0];
159
+ log("Using translation:", translation);
160
+ if (!translation.languages_code || !translation.page_settings_id) {
161
+ log(`Invalid translation data for path: ${pathname}`, { pathname }, "warn");
162
+ return NextResponse.next();
163
+ }
164
+ const directusLocale = translation.languages_code.code;
165
+ const collection = translation.page_settings_id.belongs_to_collection;
166
+ const id = translation.page_settings_id.belongs_to_key;
167
+ if (!collection) {
168
+ log(`PageSettings with id ${id} was found but is not associated with any collection.`, { id }, "warn");
169
+ return NextResponse.next();
170
+ }
171
+ const mappedLocale = ((_b = config.localeMap) == null ? void 0 : _b[directusLocale]) || directusLocale;
172
+ const idField = ((_c = config.collectionSettings[collection]) == null ? void 0 : _c.idField) || config.collectionSettings.default.idField;
173
+ log("Directus locale:", directusLocale);
174
+ log("Mapped locale:", mappedLocale);
175
+ log("Collection:", collection);
176
+ log("ID Field:", idField);
177
+ log("ID:", id);
178
+ const newPath = `/${mappedLocale}/${collection}/${id}`;
179
+ log(`Rewriting path: ${pathname} -> ${newPath}`);
180
+ const url = request.nextUrl.clone();
181
+ url.pathname = newPath;
182
+ log("Rewriting to URL:", url.toString());
183
+ return NextResponse.rewrite(url);
184
+ }
185
+ exports.directusRouteRouter = directusRouteRouter;
186
+ exports.getApiRouteUrlDefault = getApiRouteUrlDefault;
187
+ exports.getRedirectSecretDefault = getRedirectSecretDefault;
188
+ exports.getRedirectsRoute = getRedirectsRoute;
189
+ exports.handleRedirect = handleRedirect;
190
+ exports.log = log;
191
+ exports.logger = logger;
package/index.js ADDED
@@ -0,0 +1,291 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const headers = require("next/headers");
4
+ const navigation = require("next/navigation");
5
+ const radashi = require("radashi");
6
+ const directusRouteRouter = require("./directusRouteRouter-CfK0xrh0.js");
7
+ const logger = require("@okam/logger");
8
+ const coreLib = require("@okam/core-lib");
9
+ function getJsonErrorResponse(data, status) {
10
+ const headers2 = {
11
+ // eslint-disable-next-line @typescript-eslint/naming-convention
12
+ "Content-Type": "text/json; charset=UTF-8"
13
+ };
14
+ const body = JSON.stringify(data);
15
+ return new Response(body, {
16
+ status,
17
+ headers: headers2
18
+ });
19
+ }
20
+ function getDraftSecretDefault() {
21
+ return process.env.NEXT_API_DRAFT_SECRET || "";
22
+ }
23
+ function parseDraftParams(url) {
24
+ const { searchParams } = new URL(url);
25
+ const secret = searchParams.get("secret") || "";
26
+ const languagesParam = searchParams.get("languages");
27
+ const pathsParam = searchParams.get("urls");
28
+ const routesParam = searchParams.get("routes");
29
+ const pkParam = searchParams.get("pk");
30
+ const versionParam = searchParams.get("version");
31
+ const emptyReturn = {
32
+ secret: "",
33
+ languages: [],
34
+ paths: [],
35
+ routes: [],
36
+ type: "",
37
+ pk: "",
38
+ version: ""
39
+ };
40
+ if (!secret || !languagesParam || !(pathsParam || routesParam)) {
41
+ return emptyReturn;
42
+ }
43
+ const pk = typeof pkParam === "string" ? pkParam : "";
44
+ const version = typeof versionParam === "string" ? versionParam : "";
45
+ try {
46
+ const languages = JSON.parse(languagesParam);
47
+ if (routesParam) {
48
+ const routes = JSON.parse(routesParam);
49
+ return {
50
+ secret,
51
+ languages,
52
+ paths: [],
53
+ routes,
54
+ type: "route",
55
+ pk,
56
+ version
57
+ };
58
+ }
59
+ if (!pathsParam) {
60
+ return emptyReturn;
61
+ }
62
+ const paths = JSON.parse(pathsParam);
63
+ return {
64
+ secret,
65
+ languages,
66
+ paths,
67
+ routes: [],
68
+ type: "path",
69
+ pk,
70
+ version
71
+ };
72
+ } catch (e) {
73
+ return emptyReturn;
74
+ }
75
+ }
76
+ function getPathFromRoute(routeUrl, url, index = 0) {
77
+ const { searchParams } = new URL(url);
78
+ const matches = [...routeUrl.matchAll(/\{\{([a-z]+)\}\}/gi)];
79
+ const map = {};
80
+ matches.forEach((match) => {
81
+ const key = match[1] || "";
82
+ if (!key) {
83
+ return;
84
+ }
85
+ const listkey = `${key}s`;
86
+ const listParam = searchParams.get(listkey);
87
+ if (listParam) {
88
+ try {
89
+ const list = JSON.parse(listParam);
90
+ map[key] = list[index] || "";
91
+ } catch (e) {
92
+ map[key] = "";
93
+ }
94
+ } else {
95
+ const param = searchParams.get(key);
96
+ map[key] = param || "";
97
+ }
98
+ });
99
+ return radashi.template(routeUrl, map);
100
+ }
101
+ function handleDraftRoute({
102
+ url,
103
+ getDirectusLanguage,
104
+ getDraftSecret,
105
+ getJsonError
106
+ }) {
107
+ const getSecretFunction = getDraftSecret || getDraftSecretDefault;
108
+ const getJsonErrorResponseFunction = getJsonError || getJsonErrorResponse;
109
+ const { secret, languages, paths, routes, type, version } = parseDraftParams(url);
110
+ if (secret !== getSecretFunction()) {
111
+ return getJsonErrorResponseFunction({ error: "Invalid argument" }, 401);
112
+ }
113
+ if (type === "") {
114
+ return getJsonErrorResponseFunction({ error: "Invalid argument" }, 400);
115
+ }
116
+ if (!Array.isArray(languages) || languages.length <= 0) {
117
+ return getJsonErrorResponseFunction({ error: "Invalid languages argument" }, 400);
118
+ }
119
+ if (type === "path" && (!Array.isArray(paths) || paths.length <= 0)) {
120
+ return getJsonErrorResponseFunction({ error: "Invalid paths argument" }, 400);
121
+ }
122
+ if (type === "route" && (!Array.isArray(routes) || routes.length <= 0)) {
123
+ return getJsonErrorResponseFunction({ error: "Invalid routes argument" }, 400);
124
+ }
125
+ const directusLang = getDirectusLanguage();
126
+ const indexDefault = languages.indexOf(directusLang);
127
+ const index = indexDefault !== -1 ? indexDefault : 0;
128
+ let redirectUrl = "";
129
+ if (type === "path") {
130
+ const path = paths[index] || "";
131
+ if (!path) {
132
+ return getJsonErrorResponse({ error: "Invalid path" }, 400);
133
+ }
134
+ redirectUrl = path;
135
+ } else if (type === "route") {
136
+ const route = routes[index] || "";
137
+ if (!route) {
138
+ return getJsonErrorResponse({ error: "Invalid route" }, 400);
139
+ }
140
+ const pathFromRoute = getPathFromRoute(route, url, index);
141
+ if (!pathFromRoute) {
142
+ return getJsonErrorResponse({ error: "Invalid route" }, 400);
143
+ }
144
+ redirectUrl = pathFromRoute;
145
+ }
146
+ if (redirectUrl && version) {
147
+ const withParams = redirectUrl.indexOf("?") !== -1;
148
+ redirectUrl = `${redirectUrl}${withParams ? "&" : "?"}version=${encodeURIComponent(version)}`;
149
+ }
150
+ headers.draftMode().enable();
151
+ navigation.redirect(redirectUrl);
152
+ return void 0;
153
+ }
154
+ function isRedirect(redirect) {
155
+ return !!redirect && typeof redirect === "object" && "source" in redirect && "destination" in redirect;
156
+ }
157
+ function normalizeRedirects(redirects) {
158
+ if (!redirects || !Array.isArray(redirects)) return [];
159
+ return redirects.flatMap((redirect) => {
160
+ const { source, destination, ...rest } = redirect ?? {};
161
+ if (!redirect || !source || !destination || !isRedirect(redirect)) return [];
162
+ return [
163
+ {
164
+ ...rest,
165
+ source: coreLib.normalizePath(source),
166
+ destination: coreLib.normalizePath(destination)
167
+ }
168
+ ];
169
+ });
170
+ }
171
+ const redirectDefaultLimit = 2e3;
172
+ function getDefaultConfig() {
173
+ return {
174
+ graphqlEndpoint: process.env["NEXT_REDIRECT_GRAPHQL_URL"] || process.env["NEXT_PUBLIC_GRAPHQL_URL"] || "",
175
+ graphqlApiKey: process.env["NEXT_API_TOKEN_ADMIN"] || "",
176
+ redirectsFilename: "./redirect/redirects.json",
177
+ rewritesFilename: "./redirect/rewrites.json",
178
+ limit: redirectDefaultLimit
179
+ };
180
+ }
181
+ async function fetchRedirectsData(config, init) {
182
+ const {
183
+ graphqlApiKey: defaultGraphqlApiKey,
184
+ graphqlEndpoint: defaultGraphqlEndpoint,
185
+ limit: defaultLimit
186
+ } = getDefaultConfig();
187
+ const {
188
+ graphqlEndpoint = defaultGraphqlEndpoint,
189
+ graphqlApiKey = defaultGraphqlApiKey,
190
+ limit = defaultLimit
191
+ } = config;
192
+ if (!graphqlEndpoint) {
193
+ throw new Error(
194
+ "Missing fetchRedirects configuration `graphqlEndpoint`. Check environment variables NEXT_REDIRECT_GRAPHQL_URL or NEXT_PUBLIC_GRAPHQL_URL"
195
+ );
196
+ }
197
+ if (!graphqlApiKey) {
198
+ throw new Error(
199
+ "Missing fetchRedirects configuration `graphqlApiKey`. Check environment variable NEXT_API_TOKEN_ADMIN"
200
+ );
201
+ }
202
+ const query = `query fetchRedirects($limit: Int = 2000) {
203
+ redirects(filter: {status:{_eq:"published"},isrewrite:{_eq:false}}, sort: "sort", limit: $limit) {
204
+ source
205
+ destination
206
+ permanent
207
+ locale
208
+ }
209
+ rewrites: redirects(filter: {status:{_eq:"published"},isrewrite:{_eq:true}}, sort: "sort", limit: $limit) {
210
+ source
211
+ destination
212
+ permanent
213
+ locale
214
+ }
215
+ }`;
216
+ const graphqlBody = {
217
+ query,
218
+ // "operationName": "",
219
+ variables: {
220
+ limit: Number(limit) || redirectDefaultLimit
221
+ }
222
+ };
223
+ try {
224
+ const response = await fetch(graphqlEndpoint, {
225
+ ...init,
226
+ method: "POST",
227
+ headers: {
228
+ // eslint-disable-next-line @typescript-eslint/naming-convention
229
+ "Content-Type": "application/json",
230
+ Authorization: `Bearer ${graphqlApiKey}`
231
+ },
232
+ body: JSON.stringify(graphqlBody)
233
+ });
234
+ const { data } = await response.json();
235
+ const { redirects, rewrites } = data ?? {};
236
+ if (!(redirects == null ? void 0 : redirects.length) && !(rewrites == null ? void 0 : rewrites.length)) {
237
+ logger.logger.log("No redirects/rewrites found", "warn");
238
+ return {
239
+ redirects: [],
240
+ rewrites: []
241
+ };
242
+ }
243
+ logger.logger.log(`Fetch redirects count: ${(redirects == null ? void 0 : redirects.length) || 0}, rewrites count: ${(rewrites == null ? void 0 : rewrites.length) || 0}`);
244
+ return {
245
+ redirects: normalizeRedirects(redirects),
246
+ rewrites: normalizeRedirects(rewrites)
247
+ };
248
+ } catch (e) {
249
+ logger.logger.log(`Error fetching redirects: ${e.message}`, "error");
250
+ }
251
+ return {
252
+ redirects: [],
253
+ rewrites: []
254
+ };
255
+ }
256
+ function parseRedirectParams(url) {
257
+ const { searchParams } = new URL(url);
258
+ const secret = searchParams.get("secret") || "";
259
+ return { secret };
260
+ }
261
+ async function handleRedirectsRoute({
262
+ url,
263
+ getRedirectSecret = directusRouteRouter.getRedirectSecretDefault,
264
+ getJsonError = getJsonErrorResponse,
265
+ getDirectusApiToken,
266
+ getDirectusGraphqlUrl,
267
+ limit,
268
+ init
269
+ }) {
270
+ const { secret } = parseRedirectParams(url);
271
+ if (secret !== getRedirectSecret()) {
272
+ return getJsonError({ error: "Invalid argument" }, 401);
273
+ }
274
+ const graphqlEndpoint = getDirectusGraphqlUrl == null ? void 0 : getDirectusGraphqlUrl();
275
+ const graphqlApiKey = getDirectusApiToken == null ? void 0 : getDirectusApiToken();
276
+ const { redirects, rewrites } = await fetchRedirectsData({ graphqlEndpoint, graphqlApiKey, limit }, init);
277
+ return new Response(JSON.stringify({ redirects, rewrites }), { status: 200 });
278
+ }
279
+ exports.DirectusNextLogger = directusRouteRouter.logger;
280
+ exports.directusRouteRouter = directusRouteRouter.directusRouteRouter;
281
+ exports.getApiRouteUrlDefault = directusRouteRouter.getApiRouteUrlDefault;
282
+ exports.getRedirectSecretDefault = directusRouteRouter.getRedirectSecretDefault;
283
+ exports.getRedirectsRoute = directusRouteRouter.getRedirectsRoute;
284
+ exports.handleRedirect = directusRouteRouter.handleRedirect;
285
+ exports.getDraftSecretDefault = getDraftSecretDefault;
286
+ exports.getJsonErrorResponse = getJsonErrorResponse;
287
+ exports.getPathFromRoute = getPathFromRoute;
288
+ exports.handleDraftRoute = handleDraftRoute;
289
+ exports.handleRedirectsRoute = handleRedirectsRoute;
290
+ exports.parseDraftParams = parseDraftParams;
291
+ exports.parseRedirectParams = parseRedirectParams;