@strapi/utils 5.48.1 → 5.50.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 (131) hide show
  1. package/dist/async.d.ts +2 -1
  2. package/dist/async.d.ts.map +1 -1
  3. package/dist/async.js +5 -1
  4. package/dist/async.js.map +1 -1
  5. package/dist/content-api-router.d.ts.map +1 -1
  6. package/dist/content-types.d.ts +5 -5
  7. package/dist/content-types.d.ts.map +1 -1
  8. package/dist/content-types.js +21 -17
  9. package/dist/content-types.js.map +1 -1
  10. package/dist/convert-query-params.d.ts.map +1 -1
  11. package/dist/convert-query-params.js +23 -19
  12. package/dist/convert-query-params.js.map +1 -1
  13. package/dist/convert-query-params.mjs +2 -2
  14. package/dist/convert-query-params.mjs.map +1 -1
  15. package/dist/env-helper.js +12 -8
  16. package/dist/env-helper.js.map +1 -1
  17. package/dist/errors.d.ts.map +1 -1
  18. package/dist/file.d.ts +0 -10
  19. package/dist/file.d.ts.map +1 -1
  20. package/dist/format-yup-error.d.ts.map +1 -1
  21. package/dist/has-published-version-param.d.ts +1 -1
  22. package/dist/has-published-version-param.d.ts.map +1 -1
  23. package/dist/hooks.d.ts.map +1 -1
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +12 -2
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +3 -0
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/install-id.d.ts.map +1 -1
  31. package/dist/install-id.js +6 -2
  32. package/dist/install-id.js.map +1 -1
  33. package/dist/model-cache.d.ts.map +1 -1
  34. package/dist/operators.d.ts.map +1 -1
  35. package/dist/package-manager.d.ts.map +1 -1
  36. package/dist/package-manager.js +7 -2
  37. package/dist/package-manager.js.map +1 -1
  38. package/dist/pagination.d.ts.map +1 -1
  39. package/dist/parse-type.d.ts.map +1 -1
  40. package/dist/parse-type.js +4 -3
  41. package/dist/parse-type.js.map +1 -1
  42. package/dist/policy.d.ts.map +1 -1
  43. package/dist/primitives/arrays.d.ts.map +1 -1
  44. package/dist/primitives/dates.d.ts.map +1 -1
  45. package/dist/primitives/objects.d.ts.map +1 -1
  46. package/dist/primitives/objects.js +6 -2
  47. package/dist/primitives/objects.js.map +1 -1
  48. package/dist/primitives/strings.d.ts.map +1 -1
  49. package/dist/primitives/strings.js +10 -5
  50. package/dist/primitives/strings.js.map +1 -1
  51. package/dist/provider-factory.d.ts.map +1 -1
  52. package/dist/publication-filter.d.ts +1 -1
  53. package/dist/publication-filter.d.ts.map +1 -1
  54. package/dist/relations.d.ts.map +1 -1
  55. package/dist/route-serialization.d.ts.map +1 -1
  56. package/dist/sanitize/index.d.ts.map +1 -1
  57. package/dist/sanitize/index.js +4 -1
  58. package/dist/sanitize/index.js.map +1 -1
  59. package/dist/sanitize/index.mjs +4 -1
  60. package/dist/sanitize/index.mjs.map +1 -1
  61. package/dist/sanitize/sanitizers.d.ts +0 -1
  62. package/dist/sanitize/sanitizers.d.ts.map +1 -1
  63. package/dist/sanitize/visitors/remove-disallowed-fields.d.ts.map +1 -1
  64. package/dist/sanitize/visitors/remove-restricted-fields.d.ts.map +1 -1
  65. package/dist/sanitize/visitors/remove-restricted-relations.d.ts.map +1 -1
  66. package/dist/security.d.ts +1 -1
  67. package/dist/security.d.ts.map +1 -1
  68. package/dist/sessions.d.ts +35 -0
  69. package/dist/sessions.d.ts.map +1 -0
  70. package/dist/sessions.js +46 -0
  71. package/dist/sessions.js.map +1 -0
  72. package/dist/sessions.mjs +42 -0
  73. package/dist/sessions.mjs.map +1 -0
  74. package/dist/set-creator-fields.d.ts.map +1 -1
  75. package/dist/sort-query.js +5 -1
  76. package/dist/sort-query.js.map +1 -1
  77. package/dist/template.d.ts.map +1 -1
  78. package/dist/traverse/factory.d.ts +108 -9
  79. package/dist/traverse/factory.d.ts.map +1 -1
  80. package/dist/traverse/query-fields.d.ts +0 -1
  81. package/dist/traverse/query-fields.d.ts.map +1 -1
  82. package/dist/traverse/query-filters.d.ts +0 -1
  83. package/dist/traverse/query-filters.d.ts.map +1 -1
  84. package/dist/traverse/query-populate.d.ts +0 -1
  85. package/dist/traverse/query-populate.d.ts.map +1 -1
  86. package/dist/traverse/query-populate.js +24 -0
  87. package/dist/traverse/query-populate.js.map +1 -1
  88. package/dist/traverse/query-populate.mjs +24 -0
  89. package/dist/traverse/query-populate.mjs.map +1 -1
  90. package/dist/traverse/query-sort.d.ts +0 -1
  91. package/dist/traverse/query-sort.d.ts.map +1 -1
  92. package/dist/traverse-entity.d.ts +0 -1
  93. package/dist/traverse-entity.d.ts.map +1 -1
  94. package/dist/traverse-entity.js +7 -0
  95. package/dist/traverse-entity.js.map +1 -1
  96. package/dist/traverse-entity.mjs +7 -0
  97. package/dist/traverse-entity.mjs.map +1 -1
  98. package/dist/types.d.ts +0 -25
  99. package/dist/types.d.ts.map +1 -1
  100. package/dist/user-agent.d.ts +23 -0
  101. package/dist/user-agent.d.ts.map +1 -0
  102. package/dist/user-agent.js +74 -0
  103. package/dist/user-agent.js.map +1 -0
  104. package/dist/user-agent.mjs +71 -0
  105. package/dist/user-agent.mjs.map +1 -0
  106. package/dist/validate/index.d.ts.map +1 -1
  107. package/dist/validate/utils.d.ts.map +1 -1
  108. package/dist/validate/validators.d.ts +4 -4
  109. package/dist/validate/validators.d.ts.map +1 -1
  110. package/dist/validate/validators.js +157 -0
  111. package/dist/validate/validators.js.map +1 -1
  112. package/dist/validate/validators.mjs +159 -2
  113. package/dist/validate/validators.mjs.map +1 -1
  114. package/dist/validate/visitors/throw-disallowed-fields.d.ts.map +1 -1
  115. package/dist/validate/visitors/throw-restricted-fields.d.ts.map +1 -1
  116. package/dist/validate/visitors/throw-restricted-relations.d.ts.map +1 -1
  117. package/dist/validation/route-validators/query-params.js +3 -2
  118. package/dist/validation/route-validators/query-params.js.map +1 -1
  119. package/dist/validation/utilities.d.ts +5 -5
  120. package/dist/validation/utilities.d.ts.map +1 -1
  121. package/dist/validators.d.ts.map +1 -1
  122. package/dist/validators.js +3 -2
  123. package/dist/validators.js.map +1 -1
  124. package/dist/yup.d.ts.map +1 -1
  125. package/dist/yup.js +10 -6
  126. package/dist/yup.js.map +1 -1
  127. package/dist/zod.d.ts +1 -1
  128. package/dist/zod.d.ts.map +1 -1
  129. package/dist/zod.js +3 -2
  130. package/dist/zod.js.map +1 -1
  131. package/package.json +9 -5
package/dist/types.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type * as Koa from 'koa';
2
1
  type ID = number | string;
