@flamingo-stack/openframe-frontend-core 0.0.227 → 0.0.228

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 (87) hide show
  1. package/dist/{chunk-E3DB4D43.cjs → chunk-6PWR6K2K.cjs} +9 -9
  2. package/dist/{chunk-E3DB4D43.cjs.map → chunk-6PWR6K2K.cjs.map} +1 -1
  3. package/dist/{chunk-K252FYE5.js → chunk-G6EKFWIC.js} +2213 -2192
  4. package/dist/chunk-G6EKFWIC.js.map +1 -0
  5. package/dist/{chunk-JUWPBMQM.cjs → chunk-GYRRSOTR.cjs} +50 -2
  6. package/dist/chunk-GYRRSOTR.cjs.map +1 -0
  7. package/dist/{chunk-LEM4FLCU.cjs → chunk-HLKC2OBT.cjs} +12 -12
  8. package/dist/{chunk-LEM4FLCU.cjs.map → chunk-HLKC2OBT.cjs.map} +1 -1
  9. package/dist/{chunk-QFC725WU.cjs → chunk-L65QBRV5.cjs} +59 -38
  10. package/dist/chunk-L65QBRV5.cjs.map +1 -0
  11. package/dist/{chunk-53EA4QPZ.js → chunk-LLTUSEHF.js} +50 -2
  12. package/dist/chunk-LLTUSEHF.js.map +1 -0
  13. package/dist/{chunk-CUBRHI6D.js → chunk-LWJJP64X.js} +3 -3
  14. package/dist/{chunk-X3KKG6IU.js → chunk-MT5GO55P.js} +2 -2
  15. package/dist/{chunk-EURLSRHW.js → chunk-QLOU4BDD.js} +10 -5
  16. package/dist/chunk-QLOU4BDD.js.map +1 -0
  17. package/dist/{chunk-HO2VEMEX.cjs → chunk-TAWNR7IW.cjs} +32 -27
  18. package/dist/chunk-TAWNR7IW.cjs.map +1 -0
  19. package/dist/{chunk-E3WJQQGW.cjs → chunk-VXYYZFVV.cjs} +7 -7
  20. package/dist/{chunk-E3WJQQGW.cjs.map → chunk-VXYYZFVV.cjs.map} +1 -1
  21. package/dist/{chunk-YE62NF6I.js → chunk-WLCBY6ZO.js} +2 -2
  22. package/dist/components/chat/index.cjs +3 -3
  23. package/dist/components/chat/index.js +2 -2
  24. package/dist/components/contact/contact-form.d.ts.map +1 -1
  25. package/dist/components/contact/index.cjs +4 -4
  26. package/dist/components/contact/index.js +3 -3
  27. package/dist/components/features/index.cjs +3 -3
  28. package/dist/components/features/index.js +2 -2
  29. package/dist/components/features/waitlist-form.d.ts +6 -3
  30. package/dist/components/features/waitlist-form.d.ts.map +1 -1
  31. package/dist/components/index.cjs +81 -79
  32. package/dist/components/index.cjs.map +1 -1
  33. package/dist/components/index.js +7 -5
  34. package/dist/components/index.js.map +1 -1
  35. package/dist/components/navigation/index.cjs +3 -3
  36. package/dist/components/navigation/index.js +2 -2
  37. package/dist/components/onboarding-guides/index.cjs +26 -26
  38. package/dist/components/onboarding-guides/index.js +4 -4
  39. package/dist/components/tickets/index.cjs +67 -67
  40. package/dist/components/tickets/index.js +5 -5
  41. package/dist/components/ui/honeypot-field.d.ts +18 -0
  42. package/dist/components/ui/honeypot-field.d.ts.map +1 -0
  43. package/dist/components/ui/index.cjs +5 -3
  44. package/dist/components/ui/index.cjs.map +1 -1
  45. package/dist/components/ui/index.d.ts +1 -0
  46. package/dist/components/ui/index.d.ts.map +1 -1
  47. package/dist/components/ui/index.js +4 -2
  48. package/dist/hooks/index.cjs +4 -2
  49. package/dist/hooks/index.cjs.map +1 -1
  50. package/dist/hooks/index.d.ts +1 -0
  51. package/dist/hooks/index.d.ts.map +1 -1
  52. package/dist/hooks/index.js +3 -1
  53. package/dist/hooks/use-humanity-signals.d.ts +26 -0
  54. package/dist/hooks/use-humanity-signals.d.ts.map +1 -0
  55. package/dist/index.cjs +19 -3
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.js +18 -2
  58. package/dist/utils/humanity-signals.cjs +30 -0
  59. package/dist/utils/humanity-signals.cjs.map +1 -0
  60. package/dist/utils/humanity-signals.d.ts +45 -0
  61. package/dist/utils/humanity-signals.d.ts.map +1 -0
  62. package/dist/utils/humanity-signals.js +23 -0
  63. package/dist/utils/humanity-signals.js.map +1 -0
  64. package/dist/utils/index.cjs +26 -0
  65. package/dist/utils/index.cjs.map +1 -1
  66. package/dist/utils/index.d.ts +1 -0
  67. package/dist/utils/index.d.ts.map +1 -1
  68. package/dist/utils/index.js +21 -1
  69. package/dist/utils/index.js.map +1 -1
  70. package/package.json +7 -1
  71. package/src/components/contact/contact-form.tsx +11 -1
  72. package/src/components/features/waitlist-form.tsx +14 -4
  73. package/src/components/ui/honeypot-field.tsx +30 -0
  74. package/src/components/ui/index.ts +1 -0
  75. package/src/hooks/index.ts +4 -0
  76. package/src/hooks/use-humanity-signals.ts +47 -0
  77. package/src/utils/humanity-signals.ts +57 -0
  78. package/src/utils/index.ts +6 -0
  79. package/dist/chunk-53EA4QPZ.js.map +0 -1
  80. package/dist/chunk-EURLSRHW.js.map +0 -1
  81. package/dist/chunk-HO2VEMEX.cjs.map +0 -1
  82. package/dist/chunk-JUWPBMQM.cjs.map +0 -1
  83. package/dist/chunk-K252FYE5.js.map +0 -1
  84. package/dist/chunk-QFC725WU.cjs.map +0 -1
  85. /package/dist/{chunk-CUBRHI6D.js.map → chunk-LWJJP64X.js.map} +0 -0
  86. /package/dist/{chunk-X3KKG6IU.js.map → chunk-MT5GO55P.js.map} +0 -0
  87. /package/dist/{chunk-YE62NF6I.js.map → chunk-WLCBY6ZO.js.map} +0 -0
