@evinvest/kitstart 0.17.0 → 0.18.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.
- package/README.md +147 -10
- package/dist/core/accept.d.ts +14 -0
- package/dist/core/accept.js +21 -3
- package/dist/core/analytics.d.ts +11 -2
- package/dist/core/analytics.js +22 -0
- package/dist/core/channels.d.ts +12 -4
- package/dist/core/channels.js +11 -1
- package/dist/core/lead-capture-text.d.ts +6 -2
- package/dist/core/lead.d.ts +33 -10
- package/dist/core/lead.js +21 -8
- package/dist/core/messenger-message.d.ts +31 -0
- package/dist/core/messenger-message.js +33 -0
- package/dist/core/messenger-text.d.ts +104 -0
- package/dist/core/messenger-text.js +150 -0
- package/dist/core/messenger.d.ts +92 -0
- package/dist/core/messenger.js +55 -0
- package/dist/core/place/index.d.ts +1 -1
- package/dist/core/place/live.d.ts +5 -1
- package/dist/core/place/live.js +22 -1
- package/dist/core/place/types.d.ts +17 -1
- package/dist/core/site.d.ts +8 -1
- package/dist/core/site.js +22 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.js +7 -4
- package/dist/next/quote-route.js +4 -7
- package/dist/react/AnalyticsBoundary.js +3 -3
- package/dist/react/LeadCapture.d.ts +24 -1
- package/dist/react/LeadCapture.js +96 -11
- package/dist/react/LeadCaptureChannels.d.ts +7 -2
- package/dist/react/LeadCaptureChannels.js +2 -2
- package/dist/react/LeadCaptureEstimate.d.ts +6 -0
- package/dist/react/LeadCaptureFields.d.ts +17 -0
- package/dist/react/LeadCaptureFields.js +42 -33
- package/dist/react/LeadCaptureMessenger.d.ts +41 -0
- package/dist/react/LeadCaptureMessenger.js +133 -0
- package/dist/react/LeadCapturePrice.d.ts +9 -3
- package/dist/react/LeadCapturePrice.js +24 -4
- package/dist/react/LeadCaptureSubmit.d.ts +3 -0
- package/dist/react/LeadCaptureSubmit.js +2 -2
- package/dist/react/LeadCaptureTiles.js +9 -4
- package/dist/react/analytics-context.d.ts +9 -3
- package/dist/react/analytics-context.js +7 -3
- package/dist/react/index.d.ts +1 -0
- package/dist/react/messenger/action.d.ts +144 -0
- package/dist/react/messenger/action.js +301 -0
- package/dist/react/messenger/chip.d.ts +8 -0
- package/dist/react/messenger/chip.js +22 -0
- package/dist/react/messenger/fallback.d.ts +8 -0
- package/dist/react/messenger/fallback.js +11 -0
- package/dist/react/messenger/saga.d.ts +10 -0
- package/dist/react/messenger/saga.js +33 -0
- package/dist/react/messenger/segment.d.ts +8 -0
- package/dist/react/messenger/segment.js +15 -0
- package/dist/react/messenger/select.d.ts +10 -0
- package/dist/react/messenger/select.js +26 -0
- package/dist/react/messenger/sheet.d.ts +10 -0
- package/dist/react/messenger/sheet.js +57 -0
- package/dist/react/messenger/split.d.ts +9 -0
- package/dist/react/messenger/split.js +17 -0
- package/dist/react/messenger/swap.d.ts +10 -0
- package/dist/react/messenger/swap.js +18 -0
- package/dist/react/messenger/thanks.d.ts +10 -0
- package/dist/react/messenger/thanks.js +18 -0
- package/dist/react/messenger/tiles.d.ts +8 -0
- package/dist/react/messenger/tiles.js +20 -0
- package/dist/react/messenger/types.d.ts +98 -0
- package/dist/react/messenger/types.js +1 -0
- package/dist/react/messenger/urgency.d.ts +10 -0
- package/dist/react/messenger/urgency.js +29 -0
- package/dist/react/use-lead-error.d.ts +3 -3
- package/dist/react/use-lead-events.d.ts +21 -1
- package/dist/react/use-lead-events.js +9 -3
- package/dist/react/use-lead-submit.d.ts +20 -6
- package/dist/react/use-lead-submit.js +23 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/lead-store-sqlite.js +11 -5
- package/dist/server/lead-webhook.d.ts +30 -5
- package/dist/server/lead-webhook.js +13 -7
- package/dist/server/notify.js +11 -5
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/landing-contract.js +6 -1
- package/dist/testing/lead-rules.d.ts +8 -0
- package/dist/testing/lead-rules.js +30 -1
- package/package.json +5 -2
- package/template/flake.nix +1 -1
- package/template/package.json +2 -2
|
@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
|
|
|
2
2
|
import { isPublished, publicationGaps } from "../core/place/publication.js";
|
|
3
3
|
import { createRouting, NON_PAGE_ROUTES, pointSuffixes, THANKS } from "../core/routing.js";
|
|
4
4
|
import { openLaunchBlockers } from "../core/site.js";
|
|
5
|
-
import { leadRuleDisagreements } from "./lead-rules.js";
|
|
5
|
+
import { leadRuleDisagreements, messengerRuleDisagreements } from "./lead-rules.js";
|
|
6
6
|
import { servedPaths } from "./served-files.js";
|
|
7
7
|
const SOURCE_LINE = /@source\s+["'][^"']*node_modules\/@evinvest\/kitstart\/dist["']/;
|
|
8
8
|
const MATCHER = "/((?!_next/).*)";
|
|
@@ -48,6 +48,11 @@ export function describeLandingContract(site, options = {}) {
|
|
|
48
48
|
it("refuses exactly the phone numbers the form blocks", () => {
|
|
49
49
|
expect(leadRuleDisagreements(site.lead)).toEqual([]);
|
|
50
50
|
});
|
|
51
|
+
// A messenger lead is posted as the visitor leaves for the chat: the
|
|
52
|
+
// message carries the rest, and a refusal would be shown to no one.
|
|
53
|
+
it("takes a messenger lead without a postcode or a phone", () => {
|
|
54
|
+
expect(messengerRuleDisagreements(site.lead)).toEqual([]);
|
|
55
|
+
});
|
|
51
56
|
it("publishes nothing without a domain", () => {
|
|
52
57
|
if (site.brand.domain !== null)
|
|
53
58
|
return;
|
|
@@ -16,3 +16,11 @@ export declare const PHONE_MATRIX: readonly {
|
|
|
16
16
|
* a postcode — so only the phone is judged. Empty is agreement.
|
|
17
17
|
*/
|
|
18
18
|
export declare function leadRuleDisagreements(schema: LeadSchema<string>): string[];
|
|
19
|
+
/**
|
|
20
|
+
* Where a brand's form rule refuses a messenger lead it must take: one with
|
|
21
|
+
* the subject chosen and nothing else — no postcode, no phone — since the
|
|
22
|
+
* chat carries the rest and is how the business answers. And where it takes
|
|
23
|
+
* a typed number the form would block: a phone given to a messenger lead is
|
|
24
|
+
* still one the operator may call. Empty is agreement.
|
|
25
|
+
*/
|
|
26
|
+
export declare function messengerRuleDisagreements(schema: LeadSchema<string>): string[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readCandidate, validateCandidate } from "../core/lead.js";
|
|
1
|
+
import { CHANNEL_FIELD, readCandidate, validateCandidate } from "../core/lead.js";
|
|
2
2
|
import { phoneProblem } from "../core/phone.js";
|
|
3
3
|
/**
|
|
4
4
|
* Numbers people type, and whether each is a way to reach them — the
|
|
@@ -62,3 +62,32 @@ export function leadRuleDisagreements(schema) {
|
|
|
62
62
|
}
|
|
63
63
|
return out;
|
|
64
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Where a brand's form rule refuses a messenger lead it must take: one with
|
|
67
|
+
* the subject chosen and nothing else — no postcode, no phone — since the
|
|
68
|
+
* chat carries the rest and is how the business answers. And where it takes
|
|
69
|
+
* a typed number the form would block: a phone given to a messenger lead is
|
|
70
|
+
* still one the operator may call. Empty is agreement.
|
|
71
|
+
*/
|
|
72
|
+
export function messengerRuleDisagreements(schema) {
|
|
73
|
+
const out = [];
|
|
74
|
+
for (const channel of ["whatsapp", "telegram"]) {
|
|
75
|
+
const bare = new FormData();
|
|
76
|
+
bare.set(schema.wire.subject, schema.subjects[0] ?? "");
|
|
77
|
+
bare.set(CHANNEL_FIELD, channel);
|
|
78
|
+
const refused = validateCandidate(schema, readCandidate(schema, bare, null));
|
|
79
|
+
if (refused)
|
|
80
|
+
out.push(`${channel}: a lead with no postcode and no phone is refused at ${refused.field} (${refused.why})`);
|
|
81
|
+
for (const { mobile } of PHONE_MATRIX) {
|
|
82
|
+
const form = new FormData();
|
|
83
|
+
form.set(schema.wire.subject, schema.subjects[0] ?? "");
|
|
84
|
+
form.set(CHANNEL_FIELD, channel);
|
|
85
|
+
form.set(schema.wire.mobile, mobile);
|
|
86
|
+
const blocked = phoneProblem(mobile) !== null;
|
|
87
|
+
const refused = validateCandidate(schema, readCandidate(schema, form, null)) !== null;
|
|
88
|
+
if (blocked !== refused)
|
|
89
|
+
out.push(`${channel} ${mobile}: the form ${blocked ? "blocks" : "takes"} it, the server ${refused ? "refuses" : "takes"} it`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evinvest/kitstart",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Landing-site machinery for local-service brands: a site composition root, the Place/Presence/ServiceArea model with a publication gate, host/locale routing, schema.org and SEO builders, the lead funnel with its antispam, and analytics events. Pure core at '.', more subpaths per runtime.",
|
|
5
5
|
"license": "BlueOak-1.0.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -126,5 +126,8 @@
|
|
|
126
126
|
"template/proxy.ts",
|
|
127
127
|
"template/app/[locale]/[location]/layout.tsx",
|
|
128
128
|
"dist/cli/kitstart-size.js"
|
|
129
|
-
]
|
|
129
|
+
],
|
|
130
|
+
"dependencies": {
|
|
131
|
+
"qrcode-generator": "^2.0.4"
|
|
132
|
+
}
|
|
130
133
|
}
|
package/template/flake.nix
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
v_flakes.url = "github:valeratrades/v_flakes?ref=v1.6";
|
|
4
4
|
# The lib flake at the tag of the @evinvest/kitstart version in
|
|
5
5
|
# package-lock.json — mkLanding refuses a mismatch.
|
|
6
|
-
ev.url = "github:EV-invest/lib?ref=@evinvest/kitstart-v0.
|
|
6
|
+
ev.url = "github:EV-invest/lib?ref=@evinvest/kitstart-v0.18.0";
|
|
7
7
|
ev.inputs.v_flakes.follows = "v_flakes";
|
|
8
8
|
};
|
|
9
9
|
|
package/template/package.json
CHANGED
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@evinvest/analytics": "^0.4.0",
|
|
22
22
|
"@evinvest/i18n": "^0.9.0",
|
|
23
|
-
"@evinvest/kitstart": "^0.
|
|
23
|
+
"@evinvest/kitstart": "^0.18.0",
|
|
24
24
|
"@evinvest/marketing": "^0.3.0",
|
|
25
|
-
"@evinvest/uikit": "^0.
|
|
25
|
+
"@evinvest/uikit": "^0.27.0",
|
|
26
26
|
"next": "16.3.6",
|
|
27
27
|
"react": "19.3.0",
|
|
28
28
|
"react-dom": "19.3.0",
|