3
2
  export type Data = {
4
3
  id?: ID;
@@ -53,30 +52,6 @@ export interface Model {
53
52
  privateAttributes?: string[];
54
53
  attributes: Record<string, AnyAttribute>;
55
54
  }
56
- declare module 'koa' {
57
- interface Request extends Koa.BaseRequest {
58
- route: RouteInfo;
59
- }
60
- interface ExtendableContext {
61
- ok: (response?: string | object, details?: object) => Koa.Context;
62
- created: (response?: string | object, details?: object) => Koa.Context;
63
- noContent: (response?: string | object, details?: object) => Koa.Context;
64
- badRequest: (response?: string | object, details?: object) => Koa.Context;
65
- unauthorized: (response?: string | object, details?: object) => Koa.Context;
66
- forbidden: (response?: string | object, details?: object) => Koa.Context;
67
- notFound: (response?: string | object, details?: object) => Koa.Context;
68
- locked: (response?: string | object, details?: object) => Koa.Context;
69
- internalServerError: (response?: string | object, details?: object) => Koa.Context;
70
- notImplemented: (response?: string | object, data?: Record<string, unknown>) => Koa.Context;
71
- }
72
- }
73
- export interface RouteInfo {
74
- endpoint: string;
75
- controller: string;
76
- action: string;
77
- verb: string;
78
- plugin: string;
79
- }
80
55
  export type WithRequired<T, K extends keyof T> = T & {
81
56
  [P in K]-?: T[P];
82
57
  };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,KAAK,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1B,MAAM,MAAM,IAAI,GAAG;IACjB,EAAE,CAAC,EAAE,EAAE,CAAC;IACR,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,EAAE,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;CACzF,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE7C,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,mBAAoB,SAAQ,SAAS;IACpD,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AACD,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AACD,MAAM,WAAW,oBAAqB,SAAQ,SAAS;IACrD,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,IAAI,EACA,QAAQ,GACR,MAAM,GACN,UAAU,GACV,SAAS,GACT,YAAY,GACZ,OAAO,GACP,SAAS,GACT,MAAM,GACN,MAAM,GACN,UAAU,GACV,WAAW,GACX,aAAa,GACb,SAAS,GACT,MAAM,GACN,QAAQ,GACR,KAAK,GACL,UAAU,GACV,OAAO,GACP,OAAO,CAAC;CACb;AAED,MAAM,MAAM,YAAY,GACpB,eAAe,GACf,mBAAmB,GACnB,kBAAkB,GAClB,oBAAoB,CAAC;AAEzB,MAAM,MAAM,IAAI,GAAG,YAAY,GAAG,gBAAgB,CAAC;AAEnD,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,aAAa,GAAG,WAAW,CAAC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,IAAI,CAAC,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,qBAAqB,CAAC,EAAE,OAAO,CAAC;QAChC,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,CAAC;IACF,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC1C;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG;KAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Minimal, dependency-free User-Agent parsing.
3
+ *
4
+ * This is intentionally heuristic and only aims to produce a human-readable label
5
+ * (e.g. "Chrome on macOS") for displaying active sessions/devices. It is not a full
6
+ * UA parser and should not be relied upon for feature detection.
7
+ */
8
+ export interface ParsedUserAgent {
9
+ browser?: string;
10
+ os?: string;
11
+ /** Human-readable label combining browser and OS, e.g. "Chrome on macOS". */
12
+ deviceName?: string;
13
+ }
14
+ /**
15
+ * Parses a User-Agent string into a best-effort browser/OS and a display label.
16
+ * Returns an empty object when the input is missing or unrecognized.
17
+ */
18
+ export declare const parseUserAgent: (userAgent?: string | null) => ParsedUserAgent;
19
+ /**
20
+ * Convenience helper returning only the human-readable device label, or undefined.
21
+ */
22
+ export declare const getDeviceName: (userAgent?: string | null) => string | undefined;
23
+ //# sourceMappingURL=user-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-agent.d.ts","sourceRoot":"","sources":["../src/user-agent.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAwCD;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,YAAY,MAAM,GAAG,IAAI,KAAG,eAqB1D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,YAAY,MAAM,GAAG,IAAI,KAAG,MAAM,GAAG,SAC7B,CAAC"}
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Minimal, dependency-free User-Agent parsing.
5
+ *
6
+ * This is intentionally heuristic and only aims to produce a human-readable label
7
+ * (e.g. "Chrome on macOS") for displaying active sessions/devices. It is not a full
8
+ * UA parser and should not be relied upon for feature detection.
9
+ */ /**
10
+ * Upper bound on the User-Agent length we are willing to scan. Real-world UA
11
+ * strings are comfortably under this, and browser/OS tokens always appear early,
12
+ * so clamping protects against pathologically large attacker-controlled headers
13
+ * without losing accuracy for legitimate clients.
14
+ */ const MAX_UA_LENGTH = 1024;
15
+ const detectBrowser = (ua)=>{
16
+ // Order matters: more specific tokens must be checked first.
17
+ if (/\bEdg(?:e|A|iOS)?\//.test(ua)) return 'Edge';
18
+ if (/\b(?:OPR|Opera)\//.test(ua)) return 'Opera';
19
+ if (/\b(?:SamsungBrowser)\//.test(ua)) return 'Samsung Internet';
20
+ // Chromium forks below ship a "Chrome/" token too, so they must be matched
21
+ // before the generic Chrome check or they'd all collapse into "Chrome".
22
+ if (/\bVivaldi\//.test(ua)) return 'Vivaldi';
23
+ if (/\b(?:YaBrowser|Yowser)\//.test(ua)) return 'Yandex Browser';
24
+ if (/\bBrave\//.test(ua)) return 'Brave';
25
+ if (/\b(?:Firefox|FxiOS)\//.test(ua)) return 'Firefox';
26
+ if (/\b(?:Chrome|CriOS|Chromium)\//.test(ua)) return 'Chrome';
27
+ // Safari ships "Safari/xxx" but so do Chrome/Edge; only treat as Safari when no Chrome token.
28
+ if (/\bVersion\/[\d.]+ (?:Mobile\/\S+ )?Safari\//.test(ua) || /\bSafari\//.test(ua)) {
29
+ return 'Safari';
30
+ }
31
+ return undefined;
32
+ };
33
+ const detectOS = (ua)=>{
34
+ if (/\bWindows NT\b/.test(ua)) return 'Windows';
35
+ if (/\b(?:iPhone|iPad|iPod)\b/.test(ua)) return 'iOS';
36
+ if (/\bAndroid\b/.test(ua)) return 'Android';
37
+ // "Mac OS X" appears on iOS too, so this must come after the iOS check.
38
+ if (/\b(?:Macintosh|Mac OS X)\b/.test(ua)) return 'macOS';
39
+ if (/\bCrOS\b/.test(ua)) return 'ChromeOS';
40
+ if (/\bLinux\b/.test(ua)) return 'Linux';
41
+ return undefined;
42
+ };
43
+ /**
44
+ * Parses a User-Agent string into a best-effort browser/OS and a display label.
45
+ * Returns an empty object when the input is missing or unrecognized.
46
+ */ const parseUserAgent = (userAgent)=>{
47
+ if (!userAgent || typeof userAgent !== 'string') {
48
+ return {};
49
+ }
50
+ // Clamp before scanning so an oversized header cannot drive the regex work.
51
+ const ua = userAgent.length > MAX_UA_LENGTH ? userAgent.slice(0, MAX_UA_LENGTH) : userAgent;
52
+ const browser = detectBrowser(ua);
53
+ const os = detectOS(ua);
54
+ let deviceName;
55
+ if (browser && os) {
56
+ deviceName = `${browser} on ${os}`;
57
+ } else if (browser) {
58
+ deviceName = browser;
59
+ } else if (os) {
60
+ deviceName = os;
61
+ }
62
+ return {
63
+ browser,
64
+ os,
65
+ deviceName
66
+ };
67
+ };
68
+ /**
69
+ * Convenience helper returning only the human-readable device label, or undefined.
70
+ */ const getDeviceName = (userAgent)=>parseUserAgent(userAgent).deviceName;
71
+
72
+ exports.getDeviceName = getDeviceName;
73
+ exports.parseUserAgent = parseUserAgent;
74
+ //# sourceMappingURL=user-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-agent.js","sources":["../src/user-agent.ts"],"sourcesContent":["/**\n * Minimal, dependency-free User-Agent parsing.\n *\n * This is intentionally heuristic and only aims to produce a human-readable label\n * (e.g. \"Chrome on macOS\") for displaying active sessions/devices. It is not a full\n * UA parser and should not be relied upon for feature detection.\n */\n\nexport interface ParsedUserAgent {\n browser?: string;\n os?: string;\n /** Human-readable label combining browser and OS, e.g. \"Chrome on macOS\". */\n deviceName?: string;\n}\n\n/**\n * Upper bound on the User-Agent length we are willing to scan. Real-world UA\n * strings are comfortably under this, and browser/OS tokens always appear early,\n * so clamping protects against pathologically large attacker-controlled headers\n * without losing accuracy for legitimate clients.\n */\nconst MAX_UA_LENGTH = 1024;\n\nconst detectBrowser = (ua: string): string | undefined => {\n // Order matters: more specific tokens must be checked first.\n if (/\\bEdg(?:e|A|iOS)?\\//.test(ua)) return 'Edge';\n if (/\\b(?:OPR|Opera)\\//.test(ua)) return 'Opera';\n if (/\\b(?:SamsungBrowser)\\//.test(ua)) return 'Samsung Internet';\n // Chromium forks below ship a \"Chrome/\" token too, so they must be matched\n // before the generic Chrome check or they'd all collapse into \"Chrome\".\n if (/\\bVivaldi\\//.test(ua)) return 'Vivaldi';\n if (/\\b(?:YaBrowser|Yowser)\\//.test(ua)) return 'Yandex Browser';\n if (/\\bBrave\\//.test(ua)) return 'Brave';\n if (/\\b(?:Firefox|FxiOS)\\//.test(ua)) return 'Firefox';\n if (/\\b(?:Chrome|CriOS|Chromium)\\//.test(ua)) return 'Chrome';\n // Safari ships \"Safari/xxx\" but so do Chrome/Edge; only treat as Safari when no Chrome token.\n if (/\\bVersion\\/[\\d.]+ (?:Mobile\\/\\S+ )?Safari\\//.test(ua) || /\\bSafari\\//.test(ua)) {\n return 'Safari';\n }\n return undefined;\n};\n\nconst detectOS = (ua: string): string | undefined => {\n if (/\\bWindows NT\\b/.test(ua)) return 'Windows';\n if (/\\b(?:iPhone|iPad|iPod)\\b/.test(ua)) return 'iOS';\n if (/\\bAndroid\\b/.test(ua)) return 'Android';\n // \"Mac OS X\" appears on iOS too, so this must come after the iOS check.\n if (/\\b(?:Macintosh|Mac OS X)\\b/.test(ua)) return 'macOS';\n if (/\\bCrOS\\b/.test(ua)) return 'ChromeOS';\n if (/\\bLinux\\b/.test(ua)) return 'Linux';\n return undefined;\n};\n\n/**\n * Parses a User-Agent string into a best-effort browser/OS and a display label.\n * Returns an empty object when the input is missing or unrecognized.\n */\nexport const parseUserAgent = (userAgent?: string | null): ParsedUserAgent => {\n if (!userAgent || typeof userAgent !== 'string') {\n return {};\n }\n\n // Clamp before scanning so an oversized header cannot drive the regex work.\n const ua = userAgent.length > MAX_UA_LENGTH ? userAgent.slice(0, MAX_UA_LENGTH) : userAgent;\n\n const browser = detectBrowser(ua);\n const os = detectOS(ua);\n\n let deviceName: string | undefined;\n if (browser && os) {\n deviceName = `${browser} on ${os}`;\n } else if (browser) {\n deviceName = browser;\n } else if (os) {\n deviceName = os;\n }\n\n return { browser, os, deviceName };\n};\n\n/**\n * Convenience helper returning only the human-readable device label, or undefined.\n */\nexport const getDeviceName = (userAgent?: string | null): string | undefined =>\n parseUserAgent(userAgent).deviceName;\n"],"names":["MAX_UA_LENGTH","detectBrowser","ua","test","undefined","detectOS","parseUserAgent","userAgent","length","slice","browser","os","deviceName","getDeviceName"],"mappings":";;AAAA;;;;;;;;;;;AAoBC,IACD,MAAMA,aAAAA,GAAgB,IAAA;AAEtB,MAAMC,gBAAgB,CAACC,EAAAA,GAAAA;;AAErB,IAAA,IAAI,qBAAA,CAAsBC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,MAAA;AAC3C,IAAA,IAAI,mBAAA,CAAoBC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,OAAA;AACzC,IAAA,IAAI,wBAAA,CAAyBC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,kBAAA;;;AAG9C,IAAA,IAAI,aAAA,CAAcC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,SAAA;AACnC,IAAA,IAAI,0BAAA,CAA2BC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,gBAAA;AAChD,IAAA,IAAI,WAAA,CAAYC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,OAAA;AACjC,IAAA,IAAI,uBAAA,CAAwBC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,SAAA;AAC7C,IAAA,IAAI,+BAAA,CAAgCC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,QAAA;;AAErD,IAAA,IAAI,8CAA8CC,IAAI,CAACD,OAAO,YAAA,CAAaC,IAAI,CAACD,EAAAA,CAAAA,EAAK;QACnF,OAAO,QAAA;AACT,IAAA;IACA,OAAOE,SAAAA;AACT,CAAA;AAEA,MAAMC,WAAW,CAACH,EAAAA,GAAAA;AAChB,IAAA,IAAI,gBAAA,CAAiBC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,SAAA;AACtC,IAAA,IAAI,0BAAA,CAA2BC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,KAAA;AAChD,IAAA,IAAI,aAAA,CAAcC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,SAAA;;AAEnC,IAAA,IAAI,4BAAA,CAA6BC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,OAAA;AAClD,IAAA,IAAI,UAAA,CAAWC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,UAAA;AAChC,IAAA,IAAI,WAAA,CAAYC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,OAAA;IACjC,OAAOE,SAAAA;AACT,CAAA;AAEA;;;IAIO,MAAME,cAAAA,GAAiB,CAACC,SAAAA,GAAAA;AAC7B,IAAA,IAAI,CAACA,SAAAA,IAAa,OAAOA,SAAAA,KAAc,QAAA,EAAU;AAC/C,QAAA,OAAO,EAAC;AACV,IAAA;;IAGA,MAAML,EAAAA,GAAKK,UAAUC,MAAM,GAAGR,gBAAgBO,SAAAA,CAAUE,KAAK,CAAC,CAAA,EAAGT,aAAAA,CAAAA,GAAiBO,SAAAA;AAElF,IAAA,MAAMG,UAAUT,aAAAA,CAAcC,EAAAA,CAAAA;AAC9B,IAAA,MAAMS,KAAKN,QAAAA,CAASH,EAAAA,CAAAA;IAEpB,IAAIU,UAAAA;AACJ,IAAA,IAAIF,WAAWC,EAAAA,EAAI;AACjBC,QAAAA,UAAAA,GAAa,CAAA,EAAGF,OAAAA,CAAQ,IAAI,EAAEC,EAAAA,CAAAA,CAAI;AACpC,IAAA,CAAA,MAAO,IAAID,OAAAA,EAAS;QAClBE,UAAAA,GAAaF,OAAAA;AACf,IAAA,CAAA,MAAO,IAAIC,EAAAA,EAAI;QACbC,UAAAA,GAAaD,EAAAA;AACf,IAAA;IAEA,OAAO;AAAED,QAAAA,OAAAA;AAASC,QAAAA,EAAAA;AAAIC,QAAAA;AAAW,KAAA;AACnC;AAEA;;UAGaC,aAAAA,GAAgB,CAACN,YAC5BD,cAAAA,CAAeC,SAAAA,CAAAA,CAAWK;;;;;"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Minimal, dependency-free User-Agent parsing.
3
+ *
4
+ * This is intentionally heuristic and only aims to produce a human-readable label
5
+ * (e.g. "Chrome on macOS") for displaying active sessions/devices. It is not a full
6
+ * UA parser and should not be relied upon for feature detection.
7
+ */ /**
8
+ * Upper bound on the User-Agent length we are willing to scan. Real-world UA
9
+ * strings are comfortably under this, and browser/OS tokens always appear early,
10
+ * so clamping protects against pathologically large attacker-controlled headers
11
+ * without losing accuracy for legitimate clients.
12
+ */ const MAX_UA_LENGTH = 1024;
13
+ const detectBrowser = (ua)=>{
14
+ // Order matters: more specific tokens must be checked first.
15
+ if (/\bEdg(?:e|A|iOS)?\//.test(ua)) return 'Edge';
16
+ if (/\b(?:OPR|Opera)\//.test(ua)) return 'Opera';
17
+ if (/\b(?:SamsungBrowser)\//.test(ua)) return 'Samsung Internet';
18
+ // Chromium forks below ship a "Chrome/" token too, so they must be matched
19
+ // before the generic Chrome check or they'd all collapse into "Chrome".
20
+ if (/\bVivaldi\//.test(ua)) return 'Vivaldi';
21
+ if (/\b(?:YaBrowser|Yowser)\//.test(ua)) return 'Yandex Browser';
22
+ if (/\bBrave\//.test(ua)) return 'Brave';
23
+ if (/\b(?:Firefox|FxiOS)\//.test(ua)) return 'Firefox';
24
+ if (/\b(?:Chrome|CriOS|Chromium)\//.test(ua)) return 'Chrome';
25
+ // Safari ships "Safari/xxx" but so do Chrome/Edge; only treat as Safari when no Chrome token.
26
+ if (/\bVersion\/[\d.]+ (?:Mobile\/\S+ )?Safari\//.test(ua) || /\bSafari\//.test(ua)) {
27
+ return 'Safari';
28
+ }
29
+ return undefined;
30
+ };
31
+ const detectOS = (ua)=>{
32
+ if (/\bWindows NT\b/.test(ua)) return 'Windows';
33
+ if (/\b(?:iPhone|iPad|iPod)\b/.test(ua)) return 'iOS';
34
+ if (/\bAndroid\b/.test(ua)) return 'Android';
35
+ // "Mac OS X" appears on iOS too, so this must come after the iOS check.
36
+ if (/\b(?:Macintosh|Mac OS X)\b/.test(ua)) return 'macOS';
37
+ if (/\bCrOS\b/.test(ua)) return 'ChromeOS';
38
+ if (/\bLinux\b/.test(ua)) return 'Linux';
39
+ return undefined;
40
+ };
41
+ /**
42
+ * Parses a User-Agent string into a best-effort browser/OS and a display label.
43
+ * Returns an empty object when the input is missing or unrecognized.
44
+ */ const parseUserAgent = (userAgent)=>{
45
+ if (!userAgent || typeof userAgent !== 'string') {
46
+ return {};
47
+ }
48
+ // Clamp before scanning so an oversized header cannot drive the regex work.
49
+ const ua = userAgent.length > MAX_UA_LENGTH ? userAgent.slice(0, MAX_UA_LENGTH) : userAgent;
50
+ const browser = detectBrowser(ua);
51
+ const os = detectOS(ua);
52
+ let deviceName;
53
+ if (browser && os) {
54
+ deviceName = `${browser} on ${os}`;
55
+ } else if (browser) {
56
+ deviceName = browser;
57
+ } else if (os) {
58
+ deviceName = os;
59
+ }
60
+ return {
61
+ browser,
62
+ os,
63
+ deviceName
64
+ };
65
+ };
66
+ /**
67
+ * Convenience helper returning only the human-readable device label, or undefined.
68
+ */ const getDeviceName = (userAgent)=>parseUserAgent(userAgent).deviceName;
69
+
70
+ export { getDeviceName, parseUserAgent };
71
+ //# sourceMappingURL=user-agent.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-agent.mjs","sources":["../src/user-agent.ts"],"sourcesContent":["/**\n * Minimal, dependency-free User-Agent parsing.\n *\n * This is intentionally heuristic and only aims to produce a human-readable label\n * (e.g. \"Chrome on macOS\") for displaying active sessions/devices. It is not a full\n * UA parser and should not be relied upon for feature detection.\n */\n\nexport interface ParsedUserAgent {\n browser?: string;\n os?: string;\n /** Human-readable label combining browser and OS, e.g. \"Chrome on macOS\". */\n deviceName?: string;\n}\n\n/**\n * Upper bound on the User-Agent length we are willing to scan. Real-world UA\n * strings are comfortably under this, and browser/OS tokens always appear early,\n * so clamping protects against pathologically large attacker-controlled headers\n * without losing accuracy for legitimate clients.\n */\nconst MAX_UA_LENGTH = 1024;\n\nconst detectBrowser = (ua: string): string | undefined => {\n // Order matters: more specific tokens must be checked first.\n if (/\\bEdg(?:e|A|iOS)?\\//.test(ua)) return 'Edge';\n if (/\\b(?:OPR|Opera)\\//.test(ua)) return 'Opera';\n if (/\\b(?:SamsungBrowser)\\//.test(ua)) return 'Samsung Internet';\n // Chromium forks below ship a \"Chrome/\" token too, so they must be matched\n // before the generic Chrome check or they'd all collapse into \"Chrome\".\n if (/\\bVivaldi\\//.test(ua)) return 'Vivaldi';\n if (/\\b(?:YaBrowser|Yowser)\\//.test(ua)) return 'Yandex Browser';\n if (/\\bBrave\\//.test(ua)) return 'Brave';\n if (/\\b(?:Firefox|FxiOS)\\//.test(ua)) return 'Firefox';\n if (/\\b(?:Chrome|CriOS|Chromium)\\//.test(ua)) return 'Chrome';\n // Safari ships \"Safari/xxx\" but so do Chrome/Edge; only treat as Safari when no Chrome token.\n if (/\\bVersion\\/[\\d.]+ (?:Mobile\\/\\S+ )?Safari\\//.test(ua) || /\\bSafari\\//.test(ua)) {\n return 'Safari';\n }\n return undefined;\n};\n\nconst detectOS = (ua: string): string | undefined => {\n if (/\\bWindows NT\\b/.test(ua)) return 'Windows';\n if (/\\b(?:iPhone|iPad|iPod)\\b/.test(ua)) return 'iOS';\n if (/\\bAndroid\\b/.test(ua)) return 'Android';\n // \"Mac OS X\" appears on iOS too, so this must come after the iOS check.\n if (/\\b(?:Macintosh|Mac OS X)\\b/.test(ua)) return 'macOS';\n if (/\\bCrOS\\b/.test(ua)) return 'ChromeOS';\n if (/\\bLinux\\b/.test(ua)) return 'Linux';\n return undefined;\n};\n\n/**\n * Parses a User-Agent string into a best-effort browser/OS and a display label.\n * Returns an empty object when the input is missing or unrecognized.\n */\nexport const parseUserAgent = (userAgent?: string | null): ParsedUserAgent => {\n if (!userAgent || typeof userAgent !== 'string') {\n return {};\n }\n\n // Clamp before scanning so an oversized header cannot drive the regex work.\n const ua = userAgent.length > MAX_UA_LENGTH ? userAgent.slice(0, MAX_UA_LENGTH) : userAgent;\n\n const browser = detectBrowser(ua);\n const os = detectOS(ua);\n\n let deviceName: string | undefined;\n if (browser && os) {\n deviceName = `${browser} on ${os}`;\n } else if (browser) {\n deviceName = browser;\n } else if (os) {\n deviceName = os;\n }\n\n return { browser, os, deviceName };\n};\n\n/**\n * Convenience helper returning only the human-readable device label, or undefined.\n */\nexport const getDeviceName = (userAgent?: string | null): string | undefined =>\n parseUserAgent(userAgent).deviceName;\n"],"names":["MAX_UA_LENGTH","detectBrowser","ua","test","undefined","detectOS","parseUserAgent","userAgent","length","slice","browser","os","deviceName","getDeviceName"],"mappings":"AAAA;;;;;;;;;;;AAoBC,IACD,MAAMA,aAAAA,GAAgB,IAAA;AAEtB,MAAMC,gBAAgB,CAACC,EAAAA,GAAAA;;AAErB,IAAA,IAAI,qBAAA,CAAsBC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,MAAA;AAC3C,IAAA,IAAI,mBAAA,CAAoBC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,OAAA;AACzC,IAAA,IAAI,wBAAA,CAAyBC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,kBAAA;;;AAG9C,IAAA,IAAI,aAAA,CAAcC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,SAAA;AACnC,IAAA,IAAI,0BAAA,CAA2BC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,gBAAA;AAChD,IAAA,IAAI,WAAA,CAAYC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,OAAA;AACjC,IAAA,IAAI,uBAAA,CAAwBC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,SAAA;AAC7C,IAAA,IAAI,+BAAA,CAAgCC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,QAAA;;AAErD,IAAA,IAAI,8CAA8CC,IAAI,CAACD,OAAO,YAAA,CAAaC,IAAI,CAACD,EAAAA,CAAAA,EAAK;QACnF,OAAO,QAAA;AACT,IAAA;IACA,OAAOE,SAAAA;AACT,CAAA;AAEA,MAAMC,WAAW,CAACH,EAAAA,GAAAA;AAChB,IAAA,IAAI,gBAAA,CAAiBC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,SAAA;AACtC,IAAA,IAAI,0BAAA,CAA2BC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,KAAA;AAChD,IAAA,IAAI,aAAA,CAAcC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,SAAA;;AAEnC,IAAA,IAAI,4BAAA,CAA6BC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,OAAA;AAClD,IAAA,IAAI,UAAA,CAAWC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,UAAA;AAChC,IAAA,IAAI,WAAA,CAAYC,IAAI,CAACD,EAAAA,CAAAA,EAAK,OAAO,OAAA;IACjC,OAAOE,SAAAA;AACT,CAAA;AAEA;;;IAIO,MAAME,cAAAA,GAAiB,CAACC,SAAAA,GAAAA;AAC7B,IAAA,IAAI,CAACA,SAAAA,IAAa,OAAOA,SAAAA,KAAc,QAAA,EAAU;AAC/C,QAAA,OAAO,EAAC;AACV,IAAA;;IAGA,MAAML,EAAAA,GAAKK,UAAUC,MAAM,GAAGR,gBAAgBO,SAAAA,CAAUE,KAAK,CAAC,CAAA,EAAGT,aAAAA,CAAAA,GAAiBO,SAAAA;AAElF,IAAA,MAAMG,UAAUT,aAAAA,CAAcC,EAAAA,CAAAA;AAC9B,IAAA,MAAMS,KAAKN,QAAAA,CAASH,EAAAA,CAAAA;IAEpB,IAAIU,UAAAA;AACJ,IAAA,IAAIF,WAAWC,EAAAA,EAAI;AACjBC,QAAAA,UAAAA,GAAa,CAAA,EAAGF,OAAAA,CAAQ,IAAI,EAAEC,EAAAA,CAAAA,CAAI;AACpC,IAAA,CAAA,MAAO,IAAID,OAAAA,EAAS;QAClBE,UAAAA,GAAaF,OAAAA;AACf,IAAA,CAAA,MAAO,IAAIC,EAAAA,EAAI;QACbC,UAAAA,GAAaD,EAAAA;AACf,IAAA;IAEA,OAAO;AAAED,QAAAA,OAAAA;AAASC,QAAAA,EAAAA;AAAIC,QAAAA;AAAW,KAAA;AACnC;AAEA;;UAGaC,aAAAA,GAAgB,CAACN,YAC5BD,cAAAA,CAAeC,SAAAA,CAAAA,CAAWK;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validate/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAM1C,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,6BAA6B,CAAC;AAIrC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAK3C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAMvC,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,MAAM,EAAE,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACxD;AACD,MAAM,WAAW,YAAY;IAC3B,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,KAAK,EACb,OAAO,CAAC,EAAE,OAAO,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,wBAAwB,GAAG,CACrC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,KAAK,EACb,OAAO,CAAC,EAAE,OAAO,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,UAAU,UAAU;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,QAAA,MAAM,mBAAmB,SAAU,UAAU;;mBA8FlC,OAAO,MAAM,EAAE,OAAO,CAAC,UACtB,KAAK,kCAC0B,OAAO;;;;;CA+KjD,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAErD,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validate/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAM1C,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,6BAA6B,CAAC;AAIrC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAK3C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAMvC,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,MAAM,EAAE,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACxD;AACD,MAAM,WAAW,YAAY;IAC3B,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,KAAK,EACb,OAAO,CAAC,EAAE,OAAO,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,wBAAwB,GAAG,CACrC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,KAAK,EACb,OAAO,CAAC,EAAE,OAAO,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,UAAU,UAAU;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,QAAA,MAAM,mBAAmB,GAAI,MAAM,UAAU;;mBA8FlC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UACtB,KAAK,kCAC0B,OAAO;;;;;CA+KjD,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAErD,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/validate/utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,eAAe,kBAAmB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,KAAG,KAOtF,CAAC;AAEF,eAAO,MAAM,UAAU,+BACjB,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC,KAC7B,CAAC,CAAC,GAAG,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,GAAG,CAS/B,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/validate/utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,eAAe,GAAI,eAAe;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,KAAG,KAOtF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,OAAO,EAAE,EAAE,CAAC,EAC/C,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,KAC7B,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAS/B,CAAC"}
@@ -19,10 +19,10 @@ export declare const validateFields: (ctx?: Context | undefined, fields?: unknow
19
19
  export declare const defaultValidateFields: (ctx?: Context | undefined, fields?: unknown) => any;
20
20
  export declare const POPULATE_TRAVERSALS: string[];
21
21
  export declare const validatePopulate: (ctx?: PopulateContext | undefined, populate?: unknown, includes?: {
22
- fields?: string[] | undefined;
23
- sort?: string[] | undefined;
24
- filters?: string[] | undefined;
25
- populate?: string[] | undefined;
22
+ fields?: (typeof FIELDS_TRAVERSALS)[number][];
23
+ sort?: (typeof SORT_TRAVERSALS)[number][];
24
+ filters?: (typeof FILTER_TRAVERSALS)[number][];
25
+ populate?: (typeof POPULATE_TRAVERSALS)[number][];
26
26
  } | undefined) => any;
27
27
  export declare const defaultValidatePopulate: (ctx?: Context | undefined, populate?: unknown) => any;
28
28
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/validate/validators.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAIxD,UAAU,OAAO;IACf,MAAM,EAAE,KAAK,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;CACpC;AAED,UAAU,eAAgB,SAAQ,OAAO;IACvC,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,eAAO,MAAM,iBAAiB,UAM7B,CAAC;AAEF,eAAO,MAAM,eAAe,uFAoD3B,CAAC;AAEF,eAAO,MAAM,sBAAsB,uDAEjC,CAAC;AAEH,eAAO,MAAM,eAAe,UAO3B,CAAC;AAEF,eAAO,MAAM,YAAY,oFA2ExB,CAAC;AAEF,eAAO,MAAM,mBAAmB,oDAE9B,CAAC;AAEH,eAAO,MAAM,iBAAiB,UAA0D,CAAC;AAEzF,eAAO,MAAM,cAAc,sFA0C1B,CAAC;AAEF,eAAO,MAAM,qBAAqB,sDAEhC,CAAC;AAEH,eAAO,MAAM,mBAAmB,UAAwC,CAAC;AAEzE,eAAO,MAAM,gBAAgB;;;;;qBAiL5B,CAAC;AAEF,eAAO,MAAM,uBAAuB,wDAYlC,CAAC"}
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/validate/validators.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAa,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAIxD,UAAU,OAAO;IACf,MAAM,EAAE,KAAK,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;CACpC;AAED,UAAU,eAAgB,SAAQ,OAAO;IACvC,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,eAAO,MAAM,iBAAiB,UAM7B,CAAC;AAEF,eAAO,MAAM,eAAe,uFAoD3B,CAAC;AAEF,eAAO,MAAM,sBAAsB,uDAEjC,CAAC;AAEH,eAAO,MAAM,eAAe,UAO3B,CAAC;AAEF,eAAO,MAAM,YAAY,oFA2ExB,CAAC;AAEF,eAAO,MAAM,mBAAmB,oDAE9B,CAAC;AAEH,eAAO,MAAM,iBAAiB,UAA0D,CAAC;AAEzF,eAAO,MAAM,cAAc,sFA0C1B,CAAC;AAEF,eAAO,MAAM,qBAAqB,sDAEhC,CAAC;AAyKH,eAAO,MAAM,mBAAmB,UAAwC,CAAC;AAEzE,eAAO,MAAM,gBAAgB;aAKd,CAAC,OAAO,iBAAiB,EAAE,MAAM,CAAC,EAAE;WACtC,CAAC,OAAO,eAAe,EAAE,MAAM,CAAC,EAAE;cAC/B,CAAC,OAAO,iBAAiB,EAAE,MAAM,CAAC,EAAE;eACnC,CAAC,OAAO,mBAAmB,EAAE,MAAM,CAAC,EAAE;qBA0LtD,CAAC;AAEF,eAAO,MAAM,uBAAuB,wDAYlC,CAAC"}
@@ -200,6 +200,148 @@ const validateFields = utils.asyncCurry(async (ctx, fields, include)=>{
200
200
  const defaultValidateFields = utils.asyncCurry(async (ctx, fields)=>{
201
201
  return validateFields(ctx, fields, FIELDS_TRAVERSALS);
202
202
  });
203
+ const isMorphLikeAttribute = (attribute)=>contentTypes.isDynamicZoneAttribute(attribute) || contentTypes.isMorphToRelationalAttribute(attribute);
204
+ const isPopulatableAttribute = (attribute)=>!!attribute && [
205
+ 'relation',
206
+ 'dynamiczone',
207
+ 'component',
208
+ 'media'
209
+ ].includes(attribute.type);
210
+ const isDotNotationPopulate = (populate)=>{
211
+ if (populate === '*') {
212
+ return false;
213
+ }
214
+ if (typeof populate === 'string') {
215
+ return true;
216
+ }
217
+ return Array.isArray(populate) && populate.length > 0 && populate.every((p)=>typeof p === 'string');
218
+ };
219
+ const flattenDotPopulatePaths = (populate)=>{
220
+ const items = Array.isArray(populate) ? populate : [
221
+ populate
222
+ ];
223
+ return items.flatMap((item)=>item.split(',').map((segment)=>fp.trim(segment)).filter(Boolean));
224
+ };
225
+ const validatePopulateDotPathSegments = ({ schema, getModel }, segments, pathPrefix)=>{
226
+ if (!segments.length) {
227
+ return;
228
+ }
229
+ const [head, ...tail] = segments;
230
+ const fullPath = pathPrefix ? `${pathPrefix}.${head}` : head;
231
+ const attribute = schema.attributes[head];
232
+ if (!attribute || !isPopulatableAttribute(attribute)) {
233
+ utils.throwInvalidKey({
234
+ key: head,
235
+ path: fullPath
236
+ });
237
+ }
238
+ if (!tail.length) {
239
+ return;
240
+ }
241
+ if (attribute.type === 'component') {
242
+ if (!attribute.component) {
243
+ utils.throwInvalidKey({
244
+ key: head,
245
+ path: fullPath
246
+ });
247
+ }
248
+ validatePopulateDotPathSegments({
249
+ schema: getModel(attribute.component),
250
+ getModel
251
+ }, tail, fullPath);
252
+ return;
253
+ }
254
+ if (attribute.type === 'relation') {
255
+ if (isMorphLikeAttribute(attribute)) {
256
+ utils.throwInvalidKey({
257
+ key: head,
258
+ path: fullPath
259
+ });
260
+ }
261
+ if (!attribute.target) {
262
+ utils.throwInvalidKey({
263
+ key: head,
264
+ path: fullPath
265
+ });
266
+ }
267
+ validatePopulateDotPathSegments({
268
+ schema: getModel(attribute.target),
269
+ getModel
270
+ }, tail, fullPath);
271
+ return;
272
+ }
273
+ if (attribute.type === 'media') {
274
+ utils.throwInvalidKey({
275
+ key: head,
276
+ path: fullPath
277
+ });
278
+ }
279
+ if (attribute.type === 'dynamiczone') {
280
+ const [nextSegment, ...rest] = tail;
281
+ const nextPath = `${fullPath}.${nextSegment}`;
282
+ const candidates = (attribute.components ?? []).map((uid)=>getModel(uid)).filter((model)=>model?.attributes?.[nextSegment]);
283
+ if (!candidates.length) {
284
+ utils.throwInvalidKey({
285
+ key: nextSegment,
286
+ path: nextPath
287
+ });
288
+ }
289
+ let validated = false;
290
+ for (const componentSchema of candidates){
291
+ const nestedAttribute = componentSchema.attributes[nextSegment];
292
+ try {
293
+ if (!rest.length) {
294
+ if (nestedAttribute) {
295
+ validated = true;
296
+ break;
297
+ }
298
+ } else if (nestedAttribute?.type === 'component' && nestedAttribute.component) {
299
+ validatePopulateDotPathSegments({
300
+ schema: getModel(nestedAttribute.component),
301
+ getModel
302
+ }, rest, nextPath);
303
+ validated = true;
304
+ break;
305
+ } else if (nestedAttribute?.type === 'relation' && !isMorphLikeAttribute(nestedAttribute) && nestedAttribute.target) {
306
+ validatePopulateDotPathSegments({
307
+ schema: getModel(nestedAttribute.target),
308
+ getModel
309
+ }, rest, nextPath);
310
+ validated = true;
311
+ break;
312
+ }
313
+ } catch {
314
+ // Try the next dynamic-zone component type.
315
+ }
316
+ }
317
+ if (!validated) {
318
+ utils.throwInvalidKey({
319
+ key: nextSegment,
320
+ path: nextPath
321
+ });
322
+ }
323
+ }
324
+ };
325
+ const validatePopulateDotPaths = (ctx, populate)=>{
326
+ for (const path of flattenDotPopulatePaths(populate)){
327
+ const segments = path.split('.').map((segment)=>fp.trim(segment)).filter(Boolean);
328
+ validatePopulateDotPathSegments(ctx, segments, '');
329
+ }
330
+ };
331
+ const validateMorphLikeNestedPopulate = (populateValue, { path })=>{
332
+ if (typeof populateValue === 'string' && populateValue !== '*' && !fp.isNil(populateValue)) {
333
+ utils.throwInvalidKey({
334
+ key: 'populate',
335
+ path
336
+ });
337
+ }
338
+ if (fp.isPlainObject(populateValue) && !fp.isEmpty(populateValue) && !fp.isNil(populateValue)) {
339
+ utils.throwInvalidKey({
340
+ key: 'populate',
341
+ path
342
+ });
343
+ }
344
+ };
203
345
  const POPULATE_TRAVERSALS = [
204
346
  'nonAttributesOperators',
205
347
  'private'
@@ -208,6 +350,16 @@ const validatePopulate = utils.asyncCurry(async (ctx, populate, includes)=>{
208
350
  if (!ctx.schema) {
209
351
  throw new Error('Missing schema in defaultValidatePopulate');
210
352
  }
353
+ if (isDotNotationPopulate(populate)) {
354
+ validatePopulateDotPaths({
355
+ schema: ctx.schema,
356
+ getModel: ctx.getModel
357
+ }, populate);
358
+ if (includes?.populate?.includes('private')) {
359
+ return queryPopulate(throwPrivate, ctx)(populate);
360
+ }
361
+ return populate;
362
+ }
211
363
  // Build the list of functions conditionally based on the include array
212
364
  const functionsToApply = [];
213
365
  // Always include the main traversal function
@@ -224,6 +376,11 @@ const validatePopulate = utils.asyncCurry(async (ctx, populate, includes)=>{
224
376
  'component',
225
377
  'media'
226
378
  ].includes(attribute.type);
379
+ if (isMorphLikeAttribute(attribute) && fp.isObject(value) && 'populate' in value) {
380
+ validateMorphLikeNestedPopulate(value.populate, {
381
+ path: path.raw
382
+ });
383
+ }
227
384
  // Throw on non-populate attributes
228
385
  if (!isPopulatableAttribute) {
229
386
  utils.throwInvalidKey({
@@ -1 +1 @@
1
- {"version":3,"file":"validators.js","sources":["../../src/validate/validators.ts"],"sourcesContent":["import { isEmpty, isNil, isObject } from 'lodash/fp';\n\nimport { pipe as pipeAsync } from '../async';\nimport { isScalarAttribute, constants } from '../content-types';\nimport {\n traverseQueryFilters,\n traverseQuerySort,\n traverseQueryFields,\n traverseQueryPopulate,\n} from '../traverse';\nimport { throwPassword, throwPrivate, throwDynamicZones, throwMorphToRelations } from './visitors';\nimport { isOperator } from '../operators';\nimport { asyncCurry, throwInvalidKey } from './utils';\nimport type { Model } from '../types';\nimport parseType from '../parse-type';\nimport type { Parent, Path } from '../traverse/factory';\n\nconst { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = constants;\n\ninterface Context {\n schema: Model;\n getModel: (model: string) => Model;\n}\n\ninterface PopulateContext extends Context {\n path?: Path;\n parent?: Parent;\n}\n\ntype AnyFunc = (...args: any[]) => any;\n\nexport const FILTER_TRAVERSALS = [\n 'nonAttributesOperators',\n 'dynamicZones',\n 'morphRelations',\n 'passwords',\n 'private',\n];\n\nexport const validateFilters = asyncCurry(\n async (ctx: Context, filters: unknown, include: (typeof FILTER_TRAVERSALS)[number][]) => {\n // TODO: schema checks should check that it is a valid schema with yup\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidateFilters');\n }\n\n // Build the list of functions conditionally\n const functionsToApply: Array<AnyFunc> = [];\n\n // keys that are not attributes or valid operators\n if (include.includes('nonAttributesOperators')) {\n functionsToApply.push(\n traverseQueryFilters(({ key, attribute, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not removing it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n const isAttribute = !!attribute;\n\n if (!isAttribute && !isOperator(key)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n if (include.includes('dynamicZones')) {\n functionsToApply.push(traverseQueryFilters(throwDynamicZones, ctx));\n }\n\n if (include.includes('morphRelations')) {\n functionsToApply.push(traverseQueryFilters(throwMorphToRelations, ctx));\n }\n\n if (include.includes('passwords')) {\n functionsToApply.push(traverseQueryFilters(throwPassword, ctx));\n }\n\n if (include.includes('private')) {\n functionsToApply.push(traverseQueryFilters(throwPrivate, ctx));\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return filters;\n }\n\n return pipeAsync(...functionsToApply)(filters);\n }\n);\n\nexport const defaultValidateFilters = asyncCurry(async (ctx: Context, filters: unknown) => {\n return validateFilters(ctx, filters, FILTER_TRAVERSALS);\n});\n\nexport const SORT_TRAVERSALS = [\n 'nonAttributesOperators',\n 'dynamicZones',\n 'morphRelations',\n 'passwords',\n 'private',\n 'nonScalarEmptyKeys',\n];\n\nexport const validateSort = asyncCurry(\n async (ctx: Context, sort: unknown, include: (typeof SORT_TRAVERSALS)[number][]) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidateSort');\n }\n\n // Build the list of functions conditionally based on the include array\n const functionsToApply: Array<AnyFunc> = [];\n\n // Validate non attribute keys\n if (include.includes('nonAttributesOperators')) {\n functionsToApply.push(\n traverseQuerySort(({ key, attribute, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not removing it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n // status is a virtual sort key for D&P-enabled content types\n if (key === 'status' && ctx.schema?.options?.draftAndPublish) {\n return;\n }\n\n if (!attribute) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n // Validate dynamic zones from sort\n if (include.includes('dynamicZones')) {\n functionsToApply.push(traverseQuerySort(throwDynamicZones, ctx));\n }\n\n // Validate morphTo relations from sort\n if (include.includes('morphRelations')) {\n functionsToApply.push(traverseQuerySort(throwMorphToRelations, ctx));\n }\n\n // Validate passwords from sort\n if (include.includes('passwords')) {\n functionsToApply.push(traverseQuerySort(throwPassword, ctx));\n }\n\n // Validate private from sort\n if (include.includes('private')) {\n functionsToApply.push(traverseQuerySort(throwPrivate, ctx));\n }\n\n // Validate non-scalar empty keys\n if (include.includes('nonScalarEmptyKeys')) {\n functionsToApply.push(\n traverseQuerySort(({ key, attribute, value, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not removing it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!isScalarAttribute(attribute) && isEmpty(value)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return sort;\n }\n\n return pipeAsync(...functionsToApply)(sort);\n }\n);\n\nexport const defaultValidateSort = asyncCurry(async (ctx: Context, sort: unknown) => {\n return validateSort(ctx, sort, SORT_TRAVERSALS);\n});\n\nexport const FIELDS_TRAVERSALS = ['scalarAttributes', 'privateFields', 'passwordFields'];\n\nexport const validateFields = asyncCurry(\n async (ctx: Context, fields: unknown, include: (typeof FIELDS_TRAVERSALS)[number][]) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidateFields');\n }\n // Build the list of functions conditionally based on the include array\n const functionsToApply: Array<AnyFunc> = [];\n\n // Only allow scalar attributes\n if (include.includes('scalarAttributes')) {\n functionsToApply.push(\n traverseQueryFields(({ key, attribute, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not throwing because of it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (isNil(attribute) || !isScalarAttribute(attribute)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n // Private fields\n if (include.includes('privateFields')) {\n functionsToApply.push(traverseQueryFields(throwPrivate, ctx));\n }\n\n // Password fields\n if (include.includes('passwordFields')) {\n functionsToApply.push(traverseQueryFields(throwPassword, ctx));\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return fields;\n }\n\n return pipeAsync(...functionsToApply)(fields);\n }\n);\n\nexport const defaultValidateFields = asyncCurry(async (ctx: Context, fields: unknown) => {\n return validateFields(ctx, fields, FIELDS_TRAVERSALS);\n});\n\nexport const POPULATE_TRAVERSALS = ['nonAttributesOperators', 'private'];\n\nexport const validatePopulate = asyncCurry(\n async (\n ctx: PopulateContext,\n populate: unknown,\n includes: {\n fields?: (typeof FIELDS_TRAVERSALS)[number][];\n sort?: (typeof SORT_TRAVERSALS)[number][];\n filters?: (typeof FILTER_TRAVERSALS)[number][];\n populate?: (typeof POPULATE_TRAVERSALS)[number][];\n }\n ) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidatePopulate');\n }\n // Build the list of functions conditionally based on the include array\n const functionsToApply: Array<AnyFunc> = [];\n\n // Always include the main traversal function\n functionsToApply.push(\n traverseQueryPopulate(\n async ({ key, path, value, schema, attribute, getModel, parent }, { set }) => {\n /**\n * NOTE: The parent check is done to support \"filters\" (and the rest of keys) as valid attribute names.\n *\n * The parent will not be an attribute when its a \"populate\" / \"filters\" / \"sort\" ... key.\n * Only in those scenarios the node will be an attribute.\n */\n if (!parent?.attribute && attribute) {\n const isPopulatableAttribute = [\n 'relation',\n 'dynamiczone',\n 'component',\n 'media',\n ].includes(attribute.type);\n\n // Throw on non-populate attributes\n if (!isPopulatableAttribute) {\n throwInvalidKey({ key, path: path.raw });\n }\n\n // Valid populatable attribute, so return\n return;\n }\n\n // If we're looking at a populate fragment, ensure its target is valid\n if (key === 'on') {\n // Populate fragment should always be an object\n if (!isObject(value)) {\n return throwInvalidKey({ key, path: path.raw });\n }\n\n const targets = Object.keys(value);\n\n for (const target of targets) {\n const model = getModel(target);\n\n // If a target is invalid (no matching model), then raise an error\n if (!model) {\n throwInvalidKey({ key: target, path: `${path.raw}.${target}` });\n }\n }\n\n // If the fragment's target is fine, then let it pass\n return;\n }\n\n // Ignore plain wildcards\n if (key === '' && value === '*') {\n return;\n }\n\n // Ensure count is a boolean\n if (key === 'count') {\n try {\n parseType({ type: 'boolean', value });\n return;\n } catch {\n throwInvalidKey({ key, path: path.attribute });\n }\n }\n\n // Allowed boolean-like keywords should be ignored\n try {\n parseType({ type: 'boolean', value: key });\n // Key is an allowed boolean-like keyword, skipping validation...\n return;\n } catch {\n // Continue, because it's not a boolean-like\n }\n\n // Handle nested `sort` validation with custom or default traversals\n if (key === 'sort') {\n set(\n key,\n await validateSort(\n {\n schema,\n getModel,\n },\n value, // pass the sort value\n includes?.sort || SORT_TRAVERSALS\n )\n );\n return;\n }\n\n // Handle nested `filters` validation with custom or default traversals\n if (key === 'filters') {\n set(\n key,\n await validateFilters(\n {\n schema,\n getModel,\n },\n value, // pass the filters value\n includes?.filters || FILTER_TRAVERSALS\n )\n );\n return;\n }\n\n // Handle nested `fields` validation with custom or default traversals\n if (key === 'fields') {\n set(\n key,\n await validateFields(\n {\n schema,\n getModel,\n },\n value, // pass the fields value\n includes?.fields || FIELDS_TRAVERSALS\n )\n );\n return;\n }\n\n // Handle recursive nested `populate` validation with the same include object\n if (key === 'populate') {\n set(\n key,\n await validatePopulate(\n {\n schema,\n getModel,\n parent: { key, path, schema, attribute },\n path,\n },\n value, // pass the nested populate value\n includes // pass down the same includes object\n )\n );\n return;\n }\n\n // Throw an error if non-attribute operators are included in the populate array\n if (includes?.populate?.includes('nonAttributesOperators')) {\n throwInvalidKey({ key, path: path.attribute });\n }\n },\n ctx\n )\n );\n\n // Conditionally traverse for private fields only if 'private' is included\n if (includes?.populate?.includes('private')) {\n functionsToApply.push(traverseQueryPopulate(throwPrivate, ctx));\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return populate;\n }\n\n return pipeAsync(...functionsToApply)(populate);\n }\n);\n\nexport const defaultValidatePopulate = asyncCurry(async (ctx: Context, populate: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidatePopulate');\n }\n\n // Call validatePopulate and include all validations by passing in full traversal arrays\n return validatePopulate(ctx, populate, {\n filters: FILTER_TRAVERSALS,\n sort: SORT_TRAVERSALS,\n fields: FIELDS_TRAVERSALS,\n populate: POPULATE_TRAVERSALS,\n });\n});\n"],"names":["ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","constants","FILTER_TRAVERSALS","validateFilters","asyncCurry","ctx","filters","include","schema","Error","functionsToApply","includes","push","traverseQueryFilters","key","attribute","path","isAttribute","isOperator","throwInvalidKey","throwDynamicZones","throwMorphToRelations","throwPassword","throwPrivate","length","pipeAsync","defaultValidateFilters","SORT_TRAVERSALS","validateSort","sort","traverseQuerySort","options","draftAndPublish","value","isScalarAttribute","isEmpty","defaultValidateSort","FIELDS_TRAVERSALS","validateFields","fields","traverseQueryFields","isNil","defaultValidateFields","POPULATE_TRAVERSALS","validatePopulate","populate","traverseQueryPopulate","getModel","parent","set","isPopulatableAttribute","type","raw","isObject","targets","Object","keys","target","model","parseType","defaultValidatePopulate"],"mappings":"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"}
1
+ {"version":3,"file":"validators.js","sources":["../../src/validate/validators.ts"],"sourcesContent":["import { isEmpty, isNil, isObject, isPlainObject, trim } from 'lodash/fp';\n\nimport { pipe as pipeAsync } from '../async';\nimport {\n isScalarAttribute,\n constants,\n isDynamicZoneAttribute,\n isMorphToRelationalAttribute,\n} from '../content-types';\nimport {\n traverseQueryFilters,\n traverseQuerySort,\n traverseQueryFields,\n traverseQueryPopulate,\n} from '../traverse';\nimport { throwPassword, throwPrivate, throwDynamicZones, throwMorphToRelations } from './visitors';\nimport { isOperator } from '../operators';\nimport { asyncCurry, throwInvalidKey } from './utils';\nimport type { Attribute, Model } from '../types';\nimport parseType from '../parse-type';\nimport type { Parent, Path } from '../traverse/factory';\n\nconst { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = constants;\n\ninterface Context {\n schema: Model;\n getModel: (model: string) => Model;\n}\n\ninterface PopulateContext extends Context {\n path?: Path;\n parent?: Parent;\n}\n\ntype AnyFunc = (...args: any[]) => any;\n\nexport const FILTER_TRAVERSALS = [\n 'nonAttributesOperators',\n 'dynamicZones',\n 'morphRelations',\n 'passwords',\n 'private',\n];\n\nexport const validateFilters = asyncCurry(\n async (ctx: Context, filters: unknown, include: (typeof FILTER_TRAVERSALS)[number][]) => {\n // TODO: schema checks should check that it is a valid schema with yup\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidateFilters');\n }\n\n // Build the list of functions conditionally\n const functionsToApply: Array<AnyFunc> = [];\n\n // keys that are not attributes or valid operators\n if (include.includes('nonAttributesOperators')) {\n functionsToApply.push(\n traverseQueryFilters(({ key, attribute, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not removing it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n const isAttribute = !!attribute;\n\n if (!isAttribute && !isOperator(key)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n if (include.includes('dynamicZones')) {\n functionsToApply.push(traverseQueryFilters(throwDynamicZones, ctx));\n }\n\n if (include.includes('morphRelations')) {\n functionsToApply.push(traverseQueryFilters(throwMorphToRelations, ctx));\n }\n\n if (include.includes('passwords')) {\n functionsToApply.push(traverseQueryFilters(throwPassword, ctx));\n }\n\n if (include.includes('private')) {\n functionsToApply.push(traverseQueryFilters(throwPrivate, ctx));\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return filters;\n }\n\n return pipeAsync(...functionsToApply)(filters);\n }\n);\n\nexport const defaultValidateFilters = asyncCurry(async (ctx: Context, filters: unknown) => {\n return validateFilters(ctx, filters, FILTER_TRAVERSALS);\n});\n\nexport const SORT_TRAVERSALS = [\n 'nonAttributesOperators',\n 'dynamicZones',\n 'morphRelations',\n 'passwords',\n 'private',\n 'nonScalarEmptyKeys',\n];\n\nexport const validateSort = asyncCurry(\n async (ctx: Context, sort: unknown, include: (typeof SORT_TRAVERSALS)[number][]) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidateSort');\n }\n\n // Build the list of functions conditionally based on the include array\n const functionsToApply: Array<AnyFunc> = [];\n\n // Validate non attribute keys\n if (include.includes('nonAttributesOperators')) {\n functionsToApply.push(\n traverseQuerySort(({ key, attribute, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not removing it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n // status is a virtual sort key for D&P-enabled content types\n if (key === 'status' && ctx.schema?.options?.draftAndPublish) {\n return;\n }\n\n if (!attribute) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n // Validate dynamic zones from sort\n if (include.includes('dynamicZones')) {\n functionsToApply.push(traverseQuerySort(throwDynamicZones, ctx));\n }\n\n // Validate morphTo relations from sort\n if (include.includes('morphRelations')) {\n functionsToApply.push(traverseQuerySort(throwMorphToRelations, ctx));\n }\n\n // Validate passwords from sort\n if (include.includes('passwords')) {\n functionsToApply.push(traverseQuerySort(throwPassword, ctx));\n }\n\n // Validate private from sort\n if (include.includes('private')) {\n functionsToApply.push(traverseQuerySort(throwPrivate, ctx));\n }\n\n // Validate non-scalar empty keys\n if (include.includes('nonScalarEmptyKeys')) {\n functionsToApply.push(\n traverseQuerySort(({ key, attribute, value, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not removing it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!isScalarAttribute(attribute) && isEmpty(value)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return sort;\n }\n\n return pipeAsync(...functionsToApply)(sort);\n }\n);\n\nexport const defaultValidateSort = asyncCurry(async (ctx: Context, sort: unknown) => {\n return validateSort(ctx, sort, SORT_TRAVERSALS);\n});\n\nexport const FIELDS_TRAVERSALS = ['scalarAttributes', 'privateFields', 'passwordFields'];\n\nexport const validateFields = asyncCurry(\n async (ctx: Context, fields: unknown, include: (typeof FIELDS_TRAVERSALS)[number][]) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidateFields');\n }\n // Build the list of functions conditionally based on the include array\n const functionsToApply: Array<AnyFunc> = [];\n\n // Only allow scalar attributes\n if (include.includes('scalarAttributes')) {\n functionsToApply.push(\n traverseQueryFields(({ key, attribute, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not throwing because of it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (isNil(attribute) || !isScalarAttribute(attribute)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n // Private fields\n if (include.includes('privateFields')) {\n functionsToApply.push(traverseQueryFields(throwPrivate, ctx));\n }\n\n // Password fields\n if (include.includes('passwordFields')) {\n functionsToApply.push(traverseQueryFields(throwPassword, ctx));\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return fields;\n }\n\n return pipeAsync(...functionsToApply)(fields);\n }\n);\n\nexport const defaultValidateFields = asyncCurry(async (ctx: Context, fields: unknown) => {\n return validateFields(ctx, fields, FIELDS_TRAVERSALS);\n});\n\nconst isMorphLikeAttribute = (attribute?: Attribute) =>\n isDynamicZoneAttribute(attribute) || isMorphToRelationalAttribute(attribute);\n\nconst isPopulatableAttribute = (attribute?: Attribute) =>\n !!attribute && ['relation', 'dynamiczone', 'component', 'media'].includes(attribute.type);\n\nconst isDotNotationPopulate = (populate: unknown): populate is string | string[] => {\n if (populate === '*') {\n return false;\n }\n\n if (typeof populate === 'string') {\n return true;\n }\n\n return (\n Array.isArray(populate) && populate.length > 0 && populate.every((p) => typeof p === 'string')\n );\n};\n\nconst flattenDotPopulatePaths = (populate: string | string[]) => {\n const items = Array.isArray(populate) ? populate : [populate];\n\n return items.flatMap((item) =>\n item\n .split(',')\n .map((segment) => trim(segment))\n .filter(Boolean)\n );\n};\n\nconst validatePopulateDotPathSegments = (\n { schema, getModel }: { schema: Model; getModel: (uid: string) => Model },\n segments: string[],\n pathPrefix: string\n) => {\n if (!segments.length) {\n return;\n }\n\n const [head, ...tail] = segments;\n const fullPath = pathPrefix ? `${pathPrefix}.${head}` : head;\n const attribute = schema.attributes[head];\n\n if (!attribute || !isPopulatableAttribute(attribute)) {\n throwInvalidKey({ key: head, path: fullPath });\n }\n\n if (!tail.length) {\n return;\n }\n\n if (attribute.type === 'component') {\n if (!attribute.component) {\n throwInvalidKey({ key: head, path: fullPath });\n }\n\n validatePopulateDotPathSegments(\n { schema: getModel(attribute.component), getModel },\n tail,\n fullPath\n );\n return;\n }\n\n if (attribute.type === 'relation') {\n if (isMorphLikeAttribute(attribute)) {\n throwInvalidKey({ key: head, path: fullPath });\n }\n\n if (!attribute.target) {\n throwInvalidKey({ key: head, path: fullPath });\n }\n\n validatePopulateDotPathSegments(\n { schema: getModel(attribute.target!), getModel },\n tail,\n fullPath\n );\n return;\n }\n\n if (attribute.type === 'media') {\n throwInvalidKey({ key: head, path: fullPath });\n }\n\n if (attribute.type === 'dynamiczone') {\n const [nextSegment, ...rest] = tail;\n const nextPath = `${fullPath}.${nextSegment}`;\n const candidates = (attribute.components ?? [])\n .map((uid) => getModel(uid))\n .filter((model) => model?.attributes?.[nextSegment]);\n\n if (!candidates.length) {\n throwInvalidKey({ key: nextSegment, path: nextPath });\n }\n\n let validated = false;\n\n for (const componentSchema of candidates) {\n const nestedAttribute = componentSchema.attributes[nextSegment];\n\n try {\n if (!rest.length) {\n if (nestedAttribute) {\n validated = true;\n break;\n }\n } else if (nestedAttribute?.type === 'component' && nestedAttribute.component) {\n validatePopulateDotPathSegments(\n { schema: getModel(nestedAttribute.component), getModel },\n rest,\n nextPath\n );\n validated = true;\n break;\n } else if (\n nestedAttribute?.type === 'relation' &&\n !isMorphLikeAttribute(nestedAttribute) &&\n nestedAttribute.target\n ) {\n validatePopulateDotPathSegments(\n { schema: getModel(nestedAttribute.target), getModel },\n rest,\n nextPath\n );\n validated = true;\n break;\n }\n } catch {\n // Try the next dynamic-zone component type.\n }\n }\n\n if (!validated) {\n throwInvalidKey({ key: nextSegment, path: nextPath });\n }\n }\n};\n\nconst validatePopulateDotPaths = (\n ctx: { schema: Model; getModel: (uid: string) => Model },\n populate: string | string[]\n) => {\n for (const path of flattenDotPopulatePaths(populate)) {\n const segments = path\n .split('.')\n .map((segment) => trim(segment))\n .filter(Boolean);\n\n validatePopulateDotPathSegments(ctx, segments, '');\n }\n};\n\nconst validateMorphLikeNestedPopulate = (\n populateValue: unknown,\n { path }: { path: string | null }\n) => {\n if (typeof populateValue === 'string' && populateValue !== '*' && !isNil(populateValue)) {\n throwInvalidKey({ key: 'populate', path });\n }\n\n if (isPlainObject(populateValue) && !isEmpty(populateValue) && !isNil(populateValue)) {\n throwInvalidKey({ key: 'populate', path });\n }\n};\n\nexport const POPULATE_TRAVERSALS = ['nonAttributesOperators', 'private'];\n\nexport const validatePopulate = asyncCurry(\n async (\n ctx: PopulateContext,\n populate: unknown,\n includes: {\n fields?: (typeof FIELDS_TRAVERSALS)[number][];\n sort?: (typeof SORT_TRAVERSALS)[number][];\n filters?: (typeof FILTER_TRAVERSALS)[number][];\n populate?: (typeof POPULATE_TRAVERSALS)[number][];\n }\n ) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidatePopulate');\n }\n\n if (isDotNotationPopulate(populate)) {\n validatePopulateDotPaths({ schema: ctx.schema, getModel: ctx.getModel }, populate);\n\n if (includes?.populate?.includes('private')) {\n return traverseQueryPopulate(throwPrivate, ctx)(populate);\n }\n\n return populate;\n }\n\n // Build the list of functions conditionally based on the include array\n const functionsToApply: Array<AnyFunc> = [];\n\n // Always include the main traversal function\n functionsToApply.push(\n traverseQueryPopulate(\n async ({ key, path, value, schema, attribute, getModel, parent }, { set }) => {\n /**\n * NOTE: The parent check is done to support \"filters\" (and the rest of keys) as valid attribute names.\n *\n * The parent will not be an attribute when its a \"populate\" / \"filters\" / \"sort\" ... key.\n * Only in those scenarios the node will be an attribute.\n */\n if (!parent?.attribute && attribute) {\n const isPopulatableAttribute = [\n 'relation',\n 'dynamiczone',\n 'component',\n 'media',\n ].includes(attribute.type);\n\n if (isMorphLikeAttribute(attribute) && isObject(value) && 'populate' in value) {\n validateMorphLikeNestedPopulate((value as Record<string, unknown>).populate, {\n path: path.raw,\n });\n }\n\n // Throw on non-populate attributes\n if (!isPopulatableAttribute) {\n throwInvalidKey({ key, path: path.raw });\n }\n\n // Valid populatable attribute, so return\n return;\n }\n\n // If we're looking at a populate fragment, ensure its target is valid\n if (key === 'on') {\n // Populate fragment should always be an object\n if (!isObject(value)) {\n return throwInvalidKey({ key, path: path.raw });\n }\n\n const targets = Object.keys(value);\n\n for (const target of targets) {\n const model = getModel(target);\n\n // If a target is invalid (no matching model), then raise an error\n if (!model) {\n throwInvalidKey({ key: target, path: `${path.raw}.${target}` });\n }\n }\n\n // If the fragment's target is fine, then let it pass\n return;\n }\n\n // Ignore plain wildcards\n if (key === '' && value === '*') {\n return;\n }\n\n // Ensure count is a boolean\n if (key === 'count') {\n try {\n parseType({ type: 'boolean', value });\n return;\n } catch {\n throwInvalidKey({ key, path: path.attribute });\n }\n }\n\n // Allowed boolean-like keywords should be ignored\n try {\n parseType({ type: 'boolean', value: key });\n // Key is an allowed boolean-like keyword, skipping validation...\n return;\n } catch {\n // Continue, because it's not a boolean-like\n }\n\n // Handle nested `sort` validation with custom or default traversals\n if (key === 'sort') {\n set(\n key,\n await validateSort(\n {\n schema,\n getModel,\n },\n value, // pass the sort value\n includes?.sort || SORT_TRAVERSALS\n )\n );\n return;\n }\n\n // Handle nested `filters` validation with custom or default traversals\n if (key === 'filters') {\n set(\n key,\n await validateFilters(\n {\n schema,\n getModel,\n },\n value, // pass the filters value\n includes?.filters || FILTER_TRAVERSALS\n )\n );\n return;\n }\n\n // Handle nested `fields` validation with custom or default traversals\n if (key === 'fields') {\n set(\n key,\n await validateFields(\n {\n schema,\n getModel,\n },\n value, // pass the fields value\n includes?.fields || FIELDS_TRAVERSALS\n )\n );\n return;\n }\n\n // Handle recursive nested `populate` validation with the same include object\n if (key === 'populate') {\n set(\n key,\n await validatePopulate(\n {\n schema,\n getModel,\n parent: { key, path, schema, attribute },\n path,\n },\n value, // pass the nested populate value\n includes // pass down the same includes object\n )\n );\n return;\n }\n\n // Throw an error if non-attribute operators are included in the populate array\n if (includes?.populate?.includes('nonAttributesOperators')) {\n throwInvalidKey({ key, path: path.attribute });\n }\n },\n ctx\n )\n );\n\n // Conditionally traverse for private fields only if 'private' is included\n if (includes?.populate?.includes('private')) {\n functionsToApply.push(traverseQueryPopulate(throwPrivate, ctx));\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return populate;\n }\n\n return pipeAsync(...functionsToApply)(populate);\n }\n);\n\nexport const defaultValidatePopulate = asyncCurry(async (ctx: Context, populate: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidatePopulate');\n }\n\n // Call validatePopulate and include all validations by passing in full traversal arrays\n return validatePopulate(ctx, populate, {\n filters: FILTER_TRAVERSALS,\n sort: SORT_TRAVERSALS,\n fields: FIELDS_TRAVERSALS,\n populate: POPULATE_TRAVERSALS,\n });\n});\n"],"names":["ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","constants","FILTER_TRAVERSALS","validateFilters","asyncCurry","ctx","filters","include","schema","Error","functionsToApply","includes","push","traverseQueryFilters","key","attribute","path","isAttribute","isOperator","throwInvalidKey","throwDynamicZones","throwMorphToRelations","throwPassword","throwPrivate","length","pipeAsync","defaultValidateFilters","SORT_TRAVERSALS","validateSort","sort","traverseQuerySort","options","draftAndPublish","value","isScalarAttribute","isEmpty","defaultValidateSort","FIELDS_TRAVERSALS","validateFields","fields","traverseQueryFields","isNil","defaultValidateFields","isMorphLikeAttribute","isDynamicZoneAttribute","isMorphToRelationalAttribute","isPopulatableAttribute","type","isDotNotationPopulate","populate","Array","isArray","every","p","flattenDotPopulatePaths","items","flatMap","item","split","map","segment","trim","filter","Boolean","validatePopulateDotPathSegments","getModel","segments","pathPrefix","head","tail","fullPath","attributes","component","target","nextSegment","rest","nextPath","candidates","components","uid","model","validated","componentSchema","nestedAttribute","validatePopulateDotPaths","validateMorphLikeNestedPopulate","populateValue","isPlainObject","POPULATE_TRAVERSALS","validatePopulate","traverseQueryPopulate","parent","set","isObject","raw","targets","Object","keys","parseType","defaultValidatePopulate"],"mappings":"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"}