@@ -0,0 +1,23 @@
1
+ // src/utils/humanity-signals.ts
2
+ var HONEYPOT_FIELD = "contact_url_confirm";
3
+ var ELAPSED_MS_FIELD = "form_elapsed_ms";
4
+ var DEFAULT_MIN_FILL_MS = 700;
5
+ function extractHumanitySignals(body) {
6
+ const b = body ?? {};
7
+ const rawHp = b[HONEYPOT_FIELD];
8
+ const honeypot = rawHp == null ? "" : String(rawHp);
9
+ const rawMs = b[ELAPSED_MS_FIELD];
10
+ const elapsedMs = typeof rawMs === "number" && Number.isFinite(rawMs) ? rawMs : null;
11
+ return { honeypot, elapsedMs };
12
+ }
13
+ function evaluateHumanitySignals(body, opts) {
14
+ const { honeypot, elapsedMs } = extractHumanitySignals(body);
15
+ if (honeypot.trim() !== "") return { ok: false, reason: "honeypot" };
16
+ if (elapsedMs !== null && elapsedMs < opts.minFillMs) return { ok: false, reason: "too_fast" };
17
+ return { ok: true };
18
+ }
19
+ var splitCsvEnv = (s) => s?.split(",").map((t) => t.trim()).filter(Boolean) ?? [];
20
+
21
+ export { DEFAULT_MIN_FILL_MS, ELAPSED_MS_FIELD, HONEYPOT_FIELD, evaluateHumanitySignals, extractHumanitySignals, splitCsvEnv };
22
+ //# sourceMappingURL=humanity-signals.js.map
23
+ //# sourceMappingURL=humanity-signals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/humanity-signals.ts"],"names":[],"mappings":";AAgBO,IAAM,cAAA,GAAiB;AAEvB,IAAM,gBAAA,GAAmB;AAEzB,IAAM,mBAAA,GAAsB;AAS5B,SAAS,uBAAuB,IAAA,EAA+D;AACpG,EAAA,MAAM,CAAA,GAAK,QAAQ,EAAC;AACpB,EAAA,MAAM,KAAA,GAAQ,EAAE,cAAc,CAAA;AAK9B,EAAA,MAAM,QAAA,GAAW,KAAA,IAAS,IAAA,GAAO,EAAA,GAAK,OAAO,KAAK,CAAA;AAClD,EAAA,MAAM,KAAA,GAAQ,EAAE,gBAAgB,CAAA;AAChC,EAAA,MAAM,SAAA,GAAY,OAAO,KAAA,KAAU,QAAA,IAAY,OAAO,QAAA,CAAS,KAAK,IAAI,KAAA,GAAQ,IAAA;AAChF,EAAA,OAAO,EAAE,UAAU,SAAA,EAAU;AAC/B;AAOO,SAAS,uBAAA,CAAwB,MAAe,IAAA,EAA8C;AACnG,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAU,GAAI,uBAAuB,IAAI,CAAA;AAC3D,EAAA,IAAI,QAAA,CAAS,MAAK,KAAM,EAAA,SAAW,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,UAAA,EAAW;AACnE,EAAA,IAAI,SAAA,KAAc,IAAA,IAAQ,SAAA,GAAY,IAAA,CAAK,SAAA,SAAkB,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,UAAA,EAAW;AAC7F,EAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AACpB;AAGO,IAAM,cAAc,CAAC,CAAA,KAC1B,CAAA,EAAG,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAA,EAAM,EAAE,MAAA,CAAO,OAAO,KAAK","file":"humanity-signals.js","sourcesContent":["/**\n * Humanity signals — invisible bot-protection primitives shared by the lib's\n * public forms (client) and the hub's per-route `verifyHuman` gate (server).\n *\n * PURE + React-free on purpose: this module is a tsup SERVER entry (no\n * \"use client\" banner) so the hub can import it server-side without pulling a\n * client-reference boundary — same pattern as `schemas/contact-schema` and\n * `components/features/mux-origins`.\n *\n * Two origin-independent signals travel in the POST body: a honeypot (a hidden\n * field real users never fill) and timing (ms from form mount to submit).\n * `evaluateHumanitySignals` is the SINGLE source of truth for the block/allow\n * decision — the hub imports + calls it rather than re-implementing the rules.\n */\n\n/** Hidden honeypot field name. Innocuous + autofill-resistant (deliberately NOT name/email). */\nexport const HONEYPOT_FIELD = 'contact_url_confirm'\n/** Client-measured ms between form mount and submit. */\nexport const ELAPSED_MS_FIELD = 'form_elapsed_ms'\n/** Default minimum fill time (ms). A submit faster than this is treated as a bot. */\nexport const DEFAULT_MIN_FILL_MS = 700\n\n/** Keyed wire object produced by `useHumanitySignals().getSignals()` and spread into the POST body. */\nexport type HumanitySignals = Record<string, string | number>\n\n/** Result of {@link evaluateHumanitySignals}. */\nexport type HumanityVerdict = { ok: true } | { ok: false; reason: 'honeypot' | 'too_fast' }\n\n/** Tolerant reader — never throws; missing/garbage timing → null. */\nexport function extractHumanitySignals(body: unknown): { honeypot: string; elapsedMs: number | null } {\n const b = (body ?? {}) as Record<string, unknown>\n const rawHp = b[HONEYPOT_FIELD]\n // A legit client always sends a STRING here (getSignals → ref.value ?? ''),\n // so ANY present non-string value is a bot filling the decoy with a non-string\n // to dodge the empty-check — coerce to a (non-empty) string so it still trips.\n // null/undefined → '' = the correct \"field absent / unfilled\" allow case.\n const honeypot = rawHp == null ? '' : String(rawHp)\n const rawMs = b[ELAPSED_MS_FIELD]\n const elapsedMs = typeof rawMs === 'number' && Number.isFinite(rawMs) ? rawMs : null\n return { honeypot, elapsedMs }\n}\n\n/**\n * SINGLE decision fn for honeypot + timing (the hub's `verifyHuman` imports + calls this):\n * - honeypot non-empty → bot (real users never fill the off-screen field)\n * - elapsed below `minFillMs` → bot (humans take time; a MISSING timing value never blocks)\n */\nexport function evaluateHumanitySignals(body: unknown, opts: { minFillMs: number }): HumanityVerdict {\n const { honeypot, elapsedMs } = extractHumanitySignals(body)\n if (honeypot.trim() !== '') return { ok: false, reason: 'honeypot' }\n if (elapsedMs !== null && elapsedMs < opts.minFillMs) return { ok: false, reason: 'too_fast' }\n return { ok: true }\n}\n\n/** Parse a comma-separated env string → trimmed, non-empty entries (undefined → []). */\nexport const splitCsvEnv = (s?: string): string[] =>\n s?.split(',').map((t) => t.trim()).filter(Boolean) ?? []\n"]}
@@ -3312,6 +3312,26 @@ function buildDefaultHref(basePath, slug) {
3312
3312
  return { href: `${basePath}/${slug}`, targetPlatform: null };
3313
3313
  }
