@nimpl/getters 1.4.1-canary.0 → 1.4.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/README.md CHANGED
@@ -11,27 +11,31 @@ Visit https://nimpl.tech/getters to view the full documentation.
11
11
  ## Installation
12
12
 
13
13
  **Using npm:**
14
+
14
15
  ```bash
15
16
  npm i @nimpl/getters
16
17
  ```
17
18
 
18
19
  **Using yarn:**
20
+
19
21
  ```bash
20
22
  yarn add @nimpl/getters
21
23
  ```
22
24
 
23
25
  ## Current Getters
24
26
 
25
- * [get-pathname](https://nimpl.tech/getters/current-getters/get-pathname)
26
- * [get-page-config](https://nimpl.tech/getters/current-getters/get-page-config)
27
- * [get-params](https://nimpl.tech/getters/current-getters/get-params)
28
- * [get-search-params](https://nimpl.tech/getters/current-getters/get-search-params) (*deprecated*)
27
+ - [get-pathname](https://nimpl.tech/getters/current-getters/get-pathname)
28
+ - [get-page-config](https://nimpl.tech/getters/current-getters/get-page-config)
29
+ - [get-params](https://nimpl.tech/getters/current-getters/get-params)
30
+ - [get-search-params](https://nimpl.tech/getters/current-getters/get-search-params) (_deprecated_)
31
+
32
+ > _`create-server-context` and `get-server-context` were moved to a separate package - [@nimpl/context](https://nimpl.tech/context)_
29
33
 
30
34
  ## Stability
31
35
 
32
36
  All getters are covered with tests. Tests are run on every release and every 6 hours on the latest **Canary** version of `Next.js`.
33
37
 
34
- In this way, you can be sure not only of the stability of the code, but also that if there is a breaking change in `Next.js`, this will immediately become known. *Even before the release of a stable version of `Next.js`.*
38
+ In this way, you can be sure not only of the stability of the code, but also that if there is a breaking change in `Next.js`, this will immediately become known. _Even before the release of a stable version of `Next.js`._
35
39
 
36
40
  ## Additional
37
41
 
package/get-params.d.ts CHANGED
@@ -1,3 +1,16 @@
1
- export declare const getParams: () => {
2
- [key: string]: string | string[];
1
+ type GetParamsOptions = {
2
+ /**
3
+ * In case of error or segments difference
4
+ * getter will return null
5
+ * (_f.e. `/_not-found` could be at `/it/removed-page` and it would not have any params_)
6
+ */
7
+ ignoreDifferenceError?: true;
8
+ /** Custom pathname (f.e. `["/example/custom"]`). Usable for rewritten pages in SSR or custom functions */
9
+ pathname?: string;
10
+ /** Custom pagePaths list (f.e. `["/example/[slug]/page"]`). Usable for rewritten pages in SSR or custom functions */
11
+ pagePaths?: string[];
3
12
  };
13
+ export declare const getParams: (options?: GetParamsOptions) => {
14
+ [key: string]: string | string[];
15
+ } | null;
16
+ export {};
package/get-params.js CHANGED
@@ -2,34 +2,48 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getParams = void 0;
4
4
  const static_generation_async_storage_external_1 = require("next/dist/client/components/static-generation-async-storage.external");
5
- const utils_1 = require("./utils");
6
5
  const server_getter_in_client_component_error_1 = require("./server-getter-in-client-component-error");
7
- const getParams = () => {
6
+ const utils_1 = require("./utils");
7
+ const getParams = (options = {}) => {
8
8
  (0, server_getter_in_client_component_error_1.serverGetterInClientComponentError)("getParams");
9
9
  const store = static_generation_async_storage_external_1.staticGenerationAsyncStorage.getStore();
10
10
  if (!store)
11
11
  return {};
12
+ const { ignoreDifferenceError, pagePaths, pathname } = options;
12
13
  const { urlPathname, pagePath = "/" } = store;
13
- const cleanUrlPathname = (0, utils_1.normalizePathname)(urlPathname);
14
- const cleanPagePath = (0, utils_1.normalizePagePath)(pagePath);
15
- const pagePathParts = cleanPagePath.split("/");
16
- const pagePathInterceptedParts = (0, utils_1.normalizeInterceptingRoutes)(pagePathParts);
17
- const pathnameParts = cleanUrlPathname.split("/");
18
- const isNotFoundPage = pagePath.match(/\/_not-found\/?$/);
19
- const isValidCatchALl = cleanPagePath.match(/\/\[\.\.\.[^\]]+\]/) && pathnameParts.length >= pagePathInterceptedParts.length;
20
- const isValidOptionalCatchALl = cleanPagePath.match(/\/\[\[\.\.\.[^\]]+\]\]/) && pathnameParts.length >= pagePathInterceptedParts.length - 1;
21
- const isCorrectMatched = isNotFoundPage ||
22
- pagePathInterceptedParts.length === pathnameParts.length ||
23
- isValidCatchALl ||
24
- isValidOptionalCatchALl;
25
- if (!isCorrectMatched) {
14
+ const targetUrlPathname = pathname || urlPathname;
15
+ let isInvalid = false;
16
+ try {
17
+ if (pagePaths) {
18
+ for (const userPagePath of pagePaths) {
19
+ const params = (0, utils_1.parseParams)(targetUrlPathname, userPagePath);
20
+ if (params === utils_1.INVALID_PARSE) {
21
+ isInvalid ||= true;
22
+ continue;
23
+ }
24
+ return params;
25
+ }
26
+ }
27
+ else {
28
+ const params = (0, utils_1.parseParams)(targetUrlPathname, pagePath);
29
+ if (params === utils_1.INVALID_PARSE) {
30
+ isInvalid ||= true;
31
+ }
32
+ else {
33
+ return params;
34
+ }
35
+ }
36
+ }
37
+ catch {
38
+ isInvalid = true;
39
+ }
40
+ if (isInvalid && !ignoreDifferenceError) {
26
41
  const createIssueUrl = new URL("https://github.com/vordgi/nimpl-getters/issues/new");
27
42
  createIssueUrl.searchParams.set("title", "Error parsing segments in get-params");
28
- createIssueUrl.searchParams.set("body", `urlPathname: \`${urlPathname}\`;\n\npagePath: \`${pagePath}\`;`);
43
+ createIssueUrl.searchParams.set("body", `urlPathname: \`${urlPathname}\`;\n\npagePath(s): \`${pagePaths || pagePath}\`;`);
29
44
  createIssueUrl.searchParams.append("labels", "bug");
30
45
  throw new Error(`Something went wrong. Please create an issue on Github: ${createIssueUrl}`);
31
46
  }
32
- const query = (0, utils_1.parseSegments)(pagePathInterceptedParts, pathnameParts);
33
- return query;
47
+ return null;
34
48
  };
35
49
  exports.getParams = getParams;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nimpl/getters",
3
- "version": "1.4.1-canary.0",
3
+ "version": "1.4.1",
4
4
  "description": "Implementation of server getters in React Server Components without switching to SSR in next.js",
5
5
  "files": [
6
6
  "**/*.js",
@@ -43,4 +43,4 @@
43
43
  "react-dom": ">= 18.2.0",
44
44
  "next": ">= 14.0.0"
45
45
  }
46
- }
46
+ }
package/utils.d.ts CHANGED
@@ -4,3 +4,7 @@ export declare const parseSegments: (pagePathParts: string[], pathnameParts: str
4
4
  [key: string]: string | string[];
5
5
  };
6
6
  export declare const normalizeInterceptingRoutes: (pageParts: string[]) => string[];
7
+ export declare const INVALID_PARSE: unique symbol;
8
+ export declare const parseParams: (urlPathname: string, pagePath: string) => typeof INVALID_PARSE | {
9
+ [key: string]: string | string[];
10
+ };
package/utils.js CHANGED
@@ -1,20 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.normalizeInterceptingRoutes = exports.parseSegments = exports.normalizePagePath = exports.normalizePathname = void 0;
3
+ exports.parseParams = exports.INVALID_PARSE = exports.normalizeInterceptingRoutes = exports.parseSegments = exports.normalizePagePath = exports.normalizePathname = void 0;
4
4
  const normalizePathname = (pathname) => {
5
5
  const cleanPathname = pathname && new URL(pathname, "http://n").pathname;
6
6
  const pathnameWithoutTrailingSlash = cleanPathname?.replace(/^(\/.*)\/$/, "$1");
7
7
  const pathnameWithoutFileType = pathnameWithoutTrailingSlash?.replace(/\/_not-found$/, "");
8
- return pathnameWithoutFileType || "/";
8
+ return pathnameWithoutFileType.endsWith("/") ? pathnameWithoutFileType : pathnameWithoutFileType + "/";
9
9
  };
10
10
  exports.normalizePathname = normalizePathname;
11
11
  const normalizePagePath = (pagePath) => {
12
12
  const cleanPagePath = pagePath && new URL(pagePath, "http://n").pathname;
13
- const pagePathWithoutFileType = cleanPagePath?.replace(/(\/page|\/_not-found)$/, "");
13
+ const pagePathWithoutFileType = cleanPagePath?.replace(/(\/page|\/_not-found)$/, "/");
14
14
  const pagePathWithoutGroups = pagePathWithoutFileType
15
15
  .split("/")
16
+ .filter(Boolean)
16
17
  .filter((segment) => !segment.match(/^(\([^)]+\)$|^\@.+$)/g));
17
- return pagePathWithoutGroups.join("/") || "/";
18
+ if (pagePathWithoutGroups.length === 0)
19
+ return "/";
20
+ return "/" + pagePathWithoutGroups.join("/") + "/";
18
21
  };
19
22
  exports.normalizePagePath = normalizePagePath;
20
23
  const parseSegments = (pagePathParts, pathnameParts) => {
@@ -72,3 +75,32 @@ const normalizeInterceptingRoutes = (pageParts) => {
72
75
  return normilizedParts.reverse();
73
76
  };
74
77
  exports.normalizeInterceptingRoutes = normalizeInterceptingRoutes;
78
+ exports.INVALID_PARSE = Symbol("Invalid Parse");
79
+ const isSamePaths = (urlPathnameParts, pagePathParts) => {
80
+ for (let i = 0; i < pagePathParts.length; i++) {
81
+ const urlPathnamePart = urlPathnameParts[i];
82
+ const pagePathPart = pagePathParts[i];
83
+ if (pagePathPart.match(/\[\.\.\.[^\]]+\]/))
84
+ return true;
85
+ if (pagePathPart.match(/\[[^\]]+\]/))
86
+ continue;
87
+ if (urlPathnamePart !== pagePathPart)
88
+ return false;
89
+ }
90
+ return urlPathnameParts.length === pagePathParts.length;
91
+ };
92
+ const parseParams = (urlPathname, pagePath) => {
93
+ const cleanUrlPathname = (0, exports.normalizePathname)(urlPathname);
94
+ const cleanPagePath = (0, exports.normalizePagePath)(pagePath);
95
+ const pagePathParts = cleanPagePath.split("/").slice(0, -1);
96
+ const pagePathInterceptedParts = (0, exports.normalizeInterceptingRoutes)(pagePathParts);
97
+ const pathnameParts = cleanUrlPathname.split("/").slice(0, -1);
98
+ const isNotFoundPage = pagePath.match(/\/_not-found\/?$/);
99
+ const isCorrectMatched = isNotFoundPage || isSamePaths(pathnameParts, pagePathInterceptedParts);
100
+ if (!isCorrectMatched) {
101
+ return exports.INVALID_PARSE;
102
+ }
103
+ const query = (0, exports.parseSegments)(pagePathInterceptedParts, pathnameParts);
104
+ return query;
105
+ };
106
+ exports.parseParams = parseParams;