@rzl-zone/utils-js 3.12.1-beta.0 → 3.12.1-beta.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 +7 -7
- package/dist/.references/index.d.cts +1 -1
- package/dist/.references/index.d.ts +1 -1
- package/dist/{assertIsArray-BChqwPiP.cjs → assertIsArray-DJXkjHZs.cjs} +3 -3
- package/dist/{assertIsArray-BChqwPiP.cjs.map → assertIsArray-DJXkjHZs.cjs.map} +1 -1
- package/dist/{assertIsArray-BfAbIUfa.js → assertIsArray-bTA3XLjq.js} +3 -3
- package/dist/{assertIsArray-BfAbIUfa.js.map → assertIsArray-bTA3XLjq.js.map} +1 -1
- package/dist/{assertIsBoolean-DozdtbNi.cjs → assertIsBoolean-C8WEXVr2.cjs} +8 -8
- package/dist/assertIsBoolean-C8WEXVr2.cjs.map +1 -0
- package/dist/{assertIsBoolean-BlBct0Fc.js → assertIsBoolean-DR1SaXPD.js} +8 -8
- package/dist/assertIsBoolean-DR1SaXPD.js.map +1 -0
- package/dist/{assertIsString-Bvk7bUL7.cjs → assertIsString-BiHQSrB2.cjs} +3 -3
- package/dist/{assertIsString-Bvk7bUL7.cjs.map → assertIsString-BiHQSrB2.cjs.map} +1 -1
- package/dist/{assertIsString-DqV9NwbI.js → assertIsString-CEB07_83.js} +3 -3
- package/dist/{assertIsString-DqV9NwbI.js.map → assertIsString-CEB07_83.js.map} +1 -1
- package/dist/assertions/index.cjs +5 -5
- package/dist/assertions/index.d.cts +2 -2
- package/dist/assertions/index.d.ts +2 -2
- package/dist/assertions/index.js +5 -5
- package/dist/conversions/index.cjs +6 -6
- package/dist/conversions/index.d.cts +2 -2
- package/dist/conversions/index.d.ts +2 -2
- package/dist/conversions/index.js +6 -6
- package/dist/{conversions-EMJa3g-D.js → conversions-BNIh_tCH.js} +16 -18
- package/dist/conversions-BNIh_tCH.js.map +1 -0
- package/dist/{conversions-CBs8-REq.cjs → conversions-D_Kh0a_C.cjs} +16 -18
- package/dist/conversions-D_Kh0a_C.cjs.map +1 -0
- package/dist/events/index.cjs +4 -4
- package/dist/events/index.cjs.map +1 -1
- package/dist/events/index.d.cts +153 -151
- package/dist/events/index.d.ts +153 -151
- package/dist/events/index.js +4 -4
- package/dist/events/index.js.map +1 -1
- package/dist/{formatEnvPort-hHNvOim-.cjs → formatEnvPort-B3OLxQk9.cjs} +9 -9
- package/dist/formatEnvPort-B3OLxQk9.cjs.map +1 -0
- package/dist/{formatEnvPort-DpIXzPAZ.js → formatEnvPort-ByFVLjSV.js} +9 -9
- package/dist/formatEnvPort-ByFVLjSV.js.map +1 -0
- package/dist/formatters/index.cjs +2 -2
- package/dist/formatters/index.d.cts +2 -2
- package/dist/formatters/index.d.ts +2 -2
- package/dist/formatters/index.js +2 -2
- package/dist/{formatters-QcZO_Cpx.js → formatters--1m_vpE8.js} +17 -15
- package/dist/formatters--1m_vpE8.js.map +1 -0
- package/dist/{formatters-lAYgA11L.cjs → formatters-Cbij0XLU.cjs} +17 -15
- package/dist/formatters-Cbij0XLU.cjs.map +1 -0
- package/dist/generators/index.cjs +12 -8
- package/dist/generators/index.cjs.map +1 -1
- package/dist/generators/index.d.cts +2 -2
- package/dist/generators/index.d.ts +2 -2
- package/dist/generators/index.js +12 -8
- package/dist/generators/index.js.map +1 -1
- package/dist/index-59zbLcPr.d.ts +340 -0
- package/dist/index-B6tawc8L.d.cts +1716 -0
- package/dist/index-C267akkJ.d.ts +2158 -0
- package/dist/index-CeBC2Vvl.d.cts +2361 -0
- package/dist/index-CgRDTI6f.d.ts +822 -0
- package/dist/index-CoiUBVmr.d.ts +720 -0
- package/dist/index-D4fcasfZ.d.cts +720 -0
- package/dist/index-DDrSQKIc.d.ts +1716 -0
- package/dist/index-DsGxO31H.d.cts +765 -0
- package/dist/index-Hg1qJkjl.d.ts +765 -0
- package/dist/index-Qm3iFwd0.d.cts +2158 -0
- package/dist/index-UPp94Agr.d.ts +2361 -0
- package/dist/index-gBA_8SuF.d.cts +340 -0
- package/dist/index-jyDqzicx.d.cts +822 -0
- package/dist/{isBigInt-B1cijjqm.cjs → isBigInt-C4krUeAw.cjs} +2 -2
- package/dist/{isBigInt-B1cijjqm.cjs.map → isBigInt-C4krUeAw.cjs.map} +1 -1
- package/dist/{isBigInt-C0bN0Rhu.js → isBigInt-DKe0M6hp.js} +2 -2
- package/dist/{isBigInt-C0bN0Rhu.js.map → isBigInt-DKe0M6hp.js.map} +1 -1
- package/dist/{isEmptyObject-DeLVIJpl.js → isEmptyObject-DCipFwxJ.js} +3 -3
- package/dist/{isEmptyObject-DeLVIJpl.js.map → isEmptyObject-DCipFwxJ.js.map} +1 -1
- package/dist/{isEmptyObject-DI42NEo0.cjs → isEmptyObject-ZkSwRC_D.cjs} +3 -3
- package/dist/{isEmptyObject-DI42NEo0.cjs.map → isEmptyObject-ZkSwRC_D.cjs.map} +1 -1
- package/dist/{isEmptyString-BTUWYTbw.js → isEmptyString-BXzKAC2j.js} +3 -3
- package/dist/{isEmptyString-BTUWYTbw.js.map → isEmptyString-BXzKAC2j.js.map} +1 -1
- package/dist/{isEmptyString-CCK3bP74.cjs → isEmptyString-UiiUsSQj.cjs} +3 -3
- package/dist/{isEmptyString-CCK3bP74.cjs.map → isEmptyString-UiiUsSQj.cjs.map} +1 -1
- package/dist/{isEmptyValue-DMSMFTU8.cjs → isEmptyValue-BQzcjVaL.cjs} +5 -5
- package/dist/{isEmptyValue-DMSMFTU8.cjs.map → isEmptyValue-BQzcjVaL.cjs.map} +1 -1
- package/dist/{isEmptyValue-fjnfQnt5.js → isEmptyValue-jqOr7OHD.js} +5 -5
- package/dist/{isEmptyValue-fjnfQnt5.js.map → isEmptyValue-jqOr7OHD.js.map} +1 -1
- package/dist/{isEqual-DhyP8fB_.js → isEqual-BX49cF9m.js} +4 -4
- package/dist/{isEqual-DhyP8fB_.js.map → isEqual-BX49cF9m.js.map} +1 -1
- package/dist/{isEqual-B1fRgEuU.cjs → isEqual-BvumA3RA.cjs} +4 -4
- package/dist/{isEqual-B1fRgEuU.cjs.map → isEqual-BvumA3RA.cjs.map} +1 -1
- package/dist/{isFinite-BYMOo0os.js → isFinite-BCnaDpod.js} +3 -3
- package/dist/{isFinite-BYMOo0os.js.map → isFinite-BCnaDpod.js.map} +1 -1
- package/dist/{isFinite-sFkps2TY.cjs → isFinite-D24ZaE6c.cjs} +3 -3
- package/dist/{isFinite-sFkps2TY.cjs.map → isFinite-D24ZaE6c.cjs.map} +1 -1
- package/dist/{isInteger-FTCthMre.cjs → isInteger-Caeuz0rB.cjs} +2 -2
- package/dist/{isInteger-FTCthMre.cjs.map → isInteger-Caeuz0rB.cjs.map} +1 -1
- package/dist/{isInteger-DS9V7l_f.js → isInteger-naMbJsxJ.js} +2 -2
- package/dist/{isInteger-DS9V7l_f.js.map → isInteger-naMbJsxJ.js.map} +1 -1
- package/dist/isPlainObject-BF-2-phb.d.cts +339 -0
- package/dist/isPlainObject-DxNDL8XU.d.ts +339 -0
- package/dist/{isServer-q-QLFCqE.cjs → isServer-BJHVnixd.cjs} +2 -2
- package/dist/{isServer-q-QLFCqE.cjs.map → isServer-BJHVnixd.cjs.map} +1 -1
- package/dist/{isServer-D1TXfOs3.js → isServer-Da3o3XSs.js} +2 -2
- package/dist/{isServer-D1TXfOs3.js.map → isServer-Da3o3XSs.js.map} +1 -1
- package/dist/{isTypedArray-47R0wdrc.js → isTypedArray-DuNA8tK6.js} +3 -3
- package/dist/{isTypedArray-47R0wdrc.js.map → isTypedArray-DuNA8tK6.js.map} +1 -1
- package/dist/{isTypedArray-DiCoqffZ.cjs → isTypedArray-TJptiw2b.cjs} +3 -3
- package/dist/{isTypedArray-DiCoqffZ.cjs.map → isTypedArray-TJptiw2b.cjs.map} +1 -1
- package/dist/{isURL-CQiowFq2.js → isURL-C-kSk6KJ.js} +2 -2
- package/dist/{isURL-CQiowFq2.js.map → isURL-C-kSk6KJ.js.map} +1 -1
- package/dist/{isURL-WZypXsax.cjs → isURL-DeUPO_oR.cjs} +2 -2
- package/dist/{isURL-WZypXsax.cjs.map → isURL-DeUPO_oR.cjs.map} +1 -1
- package/dist/{isValidDomain-BSXshgkC.cjs → isValidDomain-BB9IGhJs.cjs} +65 -8
- package/dist/isValidDomain-BB9IGhJs.cjs.map +1 -0
- package/dist/{isValidDomain-DwA2EN79.js → isValidDomain-DoE98yhJ.js} +54 -9
- package/dist/isValidDomain-DoE98yhJ.js.map +1 -0
- package/dist/next/index.cjs +7 -7
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +185 -191
- package/dist/next/index.d.ts +185 -191
- package/dist/next/index.js +7 -7
- package/dist/next/index.js.map +1 -1
- package/dist/next/server/index.cjs +2 -2
- package/dist/next/server/index.d.cts +26 -26
- package/dist/next/server/index.d.ts +26 -26
- package/dist/next/server/index.js +2 -2
- package/dist/{noop-B2mTBhW-.cjs → noop-B13_ii35.cjs} +2 -2
- package/dist/{noop-B2mTBhW-.cjs.map → noop-B13_ii35.cjs.map} +1 -1
- package/dist/{noop-BzktGBVz.js → noop-ubqAIbHD.js} +2 -2
- package/dist/{noop-BzktGBVz.js.map → noop-ubqAIbHD.js.map} +1 -1
- package/dist/{normalizeSpaces-WS_iERJk.js → normalizeSpaces-Bg2IZW7W.js} +3 -3
- package/dist/{normalizeSpaces-WS_iERJk.js.map → normalizeSpaces-Bg2IZW7W.js.map} +1 -1
- package/dist/{normalizeSpaces-DQHR3Tlr.cjs → normalizeSpaces-ZXnR4Qzp.cjs} +3 -3
- package/dist/{normalizeSpaces-DQHR3Tlr.cjs.map → normalizeSpaces-ZXnR4Qzp.cjs.map} +1 -1
- package/dist/{normalizeString-2WLth_Gj.js → normalizeString-BDdkaXui.js} +3 -3
- package/dist/{normalizeString-2WLth_Gj.js.map → normalizeString-BDdkaXui.js.map} +1 -1
- package/dist/{normalizeString-D8euBcRD.cjs → normalizeString-BE6ELqEb.cjs} +3 -3
- package/dist/{normalizeString-D8euBcRD.cjs.map → normalizeString-BE6ELqEb.cjs.map} +1 -1
- package/dist/operations/index.cjs +10 -10
- package/dist/operations/index.cjs.map +1 -1
- package/dist/operations/index.d.cts +120 -120
- package/dist/operations/index.d.ts +120 -120
- package/dist/operations/index.js +10 -10
- package/dist/operations/index.js.map +1 -1
- package/dist/parsers/index.cjs +2 -2
- package/dist/parsers/index.d.cts +222 -222
- package/dist/parsers/index.d.ts +222 -222
- package/dist/parsers/index.js +2 -2
- package/dist/{parsers-Dpuq-V4u.js → parsers-BSBPgvsq.js} +4 -4
- package/dist/{parsers-Dpuq-V4u.js.map → parsers-BSBPgvsq.js.map} +1 -1
- package/dist/{parsers-DXtpsDyj.cjs → parsers-OqDeffqc.cjs} +4 -4
- package/dist/{parsers-DXtpsDyj.cjs.map → parsers-OqDeffqc.cjs.map} +1 -1
- package/dist/{parsing-B43x1sxn.js → parsing-Cao8b358.js} +3 -3
- package/dist/{parsing-B43x1sxn.js.map → parsing-Cao8b358.js.map} +1 -1
- package/dist/{parsing-lRoxn1Nz.cjs → parsing-DOGSCH6N.cjs} +3 -3
- package/dist/{parsing-lRoxn1Nz.cjs.map → parsing-DOGSCH6N.cjs.map} +1 -1
- package/dist/predicates/index.cjs +15 -15
- package/dist/predicates/index.d.cts +3 -3
- package/dist/predicates/index.d.ts +3 -3
- package/dist/predicates/index.js +15 -15
- package/dist/{predicates-gNepszvo.js → predicates-Bj6meyXV.js} +13 -14
- package/dist/{predicates-gNepszvo.js.map → predicates-Bj6meyXV.js.map} +1 -1
- package/dist/{predicates-DiaYA7Ps.cjs → predicates-D0ubqgqy.cjs} +13 -14
- package/dist/{predicates-DiaYA7Ps.cjs.map → predicates-D0ubqgqy.cjs.map} +1 -1
- package/dist/promises/index.cjs +4 -4
- package/dist/promises/index.d.cts +101 -101
- package/dist/promises/index.d.ts +101 -101
- package/dist/promises/index.js +4 -4
- package/dist/{punyCode-hmiFzLWT.js → punyCode-8SrbMWfM.js} +6 -6
- package/dist/punyCode-8SrbMWfM.js.map +1 -0
- package/dist/{punyCode-CTWXVVFo.cjs → punyCode-D-Qu6nj6.cjs} +6 -6
- package/dist/punyCode-D-Qu6nj6.cjs.map +1 -0
- package/dist/{removeSpaces-BE8lfh-4.js → removeSpaces-Bmc5DX4F.js} +3 -3
- package/dist/removeSpaces-Bmc5DX4F.js.map +1 -0
- package/dist/{removeSpaces-DRRxNWlb.cjs → removeSpaces-CWIvhZHg.cjs} +3 -3
- package/dist/removeSpaces-CWIvhZHg.cjs.map +1 -0
- package/dist/rzl-utils.global.js +21 -0
- package/dist/{safeJsonParse-CXruaP0p.js → safeJsonParse-BP38mwlj.js} +9 -9
- package/dist/safeJsonParse-BP38mwlj.js.map +1 -0
- package/dist/{safeJsonParse-BBnQElk8.cjs → safeJsonParse-Sms2CJf4.cjs} +9 -9
- package/dist/safeJsonParse-Sms2CJf4.cjs.map +1 -0
- package/dist/{safeStableStringify-Cc62pfRp.cjs → safeStableStringify-CJtP89qn.cjs} +4 -4
- package/dist/{safeStableStringify-Cc62pfRp.cjs.map → safeStableStringify-CJtP89qn.cjs.map} +1 -1
- package/dist/{safeStableStringify-BNh3D0K0.js → safeStableStringify-CXOZ9Ub8.js} +4 -4
- package/dist/{safeStableStringify-BNh3D0K0.js.map → safeStableStringify-CXOZ9Ub8.js.map} +1 -1
- package/dist/strings/index.cjs +12 -9
- package/dist/strings/index.cjs.map +1 -1
- package/dist/strings/index.d.cts +2 -2
- package/dist/strings/index.d.ts +2 -2
- package/dist/strings/index.js +12 -9
- package/dist/strings/index.js.map +1 -1
- package/dist/tailwind/index.cjs +2 -2
- package/dist/tailwind/index.d.cts +2 -2
- package/dist/tailwind/index.d.ts +2 -2
- package/dist/tailwind/index.js +2 -2
- package/dist/{tailwind-IJvOdkZp.js → tailwind-B2ssevxq.js} +5 -5
- package/dist/tailwind-B2ssevxq.js.map +1 -0
- package/dist/{tailwind-DJ4cmLUw.cjs → tailwind-CHIx9uxu.cjs} +5 -5
- package/dist/tailwind-CHIx9uxu.cjs.map +1 -0
- package/dist/{toStringArrayUnRecursive-xUaU8Ot9.cjs → toStringArrayUnRecursive-C4zYCja7.cjs} +6 -6
- package/dist/{toStringArrayUnRecursive-xUaU8Ot9.cjs.map → toStringArrayUnRecursive-C4zYCja7.cjs.map} +1 -1
- package/dist/{toStringArrayUnRecursive-CFs0jTEg.js → toStringArrayUnRecursive-DJGtPsFb.js} +6 -6
- package/dist/{toStringArrayUnRecursive-CFs0jTEg.js.map → toStringArrayUnRecursive-DJGtPsFb.js.map} +1 -1
- package/dist/urls/index.cjs +15 -14
- package/dist/urls/index.cjs.map +1 -1
- package/dist/urls/index.d.cts +656 -659
- package/dist/urls/index.d.ts +656 -659
- package/dist/urls/index.js +15 -14
- package/dist/urls/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/assertIsBoolean-BlBct0Fc.js.map +0 -1
- package/dist/assertIsBoolean-DozdtbNi.cjs.map +0 -1
- package/dist/conversions-CBs8-REq.cjs.map +0 -1
- package/dist/conversions-EMJa3g-D.js.map +0 -1
- package/dist/formatEnvPort-DpIXzPAZ.js.map +0 -1
- package/dist/formatEnvPort-hHNvOim-.cjs.map +0 -1
- package/dist/formatters-QcZO_Cpx.js.map +0 -1
- package/dist/formatters-lAYgA11L.cjs.map +0 -1
- package/dist/index-26W7ItWx.d.ts +0 -760
- package/dist/index-BPPQjAfs.d.cts +0 -2359
- package/dist/index-BXjlgBLz.d.cts +0 -2139
- package/dist/index-B_Wwo91H.d.ts +0 -2359
- package/dist/index-CpufydcI.d.cts +0 -704
- package/dist/index-Czc4O526.d.ts +0 -333
- package/dist/index-DPs1_p5G.d.cts +0 -760
- package/dist/index-DRpOyBSC.d.ts +0 -1703
- package/dist/index-DWWvtHUn.d.cts +0 -822
- package/dist/index-DnM0LD0n.d.cts +0 -333
- package/dist/index-GUZ9fK6T.d.ts +0 -2139
- package/dist/index-I4fAzwXV.d.ts +0 -704
- package/dist/index-JDrOl_19.d.ts +0 -822
- package/dist/index-b66P49Qe.d.cts +0 -1703
- package/dist/isPlainObject-DcFGh3_5.d.ts +0 -530
- package/dist/isPlainObject-doTI11Ib.d.cts +0 -530
- package/dist/isValidDomain-BSXshgkC.cjs.map +0 -1
- package/dist/isValidDomain-DwA2EN79.js.map +0 -1
- package/dist/punyCode-CTWXVVFo.cjs.map +0 -1
- package/dist/punyCode-hmiFzLWT.js.map +0 -1
- package/dist/removeSpaces-BE8lfh-4.js.map +0 -1
- package/dist/removeSpaces-DRRxNWlb.cjs.map +0 -1
- package/dist/safeJsonParse-BBnQElk8.cjs.map +0 -1
- package/dist/safeJsonParse-CXruaP0p.js.map +0 -1
- package/dist/tailwind-DJ4cmLUw.cjs.map +0 -1
- package/dist/tailwind-IJvOdkZp.js.map +0 -1
package/dist/next/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* ========================================================================
|
|
3
3
|
* @rzl-zone/utils-js
|
|
4
4
|
* ------------------------------------------------------------------------
|
|
5
|
-
* Version: `3.12.1-beta.
|
|
5
|
+
* Version: `3.12.1-beta.1`
|
|
6
6
|
* Author: `Rizalvin Dwiky <rizalvindwiky@gmail.com>`
|
|
7
7
|
* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/utils-js`
|
|
8
8
|
* ========================================================================
|
|
@@ -10,217 +10,211 @@
|
|
|
10
10
|
|
|
11
11
|
import { IsAny } from "@rzl-zone/ts-types-plus";
|
|
12
12
|
/** ---------------------------------------------------------
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
13
|
+
* * ***Extracts dynamic route parameters from a given route string.***
|
|
14
|
+
* ---------------------------------------------------------
|
|
15
|
+
* **This utility type recursively searches for dynamic segments within a route,
|
|
16
|
+
* extracting each parameter and constructing an object where each key represents
|
|
17
|
+
* a dynamic segment and its value is of type `string`.**
|
|
18
|
+
* - ***⚠️ Warning:***
|
|
19
|
+
* - ***This types only support when using ***[`NextJS`](https://nextjs.org/)***.***
|
|
20
|
+
* @template T - The route string containing potential dynamic segments.
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* type Params1 = ExtractRouteParams<"/user/[id]">;
|
|
24
|
+
* // ➔ { id: string }
|
|
25
|
+
* type Params2 = ExtractRouteParams<"/post/[slug]/comment/[commentId]">;
|
|
26
|
+
* // ➔ { slug: string; commentId: string }
|
|
27
|
+
* type Params3 = ExtractRouteParams<"/dashboard">;
|
|
28
|
+
* // ➔ {} (no dynamic parameters)
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
31
|
type ExtractRouteParams<T> = T extends string ? HasDynamicSegments<T> extends true ? T extends `${infer _Start}[${infer Param}]${infer Rest}` ? { [K in Param | keyof ExtractRouteParams<Rest>]: string } : unknown : unknown : unknown;
|
|
32
32
|
/** ---------------------------------------------------------
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
33
|
+
* * ***Determines whether a given route contains dynamic segments.***
|
|
34
|
+
* ---------------------------------------------------------
|
|
35
|
+
* **This type checks if the route includes at least one `[param]` pattern.
|
|
36
|
+
* If it does, the result is `true`, otherwise `false`.**
|
|
37
|
+
* - ***⚠️ Warning:***
|
|
38
|
+
* - ***This types only support when using ***[`NextJS`](https://nextjs.org/)***.***
|
|
39
|
+
* @template T - The route string to be evaluated.
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* type HasParams1 = HasDynamicSegments<"/user/[id]">;
|
|
43
|
+
* // ➔ true
|
|
44
|
+
* type HasParams2 = HasDynamicSegments<"/settings/profile">;
|
|
45
|
+
* // ➔ false
|
|
46
|
+
* type HasParams3 = HasDynamicSegments<"/blog/[category]/[slug]">;
|
|
47
|
+
* // ➔ true
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
50
|
type HasDynamicSegments<T> = T extends `${string}[${string}]${string}` ? true : false;
|
|
51
51
|
type GenerateRouteResult<T> = true extends IsAny<T> ? unknown : T extends string ? string : unknown;
|
|
52
52
|
/** ---------------------------------
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
53
|
+
* * ***Utility for NextJS: `generateRoute`.***
|
|
54
|
+
* ---------------------------------
|
|
55
|
+
* **Generates a URL by replacing dynamic route parameters with provided values.**
|
|
56
|
+
* - ***⚠️ Warning:***
|
|
57
|
+
* - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***
|
|
58
|
+
* @template T - The route string containing dynamic segments in the format `[param]`.
|
|
59
|
+
* @param {T} route - The route string containing dynamic segments.
|
|
60
|
+
* @param {ExtractRouteParams<T>} [params] - An object containing key-value pairs that match the dynamic segments in the route.
|
|
61
|
+
* @returns {string} The formatted URL with all dynamic segments replaced.
|
|
62
|
+
* @throws **{@link Error | `Error`}** if the route contains dynamic segments but no parameters object is provided.
|
|
63
|
+
* @throws **{@link Error | `Error`}** if a required parameter is missing from the `params` object.
|
|
64
|
+
* @throws **{@link Error | `Error`}** if a parameter value is an empty string.
|
|
65
|
+
* @throws **{@link Error | `Error`}** if any parameter contains invalid characters like `?`, `&`, `=`, `#`, `/`, spaces, `'`, `"`, `(`, `)`, `+`, `;`, `%`, `@`, or `:`, which can cause URL issues.
|
|
66
|
+
* @example
|
|
67
|
+
* // Basic usage
|
|
68
|
+
* generateRoute("/user/[id]", { id: "123" });
|
|
69
|
+
* // ➔ "/user/123"
|
|
70
|
+
*
|
|
71
|
+
* // No dynamic segments, returns as-is
|
|
72
|
+
* generateRoute("/dashboard");
|
|
73
|
+
* // ➔ "/dashboard"
|
|
74
|
+
*
|
|
75
|
+
* // Throws an error due to missing parameters object
|
|
76
|
+
* generateRoute("/profile/[username]");
|
|
77
|
+
* // ➔ ❌ Error: ❌ Missing parameters object for route: "/profile/[username]"
|
|
78
|
+
*
|
|
79
|
+
* // Throws an error due to an empty parameter value
|
|
80
|
+
* generateRoute("/post/[category]/[slug]", { category: "tech", slug: "" });
|
|
81
|
+
* // ➔ ❌ Error: ❌ Parameter "slug" cannot be empty in route: "/post/[category]/[slug]"
|
|
82
|
+
*
|
|
83
|
+
* // Throws an error due to parameter containing invalid characters
|
|
84
|
+
* generateRoute("/search/[query]", { query: "how to?learn" });
|
|
85
|
+
* // ➔ ❌ Error: ❌ Parameter "query" contains invalid character "?" in route: "/search/[query]"
|
|
86
|
+
*
|
|
87
|
+
* // Handles leading/trailing slashes correctly
|
|
88
|
+
* generateRoute("/blog/[category]/[slug]", { category: "/news/", slug: "/latest-update/" });
|
|
89
|
+
* // ➔ ❌ Error: ❌ Parameter "category" and "slug" contains slashes "/" which is not allowed.
|
|
90
|
+
*/
|
|
91
91
|
declare function generateRoute<T extends string>(route: T extends string ? HasDynamicSegments<T> extends true ? T : never : never, params: T extends string ? ExtractRouteParams<T> : undefined): GenerateRouteResult<T>;
|
|
92
92
|
declare function generateRoute<T extends string>(route: T extends string ? T : never, params?: Extract<ExtractRouteParams<T>, Record<string, unknown>>): GenerateRouteResult<T>;
|
|
93
93
|
declare function generateRoute<T = unknown>(route: T extends string ? HasDynamicSegments<T> extends true ? T : unknown : unknown, params?: T extends string ? ExtractRouteParams<T> : undefined): unknown;
|
|
94
94
|
type OptionsCreateBeApiUrl = {
|
|
95
95
|
/** * The prefix pathname api url, e.g:`"http://localhost.com/your-target-prefix-entri-point-api-is-here"`, default: `"/api"`.
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
*
|
|
97
|
+
* @default "/api" */
|
|
98
98
|
prefix?: string;
|
|
99
99
|
/** * Option to getting `prefix` and `pathname` of api url only `(removing origin base api url)`, default: `true`.
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
*
|
|
101
|
+
* @default true */
|
|
102
102
|
withOrigin?: boolean;
|
|
103
103
|
};
|
|
104
104
|
/** ---------------------------------
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
declare const createBeApiUrl: (
|
|
146
|
-
/** * The pathname api url, e.g:`"http://localhost.com/your-target-prefix-entri-point-api-is-here/your-target-pathname-is-here"`.
|
|
147
|
-
*
|
|
148
|
-
* @default ""
|
|
149
|
-
*/
|
|
150
|
-
|
|
151
|
-
pathname: string | null | undefined, options?: OptionsCreateBeApiUrl) => string;
|
|
105
|
+
* * ***Utility for NextJS: `createBeApiUrl`.***
|
|
106
|
+
* ---------------------------------
|
|
107
|
+
* **Constructs a backend API URL by appending a given pathname to the base API URL.**
|
|
108
|
+
* - **ℹ️ Note:**
|
|
109
|
+
* - This function builds on top of `getBeApiUrl()`.
|
|
110
|
+
* - **Determines the base API URL from:**
|
|
111
|
+
* - `NEXT_PUBLIC_BACKEND_API_URL` environment variable (or defaults to `"http://localhost:8000"`).
|
|
112
|
+
* - Automatically appends `NEXT_PUBLIC_PORT_BE` if the base URL does not already include a port.
|
|
113
|
+
* - **Features of this function:**
|
|
114
|
+
* - Allows customizing the API path with an optional `prefix` (defaults to `"/api"`).
|
|
115
|
+
* - Can include or exclude the origin (protocol + host) via `withOrigin`.
|
|
116
|
+
* - Normalizes paths to avoid duplicate slashes.
|
|
117
|
+
* - ***⚠️ Warning:***
|
|
118
|
+
* - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***
|
|
119
|
+
* @param {string|null|undefined} pathname - The API endpoint path (e.g., `/users` or `/v1/posts`), defaultValue: `""`.
|
|
120
|
+
* @param {OptionsCreateBeApiUrl} [options] - Configuration options.
|
|
121
|
+
* @param {OptionsCreateBeApiUrl["prefix"]} [options.prefix="/api"] - The prefix for the API path (default is `"/api"`).
|
|
122
|
+
* @param {OptionsCreateBeApiUrl["withOrigin"]} [options.withOrigin=true] - Whether to include the full base URL or return only the API path.
|
|
123
|
+
* @returns {string} The formatted API URL.
|
|
124
|
+
* @throws **{@link TypeError | `TypeError`}** if `withOrigin` is not a boolean.
|
|
125
|
+
* @throws **{@link TypeError | `TypeError`}** if `prefix` and `pathname` is not a string.
|
|
126
|
+
* @throws **{@link Error | `Error`}** if constructing the API URL fails due to an invalid base URL.
|
|
127
|
+
* @example
|
|
128
|
+
* createBeApiUrl("/users")
|
|
129
|
+
* // ➔ "http://localhost:8000/api/users"
|
|
130
|
+
* createBeApiUrl("/api/users")
|
|
131
|
+
* // ➔ "http://localhost:8000/api/users"
|
|
132
|
+
* createBeApiUrl("/v1", { prefix: "/v1" })
|
|
133
|
+
* // ➔ "http://localhost:8000/v1"
|
|
134
|
+
* createBeApiUrl("/v1/users")
|
|
135
|
+
* // ➔ "http://localhost:8000/api/v1/users"
|
|
136
|
+
* createBeApiUrl("/v1/users", { prefix: "/v1" })
|
|
137
|
+
* // ➔ "http://localhost:8000/v1/users"
|
|
138
|
+
* createBeApiUrl("/users", { withOrigin: false })
|
|
139
|
+
* // ➔ "/api/users"
|
|
140
|
+
* createBeApiUrl(null, { withOrigin: false })
|
|
141
|
+
* // ➔ "/api"
|
|
142
|
+
* createBeApiUrl(undefined, { withOrigin: false })
|
|
143
|
+
* // ➔ "/api"
|
|
144
|
+
*/
|
|
145
|
+
declare const createBeApiUrl: (pathname: string | null | undefined, options?: OptionsCreateBeApiUrl) => string;
|
|
152
146
|
type OptionsGetBeApiUrl = {
|
|
153
147
|
/** * ***The Suffix origin base api url, e.g:`http://localhost.com/api`, default: `"/"`.***
|
|
154
|
-
|
|
155
|
-
|
|
148
|
+
*
|
|
149
|
+
* @default "/" */
|
|
156
150
|
suffix?: string;
|
|
157
151
|
};
|
|
158
152
|
/** ---------------------------------------------------
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
153
|
+
* * ***Utility for NextJS: `getBeApiUrl`.***
|
|
154
|
+
* ---------------------------------------------------
|
|
155
|
+
* **This function determines the backend API base URL from the `NEXT_PUBLIC_BACKEND_API_URL` environment variable (retrieves the base API URL of the backend).**
|
|
156
|
+
* - **Behavior:**
|
|
157
|
+
* - If the variable is not set, it defaults to `"http://localhost:8000"`.
|
|
158
|
+
* - It also allows adding an optional suffix to the returned URL.
|
|
159
|
+
* - ***⚠️ Warning:***
|
|
160
|
+
* - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***
|
|
161
|
+
* @description
|
|
162
|
+
* This function determines the backend API base URL from the `NEXT_PUBLIC_BACKEND_API_URL` environment variable.
|
|
163
|
+
* - If `NEXT_PUBLIC_BACKEND_API_URL` is not set, it defaults to `"http://localhost:8000"`.
|
|
164
|
+
* - If `NEXT_PUBLIC_BACKEND_API_URL` does **not** contain a port, it appends one from `NEXT_PUBLIC_PORT_BE` if available.
|
|
165
|
+
* - Supports appending optional suffix (like `"/api"`).
|
|
166
|
+
* @param {OptionsGetBeApiUrl|undefined} options - Configuration options.
|
|
167
|
+
* @param {OptionsGetBeApiUrl["suffix"]} [options.suffix="/"] - The suffix to append to the base API URL.
|
|
168
|
+
* @returns {string} The formatted backend API base URL.
|
|
169
|
+
* @throws **{@link TypeError | `TypeError`}** if `suffix` is not a `string`.
|
|
170
|
+
* @throws **{@link Error | `Error`}** if `NEXT_PUBLIC_BACKEND_API_URL` is invalid.
|
|
171
|
+
* @example
|
|
172
|
+
* // With NEXT_PUBLIC_BACKEND_API_URL set at `*.env` file
|
|
173
|
+
* NEXT_PUBLIC_BACKEND_API_URL = "https://api.example.com";
|
|
174
|
+
* getBeApiUrl();
|
|
175
|
+
* // ➔ "https://api.example.com/"
|
|
176
|
+
*
|
|
177
|
+
* // With NEXT_PUBLIC_BACKEND_API_URL but no port, using NEXT_PUBLIC_PORT_BE at `*.env` file
|
|
178
|
+
* NEXT_PUBLIC_BACKEND_API_URL = "http://localhost";
|
|
179
|
+
* NEXT_PUBLIC_PORT_BE = "5000";
|
|
180
|
+
* getBeApiUrl({ suffix: "/api" });
|
|
181
|
+
* // ➔ "http://localhost:5000/api"
|
|
182
|
+
*
|
|
183
|
+
* // Without NEXT_PUBLIC_BACKEND_API_URL at `*.env` file (defaults to localhost:8000)
|
|
184
|
+
* delete NEXT_PUBLIC_BACKEND_API_URL;
|
|
185
|
+
* getBeApiUrl({ suffix: "/v1" });
|
|
186
|
+
* // ➔ "http://localhost:8000/v1"
|
|
187
|
+
*/
|
|
194
188
|
declare const getBeApiUrl: (options?: OptionsGetBeApiUrl) => string;
|
|
195
189
|
/** ---------------------------------------------------
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
190
|
+
* * ***Utility for NextJS: `getBaseUrl`.***
|
|
191
|
+
* ---------------------------------------------------
|
|
192
|
+
* **Retrieves the base URL of the application.**
|
|
193
|
+
* - **Behavior:**
|
|
194
|
+
* - It determines the base URL from the `NEXT_PUBLIC_BASE_URL` environment variable.
|
|
195
|
+
* - If `NEXT_PUBLIC_BASE_URL` is not set, it defaults to `"http://localhost:3000"`.
|
|
196
|
+
* - If `NEXT_PUBLIC_BASE_URL` does **not** contain a port, it appends one from `NEXT_PUBLIC_PORT_FE` if available.
|
|
197
|
+
* - Ensures the final URL is valid and normalized (no trailing slashes).
|
|
198
|
+
* - ***⚠️ Warning:***
|
|
199
|
+
* - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***
|
|
200
|
+
* @returns {string} The resolved base URL of the application.
|
|
201
|
+
* @throws **{@link Error | `Error`}** if the constructed URL is invalid or malformed.
|
|
202
|
+
* @example
|
|
203
|
+
* // With environment variable set at `*.env` file
|
|
204
|
+
* NEXT_PUBLIC_BASE_URL = "https://example.com";
|
|
205
|
+
* getBaseUrl();
|
|
206
|
+
* // ➔ "https://example.com"
|
|
207
|
+
*
|
|
208
|
+
* // With custom port via NEXT_PUBLIC_PORT_FE at `*.env` file
|
|
209
|
+
* NEXT_PUBLIC_BASE_URL = "http://localhost";
|
|
210
|
+
* NEXT_PUBLIC_PORT_FE = "4000";
|
|
211
|
+
* getBaseUrl();
|
|
212
|
+
* // ➔ "http://localhost:4000"
|
|
213
|
+
*
|
|
214
|
+
* // Without environment variable at `*.env` file
|
|
215
|
+
* delete NEXT_PUBLIC_BASE_URL;
|
|
216
|
+
* getBaseUrl();
|
|
217
|
+
* // ➔ "http://localhost:3000"
|
|
218
|
+
*/
|
|
225
219
|
declare const getBaseUrl: () => string;
|
|
226
220
|
export { ExtractRouteParams, HasDynamicSegments, createBeApiUrl, generateRoute, getBaseUrl, getBeApiUrl };
|
package/dist/next/index.js
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
* ========================================================================
|
|
3
3
|
* @rzl-zone/utils-js
|
|
4
4
|
* ------------------------------------------------------------------------
|
|
5
|
-
* Version: `3.12.1-beta.
|
|
5
|
+
* Version: `3.12.1-beta.1`
|
|
6
6
|
* Author: `Rizalvin Dwiky <rizalvindwiky@gmail.com>`
|
|
7
7
|
* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/utils-js`
|
|
8
8
|
* ========================================================================
|
|
9
9
|
*/
|
|
10
|
-
import { A as isPlainObject, N as isNil, S as isUndefined, T as assertIsPlainObject, b as hasOwnProp, k as isString, p as isNonEmptyArray, r as getPreciseType, t as assertIsBoolean, v as isError, y as isNonEmptyString } from "../assertIsBoolean-
|
|
11
|
-
import { t as assertIsString } from "../assertIsString-
|
|
12
|
-
import { t as safeStableStringify } from "../safeStableStringify-
|
|
13
|
-
import { t as isEmptyString } from "../isEmptyString-
|
|
14
|
-
import { t as removeSpaces } from "../removeSpaces-
|
|
15
|
-
import { n as normalizePathname, t as formatEnvPort } from "../formatEnvPort-
|
|
10
|
+
import { A as isPlainObject, N as isNil, S as isUndefined, T as assertIsPlainObject, b as hasOwnProp, k as isString, p as isNonEmptyArray, r as getPreciseType, t as assertIsBoolean, v as isError, y as isNonEmptyString } from "../assertIsBoolean-DR1SaXPD.js";
|
|
11
|
+
import { t as assertIsString } from "../assertIsString-CEB07_83.js";
|
|
12
|
+
import { t as safeStableStringify } from "../safeStableStringify-CXOZ9Ub8.js";
|
|
13
|
+
import { t as isEmptyString } from "../isEmptyString-BXzKAC2j.js";
|
|
14
|
+
import { t as removeSpaces } from "../removeSpaces-Bmc5DX4F.js";
|
|
15
|
+
import { n as normalizePathname, t as formatEnvPort } from "../formatEnvPort-ByFVLjSV.js";
|
|
16
16
|
function generateRoute(route, params) {
|
|
17
17
|
if (!isString(route) || isEmptyString(route)) throw new TypeError(`❌ 'generateRoute' Failed:\n- Invalid 'route' value.\n- Must be of type \`string\` and non-empty string, but received: "${getPreciseType(route)}": \`${safeStableStringify(route, { keepUndefined: true })}\`.`);
|
|
18
18
|
if (!/[\\[\]]/.test(route)) return route;
|
package/dist/next/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/next/generateRoute.ts","../../src/next/createBeApiUrl.ts","../../src/next/getBeApiUrl.ts","../../src/next/getBaseUrl.ts"],"sourcesContent":["import type { IsAny } from \"@rzl-zone/ts-types-plus\";\n\nimport { isNil } from \"@/predicates/is/isNil\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { isEmptyString } from \"@/predicates/is/isEmptyString\";\nimport { isNonEmptyArray } from \"@/predicates/is/isNonEmptyArray\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\nimport { assertIsPlainObject } from \"@/assertions/objects/assertIsPlainObject\";\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\n/** ---------------------------------------------------------\n * * ***Extracts dynamic route parameters from a given route string.***\n * ---------------------------------------------------------\n * **This utility type recursively searches for dynamic segments within a route,\n * extracting each parameter and constructing an object where each key represents\n * a dynamic segment and its value is of type `string`.**\n * - ***⚠️ Warning:***\n * - ***This types only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @template T - The route string containing potential dynamic segments.\n * @example\n * ```ts\n * type Params1 = ExtractRouteParams<\"/user/[id]\">;\n * // ➔ { id: string }\n * type Params2 = ExtractRouteParams<\"/post/[slug]/comment/[commentId]\">;\n * // ➔ { slug: string; commentId: string }\n * type Params3 = ExtractRouteParams<\"/dashboard\">;\n * // ➔ {} (no dynamic parameters)\n * ```\n */\nexport type ExtractRouteParams<T> = T extends string\n ? HasDynamicSegments<T> extends true\n ? T extends `${infer _Start}[${infer Param}]${infer Rest}`\n ? { [K in Param | keyof ExtractRouteParams<Rest>]: string }\n : unknown\n : unknown\n : unknown; // Ensures an empty object if no dynamic segments are found.\n\n/** ---------------------------------------------------------\n * * ***Determines whether a given route contains dynamic segments.***\n * ---------------------------------------------------------\n * **This type checks if the route includes at least one `[param]` pattern.\n * If it does, the result is `true`, otherwise `false`.**\n * - ***⚠️ Warning:***\n * - ***This types only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @template T - The route string to be evaluated.\n * @example\n * ```ts\n * type HasParams1 = HasDynamicSegments<\"/user/[id]\">;\n * // ➔ true\n * type HasParams2 = HasDynamicSegments<\"/settings/profile\">;\n * // ➔ false\n * type HasParams3 = HasDynamicSegments<\"/blog/[category]/[slug]\">;\n * // ➔ true\n * ```\n */\nexport type HasDynamicSegments<T> = T extends `${string}[${string}]${string}`\n ? true\n : false;\n\ntype GenerateRouteResult<T> =\n true extends IsAny<T> ? unknown : T extends string ? string : unknown;\n\n/** ---------------------------------\n * * ***Utility for NextJS: `generateRoute`.***\n * ---------------------------------\n * **Generates a URL by replacing dynamic route parameters with provided values.**\n * - ***⚠️ Warning:***\n * - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @template T - The route string containing dynamic segments in the format `[param]`.\n * @param {T} route - The route string containing dynamic segments.\n * @param {ExtractRouteParams<T>} [params] - An object containing key-value pairs that match the dynamic segments in the route.\n * @returns {string} The formatted URL with all dynamic segments replaced.\n * @throws **{@link Error | `Error`}** if the route contains dynamic segments but no parameters object is provided.\n * @throws **{@link Error | `Error`}** if a required parameter is missing from the `params` object.\n * @throws **{@link Error | `Error`}** if a parameter value is an empty string.\n * @throws **{@link Error | `Error`}** if any parameter contains invalid characters like `?`, `&`, `=`, `#`, `/`, spaces, `'`, `\"`, `(`, `)`, `+`, `;`, `%`, `@`, or `:`, which can cause URL issues.\n * @example\n * // Basic usage\n * generateRoute(\"/user/[id]\", { id: \"123\" });\n * // ➔ \"/user/123\"\n *\n * // No dynamic segments, returns as-is\n * generateRoute(\"/dashboard\");\n * // ➔ \"/dashboard\"\n *\n * // Throws an error due to missing parameters object\n * generateRoute(\"/profile/[username]\");\n * // ➔ ❌ Error: ❌ Missing parameters object for route: \"/profile/[username]\"\n *\n * // Throws an error due to an empty parameter value\n * generateRoute(\"/post/[category]/[slug]\", { category: \"tech\", slug: \"\" });\n * // ➔ ❌ Error: ❌ Parameter \"slug\" cannot be empty in route: \"/post/[category]/[slug]\"\n *\n * // Throws an error due to parameter containing invalid characters\n * generateRoute(\"/search/[query]\", { query: \"how to?learn\" });\n * // ➔ ❌ Error: ❌ Parameter \"query\" contains invalid character \"?\" in route: \"/search/[query]\"\n *\n * // Handles leading/trailing slashes correctly\n * generateRoute(\"/blog/[category]/[slug]\", { category: \"/news/\", slug: \"/latest-update/\" });\n * // ➔ ❌ Error: ❌ Parameter \"category\" and \"slug\" contains slashes \"/\" which is not allowed.\n */\nexport function generateRoute<T extends string>(\n route: T extends string\n ? HasDynamicSegments<T> extends true\n ? T\n : never\n : never,\n params: T extends string ? ExtractRouteParams<T> : undefined\n): GenerateRouteResult<T>;\nexport function generateRoute<T extends string>(\n route: T extends string ? T : never,\n params?: Extract<ExtractRouteParams<T>, Record<string, unknown>>\n): GenerateRouteResult<T>;\nexport function generateRoute<T = unknown>(\n route: T extends string\n ? HasDynamicSegments<T> extends true\n ? T\n : unknown\n : unknown,\n params?: T extends string ? ExtractRouteParams<T> : undefined\n): unknown;\nexport function generateRoute<T>(\n route: T,\n params?: ExtractRouteParams<T>\n): string | unknown {\n //todo: Validate the route string\n if (!isString(route) || isEmptyString(route)) {\n throw new TypeError(\n `❌ 'generateRoute' Failed:\\n- Invalid 'route' value.\\n- Must be of type \\`string\\` and non-empty string, but received: \"${getPreciseType(\n route\n )}\": \\`${safeStableStringify(route, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n //todo: If no dynamic segments exist, return the route as-is immediately\n if (!/[\\\\[\\]]/.test(route)) {\n return route;\n }\n\n //todo: Validate that params is a plain object\n assertIsPlainObject(params, {\n message: ({ validType }) =>\n `❌ 'generateRoute' Failed cause in route \"${route}\":\\n- Missing or invalid parameters \\`${validType}\\` for route: \"${route}\", must be of type \\`${validType}\\` mapping parameters.`\n });\n\n //todo: Ensure parameters are provided for dynamic routes.\n if (isNil(params)) {\n throw new TypeError(\n `❌ 'generateRoute' Failed cause in route \"${route}\":\\n- Missing parameters \\`plain-object\\` for route: \"${route}\".`\n );\n }\n\n //todo: Check for invalid characters that can break the URL format\n const invalidChars = [\n \"?\",\n \"&\",\n \"#\",\n \"=\",\n \"/\",\n // \"`\",\n // \" \",\n // \".\",\n \"'\",\n // eslint-disable-next-line quotes\n '\"',\n \"(\",\n \")\",\n \"+\",\n \";\",\n \"%\",\n \"@\",\n \":\"\n ];\n\n const errors: string[] = [];\n\n const requiredKeys = Array.from(route.matchAll(/\\[(\\w+)\\]/g)).map(\n (m) => m[1] || \"\"\n );\n\n for (const key of requiredKeys) {\n const value = params[key];\n\n if (!isString(value)) {\n errors.push(\n `- Invalid parameter: \"${key}\" must be of type \\`string\\`, but received: \\`${getPreciseType(\n value\n )}\\`.`\n );\n continue;\n }\n\n if (isEmptyString(value)) {\n errors.push(`- Parameter \"${key}\" cannot be empty string.`);\n continue;\n }\n\n const foundInvalidChars = invalidChars.filter((char) =>\n value.includes(char)\n );\n\n if (/\\s/.test(value)) {\n foundInvalidChars.push(\"white-space(s)\");\n }\n\n if (foundInvalidChars.length > 0) {\n const formattedChars = foundInvalidChars.map((c) =>\n c === \"`\" ? \"backtick - (`)\" : `\\`${c}\\``\n );\n\n if (!invalidChars.includes(\"white-space(s)\"))\n invalidChars.push(\"white-space(s)\");\n\n const formattedInvalidChars = invalidChars.map((c) =>\n c === \"`\" ? \"backtick - (`)\" : `\\`${c}\\``\n );\n\n errors.push(\n `- Parameter \"${key}\" contains invalid characters (${formattedChars.join(\n \", \"\n )}). These characters are not allowed because they could cause issues in URL structure. The following characters are forbidden in route parameters: (${formattedInvalidChars.join(\n \", \"\n )}).`\n );\n }\n }\n\n if (isNonEmptyArray(errors)) {\n throw new Error(\n `❌ 'generateRoute' Failed cause in route \"${route}\":\\n${errors.join(\"\\n\")}.`\n );\n }\n\n return route\n .replace(/\\[(\\w+)\\]/g, (_, key) => {\n const paramKey = isNonEmptyString(params[key]) ? params[key] : \"\";\n\n return paramKey.trim().replace(/^\\/+|\\/+$/g, \"\");\n })\n .replace(/\\/+/g, \"/\");\n}\n","import { getBeApiUrl } from \"@/next\";\nimport { normalizePathname } from \"@/urls/pathname/normalizePathname\";\n\nimport { isNil } from \"@/predicates/is/isNil\";\nimport { isError } from \"@/predicates/is/isError\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { isUndefined } from \"@/predicates/is/isUndefined\";\nimport { isPlainObject } from \"@/predicates/is/isPlainObject\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { assertIsString } from \"@/assertions/strings/assertIsString\";\nimport { assertIsBoolean } from \"@/assertions/booleans/assertIsBoolean\";\n\ntype OptionsCreateBeApiUrl = {\n /** * The prefix pathname api url, e.g:`\"http://localhost.com/your-target-prefix-entri-point-api-is-here\"`, default: `\"/api\"`.\n *\n * @default \"/api\" */\n prefix?: string;\n /** * Option to getting `prefix` and `pathname` of api url only `(removing origin base api url)`, default: `true`.\n *\n * @default true */\n withOrigin?: boolean;\n};\n\n/** ---------------------------------\n * * ***Utility for NextJS: `createBeApiUrl`.***\n * ---------------------------------\n * **Constructs a backend API URL by appending a given pathname to the base API URL.**\n * - **ℹ️ Note:**\n * - This function builds on top of `getBeApiUrl()`.\n * - **Determines the base API URL from:**\n * - `NEXT_PUBLIC_BACKEND_API_URL` environment variable (or defaults to `\"http://localhost:8000\"`).\n * - Automatically appends `NEXT_PUBLIC_PORT_BE` if the base URL does not already include a port.\n * - **Features of this function:**\n * - Allows customizing the API path with an optional `prefix` (defaults to `\"/api\"`).\n * - Can include or exclude the origin (protocol + host) via `withOrigin`.\n * - Normalizes paths to avoid duplicate slashes.\n * - ***⚠️ Warning:***\n * - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @param {string|null|undefined} pathname - The API endpoint path (e.g., `/users` or `/v1/posts`), defaultValue: `\"\"`.\n * @param {OptionsCreateBeApiUrl} [options] - Configuration options.\n * @param {OptionsCreateBeApiUrl[\"prefix\"]} [options.prefix=\"/api\"] - The prefix for the API path (default is `\"/api\"`).\n * @param {OptionsCreateBeApiUrl[\"withOrigin\"]} [options.withOrigin=true] - Whether to include the full base URL or return only the API path.\n * @returns {string} The formatted API URL.\n * @throws **{@link TypeError | `TypeError`}** if `withOrigin` is not a boolean.\n * @throws **{@link TypeError | `TypeError`}** if `prefix` and `pathname` is not a string.\n * @throws **{@link Error | `Error`}** if constructing the API URL fails due to an invalid base URL.\n * @example\n * createBeApiUrl(\"/users\")\n * // ➔ \"http://localhost:8000/api/users\"\n * createBeApiUrl(\"/api/users\")\n * // ➔ \"http://localhost:8000/api/users\"\n * createBeApiUrl(\"/v1\", { prefix: \"/v1\" })\n * // ➔ \"http://localhost:8000/v1\"\n * createBeApiUrl(\"/v1/users\")\n * // ➔ \"http://localhost:8000/api/v1/users\"\n * createBeApiUrl(\"/v1/users\", { prefix: \"/v1\" })\n * // ➔ \"http://localhost:8000/v1/users\"\n * createBeApiUrl(\"/users\", { withOrigin: false })\n * // ➔ \"/api/users\"\n * createBeApiUrl(null, { withOrigin: false })\n * // ➔ \"/api\"\n * createBeApiUrl(undefined, { withOrigin: false })\n * // ➔ \"/api\"\n */\nexport const createBeApiUrl = (\n /** * The pathname api url, e.g:`\"http://localhost.com/your-target-prefix-entri-point-api-is-here/your-target-pathname-is-here\"`.\n *\n * @default \"\"\n */\n pathname: string | null | undefined,\n options: OptionsCreateBeApiUrl = {}\n): string => {\n try {\n // ✅ Type checks\n assertIsString(isNil(pathname) ? \"\" : pathname, {\n message({ currentType, validType }) {\n return `First parameter (\\`pathname\\`) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n\n if (!isPlainObject(options)) {\n options = {};\n }\n\n let { prefix = \"/api\", withOrigin = true } = options;\n\n if (!isUndefined(prefix) && !isString(prefix)) {\n throw new TypeError(\n `Parameter \\`prefix\\` property of the \\`options\\` (second parameter) must be of type \\`string\\`, but received: \\`${getPreciseType(\n prefix\n )}\\`.`\n );\n }\n\n assertIsBoolean(withOrigin, {\n message: ({ currentType, validType }) =>\n `Parameter \\`withOrigin\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\n });\n\n // Normalize pathname\n pathname = normalizePathname(pathname);\n // Normalize prefix\n prefix = normalizePathname(prefix);\n\n const normalizedPrefix = prefix.endsWith(\"/\") ? prefix : prefix + \"/\";\n\n // Remove duplicate prefix in pathname\n if (\n pathname === prefix ||\n pathname === prefix + \"/\" ||\n pathname.startsWith(normalizedPrefix)\n ) {\n pathname = pathname.slice(prefix.length);\n pathname = normalizePathname(pathname);\n }\n\n // Get the base API URL\n const baseApiUrl = getBeApiUrl({ suffix: prefix });\n\n function joinPath(a: string, b: string) {\n return `${a.replace(/\\/+$/, \"\")}/${b.replace(/^\\/+/, \"\")}`;\n }\n\n const fullPath = withOrigin\n ? joinPath(baseApiUrl, pathname)\n : joinPath(new URL(baseApiUrl).pathname, pathname);\n\n return fullPath.replace(/\\/+$/, \"\");\n } catch (err) {\n if (isError(err)) {\n throw err;\n } else {\n throw new Error(\n \"Failed to generate backend API URL in `createBeApiUrl()`, Error: \" +\n String(err).trim(),\n { cause: err }\n );\n }\n\n // if (isError(err)) {\n // throw err;\n // } else\n // throw new Error(\n // \"Failed to generate backend API URL in `createBeApiUrl()`, Error: \" +\n // new Error(String(err)).message.trim()\n // );\n }\n};\n","import { formatEnvPort } from \"@/urls/utils/formatEnvPort\";\nimport { hasOwnProp } from \"@/predicates/has/hasOwnProp\";\nimport { isPlainObject } from \"@/predicates/is/isPlainObject\";\nimport { removeSpaces } from \"@/strings/sanitizations/removeSpaces\";\nimport { assertIsString } from \"@/assertions/strings/assertIsString\";\n\ntype OptionsGetBeApiUrl = {\n /** * ***The Suffix origin base api url, e.g:`http://localhost.com/api`, default: `\"/\"`.***\n *\n * @default \"/\" */\n suffix?: string;\n};\n\n/** ---------------------------------------------------\n * * ***Utility for NextJS: `getBeApiUrl`.***\n * ---------------------------------------------------\n * **This function determines the backend API base URL from the `NEXT_PUBLIC_BACKEND_API_URL` environment variable (retrieves the base API URL of the backend).**\n * - **Behavior:**\n * - If the variable is not set, it defaults to `\"http://localhost:8000\"`.\n * - It also allows adding an optional suffix to the returned URL.\n * - ***⚠️ Warning:***\n * - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @description\n * This function determines the backend API base URL from the `NEXT_PUBLIC_BACKEND_API_URL` environment variable.\n * - If `NEXT_PUBLIC_BACKEND_API_URL` is not set, it defaults to `\"http://localhost:8000\"`.\n * - If `NEXT_PUBLIC_BACKEND_API_URL` does **not** contain a port, it appends one from `NEXT_PUBLIC_PORT_BE` if available.\n * - Supports appending optional suffix (like `\"/api\"`).\n * @param {OptionsGetBeApiUrl|undefined} options - Configuration options.\n * @param {OptionsGetBeApiUrl[\"suffix\"]} [options.suffix=\"/\"] - The suffix to append to the base API URL.\n * @returns {string} The formatted backend API base URL.\n * @throws **{@link TypeError | `TypeError`}** if `suffix` is not a `string`.\n * @throws **{@link Error | `Error`}** if `NEXT_PUBLIC_BACKEND_API_URL` is invalid.\n * @example\n * // With NEXT_PUBLIC_BACKEND_API_URL set at `*.env` file\n * NEXT_PUBLIC_BACKEND_API_URL = \"https://api.example.com\";\n * getBeApiUrl();\n * // ➔ \"https://api.example.com/\"\n *\n * // With NEXT_PUBLIC_BACKEND_API_URL but no port, using NEXT_PUBLIC_PORT_BE at `*.env` file\n * NEXT_PUBLIC_BACKEND_API_URL = \"http://localhost\";\n * NEXT_PUBLIC_PORT_BE = \"5000\";\n * getBeApiUrl({ suffix: \"/api\" });\n * // ➔ \"http://localhost:5000/api\"\n *\n * // Without NEXT_PUBLIC_BACKEND_API_URL at `*.env` file (defaults to localhost:8000)\n * delete NEXT_PUBLIC_BACKEND_API_URL;\n * getBeApiUrl({ suffix: \"/v1\" });\n * // ➔ \"http://localhost:8000/v1\"\n */\nexport const getBeApiUrl = (options: OptionsGetBeApiUrl = {}): string => {\n if (!isPlainObject(options)) options = {};\n\n let suffix = hasOwnProp(options, \"suffix\") ? options.suffix : \"/\";\n\n // Ensure suffix is a string\n assertIsString(suffix, {\n message({ currentType, validType }) {\n return `Parameter \\`suffix\\` property of the first parameter must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n\n try {\n let rawBaseUrl = process.env.NEXT_PUBLIC_BACKEND_API_URL?.trim();\n\n if (rawBaseUrl) {\n rawBaseUrl = removeSpaces(rawBaseUrl);\n // const hasPort = /:\\/\\/[^/]+:\\d+/.test(rawBaseUrl);\n const urlObj = new URL(rawBaseUrl);\n const hasPort = !!urlObj.port;\n\n if (!hasPort && process.env.NEXT_PUBLIC_PORT_BE) {\n rawBaseUrl =\n urlObj.origin +\n formatEnvPort(process.env.NEXT_PUBLIC_PORT_BE, {\n prefixColon: true\n });\n }\n } else {\n // fallback\n rawBaseUrl =\n \"http://localhost\" +\n formatEnvPort(process.env.NEXT_PUBLIC_PORT_BE || \"8000\", {\n prefixColon: true\n });\n }\n\n suffix = removeSpaces(suffix).length ? removeSpaces(suffix) : \"/\";\n const baseApiUrl = new URL(rawBaseUrl.replace(/\\/+$/, \"\")).origin;\n\n const finalSuffix =\n suffix === \"/\"\n ? \"/\"\n : `${suffix.startsWith(\"/\") ? \"\" : \"/\"}${suffix.replace(/\\/+$/, \"\")}`;\n\n return `${baseApiUrl}${finalSuffix}`;\n } catch (error) {\n throw new Error(\n \"Invalid `NEXT_PUBLIC_BACKEND_API_URL`, failed to generate from `getBeApiUrl()`, Error:\" +\n error,\n { cause: error }\n );\n }\n};\n","import { formatEnvPort } from \"@/urls/utils/formatEnvPort\";\nimport { removeSpaces } from \"@/strings/sanitizations/removeSpaces\";\n\n/** ---------------------------------------------------\n * * ***Utility for NextJS: `getBaseUrl`.***\n * ---------------------------------------------------\n * **Retrieves the base URL of the application.**\n * - **Behavior:**\n * - It determines the base URL from the `NEXT_PUBLIC_BASE_URL` environment variable.\n * - If `NEXT_PUBLIC_BASE_URL` is not set, it defaults to `\"http://localhost:3000\"`.\n * - If `NEXT_PUBLIC_BASE_URL` does **not** contain a port, it appends one from `NEXT_PUBLIC_PORT_FE` if available.\n * - Ensures the final URL is valid and normalized (no trailing slashes).\n * - ***⚠️ Warning:***\n * - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @returns {string} The resolved base URL of the application.\n * @throws **{@link Error | `Error`}** if the constructed URL is invalid or malformed.\n * @example\n * // With environment variable set at `*.env` file\n * NEXT_PUBLIC_BASE_URL = \"https://example.com\";\n * getBaseUrl();\n * // ➔ \"https://example.com\"\n *\n * // With custom port via NEXT_PUBLIC_PORT_FE at `*.env` file\n * NEXT_PUBLIC_BASE_URL = \"http://localhost\";\n * NEXT_PUBLIC_PORT_FE = \"4000\";\n * getBaseUrl();\n * // ➔ \"http://localhost:4000\"\n *\n * // Without environment variable at `*.env` file\n * delete NEXT_PUBLIC_BASE_URL;\n * getBaseUrl();\n * // ➔ \"http://localhost:3000\"\n */\nexport const getBaseUrl = (): string => {\n try {\n const baseEnv = process.env.NEXT_PUBLIC_BASE_URL?.trim();\n const portEnv = process.env.NEXT_PUBLIC_PORT_FE?.trim();\n\n let baseUrl = baseEnv || \"http://localhost\";\n\n // Always clean trailing slashes first\n baseUrl = removeSpaces(baseUrl).replace(/\\/+$/, \"\");\n\n // Check if already contains port\n const hasPort = /:\\/\\/[^/]+:\\d+/.test(baseUrl);\n\n if (!hasPort && portEnv) {\n baseUrl += formatEnvPort(portEnv, { prefixColon: true });\n } else if (!hasPort && !baseEnv) {\n baseUrl += \":3000\";\n }\n\n const url = new URL(baseUrl);\n return `${url.protocol}//${url.hostname}${url.port ? `:${url.port}` : \"\"}`;\n } catch (error) {\n throw new Error(\n \"Invalid `NEXT_PUBLIC_BASE_URL`, failed to generate from `getBaseUrl()`, Error:\" +\n error,\n { cause: error }\n );\n }\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/next/generateRoute.ts","../../src/next/createBeApiUrl.ts","../../src/next/getBeApiUrl.ts","../../src/next/getBaseUrl.ts"],"sourcesContent":["import type { IsAny } from \"@rzl-zone/ts-types-plus\";\n\nimport { isNil } from \"@/predicates/is/isNil\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { isEmptyString } from \"@/predicates/is/isEmptyString\";\nimport { isNonEmptyArray } from \"@/predicates/is/isNonEmptyArray\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\nimport { assertIsPlainObject } from \"@/assertions/objects/assertIsPlainObject\";\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\n/** ---------------------------------------------------------\n * * ***Extracts dynamic route parameters from a given route string.***\n * ---------------------------------------------------------\n * **This utility type recursively searches for dynamic segments within a route,\n * extracting each parameter and constructing an object where each key represents\n * a dynamic segment and its value is of type `string`.**\n * - ***⚠️ Warning:***\n * - ***This types only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @template T - The route string containing potential dynamic segments.\n * @example\n * ```ts\n * type Params1 = ExtractRouteParams<\"/user/[id]\">;\n * // ➔ { id: string }\n * type Params2 = ExtractRouteParams<\"/post/[slug]/comment/[commentId]\">;\n * // ➔ { slug: string; commentId: string }\n * type Params3 = ExtractRouteParams<\"/dashboard\">;\n * // ➔ {} (no dynamic parameters)\n * ```\n */\nexport type ExtractRouteParams<T> = T extends string\n ? HasDynamicSegments<T> extends true\n ? T extends `${infer _Start}[${infer Param}]${infer Rest}`\n ? { [K in Param | keyof ExtractRouteParams<Rest>]: string }\n : unknown\n : unknown\n : unknown; // Ensures an empty object if no dynamic segments are found.\n\n/** ---------------------------------------------------------\n * * ***Determines whether a given route contains dynamic segments.***\n * ---------------------------------------------------------\n * **This type checks if the route includes at least one `[param]` pattern.\n * If it does, the result is `true`, otherwise `false`.**\n * - ***⚠️ Warning:***\n * - ***This types only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @template T - The route string to be evaluated.\n * @example\n * ```ts\n * type HasParams1 = HasDynamicSegments<\"/user/[id]\">;\n * // ➔ true\n * type HasParams2 = HasDynamicSegments<\"/settings/profile\">;\n * // ➔ false\n * type HasParams3 = HasDynamicSegments<\"/blog/[category]/[slug]\">;\n * // ➔ true\n * ```\n */\nexport type HasDynamicSegments<T> = T extends `${string}[${string}]${string}`\n ? true\n : false;\n\ntype GenerateRouteResult<T> =\n true extends IsAny<T> ? unknown : T extends string ? string : unknown;\n\n/** ---------------------------------\n * * ***Utility for NextJS: `generateRoute`.***\n * ---------------------------------\n * **Generates a URL by replacing dynamic route parameters with provided values.**\n * - ***⚠️ Warning:***\n * - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @template T - The route string containing dynamic segments in the format `[param]`.\n * @param {T} route - The route string containing dynamic segments.\n * @param {ExtractRouteParams<T>} [params] - An object containing key-value pairs that match the dynamic segments in the route.\n * @returns {string} The formatted URL with all dynamic segments replaced.\n * @throws **{@link Error | `Error`}** if the route contains dynamic segments but no parameters object is provided.\n * @throws **{@link Error | `Error`}** if a required parameter is missing from the `params` object.\n * @throws **{@link Error | `Error`}** if a parameter value is an empty string.\n * @throws **{@link Error | `Error`}** if any parameter contains invalid characters like `?`, `&`, `=`, `#`, `/`, spaces, `'`, `\"`, `(`, `)`, `+`, `;`, `%`, `@`, or `:`, which can cause URL issues.\n * @example\n * // Basic usage\n * generateRoute(\"/user/[id]\", { id: \"123\" });\n * // ➔ \"/user/123\"\n *\n * // No dynamic segments, returns as-is\n * generateRoute(\"/dashboard\");\n * // ➔ \"/dashboard\"\n *\n * // Throws an error due to missing parameters object\n * generateRoute(\"/profile/[username]\");\n * // ➔ ❌ Error: ❌ Missing parameters object for route: \"/profile/[username]\"\n *\n * // Throws an error due to an empty parameter value\n * generateRoute(\"/post/[category]/[slug]\", { category: \"tech\", slug: \"\" });\n * // ➔ ❌ Error: ❌ Parameter \"slug\" cannot be empty in route: \"/post/[category]/[slug]\"\n *\n * // Throws an error due to parameter containing invalid characters\n * generateRoute(\"/search/[query]\", { query: \"how to?learn\" });\n * // ➔ ❌ Error: ❌ Parameter \"query\" contains invalid character \"?\" in route: \"/search/[query]\"\n *\n * // Handles leading/trailing slashes correctly\n * generateRoute(\"/blog/[category]/[slug]\", { category: \"/news/\", slug: \"/latest-update/\" });\n * // ➔ ❌ Error: ❌ Parameter \"category\" and \"slug\" contains slashes \"/\" which is not allowed.\n */\nexport function generateRoute<T extends string>(\n route: T extends string\n ? HasDynamicSegments<T> extends true\n ? T\n : never\n : never,\n params: T extends string ? ExtractRouteParams<T> : undefined\n): GenerateRouteResult<T>;\nexport function generateRoute<T extends string>(\n route: T extends string ? T : never,\n params?: Extract<ExtractRouteParams<T>, Record<string, unknown>>\n): GenerateRouteResult<T>;\nexport function generateRoute<T = unknown>(\n route: T extends string\n ? HasDynamicSegments<T> extends true\n ? T\n : unknown\n : unknown,\n params?: T extends string ? ExtractRouteParams<T> : undefined\n): unknown;\nexport function generateRoute<T>(\n route: T,\n params?: ExtractRouteParams<T>\n): string | unknown {\n //todo: Validate the route string\n if (!isString(route) || isEmptyString(route)) {\n throw new TypeError(\n `❌ 'generateRoute' Failed:\\n- Invalid 'route' value.\\n- Must be of type \\`string\\` and non-empty string, but received: \"${getPreciseType(\n route\n )}\": \\`${safeStableStringify(route, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n //todo: If no dynamic segments exist, return the route as-is immediately\n if (!/[\\\\[\\]]/.test(route)) {\n return route;\n }\n\n //todo: Validate that params is a plain object\n assertIsPlainObject(params, {\n message: ({ validType }) =>\n `❌ 'generateRoute' Failed cause in route \"${route}\":\\n- Missing or invalid parameters \\`${validType}\\` for route: \"${route}\", must be of type \\`${validType}\\` mapping parameters.`\n });\n\n //todo: Ensure parameters are provided for dynamic routes.\n if (isNil(params)) {\n throw new TypeError(\n `❌ 'generateRoute' Failed cause in route \"${route}\":\\n- Missing parameters \\`plain-object\\` for route: \"${route}\".`\n );\n }\n\n //todo: Check for invalid characters that can break the URL format\n const invalidChars = [\n \"?\",\n \"&\",\n \"#\",\n \"=\",\n \"/\",\n \"'\",\n // eslint-disable-next-line quotes\n '\"',\n \"(\",\n \")\",\n \"+\",\n \";\",\n \"%\",\n \"@\",\n \":\"\n ];\n\n const errors: string[] = [];\n\n const requiredKeys = Array.from(route.matchAll(/\\[(\\w+)\\]/g)).map(\n (m) => m[1] || \"\"\n );\n\n for (const key of requiredKeys) {\n const value = params[key];\n\n if (!isString(value)) {\n errors.push(\n `- Invalid parameter: \"${key}\" must be of type \\`string\\`, but received: \\`${getPreciseType(\n value\n )}\\`.`\n );\n continue;\n }\n\n if (isEmptyString(value)) {\n errors.push(`- Parameter \"${key}\" cannot be empty string.`);\n continue;\n }\n\n const foundInvalidChars = invalidChars.filter((char) =>\n value.includes(char)\n );\n\n if (/\\s/.test(value)) {\n foundInvalidChars.push(\"white-space(s)\");\n }\n\n if (foundInvalidChars.length > 0) {\n const formattedChars = foundInvalidChars.map((c) =>\n c === \"`\" ? \"backtick - (`)\" : `\\`${c}\\``\n );\n\n if (!invalidChars.includes(\"white-space(s)\"))\n invalidChars.push(\"white-space(s)\");\n\n const formattedInvalidChars = invalidChars.map((c) =>\n c === \"`\" ? \"backtick - (`)\" : `\\`${c}\\``\n );\n\n errors.push(\n `- Parameter \"${key}\" contains invalid characters (${formattedChars.join(\n \", \"\n )}). These characters are not allowed because they could cause issues in URL structure. The following characters are forbidden in route parameters: (${formattedInvalidChars.join(\n \", \"\n )}).`\n );\n }\n }\n\n if (isNonEmptyArray(errors)) {\n throw new Error(\n `❌ 'generateRoute' Failed cause in route \"${route}\":\\n${errors.join(\"\\n\")}.`\n );\n }\n\n return route\n .replace(/\\[(\\w+)\\]/g, (_, key) => {\n const paramKey = isNonEmptyString(params[key]) ? params[key] : \"\";\n\n return paramKey.trim().replace(/^\\/+|\\/+$/g, \"\");\n })\n .replace(/\\/+/g, \"/\");\n}\n","import { getBeApiUrl } from \"@/next\";\nimport { normalizePathname } from \"@/urls/pathname/normalizePathname\";\n\nimport { isNil } from \"@/predicates/is/isNil\";\nimport { isError } from \"@/predicates/is/isError\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { isUndefined } from \"@/predicates/is/isUndefined\";\nimport { isPlainObject } from \"@/predicates/is/isPlainObject\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { assertIsString } from \"@/assertions/strings/assertIsString\";\nimport { assertIsBoolean } from \"@/assertions/booleans/assertIsBoolean\";\n\ntype OptionsCreateBeApiUrl = {\n /** * The prefix pathname api url, e.g:`\"http://localhost.com/your-target-prefix-entri-point-api-is-here\"`, default: `\"/api\"`.\n *\n * @default \"/api\" */\n prefix?: string;\n /** * Option to getting `prefix` and `pathname` of api url only `(removing origin base api url)`, default: `true`.\n *\n * @default true */\n withOrigin?: boolean;\n};\n\n/** ---------------------------------\n * * ***Utility for NextJS: `createBeApiUrl`.***\n * ---------------------------------\n * **Constructs a backend API URL by appending a given pathname to the base API URL.**\n * - **ℹ️ Note:**\n * - This function builds on top of `getBeApiUrl()`.\n * - **Determines the base API URL from:**\n * - `NEXT_PUBLIC_BACKEND_API_URL` environment variable (or defaults to `\"http://localhost:8000\"`).\n * - Automatically appends `NEXT_PUBLIC_PORT_BE` if the base URL does not already include a port.\n * - **Features of this function:**\n * - Allows customizing the API path with an optional `prefix` (defaults to `\"/api\"`).\n * - Can include or exclude the origin (protocol + host) via `withOrigin`.\n * - Normalizes paths to avoid duplicate slashes.\n * - ***⚠️ Warning:***\n * - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @param {string|null|undefined} pathname - The API endpoint path (e.g., `/users` or `/v1/posts`), defaultValue: `\"\"`.\n * @param {OptionsCreateBeApiUrl} [options] - Configuration options.\n * @param {OptionsCreateBeApiUrl[\"prefix\"]} [options.prefix=\"/api\"] - The prefix for the API path (default is `\"/api\"`).\n * @param {OptionsCreateBeApiUrl[\"withOrigin\"]} [options.withOrigin=true] - Whether to include the full base URL or return only the API path.\n * @returns {string} The formatted API URL.\n * @throws **{@link TypeError | `TypeError`}** if `withOrigin` is not a boolean.\n * @throws **{@link TypeError | `TypeError`}** if `prefix` and `pathname` is not a string.\n * @throws **{@link Error | `Error`}** if constructing the API URL fails due to an invalid base URL.\n * @example\n * createBeApiUrl(\"/users\")\n * // ➔ \"http://localhost:8000/api/users\"\n * createBeApiUrl(\"/api/users\")\n * // ➔ \"http://localhost:8000/api/users\"\n * createBeApiUrl(\"/v1\", { prefix: \"/v1\" })\n * // ➔ \"http://localhost:8000/v1\"\n * createBeApiUrl(\"/v1/users\")\n * // ➔ \"http://localhost:8000/api/v1/users\"\n * createBeApiUrl(\"/v1/users\", { prefix: \"/v1\" })\n * // ➔ \"http://localhost:8000/v1/users\"\n * createBeApiUrl(\"/users\", { withOrigin: false })\n * // ➔ \"/api/users\"\n * createBeApiUrl(null, { withOrigin: false })\n * // ➔ \"/api\"\n * createBeApiUrl(undefined, { withOrigin: false })\n * // ➔ \"/api\"\n */\nexport const createBeApiUrl = (\n /** * The pathname api url, e.g:`\"http://localhost.com/your-target-prefix-entri-point-api-is-here/your-target-pathname-is-here\"`.\n *\n * @default \"\"\n */\n pathname: string | null | undefined,\n options: OptionsCreateBeApiUrl = {}\n): string => {\n try {\n // ✅ Type checks\n assertIsString(isNil(pathname) ? \"\" : pathname, {\n message({ currentType, validType }) {\n return `First parameter (\\`pathname\\`) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n\n if (!isPlainObject(options)) {\n options = {};\n }\n\n let { prefix = \"/api\", withOrigin = true } = options;\n\n if (!isUndefined(prefix) && !isString(prefix)) {\n throw new TypeError(\n `Parameter \\`prefix\\` property of the \\`options\\` (second parameter) must be of type \\`string\\`, but received: \\`${getPreciseType(\n prefix\n )}\\`.`\n );\n }\n\n assertIsBoolean(withOrigin, {\n message: ({ currentType, validType }) =>\n `Parameter \\`withOrigin\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\n });\n\n // Normalize pathname\n pathname = normalizePathname(pathname);\n // Normalize prefix\n prefix = normalizePathname(prefix);\n\n const normalizedPrefix = prefix.endsWith(\"/\") ? prefix : prefix + \"/\";\n\n // Remove duplicate prefix in pathname\n if (\n pathname === prefix ||\n pathname === prefix + \"/\" ||\n pathname.startsWith(normalizedPrefix)\n ) {\n pathname = pathname.slice(prefix.length);\n pathname = normalizePathname(pathname);\n }\n\n // Get the base API URL\n const baseApiUrl = getBeApiUrl({ suffix: prefix });\n\n function joinPath(a: string, b: string) {\n return `${a.replace(/\\/+$/, \"\")}/${b.replace(/^\\/+/, \"\")}`;\n }\n\n const fullPath = withOrigin\n ? joinPath(baseApiUrl, pathname)\n : joinPath(new URL(baseApiUrl).pathname, pathname);\n\n return fullPath.replace(/\\/+$/, \"\");\n } catch (err) {\n if (isError(err)) {\n throw err;\n } else {\n throw new Error(\n \"Failed to generate backend API URL in `createBeApiUrl()`, Error: \" +\n String(err).trim(),\n { cause: err }\n );\n }\n }\n};\n","import { formatEnvPort } from \"@/urls/utils/formatEnvPort\";\nimport { hasOwnProp } from \"@/predicates/has/hasOwnProp\";\nimport { isPlainObject } from \"@/predicates/is/isPlainObject\";\nimport { removeSpaces } from \"@/strings/sanitizations/removeSpaces\";\nimport { assertIsString } from \"@/assertions/strings/assertIsString\";\n\ntype OptionsGetBeApiUrl = {\n /** * ***The Suffix origin base api url, e.g:`http://localhost.com/api`, default: `\"/\"`.***\n *\n * @default \"/\" */\n suffix?: string;\n};\n\n/** ---------------------------------------------------\n * * ***Utility for NextJS: `getBeApiUrl`.***\n * ---------------------------------------------------\n * **This function determines the backend API base URL from the `NEXT_PUBLIC_BACKEND_API_URL` environment variable (retrieves the base API URL of the backend).**\n * - **Behavior:**\n * - If the variable is not set, it defaults to `\"http://localhost:8000\"`.\n * - It also allows adding an optional suffix to the returned URL.\n * - ***⚠️ Warning:***\n * - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @description\n * This function determines the backend API base URL from the `NEXT_PUBLIC_BACKEND_API_URL` environment variable.\n * - If `NEXT_PUBLIC_BACKEND_API_URL` is not set, it defaults to `\"http://localhost:8000\"`.\n * - If `NEXT_PUBLIC_BACKEND_API_URL` does **not** contain a port, it appends one from `NEXT_PUBLIC_PORT_BE` if available.\n * - Supports appending optional suffix (like `\"/api\"`).\n * @param {OptionsGetBeApiUrl|undefined} options - Configuration options.\n * @param {OptionsGetBeApiUrl[\"suffix\"]} [options.suffix=\"/\"] - The suffix to append to the base API URL.\n * @returns {string} The formatted backend API base URL.\n * @throws **{@link TypeError | `TypeError`}** if `suffix` is not a `string`.\n * @throws **{@link Error | `Error`}** if `NEXT_PUBLIC_BACKEND_API_URL` is invalid.\n * @example\n * // With NEXT_PUBLIC_BACKEND_API_URL set at `*.env` file\n * NEXT_PUBLIC_BACKEND_API_URL = \"https://api.example.com\";\n * getBeApiUrl();\n * // ➔ \"https://api.example.com/\"\n *\n * // With NEXT_PUBLIC_BACKEND_API_URL but no port, using NEXT_PUBLIC_PORT_BE at `*.env` file\n * NEXT_PUBLIC_BACKEND_API_URL = \"http://localhost\";\n * NEXT_PUBLIC_PORT_BE = \"5000\";\n * getBeApiUrl({ suffix: \"/api\" });\n * // ➔ \"http://localhost:5000/api\"\n *\n * // Without NEXT_PUBLIC_BACKEND_API_URL at `*.env` file (defaults to localhost:8000)\n * delete NEXT_PUBLIC_BACKEND_API_URL;\n * getBeApiUrl({ suffix: \"/v1\" });\n * // ➔ \"http://localhost:8000/v1\"\n */\nexport const getBeApiUrl = (options: OptionsGetBeApiUrl = {}): string => {\n if (!isPlainObject(options)) options = {};\n\n let suffix = hasOwnProp(options, \"suffix\") ? options.suffix : \"/\";\n\n // Ensure suffix is a string\n assertIsString(suffix, {\n message({ currentType, validType }) {\n return `Parameter \\`suffix\\` property of the first parameter must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n\n try {\n let rawBaseUrl = process.env.NEXT_PUBLIC_BACKEND_API_URL?.trim();\n\n if (rawBaseUrl) {\n rawBaseUrl = removeSpaces(rawBaseUrl);\n\n const urlObj = new URL(rawBaseUrl);\n const hasPort = !!urlObj.port;\n\n if (!hasPort && process.env.NEXT_PUBLIC_PORT_BE) {\n rawBaseUrl =\n urlObj.origin +\n formatEnvPort(process.env.NEXT_PUBLIC_PORT_BE, {\n prefixColon: true\n });\n }\n } else {\n // fallback\n rawBaseUrl =\n \"http://localhost\" +\n formatEnvPort(process.env.NEXT_PUBLIC_PORT_BE || \"8000\", {\n prefixColon: true\n });\n }\n\n suffix = removeSpaces(suffix).length ? removeSpaces(suffix) : \"/\";\n const baseApiUrl = new URL(rawBaseUrl.replace(/\\/+$/, \"\")).origin;\n\n const finalSuffix =\n suffix === \"/\"\n ? \"/\"\n : `${suffix.startsWith(\"/\") ? \"\" : \"/\"}${suffix.replace(/\\/+$/, \"\")}`;\n\n return `${baseApiUrl}${finalSuffix}`;\n } catch (error) {\n throw new Error(\n \"Invalid `NEXT_PUBLIC_BACKEND_API_URL`, failed to generate from `getBeApiUrl()`, Error:\" +\n error,\n { cause: error }\n );\n }\n};\n","import { formatEnvPort } from \"@/urls/utils/formatEnvPort\";\nimport { removeSpaces } from \"@/strings/sanitizations/removeSpaces\";\n\n/** ---------------------------------------------------\n * * ***Utility for NextJS: `getBaseUrl`.***\n * ---------------------------------------------------\n * **Retrieves the base URL of the application.**\n * - **Behavior:**\n * - It determines the base URL from the `NEXT_PUBLIC_BASE_URL` environment variable.\n * - If `NEXT_PUBLIC_BASE_URL` is not set, it defaults to `\"http://localhost:3000\"`.\n * - If `NEXT_PUBLIC_BASE_URL` does **not** contain a port, it appends one from `NEXT_PUBLIC_PORT_FE` if available.\n * - Ensures the final URL is valid and normalized (no trailing slashes).\n * - ***⚠️ Warning:***\n * - ***This function only support when using ***[`NextJS`](https://nextjs.org/)***.***\n * @returns {string} The resolved base URL of the application.\n * @throws **{@link Error | `Error`}** if the constructed URL is invalid or malformed.\n * @example\n * // With environment variable set at `*.env` file\n * NEXT_PUBLIC_BASE_URL = \"https://example.com\";\n * getBaseUrl();\n * // ➔ \"https://example.com\"\n *\n * // With custom port via NEXT_PUBLIC_PORT_FE at `*.env` file\n * NEXT_PUBLIC_BASE_URL = \"http://localhost\";\n * NEXT_PUBLIC_PORT_FE = \"4000\";\n * getBaseUrl();\n * // ➔ \"http://localhost:4000\"\n *\n * // Without environment variable at `*.env` file\n * delete NEXT_PUBLIC_BASE_URL;\n * getBaseUrl();\n * // ➔ \"http://localhost:3000\"\n */\nexport const getBaseUrl = (): string => {\n try {\n const baseEnv = process.env.NEXT_PUBLIC_BASE_URL?.trim();\n const portEnv = process.env.NEXT_PUBLIC_PORT_FE?.trim();\n\n let baseUrl = baseEnv || \"http://localhost\";\n\n // Always clean trailing slashes first\n baseUrl = removeSpaces(baseUrl).replace(/\\/+$/, \"\");\n\n // Check if already contains port\n const hasPort = /:\\/\\/[^/]+:\\d+/.test(baseUrl);\n\n if (!hasPort && portEnv) {\n baseUrl += formatEnvPort(portEnv, { prefixColon: true });\n } else if (!hasPort && !baseEnv) {\n baseUrl += \":3000\";\n }\n\n const url = new URL(baseUrl);\n return `${url.protocol}//${url.hostname}${url.port ? `:${url.port}` : \"\"}`;\n } catch (error) {\n throw new Error(\n \"Invalid `NEXT_PUBLIC_BASE_URL`, failed to generate from `getBaseUrl()`, Error:\" +\n error,\n { cause: error }\n );\n }\n};\n"],"mappings":"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"}
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* ========================================================================
|
|
3
3
|
* @rzl-zone/utils-js
|
|
4
4
|
* ------------------------------------------------------------------------
|
|
5
|
-
* Version: `3.12.1-beta.
|
|
5
|
+
* Version: `3.12.1-beta.1`
|
|
6
6
|
* Author: `Rizalvin Dwiky <rizalvindwiky@gmail.com>`
|
|
7
7
|
* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/utils-js`
|
|
8
8
|
* ========================================================================
|
|
9
9
|
*/
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
12
|
-
const require_assertIsBoolean = require('../../assertIsBoolean-
|
|
12
|
+
const require_assertIsBoolean = require('../../assertIsBoolean-C8WEXVr2.cjs');
|
|
13
13
|
require("@rzl-zone/node-only");
|
|
14
14
|
let next_server = require("next/server");
|
|
15
15
|
const getClientIpOrUrl = (request, includeFullUrl = true) => {
|