3314
3314
 
3315
+ // src/utils/humanity-signals.ts
3316
+ var HONEYPOT_FIELD = "contact_url_confirm";
3317
+ var ELAPSED_MS_FIELD = "form_elapsed_ms";
3318
+ var DEFAULT_MIN_FILL_MS = 700;
3319
+ function extractHumanitySignals(body) {
3320
+ const b = body ?? {};
3321
+ const rawHp = b[HONEYPOT_FIELD];
3322
+ const honeypot = rawHp == null ? "" : String(rawHp);
3323
+ const rawMs = b[ELAPSED_MS_FIELD];
3324
+ const elapsedMs = typeof rawMs === "number" && Number.isFinite(rawMs) ? rawMs : null;
3325
+ return { honeypot, elapsedMs };
3326
+ }
3327
+ function evaluateHumanitySignals(body, opts) {
3328
+ const { honeypot, elapsedMs } = extractHumanitySignals(body);
3329
+ if (honeypot.trim() !== "") return { ok: false, reason: "honeypot" };
3330
+ if (elapsedMs !== null && elapsedMs < opts.minFillMs) return { ok: false, reason: "too_fast" };
3331
+ return { ok: true };
3332
+ }
3333
+ var splitCsvEnv = (s) => s?.split(",").map((t) => t.trim()).filter(Boolean) ?? [];
3334
+
3315
3335
  exports.ANTHROPIC_SUPPORTED_IMAGE_MIME = ANTHROPIC_SUPPORTED_IMAGE_MIME;
