@okam/directus-node 0.4.0 → 0.6.0

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,32 @@
1
+ ## 0.6.0 (2025-07-22)
2
+
3
+ ### 🚀 Features
4
+
5
+ - **directus-next:** /api/redirect route handler to fetch + cache directus redirects ([c21b953](https://github.com/OKAMca/stack/commit/c21b953))
6
+
7
+ ### 🩹 Fixes
8
+
9
+ - **directus-node:** export edge-compatible code from separate file ([9f77744](https://github.com/OKAMca/stack/commit/9f77744))
10
+ - package deps error ([b665a45](https://github.com/OKAMca/stack/commit/b665a45))
11
+ - search field icon ([0850fde](https://github.com/OKAMca/stack/commit/0850fde))
12
+
13
+ ### ❤️ Thank You
14
+
15
+ - Marie-Maxime Tanguay
16
+ - Pierre-Olivier Clerson @poclerson
17
+ - poclerson
18
+
19
+ ## 0.5.0 (2025-01-30)
20
+
21
+ ### 🚀 Features
22
+
23
+ - **redirection:** use new variable for redirection ([0c21683](https://github.com/OKAMca/stack/commit/0c21683))
24
+ - **directus-node:** adding unit test, fix logger and adding read/write functions for redirections ([6d68bb4](https://github.com/OKAMca/stack/commit/6d68bb4))
25
+
26
+ ### ❤️ Thank You
27
+
28
+ - Yan Morin
29
+
1
30
  ## 0.3.0 (2024-09-11)
2
31
 
3
32
 
package/README.md CHANGED
@@ -57,13 +57,22 @@ module.exports = {
57
57
  redirects: async () => redirects,
58
58
  rewrites: async () => rewrites,
59
59
  }
60
+ ```
61
+
62
+ 4.1 or redirect/index.mjs
63
+ ```
64
+ import redirectsData from './redirects.json' with { type: 'json' }
65
+ import rewritesData from './rewrites.json' with { type: 'json' }
60
66
 
67
+ export const redirects = async () => redirectsData
68
+ export const rewrites = async () => rewritesData
61
69
  ```
62
70
 
63
71
  5. Define environments variables
64
72
  ```
65
- NEXT_PUBLIC_GRAPHQL_URL=
66
- NEXT_API_TOKEN_ADMIN=
73
+ NEXT_REDIRECT_GRAPHQL_URL=http://server.some.url/graphql
74
+ NEXT_PUBLIC_GRAPHQL_URL=https://server.external/graphql
75
+ NEXT_API_TOKEN_ADMIN=user_token_for_graphql
67
76
  ```
68
77
 
69
78
  6. Generate redirect/redirects.json and redirect/rewrites.json using fetch-redirect (or build project with nx)
@@ -75,13 +84,23 @@ npx env-cmd -f ../../.env.local node fetch-redirect.js
75
84
  ```
76
85
  const { rewrites, redirects } = require('./redirect/index')
77
86
  ```
87
+
88
+ for next.config.mjs
89
+ ```
90
+ import { redirects, rewrites } from './redirect/index.mjs'
91
+ ```
92
+
93
+ and
94
+
78
95
  ```
79
96
  const nextConfig = {
80
97
  ...
81
98
  async redirects() {
82
99
  const rest = await redirects()
83
100
  return [
101
+ // optional i18nrouter should be before
84
102
  ...i18nReRouter({locale: false, permanent: true}, 'redirect'),
103
+ // custom redirect should be here
85
104
  ...rest,
86
105
  ]
87
106
  return rest
@@ -90,9 +109,11 @@ const nextConfig = {
90
109
  const fallback = await rewrites()
91
110
  return {
92
111
  beforeFiles: [
112
+ // optional i18n router
93
113
  ...i18nReRouter({locale: false}, 'rewrite'),
94
114
  ],
95
115
  afterFiles: [
116
+ // optional i18n router
96
117
  ...i18nRewriter({...i18nConfigWithoutLocaleDetector, localeDetector: false}),
97
118
  ],
98
119
  fallback,
@@ -101,3 +122,6 @@ const nextConfig = {
101
122
  ...
102
123
  }
103
124
  ```
125
+
126
+ ## Warning
127
+ In production (build), you can't reload dynamically in next.config.(m?)js in rewrites()/redirects() because it was compiled in `.nx/route-manifest.json`. Updating the files in redirects/ won't work. In dev mode, both rewrites()/redirects() of next.config.(m?)js are runned on each server start.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@okam/directus-node",
3
3
  "main": "./src/index.js",
4
- "version": "0.4.0",
4
+ "version": "0.6.0",
5
5
  "types": "./src/index.d.ts",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -12,7 +12,8 @@
12
12
  "dependencies": {
13
13
  "@graphql-codegen/cli": "^5.0.3",
14
14
  "@okam/logger": "1.1.0",
15
- "tslib": "^2.8.1"
15
+ "tslib": "^2.8.1",
16
+ "@okam/core-lib": "1.16.0"
16
17
  },
17
18
  "type": "commonjs"
18
19
  }
package/src/edge.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @fileoverview Export file for functions that are used in edge functions (middleware-compatible)
3
+ */
4
+ export type { TFetchRedirectsConfig, TFetchRedirectsResponse, TRedirectData, TRedirectType, } from './lib/redirection/interface';
5
+ export { fetchRedirectsData, getDefaultConfig } from './lib/redirection/fetchRedirectsData';
6
+ export { isRedirect, normalizeRedirects } from './lib/redirection/utils/validateRedirects';
package/src/edge.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview Export file for functions that are used in edge functions (middleware-compatible)
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.normalizeRedirects = exports.isRedirect = exports.getDefaultConfig = exports.fetchRedirectsData = void 0;
7
+ var fetchRedirectsData_1 = require("./lib/redirection/fetchRedirectsData");
8
+ Object.defineProperty(exports, "fetchRedirectsData", { enumerable: true, get: function () { return fetchRedirectsData_1.fetchRedirectsData; } });
9
+ Object.defineProperty(exports, "getDefaultConfig", { enumerable: true, get: function () { return fetchRedirectsData_1.getDefaultConfig; } });
10
+ var validateRedirects_1 = require("./lib/redirection/utils/validateRedirects");
11
+ Object.defineProperty(exports, "isRedirect", { enumerable: true, get: function () { return validateRedirects_1.isRedirect; } });
12
+ Object.defineProperty(exports, "normalizeRedirects", { enumerable: true, get: function () { return validateRedirects_1.normalizeRedirects; } });
13
+ //# sourceMappingURL=edge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge.js","sourceRoot":"","sources":["../../../../../libs/directus/directus-node/src/edge.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AASH,2EAA2F;AAAlF,wHAAA,kBAAkB,OAAA;AAAE,sHAAA,gBAAgB,OAAA;AAC7C,+EAA0F;AAAjF,+GAAA,UAAU,OAAA;AAAE,uHAAA,kBAAkB,OAAA"}
@@ -0,0 +1,8 @@
1
+ import type { TFetchRedirectsConfig, TFetchRedirectsResponse } from './interface';
2
+ export declare const redirectDefaultLimit = 2000;
3
+ /**
4
+ * Get Fetch Redirects Configuration
5
+ * @returns {object}
6
+ */
7
+ export declare function getDefaultConfig(): TFetchRedirectsConfig;
8
+ export declare function fetchRedirectsData(config: TFetchRedirectsConfig, init?: Omit<RequestInit, 'body' | 'method' | 'headers'>): Promise<TFetchRedirectsResponse>;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.redirectDefaultLimit = void 0;
4
+ exports.getDefaultConfig = getDefaultConfig;
5
+ exports.fetchRedirectsData = fetchRedirectsData;
6
+ const tslib_1 = require("tslib");
7
+ const logger_1 = require("@okam/logger");
8
+ const validateRedirects_1 = require("./utils/validateRedirects");
9
+ exports.redirectDefaultLimit = 2000;
10
+ /**
11
+ * Get Fetch Redirects Configuration
12
+ * @returns {object}
13
+ */
14
+ function getDefaultConfig() {
15
+ return {
16
+ graphqlEndpoint: process.env['NEXT_REDIRECT_GRAPHQL_URL'] || process.env['NEXT_PUBLIC_GRAPHQL_URL'] || '',
17
+ graphqlApiKey: process.env['NEXT_API_TOKEN_ADMIN'] || '',
18
+ redirectsFilename: './redirect/redirects.json',
19
+ rewritesFilename: './redirect/rewrites.json',
20
+ limit: exports.redirectDefaultLimit,
21
+ };
22
+ }
23
+ function fetchRedirectsData(config, init) {
24
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
25
+ const { graphqlApiKey: defaultGraphqlApiKey, graphqlEndpoint: defaultGraphqlEndpoint, limit: defaultLimit, } = getDefaultConfig();
26
+ const { graphqlEndpoint = defaultGraphqlEndpoint, graphqlApiKey = defaultGraphqlApiKey, limit = defaultLimit, } = config;
27
+ if (!graphqlEndpoint) {
28
+ throw new Error('Missing fetchRedirects configuration `graphqlEndpoint`. Check environment variables NEXT_REDIRECT_GRAPHQL_URL or NEXT_PUBLIC_GRAPHQL_URL');
29
+ }
30
+ if (!graphqlApiKey) {
31
+ throw new Error('Missing fetchRedirects configuration `graphqlApiKey`. Check environment variable NEXT_API_TOKEN_ADMIN');
32
+ }
33
+ const query = `query fetchRedirects($limit: Int = 2000) {
34
+ redirects(filter: {status:{_eq:"published"},isrewrite:{_eq:false}}, sort: "sort", limit: $limit) {
35
+ source
36
+ destination
37
+ permanent
38
+ locale
39
+ }
40
+ rewrites: redirects(filter: {status:{_eq:"published"},isrewrite:{_eq:true}}, sort: "sort", limit: $limit) {
41
+ source
42
+ destination
43
+ permanent
44
+ locale
45
+ }
46
+ }`;
47
+ const graphqlBody = {
48
+ query,
49
+ // "operationName": "",
50
+ variables: {
51
+ limit: Number(limit) || exports.redirectDefaultLimit,
52
+ },
53
+ };
54
+ try {
55
+ // console.info(`Fetching redirects on ${graphqlEndpoint}`)
56
+ const response = yield fetch(graphqlEndpoint, Object.assign(Object.assign({}, init), { method: 'POST', headers: {
57
+ // eslint-disable-next-line @typescript-eslint/naming-convention
58
+ 'Content-Type': 'application/json',
59
+ Authorization: `Bearer ${graphqlApiKey}`,
60
+ }, body: JSON.stringify(graphqlBody) }));
61
+ const { data } = yield response.json();
62
+ const { redirects, rewrites } = data !== null && data !== void 0 ? data : {};
63
+ if (!(redirects === null || redirects === void 0 ? void 0 : redirects.length) && !(rewrites === null || rewrites === void 0 ? void 0 : rewrites.length)) {
64
+ logger_1.logger.log('No redirects/rewrites found', 'warn');
65
+ return {
66
+ redirects: [],
67
+ rewrites: [],
68
+ };
69
+ }
70
+ logger_1.logger.log(`Fetch redirects count: ${(redirects === null || redirects === void 0 ? void 0 : redirects.length) || 0}, rewrites count: ${(rewrites === null || rewrites === void 0 ? void 0 : rewrites.length) || 0}`);
71
+ return {
72
+ redirects: (0, validateRedirects_1.normalizeRedirects)(redirects),
73
+ rewrites: (0, validateRedirects_1.normalizeRedirects)(rewrites),
74
+ };
75
+ }
76
+ catch (e) {
77
+ logger_1.logger.log(`Error fetching redirects: ${e.message}`, 'error');
78
+ }
79
+ return {
80
+ redirects: [],
81
+ rewrites: [],
82
+ };
83
+ });
84
+ }
85
+ //# sourceMappingURL=fetchRedirectsData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchRedirectsData.js","sourceRoot":"","sources":["../../../../../../../libs/directus/directus-node/src/lib/redirection/fetchRedirectsData.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import * as fetchRedirectsDataFile from './fetchRedirectsData';
2
+ /**
3
+ * @deprecated Import from `@okam/directus-node/edge` instead
4
+ */
5
+ export declare const fetchRedirectsData: typeof fetchRedirectsDataFile.fetchRedirectsData;
6
+ /**
7
+ * @deprecated Import from `@okam/directus-node/edge` instead
8
+ */
9
+ export declare const getDefaultConfig: typeof fetchRedirectsDataFile.getDefaultConfig;
10
+ /**
11
+ * @deprecated Import from `@okam/directus-node/edge` instead
12
+ */
13
+ export declare const redirectDefaultLimit = 2000;
14
+ export type { TFetchRedirectsConfig, TFetchRedirectsResponse, TRedirectData, TRedirectType } from './interface';
15
+ export * from './utils/validateRedirects';
16
+ export * from './redirectsFile';
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /* eslint-disable prefer-destructuring */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.redirectDefaultLimit = exports.getDefaultConfig = exports.fetchRedirectsData = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const fetchRedirectsDataFile = tslib_1.__importStar(require("./fetchRedirectsData"));
7
+ // Re-export with deprecation warnings
8
+ /**
9
+ * @deprecated Import from `@okam/directus-node/edge` instead
10
+ */
11
+ exports.fetchRedirectsData = fetchRedirectsDataFile.fetchRedirectsData;
12
+ /**
13
+ * @deprecated Import from `@okam/directus-node/edge` instead
14
+ */
15
+ exports.getDefaultConfig = fetchRedirectsDataFile.getDefaultConfig;
16
+ /**
17
+ * @deprecated Import from `@okam/directus-node/edge` instead
18
+ */
19
+ exports.redirectDefaultLimit = fetchRedirectsDataFile.redirectDefaultLimit;
20
+ tslib_1.__exportStar(require("./utils/validateRedirects"), exports);
21
+ tslib_1.__exportStar(require("./redirectsFile"), exports);
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../libs/directus/directus-node/src/lib/redirection/index.ts"],"names":[],"mappings":";AAAA,yCAAyC;;;;AAEzC,qFAA8D;AAC9D,sCAAsC;AACtC;;GAEG;AACU,QAAA,kBAAkB,GAAG,sBAAsB,CAAC,kBAAkB,CAAA;AAC3E;;GAEG;AACU,QAAA,gBAAgB,GAAG,sBAAsB,CAAC,gBAAgB,CAAA;AACvE;;GAEG;AACU,QAAA,oBAAoB,GAAG,sBAAsB,CAAC,oBAAoB,CAAA;AAG/E,oEAAyC;AACzC,0DAA+B"}
@@ -0,0 +1,18 @@
1
+ export interface TFetchRedirectsConfig {
2
+ graphqlEndpoint: string | undefined;
3
+ graphqlApiKey: string | undefined;
4
+ redirectsFilename?: string;
5
+ rewritesFilename?: string;
6
+ limit: number | undefined;
7
+ }
8
+ export interface TFetchRedirectsResponse {
9
+ redirects: TRedirectData[];
10
+ rewrites: TRedirectData[];
11
+ }
12
+ export interface TRedirectData {
13
+ source: string;
14
+ destination: string;
15
+ permanent?: boolean;
16
+ locale?: boolean;
17
+ }
18
+ export type TRedirectType = 'redirects' | 'rewrites';
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../../../../../../libs/directus/directus-node/src/lib/redirection/interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import type { TFetchRedirectsConfig, TRedirectType, TRedirectData } from './interface';
2
+ /**
3
+ * Write Redirect Data
4
+ * @param {string} filename filename
5
+ * @param {unknown} data redirects data (rewrites or redirects)
6
+ */
7
+ export declare function writeRedirectFile(filename: string, data: unknown): Promise<boolean>;
8
+ export declare function readRedirectFileData(filename: string): Promise<unknown>;
9
+ /**
10
+ * Read one redirects or rewrites file
11
+ * @param {string} filePath relative file path like './redirect/redirects.json' to the current working dir
12
+ * @param {TRedirectType} type redirects or rewrites
13
+ * @returns {Promise<TRedirectData[]>} an array of redirect information
14
+ */
15
+ export declare function readRedirectFile(filePath: string, type?: TRedirectType): Promise<TRedirectData[]>;
16
+ /**
17
+ * Fetch and write redirects and rewrites files
18
+ * @param {TFetchRedirectsConfig} config fetch redirects configuration
19
+ * @returns {Promise<boolean>} true
20
+ * @throws {Error}
21
+ */
22
+ export declare function fetchRedirects(config: TFetchRedirectsConfig): Promise<boolean>;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.writeRedirectFile = writeRedirectFile;
4
+ exports.readRedirectFileData = readRedirectFileData;
5
+ exports.readRedirectFile = readRedirectFile;
6
+ exports.fetchRedirects = fetchRedirects;
7
+ const tslib_1 = require("tslib");
8
+ const promises_1 = require("fs/promises");
9
+ const path = tslib_1.__importStar(require("path"));
10
+ const logger_1 = require("../../logger");
11
+ const fetchRedirectsData_1 = require("./fetchRedirectsData");
12
+ /**
13
+ * Write Redirect Data
14
+ * @param {string} filename filename
15
+ * @param {unknown} data redirects data (rewrites or redirects)
16
+ */
17
+ function writeRedirectFile(filename, data) {
18
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
19
+ try {
20
+ const writeData = JSON.stringify(data || []);
21
+ yield (0, promises_1.writeFile)(filename, writeData);
22
+ return true;
23
+ }
24
+ catch (e) {
25
+ logger_1.logger.log(`Error writing redirect file ${filename}: ${e.message}`, 'error');
26
+ }
27
+ return false;
28
+ });
29
+ }
30
+ function readRedirectFileData(filename) {
31
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
32
+ try {
33
+ const file = yield (0, promises_1.readFile)(filename, { encoding: 'utf8' });
34
+ const data = JSON.parse(file);
35
+ return data;
36
+ }
37
+ catch (e) {
38
+ logger_1.logger.log(`Failed loading redirects JSON from ${filename}: ${e.message}`, 'error');
39
+ }
40
+ return [];
41
+ });
42
+ }
43
+ /**
44
+ * Read one redirects or rewrites file
45
+ * @param {string} filePath relative file path like './redirect/redirects.json' to the current working dir
46
+ * @param {TRedirectType} type redirects or rewrites
47
+ * @returns {Promise<TRedirectData[]>} an array of redirect information
48
+ */
49
+ function readRedirectFile(filePath_1) {
50
+ return tslib_1.__awaiter(this, arguments, void 0, function* (filePath, type = 'redirects') {
51
+ const absolutePath = path.resolve(process.cwd(), filePath);
52
+ const data = yield readRedirectFileData(absolutePath);
53
+ if (Array.isArray(data)) {
54
+ // check data integrity
55
+ const checkedData = data.filter((x) => {
56
+ return x && typeof (x === null || x === void 0 ? void 0 : x.source) === 'string' && typeof (x === null || x === void 0 ? void 0 : x.destination) === 'string';
57
+ });
58
+ logger_1.logger.log(`Loading ${type} length: ${checkedData.length}`);
59
+ return checkedData;
60
+ }
61
+ logger_1.logger.log(`Failed loading ${type}, not a valid array`, 'error');
62
+ return [];
63
+ });
64
+ }
65
+ /**
66
+ * Fetch and write redirects and rewrites files
67
+ * @param {TFetchRedirectsConfig} config fetch redirects configuration
68
+ * @returns {Promise<boolean>} true
69
+ * @throws {Error}
70
+ */
71
+ function fetchRedirects(config) {
72
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
73
+ const { redirectsFilename, rewritesFilename } = config;
74
+ if (!redirectsFilename) {
75
+ throw new Error('Missing fetchRedirects configuration `redirectsFilename`');
76
+ }
77
+ if (!rewritesFilename) {
78
+ throw new Error('Missing fetchRedirects configuration `rewritesFilename`');
79
+ }
80
+ // fetch can throw
81
+ const data = yield (0, fetchRedirectsData_1.fetchRedirectsData)(config);
82
+ // should not throw
83
+ yield writeRedirectFile(redirectsFilename, data.redirects);
84
+ yield writeRedirectFile(rewritesFilename, data.rewrites);
85
+ return true;
86
+ });
87
+ }
88
+ //# sourceMappingURL=redirectsFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirectsFile.js","sourceRoot":"","sources":["../../../../../../../libs/directus/directus-node/src/lib/redirection/redirectsFile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { TRedirectData } from '../interface';
2
+ export declare function isRedirect(redirect: unknown): boolean;
3
+ export declare function normalizeRedirects(redirects: (TRedirectData | null)[] | null): TRedirectData[];
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isRedirect = isRedirect;
4
+ exports.normalizeRedirects = normalizeRedirects;
5
+ const tslib_1 = require("tslib");
6
+ const core_lib_1 = require("@okam/core-lib");
7
+ function isRedirect(redirect) {
8
+ return !!redirect && typeof redirect === 'object' && 'source' in redirect && 'destination' in redirect;
9
+ }
10
+ function normalizeRedirects(redirects) {
11
+ if (!redirects || !Array.isArray(redirects))
12
+ return [];
13
+ return redirects.flatMap((redirect) => {
14
+ const _a = redirect !== null && redirect !== void 0 ? redirect : {}, { source, destination } = _a, rest = tslib_1.__rest(_a, ["source", "destination"]);
15
+ if (!redirect || !source || !destination || !isRedirect(redirect))
16
+ return [];
17
+ return [
18
+ Object.assign(Object.assign({}, rest), { source: (0, core_lib_1.normalizePath)(source), destination: (0, core_lib_1.normalizePath)(destination) }),
19
+ ];
20
+ });
21
+ }
22
+ //# sourceMappingURL=validateRedirects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateRedirects.js","sourceRoot":"","sources":["../../../../../../../../libs/directus/directus-node/src/lib/redirection/utils/validateRedirects.ts"],"names":[],"mappings":";;AAGA,gCAEC;AAED,gDAaC;;AApBD,6CAA8C;AAG9C,SAAgB,UAAU,CAAC,QAAiB;IAC1C,OAAO,CAAC,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,IAAI,QAAQ,IAAI,aAAa,IAAI,QAAQ,CAAA;AACxG,CAAC;AAED,SAAgB,kBAAkB,CAAC,SAA0C;IAC3E,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,CAAA;IACtD,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;QACpC,MAAM,KAAmC,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,EAAjD,EAAE,MAAM,EAAE,WAAW,OAA4B,EAAvB,IAAI,sBAA9B,yBAAgC,CAAiB,CAAA;QACvD,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAA;QAC5E,OAAO;4CAEA,IAAI,KACP,MAAM,EAAE,IAAA,wBAAa,EAAC,MAAM,CAAC,EAC7B,WAAW,EAAE,IAAA,wBAAa,EAAC,WAAW,CAAC;SAE1C,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
package/src/logger.d.ts CHANGED
@@ -1,2 +1 @@
1
1
  export declare const logger: import("@okam/logger").Logger;
2
- export declare const log: (message: string, severity?: import("@okam/logger").LogSeverity, context?: Record<string, unknown>) => void;
package/src/logger.js CHANGED
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.log = exports.logger = void 0;
3
+ exports.logger = void 0;
4
4
  const logger_1 = require("@okam/logger");
5
5
  exports.logger = (0, logger_1.createLogger)('[DirectusNode]');
6
- exports.log = exports.logger.log;
7
6
  //# sourceMappingURL=logger.js.map
package/src/logger.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../../../libs/directus/directus-node/src/logger.ts"],"names":[],"mappings":";;;AAAA,yCAA2C;AAE9B,QAAA,MAAM,GAAG,IAAA,qBAAY,EAAC,gBAAgB,CAAC,CAAA;AAErC,WAAG,GAAK,cAAM,KAAA"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../../../libs/directus/directus-node/src/logger.ts"],"names":[],"mappings":";;;AAAA,yCAA2C;AAE9B,QAAA,MAAM,GAAG,IAAA,qBAAY,EAAC,gBAAgB,CAAC,CAAA"}
@@ -1,15 +0,0 @@
1
- interface TFetchRedirectsConfig {
2
- graphqlEndpoint: string;
3
- graphqlApiKey: string;
4
- redirectsFilename: string;
5
- rewritesFilename: string;
6
- limit: number | undefined;
7
- }
8
- export declare const redirectDefaultLimit = 2000;
9
- /**
10
- * Get Fetch Redirects Configuration
11
- * @returns {object}
12
- */
13
- export declare function getDefaultConfig(): TFetchRedirectsConfig;
14
- export declare function fetchRedirects(config: TFetchRedirectsConfig): Promise<boolean>;
15
- export {};
@@ -1,79 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.redirectDefaultLimit = void 0;
4
- exports.getDefaultConfig = getDefaultConfig;
5
- exports.fetchRedirects = fetchRedirects;
6
- const tslib_1 = require("tslib");
7
- const promises_1 = require("node:fs/promises");
8
- const logger_1 = require("../logger");
9
- exports.redirectDefaultLimit = 2000;
10
- /**
11
- * Get Fetch Redirects Configuration
12
- * @returns {object}
13
- */
14
- function getDefaultConfig() {
15
- return {
16
- graphqlEndpoint: process.env['NEXT_PUBLIC_GRAPHQL_URL'] || '',
17
- graphqlApiKey: process.env['NEXT_API_TOKEN_ADMIN'] || '',
18
- redirectsFilename: './redirect/redirects.json',
19
- rewritesFilename: './redirect/rewrites.json',
20
- limit: exports.redirectDefaultLimit,
21
- };
22
- }
23
- function fetchRedirects(config) {
24
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
25
- var _a, _b;
26
- const { graphqlEndpoint, graphqlApiKey, redirectsFilename, rewritesFilename, limit } = config;
27
- if (!graphqlEndpoint || !graphqlApiKey) {
28
- throw new Error('Missing graphql configuration: NEXT_PUBLIC_GRAPHQL_URL or NEXT_API_TOKEN_ADMIN');
29
- }
30
- if (!redirectsFilename || !rewritesFilename) {
31
- throw new Error('Missing filename');
32
- }
33
- const query = `query fetchRedirects($limit: Int = 2000) {
34
- redirects(filter: {status:{_eq:"published"},isrewrite:{_eq:false}}, sort: "sort", limit: $limit) {
35
- source
36
- destination
37
- permanent
38
- locale
39
- }
40
- rewrites: redirects(filter: {status:{_eq:"published"},isrewrite:{_eq:true}}, sort: "sort", limit: $limit) {
41
- source
42
- destination
43
- permanent
44
- locale
45
- }
46
- }`;
47
- const graphqlBody = {
48
- query,
49
- // "operationName": "",
50
- variables: {
51
- limit: Number(limit) || exports.redirectDefaultLimit,
52
- },
53
- };
54
- try {
55
- // console.info(`Fetching redirects on ${graphqlEndpoint}`)
56
- const response = yield fetch(graphqlEndpoint, {
57
- method: 'POST',
58
- headers: {
59
- // eslint-disable-next-line @typescript-eslint/naming-convention
60
- 'Content-Type': 'application/json',
61
- Authorization: `Bearer ${graphqlApiKey}`,
62
- },
63
- body: JSON.stringify(graphqlBody),
64
- });
65
- const { data } = yield response.json();
66
- const writeDataRedirects = JSON.stringify(data.redirects || []);
67
- yield (0, promises_1.writeFile)(redirectsFilename, writeDataRedirects);
68
- const writeDataRewrites = JSON.stringify(data.rewrites || []);
69
- yield (0, promises_1.writeFile)(rewritesFilename, writeDataRewrites);
70
- (0, logger_1.log)(`Redirects count: ${((_a = data.redirects) === null || _a === void 0 ? void 0 : _a.length) || 0}, Rewrites count: ${((_b = data.rewrites) === null || _b === void 0 ? void 0 : _b.length) || 0}`);
71
- }
72
- catch (e) {
73
- (0, logger_1.log)(`Error fetching redirects: ${e.message}`, 'error');
74
- return true; // still want build to pass
75
- }
76
- return true;
77
- });
78
- }
79
- //# sourceMappingURL=redirection.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"redirection.js","sourceRoot":"","sources":["../../../../../../libs/directus/directus-node/src/lib/redirection.ts"],"names":[],"mappings":";;;AAkBA,4CAQC;AAED,wCA4DC;;AAxFD,+CAA4C;AAE5C,sCAA+B;AAUlB,QAAA,oBAAoB,GAAG,IAAI,CAAA;AAExC;;;GAGG;AACH,SAAgB,gBAAgB;IAC9B,OAAO;QACL,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,IAAI,EAAE;QAC7D,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,EAAE;QACxD,iBAAiB,EAAE,2BAA2B;QAC9C,gBAAgB,EAAE,0BAA0B;QAC5C,KAAK,EAAE,4BAAoB;KAC5B,CAAA;AACH,CAAC;AAED,SAAsB,cAAc,CAAC,MAA6B;;;QAChE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,KAAK,EAAE,GAAG,MAAM,CAAA;QAE7F,IAAI,CAAC,eAAe,IAAI,CAAC,aAAa,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAA;QACnG,CAAC;QAED,IAAI,CAAC,iBAAiB,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAA;QACrC,CAAC;QAED,MAAM,KAAK,GAAG;;;;;;;;;;;;;EAad,CAAA;QAEA,MAAM,WAAW,GAAG;YAClB,KAAK;YACL,uBAAuB;YACvB,SAAS,EAAE;gBACT,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,4BAAoB;aAC7C;SACF,CAAA;QAED,IAAI,CAAC;YACH,2DAA2D;YAC3D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE;gBAC5C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,gEAAgE;oBAChE,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,UAAU,aAAa,EAAE;iBACzC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;aAClC,CAAC,CAAA;YACF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YAEtC,MAAM,kBAAkB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAA;YAC/D,MAAM,IAAA,oBAAS,EAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAAA;YAEtD,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAA;YAC7D,MAAM,IAAA,oBAAS,EAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAA;YAEpD,IAAA,YAAG,EAAC,oBAAoB,CAAA,MAAA,IAAI,CAAC,SAAS,0CAAE,MAAM,KAAI,CAAC,qBAAqB,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,MAAM,KAAI,CAAC,EAAE,CAAC,CAAA;QACvG,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAA,YAAG,EAAC,6BAA8B,CAAW,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAA;YACjE,OAAO,IAAI,CAAA,CAAC,2BAA2B;QACzC,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;CAAA"}