@calmlens/sdk 0.16.2 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +399 -162
  2. package/cjs/BrowserUpload-DZ0Vbmxi.js +10 -0
  3. package/cjs/BrowserUpload-uZjVFGfP.d.ts +11 -0
  4. package/cjs/CalmLensAppClient-CV_K26Ce.d.ts +40 -0
  5. package/cjs/CalmLensAppClient-DBGmaDlG.js +89 -0
  6. package/cjs/CalmLensConnection-K1TAD1Z-.js +659 -0
  7. package/cjs/CalmLensServerClient-C-pxiz0C.js +645 -0
  8. package/cjs/CalmLensServerClient-JtP687a3.d.ts +235 -0
  9. package/cjs/CalmLensTypes-9Vt16pc7.d.ts +40400 -0
  10. package/cjs/Classification-94kSYWZw-CMnQKW13.d.ts +5873 -0
  11. package/cjs/CryptoUtils-B_x8lMIx-YBW1-bvL.js +42 -0
  12. package/cjs/FileIcons-Ob003MdS.js +175 -0
  13. package/cjs/Jurisdiction-FusEXb4U-zVs21tDv.js +91 -0
  14. package/cjs/ModerationContext-9lGm-Mna-CcmbRnOy.d.ts +67 -0
  15. package/cjs/ModerationContextLimits-Dj1YAl3G.js +1311 -0
  16. package/cjs/ReactUpload-DxtFMr06.js +54 -0
  17. package/cjs/ReactUpload-nZahpmyg.d.ts +17 -0
  18. package/cjs/TestTriggers-By07LR31-CmK0yTyR.d.ts +271 -0
  19. package/cjs/TestTriggers-DcArt0Nu-CvoaONUB.js +1326 -0
  20. package/cjs/UploadController-BBkN4Ni6.js +618 -0
  21. package/{esm/index-C9Xw1aid.d.ts → cjs/WebhookPayload-2aL31v0J.d.ts} +131 -155
  22. package/cjs/app.d.ts +7 -44
  23. package/cjs/app.js +11 -89
  24. package/cjs/elements.d.ts +88 -0
  25. package/cjs/elements.js +555 -0
  26. package/cjs/file-icons.d.ts +67 -0
  27. package/cjs/file-icons.js +10 -0
  28. package/cjs/index-CI4BzN4W.d.ts +252 -0
  29. package/cjs/index.d.ts +6 -4
  30. package/cjs/index.js +9 -4
  31. package/cjs/react-native.d.ts +56 -0
  32. package/cjs/react-native.js +495 -0
  33. package/cjs/react.d.ts +30 -0
  34. package/cjs/react.js +370 -0
  35. package/cjs/server.d.ts +12 -191
  36. package/cjs/server.js +18 -378
  37. package/cjs/test-inputs.d.ts +2 -2
  38. package/cjs/test-inputs.js +9 -264
  39. package/cjs/testing.d.ts +285 -190
  40. package/cjs/testing.js +2393 -1203
  41. package/cjs/ui-CgZpgpNo.d.ts +526 -0
  42. package/cjs/ui-KceuoVCM.js +583 -0
  43. package/cjs/ui.d.ts +2 -0
  44. package/cjs/ui.js +27 -0
  45. package/cjs/vue.d.ts +490 -0
  46. package/cjs/vue.js +419 -0
  47. package/esm/BrowserUpload-D7-zNmc0.js +5 -0
  48. package/esm/BrowserUpload-uZjVFGfP.d.ts +11 -0
  49. package/esm/CalmLensAppClient-CV_K26Ce.d.ts +40 -0
  50. package/esm/CalmLensAppClient-FVMwrHlH.js +84 -0
  51. package/esm/CalmLensConnection-iyNQHA8L.js +582 -0
  52. package/esm/CalmLensServerClient-JtP687a3.d.ts +235 -0
  53. package/esm/CalmLensServerClient-fQEYKLw4.js +586 -0
  54. package/esm/CalmLensTypes-9Vt16pc7.d.ts +40400 -0
  55. package/esm/Classification-94kSYWZw-CMnQKW13.d.ts +5873 -0
  56. package/esm/CryptoUtils-B_x8lMIx-DhuWGzqn.js +25 -0
  57. package/esm/FileIcons-M6dzjFxd.js +128 -0
  58. package/esm/Jurisdiction-FusEXb4U-1ov6m5yE.js +46 -0
  59. package/esm/ModerationContext-9lGm-Mna-CcmbRnOy.d.ts +67 -0
  60. package/esm/ModerationContextLimits-D1x_WAtP.js +1114 -0
  61. package/esm/ReactUpload-D6yBCkcw.js +37 -0
  62. package/esm/ReactUpload-nZahpmyg.d.ts +17 -0
  63. package/esm/TestTriggers-By07LR31-CmK0yTyR.d.ts +271 -0
  64. package/esm/TestTriggers-DcArt0Nu-s0AQZuWE.js +1266 -0
  65. package/esm/UploadController-txp5NuzH.js +589 -0
  66. package/{cjs/index-C9Xw1aid.d.ts → esm/WebhookPayload-2aL31v0J.d.ts} +131 -155
  67. package/esm/app.d.ts +7 -44
  68. package/esm/app.js +3 -86
  69. package/esm/elements.d.ts +88 -0
  70. package/esm/elements.js +528 -0
  71. package/esm/file-icons.d.ts +67 -0
  72. package/esm/file-icons.js +1 -0
  73. package/esm/index-CI4BzN4W.d.ts +252 -0
  74. package/esm/index.d.ts +6 -4
  75. package/esm/index.js +1 -1
  76. package/esm/react-native.d.ts +56 -0
  77. package/esm/react-native.js +467 -0
  78. package/esm/react.d.ts +30 -0
  79. package/esm/react.js +343 -0
  80. package/esm/server.d.ts +12 -191
  81. package/esm/server.js +3 -369
  82. package/esm/styles.css +147 -0
  83. package/esm/svelte/CalmLensMedia.svelte +134 -0
  84. package/esm/svelte/CalmLensUploader.svelte +175 -0
  85. package/esm/svelte/Icon.svelte +7 -0
  86. package/esm/svelte/index.d.ts +37 -0
  87. package/esm/svelte/index.js +6 -0
  88. package/esm/test-inputs.d.ts +2 -2
  89. package/esm/test-inputs.js +1 -256
  90. package/esm/testing.d.ts +285 -190
  91. package/esm/testing.js +2329 -1122
  92. package/esm/ui-Ca_SpJXf.js +458 -0
  93. package/esm/ui-CgZpgpNo.d.ts +526 -0
  94. package/esm/ui.d.ts +2 -0
  95. package/esm/ui.js +3 -0
  96. package/esm/vue.d.ts +490 -0
  97. package/esm/vue.js +392 -0
  98. package/package.json +110 -11
  99. package/cjs/CalmLensConnection-5Hj3trGr.js +0 -234
  100. package/cjs/CalmLensUtils-BeIl1N6N.js +0 -699
  101. package/cjs/CalmLensVersion-BGpB9t4-.js +0 -480
  102. package/cjs/CalmLensWebhooks-CogUYk8-.js +0 -201
  103. package/cjs/Classification-BNhgwGEm-DmA9VEuE.d.ts +0 -4806
  104. package/cjs/TestTriggers-CRKtulyp-vrzEq2wm.d.ts +0 -44
  105. package/cjs/WebhookPayload-CJoIkGBD.d.ts +0 -11753
  106. package/esm/CalmLensConnection-BAJdoZHy.js +0 -193
  107. package/esm/CalmLensUtils-DqniTKJ8.js +0 -574
  108. package/esm/CalmLensVersion-l_khh4nS.js +0 -415
  109. package/esm/CalmLensWebhooks-BtrKKLvg.js +0 -148
  110. package/esm/Classification-BNhgwGEm-DmA9VEuE.d.ts +0 -4806
  111. package/esm/TestTriggers-CRKtulyp-vrzEq2wm.d.ts +0 -44
  112. package/esm/WebhookPayload-CJoIkGBD.d.ts +0 -11753
