@cyberskill/shared 3.6.0 → 3.8.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.
Files changed (48) hide show
  1. package/dist/config/vitest/vitest.e2e.js +1 -1
  2. package/dist/config/vitest/vitest.e2e.js.map +1 -1
  3. package/dist/config/vitest/vitest.unit.js +1 -1
  4. package/dist/config/vitest/vitest.unit.js.map +1 -1
  5. package/dist/constant/common.d.ts +3 -2
  6. package/dist/constant/common.js +1 -1
  7. package/dist/constant/common.js.map +1 -1
  8. package/dist/node/apollo-server/apollo-server.util.js +15 -13
  9. package/dist/node/apollo-server/apollo-server.util.js.map +1 -1
  10. package/dist/node/command/command.util.js +29 -29
  11. package/dist/node/command/command.util.js.map +1 -1
  12. package/dist/node/express/express.util.d.ts +4 -0
  13. package/dist/node/express/express.util.js +7 -6
  14. package/dist/node/express/express.util.js.map +1 -1
  15. package/dist/node/mongo/mongo.controller.mongoose.d.ts +6 -1
  16. package/dist/node/mongo/mongo.controller.mongoose.js +10 -11
  17. package/dist/node/mongo/mongo.controller.mongoose.js.map +1 -1
  18. package/dist/node/mongo/mongo.controller.native.d.ts +1 -1
  19. package/dist/node/mongo/mongo.controller.native.js +5 -4
  20. package/dist/node/mongo/mongo.controller.native.js.map +1 -1
  21. package/dist/node/mongo/mongo.controller.type.d.ts +15 -0
  22. package/dist/node/mongo/mongo.dynamic-populate.js +12 -12
  23. package/dist/node/mongo/mongo.dynamic-populate.js.map +1 -1
  24. package/dist/node/mongo/mongo.util.d.ts +3 -3
  25. package/dist/node/mongo/mongo.util.js.map +1 -1
  26. package/dist/node/path/index.js +2 -2
  27. package/dist/node/path/path.constant.d.ts +21 -7
  28. package/dist/node/path/path.constant.js +48 -29
  29. package/dist/node/path/path.constant.js.map +1 -1
  30. package/dist/node/storage/storage.util.js +2 -6
  31. package/dist/node/storage/storage.util.js.map +1 -1
  32. package/dist/node/ws/ws.util.js +2 -0
  33. package/dist/node/ws/ws.util.js.map +1 -1
  34. package/dist/react/apollo-client/apollo-client.util.js +42 -41
  35. package/dist/react/apollo-client/apollo-client.util.js.map +1 -1
  36. package/dist/react/log/log.util.d.ts +5 -0
  37. package/dist/react/log/log.util.js.map +1 -1
  38. package/dist/typescript/common.type.d.ts +18 -0
  39. package/dist/typescript/common.type.js +9 -2
  40. package/dist/typescript/common.type.js.map +1 -1
  41. package/dist/typescript/index.js +2 -2
  42. package/dist/util/object/object.util.js +43 -37
  43. package/dist/util/object/object.util.js.map +1 -1
  44. package/dist/util/serializer/serializer.util.d.ts +13 -0
  45. package/dist/util/serializer/serializer.util.js.map +1 -1
  46. package/dist/util/string/string.util.js +45 -13
  47. package/dist/util/string/string.util.js.map +1 -1
  48. package/package.json +7 -6
@@ -1,60 +1,61 @@
1
- import { toast as e } from "../toast/index.js";
2
- import { log as t } from "../log/log.util.js";
3
- import { hasCustomApolloErrorHandler as n, showGlobalApolloError as r } from "../apollo-error/apollo-error.util.js";
4
- import { GRAPHQL_URI_DEFAULT as i } from "./apollo-client.constant.js";
5
- import a from "./apollo-client.module.scss.js";
6
- import { createUploadLink as o } from "./links/upload.js";
7
- import * as s from "react";
8
- import { ApolloLink as c } from "@apollo/client/link";
9
- import { ApolloClient as l, CombinedGraphQLErrors as u, CombinedProtocolErrors as d, InMemoryCache as f, ServerError as p } from "@apollo/client/core";
10
- import { ErrorLink as m } from "@apollo/client/link/error";
11
- import { RemoveTypenameFromVariablesLink as h } from "@apollo/client/link/remove-typename";
12
- import { GraphQLWsLink as g } from "@apollo/client/link/subscriptions";
13
- import { OperationTypeNode as _ } from "graphql";
14
- import { createClient as v } from "graphql-ws";
15
- import { tap as y } from "rxjs";
1
+ import { IS_BROWSER as e } from "../../constant/common.js";
2
+ import { toast as t } from "../toast/index.js";
3
+ import { log as n } from "../log/log.util.js";
4
+ import { hasCustomApolloErrorHandler as r, showGlobalApolloError as i } from "../apollo-error/apollo-error.util.js";
5
+ import { GRAPHQL_URI_DEFAULT as a } from "./apollo-client.constant.js";
6
+ import o from "./apollo-client.module.scss.js";
7
+ import { createUploadLink as s } from "./links/upload.js";
8
+ import * as c from "react";
9
+ import { ApolloLink as l } from "@apollo/client/link";
10
+ import { ApolloClient as u, CombinedGraphQLErrors as d, CombinedProtocolErrors as f, InMemoryCache as p, ServerError as m } from "@apollo/client/core";
11
+ import { ErrorLink as h } from "@apollo/client/link/error";
12
+ import { RemoveTypenameFromVariablesLink as g } from "@apollo/client/link/remove-typename";
13
+ import { GraphQLWsLink as _ } from "@apollo/client/link/subscriptions";
14
+ import { OperationTypeNode as v } from "graphql";
15
+ import { createClient as y } from "graphql-ws";
16
+ import { tap as b } from "rxjs";
16
17
  //#region src/react/apollo-client/apollo-client.util.tsx