3316
3336
  exports.AUTO_CONTINUATION_DIRECTIVE_PREFIX = AUTO_CONTINUATION_DIRECTIVE_PREFIX;
3317
3337
  exports.CHAT_ATTACHMENT_MARKDOWN_PATTERN = CHAT_ATTACHMENT_MARKDOWN_PATTERN;
@@ -3320,12 +3340,15 @@ exports.CHAT_ATTACHMENT_VIEW_URL_PREFIX = CHAT_ATTACHMENT_VIEW_URL_PREFIX;
3320
3340
  exports.CHAT_ATTACHMENT_VIEW_URL_PREFIX_REGEX_ESCAPED = CHAT_ATTACHMENT_VIEW_URL_PREFIX_REGEX_ESCAPED;
3321
3341
  exports.CUSTOM_ITEM_ID = CUSTOM_ITEM_ID;
3322
3342
  exports.DEFAULT_CONTENT_SUFFIXES = DEFAULT_CONTENT_SUFFIXES;
3343
+ exports.DEFAULT_MIN_FILL_MS = DEFAULT_MIN_FILL_MS;
3323
3344
  exports.DEFAULT_OS_PLATFORM = DEFAULT_OS_PLATFORM;
3324
3345
  exports.DELIVERY_TASK_TYPE_OPTIONS = DELIVERY_TASK_TYPE_OPTIONS;
3325
3346
  exports.DESIGN_PALETTE = DESIGN_PALETTE;
3326
3347
  exports.DEV_SECTION_PARAM_KEYS = DEV_SECTION_PARAM_KEYS;
3348
+ exports.ELAPSED_MS_FIELD = ELAPSED_MS_FIELD;
3327
3349
  exports.GENERIC_EMAIL_DOMAINS = GENERIC_EMAIL_DOMAINS;
3328
3350
  exports.HEX_PATTERN = HEX_PATTERN;
3351
+ exports.HONEYPOT_FIELD = HONEYPOT_FIELD;
3329
3352
  exports.ICON_REGISTRY = ICON_REGISTRY;
3330
3353
  exports.OPENFRAME_DEV_SECTIONS = OPENFRAME_DEV_SECTIONS;
3331
3354
  exports.OS_PLATFORMS = OS_PLATFORMS;
@@ -3353,9 +3376,11 @@ exports.deepClone = deepClone;
3353
3376
  exports.delay = delay;
3354
3377
  exports.embedAuthedFetch = embedAuthedFetch;
3355
3378
  exports.escapeMarkdownInline = escapeMarkdownInline;
3379
+ exports.evaluateHumanitySignals = evaluateHumanitySignals;
3356
3380
  exports.extractDomainFromEmail = extractDomainFromEmail;
3357
3381
  exports.extractDominantColor = extractDominantColor;
3358
3382
  exports.extractEntityIdFilter = extractEntityIdFilter;
3383
+ exports.extractHumanitySignals = extractHumanitySignals;
3359
3384
  exports.extractImageEdgeColorAsync = extractImageEdgeColorAsync;
3360
3385
  exports.fetchPriorityProp = fetchPriorityProp;
3361
3386
  exports.flattenAssistantContent = flattenAssistantContent;
@@ -3475,6 +3500,7 @@ exports.scrollElementIntoView = scrollElementIntoView;
3475
3500
  exports.setEmbedAuthAdapter = setEmbedAuthAdapter;
3476
3501
  exports.setEmbedProxyAuth = setEmbedProxyAuth;
3477
3502
  exports.shouldProxyImage = shouldProxyImage;
3503
+ exports.splitCsvEnv = splitCsvEnv;
3478
3504
  exports.stripChatAttachmentMarkdown = stripChatAttachmentMarkdown;
3479
3505
  exports.stripHtml = stripHtml;
3480
3506
  exports.toToolLabel = toToolLabel;