@usergist/sdk-core 0.1.0 → 0.1.2
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/CHANGELOG.md +5 -0
- package/dist/{mobile-H9slSAy8.d.cts → client-DGHJLNJu.d.cts} +1395 -15
- package/dist/{mobile-H9slSAy8.d.ts → client-DGHJLNJu.d.ts} +1395 -15
- package/dist/client.cjs +1235 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +2 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +1170 -0
- package/dist/client.js.map +1 -0
- package/dist/index.cjs +1218 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +880 -17
- package/dist/index.d.ts +880 -17
- package/dist/index.js +1189 -39
- package/dist/index.js.map +1 -1
- package/dist/mobile.cjs +495 -23
- package/dist/mobile.cjs.map +1 -1
- package/dist/mobile.d.cts +2 -1
- package/dist/mobile.d.ts +2 -1
- package/dist/mobile.js +484 -24
- package/dist/mobile.js.map +1 -1
- package/package.json +7 -2
package/dist/index.cjs
CHANGED
|
@@ -27,6 +27,16 @@ function err(code, message, details) {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// src/types/workspace.ts
|
|
31
|
+
function defaultOnboardingMessage(appName) {
|
|
32
|
+
return {
|
|
33
|
+
title: `Welcome to ${appName.trim() || "our app"}`,
|
|
34
|
+
body: "Glad you\u2019re here. Take a look around and make yourself at home.",
|
|
35
|
+
buttonLabel: "Got it",
|
|
36
|
+
format: "modal"
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
30
40
|
// src/types/survey.ts
|
|
31
41
|
var SURVEY_END_SENTINEL = "__end__";
|
|
32
42
|
|
|
@@ -270,8 +280,8 @@ var THEME_PRESETS = [
|
|
|
270
280
|
swatches: ["#8B5CF6", "#EC4899", "#E9D5FF"]
|
|
271
281
|
}
|
|
272
282
|
];
|
|
273
|
-
function getThemePresetById(
|
|
274
|
-
return THEME_PRESETS.find((preset) => preset.id ===
|
|
283
|
+
function getThemePresetById(id2) {
|
|
284
|
+
return THEME_PRESETS.find((preset) => preset.id === id2);
|
|
275
285
|
}
|
|
276
286
|
function defaultThemePreset() {
|
|
277
287
|
return THEME_PRESETS[0];
|
|
@@ -322,7 +332,7 @@ var USER_IDENTIFIED_EVENT_NAME = "$user_identified";
|
|
|
322
332
|
function camelize(value) {
|
|
323
333
|
return value.replace(/_([a-z])/g, (_match, letter) => letter.toUpperCase());
|
|
324
334
|
}
|
|
325
|
-
var ids = (...keys) => Object.fromEntries(keys.map((
|
|
335
|
+
var ids = (...keys) => Object.fromEntries(keys.map((key2) => [key2, [key2, camelize(key2)]]));
|
|
326
336
|
var pushEvents = [
|
|
327
337
|
["$push_sent", "UserGist Push Sent"],
|
|
328
338
|
["$push_delivered", "UserGist Push Delivered"],
|
|
@@ -379,8 +389,8 @@ var CORE_INTEGRATION_EVENTS = [
|
|
|
379
389
|
{ key: "$inapp_dismissed", name: "UserGist In-App Message Dismissed", category: "inapp", subjectRole: "actor", properties: { ...ids("message_id", "dismiss_reason") } },
|
|
380
390
|
{ key: "$inapp_auto_dismissed", name: "UserGist In-App Message Auto-Dismissed", category: "inapp", subjectRole: "actor", properties: { ...ids("message_id", "dismiss_reason") } },
|
|
381
391
|
{ key: "$inapp_cta_clicked", name: "UserGist In-App Message CTA Clicked", category: "inapp", subjectRole: "actor", properties: { ...ids("message_id", "cta_id", "cta_index"), action: ["action", "cta_action"] } },
|
|
382
|
-
...pushEvents.map(([
|
|
383
|
-
key,
|
|
392
|
+
...pushEvents.map(([key2, name]) => ({
|
|
393
|
+
key: key2,
|
|
384
394
|
name,
|
|
385
395
|
category: "push",
|
|
386
396
|
subjectRole: "actor",
|
|
@@ -389,11 +399,11 @@ var CORE_INTEGRATION_EVENTS = [
|
|
|
389
399
|
action_id: ["action_id", "actionId", "action_button", "actionButton"]
|
|
390
400
|
}
|
|
391
401
|
})),
|
|
392
|
-
...requestEvents.map(([
|
|
402
|
+
...requestEvents.map(([key2, name, subjectRole]) => ({ key: key2, name, category: "requests", subjectRole, properties: { ...ids("request_id", "comment_id", "source", "old_status", "new_status", "deleted_by"), usergist_actor_type: ["usergist_actor_type", "actor_type"] } }))
|
|
393
403
|
];
|
|
394
404
|
var CORE_EVENT_BY_KEY = new Map(CORE_INTEGRATION_EVENTS.map((event) => [event.key, event]));
|
|
395
|
-
function getCoreIntegrationEvent(
|
|
396
|
-
return CORE_EVENT_BY_KEY.get(
|
|
405
|
+
function getCoreIntegrationEvent(key2) {
|
|
406
|
+
return CORE_EVENT_BY_KEY.get(key2) ?? null;
|
|
397
407
|
}
|
|
398
408
|
function sanitizeCoreIntegrationProperties(definition, input) {
|
|
399
409
|
if (!input) return {};
|
|
@@ -500,15 +510,15 @@ function evaluateGroup(group, user, now) {
|
|
|
500
510
|
}
|
|
501
511
|
return group.predicates.some((p) => evaluateNode(p, user, now));
|
|
502
512
|
}
|
|
503
|
-
function evaluateNode(
|
|
504
|
-
if ("combinator" in
|
|
505
|
-
switch (
|
|
513
|
+
function evaluateNode(node2, user, now) {
|
|
514
|
+
if ("combinator" in node2) return evaluateGroup(node2, user, now);
|
|
515
|
+
switch (node2.kind) {
|
|
506
516
|
case "user_property":
|
|
507
|
-
return evaluateUserProperty(
|
|
517
|
+
return evaluateUserProperty(node2, user);
|
|
508
518
|
case "event_count":
|
|
509
|
-
return evaluateEventCount(
|
|
519
|
+
return evaluateEventCount(node2, user);
|
|
510
520
|
case "event_occurred":
|
|
511
|
-
return evaluateEventOccurred(
|
|
521
|
+
return evaluateEventOccurred(node2, user, now);
|
|
512
522
|
}
|
|
513
523
|
}
|
|
514
524
|
function evaluateUserProperty(p, user) {
|
|
@@ -662,15 +672,15 @@ function reachableQuestions(flow, startId) {
|
|
|
662
672
|
const visited = /* @__PURE__ */ new Set();
|
|
663
673
|
const stack = [start];
|
|
664
674
|
while (stack.length > 0) {
|
|
665
|
-
const
|
|
666
|
-
if (
|
|
667
|
-
if (visited.has(
|
|
668
|
-
visited.add(
|
|
669
|
-
const outgoing = flow.branches.filter((b) => b.fromQuestionId ===
|
|
675
|
+
const id2 = stack.pop();
|
|
676
|
+
if (id2 === void 0) continue;
|
|
677
|
+
if (visited.has(id2)) continue;
|
|
678
|
+
visited.add(id2);
|
|
679
|
+
const outgoing = flow.branches.filter((b) => b.fromQuestionId === id2);
|
|
670
680
|
for (const b of outgoing) {
|
|
671
681
|
if (b.toQuestionId !== SURVEY_END_SENTINEL) stack.push(b.toQuestionId);
|
|
672
682
|
}
|
|
673
|
-
const idx = flow.questions.findIndex((q) => q.id ===
|
|
683
|
+
const idx = flow.questions.findIndex((q) => q.id === id2);
|
|
674
684
|
if (idx >= 0 && idx < flow.questions.length - 1) {
|
|
675
685
|
const next = flow.questions[idx + 1];
|
|
676
686
|
if (next) stack.push(next.id);
|
|
@@ -709,7 +719,7 @@ function tzOffsetMinutes(at, tz) {
|
|
|
709
719
|
function startCandidate(schedule, now, tz) {
|
|
710
720
|
const localNow = wallClock(now, tz);
|
|
711
721
|
const target = new Date(localNow);
|
|
712
|
-
target.
|
|
722
|
+
target.setUTCHours(schedule.hourLocal, schedule.minuteLocal, 0, 0);
|
|
713
723
|
return localToUtc(target, tz);
|
|
714
724
|
}
|
|
715
725
|
function walkForward(candidate, schedule, now, tz) {
|
|
@@ -727,30 +737,30 @@ function walkForward(candidate, schedule, now, tz) {
|
|
|
727
737
|
function matchesFrequency(local, schedule) {
|
|
728
738
|
if (schedule.frequency === "daily") return true;
|
|
729
739
|
if (schedule.frequency === "weekly") {
|
|
730
|
-
return schedule.weekday === void 0 || local.
|
|
740
|
+
return schedule.weekday === void 0 || local.getUTCDay() === schedule.weekday;
|
|
731
741
|
}
|
|
732
|
-
return schedule.dayOfMonth === void 0 || local.
|
|
742
|
+
return schedule.dayOfMonth === void 0 || local.getUTCDate() === schedule.dayOfMonth;
|
|
733
743
|
}
|
|
734
744
|
function step(cursor, cursorLocal, schedule, tz) {
|
|
735
745
|
if (schedule.frequency === "daily" || schedule.frequency === "weekly") {
|
|
736
746
|
return addDays(cursor, 1);
|
|
737
747
|
}
|
|
738
748
|
const next = new Date(cursorLocal);
|
|
739
|
-
next.
|
|
749
|
+
next.setUTCMonth(next.getUTCMonth() + 1);
|
|
740
750
|
if (schedule.dayOfMonth !== void 0) {
|
|
741
|
-
const lastDay = lastDayOfMonth(next.
|
|
742
|
-
next.
|
|
751
|
+
const lastDay = lastDayOfMonth(next.getUTCFullYear(), next.getUTCMonth());
|
|
752
|
+
next.setUTCDate(Math.min(schedule.dayOfMonth, lastDay));
|
|
743
753
|
}
|
|
744
|
-
next.
|
|
754
|
+
next.setUTCHours(schedule.hourLocal, schedule.minuteLocal, 0, 0);
|
|
745
755
|
return localToUtc(next, tz);
|
|
746
756
|
}
|
|
747
757
|
function addDays(d, days) {
|
|
748
758
|
const next = new Date(d.getTime());
|
|
749
|
-
next.
|
|
759
|
+
next.setUTCDate(next.getUTCDate() + days);
|
|
750
760
|
return next;
|
|
751
761
|
}
|
|
752
762
|
function lastDayOfMonth(year, monthIndex) {
|
|
753
|
-
return new Date(year, monthIndex + 1, 0).
|
|
763
|
+
return new Date(Date.UTC(year, monthIndex + 1, 0)).getUTCDate();
|
|
754
764
|
}
|
|
755
765
|
function wallClock(d, tz) {
|
|
756
766
|
const offsetMin = tzOffsetMinutes(d, tz);
|
|
@@ -778,11 +788,151 @@ function getFormatter(tz) {
|
|
|
778
788
|
return fmt;
|
|
779
789
|
}
|
|
780
790
|
|
|
791
|
+
// src/timezone.ts
|
|
792
|
+
var PARTS_FORMATTER_CACHE = /* @__PURE__ */ new Map();
|
|
793
|
+
function isValidIanaTimeZone(value) {
|
|
794
|
+
if (!value.trim()) return false;
|
|
795
|
+
try {
|
|
796
|
+
new Intl.DateTimeFormat("en-US", { timeZone: value }).format();
|
|
797
|
+
return true;
|
|
798
|
+
} catch {
|
|
799
|
+
return false;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
function zonedDateTimeParts(instant, timeZone) {
|
|
803
|
+
if (!isValidIanaTimeZone(timeZone)) {
|
|
804
|
+
throw new RangeError(`Invalid IANA timezone: ${timeZone}`);
|
|
805
|
+
}
|
|
806
|
+
if (!Number.isFinite(instant.getTime())) {
|
|
807
|
+
throw new RangeError("Invalid date");
|
|
808
|
+
}
|
|
809
|
+
const formatter = getPartsFormatter(timeZone);
|
|
810
|
+
const parts = formatter.formatToParts(instant).reduce(
|
|
811
|
+
(result, part) => {
|
|
812
|
+
if (part.type !== "literal") result[part.type] = part.value;
|
|
813
|
+
return result;
|
|
814
|
+
},
|
|
815
|
+
{}
|
|
816
|
+
);
|
|
817
|
+
const year = Number(parts.year);
|
|
818
|
+
const month = Number(parts.month);
|
|
819
|
+
const day = Number(parts.day);
|
|
820
|
+
const hour = Number(parts.hour);
|
|
821
|
+
const minute = Number(parts.minute);
|
|
822
|
+
return {
|
|
823
|
+
date: `${year}-${pad2(month)}-${pad2(day)}`,
|
|
824
|
+
time: `${pad2(hour)}:${pad2(minute)}`,
|
|
825
|
+
weekday: new Date(Date.UTC(year, month - 1, day)).getUTCDay(),
|
|
826
|
+
dayOfMonth: day
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
function zonedDateTimeToUtc(date, time, timeZone) {
|
|
830
|
+
if (!isValidIanaTimeZone(timeZone)) {
|
|
831
|
+
throw new RangeError(`Invalid IANA timezone: ${timeZone}`);
|
|
832
|
+
}
|
|
833
|
+
const dateMatch = /^(\d{4})-(\d{2})-(\d{2})$/.exec(date);
|
|
834
|
+
const timeMatch = /^(\d{2}):(\d{2})$/.exec(time);
|
|
835
|
+
if (!dateMatch || !timeMatch) throw new RangeError("Invalid local date or time");
|
|
836
|
+
const year = Number(dateMatch[1]);
|
|
837
|
+
const month = Number(dateMatch[2]);
|
|
838
|
+
const day = Number(dateMatch[3]);
|
|
839
|
+
const hour = Number(timeMatch[1]);
|
|
840
|
+
const minute = Number(timeMatch[2]);
|
|
841
|
+
const naive = Date.UTC(year, month - 1, day, hour, minute, 0, 0);
|
|
842
|
+
const calendarCheck = new Date(naive);
|
|
843
|
+
if (calendarCheck.getUTCFullYear() !== year || calendarCheck.getUTCMonth() !== month - 1 || calendarCheck.getUTCDate() !== day || hour > 23 || minute > 59) {
|
|
844
|
+
throw new RangeError("Invalid local date or time");
|
|
845
|
+
}
|
|
846
|
+
const offsets = new Set(
|
|
847
|
+
[-36, -12, 0, 12, 36].map(
|
|
848
|
+
(hours) => timeZoneOffsetMinutes(new Date(naive + hours * 36e5), timeZone)
|
|
849
|
+
)
|
|
850
|
+
);
|
|
851
|
+
const candidates = [...offsets].map((offset) => new Date(naive - offset * 6e4)).filter((candidate2) => {
|
|
852
|
+
const roundTrip = zonedDateTimeParts(candidate2, timeZone);
|
|
853
|
+
return roundTrip.date === date && roundTrip.time === time;
|
|
854
|
+
}).sort((left, right) => left.getTime() - right.getTime());
|
|
855
|
+
const candidate = candidates[0];
|
|
856
|
+
if (!candidate) {
|
|
857
|
+
throw new RangeError("This local time does not exist in the selected timezone");
|
|
858
|
+
}
|
|
859
|
+
return candidate;
|
|
860
|
+
}
|
|
861
|
+
function zonedDateEndToUtc(date, timeZone) {
|
|
862
|
+
const lastMinute = zonedDateTimeToUtc(date, "23:59", timeZone);
|
|
863
|
+
return new Date(lastMinute.getTime() + 59999);
|
|
864
|
+
}
|
|
865
|
+
function timeZoneOffsetMinutes(instant, timeZone) {
|
|
866
|
+
const parts = getPartsFormatter(timeZone).formatToParts(instant).reduce((result, part) => {
|
|
867
|
+
if (part.type !== "literal") result[part.type] = part.value;
|
|
868
|
+
return result;
|
|
869
|
+
}, {});
|
|
870
|
+
const asUtc = Date.UTC(
|
|
871
|
+
Number(parts.year),
|
|
872
|
+
Number(parts.month) - 1,
|
|
873
|
+
Number(parts.day),
|
|
874
|
+
Number(parts.hour),
|
|
875
|
+
Number(parts.minute),
|
|
876
|
+
Number(parts.second)
|
|
877
|
+
);
|
|
878
|
+
return Math.round((asUtc - instant.getTime()) / 6e4);
|
|
879
|
+
}
|
|
880
|
+
function getPartsFormatter(timeZone) {
|
|
881
|
+
const cached = PARTS_FORMATTER_CACHE.get(timeZone);
|
|
882
|
+
if (cached) return cached;
|
|
883
|
+
const formatter = new Intl.DateTimeFormat("en-US", {
|
|
884
|
+
timeZone,
|
|
885
|
+
hourCycle: "h23",
|
|
886
|
+
year: "numeric",
|
|
887
|
+
month: "2-digit",
|
|
888
|
+
day: "2-digit",
|
|
889
|
+
hour: "2-digit",
|
|
890
|
+
minute: "2-digit",
|
|
891
|
+
second: "2-digit"
|
|
892
|
+
});
|
|
893
|
+
PARTS_FORMATTER_CACHE.set(timeZone, formatter);
|
|
894
|
+
return formatter;
|
|
895
|
+
}
|
|
896
|
+
function pad2(value) {
|
|
897
|
+
return String(value).padStart(2, "0");
|
|
898
|
+
}
|
|
899
|
+
|
|
781
900
|
// src/contract/endpoints.ts
|
|
782
901
|
var endpoints = {
|
|
902
|
+
"GET /v1/apps/:appId/search": {},
|
|
903
|
+
"POST /v1/apps/:appId/delivery-diagnostics": {},
|
|
904
|
+
"GET /v1/workspaces/:wid/portal": {},
|
|
905
|
+
"PUT /v1/workspaces/:wid/portal": {},
|
|
906
|
+
"GET /v1/workspaces/:wid/portal/slug-available": {},
|
|
907
|
+
"PUT /v1/workspaces/:wid/portal/apps/:appId": {},
|
|
908
|
+
"POST /v1/workspaces/:wid/portal/publish": {},
|
|
909
|
+
"POST /v1/workspaces/:wid/portal/unpublish": {},
|
|
910
|
+
"GET /v1/workspaces/:wid/portal/preview/:appId": {},
|
|
911
|
+
"PATCH /v1/apps/:appId/requests/portal-visibility": {},
|
|
912
|
+
"GET /v1/portal/:portalSlug": {},
|
|
913
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/requests": {},
|
|
914
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/requests/counts": {},
|
|
915
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/requests/:requestId": {},
|
|
916
|
+
"POST /v1/portal/:portalSlug/auth/start": {},
|
|
917
|
+
"POST /v1/portal/:portalSlug/auth/verify": {},
|
|
918
|
+
"GET /v1/portal/:portalSlug/session": {},
|
|
919
|
+
"DELETE /v1/portal/:portalSlug/session": {},
|
|
920
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/votes": {},
|
|
921
|
+
"POST /v1/portal/:portalSlug/apps/:appSlug/requests": {},
|
|
922
|
+
"PUT /v1/portal/:portalSlug/apps/:appSlug/requests/:requestId/vote": {},
|
|
923
|
+
"POST /v1/sdk/clients": {},
|
|
924
|
+
"POST /v1/sdk/clients/:id/end": {},
|
|
925
|
+
"GET /v1/sdk/clients/:id/instructions": {},
|
|
926
|
+
"POST /v1/sdk/presentations/authorize": {},
|
|
927
|
+
"POST /v1/sdk/presentations/:id/receipt": {},
|
|
783
928
|
"GET /v1/me": {},
|
|
929
|
+
"PATCH /v1/me": {},
|
|
930
|
+
"PATCH /v1/me/onboarding": {},
|
|
931
|
+
"GET /v1/features": {},
|
|
932
|
+
"GET /v1/signup-status": {},
|
|
784
933
|
"GET /v1/workspaces": {},
|
|
785
934
|
"POST /v1/workspaces": {},
|
|
935
|
+
"PATCH /v1/workspaces/:wid": {},
|
|
786
936
|
"GET /v1/workspaces/:wid/members": {},
|
|
787
937
|
"GET /v1/workspaces/:wid/invites": {},
|
|
788
938
|
"POST /v1/workspaces/:wid/invites": {},
|
|
@@ -791,11 +941,18 @@ var endpoints = {
|
|
|
791
941
|
"GET /v1/workspaces/:wid/apps": {},
|
|
792
942
|
"POST /v1/workspaces/:wid/apps": {},
|
|
793
943
|
"GET /v1/workspaces/:wid/api-tokens": {},
|
|
944
|
+
"GET /v1/workspaces/:wid/ai-connections": {},
|
|
945
|
+
"PATCH /v1/workspaces/:wid/ai-connections/:id": {},
|
|
946
|
+
"POST /v1/workspaces/:wid/ai-connections/:id/revoke": {},
|
|
947
|
+
"GET /v1/workspaces/:wid/ai-connections/:id/activity": {},
|
|
948
|
+
"POST /v1/mcp/consent": {},
|
|
794
949
|
"POST /v1/workspaces/:wid/api-tokens": {},
|
|
795
950
|
"DELETE /v1/workspaces/:wid/api-tokens/:tokenId": {},
|
|
796
951
|
"GET /v1/apps/:appId": {},
|
|
797
952
|
"PATCH /v1/apps/:appId": {},
|
|
798
953
|
"DELETE /v1/apps/:appId": {},
|
|
954
|
+
"GET /v1/apps/:appId/onboarding": {},
|
|
955
|
+
"PATCH /v1/apps/:appId/onboarding": {},
|
|
799
956
|
"POST /v1/apps/:appId/sdk/subject-tokens": {},
|
|
800
957
|
// ---------- outbound analytics integrations ----------
|
|
801
958
|
"GET /v1/apps/:appId/integrations": {},
|
|
@@ -852,6 +1009,10 @@ var endpoints = {
|
|
|
852
1009
|
"POST /v1/sdk/ingest": {},
|
|
853
1010
|
"GET /v1/sdk/armed-triggers": {},
|
|
854
1011
|
"POST /v1/sdk/consent": {},
|
|
1012
|
+
"PATCH /v1/apps/:appId/users/properties": {},
|
|
1013
|
+
"POST /v1/sdk/user-properties": {},
|
|
1014
|
+
"GET /v1/apps/:appId/personalization/fields": {},
|
|
1015
|
+
"POST /v1/apps/:appId/personalization/preview": {},
|
|
855
1016
|
"POST /v1/sdk/identify": {},
|
|
856
1017
|
"POST /v1/sdk/responses": {},
|
|
857
1018
|
// GDPR
|
|
@@ -956,6 +1117,9 @@ var endpoints = {
|
|
|
956
1117
|
"GET /v1/apps/:appId/request-settings": {},
|
|
957
1118
|
"PUT /v1/apps/:appId/request-settings": {},
|
|
958
1119
|
"GET /v1/apps/:appId/request-settings/slug-available": {},
|
|
1120
|
+
/** Multipart `file` field; the processed logo URL is saved into branding.logoUrl. */
|
|
1121
|
+
"POST /v1/apps/:appId/request-settings/logo": {},
|
|
1122
|
+
"DELETE /v1/apps/:appId/request-settings/logo": {},
|
|
959
1123
|
"POST /v1/apps/:appId/requests/seed-segments": {},
|
|
960
1124
|
// ---------- feature requests — SDK (write-key) ----------
|
|
961
1125
|
"GET /v1/sdk/requests": {},
|
|
@@ -983,8 +1147,15 @@ var endpoints = {
|
|
|
983
1147
|
"GET /v1/workspaces/:wid/billing/periods": {},
|
|
984
1148
|
// ---------- super admin ----------
|
|
985
1149
|
"GET /v1/admin/session": {},
|
|
1150
|
+
"GET /v1/admin/feature-flags": {},
|
|
1151
|
+
"PATCH /v1/admin/feature-flags/:key": {},
|
|
986
1152
|
"GET /v1/admin/customers": {},
|
|
987
1153
|
"GET /v1/admin/customers/:workspaceId": {},
|
|
1154
|
+
"POST /v1/admin/customers/:workspaceId/permanent-deletion": {},
|
|
1155
|
+
"GET /v1/admin/dashboard-users": {},
|
|
1156
|
+
"POST /v1/admin/dashboard-users/:userId/permanent-deletion": {},
|
|
1157
|
+
"GET /v1/admin/deletion-jobs/:jobId": {},
|
|
1158
|
+
"POST /v1/admin/deletion-jobs/:jobId/retry": {},
|
|
988
1159
|
"POST /v1/admin/customers/:workspaceId/billing-events/:eventId/replay": {},
|
|
989
1160
|
"POST /v1/admin/customers/:workspaceId/grants": {},
|
|
990
1161
|
"POST /v1/admin/customers/:workspaceId/grants/:grantId/extend": {},
|
|
@@ -997,7 +1168,43 @@ var endpoints = {
|
|
|
997
1168
|
// ---------- feature requests — public web roadmap (no auth) ----------
|
|
998
1169
|
"GET /v1/public/roadmap/:slug": {},
|
|
999
1170
|
"GET /v1/public/roadmap/:slug/r/:requestId": {},
|
|
1000
|
-
"GET /v1/public/roadmap/:slug/branding": {}
|
|
1171
|
+
"GET /v1/public/roadmap/:slug/branding": {},
|
|
1172
|
+
"GET /v1/apps/:appId/help/articles": {},
|
|
1173
|
+
"POST /v1/apps/:appId/help/articles": {},
|
|
1174
|
+
"GET /v1/apps/:appId/help/articles/:documentId": {},
|
|
1175
|
+
"PUT /v1/apps/:appId/help/articles/:documentId": {},
|
|
1176
|
+
"POST /v1/apps/:appId/help/articles/:documentId/lifecycle": {},
|
|
1177
|
+
"GET /v1/apps/:appId/changelog": {},
|
|
1178
|
+
"POST /v1/apps/:appId/changelog": {},
|
|
1179
|
+
"GET /v1/apps/:appId/changelog/:documentId": {},
|
|
1180
|
+
"PUT /v1/apps/:appId/changelog/:documentId": {},
|
|
1181
|
+
"POST /v1/apps/:appId/changelog/:documentId/lifecycle": {},
|
|
1182
|
+
"GET /v1/apps/:appId/help/collections": {},
|
|
1183
|
+
"POST /v1/apps/:appId/help/collections": {},
|
|
1184
|
+
"PATCH /v1/apps/:appId/help/collections/:collectionId": {},
|
|
1185
|
+
"POST /v1/apps/:appId/help/collections/:collectionId/position": {},
|
|
1186
|
+
"POST /v1/apps/:appId/help/articles/:documentId/position": {},
|
|
1187
|
+
"GET /v1/apps/:appId/roadmap": {},
|
|
1188
|
+
"POST /v1/apps/:appId/roadmap": {},
|
|
1189
|
+
"GET /v1/apps/:appId/roadmap/:itemId": {},
|
|
1190
|
+
"PUT /v1/apps/:appId/roadmap/:itemId": {},
|
|
1191
|
+
"POST /v1/apps/:appId/roadmap/:itemId/status": {},
|
|
1192
|
+
"POST /v1/apps/:appId/roadmap/:itemId/lifecycle": {},
|
|
1193
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/help/collections": {},
|
|
1194
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/help/collections/:collectionId": {},
|
|
1195
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/help/articles": {},
|
|
1196
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/help/articles/:documentId": {},
|
|
1197
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/changelog": {},
|
|
1198
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/changelog/:documentId": {},
|
|
1199
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/roadmap": {},
|
|
1200
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/roadmap/:itemId": {},
|
|
1201
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/requests/:requestId/changelog": {},
|
|
1202
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/roadmap/:itemId/changelog": {},
|
|
1203
|
+
"GET /v1/apps/:appId/portal-content/link-targets": {},
|
|
1204
|
+
// Binary routes use multipart/stream transports, not the JSON client helper.
|
|
1205
|
+
"POST /v1/apps/:appId/portal-content/assets/:kind/:documentId": {},
|
|
1206
|
+
"GET /v1/apps/:appId/portal-content/assets/:assetId": {},
|
|
1207
|
+
"GET /v1/portal/:portalSlug/apps/:appSlug/assets/:assetId": {}
|
|
1001
1208
|
};
|
|
1002
1209
|
|
|
1003
1210
|
// src/schemas/index.ts
|
|
@@ -1005,24 +1212,74 @@ var schemas_exports = {};
|
|
|
1005
1212
|
__export(schemas_exports, {
|
|
1006
1213
|
acceptWorkspaceInviteSchema: () => acceptWorkspaceInviteSchema,
|
|
1007
1214
|
apiTokenScopeSchema: () => apiTokenScopeSchema,
|
|
1215
|
+
contentActionSchema: () => contentActionSchema,
|
|
1216
|
+
contentBodySchema: () => contentBodySchema,
|
|
1217
|
+
contentKindSchema: () => contentKindSchema,
|
|
1218
|
+
contentLinkQuerySchema: () => contentLinkQuerySchema,
|
|
1219
|
+
contentLinkSchema: () => contentLinkSchema,
|
|
1220
|
+
contentPageQuerySchema: () => contentPageQuerySchema,
|
|
1221
|
+
contentQuerySchema: () => contentQuerySchema,
|
|
1222
|
+
contentStateSchema: () => contentStateSchema,
|
|
1008
1223
|
createApiTokenSchema: () => createApiTokenSchema,
|
|
1009
1224
|
createAppSchema: () => createAppSchema,
|
|
1225
|
+
createCollectionSchema: () => createCollectionSchema,
|
|
1226
|
+
createDocumentSchema: () => createDocumentSchema,
|
|
1227
|
+
createRoadmapSchema: () => createRoadmapSchema,
|
|
1010
1228
|
createWorkspaceSchema: () => createWorkspaceSchema,
|
|
1011
1229
|
createWriteKeySchema: () => createWriteKeySchema,
|
|
1230
|
+
deferCurrentUserOnboardingSchema: () => deferCurrentUserOnboardingSchema,
|
|
1231
|
+
deliveryPlatformsSchema: () => deliveryPlatformsSchema,
|
|
1232
|
+
documentDraftSchema: () => documentDraftSchema,
|
|
1012
1233
|
emailSchema: () => emailSchema,
|
|
1013
1234
|
inviteMemberSchema: () => inviteMemberSchema,
|
|
1014
1235
|
isoDateTimeSchema: () => isoDateTimeSchema,
|
|
1015
1236
|
loginMagicLinkConsumeRequestSchema: () => loginMagicLinkConsumeRequestSchema,
|
|
1016
1237
|
loginMagicLinkRequestSchema: () => loginMagicLinkRequestSchema,
|
|
1017
1238
|
loginPasswordRequestSchema: () => loginPasswordRequestSchema,
|
|
1239
|
+
mcpCapabilitySchema: () => mcpCapabilitySchema,
|
|
1240
|
+
mcpConsentSchema: () => mcpConsentSchema,
|
|
1241
|
+
mcpGrantSchema: () => mcpGrantSchema,
|
|
1242
|
+
mcpPageSchema: () => mcpPageSchema,
|
|
1243
|
+
mcpSearchSchema: () => mcpSearchSchema,
|
|
1244
|
+
mcpUpdateConnectionSchema: () => mcpUpdateConnectionSchema,
|
|
1245
|
+
moveRoadmapSchema: () => moveRoadmapSchema,
|
|
1246
|
+
onboardingGoalSchema: () => onboardingGoalSchema,
|
|
1247
|
+
onboardingPushChoiceSchema: () => onboardingPushChoiceSchema,
|
|
1248
|
+
onboardingStatusSchema: () => onboardingStatusSchema,
|
|
1249
|
+
onboardingStepSchema: () => onboardingStepSchema,
|
|
1018
1250
|
passwordSchema: () => passwordSchema,
|
|
1019
1251
|
platformSchema: () => platformSchema,
|
|
1252
|
+
portalAssetUploadKeySchema: () => portalAssetUploadKeySchema,
|
|
1253
|
+
portalAuthStartSchema: () => portalAuthStartSchema,
|
|
1254
|
+
portalAuthVerifySchema: () => portalAuthVerifySchema,
|
|
1255
|
+
portalEmailSchema: () => portalEmailSchema,
|
|
1256
|
+
portalRequestQuerySchema: () => portalRequestQuerySchema,
|
|
1257
|
+
portalSlugSchema: () => portalSlugSchema,
|
|
1258
|
+
portalSubmissionSchema: () => portalSubmissionSchema,
|
|
1259
|
+
portalVisibilitySchema: () => portalVisibilitySchema,
|
|
1260
|
+
portalVoteSchema: () => portalVoteSchema,
|
|
1261
|
+
reorderContentSchema: () => reorderContentSchema,
|
|
1262
|
+
roadmapQuerySchema: () => roadmapQuerySchema,
|
|
1263
|
+
roadmapStatusSchema: () => roadmapStatusSchema,
|
|
1020
1264
|
rotateWriteKeySchema: () => rotateWriteKeySchema,
|
|
1265
|
+
saveDocumentSchema: () => saveDocumentSchema,
|
|
1266
|
+
saveRoadmapSchema: () => saveRoadmapSchema,
|
|
1021
1267
|
signupRequestSchema: () => signupRequestSchema,
|
|
1022
1268
|
slugSchema: () => slugSchema,
|
|
1269
|
+
subjectRefSchema: () => subjectRefSchema,
|
|
1023
1270
|
updateAppSchema: () => updateAppSchema,
|
|
1271
|
+
updateCollectionSchema: () => updateCollectionSchema,
|
|
1272
|
+
updateCurrentUserSchema: () => updateCurrentUserSchema,
|
|
1273
|
+
updateOnboardingSchema: () => updateOnboardingSchema,
|
|
1274
|
+
updatePortalAppSchema: () => updatePortalAppSchema,
|
|
1275
|
+
updatePortalSchema: () => updatePortalSchema,
|
|
1276
|
+
updateWorkspaceSchema: () => updateWorkspaceSchema,
|
|
1024
1277
|
uuidSchema: () => uuidSchema,
|
|
1278
|
+
webAppConfigSchema: () => webAppConfigSchema,
|
|
1279
|
+
webOriginSchema: () => webOriginSchema,
|
|
1280
|
+
webPresentationSchema: () => webPresentationSchema,
|
|
1025
1281
|
workspaceRoleSchema: () => workspaceRoleSchema,
|
|
1282
|
+
workspaceTimezoneSchema: () => workspaceTimezoneSchema,
|
|
1026
1283
|
writeKeyEnvironmentSchema: () => writeKeyEnvironmentSchema
|
|
1027
1284
|
});
|
|
1028
1285
|
var slugSchema = zod.z.string().min(1).max(64).regex(/^[a-z0-9-]+$/, "Must be lowercase, digits, and dashes only");
|
|
@@ -1049,21 +1306,199 @@ var loginMagicLinkRequestSchema = zod.z.object({
|
|
|
1049
1306
|
var loginMagicLinkConsumeRequestSchema = zod.z.object({
|
|
1050
1307
|
token: zod.z.string().min(16).max(512)
|
|
1051
1308
|
});
|
|
1052
|
-
var
|
|
1053
|
-
|
|
1054
|
-
|
|
1309
|
+
var updateCurrentUserSchema = zod.z.object({
|
|
1310
|
+
name: zod.z.string().trim().min(1).max(120).optional()
|
|
1311
|
+
}).strict().refine((value) => Object.keys(value).length > 0, {
|
|
1312
|
+
message: "At least one field is required"
|
|
1313
|
+
});
|
|
1314
|
+
var deliveryPlatformsSchema = zod.z.array(zod.z.enum(["ios", "android", "web"])).min(1).max(3).transform((values) => [...new Set(values)]);
|
|
1315
|
+
var webPresentationSchema = zod.z.object({
|
|
1316
|
+
layout: zod.z.enum(["modal", "card", "panel"]).optional(),
|
|
1317
|
+
size: zod.z.enum(["compact", "standard", "wide"]).optional(),
|
|
1318
|
+
position: zod.z.enum(["left", "right"]).optional(),
|
|
1319
|
+
backdrop: zod.z.boolean().optional()
|
|
1320
|
+
}).strict();
|
|
1321
|
+
var webOriginSchema = zod.z.string().max(2048).refine((value) => {
|
|
1322
|
+
try {
|
|
1323
|
+
const url = new URL(value);
|
|
1324
|
+
return url.origin === value && !url.username && !url.password && (url.protocol === "https:" || url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname));
|
|
1325
|
+
} catch {
|
|
1326
|
+
return false;
|
|
1327
|
+
}
|
|
1328
|
+
}, "Use an exact HTTPS origin, or an HTTP localhost origin for development");
|
|
1329
|
+
var webAppConfigSchema = zod.z.object({
|
|
1330
|
+
allowedOrigins: zod.z.array(webOriginSchema).max(30).transform((values) => [...new Set(values)])
|
|
1331
|
+
}).strict();
|
|
1332
|
+
|
|
1333
|
+
// src/types/portal.ts
|
|
1334
|
+
var PORTAL_RESERVED_SLUGS = [
|
|
1335
|
+
"www",
|
|
1336
|
+
"app",
|
|
1337
|
+
"api",
|
|
1338
|
+
"admin",
|
|
1339
|
+
"auth",
|
|
1340
|
+
"portal",
|
|
1341
|
+
"docs",
|
|
1342
|
+
"status",
|
|
1343
|
+
"mail",
|
|
1344
|
+
"support",
|
|
1345
|
+
"login",
|
|
1346
|
+
"logout",
|
|
1347
|
+
"signup",
|
|
1348
|
+
"billing",
|
|
1349
|
+
"dashboard",
|
|
1350
|
+
"cdn",
|
|
1351
|
+
"assets",
|
|
1352
|
+
"static",
|
|
1353
|
+
"smtp",
|
|
1354
|
+
"ftp",
|
|
1355
|
+
"help",
|
|
1356
|
+
"account",
|
|
1357
|
+
"accounts",
|
|
1358
|
+
"developer"
|
|
1359
|
+
];
|
|
1360
|
+
var PORTAL_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{1,46})[a-z0-9]$/;
|
|
1361
|
+
function validPortalSlug(slug) {
|
|
1362
|
+
return PORTAL_SLUG_PATTERN.test(slug) && !PORTAL_RESERVED_SLUGS.includes(slug);
|
|
1363
|
+
}
|
|
1364
|
+
function suggestPortalSlug(name) {
|
|
1365
|
+
const value = name.toLowerCase().normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 48).replace(/-$/, "");
|
|
1366
|
+
return validPortalSlug(value) ? value : value.length >= 3 ? `${value.slice(0, 40)}-team` : "";
|
|
1367
|
+
}
|
|
1368
|
+
function buildPortalUrl(slug, baseDomain = "usergist.com", appSlug) {
|
|
1369
|
+
if (!validPortalSlug(slug) || !/^[a-z0-9.-]+$/i.test(baseDomain)) throw new Error("Invalid portal address");
|
|
1370
|
+
const base = `https://${slug}.${baseDomain}`;
|
|
1371
|
+
return appSlug ? `${base}/${encodeURIComponent(appSlug)}/requests` : base;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
// src/schemas/portal.ts
|
|
1375
|
+
var portalSlugSchema = zod.z.string().refine(
|
|
1376
|
+
validPortalSlug,
|
|
1377
|
+
"Use 3\u201348 lowercase letters, numbers, or interior hyphens. This name must not be reserved."
|
|
1378
|
+
);
|
|
1379
|
+
var updatePortalSchema = zod.z.object({
|
|
1380
|
+
displayName: zod.z.string().trim().min(1).max(100).optional(),
|
|
1381
|
+
slug: portalSlugSchema.optional(),
|
|
1382
|
+
setupDismissed: zod.z.boolean().optional()
|
|
1383
|
+
}).strict();
|
|
1384
|
+
var updatePortalAppSchema = zod.z.object({ slug: portalSlugSchema, enabled: zod.z.boolean() }).strict();
|
|
1385
|
+
var portalVisibilitySchema = zod.z.object({ ids: zod.z.array(zod.z.string().uuid()).min(1).max(100), visible: zod.z.boolean() }).strict();
|
|
1386
|
+
var portalEmailSchema = zod.z.string().trim().email().max(254).transform((value) => value.toLowerCase());
|
|
1387
|
+
var portalAuthStartSchema = zod.z.object({ email: portalEmailSchema }).strict();
|
|
1388
|
+
var portalAuthVerifySchema = zod.z.object({ email: portalEmailSchema, code: zod.z.string().regex(/^\d{6}$/) }).strict();
|
|
1389
|
+
var portalSubmissionSchema = zod.z.object({
|
|
1390
|
+
title: zod.z.string().trim().min(1).max(120),
|
|
1391
|
+
description: zod.z.string().trim().min(1).max(1500),
|
|
1392
|
+
idempotencyKey: zod.z.string().uuid(),
|
|
1393
|
+
feedbackConsent: zod.z.literal(true)
|
|
1394
|
+
}).strict();
|
|
1395
|
+
var portalVoteSchema = zod.z.object({ vote: zod.z.boolean(), feedbackConsent: zod.z.literal(true) }).strict();
|
|
1396
|
+
var portalRequestQuerySchema = zod.z.object({
|
|
1397
|
+
q: zod.z.string().trim().max(200).optional(),
|
|
1398
|
+
status: zod.z.enum(["under_review", "planned", "in_progress", "shipped", "declined"]).optional(),
|
|
1399
|
+
sort: zod.z.enum(["top", "newest", "status_changed"]).default("top"),
|
|
1400
|
+
page: zod.z.coerce.number().int().min(1).max(1e5).default(1),
|
|
1401
|
+
limit: zod.z.coerce.number().int().min(1).max(100).default(20)
|
|
1402
|
+
}).strict();
|
|
1403
|
+
|
|
1404
|
+
// src/schemas/apps.ts
|
|
1405
|
+
var workspaceTimezoneSchema = zod.z.string().trim().min(1).max(64).refine(isValidIanaTimeZone, "Enter a valid IANA timezone");
|
|
1406
|
+
var platformSchema = zod.z.enum([
|
|
1407
|
+
"ios",
|
|
1408
|
+
"android",
|
|
1409
|
+
"react-native",
|
|
1410
|
+
"expo",
|
|
1411
|
+
"flutter",
|
|
1412
|
+
"web"
|
|
1413
|
+
]);
|
|
1414
|
+
var writeKeyEnvironmentSchema = zod.z.enum([
|
|
1415
|
+
"production",
|
|
1416
|
+
"staging",
|
|
1417
|
+
"development"
|
|
1418
|
+
]);
|
|
1419
|
+
var onboardingGoalSchema = zod.z.enum([
|
|
1420
|
+
"feedback",
|
|
1421
|
+
"survey",
|
|
1422
|
+
"inapp",
|
|
1423
|
+
"push",
|
|
1424
|
+
"requests"
|
|
1425
|
+
]);
|
|
1426
|
+
var onboardingStatusSchema = zod.z.enum([
|
|
1427
|
+
"in_progress",
|
|
1428
|
+
"deferred",
|
|
1429
|
+
"completed"
|
|
1430
|
+
]);
|
|
1431
|
+
var onboardingStepSchema = zod.z.enum([
|
|
1432
|
+
"connect",
|
|
1433
|
+
"verify",
|
|
1434
|
+
"experience",
|
|
1435
|
+
"push",
|
|
1436
|
+
"launch"
|
|
1437
|
+
]);
|
|
1438
|
+
var onboardingPushChoiceSchema = zod.z.enum([
|
|
1439
|
+
"pending",
|
|
1440
|
+
"configured",
|
|
1441
|
+
"skipped"
|
|
1442
|
+
]);
|
|
1443
|
+
var apiTokenScopeSchema = zod.z.enum([
|
|
1444
|
+
"sdk:subjects",
|
|
1445
|
+
"push.transactional",
|
|
1446
|
+
"users.properties.write"
|
|
1447
|
+
]);
|
|
1055
1448
|
var createAppSchema = zod.z.object({
|
|
1056
1449
|
name: zod.z.string().min(1).max(120),
|
|
1057
1450
|
slug: slugSchema.optional(),
|
|
1058
1451
|
platforms: zod.z.array(platformSchema).min(1).max(8),
|
|
1059
|
-
environment: writeKeyEnvironmentSchema.default("production")
|
|
1452
|
+
environment: writeKeyEnvironmentSchema.default("production"),
|
|
1453
|
+
onboardingGoal: onboardingGoalSchema.optional(),
|
|
1454
|
+
setupMode: zod.z.enum(["sdk", "portal"]).optional(),
|
|
1455
|
+
portal: zod.z.object({
|
|
1456
|
+
appSlug: portalSlugSchema,
|
|
1457
|
+
company: zod.z.object({
|
|
1458
|
+
displayName: zod.z.string().trim().min(1).max(100),
|
|
1459
|
+
slug: portalSlugSchema
|
|
1460
|
+
}).strict().optional()
|
|
1461
|
+
}).strict().optional(),
|
|
1462
|
+
webConfig: webAppConfigSchema.optional()
|
|
1463
|
+
});
|
|
1464
|
+
var updateOnboardingSchema = zod.z.object({
|
|
1465
|
+
action: zod.z.enum([
|
|
1466
|
+
"resume",
|
|
1467
|
+
"defer",
|
|
1468
|
+
"create_first_inapp",
|
|
1469
|
+
"first_inapp_completed",
|
|
1470
|
+
"create_first_feedback",
|
|
1471
|
+
"first_feedback_completed",
|
|
1472
|
+
"push_configured",
|
|
1473
|
+
"push_skipped",
|
|
1474
|
+
"complete"
|
|
1475
|
+
]).optional(),
|
|
1476
|
+
step: onboardingStepSchema.optional(),
|
|
1477
|
+
question: zod.z.string().trim().min(1).max(500).optional(),
|
|
1478
|
+
message: zod.z.object({
|
|
1479
|
+
title: zod.z.string().trim().min(1).max(200),
|
|
1480
|
+
body: zod.z.string().trim().min(1).max(500),
|
|
1481
|
+
buttonLabel: zod.z.string().trim().min(1).max(40),
|
|
1482
|
+
format: zod.z.enum(["modal", "slideup"])
|
|
1483
|
+
}).strict().optional()
|
|
1484
|
+
}).refine((value) => Boolean(value.action || value.step), {
|
|
1485
|
+
message: "Provide an onboarding action or step"
|
|
1486
|
+
}).refine(
|
|
1487
|
+
(value) => value.action !== "create_first_feedback" || Boolean(value.question),
|
|
1488
|
+
{ message: "Provide a question for the first feedback experience" }
|
|
1489
|
+
);
|
|
1490
|
+
var deferCurrentUserOnboardingSchema = zod.z.object({
|
|
1491
|
+
action: zod.z.literal("defer")
|
|
1060
1492
|
});
|
|
1061
1493
|
var updateAppSchema = zod.z.object({
|
|
1062
1494
|
name: zod.z.string().min(1).max(120).optional(),
|
|
1063
1495
|
platforms: zod.z.array(platformSchema).min(1).max(8).optional(),
|
|
1064
1496
|
piiAllowList: zod.z.array(zod.z.string().min(1).max(120)).max(128).optional(),
|
|
1065
|
-
lifecycleEventsEnabled: zod.z.boolean().optional()
|
|
1066
|
-
|
|
1497
|
+
lifecycleEventsEnabled: zod.z.boolean().optional(),
|
|
1498
|
+
webConfig: webAppConfigSchema.optional()
|
|
1499
|
+
}).refine((v) => Object.keys(v).length > 0, {
|
|
1500
|
+
message: "At least one field is required"
|
|
1501
|
+
});
|
|
1067
1502
|
var createWriteKeySchema = zod.z.object({
|
|
1068
1503
|
label: zod.z.string().min(1).max(120).optional(),
|
|
1069
1504
|
environment: writeKeyEnvironmentSchema.default("production")
|
|
@@ -1078,8 +1513,15 @@ var createApiTokenSchema = zod.z.object({
|
|
|
1078
1513
|
expiresInDays: zod.z.number().int().min(1).max(365).default(90)
|
|
1079
1514
|
});
|
|
1080
1515
|
var createWorkspaceSchema = zod.z.object({
|
|
1081
|
-
name: zod.z.string().min(1).max(120),
|
|
1082
|
-
slug: slugSchema.optional()
|
|
1516
|
+
name: zod.z.string().trim().min(1).max(120),
|
|
1517
|
+
slug: slugSchema.optional(),
|
|
1518
|
+
timezone: workspaceTimezoneSchema.default("UTC")
|
|
1519
|
+
});
|
|
1520
|
+
var updateWorkspaceSchema = zod.z.object({
|
|
1521
|
+
name: zod.z.string().trim().min(1).max(120).optional(),
|
|
1522
|
+
timezone: workspaceTimezoneSchema.optional()
|
|
1523
|
+
}).strict().refine((value) => Object.keys(value).length > 0, {
|
|
1524
|
+
message: "At least one field is required"
|
|
1083
1525
|
});
|
|
1084
1526
|
var inviteMemberSchema = zod.z.object({
|
|
1085
1527
|
email: emailSchema,
|
|
@@ -1089,6 +1531,714 @@ var acceptWorkspaceInviteSchema = zod.z.object({
|
|
|
1089
1531
|
token: zod.z.string().regex(/^[a-f0-9]{64}$/i, "Invalid invitation token")
|
|
1090
1532
|
});
|
|
1091
1533
|
|
|
1534
|
+
// src/types/portal-content.ts
|
|
1535
|
+
function emptyDocumentDraft() {
|
|
1536
|
+
return {
|
|
1537
|
+
title: "",
|
|
1538
|
+
summary: "",
|
|
1539
|
+
body: { type: "doc", content: [{ type: "paragraph" }] },
|
|
1540
|
+
collectionId: null,
|
|
1541
|
+
category: "improved",
|
|
1542
|
+
releaseDate: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
1543
|
+
version: "",
|
|
1544
|
+
links: []
|
|
1545
|
+
};
|
|
1546
|
+
}
|
|
1547
|
+
function contentText(node2) {
|
|
1548
|
+
return node2.text ?? (node2.content ?? []).map(contentText).join(node2.type === "paragraph" || node2.type === "heading" ? "" : "\n");
|
|
1549
|
+
}
|
|
1550
|
+
function contentAssetIds(node2) {
|
|
1551
|
+
return [
|
|
1552
|
+
.../* @__PURE__ */ new Set([
|
|
1553
|
+
...node2.type === "image" && node2.attrs?.assetId ? [node2.attrs.assetId] : [],
|
|
1554
|
+
...(node2.content ?? []).flatMap(contentAssetIds)
|
|
1555
|
+
])
|
|
1556
|
+
];
|
|
1557
|
+
}
|
|
1558
|
+
function contentSlug(title) {
|
|
1559
|
+
return title.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 96).replace(/-$/, "") || "article";
|
|
1560
|
+
}
|
|
1561
|
+
function safeContentHref(href) {
|
|
1562
|
+
return /^(https?:\/\/|mailto:|\/[^/]|#[a-zA-Z0-9_-])/.test(href) && !/[\u0000-\u0020\\]/.test(href);
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
// src/schemas/portal-content.ts
|
|
1566
|
+
var uuid = zod.z.string().uuid();
|
|
1567
|
+
var contentKindSchema = zod.z.enum(["article", "changelog"]);
|
|
1568
|
+
var contentStateSchema = zod.z.enum(["draft", "published", "archived"]);
|
|
1569
|
+
var roadmapStatusSchema = zod.z.enum(["planned", "in_progress", "shipped"]);
|
|
1570
|
+
var contentLinkSchema = zod.z.object({ kind: zod.z.enum(["request", "roadmap"]), id: uuid }).strict();
|
|
1571
|
+
var mark = zod.z.object({
|
|
1572
|
+
type: zod.z.enum(["bold", "italic", "code", "link"]),
|
|
1573
|
+
attrs: zod.z.object({ href: zod.z.string().max(2048).refine(safeContentHref, "Use a safe link URL") }).strict().optional()
|
|
1574
|
+
}).strict().refine((m) => m.type === "link" ? Boolean(m.attrs) : !m.attrs);
|
|
1575
|
+
var node = zod.z.lazy(
|
|
1576
|
+
() => zod.z.object({
|
|
1577
|
+
type: zod.z.enum([
|
|
1578
|
+
"doc",
|
|
1579
|
+
"paragraph",
|
|
1580
|
+
"heading",
|
|
1581
|
+
"text",
|
|
1582
|
+
"bulletList",
|
|
1583
|
+
"orderedList",
|
|
1584
|
+
"listItem",
|
|
1585
|
+
"blockquote",
|
|
1586
|
+
"codeBlock",
|
|
1587
|
+
"hardBreak",
|
|
1588
|
+
"image"
|
|
1589
|
+
]),
|
|
1590
|
+
text: zod.z.string().max(1e5).optional(),
|
|
1591
|
+
attrs: zod.z.object({
|
|
1592
|
+
level: zod.z.number().int().min(2).max(3).optional(),
|
|
1593
|
+
start: zod.z.number().int().min(1).max(1e4).optional(),
|
|
1594
|
+
language: zod.z.string().max(40).nullable().optional(),
|
|
1595
|
+
assetId: uuid.optional(),
|
|
1596
|
+
alt: zod.z.string().max(500).optional()
|
|
1597
|
+
}).strict().optional(),
|
|
1598
|
+
marks: zod.z.array(mark).max(4).optional(),
|
|
1599
|
+
content: zod.z.array(node).max(5e3).optional()
|
|
1600
|
+
}).strict()
|
|
1601
|
+
);
|
|
1602
|
+
var contentBodySchema = zod.z.unknown().superRefine((value, ctx) => {
|
|
1603
|
+
let count = 0, invalid = false;
|
|
1604
|
+
const walk = (v, depth) => {
|
|
1605
|
+
if (depth > 20 || ++count > 5e3) {
|
|
1606
|
+
invalid = true;
|
|
1607
|
+
return;
|
|
1608
|
+
}
|
|
1609
|
+
if (v && typeof v === "object" && "content" in v && Array.isArray(v.content))
|
|
1610
|
+
for (const child of v.content) {
|
|
1611
|
+
if (invalid) break;
|
|
1612
|
+
walk(child, depth + 1);
|
|
1613
|
+
}
|
|
1614
|
+
};
|
|
1615
|
+
walk(value, 0);
|
|
1616
|
+
if (invalid)
|
|
1617
|
+
ctx.addIssue({
|
|
1618
|
+
code: zod.z.ZodIssueCode.custom,
|
|
1619
|
+
message: "Document is too deeply nested or contains too many blocks"
|
|
1620
|
+
});
|
|
1621
|
+
}).pipe(node).superRefine((value, ctx) => {
|
|
1622
|
+
if (value.type !== "doc" || contentText(value).length > 1e5)
|
|
1623
|
+
ctx.addIssue({
|
|
1624
|
+
code: zod.z.ZodIssueCode.custom,
|
|
1625
|
+
message: "Invalid document or body exceeds 100,000 characters"
|
|
1626
|
+
});
|
|
1627
|
+
const walk = (v, root = false) => {
|
|
1628
|
+
const blocks = ["paragraph", "heading", "bulletList", "orderedList", "blockquote", "codeBlock", "image"];
|
|
1629
|
+
const children = v.content ?? [];
|
|
1630
|
+
const allowed = v.type === "doc" || v.type === "blockquote" ? blocks : v.type === "listItem" ? blocks.filter((t) => t !== "heading") : v.type === "bulletList" || v.type === "orderedList" ? ["listItem"] : v.type === "paragraph" || v.type === "heading" ? ["text", "hardBreak"] : v.type === "codeBlock" ? ["text"] : [];
|
|
1631
|
+
const attrs = Object.keys(v.attrs ?? {});
|
|
1632
|
+
const allowedAttrs = v.type === "heading" ? ["level"] : v.type === "orderedList" ? ["start"] : v.type === "codeBlock" ? ["language"] : v.type === "image" ? ["assetId", "alt"] : [];
|
|
1633
|
+
if (!root && v.type === "doc" || v.type === "text" && (!v.text || v.content) || v.type !== "text" && (v.text !== void 0 || Boolean(v.marks?.length)) || v.type === "image" && (!v.attrs?.assetId || v.content) || v.type === "heading" && !v.attrs?.level || attrs.some((a) => !allowedAttrs.includes(a)) || children.some((c) => !allowed.includes(c.type)) || v.type === "listItem" && children[0]?.type !== "paragraph" || ["bulletList", "orderedList", "blockquote", "doc"].includes(v.type) && !children.length || v.type === "codeBlock" && children.some((c) => c.marks?.length))
|
|
1634
|
+
ctx.addIssue({ code: zod.z.ZodIssueCode.custom, message: "Invalid content block" });
|
|
1635
|
+
v.content?.forEach((c) => walk(c));
|
|
1636
|
+
};
|
|
1637
|
+
walk(value, true);
|
|
1638
|
+
});
|
|
1639
|
+
var documentDraftSchema = zod.z.object({
|
|
1640
|
+
title: zod.z.string().trim().max(160),
|
|
1641
|
+
summary: zod.z.string().max(280),
|
|
1642
|
+
body: contentBodySchema,
|
|
1643
|
+
collectionId: uuid.nullable(),
|
|
1644
|
+
category: zod.z.enum(["new", "improved", "fixed"]),
|
|
1645
|
+
releaseDate: zod.z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(
|
|
1646
|
+
(v) => !Number.isNaN(Date.parse(v)) && new Date(v).toISOString().slice(0, 10) === v,
|
|
1647
|
+
"Choose a valid date"
|
|
1648
|
+
),
|
|
1649
|
+
version: zod.z.string().max(40),
|
|
1650
|
+
links: zod.z.array(contentLinkSchema).max(100)
|
|
1651
|
+
}).strict();
|
|
1652
|
+
var createDocumentSchema = zod.z.object({
|
|
1653
|
+
idempotencyKey: uuid,
|
|
1654
|
+
title: zod.z.string().trim().max(160).optional(),
|
|
1655
|
+
collectionId: uuid.nullable().optional(),
|
|
1656
|
+
links: zod.z.array(contentLinkSchema).max(100).optional()
|
|
1657
|
+
}).strict();
|
|
1658
|
+
var saveDocumentSchema = zod.z.object({ revision: zod.z.number().int().positive(), draft: documentDraftSchema }).strict();
|
|
1659
|
+
var contentActionSchema = zod.z.object({
|
|
1660
|
+
revision: zod.z.number().int().positive(),
|
|
1661
|
+
action: zod.z.enum(["publish", "unpublish", "archive", "restore"])
|
|
1662
|
+
}).strict();
|
|
1663
|
+
var contentQuerySchema = zod.z.object({
|
|
1664
|
+
q: zod.z.string().trim().max(200).optional(),
|
|
1665
|
+
state: contentStateSchema.optional(),
|
|
1666
|
+
collectionId: uuid.optional(),
|
|
1667
|
+
category: zod.z.enum(["new", "improved", "fixed"]).optional(),
|
|
1668
|
+
cursor: zod.z.string().max(2e3).optional(),
|
|
1669
|
+
limit: zod.z.coerce.number().int().min(1).max(50).default(20)
|
|
1670
|
+
}).strict();
|
|
1671
|
+
var createCollectionSchema = zod.z.object({
|
|
1672
|
+
title: zod.z.string().trim().min(1).max(160),
|
|
1673
|
+
description: zod.z.string().max(280),
|
|
1674
|
+
idempotencyKey: uuid
|
|
1675
|
+
}).strict();
|
|
1676
|
+
var contentPageQuerySchema = contentQuerySchema.pick({ cursor: true, limit: true });
|
|
1677
|
+
var portalAssetUploadKeySchema = uuid;
|
|
1678
|
+
var updateCollectionSchema = zod.z.object({
|
|
1679
|
+
revision: zod.z.number().int().positive(),
|
|
1680
|
+
title: zod.z.string().trim().min(1).max(160).optional(),
|
|
1681
|
+
description: zod.z.string().max(280).optional(),
|
|
1682
|
+
archived: zod.z.boolean().optional()
|
|
1683
|
+
}).strict();
|
|
1684
|
+
var reorderContentSchema = zod.z.object({ revision: zod.z.number().int().positive(), direction: zod.z.enum(["up", "down"]) }).strict();
|
|
1685
|
+
var roadmapQuerySchema = zod.z.object({
|
|
1686
|
+
status: roadmapStatusSchema,
|
|
1687
|
+
cursor: zod.z.string().max(2e3).optional(),
|
|
1688
|
+
limit: zod.z.coerce.number().int().min(1).max(50).default(20),
|
|
1689
|
+
archived: zod.z.enum(["true", "false"]).transform((v) => v === "true").optional()
|
|
1690
|
+
}).strict();
|
|
1691
|
+
var roadmapFields = {
|
|
1692
|
+
title: zod.z.string().trim().min(1).max(120),
|
|
1693
|
+
description: zod.z.string().max(1500),
|
|
1694
|
+
requestIds: zod.z.array(uuid).max(100).refine((v) => new Set(v).size === v.length)
|
|
1695
|
+
};
|
|
1696
|
+
var createRoadmapSchema = zod.z.object({ ...roadmapFields, idempotencyKey: uuid, status: roadmapStatusSchema }).strict();
|
|
1697
|
+
var saveRoadmapSchema = zod.z.object({ ...roadmapFields, revision: zod.z.number().int().positive() }).strict();
|
|
1698
|
+
var moveRoadmapSchema = zod.z.object({
|
|
1699
|
+
revision: zod.z.number().int().positive(),
|
|
1700
|
+
status: roadmapStatusSchema,
|
|
1701
|
+
requests: zod.z.array(zod.z.object({ id: uuid, updatedAt: zod.z.string().datetime() }).strict()).max(100).refine((v) => new Set(v.map((r) => r.id)).size === v.length)
|
|
1702
|
+
}).strict();
|
|
1703
|
+
var contentLinkQuerySchema = zod.z.object({
|
|
1704
|
+
kind: zod.z.enum(["request", "roadmap"]),
|
|
1705
|
+
q: zod.z.string().trim().max(200).optional(),
|
|
1706
|
+
cursor: zod.z.string().max(2e3).optional(),
|
|
1707
|
+
limit: zod.z.coerce.number().int().min(1).max(100).default(20),
|
|
1708
|
+
ids: zod.z.string().max(4e3).optional().refine((v) => !v || v.split(",").every((id2) => uuid.safeParse(id2).success), "Invalid linked IDs")
|
|
1709
|
+
}).strict();
|
|
1710
|
+
|
|
1711
|
+
// src/types/mcp.ts
|
|
1712
|
+
var MCP_DOMAINS = ["context", "users", "analytics", "requests", "roadmap", "content", "experiences", "segments", "brand", "portal", "push", "integrations", "sdk", "apps"];
|
|
1713
|
+
var MCP_ACCESS_MODES = ["read_only", "approve_changes", "automatic"];
|
|
1714
|
+
var MCP_CAPABILITIES = [
|
|
1715
|
+
"context:read",
|
|
1716
|
+
"users:read",
|
|
1717
|
+
"analytics:read",
|
|
1718
|
+
"requests:read",
|
|
1719
|
+
"requests:manage",
|
|
1720
|
+
"requests:publish",
|
|
1721
|
+
"roadmap:read",
|
|
1722
|
+
"roadmap:manage",
|
|
1723
|
+
"roadmap:publish",
|
|
1724
|
+
"content:read",
|
|
1725
|
+
"content:manage",
|
|
1726
|
+
"content:publish",
|
|
1727
|
+
"experiences:read",
|
|
1728
|
+
"experiences:manage",
|
|
1729
|
+
"experiences:publish",
|
|
1730
|
+
"segments:read",
|
|
1731
|
+
"segments:manage",
|
|
1732
|
+
"brand:read",
|
|
1733
|
+
"brand:manage",
|
|
1734
|
+
"portal:read",
|
|
1735
|
+
"portal:manage",
|
|
1736
|
+
"portal:publish",
|
|
1737
|
+
"push:read",
|
|
1738
|
+
"push:manage",
|
|
1739
|
+
"push:send",
|
|
1740
|
+
"integrations:read",
|
|
1741
|
+
"integrations:manage",
|
|
1742
|
+
"integrations:send",
|
|
1743
|
+
"sdk:read",
|
|
1744
|
+
"sdk:manage",
|
|
1745
|
+
"apps:read",
|
|
1746
|
+
"apps:manage"
|
|
1747
|
+
];
|
|
1748
|
+
var MCP_DEFAULT_CAPABILITIES = [
|
|
1749
|
+
"context:read",
|
|
1750
|
+
"users:read",
|
|
1751
|
+
"analytics:read",
|
|
1752
|
+
"requests:read",
|
|
1753
|
+
"roadmap:read",
|
|
1754
|
+
"content:read",
|
|
1755
|
+
"experiences:read",
|
|
1756
|
+
"segments:read",
|
|
1757
|
+
"brand:read",
|
|
1758
|
+
"portal:read",
|
|
1759
|
+
"push:read",
|
|
1760
|
+
"sdk:read",
|
|
1761
|
+
"apps:read",
|
|
1762
|
+
"requests:manage",
|
|
1763
|
+
"roadmap:manage",
|
|
1764
|
+
"content:manage",
|
|
1765
|
+
"experiences:manage",
|
|
1766
|
+
"segments:manage"
|
|
1767
|
+
];
|
|
1768
|
+
|
|
1769
|
+
// src/schemas/mcp.ts
|
|
1770
|
+
var mcpCapabilitySchema = zod.z.string().refine((value) => MCP_CAPABILITIES.includes(value), "Unknown MCP capability");
|
|
1771
|
+
var mcpGrantSchema = zod.z.object({
|
|
1772
|
+
name: zod.z.string().trim().min(1).max(100).default("AI connection"),
|
|
1773
|
+
appIds: zod.z.array(zod.z.string().uuid()).min(1).max(100).refine((v) => new Set(v).size === v.length, "Duplicate app IDs"),
|
|
1774
|
+
capabilities: zod.z.array(mcpCapabilitySchema).max(56).default([...MCP_DEFAULT_CAPABILITIES]),
|
|
1775
|
+
mode: zod.z.enum(MCP_ACCESS_MODES).default("approve_changes")
|
|
1776
|
+
}).strict();
|
|
1777
|
+
var mcpConsentSchema = mcpGrantSchema.extend({
|
|
1778
|
+
workspaceId: zod.z.string().uuid(),
|
|
1779
|
+
externalAuthId: zod.z.string().min(10).max(256).regex(/^[a-zA-Z0-9_-]+$/)
|
|
1780
|
+
});
|
|
1781
|
+
var mcpUpdateConnectionSchema = mcpGrantSchema.extend({ policyVersion: zod.z.number().int().positive() });
|
|
1782
|
+
var subjectRefSchema = zod.z.union([
|
|
1783
|
+
zod.z.object({ subjectId: zod.z.string().uuid() }).strict(),
|
|
1784
|
+
zod.z.object({ externalId: zod.z.string().min(1).max(256) }).strict(),
|
|
1785
|
+
zod.z.object({ anonymousId: zod.z.string().min(1).max(256) }).strict()
|
|
1786
|
+
]);
|
|
1787
|
+
var mcpPageSchema = zod.z.object({ cursor: zod.z.string().max(4096).optional(), limit: zod.z.number().int().min(1).max(100).default(25) });
|
|
1788
|
+
var mcpSearchSchema = mcpPageSchema.extend({
|
|
1789
|
+
query: zod.z.string().trim().min(1).max(500),
|
|
1790
|
+
types: zod.z.array(zod.z.enum(["request", "feedback_answer", "survey_answer", "roadmap", "article", "changelog"])).max(6).optional(),
|
|
1791
|
+
variant: zod.z.enum(["draft", "published", "record"]).optional()
|
|
1792
|
+
});
|
|
1793
|
+
|
|
1794
|
+
// src/types/web.ts
|
|
1795
|
+
var DELIVERY_PROTOCOL_VERSION = 2;
|
|
1796
|
+
function deliveryPlatformsForApp(platforms) {
|
|
1797
|
+
const values = /* @__PURE__ */ new Set();
|
|
1798
|
+
for (const platform of platforms) {
|
|
1799
|
+
if (platform === "web" || platform === "ios" || platform === "android") values.add(platform);
|
|
1800
|
+
if (platform === "expo" || platform === "react-native" || platform === "flutter") {
|
|
1801
|
+
values.add("ios");
|
|
1802
|
+
values.add("android");
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
return [...values];
|
|
1806
|
+
}
|
|
1807
|
+
function resolveWebPresentation(pillar, override) {
|
|
1808
|
+
return {
|
|
1809
|
+
layout: override?.layout ?? "modal",
|
|
1810
|
+
size: override?.size ?? (pillar === "requests" ? "wide" : "standard"),
|
|
1811
|
+
position: override?.position ?? "right",
|
|
1812
|
+
backdrop: override?.backdrop ?? override?.layout !== "card"
|
|
1813
|
+
};
|
|
1814
|
+
}
|
|
1815
|
+
var id = zod.z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/);
|
|
1816
|
+
var key = zod.z.string().min(1).max(120).refine(
|
|
1817
|
+
(v) => !["__proto__", "prototype", "constructor"].includes(v),
|
|
1818
|
+
"Reserved property key"
|
|
1819
|
+
);
|
|
1820
|
+
var scalar = zod.z.union([
|
|
1821
|
+
zod.z.string().max(8192),
|
|
1822
|
+
zod.z.number().finite(),
|
|
1823
|
+
zod.z.boolean(),
|
|
1824
|
+
zod.z.null()
|
|
1825
|
+
]);
|
|
1826
|
+
var baseSource = { id, label: zod.z.string().min(1).max(120) };
|
|
1827
|
+
var filterSchema = zod.z.object({
|
|
1828
|
+
key,
|
|
1829
|
+
op: zod.z.enum([
|
|
1830
|
+
"eq",
|
|
1831
|
+
"neq",
|
|
1832
|
+
"gt",
|
|
1833
|
+
"gte",
|
|
1834
|
+
"lt",
|
|
1835
|
+
"lte",
|
|
1836
|
+
"in",
|
|
1837
|
+
"nin",
|
|
1838
|
+
"contains",
|
|
1839
|
+
"starts_with",
|
|
1840
|
+
"exists",
|
|
1841
|
+
"not_exists"
|
|
1842
|
+
]),
|
|
1843
|
+
value: zod.z.union([
|
|
1844
|
+
zod.z.string(),
|
|
1845
|
+
zod.z.number().finite(),
|
|
1846
|
+
zod.z.boolean(),
|
|
1847
|
+
zod.z.array(zod.z.union([zod.z.string(), zod.z.number().finite()])).max(100)
|
|
1848
|
+
]).optional()
|
|
1849
|
+
});
|
|
1850
|
+
var personalizationSpecSchema = zod.z.object({
|
|
1851
|
+
version: zod.z.literal(1),
|
|
1852
|
+
sources: zod.z.array(
|
|
1853
|
+
zod.z.discriminatedUnion("kind", [
|
|
1854
|
+
zod.z.object({ ...baseSource, kind: zod.z.literal("user_property") }),
|
|
1855
|
+
zod.z.object({ ...baseSource, kind: zod.z.literal("trigger_event") }),
|
|
1856
|
+
zod.z.object({ ...baseSource, kind: zod.z.literal("send_data") }),
|
|
1857
|
+
zod.z.object({ ...baseSource, kind: zod.z.literal("app") }),
|
|
1858
|
+
zod.z.object({ ...baseSource, kind: zod.z.literal("now") }),
|
|
1859
|
+
zod.z.object({
|
|
1860
|
+
...baseSource,
|
|
1861
|
+
kind: zod.z.literal("latest_event"),
|
|
1862
|
+
eventName: zod.z.string().min(1).max(120),
|
|
1863
|
+
lookbackDays: zod.z.number().int().min(1).max(90),
|
|
1864
|
+
filters: zod.z.array(filterSchema).max(8).optional()
|
|
1865
|
+
})
|
|
1866
|
+
])
|
|
1867
|
+
).max(16),
|
|
1868
|
+
bindings: zod.z.array(
|
|
1869
|
+
zod.z.object({
|
|
1870
|
+
id,
|
|
1871
|
+
label: zod.z.string().min(1).max(120),
|
|
1872
|
+
sourceId: id,
|
|
1873
|
+
key,
|
|
1874
|
+
type: zod.z.enum(["string", "number", "boolean", "date"]),
|
|
1875
|
+
fallback: scalar.optional()
|
|
1876
|
+
})
|
|
1877
|
+
).max(64),
|
|
1878
|
+
missingData: zod.z.literal("skip")
|
|
1879
|
+
}).superRefine((spec, ctx) => {
|
|
1880
|
+
const sources = new Set(spec.sources.map((source) => source.id));
|
|
1881
|
+
if (sources.size !== spec.sources.length)
|
|
1882
|
+
ctx.addIssue({
|
|
1883
|
+
code: "custom",
|
|
1884
|
+
path: ["sources"],
|
|
1885
|
+
message: "Source IDs must be unique"
|
|
1886
|
+
});
|
|
1887
|
+
if (spec.sources.filter((source) => source.kind === "latest_event").length > 4)
|
|
1888
|
+
ctx.addIssue({
|
|
1889
|
+
code: "custom",
|
|
1890
|
+
path: ["sources"],
|
|
1891
|
+
message: "Use at most four activity sources"
|
|
1892
|
+
});
|
|
1893
|
+
const bindings = /* @__PURE__ */ new Set();
|
|
1894
|
+
spec.bindings.forEach((binding, index) => {
|
|
1895
|
+
if (bindings.has(binding.id))
|
|
1896
|
+
ctx.addIssue({
|
|
1897
|
+
code: "custom",
|
|
1898
|
+
path: ["bindings", index, "id"],
|
|
1899
|
+
message: "Field IDs must be unique"
|
|
1900
|
+
});
|
|
1901
|
+
bindings.add(binding.id);
|
|
1902
|
+
if (!sources.has(binding.sourceId))
|
|
1903
|
+
ctx.addIssue({
|
|
1904
|
+
code: "custom",
|
|
1905
|
+
path: ["bindings", index, "sourceId"],
|
|
1906
|
+
message: "Choose an existing source"
|
|
1907
|
+
});
|
|
1908
|
+
if (binding.fallback !== void 0 && (isMissing(binding.fallback) || !matchesType(binding.fallback, binding.type)))
|
|
1909
|
+
ctx.addIssue({
|
|
1910
|
+
code: "custom",
|
|
1911
|
+
path: ["bindings", index, "fallback"],
|
|
1912
|
+
message: "Fallback must be a non-empty value of the selected type"
|
|
1913
|
+
});
|
|
1914
|
+
});
|
|
1915
|
+
});
|
|
1916
|
+
var userPropertiesUpdateSchema = zod.z.object({
|
|
1917
|
+
mutationId: zod.z.string().uuid(),
|
|
1918
|
+
set: zod.z.record(key, scalar).refine(
|
|
1919
|
+
(v) => Object.keys(v).length <= 64,
|
|
1920
|
+
"Update at most 64 properties"
|
|
1921
|
+
).optional(),
|
|
1922
|
+
unset: zod.z.array(key).max(64).optional()
|
|
1923
|
+
}).superRefine((update, ctx) => {
|
|
1924
|
+
if (!Object.keys(update.set ?? {}).length && !update.unset?.length)
|
|
1925
|
+
ctx.addIssue({
|
|
1926
|
+
code: "custom",
|
|
1927
|
+
message: "Supply properties to set or remove"
|
|
1928
|
+
});
|
|
1929
|
+
if (update.unset?.some((name) => Object.hasOwn(update.set ?? {}, name)))
|
|
1930
|
+
ctx.addIssue({
|
|
1931
|
+
code: "custom",
|
|
1932
|
+
message: "A property cannot be set and removed in the same update"
|
|
1933
|
+
});
|
|
1934
|
+
});
|
|
1935
|
+
function isMissing(value) {
|
|
1936
|
+
return value == null || typeof value === "string" && !value.trim();
|
|
1937
|
+
}
|
|
1938
|
+
function matchesType(value, type) {
|
|
1939
|
+
if (type === "date")
|
|
1940
|
+
return typeof value === "string" && !Number.isNaN(Date.parse(value));
|
|
1941
|
+
return typeof value === type && (typeof value !== "number" || Number.isFinite(value));
|
|
1942
|
+
}
|
|
1943
|
+
function resolvePersonalizationBindings(spec, sources) {
|
|
1944
|
+
const values = /* @__PURE__ */ Object.create(null);
|
|
1945
|
+
const issues = [];
|
|
1946
|
+
const fallbackBindingIds = [];
|
|
1947
|
+
for (const binding of spec.bindings) {
|
|
1948
|
+
const source = sources[binding.sourceId]?.values;
|
|
1949
|
+
const value = source && Object.hasOwn(source, binding.key) ? source[binding.key] : void 0;
|
|
1950
|
+
const missing = isMissing(value);
|
|
1951
|
+
if (!missing && matchesType(value, binding.type))
|
|
1952
|
+
values[binding.id] = value;
|
|
1953
|
+
else if (missing && binding.fallback !== void 0) {
|
|
1954
|
+
values[binding.id] = binding.fallback;
|
|
1955
|
+
fallbackBindingIds.push(binding.id);
|
|
1956
|
+
} else
|
|
1957
|
+
issues.push({
|
|
1958
|
+
code: missing ? "missing" : "type_mismatch",
|
|
1959
|
+
bindingId: binding.id,
|
|
1960
|
+
message: missing ? `${binding.label} is missing` : `${binding.label} must be ${binding.type}`
|
|
1961
|
+
});
|
|
1962
|
+
}
|
|
1963
|
+
return {
|
|
1964
|
+
status: issues.length ? "skipped" : fallbackBindingIds.length ? "using_fallback" : "ready",
|
|
1965
|
+
values,
|
|
1966
|
+
fallbackBindingIds,
|
|
1967
|
+
issues,
|
|
1968
|
+
sources
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
var TOKEN = /\{\{\s*p\.([A-Za-z][A-Za-z0-9_]*)\s*\}\}/g;
|
|
1972
|
+
var WHOLE_TOKEN = /^\{\{\s*p\.([A-Za-z][A-Za-z0-9_]*)\s*\}\}$/;
|
|
1973
|
+
function personalizationToken(bindingId) {
|
|
1974
|
+
return `{{p.${bindingId}}}`;
|
|
1975
|
+
}
|
|
1976
|
+
function renderPersonalizedValue(input, values, issues, path = "", mode = "text") {
|
|
1977
|
+
if (typeof input === "string") {
|
|
1978
|
+
const whole = WHOLE_TOKEN.exec(input);
|
|
1979
|
+
const lookup = (bindingId) => {
|
|
1980
|
+
if (Object.hasOwn(values, bindingId)) return values[bindingId];
|
|
1981
|
+
issues.push({
|
|
1982
|
+
code: "unknown_binding",
|
|
1983
|
+
bindingId,
|
|
1984
|
+
path,
|
|
1985
|
+
message: `No value is available for ${bindingId}`
|
|
1986
|
+
});
|
|
1987
|
+
return null;
|
|
1988
|
+
};
|
|
1989
|
+
if (mode === "json" && whole) return lookup(whole[1]);
|
|
1990
|
+
if (/\{\{|\}\}/.test(input.replace(TOKEN, "")))
|
|
1991
|
+
issues.push({
|
|
1992
|
+
code: "invalid_template",
|
|
1993
|
+
path,
|
|
1994
|
+
message: "Insert a valid dynamic field"
|
|
1995
|
+
});
|
|
1996
|
+
const result = input.replace(TOKEN, (_, bindingId) => {
|
|
1997
|
+
const value = lookup(bindingId);
|
|
1998
|
+
return mode === "url" && !whole ? encodeURIComponent(String(value ?? "")) : String(value ?? "");
|
|
1999
|
+
});
|
|
2000
|
+
if (mode === "url" && result) {
|
|
2001
|
+
try {
|
|
2002
|
+
const url = new URL(result);
|
|
2003
|
+
if (["javascript:", "data:", "file:", "vbscript:"].includes(url.protocol))
|
|
2004
|
+
throw new Error("unsafe");
|
|
2005
|
+
if (!whole && /\{\{/.test(input.split(/:\/\//)[0] ?? ""))
|
|
2006
|
+
throw new Error("dynamic scheme");
|
|
2007
|
+
if (!whole && /\{\{/.test(
|
|
2008
|
+
input.match(/^[a-z][a-z0-9+.-]*:\/\/([^/?#]*)/i)?.[1] ?? ""
|
|
2009
|
+
))
|
|
2010
|
+
throw new Error("dynamic authority");
|
|
2011
|
+
} catch {
|
|
2012
|
+
issues.push({
|
|
2013
|
+
code: "invalid_destination",
|
|
2014
|
+
path,
|
|
2015
|
+
message: "The resolved destination must be a valid app link or web URL"
|
|
2016
|
+
});
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
return result;
|
|
2020
|
+
}
|
|
2021
|
+
if (Array.isArray(input))
|
|
2022
|
+
return input.map(
|
|
2023
|
+
(item, index) => renderPersonalizedValue(item, values, issues, `${path}/${index}`, mode)
|
|
2024
|
+
);
|
|
2025
|
+
if (input && typeof input === "object") {
|
|
2026
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
2027
|
+
for (const [name, value] of Object.entries(input)) {
|
|
2028
|
+
if (["__proto__", "constructor", "prototype"].includes(name)) {
|
|
2029
|
+
issues.push({
|
|
2030
|
+
code: "invalid_template",
|
|
2031
|
+
path,
|
|
2032
|
+
message: "Reserved object key"
|
|
2033
|
+
});
|
|
2034
|
+
continue;
|
|
2035
|
+
}
|
|
2036
|
+
result[name] = renderPersonalizedValue(
|
|
2037
|
+
value,
|
|
2038
|
+
values,
|
|
2039
|
+
issues,
|
|
2040
|
+
`${path}/${name}`,
|
|
2041
|
+
mode
|
|
2042
|
+
);
|
|
2043
|
+
}
|
|
2044
|
+
return result;
|
|
2045
|
+
}
|
|
2046
|
+
return input;
|
|
2047
|
+
}
|
|
2048
|
+
var TEXT_KEYS = /* @__PURE__ */ new Set([
|
|
2049
|
+
"title",
|
|
2050
|
+
"body",
|
|
2051
|
+
"subtitle",
|
|
2052
|
+
"headline",
|
|
2053
|
+
"label",
|
|
2054
|
+
"placeholder",
|
|
2055
|
+
"followUp",
|
|
2056
|
+
"lowLabel",
|
|
2057
|
+
"highLabel",
|
|
2058
|
+
"description",
|
|
2059
|
+
"buttonText",
|
|
2060
|
+
"submitLabel",
|
|
2061
|
+
"nextLabel",
|
|
2062
|
+
"backLabel",
|
|
2063
|
+
"text"
|
|
2064
|
+
]);
|
|
2065
|
+
var URL_KEYS = /* @__PURE__ */ new Set(["imageUrl", "deepLink", "target"]);
|
|
2066
|
+
var CONTENT_KEYS = /* @__PURE__ */ new Set([
|
|
2067
|
+
"questions",
|
|
2068
|
+
"options",
|
|
2069
|
+
"ctas",
|
|
2070
|
+
"cta",
|
|
2071
|
+
"actionButtons",
|
|
2072
|
+
"flow",
|
|
2073
|
+
"welcome",
|
|
2074
|
+
"thankYou",
|
|
2075
|
+
"completion",
|
|
2076
|
+
"endScreen",
|
|
2077
|
+
"openAction"
|
|
2078
|
+
]);
|
|
2079
|
+
function personalizationUsage(content) {
|
|
2080
|
+
const usage = /* @__PURE__ */ new Map();
|
|
2081
|
+
const scan = (value, field) => {
|
|
2082
|
+
if (typeof value === "string") {
|
|
2083
|
+
for (const match of value.matchAll(TOKEN)) {
|
|
2084
|
+
const fields = usage.get(match[1]) ?? /* @__PURE__ */ new Set();
|
|
2085
|
+
fields.add(field);
|
|
2086
|
+
usage.set(match[1], fields);
|
|
2087
|
+
}
|
|
2088
|
+
} else if (Array.isArray(value)) value.forEach((item) => scan(item, field));
|
|
2089
|
+
else if (value && typeof value === "object")
|
|
2090
|
+
Object.values(value).forEach((item) => scan(item, field));
|
|
2091
|
+
};
|
|
2092
|
+
const walk = (value) => {
|
|
2093
|
+
if (Array.isArray(value)) {
|
|
2094
|
+
value.forEach(walk);
|
|
2095
|
+
return;
|
|
2096
|
+
}
|
|
2097
|
+
if (!value || typeof value !== "object") return;
|
|
2098
|
+
for (const [key2, item] of Object.entries(value)) {
|
|
2099
|
+
if (TEXT_KEYS.has(key2) || URL_KEYS.has(key2) || key2 === "actionJson" || key2 === "payloadExtras")
|
|
2100
|
+
scan(item, key2);
|
|
2101
|
+
else if (CONTENT_KEYS.has(key2)) walk(item);
|
|
2102
|
+
}
|
|
2103
|
+
};
|
|
2104
|
+
walk(content);
|
|
2105
|
+
return usage;
|
|
2106
|
+
}
|
|
2107
|
+
function renderPersonalizedContent(content, resolution) {
|
|
2108
|
+
const usage = personalizationUsage(content);
|
|
2109
|
+
const onlyOptionalImage = (id2) => usage.get(id2)?.size === 1 && usage.get(id2)?.has("imageUrl");
|
|
2110
|
+
const issues = resolution.issues.filter(
|
|
2111
|
+
(issue) => !issue.bindingId || usage.has(issue.bindingId) && !(issue.code === "missing" && onlyOptionalImage(issue.bindingId))
|
|
2112
|
+
);
|
|
2113
|
+
const fallbacks = resolution.fallbackBindingIds.filter((id2) => usage.has(id2));
|
|
2114
|
+
const walk = (value, path = "") => {
|
|
2115
|
+
if (Array.isArray(value))
|
|
2116
|
+
return value.map((item, index) => walk(item, `${path}/${index}`));
|
|
2117
|
+
if (!value || typeof value !== "object") return value;
|
|
2118
|
+
return Object.fromEntries(
|
|
2119
|
+
Object.entries(value).map(([name, item]) => {
|
|
2120
|
+
const childPath = `${path}/${name}`;
|
|
2121
|
+
if (TEXT_KEYS.has(name) && typeof item === "string")
|
|
2122
|
+
return [
|
|
2123
|
+
name,
|
|
2124
|
+
renderPersonalizedValue(item, resolution.values, issues, childPath)
|
|
2125
|
+
];
|
|
2126
|
+
if (URL_KEYS.has(name) && typeof item === "string") {
|
|
2127
|
+
if (name === "imageUrl" && [...item.matchAll(TOKEN)].some(
|
|
2128
|
+
(match) => resolution.issues.some(
|
|
2129
|
+
(issue) => issue.bindingId === match[1] && issue.code === "missing"
|
|
2130
|
+
)
|
|
2131
|
+
))
|
|
2132
|
+
return [name, null];
|
|
2133
|
+
const isEvent = name === "target" && value.action === "custom_event";
|
|
2134
|
+
const rendered2 = renderPersonalizedValue(
|
|
2135
|
+
item,
|
|
2136
|
+
resolution.values,
|
|
2137
|
+
issues,
|
|
2138
|
+
childPath,
|
|
2139
|
+
isEvent ? "text" : "url"
|
|
2140
|
+
);
|
|
2141
|
+
if (name === "imageUrl" && rendered2 && !String(rendered2).startsWith("https://"))
|
|
2142
|
+
issues.push({
|
|
2143
|
+
code: "invalid_destination",
|
|
2144
|
+
path: childPath,
|
|
2145
|
+
message: "Image URLs must use HTTPS"
|
|
2146
|
+
});
|
|
2147
|
+
return [name, rendered2];
|
|
2148
|
+
}
|
|
2149
|
+
if (name === "actionJson" || name === "payloadExtras")
|
|
2150
|
+
return [
|
|
2151
|
+
name,
|
|
2152
|
+
renderPersonalizedValue(
|
|
2153
|
+
item,
|
|
2154
|
+
resolution.values,
|
|
2155
|
+
issues,
|
|
2156
|
+
childPath,
|
|
2157
|
+
"json"
|
|
2158
|
+
)
|
|
2159
|
+
];
|
|
2160
|
+
if (CONTENT_KEYS.has(name)) return [name, walk(item, childPath)];
|
|
2161
|
+
return [name, item];
|
|
2162
|
+
})
|
|
2163
|
+
);
|
|
2164
|
+
};
|
|
2165
|
+
const rendered = walk(content);
|
|
2166
|
+
return {
|
|
2167
|
+
content: rendered,
|
|
2168
|
+
resolution: {
|
|
2169
|
+
...resolution,
|
|
2170
|
+
fallbackBindingIds: fallbacks,
|
|
2171
|
+
status: issues.length ? "skipped" : fallbacks.length ? "using_fallback" : "ready",
|
|
2172
|
+
issues
|
|
2173
|
+
}
|
|
2174
|
+
};
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
// src/presentation.ts
|
|
2178
|
+
var PresentationGate = class {
|
|
2179
|
+
paused;
|
|
2180
|
+
identity = 0;
|
|
2181
|
+
revisions = { feedback: 0, survey: 0 };
|
|
2182
|
+
listeners = /* @__PURE__ */ new Set();
|
|
2183
|
+
constructor(paused = false) {
|
|
2184
|
+
this.paused = paused;
|
|
2185
|
+
}
|
|
2186
|
+
get isPaused() {
|
|
2187
|
+
return this.paused;
|
|
2188
|
+
}
|
|
2189
|
+
setPaused(paused) {
|
|
2190
|
+
this.paused = paused;
|
|
2191
|
+
this.notify();
|
|
2192
|
+
}
|
|
2193
|
+
invalidate(purpose) {
|
|
2194
|
+
if (purpose) this.revisions[purpose]++;
|
|
2195
|
+
else this.identity++;
|
|
2196
|
+
this.notify();
|
|
2197
|
+
}
|
|
2198
|
+
validator(purpose) {
|
|
2199
|
+
const identity = this.identity;
|
|
2200
|
+
const revision = this.revisions[purpose];
|
|
2201
|
+
return () => identity === this.identity && revision === this.revisions[purpose];
|
|
2202
|
+
}
|
|
2203
|
+
subscribe(listener) {
|
|
2204
|
+
this.listeners.add(listener);
|
|
2205
|
+
return () => {
|
|
2206
|
+
this.listeners.delete(listener);
|
|
2207
|
+
};
|
|
2208
|
+
}
|
|
2209
|
+
runWhenReady(run, valid, cancel = () => {
|
|
2210
|
+
}) {
|
|
2211
|
+
if (!valid()) {
|
|
2212
|
+
cancel();
|
|
2213
|
+
return;
|
|
2214
|
+
}
|
|
2215
|
+
if (!this.paused) {
|
|
2216
|
+
run();
|
|
2217
|
+
return;
|
|
2218
|
+
}
|
|
2219
|
+
const stop = this.subscribe(() => {
|
|
2220
|
+
if (valid() && this.paused) return;
|
|
2221
|
+
stop();
|
|
2222
|
+
if (valid()) run();
|
|
2223
|
+
else cancel();
|
|
2224
|
+
});
|
|
2225
|
+
}
|
|
2226
|
+
waitUntilReady(valid) {
|
|
2227
|
+
if (!valid()) return Promise.resolve(false);
|
|
2228
|
+
if (!this.paused) return Promise.resolve(true);
|
|
2229
|
+
return new Promise((resolve) => {
|
|
2230
|
+
const stop = this.subscribe(() => {
|
|
2231
|
+
if (valid() && this.paused) return;
|
|
2232
|
+
stop();
|
|
2233
|
+
resolve(valid());
|
|
2234
|
+
});
|
|
2235
|
+
});
|
|
2236
|
+
}
|
|
2237
|
+
notify() {
|
|
2238
|
+
for (const listener of [...this.listeners]) listener();
|
|
2239
|
+
}
|
|
2240
|
+
};
|
|
2241
|
+
|
|
1092
2242
|
exports.APP_OPEN_EVENT_NAME = APP_OPEN_EVENT_NAME;
|
|
1093
2243
|
exports.APP_VERSION_CHANGED_EVENT_NAME = APP_VERSION_CHANGED_EVENT_NAME;
|
|
1094
2244
|
exports.AUDIENCE_JOIN_EVENT_NAME = AUDIENCE_JOIN_EVENT_NAME;
|
|
@@ -1096,13 +2246,21 @@ exports.AUDIENCE_JOIN_TRIGGER_KIND = AUDIENCE_JOIN_TRIGGER_KIND;
|
|
|
1096
2246
|
exports.BILLING_GRACE_DAYS = BILLING_GRACE_DAYS;
|
|
1097
2247
|
exports.COMMERCIAL_BILLING_PLANS = COMMERCIAL_BILLING_PLANS;
|
|
1098
2248
|
exports.CORE_INTEGRATION_EVENTS = CORE_INTEGRATION_EVENTS;
|
|
2249
|
+
exports.DELIVERY_PROTOCOL_VERSION = DELIVERY_PROTOCOL_VERSION;
|
|
1099
2250
|
exports.INAPP_AUTO_DISMISSED_EVENT_NAME = INAPP_AUTO_DISMISSED_EVENT_NAME;
|
|
1100
2251
|
exports.INAPP_CTA_CLICKED_EVENT_NAME = INAPP_CTA_CLICKED_EVENT_NAME;
|
|
1101
2252
|
exports.INAPP_DISMISSED_EVENT_NAME = INAPP_DISMISSED_EVENT_NAME;
|
|
1102
2253
|
exports.INAPP_SHOWN_EVENT_NAME = INAPP_SHOWN_EVENT_NAME;
|
|
1103
2254
|
exports.INTEGRATION_CATEGORIES = INTEGRATION_CATEGORIES;
|
|
1104
2255
|
exports.INTEGRATION_PROVIDERS = INTEGRATION_PROVIDERS;
|
|
2256
|
+
exports.MCP_ACCESS_MODES = MCP_ACCESS_MODES;
|
|
2257
|
+
exports.MCP_CAPABILITIES = MCP_CAPABILITIES;
|
|
2258
|
+
exports.MCP_DEFAULT_CAPABILITIES = MCP_DEFAULT_CAPABILITIES;
|
|
2259
|
+
exports.MCP_DOMAINS = MCP_DOMAINS;
|
|
2260
|
+
exports.PORTAL_RESERVED_SLUGS = PORTAL_RESERVED_SLUGS;
|
|
2261
|
+
exports.PORTAL_SLUG_PATTERN = PORTAL_SLUG_PATTERN;
|
|
1105
2262
|
exports.PUSH_EVENTS = PUSH_EVENTS;
|
|
2263
|
+
exports.PresentationGate = PresentationGate;
|
|
1106
2264
|
exports.RADIUS_PRESETS = RADIUS_PRESETS;
|
|
1107
2265
|
exports.RECIPIENTS_LIMIT = RECIPIENTS_LIMIT;
|
|
1108
2266
|
exports.REQUEST_COMMENTED_EVENT_NAME = REQUEST_COMMENTED_EVENT_NAME;
|
|
@@ -1123,10 +2281,17 @@ exports.TRIAL_APP_LIMIT = TRIAL_APP_LIMIT;
|
|
|
1123
2281
|
exports.TRIAL_DAYS = TRIAL_DAYS;
|
|
1124
2282
|
exports.USER_IDENTIFIED_EVENT_NAME = USER_IDENTIFIED_EVENT_NAME;
|
|
1125
2283
|
exports.brandTokensFromPreset = brandTokensFromPreset;
|
|
2284
|
+
exports.buildPortalUrl = buildPortalUrl;
|
|
2285
|
+
exports.contentAssetIds = contentAssetIds;
|
|
2286
|
+
exports.contentSlug = contentSlug;
|
|
2287
|
+
exports.contentText = contentText;
|
|
1126
2288
|
exports.defaultEventTrigger = defaultEventTrigger;
|
|
2289
|
+
exports.defaultOnboardingMessage = defaultOnboardingMessage;
|
|
1127
2290
|
exports.defaultThemePreset = defaultThemePreset;
|
|
1128
2291
|
exports.defaultTriggerSpec = defaultTriggerSpec;
|
|
2292
|
+
exports.deliveryPlatformsForApp = deliveryPlatformsForApp;
|
|
1129
2293
|
exports.emptyAudienceSpec = emptyAudienceSpec;
|
|
2294
|
+
exports.emptyDocumentDraft = emptyDocumentDraft;
|
|
1130
2295
|
exports.emptySegmentDsl = emptySegmentDsl;
|
|
1131
2296
|
exports.endpoints = endpoints;
|
|
1132
2297
|
exports.err = err;
|
|
@@ -1140,15 +2305,30 @@ exports.getCoreIntegrationEvent = getCoreIntegrationEvent;
|
|
|
1140
2305
|
exports.getThemePresetById = getThemePresetById;
|
|
1141
2306
|
exports.inAppColorsFromBrandTokens = inAppColorsFromBrandTokens;
|
|
1142
2307
|
exports.isSilentPushPayload = isSilentPushPayload;
|
|
2308
|
+
exports.isValidIanaTimeZone = isValidIanaTimeZone;
|
|
1143
2309
|
exports.nextPeriodicFire = nextPeriodicFire;
|
|
1144
2310
|
exports.nextQuestionId = nextQuestionId;
|
|
1145
2311
|
exports.ok = ok;
|
|
2312
|
+
exports.personalizationSpecSchema = personalizationSpecSchema;
|
|
2313
|
+
exports.personalizationToken = personalizationToken;
|
|
2314
|
+
exports.personalizationUsage = personalizationUsage;
|
|
1146
2315
|
exports.promptThemeFromBrandTokens = promptThemeFromBrandTokens;
|
|
1147
2316
|
exports.reachableQuestions = reachableQuestions;
|
|
2317
|
+
exports.renderPersonalizedContent = renderPersonalizedContent;
|
|
2318
|
+
exports.renderPersonalizedValue = renderPersonalizedValue;
|
|
1148
2319
|
exports.requestAccentFromBrandTokens = requestAccentFromBrandTokens;
|
|
2320
|
+
exports.resolvePersonalizationBindings = resolvePersonalizationBindings;
|
|
2321
|
+
exports.resolveWebPresentation = resolveWebPresentation;
|
|
2322
|
+
exports.safeContentHref = safeContentHref;
|
|
1149
2323
|
exports.sanitizeCoreIntegrationProperties = sanitizeCoreIntegrationProperties;
|
|
1150
2324
|
exports.schemas = schemas_exports;
|
|
1151
2325
|
exports.serializedRulesToDsl = serializedRulesToDsl;
|
|
2326
|
+
exports.suggestPortalSlug = suggestPortalSlug;
|
|
1152
2327
|
exports.tzOffsetMinutes = tzOffsetMinutes;
|
|
2328
|
+
exports.userPropertiesUpdateSchema = userPropertiesUpdateSchema;
|
|
2329
|
+
exports.validPortalSlug = validPortalSlug;
|
|
2330
|
+
exports.zonedDateEndToUtc = zonedDateEndToUtc;
|
|
2331
|
+
exports.zonedDateTimeParts = zonedDateTimeParts;
|
|
2332
|
+
exports.zonedDateTimeToUtc = zonedDateTimeToUtc;
|
|
1153
2333
|
//# sourceMappingURL=index.cjs.map
|
|
1154
2334
|
//# sourceMappingURL=index.cjs.map
|