17
- var b = new c((e, n) => (e.setContext({ start: performance.now() }), n(e).pipe(y(() => {
18
- let n = Math.round(performance.now() - e.getContext().start);
19
- t.info(`Operation ${e.operationName} took ${n}ms to complete`);
20
- })))), x = new m(({ error: i, operation: o }) => {
21
- let c = o?.operationName || "Unknown", l = "";
22
- u.is(i) ? i.errors.forEach(({ message: e, locations: n, path: r }, i) => {
23
- i === 0 && (l = e), t.error(`[GraphQL error] ${c}: ${e}, Location: ${JSON.stringify(n, null, 4)}, Path: ${r}`);
24
- }) : d.is(i) ? i.errors.forEach(({ message: e, extensions: n }, r) => {
25
- r === 0 && (l = e), t.error(`[Protocol error]: ${e}, Extensions: ${JSON.stringify(n, null, 4)}`);
26
- }) : p.is(i) ? (l = i.message, t.error(`[Server error]: ${i.message}`)) : (l = i.message, t.error(`[Network error]: ${i.message}`)), i && l && typeof window < "u" && (n() ? r(i) : e.error((t) => /* @__PURE__ */ s.createElement("div", { className: a["error-container"] }, l, /* @__PURE__ */ s.createElement("button", {
18
+ var x = new l((e, t) => (e.setContext({ start: performance.now() }), t(e).pipe(b(() => {
19
+ let t = Math.round(performance.now() - e.getContext().start);
20
+ n.info(`Operation ${e.operationName} took ${t}ms to complete`);
21
+ })))), S = new h(({ error: a, operation: s }) => {
22
+ let l = s?.operationName || "Unknown", u = "";
23
+ d.is(a) ? a.errors.forEach(({ message: e, locations: t, path: r }, i) => {
24
+ i === 0 && (u = e), n.error(`[GraphQL error] ${l}: ${e}, Location: ${JSON.stringify(t, null, 4)}, Path: ${r}`);
25
+ }) : f.is(a) ? a.errors.forEach(({ message: e, extensions: t }, r) => {
26
+ r === 0 && (u = e), n.error(`[Protocol error]: ${e}, Extensions: ${JSON.stringify(t, null, 4)}`);
27
+ }) : m.is(a) ? (u = a.message, n.error(`[Server error]: ${a.message}`)) : (u = a.message, n.error(`[Network error]: ${a.message}`)), a && u && e && (r() ? i(a) : t.error((e) => /* @__PURE__ */ c.createElement("div", { className: o["error-container"] }, u, /* @__PURE__ */ c.createElement("button", {
27
28
  type: "button",
28
- className: a["error-details-button"],
29
+ className: o["error-details-button"],
29
30
  onClick: () => {
30
- r(i), e.dismiss(t.id);
31
+ i(a), t.dismiss(e.id);
31
32
  }
32
33
  }, "Error Details"))));
33
34
  });
34
- function S(e) {
35
- let { uri: n, wsUrl: r, customLinks: a } = e, s = new h();
36
- n || t.warn(`[Apollo] No GraphQL URI provided — using "${i}" as default`);
37
- let l = o({
38
- uri: n ?? "/graphql",
35
+ function C(e) {
36
+ let { uri: t, wsUrl: r, customLinks: i } = e, o = new g();
37
+ t || n.warn(`[Apollo] No GraphQL URI provided — using "${a}" as default`);
38
+ let c = s({
39
+ uri: t ?? "/graphql",
39
40
  credentials: "include",
40
41
  headers: { "apollo-require-preflight": "true" }
41
- }), u = r ? new g(v({ url: r })) : c.empty(), d = r ? c.split(({ operationType: e }) => e === _.SUBSCRIPTION, u, l) : l;
42
+ }), u = r ? new _(y({ url: r })) : l.empty(), d = r ? l.split(({ operationType: e }) => e === v.SUBSCRIPTION, u, c) : c;
42
43
  return [
43
- b,
44
44
  x,
45
- s,
46
- ...a ?? [],
45
+ S,
46
+ o,
47
+ ...i ?? [],
47
48
  d
48
49
  ];
49
50
  }
50
- function C(e) {
51
- return new l({
52
- link: c.from(S(e)),
53
- cache: new f(),
51
+ function w(e) {
52
+ return new u({
53
+ link: l.from(C(e)),
54
+ cache: new p(),
54
55
  ...e
55
56
  });
56
57
  }
57
58
  //#endregion
58
- export { S as createApolloLinks, C as getClient };
59
+ export { C as createApolloLinks, w as getClient };
59
60
 
60
61
  //# sourceMappingURL=apollo-client.util.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"apollo-client.util.js","names":[],"sources":["../../../src/react/apollo-client/apollo-client.util.tsx"],"sourcesContent":["import { ApolloClient, CombinedGraphQLErrors, CombinedProtocolErrors, InMemoryCache, ServerError } from '@apollo/client/core';\nimport { ApolloLink } from '@apollo/client/link';\nimport { ErrorLink } from '@apollo/client/link/error';\nimport { RemoveTypenameFromVariablesLink } from '@apollo/client/link/remove-typename';\nimport { GraphQLWsLink } from '@apollo/client/link/subscriptions';\nimport { OperationTypeNode } from 'graphql';\nimport { createClient } from 'graphql-ws';\nimport * as React from 'react';\nimport { tap } from 'rxjs';\n\nimport type { I_ApolloOptions } from './apollo-client.type.js';\n\nimport { hasCustomApolloErrorHandler, showGlobalApolloError } from '../apollo-error/index.js';\nimport { log } from '../log/index.js';\nimport { toast } from '../toast/index.js';\nimport { GRAPHQL_URI_DEFAULT } from './apollo-client.constant.js';\nimport styles from './apollo-client.module.scss';\nimport { createUploadLink } from './links/index.js';\n\nconst roundTripLink = new ApolloLink((operation, forward) => {\n operation.setContext({ start: performance.now() });\n\n return forward(operation).pipe(\n tap(() => {\n const time = Math.round(performance.now() - operation.getContext()['start']);\n\n log.info(`Operation ${operation.operationName} took ${time}ms to complete`);\n }),\n );\n});\n\nconst errorLink = new ErrorLink(({ error, operation }) => {\n const opName = operation?.operationName || 'Unknown';\n let errorMessage = '';\n\n if (CombinedGraphQLErrors.is(error)) {\n error.errors.forEach(({ message, locations, path }, index) => {\n if (index === 0) {\n errorMessage = message;\n }\n\n log.error(\n `[GraphQL error] ${opName}: ${message}, Location: ${JSON.stringify(locations, null, 4)}, Path: ${path}`,\n );\n });\n }\n else if (CombinedProtocolErrors.is(error)) {\n error.errors.forEach(({ message, extensions }, index) => {\n if (index === 0) {\n errorMessage = message;\n }\n\n log.error(\n `[Protocol error]: ${message}, Extensions: ${JSON.stringify(extensions, null, 4)}`,\n );\n });\n }\n else if (ServerError.is(error)) {\n errorMessage = error.message;\n\n log.error(`[Server error]: ${error.message}`);\n }\n else {\n errorMessage = error.message;\n\n log.error(`[Network error]: ${error.message}`);\n }\n\n if (error && errorMessage && typeof window !== 'undefined') {\n if (hasCustomApolloErrorHandler()) {\n showGlobalApolloError(error);\n }\n else {\n toast.error((t: { id: string }) => (\n <div className={styles['error-container']}>\n {errorMessage}\n <button\n type=\"button\"\n className={styles['error-details-button']}\n onClick={() => {\n showGlobalApolloError(error);\n\n toast.dismiss(t.id);\n }}\n >\n Error Details\n </button>\n </div>\n ));\n }\n }\n});\n\n/**\n * Creates a comprehensive Apollo Link chain with all necessary middleware.\n * This function sets up a complete Apollo Link chain including error handling,\n * logging, file uploads, WebSocket subscriptions, and custom links. The chain\n * is configured to handle both HTTP and WebSocket operations with proper routing.\n *\n * The link chain includes:\n * - Development logging for operation tracking\n * - Error handling with user-friendly notifications\n * - Type name removal for cleaner requests\n * - File upload support\n * - WebSocket subscription support\n * - Custom link integration\n *\n * @param options - Configuration options for the Apollo Client including URI, WebSocket URL, and custom links.\n * @returns An array of Apollo Links configured for the specified options.\n */\nexport function createApolloLinks(options: I_ApolloOptions): ApolloLink[] {\n const { uri, wsUrl, customLinks } = options;\n\n const removeTypenameLink = new RemoveTypenameFromVariablesLink();\n\n if (!uri) {\n log.warn(`[Apollo] No GraphQL URI provided — using \"${GRAPHQL_URI_DEFAULT}\" as default`);\n }\n\n const uploadLink = createUploadLink({\n uri: uri ?? GRAPHQL_URI_DEFAULT,\n credentials: 'include',\n headers: {\n 'apollo-require-preflight': 'true',\n },\n });\n\n const wsLink = wsUrl\n ? new GraphQLWsLink(createClient({ url: wsUrl }))\n : ApolloLink.empty();\n\n const splitLink = wsUrl\n ? ApolloLink.split(\n ({ operationType }) => {\n return operationType === OperationTypeNode.SUBSCRIPTION;\n },\n wsLink,\n uploadLink as unknown as ApolloLink,\n )\n : uploadLink;\n\n return [\n roundTripLink,\n errorLink,\n removeTypenameLink,\n ...(customLinks ?? []),\n splitLink as unknown as ApolloLink,\n ];\n}\n\n/**\n * Creates a fully configured Apollo Client instance.\n * This function creates an Apollo Client with all necessary configuration including\n * the link chain, cache, and any additional options provided. The client is ready\n * for immediate use in React applications with comprehensive error handling and\n * development tooling.\n *\n * @param options - Configuration options for the Apollo Client including links, cache, and other settings.\n * @returns A fully configured Apollo Client instance ready for use.\n */\nexport function getClient(options: I_ApolloOptions) {\n const link = ApolloLink.from(createApolloLinks(options));\n\n return new ApolloClient({\n link,\n cache: new InMemoryCache(),\n ...options,\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,IAAM,IAAgB,IAAI,GAAY,GAAW,OAC7C,EAAU,WAAW,EAAE,OAAO,YAAY,KAAK,EAAE,CAAC,EAE3C,EAAQ,EAAU,CAAC,KACtB,QAAU;CACN,IAAM,IAAO,KAAK,MAAM,YAAY,KAAK,GAAG,EAAU,YAAY,CAAC,MAAS;AAE5E,GAAI,KAAK,aAAa,EAAU,cAAc,QAAQ,EAAK,gBAAgB;EAC7E,CACL,EACH,EAEI,IAAY,IAAI,GAAW,EAAE,UAAO,mBAAgB;CACtD,IAAM,IAAS,GAAW,iBAAiB,WACvC,IAAe;AAmCnB,CAjCI,EAAsB,GAAG,EAAM,GAC/B,EAAM,OAAO,SAAS,EAAE,YAAS,cAAW,WAAQ,MAAU;AAK1D,EAJI,MAAU,MACV,IAAe,IAGnB,EAAI,MACA,mBAAmB,EAAO,IAAI,EAAQ,cAAc,KAAK,UAAU,GAAW,MAAM,EAAE,CAAC,UAAU,IACpG;GACH,GAEG,EAAuB,GAAG,EAAM,GACrC,EAAM,OAAO,SAAS,EAAE,YAAS,iBAAc,MAAU;AAKrD,EAJI,MAAU,MACV,IAAe,IAGnB,EAAI,MACA,qBAAqB,EAAQ,gBAAgB,KAAK,UAAU,GAAY,MAAM,EAAE,GACnF;GACH,GAEG,EAAY,GAAG,EAAM,IAC1B,IAAe,EAAM,SAErB,EAAI,MAAM,mBAAmB,EAAM,UAAU,KAG7C,IAAe,EAAM,SAErB,EAAI,MAAM,oBAAoB,EAAM,UAAU,GAG9C,KAAS,KAAgB,OAAO,SAAW,QACvC,GAA6B,GAC7B,EAAsB,EAAM,GAG5B,EAAM,OAAO,MACT,kBAAA,cAAC,OAAD,EAAK,WAAW,EAAO,oBAajB,EAZD,GACD,kBAAA,cAAC,UAAD;EACI,MAAK;EACL,WAAW,EAAO;EAClB,eAAe;AAGX,GAFA,EAAsB,EAAM,EAE5B,EAAM,QAAQ,EAAE,GAAG;;EAIlB,EAFR,gBAEQ,CACP,CACR;EAGZ;AAmBF,SAAgB,EAAkB,GAAwC;CACtE,IAAM,EAAE,QAAK,UAAO,mBAAgB,GAE9B,IAAqB,IAAI,GAAiC;AAEhE,CAAK,KACD,EAAI,KAAK,6CAA6C,EAAoB,cAAc;CAG5F,IAAM,IAAa,EAAiB;EAChC,KAAK,KAAA;EACL,aAAa;EACb,SAAS,EACL,4BAA4B,QAC/B;EACJ,CAAC,EAEI,IAAS,IACT,IAAI,EAAc,EAAa,EAAE,KAAK,GAAO,CAAC,CAAC,GAC/C,EAAW,OAAO,EAElB,IAAY,IACZ,EAAW,OACJ,EAAE,uBACQ,MAAkB,EAAkB,cAE/C,GACA,EACH,GACH;AAEN,QAAO;EACH;EACA;EACA;EACA,GAAI,KAAe,EAAE;EACrB;EACH;;AAaL,SAAgB,EAAU,GAA0B;AAGhD,QAAO,IAAI,EAAa;EACpB,MAHS,EAAW,KAAK,EAAkB,EAAQ,CAAC;EAIpD,OAAO,IAAI,GAAe;EAC1B,GAAG;EACN,CAAC"}
1
+ {"version":3,"file":"apollo-client.util.js","names":[],"sources":["../../../src/react/apollo-client/apollo-client.util.tsx"],"sourcesContent":["import { ApolloClient, CombinedGraphQLErrors, CombinedProtocolErrors, InMemoryCache, ServerError } from '@apollo/client/core';\nimport { ApolloLink } from '@apollo/client/link';\nimport { ErrorLink } from '@apollo/client/link/error';\nimport { RemoveTypenameFromVariablesLink } from '@apollo/client/link/remove-typename';\nimport { GraphQLWsLink } from '@apollo/client/link/subscriptions';\nimport { OperationTypeNode } from 'graphql';\nimport { createClient } from 'graphql-ws';\nimport * as React from 'react';\nimport { tap } from 'rxjs';\n\nimport { IS_BROWSER } from '#constant/index.js';\n\nimport type { I_ApolloOptions } from './apollo-client.type.js';\n\nimport { hasCustomApolloErrorHandler, showGlobalApolloError } from '../apollo-error/index.js';\nimport { log } from '../log/index.js';\nimport { toast } from '../toast/index.js';\nimport { GRAPHQL_URI_DEFAULT } from './apollo-client.constant.js';\nimport styles from './apollo-client.module.scss';\nimport { createUploadLink } from './links/index.js';\n\nconst roundTripLink = new ApolloLink((operation, forward) => {\n operation.setContext({ start: performance.now() });\n\n return forward(operation).pipe(\n tap(() => {\n const time = Math.round(performance.now() - operation.getContext()['start']);\n\n log.info(`Operation ${operation.operationName} took ${time}ms to complete`);\n }),\n );\n});\n\nconst errorLink = new ErrorLink(({ error, operation }) => {\n const opName = operation?.operationName || 'Unknown';\n let errorMessage = '';\n\n if (CombinedGraphQLErrors.is(error)) {\n error.errors.forEach(({ message, locations, path }, index) => {\n if (index === 0) {\n errorMessage = message;\n }\n\n log.error(\n `[GraphQL error] ${opName}: ${message}, Location: ${JSON.stringify(locations, null, 4)}, Path: ${path}`,\n );\n });\n }\n else if (CombinedProtocolErrors.is(error)) {\n error.errors.forEach(({ message, extensions }, index) => {\n if (index === 0) {\n errorMessage = message;\n }\n\n log.error(\n `[Protocol error]: ${message}, Extensions: ${JSON.stringify(extensions, null, 4)}`,\n );\n });\n }\n else if (ServerError.is(error)) {\n errorMessage = error.message;\n\n log.error(`[Server error]: ${error.message}`);\n }\n else {\n errorMessage = error.message;\n\n log.error(`[Network error]: ${error.message}`);\n }\n\n if (error && errorMessage && IS_BROWSER) {\n if (hasCustomApolloErrorHandler()) {\n showGlobalApolloError(error);\n }\n else {\n toast.error((t: { id: string }) => (\n <div className={styles['error-container']}>\n {errorMessage}\n <button\n type=\"button\"\n className={styles['error-details-button']}\n onClick={() => {\n showGlobalApolloError(error);\n\n toast.dismiss(t.id);\n }}\n >\n Error Details\n </button>\n </div>\n ));\n }\n }\n});\n\n/**\n * Creates a comprehensive Apollo Link chain with all necessary middleware.\n * This function sets up a complete Apollo Link chain including error handling,\n * logging, file uploads, WebSocket subscriptions, and custom links. The chain\n * is configured to handle both HTTP and WebSocket operations with proper routing.\n *\n * The link chain includes:\n * - Development logging for operation tracking\n * - Error handling with user-friendly notifications\n * - Type name removal for cleaner requests\n * - File upload support\n * - WebSocket subscription support\n * - Custom link integration\n *\n * @param options - Configuration options for the Apollo Client including URI, WebSocket URL, and custom links.\n * @returns An array of Apollo Links configured for the specified options.\n */\nexport function createApolloLinks(options: I_ApolloOptions): ApolloLink[] {\n const { uri, wsUrl, customLinks } = options;\n\n const removeTypenameLink = new RemoveTypenameFromVariablesLink();\n\n if (!uri) {\n log.warn(`[Apollo] No GraphQL URI provided — using \"${GRAPHQL_URI_DEFAULT}\" as default`);\n }\n\n const uploadLink = createUploadLink({\n uri: uri ?? GRAPHQL_URI_DEFAULT,\n credentials: 'include',\n headers: {\n 'apollo-require-preflight': 'true',\n },\n });\n\n const wsLink = wsUrl\n ? new GraphQLWsLink(createClient({ url: wsUrl }))\n : ApolloLink.empty();\n\n const splitLink = wsUrl\n ? ApolloLink.split(\n ({ operationType }) => {\n return operationType === OperationTypeNode.SUBSCRIPTION;\n },\n wsLink,\n uploadLink as unknown as ApolloLink,\n )\n : uploadLink;\n\n return [\n roundTripLink,\n errorLink,\n removeTypenameLink,\n ...(customLinks ?? []),\n splitLink as unknown as ApolloLink,\n ];\n}\n\n/**\n * Creates a fully configured Apollo Client instance.\n * This function creates an Apollo Client with all necessary configuration including\n * the link chain, cache, and any additional options provided. The client is ready\n * for immediate use in React applications with comprehensive error handling and\n * development tooling.\n *\n * @param options - Configuration options for the Apollo Client including links, cache, and other settings.\n * @returns A fully configured Apollo Client instance ready for use.\n */\nexport function getClient(options: I_ApolloOptions) {\n const link = ApolloLink.from(createApolloLinks(options));\n\n return new ApolloClient({\n link,\n cache: new InMemoryCache(),\n ...options,\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAqBA,IAAM,IAAgB,IAAI,GAAY,GAAW,OAC7C,EAAU,WAAW,EAAE,OAAO,YAAY,KAAK,EAAE,CAAC,EAE3C,EAAQ,EAAU,CAAC,KACtB,QAAU;CACN,IAAM,IAAO,KAAK,MAAM,YAAY,KAAK,GAAG,EAAU,YAAY,CAAC,MAAS;AAE5E,GAAI,KAAK,aAAa,EAAU,cAAc,QAAQ,EAAK,gBAAgB;EAC7E,CACL,EACH,EAEI,IAAY,IAAI,GAAW,EAAE,UAAO,mBAAgB;CACtD,IAAM,IAAS,GAAW,iBAAiB,WACvC,IAAe;AAmCnB,CAjCI,EAAsB,GAAG,EAAM,GAC/B,EAAM,OAAO,SAAS,EAAE,YAAS,cAAW,WAAQ,MAAU;AAK1D,EAJI,MAAU,MACV,IAAe,IAGnB,EAAI,MACA,mBAAmB,EAAO,IAAI,EAAQ,cAAc,KAAK,UAAU,GAAW,MAAM,EAAE,CAAC,UAAU,IACpG;GACH,GAEG,EAAuB,GAAG,EAAM,GACrC,EAAM,OAAO,SAAS,EAAE,YAAS,iBAAc,MAAU;AAKrD,EAJI,MAAU,MACV,IAAe,IAGnB,EAAI,MACA,qBAAqB,EAAQ,gBAAgB,KAAK,UAAU,GAAY,MAAM,EAAE,GACnF;GACH,GAEG,EAAY,GAAG,EAAM,IAC1B,IAAe,EAAM,SAErB,EAAI,MAAM,mBAAmB,EAAM,UAAU,KAG7C,IAAe,EAAM,SAErB,EAAI,MAAM,oBAAoB,EAAM,UAAU,GAG9C,KAAS,KAAgB,MACrB,GAA6B,GAC7B,EAAsB,EAAM,GAG5B,EAAM,OAAO,MACT,kBAAA,cAAC,OAAD,EAAK,WAAW,EAAO,oBAajB,EAZD,GACD,kBAAA,cAAC,UAAD;EACI,MAAK;EACL,WAAW,EAAO;EAClB,eAAe;AAGX,GAFA,EAAsB,EAAM,EAE5B,EAAM,QAAQ,EAAE,GAAG;;EAIlB,EAFR,gBAEQ,CACP,CACR;EAGZ;AAmBF,SAAgB,EAAkB,GAAwC;CACtE,IAAM,EAAE,QAAK,UAAO,mBAAgB,GAE9B,IAAqB,IAAI,GAAiC;AAEhE,CAAK,KACD,EAAI,KAAK,6CAA6C,EAAoB,cAAc;CAG5F,IAAM,IAAa,EAAiB;EAChC,KAAK,KAAA;EACL,aAAa;EACb,SAAS,EACL,4BAA4B,QAC/B;EACJ,CAAC,EAEI,IAAS,IACT,IAAI,EAAc,EAAa,EAAE,KAAK,GAAO,CAAC,CAAC,GAC/C,EAAW,OAAO,EAElB,IAAY,IACZ,EAAW,OACJ,EAAE,uBACQ,MAAkB,EAAkB,cAE/C,GACA,EACH,GACH;AAEN,QAAO;EACH;EACA;EACA;EACA,GAAI,KAAe,EAAE;EACrB;EACH;;AAaL,SAAgB,EAAU,GAA0B;AAGhD,QAAO,IAAI,EAAa;EACpB,MAHS,EAAW,KAAK,EAAkB,EAAQ,CAAC;EAIpD,OAAO,IAAI,GAAe;EAC1B,GAAG;EACN,CAAC"}
@@ -4,6 +4,11 @@ import { I_CatchErrorOptions } from './log.type.js';
4
4
  * Browser-compatible logging interface using consola.
5
5
  * This object provides all standard consola logging methods for use in browser environments,
6
6
  * including error, warning, info, success, and debug logging capabilities.
7
+ *
8
+ * @remarks
9
+ * This module imports from `consola/browser` (not `consola`) to ensure no Node.js-specific
10
+ * code is included in client bundles. The `I_Log` type from `#typescript` is a type-only
11
+ * import and is erased at build time.
7
12
  */
8
13
  export declare const log: I_Log;
9
14
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"log.util.js","names":[],"sources":["../../../src/react/log/log.util.ts"],"sourcesContent":["import { consola } from 'consola/browser';\n\nimport type { I_Log, I_Return } from '#typescript/index.js';\n\nimport { RESPONSE_STATUS } from '#constant/index.js';\nimport { baseCatchError } from '#util/log/index.js';\n\nimport type { I_CatchErrorOptions } from './log.type.js';\n\n/**\n * Browser-compatible logging interface using consola.\n * This object provides all standard consola logging methods for use in browser environments,\n * including error, warning, info, success, and debug logging capabilities.\n */\nexport const log: I_Log = {\n silent: consola.silent,\n level: consola.level,\n fatal: consola.fatal,\n error: consola.error,\n warn: consola.warn,\n log: consola.log,\n info: consola.info,\n success: consola.success,\n ready: consola.ready,\n start: consola.start,\n box: consola.box,\n debug: consola.debug,\n trace: consola.trace,\n verbose: consola.verbose,\n};\n\n/**\n * Catches and handles errors with configurable behavior for React applications.\n * Delegates to the shared `baseCatchError` implementation, using the browser\n * consola instance for logging.\n *\n * @param errorInput - The error to catch and handle, can be Error object, string, or unknown type.\n * @param options - Configuration options for error handling behavior.\n * @returns Either the specified return value or a standardized error response object.\n */\nexport function catchError<T = unknown>(errorInput: unknown, options: I_CatchErrorOptions & { returnValue: T }): T;\nexport function catchError<T = unknown>(errorInput: unknown, options?: I_CatchErrorOptions): I_Return<T>;\nexport function catchError<T = unknown>(errorInput: unknown, options?: I_CatchErrorOptions): I_Return<T> | T {\n return baseCatchError<T>(errorInput, options, message => log.error(message));\n}\n\n/**\n * Throws a standardized error with a message and optional HTTP status code.\n * Provides a consistent way to throw errors across React and Node environments.\n *\n * @param message - The error message.\n * @param code - Optional HTTP status code (defaults to 500).\n */\nexport function throwError(message: string, code?: number): never {\n const error = new Error(message);\n (error as Error & { code?: number }).code = code ?? RESPONSE_STATUS.INTERNAL_SERVER_ERROR.CODE;\n throw error;\n}\n"],"mappings":";;;;AAcA,IAAa,IAAa;CACtB,QAAQ,EAAQ;CAChB,OAAO,EAAQ;CACf,OAAO,EAAQ;CACf,OAAO,EAAQ;CACf,MAAM,EAAQ;CACd,KAAK,EAAQ;CACb,MAAM,EAAQ;CACd,SAAS,EAAQ;CACjB,OAAO,EAAQ;CACf,OAAO,EAAQ;CACf,KAAK,EAAQ;CACb,OAAO,EAAQ;CACf,OAAO,EAAQ;CACf,SAAS,EAAQ;CACpB;AAaD,SAAgB,EAAwB,GAAqB,GAAgD;AACzG,QAAO,EAAkB,GAAY,IAAS,MAAW,EAAI,MAAM,EAAQ,CAAC;;AAUhF,SAAgB,EAAW,GAAiB,GAAsB;CAC9D,IAAM,IAAY,MAAM,EAAQ;AAEhC,OADC,EAAoC,OAAO,KAAQ,EAAgB,sBAAsB,MACpF"}
1
+ {"version":3,"file":"log.util.js","names":[],"sources":["../../../src/react/log/log.util.ts"],"sourcesContent":["import { consola } from 'consola/browser';\n\nimport type { I_Log, I_Return } from '#typescript/index.js';\n\nimport { RESPONSE_STATUS } from '#constant/index.js';\nimport { baseCatchError } from '#util/log/index.js';\n\nimport type { I_CatchErrorOptions } from './log.type.js';\n\n/**\n * Browser-compatible logging interface using consola.\n * This object provides all standard consola logging methods for use in browser environments,\n * including error, warning, info, success, and debug logging capabilities.\n *\n * @remarks\n * This module imports from `consola/browser` (not `consola`) to ensure no Node.js-specific\n * code is included in client bundles. The `I_Log` type from `#typescript` is a type-only\n * import and is erased at build time.\n */\nexport const log: I_Log = {\n silent: consola.silent,\n level: consola.level,\n fatal: consola.fatal,\n error: consola.error,\n warn: consola.warn,\n log: consola.log,\n info: consola.info,\n success: consola.success,\n ready: consola.ready,\n start: consola.start,\n box: consola.box,\n debug: consola.debug,\n trace: consola.trace,\n verbose: consola.verbose,\n};\n\n/**\n * Catches and handles errors with configurable behavior for React applications.\n * Delegates to the shared `baseCatchError` implementation, using the browser\n * consola instance for logging.\n *\n * @param errorInput - The error to catch and handle, can be Error object, string, or unknown type.\n * @param options - Configuration options for error handling behavior.\n * @returns Either the specified return value or a standardized error response object.\n */\nexport function catchError<T = unknown>(errorInput: unknown, options: I_CatchErrorOptions & { returnValue: T }): T;\nexport function catchError<T = unknown>(errorInput: unknown, options?: I_CatchErrorOptions): I_Return<T>;\nexport function catchError<T = unknown>(errorInput: unknown, options?: I_CatchErrorOptions): I_Return<T> | T {\n return baseCatchError<T>(errorInput, options, message => log.error(message));\n}\n\n/**\n * Throws a standardized error with a message and optional HTTP status code.\n * Provides a consistent way to throw errors across React and Node environments.\n *\n * @param message - The error message.\n * @param code - Optional HTTP status code (defaults to 500).\n */\nexport function throwError(message: string, code?: number): never {\n const error = new Error(message);\n (error as Error & { code?: number }).code = code ?? RESPONSE_STATUS.INTERNAL_SERVER_ERROR.CODE;\n throw error;\n}\n"],"mappings":";;;;AAmBA,IAAa,IAAa;CACtB,QAAQ,EAAQ;CAChB,OAAO,EAAQ;CACf,OAAO,EAAQ;CACf,OAAO,EAAQ;CACf,MAAM,EAAQ;CACd,KAAK,EAAQ;CACb,MAAM,EAAQ;CACd,SAAS,EAAQ;CACjB,OAAO,EAAQ;CACf,OAAO,EAAQ;CACf,KAAK,EAAQ;CACb,OAAO,EAAQ;CACf,OAAO,EAAQ;CACf,SAAS,EAAQ;CACpB;AAaD,SAAgB,EAAwB,GAAqB,GAAgD;AACzG,QAAO,EAAkB,GAAY,IAAS,MAAW,EAAI,MAAM,EAAQ,CAAC;;AAUhF,SAAgB,EAAW,GAAiB,GAAsB;CAC9D,IAAM,IAAY,MAAM,EAAQ;AAEhC,OADC,EAAoC,OAAO,KAAQ,EAAgB,sBAAsB,MACpF"}
@@ -38,6 +38,8 @@ export interface I_ReturnBase {
38
38
  export interface I_ReturnSuccess<T, E = unknown> extends I_ReturnBase {
39
39
  success: true;
40
40
  result: T & E;
41
+ /** True when results were limited by a default cap and may not include all matching documents. */
42
+ truncated?: boolean;
41
43
  }
42
44
  /**
43
45
  * Failure return type with error information.
@@ -67,6 +69,22 @@ export interface I_ReturnFailure extends I_ReturnBase {
67
69
  * ```
68
70
  */
69
71
  export type I_Return<T = void, E = unknown> = I_ReturnSuccess<T, E> | I_ReturnFailure;
72
+ /**
73
+ * Type guard that narrows an `I_Return` to `I_ReturnSuccess`.
74
+ *
75
+ * @param result - The result to check.
76
+ * @returns True if the result is a success.
77
+ */
78
+ export declare function isSuccess<T, E = unknown>(result: I_Return<T, E>): result is I_ReturnSuccess<T, E>;
79
+ /**
80
+ * Unwraps a successful `I_Return`, throwing an error for failure cases.
81
+ * Useful when a failure is unexpected and should abort execution.
82
+ *
83
+ * @param result - The result to unwrap.
84
+ * @returns The success result value.
85
+ * @throws {Error} When the result is a failure.
86
+ */
87
+ export declare function unwrapResult<T, E = unknown>(result: I_Return<T, E>): T & E;
70
88
  export declare enum E_Environment {
71
89
  PRODUCTION = "production",
72
90
  STAGING = "staging",
@@ -1,8 +1,15 @@
1
1
  //#region src/typescript/common.type.ts
2
- var e = /* @__PURE__ */ function(e) {
2
+ function e(e) {
3
+ return e.success;
4
+ }
5
+ function t(e) {
6
+ if (!e.success) throw Error(e.message);
7
+ return e.result;
8
+ }
9
+ var n = /* @__PURE__ */ function(e) {
3
10
  return e.PRODUCTION = "production", e.STAGING = "staging", e.DEVELOPMENT = "development", e;
4
11
  }({});
5
12
  //#endregion
6
- export { e as E_Environment };
13
+ export { n as E_Environment, e as isSuccess, t as unwrapResult };
7
14
 
8
15
  //# sourceMappingURL=common.type.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.type.js","names":[],"sources":["../../src/typescript/common.type.ts"],"sourcesContent":["import type consola from 'consola';\n\n/**\n * Generic object type with string keys and values of type T (defaults to unknown).\n */\nexport type T_Object<T = unknown> = Record<string, T>;\n\n/**\n * Logging interface for browser and Node.js environments, compatible with consola.\n */\nexport interface I_Log {\n silent: typeof consola['silent'];\n level: typeof consola['level'];\n fatal: typeof consola['fatal'];\n error: typeof consola['error'];\n warn: typeof consola['warn'];\n log: typeof consola['log'];\n info: typeof consola['info'];\n success: typeof consola['success'];\n ready: typeof consola['ready'];\n start: typeof consola['start'];\n box: typeof consola['box'];\n debug: typeof consola['debug'];\n trace: typeof consola['trace'];\n verbose: typeof consola['verbose'];\n}\n\n/**\n * Base interface for return types with common properties.\n */\nexport interface I_ReturnBase {\n success: boolean;\n message?: string;\n code?: number | string;\n}\n\n/**\n * Success return type with result data.\n * @template T - The main result type\n * @template E - Additional properties to merge with the result (defaults to unknown)\n */\nexport interface I_ReturnSuccess<T, E = unknown> extends I_ReturnBase {\n success: true;\n result: T & E;\n}\n\n/**\n * Failure return type with error information.\n */\nexport interface I_ReturnFailure extends I_ReturnBase {\n success: false;\n message: string;\n code: number | string;\n}\n\n/**\n * Discriminated union type for function return values.\n * Provides type-safe handling of success and failure cases.\n *\n * @template T - The success result type (defaults to void)\n * @template E - Additional properties to merge with the result (defaults to unknown)\n *\n * @example\n * ```typescript\n * function fetchUser(id: string): I_Return<User> {\n * try {\n * const user = await getUser(id);\n * return { success: true, result: user };\n * } catch (error) {\n * return { success: false, message: error.message, code: 'USER_NOT_FOUND' };\n * }\n * }\n * ```\n */\nexport type I_Return<T = void, E = unknown> = I_ReturnSuccess<T, E> | I_ReturnFailure;\n\nexport enum E_Environment {\n PRODUCTION = 'production',\n STAGING = 'staging',\n DEVELOPMENT = 'development',\n}\n"],"mappings":";AA4EA,IAAY,IAAL,yBAAA,GAAA;QACH,EAAA,aAAA,cACA,EAAA,UAAA,WACA,EAAA,cAAA;KACH"}
1
+ {"version":3,"file":"common.type.js","names":[],"sources":["../../src/typescript/common.type.ts"],"sourcesContent":["import type consola from 'consola';\n\n/**\n * Generic object type with string keys and values of type T (defaults to unknown).\n */\nexport type T_Object<T = unknown> = Record<string, T>;\n\n/**\n * Logging interface for browser and Node.js environments, compatible with consola.\n */\nexport interface I_Log {\n silent: typeof consola['silent'];\n level: typeof consola['level'];\n fatal: typeof consola['fatal'];\n error: typeof consola['error'];\n warn: typeof consola['warn'];\n log: typeof consola['log'];\n info: typeof consola['info'];\n success: typeof consola['success'];\n ready: typeof consola['ready'];\n start: typeof consola['start'];\n box: typeof consola['box'];\n debug: typeof consola['debug'];\n trace: typeof consola['trace'];\n verbose: typeof consola['verbose'];\n}\n\n/**\n * Base interface for return types with common properties.\n */\nexport interface I_ReturnBase {\n success: boolean;\n message?: string;\n code?: number | string;\n}\n\n/**\n * Success return type with result data.\n * @template T - The main result type\n * @template E - Additional properties to merge with the result (defaults to unknown)\n */\nexport interface I_ReturnSuccess<T, E = unknown> extends I_ReturnBase {\n success: true;\n result: T & E;\n /** True when results were limited by a default cap and may not include all matching documents. */\n truncated?: boolean;\n}\n\n/**\n * Failure return type with error information.\n */\nexport interface I_ReturnFailure extends I_ReturnBase {\n success: false;\n message: string;\n code: number | string;\n}\n\n/**\n * Discriminated union type for function return values.\n * Provides type-safe handling of success and failure cases.\n *\n * @template T - The success result type (defaults to void)\n * @template E - Additional properties to merge with the result (defaults to unknown)\n *\n * @example\n * ```typescript\n * function fetchUser(id: string): I_Return<User> {\n * try {\n * const user = await getUser(id);\n * return { success: true, result: user };\n * } catch (error) {\n * return { success: false, message: error.message, code: 'USER_NOT_FOUND' };\n * }\n * }\n * ```\n */\nexport type I_Return<T = void, E = unknown> = I_ReturnSuccess<T, E> | I_ReturnFailure;\n\n/**\n * Type guard that narrows an `I_Return` to `I_ReturnSuccess`.\n *\n * @param result - The result to check.\n * @returns True if the result is a success.\n */\nexport function isSuccess<T, E = unknown>(result: I_Return<T, E>): result is I_ReturnSuccess<T, E> {\n return result.success;\n}\n\n/**\n * Unwraps a successful `I_Return`, throwing an error for failure cases.\n * Useful when a failure is unexpected and should abort execution.\n *\n * @param result - The result to unwrap.\n * @returns The success result value.\n * @throws {Error} When the result is a failure.\n */\nexport function unwrapResult<T, E = unknown>(result: I_Return<T, E>): T & E {\n if (!result.success) {\n throw new Error(result.message);\n }\n\n return result.result;\n}\n\nexport enum E_Environment {\n PRODUCTION = 'production',\n STAGING = 'staging',\n DEVELOPMENT = 'development',\n}\n"],"mappings":";AAoFA,SAAgB,EAA0B,GAAyD;AAC/F,QAAO,EAAO;;AAWlB,SAAgB,EAA6B,GAA+B;AACxE,KAAI,CAAC,EAAO,QACR,OAAU,MAAM,EAAO,QAAQ;AAGnC,QAAO,EAAO;;AAGlB,IAAY,IAAL,yBAAA,GAAA;QACH,EAAA,aAAA,cACA,EAAA,UAAA,WACA,EAAA,cAAA;KACH"}
@@ -1,2 +1,2 @@
1
- import { E_Environment as e } from "./common.type.js";
2
- export { e as E_Environment };
1
+ import { E_Environment as e, isSuccess as t, unwrapResult as n } from "./common.type.js";
2
+ export { e as E_Environment, t as isSuccess, n as unwrapResult };
@@ -33,45 +33,52 @@ function r(e, t, r) {
33
33
  return t.length === 0 ? e : n(e, t, r, 0);
34
34
  }
35
35
  function i(e) {
36
+ return a(e, /* @__PURE__ */ new WeakSet());
37
+ }
38
+ function a(e, t) {
36
39
  if (typeof e != "object" || !e) return e;
37
- if (e instanceof Date) return new Date(e.getTime());
40
+ if (t.has(e)) throw Error("deepClone: Circular reference detected.");
41
+ if (t.add(e), e instanceof Date) return new Date(e.getTime());
38
42
  if (e instanceof RegExp) return new RegExp(e.source, e.flags);
39
43
  if (Array.isArray(e)) {
40
- let t = e.length, n = Array(t);
41
- for (let r = 0; r < t; r++) n[r] = i(e[r]);
42
- return n;
44
+ let n = e.length, r = Array(n);
45
+ for (let i = 0; i < n; i++) r[i] = a(e[i], t);
46
+ return r;
43
47
  }
44
- let t = Object.getPrototypeOf(e);
45
- if (t !== Object.prototype && t !== null) return e;
46
- let n = {};
47
- for (let t in e) Object.hasOwn(e, t) && (n[t] = i(e[t]));
48
- return n;
48
+ let n = Object.getPrototypeOf(e);
49
+ if (n !== Object.prototype && n !== null) return e;
50
+ let r = {};
51
+ for (let n in e) Object.hasOwn(e, n) && (r[n] = a(e[n], t));
52
+ return r;
49
53
  }
50
- function a(...e) {
51
- if (e.length === 0) return {};
52
- let t = e.filter((e) => e != null);
53
- if (t.length === 0) return {};
54
- if (t.length === 1) return t[0];
55
- if (t.every(Array.isArray)) return t.flat();
56
- if (t.every((e) => typeof e == "object" && !!e && !Array.isArray(e))) {
57
- let e = {};
58
- for (let n of t) {
59
- let t = n;
60
- for (let n in t) if (Object.hasOwn(t, n)) {
61
- let r = t[n];
62
- if (Object.hasOwn(e, n)) {
63
- let t = e[n];
64
- typeof r == "object" && r && typeof t == "object" && t ? Array.isArray(r) && Array.isArray(t) ? e[n] = [...t, ...r] : !Array.isArray(r) && !Array.isArray(t) ? e[n] = a(t, r) : e[n] = r : e[n] = r;
65
- } else e[n] = r;
54
+ function o(...e) {
55
+ function t(e, n, r) {
56
+ if (n > 20) throw Error("deepMerge: Maximum depth of 20 exceeded. Possible circular reference or excessively nested objects.");
57
+ if (e.length === 0) return {};
58
+ if (e.length === 1) return e[0];
59
+ if (e.every(Array.isArray)) return e.flat();
60
+ if (e.every((e) => typeof e == "object" && !!e && !Array.isArray(e))) {
61
+ let i = {};
62
+ for (let a of e) {
63
+ if (r.has(a)) throw Error("deepMerge: Circular reference detected.");
64
+ let e = a;
65
+ for (let r in e) if (Object.hasOwn(e, r)) {
66
+ let a = e[r];
67
+ if (Object.hasOwn(i, r)) {
68
+ let e = i[r];
69
+ typeof a == "object" && a && typeof e == "object" && e ? Array.isArray(a) && Array.isArray(e) ? i[r] = [...e, ...a] : !Array.isArray(a) && !Array.isArray(e) ? i[r] = t([e, a], n + 1, /* @__PURE__ */ new WeakSet()) : i[r] = a : i[r] = a;
70
+ } else i[r] = a;
71
+ }
66
72
  }
73
+ return i;
67
74
  }
68
- return e;
75
+ if (e.every((e) => typeof e != "object" || !e)) throw Error("deepMerge: Cannot merge primitive values. All arguments must be objects or arrays.");
76
+ let i = e.some(Array.isArray), a = e.some((e) => typeof e == "object" && !!e && !Array.isArray(e));
77
+ throw Error(i && a ? "deepMerge: Cannot mix arrays and objects. All arguments must be either arrays or objects." : "deepMerge: Invalid arguments provided. All arguments must be objects or arrays of the same type.");
69
78
  }
70
- if (t.every((e) => typeof e != "object" || !e)) throw Error("deepMerge: Cannot merge primitive values. All arguments must be objects or arrays.");
71
- let n = t.some(Array.isArray), r = t.some((e) => typeof e == "object" && !!e && !Array.isArray(e));
72
- throw Error(n && r ? "deepMerge: Cannot mix arrays and objects. All arguments must be either arrays or objects." : "deepMerge: Invalid arguments provided. All arguments must be objects or arrays of the same type.");
79
+ return t(e.filter((e) => e != null), 0, /* @__PURE__ */ new WeakSet());
73
80
  }
74
- function o(e) {
81
+ function s(e) {
75
82
  if (!e || typeof e != "object") return e;
76
83
  let t = {};
77
84
  function n(e, r) {
@@ -79,23 +86,22 @@ function o(e) {
79
86
  if (!Object.hasOwn(e, i)) continue;
80
87
  let a = e[i], o = r ? `${r}.${i}` : i;
81
88
  if (a && typeof a == "object" && !Array.isArray(a)) {
82
- let e = Object.getPrototypeOf(a);
83
- if (e !== Object.prototype && e !== null) {
89
+ if (!(a.constructor === Object || Object.getPrototypeOf(a) === null)) {
84
90
  t[o] = a;
85
91
  continue;
86
92
  }
87
- let r = !1;
88
- for (let e in a) if (Object.hasOwn(a, e) && e.startsWith("$")) {
89
- r = !0;
93
+ let e = !1;
94
+ for (let t in a) if (Object.hasOwn(a, t) && t.startsWith("$")) {
95
+ e = !0;
90
96
  break;
91
97
  }
92
- r ? t[o] = a : n(a, o);
98
+ e ? t[o] = a : n(a, o);
93
99
  } else t[o] = a;
94
100
  }
95
101
  }
96
102
  return n(e, ""), t;
97
103
  }
98
104
  //#endregion
99
- export { i as deepClone, a as deepMerge, t as getNestedValue, e as isJSON, o as normalizeMongoFilter, r as setNestedValue };
105
+ export { i as deepClone, o as deepMerge, t as getNestedValue, e as isJSON, s as normalizeMongoFilter, r as setNestedValue };
100
106
 
101
107
  //# sourceMappingURL=object.util.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"object.util.js","names":[],"sources":["../../../src/util/object/object.util.ts"],"sourcesContent":["/**\n * Check if a string is a valid JSON string.\n * This function attempts to parse the string as JSON and returns true if successful,\n * false if the string is not valid JSON.\n *\n * @param str - The string to check for valid JSON format.\n * @returns True if the string is a valid JSON string, false otherwise.\n */\nexport function isJSON(str: string): boolean {\n try {\n JSON.parse(str);\n return true;\n }\n catch {\n return false;\n }\n}\n\n/**\n * Gets a nested value from an object using a path array.\n * This function traverses the object following the provided path and returns\n * the value at the specified location, or undefined if the path doesn't exist.\n *\n * @param obj - The object to get the value from.\n * @param path - An array of keys representing the path to the desired value.\n * @returns The value at the specified path, or undefined if the path doesn't exist.\n */\nexport function getNestedValue<T>(obj: T, path: (string | number)[]): unknown {\n // Optimization: Loop is faster than reduce and allows early exit\n let current: unknown = obj;\n const len = path.length;\n\n for (let i = 0; i < len; i++) {\n // Optimization: Early return if current value is null/undefined or not an object\n // This avoids unnecessary key lookups and type checks\n if (current == null || typeof current !== 'object') {\n return undefined;\n }\n\n const key = path[i];\n\n if (key !== undefined && key in (current as Record<string | number, unknown>)) {\n current = (current as Record<string | number, unknown>)[key];\n }\n else {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Recursively sets a value at a nested path within an object, creating intermediate objects as needed.\n *\n * @param obj - The source object.\n * @param path - Array of keys forming the path.\n * @param value - The value to set.\n * @param index - Current recursion depth.\n * @returns A new object with the value set at the specified path.\n */\nfunction setNestedValueHelper<T>(obj: T, path: (string | number)[], value: unknown, index: number): T {\n if (index >= path.length)\n return obj;\n\n const head = path[index];\n\n if (index === path.length - 1) {\n return {\n ...(obj as Record<string | number, unknown>),\n [head as string | number]: value,\n } as T;\n }\n\n const current = (obj as Record<string | number, unknown>)[head as string | number];\n\n return {\n ...(obj as Record<string | number, unknown>),\n [head as string | number | symbol]: setNestedValueHelper(\n typeof current === 'object' && current !== null\n ? (current as object)\n : {},\n path,\n value,\n index + 1,\n ),\n } as T;\n}\n\n/**\n * Sets a nested value in an object using a path array.\n * This function creates the path if it doesn't exist and sets the value at the specified location.\n * The function returns a new object with the updated value, maintaining immutability.\n *\n * @param obj - The object to set the value in.\n * @param path - An array of keys representing the path to the desired location.\n * @param value - The value to set at the specified path.\n * @returns A new object with the updated value at the specified path.\n */\nexport function setNestedValue<T>(obj: T, path: (string | number)[], value: unknown): T {\n if (path.length === 0)\n return obj;\n\n return setNestedValueHelper(obj, path, value, 0);\n}\n\n/**\n * Deep clones an object or array.\n * This function creates a deep copy of the input, recursively cloning objects and arrays.\n * Primitive values, dates, and other non-plain objects are returned as is (or cloned if supported).\n * Note: This implementation focuses on plain objects and arrays. For complex types like Map/Set/Buffer/ObjectId,\n * it returns the reference or handles them according to specific logic.\n *\n * @param obj - The object to clone.\n * @returns A deep copy of the object.\n */\nexport function deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as unknown as T;\n }\n\n if (obj instanceof RegExp) {\n return new RegExp(obj.source, obj.flags) as unknown as T;\n }\n\n if (Array.isArray(obj)) {\n // Optimization: `new Array(len)` + `for` loop is ~10-15% faster than `Array.map` or `Array.from`\n // for large arrays since it avoids callback overhead and pre-allocates memory.\n const len = obj.length;\n // eslint-disable-next-line unicorn/no-new-array -- Pre-allocating array size for performance\n const arr = new Array(len);\n for (let i = 0; i < len; i++) {\n arr[i] = deepClone(obj[i]);\n }\n return arr as unknown as T;\n }\n\n // Handle Mongoose ObjectId and other custom classes by returning reference.\n // structuredClone is not used here because it silently corrupts nested non-POJO\n // types (e.g., ObjectId → plain object) and Date instances in jsdom environments.\n const proto = Object.getPrototypeOf(obj);\n if (proto !== Object.prototype && proto !== null) {\n return obj;\n }\n\n const result = {} as Record<string, unknown>;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n result[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n }\n\n return result as T;\n}\n\n/**\n * Deep merges multiple objects into a single object.\n * @param args - The objects to merge. Can be empty, in which case returns an empty object.\n * @returns The merged object.\n */\nexport function deepMerge<T = Record<string, unknown>>(\n ...args: (object | null | undefined)[]\n): T;\n\n/**\n * Deep merges multiple arrays into a single array.\n * @param args - The arrays to merge. Can be empty, in which case returns an empty array.\n * @returns The merged array.\n */\nexport function deepMerge<T = unknown[]>(\n ...args: (unknown[] | null | undefined)[]\n): T;\n\n/**\n * Implementation of deepMerge function.\n * @param args - The objects or arrays to merge.\n * @returns The merged result.\n */\nexport function deepMerge<T = Record<string, unknown> | unknown[]>(\n ...args: (object | unknown[] | null | undefined)[]\n): T {\n // Handle empty arguments\n if (args.length === 0) {\n return {} as T;\n }\n\n // Filter out null/undefined and convert to empty objects/arrays\n const validArgs = args.filter((arg): arg is object => arg !== null && arg !== undefined);\n\n // If no valid arguments after filtering, return empty object/array\n if (validArgs.length === 0) {\n return {} as T;\n }\n\n // If only one argument, return it directly\n if (validArgs.length === 1) {\n return validArgs[0] as T;\n }\n\n // Check if all arguments are arrays\n if (validArgs.every(Array.isArray)) {\n return (validArgs as unknown[][]).flat() as T;\n }\n\n // Check if all arguments are objects (but not arrays)\n if (validArgs.every(arg => typeof arg === 'object' && arg !== null && !Array.isArray(arg))) {\n const result = {} as Record<string, unknown>;\n\n for (const arg of validArgs) {\n const obj = arg as Record<string, unknown>;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n const value = obj[key];\n if (Object.hasOwn(result, key)) {\n const existingValue = result[key];\n if (\n typeof value === 'object' && value !== null\n && typeof existingValue === 'object' && existingValue !== null\n ) {\n if (Array.isArray(value) && Array.isArray(existingValue)) {\n result[key] = [...existingValue, ...value];\n }\n else if (!Array.isArray(value) && !Array.isArray(existingValue)) {\n result[key] = deepMerge(\n existingValue as Record<string, unknown>,\n value as Record<string, unknown>,\n );\n }\n else {\n // One is array, other is object (shouldn't happen with strict types but possible)\n // Overwrite\n result[key] = value;\n }\n }\n else {\n result[key] = value;\n }\n }\n else {\n result[key] = value;\n }\n }\n }\n }\n return result as T;\n }\n\n // Check if all arguments are primitive values\n if (validArgs.every(arg => typeof arg !== 'object' || arg === null)) {\n throw new Error(\n 'deepMerge: Cannot merge primitive values. All arguments must be objects or arrays.',\n );\n }\n\n // Mixed types error\n const hasArrays = validArgs.some(Array.isArray);\n const hasObjects = validArgs.some(arg =>\n typeof arg === 'object' && arg !== null && !Array.isArray(arg),\n );\n\n if (hasArrays && hasObjects) {\n throw new Error(\n 'deepMerge: Cannot mix arrays and objects. All arguments must be either arrays or objects.',\n );\n }\n\n // Fallback for unexpected cases\n throw new Error(\n 'deepMerge: Invalid arguments provided. All arguments must be objects or arrays of the same type.',\n );\n}\n\n/**\n * Normalizes MongoDB filters to support both dot notation strings and nested objects.\n * This function converts nested object filters to dot notation format while preserving\n * MongoDB operators to ensure consistent behavior across different filter input formats.\n *\n * @param filter - The filter object to normalize.\n * @returns A normalized filter object with nested objects converted to dot notation,\n * while preserving MongoDB operators as nested objects.\n *\n * @example\n * ```typescript\n * // Both of these will work the same way:\n * normalizeMongoFilter({ \"location.countryId\": \"240\" })\n * normalizeMongoFilter({ location: { countryId: \"240\" } })\n * // Both return: { \"location.countryId\": \"240\" }\n *\n * // MongoDB operators are preserved:\n * normalizeMongoFilter({ id: { $in: [\"240\", \"59\"] } })\n * // Returns: { id: { $in: [\"240\", \"59\"] } }\n * ```\n */\nexport function normalizeMongoFilter<T extends Record<string, unknown>>(filter: T): T {\n if (!filter || typeof filter !== 'object') {\n return filter;\n }\n\n const normalized: Record<string, unknown> = {};\n\n /**\n * Recursively flattens nested objects into dot-notation keys, preserving MongoDB operators.\n */\n function flatten(current: Record<string, unknown>, prefix: string) {\n for (const key in current) {\n if (!Object.hasOwn(current, key))\n continue;\n\n const value = current[key];\n const newKey = prefix ? `${prefix}.${key}` : key;\n\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n // Skip flattening for Mongoose ObjectId, Date, RegExp, and other non-POJO types\n const valueProto = Object.getPrototypeOf(value);\n if (valueProto !== Object.prototype && valueProto !== null) {\n normalized[newKey] = value;\n continue;\n }\n\n // Check for Mongo operator\n let hasMongoOperator = false;\n for (const subKey in value as Record<string, unknown>) {\n if (Object.hasOwn(value, subKey) && subKey.startsWith('$')) {\n hasMongoOperator = true;\n break;\n }\n }\n\n if (hasMongoOperator) {\n normalized[newKey] = value;\n }\n else {\n flatten(value as Record<string, unknown>, newKey);\n }\n }\n else {\n normalized[newKey] = value;\n }\n }\n }\n\n flatten(filter, '');\n\n return normalized as T;\n}\n"],"mappings":";AAQA,SAAgB,EAAO,GAAsB;AACzC,KAAI;AAEA,SADA,KAAK,MAAM,EAAI,EACR;SAEL;AACF,SAAO;;;AAaf,SAAgB,EAAkB,GAAQ,GAAoC;CAE1E,IAAI,IAAmB,GACjB,IAAM,EAAK;AAEjB,MAAK,IAAI,IAAI,GAAG,IAAI,GAAK,KAAK;AAG1B,MAAuB,OAAO,KAAY,aAAtC,EACA;EAGJ,IAAM,IAAM,EAAK;AAEjB,MAAI,MAAQ,KAAA,KAAa,KAAQ,EAC7B,KAAW,EAA6C;MAGxD;;AAIR,QAAO;;AAYX,SAAS,EAAwB,GAAQ,GAA2B,GAAgB,GAAkB;AAClG,KAAI,KAAS,EAAK,OACd,QAAO;CAEX,IAAM,IAAO,EAAK;AAElB,KAAI,MAAU,EAAK,SAAS,EACxB,QAAO;EACH,GAAI;GACH,IAA0B;EAC9B;CAGL,IAAM,IAAW,EAAyC;AAE1D,QAAO;EACH,GAAI;GACH,IAAmC,EAChC,OAAO,KAAY,YAAY,IACxB,IACD,EAAE,EACR,GACA,GACA,IAAQ,EACX;EACJ;;AAaL,SAAgB,EAAkB,GAAQ,GAA2B,GAAmB;AAIpF,QAHI,EAAK,WAAW,IACT,IAEJ,EAAqB,GAAK,GAAM,GAAO,EAAE;;AAapD,SAAgB,EAAa,GAAW;AACpC,KAAoB,OAAO,KAAQ,aAA/B,EACA,QAAO;AAGX,KAAI,aAAe,KACf,QAAO,IAAI,KAAK,EAAI,SAAS,CAAC;AAGlC,KAAI,aAAe,OACf,QAAO,IAAI,OAAO,EAAI,QAAQ,EAAI,MAAM;AAG5C,KAAI,MAAM,QAAQ,EAAI,EAAE;EAGpB,IAAM,IAAM,EAAI,QAEV,IAAU,MAAM,EAAI;AAC1B,OAAK,IAAI,IAAI,GAAG,IAAI,GAAK,IACrB,GAAI,KAAK,EAAU,EAAI,GAAG;AAE9B,SAAO;;CAMX,IAAM,IAAQ,OAAO,eAAe,EAAI;AACxC,KAAI,MAAU,OAAO,aAAa,MAAU,KACxC,QAAO;CAGX,IAAM,IAAS,EAAE;AACjB,MAAK,IAAM,KAAO,EACd,CAAI,OAAO,OAAO,GAAK,EAAI,KACvB,EAAO,KAAO,EAAW,EAAgC,GAAK;AAItE,QAAO;;AA0BX,SAAgB,EACZ,GAAG,GACF;AAED,KAAI,EAAK,WAAW,EAChB,QAAO,EAAE;CAIb,IAAM,IAAY,EAAK,QAAQ,MAAuB,KAAQ,KAA0B;AAGxF,KAAI,EAAU,WAAW,EACrB,QAAO,EAAE;AAIb,KAAI,EAAU,WAAW,EACrB,QAAO,EAAU;AAIrB,KAAI,EAAU,MAAM,MAAM,QAAQ,CAC9B,QAAQ,EAA0B,MAAM;AAI5C,KAAI,EAAU,OAAM,MAAO,OAAO,KAAQ,cAAY,KAAgB,CAAC,MAAM,QAAQ,EAAI,CAAC,EAAE;EACxF,IAAM,IAAS,EAAE;AAEjB,OAAK,IAAM,KAAO,GAAW;GACzB,IAAM,IAAM;AACZ,QAAK,IAAM,KAAO,EACd,KAAI,OAAO,OAAO,GAAK,EAAI,EAAE;IACzB,IAAM,IAAQ,EAAI;AAClB,QAAI,OAAO,OAAO,GAAQ,EAAI,EAAE;KAC5B,IAAM,IAAgB,EAAO;AAC7B,KACI,OAAO,KAAU,YAAY,KAC1B,OAAO,KAAkB,YAAY,IAEpC,MAAM,QAAQ,EAAM,IAAI,MAAM,QAAQ,EAAc,GACpD,EAAO,KAAO,CAAC,GAAG,GAAe,GAAG,EAAM,GAErC,CAAC,MAAM,QAAQ,EAAM,IAAI,CAAC,MAAM,QAAQ,EAAc,GAC3D,EAAO,KAAO,EACV,GACA,EACH,GAKD,EAAO,KAAO,IAIlB,EAAO,KAAO;UAIlB,GAAO,KAAO;;;AAK9B,SAAO;;AAIX,KAAI,EAAU,OAAM,MAAO,OAAO,KAAQ,aAAY,EAAa,CAC/D,OAAU,MACN,qFACH;CAIL,IAAM,IAAY,EAAU,KAAK,MAAM,QAAQ,EACzC,IAAa,EAAU,MAAK,MAC9B,OAAO,KAAQ,cAAY,KAAgB,CAAC,MAAM,QAAQ,EAAI,CACjE;AASD,OANc,MADV,KAAa,IAET,8FAMJ,mGALC;;AA8BT,SAAgB,EAAwD,GAAc;AAClF,KAAI,CAAC,KAAU,OAAO,KAAW,SAC7B,QAAO;CAGX,IAAM,IAAsC,EAAE;CAK9C,SAAS,EAAQ,GAAkC,GAAgB;AAC/D,OAAK,IAAM,KAAO,GAAS;AACvB,OAAI,CAAC,OAAO,OAAO,GAAS,EAAI,CAC5B;GAEJ,IAAM,IAAQ,EAAQ,IAChB,IAAS,IAAS,GAAG,EAAO,GAAG,MAAQ;AAE7C,OAAI,KAAS,OAAO,KAAU,YAAY,CAAC,MAAM,QAAQ,EAAM,EAAE;IAE7D,IAAM,IAAa,OAAO,eAAe,EAAM;AAC/C,QAAI,MAAe,OAAO,aAAa,MAAe,MAAM;AACxD,OAAW,KAAU;AACrB;;IAIJ,IAAI,IAAmB;AACvB,SAAK,IAAM,KAAU,EACjB,KAAI,OAAO,OAAO,GAAO,EAAO,IAAI,EAAO,WAAW,IAAI,EAAE;AACxD,SAAmB;AACnB;;AAIR,IAAI,IACA,EAAW,KAAU,IAGrB,EAAQ,GAAkC,EAAO;SAIrD,GAAW,KAAU;;;AAOjC,QAFA,EAAQ,GAAQ,GAAG,EAEZ"}
1
+ {"version":3,"file":"object.util.js","names":[],"sources":["../../../src/util/object/object.util.ts"],"sourcesContent":["/**\n * Check if a string is a valid JSON string.\n * This function attempts to parse the string as JSON and returns true if successful,\n * false if the string is not valid JSON.\n *\n * @param str - The string to check for valid JSON format.\n * @returns True if the string is a valid JSON string, false otherwise.\n */\nexport function isJSON(str: string): boolean {\n try {\n JSON.parse(str);\n return true;\n }\n catch {\n return false;\n }\n}\n\n/**\n * Gets a nested value from an object using a path array.\n * This function traverses the object following the provided path and returns\n * the value at the specified location, or undefined if the path doesn't exist.\n *\n * @param obj - The object to get the value from.\n * @param path - An array of keys representing the path to the desired value.\n * @returns The value at the specified path, or undefined if the path doesn't exist.\n */\nexport function getNestedValue<T>(obj: T, path: (string | number)[]): unknown {\n // Optimization: Loop is faster than reduce and allows early exit\n let current: unknown = obj;\n const len = path.length;\n\n for (let i = 0; i < len; i++) {\n // Optimization: Early return if current value is null/undefined or not an object\n // This avoids unnecessary key lookups and type checks\n if (current == null || typeof current !== 'object') {\n return undefined;\n }\n\n const key = path[i];\n\n if (key !== undefined && key in (current as Record<string | number, unknown>)) {\n current = (current as Record<string | number, unknown>)[key];\n }\n else {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Recursively sets a value at a nested path within an object, creating intermediate objects as needed.\n *\n * @param obj - The source object.\n * @param path - Array of keys forming the path.\n * @param value - The value to set.\n * @param index - Current recursion depth.\n * @returns A new object with the value set at the specified path.\n */\nfunction setNestedValueHelper<T>(obj: T, path: (string | number)[], value: unknown, index: number): T {\n if (index >= path.length)\n return obj;\n\n const head = path[index];\n\n if (index === path.length - 1) {\n return {\n ...(obj as Record<string | number, unknown>),\n [head as string | number]: value,\n } as T;\n }\n\n const current = (obj as Record<string | number, unknown>)[head as string | number];\n\n return {\n ...(obj as Record<string | number, unknown>),\n [head as string | number | symbol]: setNestedValueHelper(\n typeof current === 'object' && current !== null\n ? (current as object)\n : {},\n path,\n value,\n index + 1,\n ),\n } as T;\n}\n\n/**\n * Sets a nested value in an object using a path array.\n * This function creates the path if it doesn't exist and sets the value at the specified location.\n * The function returns a new object with the updated value, maintaining immutability.\n *\n * @param obj - The object to set the value in.\n * @param path - An array of keys representing the path to the desired location.\n * @param value - The value to set at the specified path.\n * @returns A new object with the updated value at the specified path.\n */\nexport function setNestedValue<T>(obj: T, path: (string | number)[], value: unknown): T {\n if (path.length === 0)\n return obj;\n\n return setNestedValueHelper(obj, path, value, 0);\n}\n\n/**\n * Deep clones an object or array.\n * This function creates a deep copy of the input, recursively cloning objects and arrays.\n * Primitive values, dates, and other non-plain objects are returned as is (or cloned if supported).\n * Note: This implementation focuses on plain objects and arrays. For complex types like Map/Set/Buffer/ObjectId,\n * it returns the reference or handles them according to specific logic.\n *\n * @param obj - The object to clone.\n * @returns A deep copy of the object.\n */\nexport function deepClone<T>(obj: T): T {\n return deepCloneInternal(obj, new WeakSet<object>());\n}\n\n/**\n * Internal recursive implementation of deepClone with circular reference detection.\n *\n * @param obj - The value to clone.\n * @param seen - A WeakSet tracking already-visited objects to prevent infinite recursion.\n * @returns A deep copy of the value.\n */\nfunction deepCloneInternal<T>(obj: T, seen: WeakSet<object>): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (seen.has(obj as object)) {\n throw new Error('deepClone: Circular reference detected.');\n }\n seen.add(obj as object);\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as unknown as T;\n }\n\n if (obj instanceof RegExp) {\n return new RegExp(obj.source, obj.flags) as unknown as T;\n }\n\n if (Array.isArray(obj)) {\n // Optimization: `new Array(len)` + `for` loop is ~10-15% faster than `Array.map` or `Array.from`\n // for large arrays since it avoids callback overhead and pre-allocates memory.\n const len = obj.length;\n // eslint-disable-next-line unicorn/no-new-array -- Pre-allocating array size for performance\n const arr = new Array(len);\n for (let i = 0; i < len; i++) {\n arr[i] = deepCloneInternal(obj[i], seen);\n }\n return arr as unknown as T;\n }\n\n // Handle Mongoose ObjectId and other custom classes by returning reference.\n // structuredClone is not used here because it silently corrupts nested non-POJO\n // types (e.g., ObjectId → plain object) and Date instances in jsdom environments.\n const proto = Object.getPrototypeOf(obj);\n if (proto !== Object.prototype && proto !== null) {\n return obj;\n }\n\n const result = {} as Record<string, unknown>;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n result[key] = deepCloneInternal((obj as Record<string, unknown>)[key], seen);\n }\n }\n\n return result as T;\n}\n\n/**\n * Deep merges multiple objects into a single object.\n * @param args - The objects to merge. Can be empty, in which case returns an empty object.\n * @returns The merged object.\n */\nexport function deepMerge<T = Record<string, unknown>>(\n ...args: (object | null | undefined)[]\n): T;\n\n/**\n * Deep merges multiple arrays into a single array.\n * @param args - The arrays to merge. Can be empty, in which case returns an empty array.\n * @returns The merged array.\n */\nexport function deepMerge<T = unknown[]>(\n ...args: (unknown[] | null | undefined)[]\n): T;\n\n/**\n * Implementation of deepMerge function.\n * @param args - The objects or arrays to merge.\n * @returns The merged result.\n */\nexport function deepMerge<T = Record<string, unknown> | unknown[]>(\n ...args: (object | unknown[] | null | undefined)[]\n): T {\n const MAX_DEPTH = 20;\n\n /** Recursively merges an array of objects with depth and circular-reference tracking. */\n function mergeRecursive(\n validArgs: object[],\n depth: number,\n seen: WeakSet<object>,\n ): unknown {\n // Depth guard\n if (depth > MAX_DEPTH) {\n throw new Error(`deepMerge: Maximum depth of ${MAX_DEPTH} exceeded. Possible circular reference or excessively nested objects.`);\n }\n\n // Handle empty arguments\n if (validArgs.length === 0) {\n return {};\n }\n\n // If only one argument, return it directly\n if (validArgs.length === 1) {\n return validArgs[0];\n }\n\n // Check if all arguments are arrays\n if (validArgs.every(Array.isArray)) {\n return (validArgs as unknown[][]).flat();\n }\n\n // Check if all arguments are objects (but not arrays)\n if (validArgs.every(arg => typeof arg === 'object' && arg !== null && !Array.isArray(arg))) {\n const result = {} as Record<string, unknown>;\n\n for (const arg of validArgs) {\n // Circular reference protection (per-arg scope prevents false\n // positives when the same object appears in multiple branches)\n if (seen.has(arg)) {\n throw new Error('deepMerge: Circular reference detected.');\n }\n\n const obj = arg as Record<string, unknown>;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n const value = obj[key];\n if (Object.hasOwn(result, key)) {\n const existingValue = result[key];\n if (\n typeof value === 'object' && value !== null\n && typeof existingValue === 'object' && existingValue !== null\n ) {\n if (Array.isArray(value) && Array.isArray(existingValue)) {\n result[key] = [...existingValue, ...value];\n }\n else if (!Array.isArray(value) && !Array.isArray(existingValue)) {\n result[key] = mergeRecursive(\n [existingValue as Record<string, unknown>, value as Record<string, unknown>],\n depth + 1,\n new WeakSet<object>(),\n );\n }\n else {\n // One is array, other is object — overwrite\n result[key] = value;\n }\n }\n else {\n result[key] = value;\n }\n }\n else {\n result[key] = value;\n }\n }\n }\n }\n return result;\n }\n\n // Check if all arguments are primitive values\n if (validArgs.every(arg => typeof arg !== 'object' || arg === null)) {\n throw new Error(\n 'deepMerge: Cannot merge primitive values. All arguments must be objects or arrays.',\n );\n }\n\n // Mixed types error\n const hasArrays = validArgs.some(Array.isArray);\n const hasObjects = validArgs.some(arg =>\n typeof arg === 'object' && arg !== null && !Array.isArray(arg),\n );\n\n if (hasArrays && hasObjects) {\n throw new Error(\n 'deepMerge: Cannot mix arrays and objects. All arguments must be either arrays or objects.',\n );\n }\n\n // Fallback for unexpected cases\n throw new Error(\n 'deepMerge: Invalid arguments provided. All arguments must be objects or arrays of the same type.',\n );\n }\n\n // Filter out null/undefined\n const validArgs = args.filter((arg): arg is object => arg !== null && arg !== undefined);\n\n return mergeRecursive(validArgs, 0, new WeakSet<object>()) as T;\n}\n\n/**\n * Normalizes MongoDB filters to support both dot notation strings and nested objects.\n * This function converts nested object filters to dot notation format while preserving\n * MongoDB operators to ensure consistent behavior across different filter input formats.\n *\n * @param filter - The filter object to normalize.\n * @returns A normalized filter object with nested objects converted to dot notation,\n * while preserving MongoDB operators as nested objects.\n *\n * @example\n * ```typescript\n * // Both of these will work the same way:\n * normalizeMongoFilter({ \"location.countryId\": \"240\" })\n * normalizeMongoFilter({ location: { countryId: \"240\" } })\n * // Both return: { \"location.countryId\": \"240\" }\n *\n * // MongoDB operators are preserved:\n * normalizeMongoFilter({ id: { $in: [\"240\", \"59\"] } })\n * // Returns: { id: { $in: [\"240\", \"59\"] } }\n * ```\n */\nexport function normalizeMongoFilter<T extends Record<string, unknown>>(filter: T): T {\n if (!filter || typeof filter !== 'object') {\n return filter;\n }\n\n const normalized: Record<string, unknown> = {};\n\n /**\n * Recursively flattens nested objects into dot-notation keys, preserving MongoDB operators.\n */\n function flatten(current: Record<string, unknown>, prefix: string) {\n for (const key in current) {\n if (!Object.hasOwn(current, key))\n continue;\n\n const value = current[key];\n const newKey = prefix ? `${prefix}.${key}` : key;\n\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n // Fast-path POJO check: `.constructor` is safe even on null-prototype objects\n // (returns undefined, so the === Object check simply fails and falls through\n // to the getPrototypeOf check which correctly identifies it as a POJO).\n const isPojo = (value as object).constructor === Object\n || Object.getPrototypeOf(value) === null;\n\n if (!isPojo) {\n normalized[newKey] = value;\n continue;\n }\n\n // Check for Mongo operator\n let hasMongoOperator = false;\n for (const subKey in value as Record<string, unknown>) {\n if (Object.hasOwn(value, subKey) && subKey.startsWith('$')) {\n hasMongoOperator = true;\n break;\n }\n }\n\n if (hasMongoOperator) {\n normalized[newKey] = value;\n }\n else {\n flatten(value as Record<string, unknown>, newKey);\n }\n }\n else {\n normalized[newKey] = value;\n }\n }\n }\n\n flatten(filter, '');\n\n return normalized as T;\n}\n"],"mappings":"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"}
@@ -6,5 +6,18 @@ import { I_Serializer } from './serializer.type.js';
6
6
  * The serializer works by:
7
7
  * 1. During serialization: Wrapping special types with type information before JSON stringification
8
8
  * 2. During deserialization: Detecting wrapped types and reconstructing them to their original form
9
+ *
10
+ * @remarks
11
+ * **Wire format protocol:** Non-JSON-native types are serialized as wrapper objects with the shape
12
+ * `{ __type: string, value: unknown }`. For example:
13
+ * - Date → `{ __type: 'Date', value: '2024-01-01T00:00:00.000Z' }`
14
+ * - Map → `{ __type: 'Map', value: [['key', 'val']] }`
15
+ * - Set → `{ __type: 'Set', value: [1, 2, 3] }`
16
+ * - RegExp → `{ __type: 'RegExp', value: { source: '...', flags: '...' } }`
17
+ * - BigInt → `{ __type: 'BigInt', value: '12345' }`
18
+ *
19
+ * **Cross-service compatibility:** Any service that deserializes data produced by this serializer
20
+ * must use the same `__type` protocol. Plain `JSON.parse` will return the wrapper objects as-is
21
+ * without reconstructing the original types.
9
22
  */
10
23
  export declare const serializer: I_Serializer<unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"serializer.util.js","names":[],"sources":["../../../src/util/serializer/serializer.util.ts"],"sourcesContent":["import type {\n I_Serializer,\n I_SerializerTypeWrapper,\n I_SerializerValueMap,\n T_SerializerKnownTypes,\n} from './serializer.type.js';\n\n/**\n * Interface for handling serialization and deserialization of specific types.\n * Each handler provides methods to check if a value is of the specific type,\n * serialize it to a format that can be JSON stringified, and deserialize it back.\n */\ninterface I_Handler<T extends T_SerializerKnownTypes> {\n /** Checks if a value is of the specific type */\n is: (value: unknown) => value is I_SerializerValueMap[T];\n /** Serializes a value of the specific type to a format that can be JSON stringified */\n serialize: (value: I_SerializerValueMap[T]) => I_SerializerTypeWrapper<T>;\n /** Deserializes a value back to the specific type */\n deserialize: (value: unknown) => I_SerializerValueMap[T];\n}\n\n/**\n * Type handlers for different JavaScript types that cannot be directly serialized to JSON.\n * Each handler provides methods to serialize and deserialize specific types like Date, Map, Set, etc.\n */\nconst typeHandlers: {\n [K in T_SerializerKnownTypes]: I_Handler<K>;\n} = {\n Date: {\n is: (v): v is Date => v instanceof Date,\n serialize: v => ({ __type: 'Date', value: v.toISOString() }),\n deserialize: v => new Date(v as string),\n },\n Map: {\n is: (v): v is Map<unknown, unknown> => v instanceof Map,\n serialize: v => ({ __type: 'Map', value: [...v.entries()] }),\n deserialize: v => new Map(v as [unknown, unknown][]),\n },\n Set: {\n is: (v): v is Set<unknown> => v instanceof Set,\n serialize: v => ({ __type: 'Set', value: [...v] }),\n deserialize: v => new Set(v as unknown[]),\n },\n RegExp: {\n is: (v): v is RegExp => v instanceof RegExp,\n serialize: v => ({\n __type: 'RegExp',\n value: { source: v.source, flags: v.flags },\n }),\n deserialize: (v) => {\n const { source, flags } = v as { source: string; flags: string };\n return new RegExp(source, flags);\n },\n },\n BigInt: {\n is: (v): v is bigint => typeof v === 'bigint',\n serialize: v => ({ __type: 'BigInt', value: v.toString() }),\n deserialize: v => BigInt(v as string),\n },\n};\n\n/**\n * A serializer that can handle complex JavaScript types that cannot be directly JSON stringified.\n * This serializer extends JSON.stringify and JSON.parse to handle types like Date, Map, Set, RegExp, and BigInt.\n *\n * The serializer works by:\n * 1. During serialization: Wrapping special types with type information before JSON stringification\n * 2. During deserialization: Detecting wrapped types and reconstructing them to their original form\n */\nexport const serializer: I_Serializer<unknown> = {\n /**\n * Serializes a value to a JSON string.\n * If the value is of a known type (Date, Map, Set, RegExp, BigInt),\n * it will be serialized using the corresponding handler.\n * Otherwise, it will be serialized as is.\n *\n * @param value - The value to serialize to a JSON string.\n * @returns The serialized JSON string that can be safely stored or transmitted.\n */\n serialize(value) {\n return JSON.stringify(value, function (_key, val) {\n // eslint-disable-next-line ts/no-this-alias\n const context = this;\n const originalValue = context[_key];\n\n if (originalValue instanceof Date) {\n return typeHandlers.Date.serialize(originalValue);\n }\n\n for (const type of Object.keys(typeHandlers) as T_SerializerKnownTypes[]) {\n const handler = typeHandlers[type];\n\n if (handler.is(val)) {\n return (handler as I_Handler<typeof type>).serialize(val);\n }\n }\n\n return val;\n });\n },\n /**\n * Deserializes a JSON string to its original value.\n * If the value is of a known type (Date, Map, Set, RegExp, BigInt),\n * it will be deserialized using the corresponding handler.\n * Otherwise, it will be deserialized as is.\n *\n * @param json - The JSON string to deserialize back to its original form.\n * @returns The deserialized value with all special types reconstructed.\n */\n deserialize(json) {\n return JSON.parse(json, (_key, val) => {\n if (\n val\n && typeof val === 'object'\n && '__type' in val\n && typeof val.__type === 'string'\n ) {\n const type = val.__type as T_SerializerKnownTypes;\n const handler = typeHandlers[type];\n\n if (handler) {\n return handler.deserialize(val.value);\n }\n }\n return val;\n });\n },\n};\n"],"mappings":";AAyBA,IAAM,IAEF;CACA,MAAM;EACF,KAAK,MAAiB,aAAa;EACnC,YAAW,OAAM;GAAE,QAAQ;GAAQ,OAAO,EAAE,aAAa;GAAE;EAC3D,cAAa,MAAK,IAAI,KAAK,EAAY;EAC1C;CACD,KAAK;EACD,KAAK,MAAkC,aAAa;EACpD,YAAW,OAAM;GAAE,QAAQ;GAAO,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC;GAAE;EAC3D,cAAa,MAAK,IAAI,IAAI,EAA0B;EACvD;CACD,KAAK;EACD,KAAK,MAAyB,aAAa;EAC3C,YAAW,OAAM;GAAE,QAAQ;GAAO,OAAO,CAAC,GAAG,EAAE;GAAE;EACjD,cAAa,MAAK,IAAI,IAAI,EAAe;EAC5C;CACD,QAAQ;EACJ,KAAK,MAAmB,aAAa;EACrC,YAAW,OAAM;GACb,QAAQ;GACR,OAAO;IAAE,QAAQ,EAAE;IAAQ,OAAO,EAAE;IAAO;GAC9C;EACD,cAAc,MAAM;GAChB,IAAM,EAAE,WAAQ,aAAU;AAC1B,UAAO,IAAI,OAAO,GAAQ,EAAM;;EAEvC;CACD,QAAQ;EACJ,KAAK,MAAmB,OAAO,KAAM;EACrC,YAAW,OAAM;GAAE,QAAQ;GAAU,OAAO,EAAE,UAAU;GAAE;EAC1D,cAAa,MAAK,OAAO,EAAY;EACxC;CACJ,EAUY,IAAoC;CAU7C,UAAU,GAAO;AACb,SAAO,KAAK,UAAU,GAAO,SAAU,GAAM,GAAK;GAG9C,IAAM,IADU,KACc;AAE9B,OAAI,aAAyB,KACzB,QAAO,EAAa,KAAK,UAAU,EAAc;AAGrD,QAAK,IAAM,KAAQ,OAAO,KAAK,EAAa,EAA8B;IACtE,IAAM,IAAU,EAAa;AAE7B,QAAI,EAAQ,GAAG,EAAI,CACf,QAAQ,EAAmC,UAAU,EAAI;;AAIjE,UAAO;IACT;;CAWN,YAAY,GAAM;AACd,SAAO,KAAK,MAAM,IAAO,GAAM,MAAQ;AACnC,OACI,KACG,OAAO,KAAQ,YACf,YAAY,KACZ,OAAO,EAAI,UAAW,UAC3B;IAEE,IAAM,IAAU,EADH,EAAI;AAGjB,QAAI,EACA,QAAO,EAAQ,YAAY,EAAI,MAAM;;AAG7C,UAAO;IACT;;CAET"}
1
+ {"version":3,"file":"serializer.util.js","names":[],"sources":["../../../src/util/serializer/serializer.util.ts"],"sourcesContent":["import type {\n I_Serializer,\n I_SerializerTypeWrapper,\n I_SerializerValueMap,\n T_SerializerKnownTypes,\n} from './serializer.type.js';\n\n/**\n * Interface for handling serialization and deserialization of specific types.\n * Each handler provides methods to check if a value is of the specific type,\n * serialize it to a format that can be JSON stringified, and deserialize it back.\n */\ninterface I_Handler<T extends T_SerializerKnownTypes> {\n /** Checks if a value is of the specific type */\n is: (value: unknown) => value is I_SerializerValueMap[T];\n /** Serializes a value of the specific type to a format that can be JSON stringified */\n serialize: (value: I_SerializerValueMap[T]) => I_SerializerTypeWrapper<T>;\n /** Deserializes a value back to the specific type */\n deserialize: (value: unknown) => I_SerializerValueMap[T];\n}\n\n/**\n * Type handlers for different JavaScript types that cannot be directly serialized to JSON.\n * Each handler provides methods to serialize and deserialize specific types like Date, Map, Set, etc.\n */\nconst typeHandlers: {\n [K in T_SerializerKnownTypes]: I_Handler<K>;\n} = {\n Date: {\n is: (v): v is Date => v instanceof Date,\n serialize: v => ({ __type: 'Date', value: v.toISOString() }),\n deserialize: v => new Date(v as string),\n },\n Map: {\n is: (v): v is Map<unknown, unknown> => v instanceof Map,\n serialize: v => ({ __type: 'Map', value: [...v.entries()] }),\n deserialize: v => new Map(v as [unknown, unknown][]),\n },\n Set: {\n is: (v): v is Set<unknown> => v instanceof Set,\n serialize: v => ({ __type: 'Set', value: [...v] }),\n deserialize: v => new Set(v as unknown[]),\n },\n RegExp: {\n is: (v): v is RegExp => v instanceof RegExp,\n serialize: v => ({\n __type: 'RegExp',\n value: { source: v.source, flags: v.flags },\n }),\n deserialize: (v) => {\n const { source, flags } = v as { source: string; flags: string };\n return new RegExp(source, flags);\n },\n },\n BigInt: {\n is: (v): v is bigint => typeof v === 'bigint',\n serialize: v => ({ __type: 'BigInt', value: v.toString() }),\n deserialize: v => BigInt(v as string),\n },\n};\n\n/**\n * A serializer that can handle complex JavaScript types that cannot be directly JSON stringified.\n * This serializer extends JSON.stringify and JSON.parse to handle types like Date, Map, Set, RegExp, and BigInt.\n *\n * The serializer works by:\n * 1. During serialization: Wrapping special types with type information before JSON stringification\n * 2. During deserialization: Detecting wrapped types and reconstructing them to their original form\n *\n * @remarks\n * **Wire format protocol:** Non-JSON-native types are serialized as wrapper objects with the shape\n * `{ __type: string, value: unknown }`. For example:\n * - Date → `{ __type: 'Date', value: '2024-01-01T00:00:00.000Z' }`\n * - Map → `{ __type: 'Map', value: [['key', 'val']] }`\n * - Set → `{ __type: 'Set', value: [1, 2, 3] }`\n * - RegExp → `{ __type: 'RegExp', value: { source: '...', flags: '...' } }`\n * - BigInt → `{ __type: 'BigInt', value: '12345' }`\n *\n * **Cross-service compatibility:** Any service that deserializes data produced by this serializer\n * must use the same `__type` protocol. Plain `JSON.parse` will return the wrapper objects as-is\n * without reconstructing the original types.\n */\nexport const serializer: I_Serializer<unknown> = {\n /**\n * Serializes a value to a JSON string.\n * If the value is of a known type (Date, Map, Set, RegExp, BigInt),\n * it will be serialized using the corresponding handler.\n * Otherwise, it will be serialized as is.\n *\n * @param value - The value to serialize to a JSON string.\n * @returns The serialized JSON string that can be safely stored or transmitted.\n */\n serialize(value) {\n return JSON.stringify(value, function (_key, val) {\n // eslint-disable-next-line ts/no-this-alias\n const context = this;\n const originalValue = context[_key];\n\n if (originalValue instanceof Date) {\n return typeHandlers.Date.serialize(originalValue);\n }\n\n for (const type of Object.keys(typeHandlers) as T_SerializerKnownTypes[]) {\n const handler = typeHandlers[type];\n\n if (handler.is(val)) {\n return (handler as I_Handler<typeof type>).serialize(val);\n }\n }\n\n return val;\n });\n },\n /**\n * Deserializes a JSON string to its original value.\n * If the value is of a known type (Date, Map, Set, RegExp, BigInt),\n * it will be deserialized using the corresponding handler.\n * Otherwise, it will be deserialized as is.\n *\n * @param json - The JSON string to deserialize back to its original form.\n * @returns The deserialized value with all special types reconstructed.\n */\n deserialize(json) {\n return JSON.parse(json, (_key, val) => {\n if (\n val\n && typeof val === 'object'\n && '__type' in val\n && typeof val.__type === 'string'\n ) {\n const type = val.__type as T_SerializerKnownTypes;\n const handler = typeHandlers[type];\n\n if (handler) {\n return handler.deserialize(val.value);\n }\n }\n return val;\n });\n },\n};\n"],"mappings":";AAyBA,IAAM,IAEF;CACA,MAAM;EACF,KAAK,MAAiB,aAAa;EACnC,YAAW,OAAM;GAAE,QAAQ;GAAQ,OAAO,EAAE,aAAa;GAAE;EAC3D,cAAa,MAAK,IAAI,KAAK,EAAY;EAC1C;CACD,KAAK;EACD,KAAK,MAAkC,aAAa;EACpD,YAAW,OAAM;GAAE,QAAQ;GAAO,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC;GAAE;EAC3D,cAAa,MAAK,IAAI,IAAI,EAA0B;EACvD;CACD,KAAK;EACD,KAAK,MAAyB,aAAa;EAC3C,YAAW,OAAM;GAAE,QAAQ;GAAO,OAAO,CAAC,GAAG,EAAE;GAAE;EACjD,cAAa,MAAK,IAAI,IAAI,EAAe;EAC5C;CACD,QAAQ;EACJ,KAAK,MAAmB,aAAa;EACrC,YAAW,OAAM;GACb,QAAQ;GACR,OAAO;IAAE,QAAQ,EAAE;IAAQ,OAAO,EAAE;IAAO;GAC9C;EACD,cAAc,MAAM;GAChB,IAAM,EAAE,WAAQ,aAAU;AAC1B,UAAO,IAAI,OAAO,GAAQ,EAAM;;EAEvC;CACD,QAAQ;EACJ,KAAK,MAAmB,OAAO,KAAM;EACrC,YAAW,OAAM;GAAE,QAAQ;GAAU,OAAO,EAAE,UAAU;GAAE;EAC1D,cAAa,MAAK,OAAO,EAAY;EACxC;CACJ,EAuBY,IAAoC;CAU7C,UAAU,GAAO;AACb,SAAO,KAAK,UAAU,GAAO,SAAU,GAAM,GAAK;GAG9C,IAAM,IADU,KACc;AAE9B,OAAI,aAAyB,KACzB,QAAO,EAAa,KAAK,UAAU,EAAc;AAGrD,QAAK,IAAM,KAAQ,OAAO,KAAK,EAAa,EAA8B;IACtE,IAAM,IAAU,EAAa;AAE7B,QAAI,EAAQ,GAAG,EAAI,CACf,QAAQ,EAAmC,UAAU,EAAI;;AAIjE,UAAO;IACT;;CAWN,YAAY,GAAM;AACd,SAAO,KAAK,MAAM,IAAO,GAAM,MAAQ;AACnC,OACI,KACG,OAAO,KAAQ,YACf,YAAY,KACZ,OAAO,EAAI,UAAW,UAC3B;IAEE,IAAM,IAAU,EADH,EAAI;AAGjB,QAAI,EACA,QAAO,EAAQ,YAAY,EAAI,MAAM;;AAG7C,UAAO;IACT;;CAET"}
@@ -1,12 +1,12 @@
1
1
  import { removeAccent as e } from "../common/common.util.js";
2
2
  //#region src/util/string/string.util.ts
3
- var t = /[^a-z0-9\s-]/gi, n = /[\s-]+/g, r = /^-+|-+$/g, i = /-/g, a = /[?#]/;
4
- function o(i, a) {
3
+ var t = /[^a-z0-9\s-]/gi, n = /[\s-]+/g, r = /^-+|-+$/g, i = /-/g, a = /[?#]/, o = /[a-z]/, s = /[A-Z]/, c = /\d/, l = /[!@#$%^&*()_+[\]{}|;:,.<>?]/;
4
+ function u(i, a) {
5
5
  let o = i.trim();
6
6
  return o = e(o), a?.lower !== !1 && (o = o.toLowerCase()), o = o.replace(t, " "), o = o.replace(n, "-"), o = o.replace(r, ""), o;
7
7
  }
8
- function s(e, t) {
9
- let n = (e) => o(e ?? "", t);
8
+ function d(e, t) {
9
+ let n = (e) => u(e ?? "", t);
10
10
  if (typeof e == "object" && e) {
11
11
  let t = {};
12
12
  for (let [r, i] of Object.entries(e)) t[r] = n(i);
@@ -14,13 +14,13 @@ function s(e, t) {
14
14
  }
15
15
  return n(e);
16
16
  }
17
- function c(e, t = 4) {
17
+ function f(e, t = 4) {
18
18
  let n = 2166136261;
19
19
  for (let t = 0; t < e.length; t++) n ^= e.charCodeAt(t), n = Math.imul(n, 16777619);
20
20
  let r = (n >>> 0).toString(16).padStart(8, "0");
21
21
  return t > 8 ? e.replace(i, "").slice(0, t) : r.slice(0, t);
22
22
  }
23
- function l(e, t) {
23
+ function p(e, t) {
24
24
  let n = Math.floor(2 ** 32 / t.length) * t.length, r = [], i = 16384;
25
25
  for (; r.length < e;) {
26
26
  let a = e - r.length, o = new Uint32Array(a > i ? i : a);
@@ -32,28 +32,60 @@ function l(e, t) {
32
32
  }
33
33
  return r.join("");
34
34
  }
35
- function u(e = 8) {
35
+ function m(e = 8) {
36
36
  if (!Number.isSafeInteger(e) || e < 0) throw RangeError("length must be a non-negative safe integer");
37
- return l(e, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+[]{}|;:,.<>?");
37
+ let t = "abcdefghijklmnopqrstuvwxyz", n = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", r = "0123456789", i = "!@#$%^&*()_+[]{}|;:,.<>?", a = p(e, t + n + r + i);
38
+ if (e >= 4) {
39
+ let u = o.test(a), d = s.test(a), f = c.test(a), m = l.test(a);
40
+ if (u && d && f && m) return a;
41
+ let h = [...a], g = [
42
+ {
43
+ test: u,
44
+ pool: t
45
+ },
46
+ {
47
+ test: d,
48
+ pool: n
49
+ },
50
+ {
51
+ test: f,
52
+ pool: r
53
+ },
54
+ {
55
+ test: m,
56
+ pool: i
57
+ }
58
+ ], _ = Array.from({ length: e }, (e, t) => t);
59
+ for (let e = _.length - 1; e > 0; e--) {
60
+ let t = new Uint32Array(1);
61
+ crypto.getRandomValues(t);
62
+ let n = t[0] % (e + 1);
63
+ [_[e], _[n]] = [_[n], _[e]];
64
+ }
65
+ let v = 0;
66
+ for (let { test: e, pool: t } of g) e || (h[_[v]] = p(1, t), v++);
67
+ return h.join("");
68
+ }
69
+ return a;
38
70
  }
39
- function d(e = 8, t = "abcdefghijklmnopqrstuvwxyz0123456789") {
71
+ function h(e = 8, t = "abcdefghijklmnopqrstuvwxyz0123456789") {
40
72
  if (!Number.isSafeInteger(e) || e < 0) throw RangeError("length must be a non-negative safe integer");
41
73
  if (t.length === 0 || t.length > 2 ** 32) throw RangeError("charset.length must be between 1 and 2^32");
42
- return l(e, t);
74
+ return p(e, t);
43
75
  }
44
- function f(e = "", t = !1) {
76
+ function g(e = "", t = !1) {
45
77
  let n = e.split(a)[0] || "", r = n.substring(n.lastIndexOf("/") + 1);
46
78
  if (t) return r;
47
79
  let i = r.lastIndexOf(".");
48
80
  return i > 0 ? r.slice(0, i) : r;
49
81
  }
50
- function p(e, t, n) {
82
+ function _(e, t, n) {
51
83
  let r = e.indexOf(t);
52
84
  if (r === -1) return "";
53
85
  let i = r + t.length, a = e.indexOf(n, i);
54
86
  return a === -1 ? "" : e.slice(i, a);
55
87
  }
56
88
  //#endregion
57
- export { u as generateRandomPassword, d as generateRandomString, c as generateShortId, s as generateSlug, f as getFileName, p as substringBetween };
89
+ export { m as generateRandomPassword, h as generateRandomString, f as generateShortId, d as generateSlug, g as getFileName, _ as substringBetween };
58
90
 
59
91
  //# sourceMappingURL=string.util.js.map