@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.
- package/dist/{chunk-E3DB4D43.cjs → chunk-6PWR6K2K.cjs} +9 -9
- package/dist/{chunk-E3DB4D43.cjs.map → chunk-6PWR6K2K.cjs.map} +1 -1
- package/dist/{chunk-K252FYE5.js → chunk-G6EKFWIC.js} +2213 -2192
- package/dist/chunk-G6EKFWIC.js.map +1 -0
- package/dist/{chunk-JUWPBMQM.cjs → chunk-GYRRSOTR.cjs} +50 -2
- package/dist/chunk-GYRRSOTR.cjs.map +1 -0
- package/dist/{chunk-LEM4FLCU.cjs → chunk-HLKC2OBT.cjs} +12 -12
- package/dist/{chunk-LEM4FLCU.cjs.map → chunk-HLKC2OBT.cjs.map} +1 -1
- package/dist/{chunk-QFC725WU.cjs → chunk-L65QBRV5.cjs} +59 -38
- package/dist/chunk-L65QBRV5.cjs.map +1 -0
- package/dist/{chunk-53EA4QPZ.js → chunk-LLTUSEHF.js} +50 -2
- package/dist/chunk-LLTUSEHF.js.map +1 -0
- package/dist/{chunk-CUBRHI6D.js → chunk-LWJJP64X.js} +3 -3
- package/dist/{chunk-X3KKG6IU.js → chunk-MT5GO55P.js} +2 -2
- package/dist/{chunk-EURLSRHW.js → chunk-QLOU4BDD.js} +10 -5
- package/dist/chunk-QLOU4BDD.js.map +1 -0
- package/dist/{chunk-HO2VEMEX.cjs → chunk-TAWNR7IW.cjs} +32 -27
- package/dist/chunk-TAWNR7IW.cjs.map +1 -0
- package/dist/{chunk-E3WJQQGW.cjs → chunk-VXYYZFVV.cjs} +7 -7
- package/dist/{chunk-E3WJQQGW.cjs.map → chunk-VXYYZFVV.cjs.map} +1 -1
- package/dist/{chunk-YE62NF6I.js → chunk-WLCBY6ZO.js} +2 -2
- package/dist/components/chat/index.cjs +3 -3
- package/dist/components/chat/index.js +2 -2
- package/dist/components/contact/contact-form.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +4 -4
- package/dist/components/contact/index.js +3 -3
- package/dist/components/features/index.cjs +3 -3
- package/dist/components/features/index.js +2 -2
- package/dist/components/features/waitlist-form.d.ts +6 -3
- package/dist/components/features/waitlist-form.d.ts.map +1 -1
- package/dist/components/index.cjs +81 -79
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +7 -5
- package/dist/components/index.js.map +1 -1
- package/dist/components/navigation/index.cjs +3 -3
- package/dist/components/navigation/index.js +2 -2
- package/dist/components/onboarding-guides/index.cjs +26 -26
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/tickets/index.cjs +67 -67
- package/dist/components/tickets/index.js +5 -5
- package/dist/components/ui/honeypot-field.d.ts +18 -0
- package/dist/components/ui/honeypot-field.d.ts.map +1 -0
- package/dist/components/ui/index.cjs +5 -3
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.d.ts +1 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +4 -2
- package/dist/hooks/index.cjs +4 -2
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +3 -1
- package/dist/hooks/use-humanity-signals.d.ts +26 -0
- package/dist/hooks/use-humanity-signals.d.ts.map +1 -0
- package/dist/index.cjs +19 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +18 -2
- package/dist/utils/humanity-signals.cjs +30 -0
- package/dist/utils/humanity-signals.cjs.map +1 -0
- package/dist/utils/humanity-signals.d.ts +45 -0
- package/dist/utils/humanity-signals.d.ts.map +1 -0
- package/dist/utils/humanity-signals.js +23 -0
- package/dist/utils/humanity-signals.js.map +1 -0
- package/dist/utils/index.cjs +26 -0
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +21 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +7 -1
- package/src/components/contact/contact-form.tsx +11 -1
- package/src/components/features/waitlist-form.tsx +14 -4
- package/src/components/ui/honeypot-field.tsx +30 -0
- package/src/components/ui/index.ts +1 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/use-humanity-signals.ts +47 -0
- package/src/utils/humanity-signals.ts +57 -0
- package/src/utils/index.ts +6 -0
- package/dist/chunk-53EA4QPZ.js.map +0 -1
- package/dist/chunk-EURLSRHW.js.map +0 -1
- package/dist/chunk-HO2VEMEX.cjs.map +0 -1
- package/dist/chunk-JUWPBMQM.cjs.map +0 -1
- package/dist/chunk-K252FYE5.js.map +0 -1
- package/dist/chunk-QFC725WU.cjs.map +0 -1
- /package/dist/{chunk-CUBRHI6D.js.map → chunk-LWJJP64X.js.map} +0 -0
- /package/dist/{chunk-X3KKG6IU.js.map → chunk-MT5GO55P.js.map} +0 -0
- /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"]}
|
package/dist/utils/index.cjs
CHANGED
|
@@ -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;
|