@@ -0,0 +1,25 @@
1
+ // src/contract/CryptoUtils-B_x8lMIx.js
2
+ const encoder = new TextEncoder();
3
+ /** Lowercase hex of `bytes`, two characters per byte. */
4
+ const bytesToHex = (bytes) => Array.from(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes), (byte) => byte.toString(16).padStart(2, "0")).join("");
5
+ /** SHA-256 of the UTF-8 encoding of `value`, as lowercase hex. */
6
+ const sha256Hex = async (value) => bytesToHex(await crypto.subtle.digest("SHA-256", encoder.encode(value)));
7
+ /** HMAC-SHA256 of `message` keyed with `secret` (both UTF-8 encoded), as lowercase hex. */
8
+ const hmacSha256Hex = async (secret, message) => {
9
+ const key = await crypto.subtle.importKey("raw", encoder.encode(secret), {
10
+ name: "HMAC",
11
+ hash: "SHA-256"
12
+ }, false, ["sign"]);
13
+ return bytesToHex(await crypto.subtle.sign("HMAC", key, encoder.encode(message)));
14
+ };
15
+ /**
16
+ * Compares two strings without leaking, through timing, where they first differ. Strings of
17
+ * different lengths are unequal immediately (the length itself is not secret here).
18
+ */
19
+ const timingSafeEqual = (a, b) => {
20
+ if (a.length !== b.length) return false;
21
+ let difference = 0;
22
+ for (let index = 0; index < a.length; index++) difference |= a.charCodeAt(index) ^ b.charCodeAt(index);
23
+ return difference === 0;
24
+ };
25
+ export { sha256Hex as n, timingSafeEqual as r, hmacSha256Hex as t };
@@ -0,0 +1,128 @@
1
+ // src/ui/FileIcons.ts
2
+ /** The file outline every family's icon is drawn on. */
3
+ const FILE_ICON_OUTLINE = "M14 3v4a1 1 0 0 0 1 1h4 M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2";
4
+ /** The symbols of the families `getFileIcon` finds, which the upload widget draws. */
5
+ const FILE_ICON_SYMBOLS = {
6
+ documents: "M4 6l16 0 M4 12l10 0 M4 18l14 0",
7
+ spreadsheets: "M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14 M3 10h18 M10 3v18",
8
+ presentations: "M3 13a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v6a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -6 M15 9a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -10 M9 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v14a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -14 M4 20h14",
9
+ images: "M15 8h.01 M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12 M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5 M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3",
10
+ audio: "M3 17a3 3 0 1 0 6 0a3 3 0 0 0 -6 0 M13 17a3 3 0 1 0 6 0a3 3 0 0 0 -6 0 M9 17v-13h10v13 M9 8h10",
11
+ video: "M15 10l4.553 -2.276a1 1 0 0 1 1.447 .894v6.764a1 1 0 0 1 -1.447 .894l-4.553 -2.276v-4 M3 8a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2l0 -8",
12
+ archives: "M3 6a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2 M5 8v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-10 M10 12l4 0",
13
+ code: "M7 8l-4 4l4 4 M17 8l4 4l-4 4 M14 4l-4 16",
14
+ data: "M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0 M4 6v6a8 3 0 0 0 16 0v-6 M4 12v6a8 3 0 0 0 16 0v-6",
15
+ design: "M3 21v-4a4 4 0 1 1 4 4h-4 M21 3a16 16 0 0 0 -12.8 10.2 M21 3a16 16 0 0 1 -10.2 12.8 M10.6 9a9 9 0 0 1 4.4 4.4",
16
+ fonts: "M4 20l3 0 M14 20l7 0 M6.9 15l6.9 0 M10.2 6.3l5.8 13.7 M5 20l6 -16l2 0l7 16"
17
+ };
18
+ /**
19
+ * The symbols of the families only an app's own file detection finds, kept apart so the upload
20
+ * widget doesn't bundle them.
21
+ */
22
+ const MORE_FILE_ICON_SYMBOLS = {
23
+ applications: "M4 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4 M4 15a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4 M14 15a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4 M14 7l6 0 M17 4l0 6",
24
+ maps: "M3 7l6 -3l6 3l6 -3v13l-6 3l-6 -3l-6 3v-13 M9 4v13 M15 7v13",
25
+ games: "M12 5h3.5a5 5 0 0 1 0 10h-5.5l-4.015 4.227a2.3 2.3 0 0 1 -3.923 -2.035l1.634 -8.173a5 5 0 0 1 4.904 -4.019h3.4 M14 15l4.07 4.284a2.3 2.3 0 0 0 3.925 -2.023l-1.6 -8.232 M8 9v2 M7 10h2 M14 10h2",
26
+ system: "M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065 M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0",
27
+ security: "M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1 -8.5 15a12 12 0 0 1 -8.5 -15a12 12 0 0 0 8.5 -3 M11 11a1 1 0 1 0 2 0a1 1 0 1 0 -2 0 M12 12l0 2.5"
28
+ };
29
+ const FILE_ICON_COLORS = {
30
+ documents: "#2563eb",
31
+ spreadsheets: "#15803d",
32
+ presentations: "#c2410c",
33
+ images: "#7c3aed",
34
+ audio: "#be185d",
35
+ video: "#b91c1c",
36
+ archives: "#a16207",
37
+ code: "#0e7490",
38
+ data: "#4338ca",
39
+ design: "#a21caf",
40
+ applications: "#475569",
41
+ fonts: "#7c3aed",
42
+ maps: "#15803d",
43
+ games: "#c2410c",
44
+ system: "#475569",
45
+ security: "#0e7490",
46
+ unknown: "#64748b"
47
+ };
48
+ const EXTENSION_FAMILIES = {
49
+ documents: "pdf doc docx odt rtf txt md epub pages",
50
+ spreadsheets: "xls xlsx ods csv tsv numbers",
51
+ presentations: "ppt pptx odp key",
52
+ archives: "zip rar 7z tar gz tgz bz2 xz",
53
+ code: "js ts jsx tsx html css py rb go rs java php c cpp h sh",
54
+ data: "json xml yaml yml sql sqlite db",
55
+ design: "psd ai sketch fig xd",
56
+ fonts: "ttf otf woff woff2"
57
+ };
58
+ const MIME_FAMILIES = {
59
+ image: "images",
60
+ audio: "audio",
61
+ video: "video",
62
+ font: "fonts",
63
+ text: "documents"
64
+ };
65
+ /** A file's icon family and the extension its label shows, such as `pdf`. */
66
+ const getFileIcon = (file) => {
67
+ const dot = file.name.lastIndexOf(".");
68
+ const suffix = dot > 0 ? file.name.slice(dot + 1).toLowerCase() : "";
69
+ const extension = /^[a-z0-9]{1,8}$/.test(suffix) ? suffix : "";
70
+ const listed = Object.entries(EXTENSION_FAMILIES).find(([, extensions]) => ` ${extensions} `.includes(` ${extension} `))?.[0];
71
+ return {
72
+ family: (extension ? listed : void 0) ?? MIME_FAMILIES[file.type.split("/")[0] ?? ""] ?? (file.type === "application/pdf" ? "documents" : "unknown"),
73
+ extension
74
+ };
75
+ };
76
+ /**
77
+ * Where each part of the icon goes in its 24×24 box: the symbol inside the outline, above a band
78
+ * holding the extension. Icons 32 pixels or smaller leave the band out and centre the symbol.
79
+ */
80
+ const getFileIconLayout = (size) => {
81
+ const compact = size <= 32;
82
+ return {
83
+ compact,
84
+ symbol: compact ? {
85
+ x: 6,
86
+ y: 10,
87
+ width: 11,
88
+ height: 10
89
+ } : {
90
+ x: 6.5,
91
+ y: 6.5,
92
+ width: 8.5,
93
+ height: 7
94
+ },
95
+ outlineStroke: 36 / Math.max(size, 24),
96
+ /** The band and its label, in a half-scale group: `transform="scale(0.5)"`. */
97
+ band: {
98
+ x: 3,
99
+ y: 29,
100
+ width: 39,
101
+ height: 14,
102
+ rx: 3
103
+ },
104
+ label: {
105
+ x: 22.5,
106
+ y: 38.9
107
+ }
108
+ };
109
+ };
110
+ /** The label's font size, and a squeezed width for long extensions. */
111
+ const getFileIconLabel = (extension) => ({
112
+ text: extension.toUpperCase() || "FILE",
113
+ fontSize: extension.length > 4 ? 7 : 9,
114
+ textLength: extension.length > 5 ? 33 : void 0
115
+ });
116
+ /**
117
+ * The icon as SVG markup, for the components to insert as it is. `extension` must come from
118
+ * `getFileIcon`, which keeps only letters and digits.
119
+ */
120
+ const renderFileIconSvg = ({ family, extension }, size) => {
121
+ const tint = FILE_ICON_COLORS[family];
122
+ const { compact, symbol, outlineStroke, band, label } = getFileIconLayout(size);
123
+ const text = getFileIconLabel(extension);
124
+ const symbolSvg = family === "unknown" ? "" : `<svg x="${symbol.x}" y="${symbol.y}" width="${symbol.width}" height="${symbol.height}" viewBox="0 0 24 24" stroke-width="1.5"><path d="${FILE_ICON_SYMBOLS[family]}"/></svg>`;
125
+ const bandSvg = compact ? "" : `<g transform="scale(0.5)" stroke="none"><rect x="${band.x}" y="${band.y}" width="${band.width}" height="${band.height}" rx="${band.rx}" fill="${tint}"/><text x="${label.x}" y="${label.y}" text-anchor="middle" fill="#fff" font-family="ui-monospace, monospace" font-size="${text.fontSize}" font-weight="700"${text.textLength ? ` textLength="${text.textLength}" lengthAdjust="spacingAndGlyphs"` : ""}>${text.text}</text></g>`;
126
+ return `<svg class="calmlens-file-icon" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${tint}" stroke-width="${outlineStroke}" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="${FILE_ICON_OUTLINE}"/>${symbolSvg}${bandSvg}</svg>`;
127
+ };
128
+ export { getFileIcon as a, renderFileIconSvg as c, MORE_FILE_ICON_SYMBOLS as i, FILE_ICON_OUTLINE as n, getFileIconLabel as o, FILE_ICON_SYMBOLS as r, getFileIconLayout as s, FILE_ICON_COLORS as t };
@@ -0,0 +1,46 @@
1
+ import * as z from "zod";
2
+ // src/contract/Jurisdiction-FusEXb4U.js
3
+ const JURISDICTION_SCHEMA = z.enum(Object.keys({
4
+ global: {
5
+ name: "Global",
6
+ ageCheckStandard: "any"
7
+ },
8
+ DE: {
9
+ name: "Germany",
10
+ ageCheckStandard: "any"
11
+ },
12
+ AT: {
13
+ name: "Austria",
14
+ ageCheckStandard: "any"
15
+ },
16
+ FR: {
17
+ name: "France",
18
+ ageCheckStandard: "any"
19
+ },
20
+ GB: {
21
+ name: "United Kingdom",
22
+ ageCheckStandard: "verified"
23
+ },
24
+ EU: {
25
+ name: "European Union",
26
+ ageCheckStandard: "verified"
27
+ },
28
+ AU: {
29
+ name: "Australia",
30
+ ageCheckStandard: "verified"
31
+ },
32
+ BR: {
33
+ name: "Brazil",
34
+ ageCheckStandard: "verified"
35
+ }
36
+ }));
37
+ JURISDICTION_SCHEMA.array().min(1).refine((regions) => regions.includes("global") && new Set(regions).size === regions.length, { message: "jurisdiction/global-required-or-duplicate" });
38
+ const COUNTRIES = new Set("AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG EH ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY QA RE RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS YE YT ZA ZM ZW".split(" "));
39
+ const VIEWER_REGION_SCHEMA = z.enum([...COUNTRIES]).describe("Viewer's ISO 3166-1 alpha-2 country, supplied by your integration; not the proxy server's country. EU is not a viewer country.");
40
+ const EU_COUNTRIES = new Set("AT BE BG HR CY CZ DK EE FI FR DE GR HU IE IT LV LT LU MT NL PL PT RO SK SI ES SE".split(" "));
41
+ /** Customer assertions used only for this CDN request. */
42
+ const VIEWER_CLAIMS_SCHEMA = z.object({
43
+ region: VIEWER_REGION_SCHEMA.optional().describe("Viewer country. Defaults to the country of the connection reaching CalmLens; proxies should forward the viewer country explicitly."),
44
+ ageConfirmed: z.boolean().optional().describe("Customer confirmation that age-restricted content may be delivered. Defaults to false; CalmLens does not verify the assertion.")
45
+ }).strict();
46
+ export { JURISDICTION_SCHEMA as n, VIEWER_CLAIMS_SCHEMA as r, EU_COUNTRIES as t };
@@ -0,0 +1,67 @@
1
+ import * as zod from "zod";
2
+ /**
3
+ * What moderation decided for an asset, which also decides how it is delivered: served to anyone
4
+ * with access (`allowed`), served the same way but marked for reduced reach (`limited`), only to
5
+ * requests that confirm the viewer's age with `ageConfirmed`, signed URLs and server keys included
6
+ * (`age-restricted`), not served (`blocked`), or not served with its stored content deleted
7
+ * (`purged`).
8
+ */
9
+ declare const ASSET_MODERATION_DECISION_SCHEMA: zod.ZodEnum<{
10
+ "age-restricted": "age-restricted";
11
+ allowed: "allowed";
12
+ blocked: "blocked";
13
+ limited: "limited";
14
+ purged: "purged";
15
+ }>;
16
+ type AssetModerationDecision = zod.infer<typeof ASSET_MODERATION_DECISION_SCHEMA>;
17
+ declare const HASH_LIST_SCHEMA: zod.ZodObject<{
18
+ id: zod.ZodString;
19
+ projectId: zod.ZodString;
20
+ name: zod.ZodPipe<zod.ZodString, zod.ZodTransform<string, string>>;
21
+ description: zod.ZodOptional<zod.ZodNullable<zod.ZodPipe<zod.ZodString, zod.ZodTransform<string, string>>>>;
22
+ action: zod.ZodEnum<{
23
+ block: "block";
24
+ flag: "flag";
25
+ }>;
26
+ createdAt: zod.ZodNumber;
27
+ updatedAt: zod.ZodOptional<zod.ZodNumber>;
28
+ }, zod.core.$strip>;
29
+ type HashList = zod.infer<typeof HASH_LIST_SCHEMA>;
30
+ declare const HASH_LIST_ENTRY_SCHEMA: zod.ZodObject<{
31
+ id: zod.ZodString;
32
+ projectId: zod.ZodString;
33
+ hashListId: zod.ZodString;
34
+ hash: zod.ZodString;
35
+ quality: zod.ZodNullable<zod.ZodNumber>;
36
+ label: zod.ZodOptional<zod.ZodNullable<zod.ZodPipe<zod.ZodString, zod.ZodTransform<string, string>>>>;
37
+ sourceAssetId: zod.ZodOptional<zod.ZodNullable<zod.ZodString>>;
38
+ createdAt: zod.ZodNumber;
39
+ }, zod.core.$strip>;
40
+ type HashListEntry = zod.infer<typeof HASH_LIST_ENTRY_SCHEMA>;
41
+ /** The most recent earlier posts CalmLens uses. */
42
+ declare const MODERATION_CONTEXT_USED_ITEMS = 5;
43
+ /**
44
+ * The most characters of earlier posts CalmLens uses. The newest post always fits, since no post
45
+ * may be longer.
46
+ */
47
+ declare const MODERATION_CONTEXT_USED_CHARACTERS = 2000;
48
+ /** An earlier post in the conversation. */
49
+ interface ModerationContextItem {
50
+ text: string;
51
+ authorId?: string;
52
+ }
53
+ /**
54
+ * The earlier posts CalmLens uses: the most recent ones, newest first, while at most
55
+ * `MODERATION_CONTEXT_USED_ITEMS` and `MODERATION_CONTEXT_USED_CHARACTERS` allow, returned oldest
56
+ * first. The newest post is always kept, so an over-long one is left for validation to reject.
57
+ */
58
+ declare const selectModerationContextItems: <Item extends ModerationContextItem>(items: readonly Item[]) => Item[];
59
+ /** The context a request may send: up to 20 earlier posts, oldest first. */
60
+ declare const MODERATION_CONTEXT_SCHEMA: zod.ZodObject<{
61
+ items: zod.ZodArray<zod.ZodObject<{
62
+ text: zod.ZodString;
63
+ authorId: zod.ZodOptional<zod.ZodString>;
64
+ }, zod.core.$strict>>;
65
+ }, zod.core.$strict>;
66
+ type ModerationContext = zod.infer<typeof MODERATION_CONTEXT_SCHEMA>;
67
+ export { selectModerationContextItems as a, AssetModerationDecision as c, ModerationContextItem as i, MODERATION_CONTEXT_USED_CHARACTERS as n, HashList as o, MODERATION_CONTEXT_USED_ITEMS as r, HashListEntry as s, ModerationContext as t };