@odla-ai/chapter 0.43.2 → 0.44.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/dist/{copy-context-Bh1EZvCg.d.ts → copy-context-B4SCy6vx.d.ts} +18 -0
- package/dist/index.cjs +214 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +214 -102
- package/dist/index.js.map +1 -1
- package/dist/ui/admin/index.d.ts +2 -2
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/member/index.d.ts +2 -2
- package/dist/worker/index.cjs +651 -60
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +18 -0
- package/dist/worker/index.d.ts +18 -0
- package/dist/worker/index.js +651 -60
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -168,6 +168,7 @@ __export(index_exports, {
|
|
|
168
168
|
resolveJoinContinuation: () => resolveJoinContinuation,
|
|
169
169
|
resolveLeaderFormation: () => resolveLeaderFormation,
|
|
170
170
|
resolveMemberContent: () => resolveMemberContent,
|
|
171
|
+
resolveNetworkPersonRegistry: () => resolveNetworkPersonRegistry,
|
|
171
172
|
resolvePipeline: () => resolvePipeline,
|
|
172
173
|
resolveScheduling: () => resolveScheduling,
|
|
173
174
|
resolveSignupControl: () => resolveSignupControl,
|
|
@@ -319,8 +320,8 @@ async function submitApplication(db, chapter, fields, opts) {
|
|
|
319
320
|
if (app.requireDisclaimerAck && !acked) {
|
|
320
321
|
return { ok: false, error: "disclaimerAck is required" };
|
|
321
322
|
}
|
|
322
|
-
const
|
|
323
|
-
const row = { id:
|
|
323
|
+
const id5 = opts.submissionId ? await applicationIdForSubmission(opts.submissionId) : opts.newId();
|
|
324
|
+
const row = { id: id5, status: chapter.pipeline.initial, createdAt: opts.now };
|
|
324
325
|
for (const f of [...app.required, ...app.optional]) {
|
|
325
326
|
if (fieldStates[f]?.visible === false) continue;
|
|
326
327
|
if (typeof fields[f] === "string") row[f] = fields[f].trim();
|
|
@@ -344,19 +345,19 @@ async function submitApplication(db, chapter, fields, opts) {
|
|
|
344
345
|
}
|
|
345
346
|
if (acked) row.disclaimerAckAt = opts.now;
|
|
346
347
|
const ops = [
|
|
347
|
-
{ t: "update", ns: "applications", id:
|
|
348
|
+
{ t: "update", ns: "applications", id: id5, attrs: row }
|
|
348
349
|
];
|
|
349
350
|
if (opts.admissionGrant?.decision === "waive_interview") {
|
|
350
351
|
ops.push({ t: "update", ns: "admissionGrants", id: opts.admissionGrant.id, attrs: {
|
|
351
352
|
consumedAt: opts.now,
|
|
352
|
-
consumedApplicationId:
|
|
353
|
+
consumedApplicationId: id5
|
|
353
354
|
} });
|
|
354
355
|
}
|
|
355
356
|
const { duplicate } = await db.transact(
|
|
356
357
|
ops,
|
|
357
358
|
opts.submissionId ? { mutationId: `join:${opts.submissionId}` } : void 0
|
|
358
359
|
);
|
|
359
|
-
return { ok: true, id:
|
|
360
|
+
return { ok: true, id: id5, duplicate, status: chapter.pipeline.initial, disclaimerAckAt: acked ? opts.now : null };
|
|
360
361
|
}
|
|
361
362
|
function joinConfig(group, paymentsReady2, tiers2 = [], conditions = {}) {
|
|
362
363
|
return {
|
|
@@ -670,6 +671,88 @@ var stripeEventReceiptsEntity = {
|
|
|
670
671
|
}
|
|
671
672
|
};
|
|
672
673
|
|
|
674
|
+
// src/schema-network-person.ts
|
|
675
|
+
var string = (flags = {}) => ({
|
|
676
|
+
type: "string",
|
|
677
|
+
unique: flags.unique ?? false,
|
|
678
|
+
indexed: flags.indexed ?? false,
|
|
679
|
+
optional: flags.optional ?? false
|
|
680
|
+
});
|
|
681
|
+
var number = (flags = {}) => ({
|
|
682
|
+
type: "number",
|
|
683
|
+
unique: false,
|
|
684
|
+
indexed: flags.indexed ?? false,
|
|
685
|
+
optional: flags.optional ?? false
|
|
686
|
+
});
|
|
687
|
+
var json = (flags = {}) => ({
|
|
688
|
+
type: "json",
|
|
689
|
+
unique: false,
|
|
690
|
+
indexed: false,
|
|
691
|
+
optional: flags.optional ?? false
|
|
692
|
+
});
|
|
693
|
+
var id3 = () => string({ unique: true, indexed: true });
|
|
694
|
+
var networkPersonsEntity = { attrs: {
|
|
695
|
+
id: id3(),
|
|
696
|
+
displayName: string({ indexed: true }),
|
|
697
|
+
state: string({ indexed: true }),
|
|
698
|
+
mergedIntoId: string({ indexed: true, optional: true }),
|
|
699
|
+
contactPolicy: json(),
|
|
700
|
+
revision: number({ indexed: true }),
|
|
701
|
+
createdAt: number({ indexed: true }),
|
|
702
|
+
updatedAt: number({ indexed: true })
|
|
703
|
+
} };
|
|
704
|
+
var networkIdentityClaimsEntity = { attrs: {
|
|
705
|
+
id: id3(),
|
|
706
|
+
personId: string({ indexed: true }),
|
|
707
|
+
kind: string({ indexed: true }),
|
|
708
|
+
value: string(),
|
|
709
|
+
hint: string({ optional: true }),
|
|
710
|
+
verifiedAt: number({ indexed: true }),
|
|
711
|
+
createdAt: number({ indexed: true })
|
|
712
|
+
} };
|
|
713
|
+
var networkPersonAliasesEntity = { attrs: {
|
|
714
|
+
id: id3(),
|
|
715
|
+
sourceSystem: string({ indexed: true }),
|
|
716
|
+
sourceRecordId: string({ indexed: true }),
|
|
717
|
+
sourceKey: string({ unique: true, indexed: true }),
|
|
718
|
+
displayName: string({ indexed: true }),
|
|
719
|
+
provenance: string(),
|
|
720
|
+
consent: json(),
|
|
721
|
+
status: string({ indexed: true }),
|
|
722
|
+
personId: string({ indexed: true, optional: true }),
|
|
723
|
+
candidatePersonIds: json({ optional: true }),
|
|
724
|
+
identityClaims: json(),
|
|
725
|
+
chapterLinks: json(),
|
|
726
|
+
revision: number({ indexed: true }),
|
|
727
|
+
createdAt: number({ indexed: true }),
|
|
728
|
+
updatedAt: number({ indexed: true })
|
|
729
|
+
} };
|
|
730
|
+
var networkChapterPersonLinksEntity = { attrs: {
|
|
731
|
+
id: id3(),
|
|
732
|
+
personId: string({ indexed: true }),
|
|
733
|
+
chapterId: string({ indexed: true }),
|
|
734
|
+
chapterPersonId: string({ indexed: true }),
|
|
735
|
+
state: string({ indexed: true }),
|
|
736
|
+
createdAt: number({ indexed: true })
|
|
737
|
+
} };
|
|
738
|
+
var networkPersonEventsEntity = { attrs: {
|
|
739
|
+
id: id3(),
|
|
740
|
+
kind: string({ indexed: true }),
|
|
741
|
+
personId: string({ indexed: true, optional: true }),
|
|
742
|
+
aliasId: string({ indexed: true, optional: true }),
|
|
743
|
+
actorId: string({ indexed: true }),
|
|
744
|
+
mutationId: string({ unique: true, indexed: true }),
|
|
745
|
+
detail: json(),
|
|
746
|
+
createdAt: number({ indexed: true })
|
|
747
|
+
} };
|
|
748
|
+
var networkPersonEntities = {
|
|
749
|
+
networkPersons: networkPersonsEntity,
|
|
750
|
+
networkIdentityClaims: networkIdentityClaimsEntity,
|
|
751
|
+
networkPersonAliases: networkPersonAliasesEntity,
|
|
752
|
+
networkChapterPersonLinks: networkChapterPersonLinksEntity,
|
|
753
|
+
networkPersonEvents: networkPersonEventsEntity
|
|
754
|
+
};
|
|
755
|
+
|
|
673
756
|
// src/schema.ts
|
|
674
757
|
function attr5(type, flags = {}) {
|
|
675
758
|
return {
|
|
@@ -679,10 +762,10 @@ function attr5(type, flags = {}) {
|
|
|
679
762
|
optional: flags.optional ?? false
|
|
680
763
|
};
|
|
681
764
|
}
|
|
682
|
-
var
|
|
765
|
+
var id4 = () => attr5("string", { unique: true, indexed: true });
|
|
683
766
|
var admins = {
|
|
684
767
|
attrs: {
|
|
685
|
-
id:
|
|
768
|
+
id: id4(),
|
|
686
769
|
email: attr5("string", { unique: true, indexed: true }),
|
|
687
770
|
name: attr5("string", { optional: true }),
|
|
688
771
|
note: attr5("string", { optional: true })
|
|
@@ -690,7 +773,7 @@ var admins = {
|
|
|
690
773
|
};
|
|
691
774
|
var superAdmins = {
|
|
692
775
|
attrs: {
|
|
693
|
-
id:
|
|
776
|
+
id: id4(),
|
|
694
777
|
email: attr5("string", { unique: true, indexed: true }),
|
|
695
778
|
note: attr5("string", { optional: true }),
|
|
696
779
|
createdAt: attr5("number", { indexed: true })
|
|
@@ -698,7 +781,7 @@ var superAdmins = {
|
|
|
698
781
|
};
|
|
699
782
|
var networkNotes = {
|
|
700
783
|
attrs: {
|
|
701
|
-
id:
|
|
784
|
+
id: id4(),
|
|
702
785
|
recordKey: attr5("string", { indexed: true }),
|
|
703
786
|
targetId: attr5("string", { indexed: true }),
|
|
704
787
|
recordType: attr5("string", { indexed: true }),
|
|
@@ -711,7 +794,7 @@ var networkNotes = {
|
|
|
711
794
|
};
|
|
712
795
|
var signupControls = {
|
|
713
796
|
attrs: {
|
|
714
|
-
id:
|
|
797
|
+
id: id4(),
|
|
715
798
|
sourceId: attr5("string", { indexed: true }),
|
|
716
799
|
targetId: attr5("string", { indexed: true }),
|
|
717
800
|
environment: attr5("string", { indexed: true }),
|
|
@@ -724,7 +807,7 @@ var signupControls = {
|
|
|
724
807
|
};
|
|
725
808
|
var memberContentControls = {
|
|
726
809
|
attrs: {
|
|
727
|
-
id:
|
|
810
|
+
id: id4(),
|
|
728
811
|
sourceId: attr5("string", { indexed: true }),
|
|
729
812
|
targetId: attr5("string", { indexed: true }),
|
|
730
813
|
environment: attr5("string", { indexed: true }),
|
|
@@ -737,7 +820,7 @@ var memberContentControls = {
|
|
|
737
820
|
};
|
|
738
821
|
var memberContentLocal = {
|
|
739
822
|
attrs: {
|
|
740
|
-
id:
|
|
823
|
+
id: id4(),
|
|
741
824
|
chapterId: attr5("string", { indexed: true }),
|
|
742
825
|
environment: attr5("string", { indexed: true }),
|
|
743
826
|
revision: attr5("number", { indexed: true }),
|
|
@@ -748,7 +831,7 @@ var memberContentLocal = {
|
|
|
748
831
|
};
|
|
749
832
|
var builderLibraryControls = {
|
|
750
833
|
attrs: {
|
|
751
|
-
id:
|
|
834
|
+
id: id4(),
|
|
752
835
|
sourceId: attr5("string", { indexed: true }),
|
|
753
836
|
targetId: attr5("string", { indexed: true }),
|
|
754
837
|
environment: attr5("string", { indexed: true }),
|
|
@@ -761,7 +844,7 @@ var builderLibraryControls = {
|
|
|
761
844
|
};
|
|
762
845
|
var builderLibraryLocal = {
|
|
763
846
|
attrs: {
|
|
764
|
-
id:
|
|
847
|
+
id: id4(),
|
|
765
848
|
appId: attr5("string", { indexed: true }),
|
|
766
849
|
environment: attr5("string", { indexed: true }),
|
|
767
850
|
revision: attr5("number", { indexed: true }),
|
|
@@ -772,7 +855,7 @@ var builderLibraryLocal = {
|
|
|
772
855
|
};
|
|
773
856
|
var groups = {
|
|
774
857
|
attrs: {
|
|
775
|
-
id:
|
|
858
|
+
id: id4(),
|
|
776
859
|
name: attr5("string"),
|
|
777
860
|
standardPriceCents: attr5("number"),
|
|
778
861
|
foundingDiscountCents: attr5("number"),
|
|
@@ -795,7 +878,7 @@ var groups = {
|
|
|
795
878
|
};
|
|
796
879
|
var tiers = {
|
|
797
880
|
attrs: {
|
|
798
|
-
id:
|
|
881
|
+
id: id4(),
|
|
799
882
|
groupId: attr5("string", { indexed: true }),
|
|
800
883
|
name: attr5("string"),
|
|
801
884
|
priceCents: attr5("number"),
|
|
@@ -808,7 +891,7 @@ var tiers = {
|
|
|
808
891
|
};
|
|
809
892
|
var meetings = {
|
|
810
893
|
attrs: {
|
|
811
|
-
id:
|
|
894
|
+
id: id4(),
|
|
812
895
|
applicationId: attr5("string", { indexed: true }),
|
|
813
896
|
groupId: attr5("string", { indexed: true }),
|
|
814
897
|
startAt: attr5("number", { indexed: true }),
|
|
@@ -827,7 +910,7 @@ var meetings = {
|
|
|
827
910
|
};
|
|
828
911
|
var emailLog = {
|
|
829
912
|
attrs: {
|
|
830
|
-
id:
|
|
913
|
+
id: id4(),
|
|
831
914
|
groupId: attr5("string", { indexed: true }),
|
|
832
915
|
applicationId: attr5("string", { indexed: true, optional: true }),
|
|
833
916
|
to: attr5("string", { indexed: true }),
|
|
@@ -842,7 +925,7 @@ var emailLog = {
|
|
|
842
925
|
sentAt: attr5("number", { indexed: true })
|
|
843
926
|
}
|
|
844
927
|
};
|
|
845
|
-
function chapterDb(mode, auth, includeNetworkNotes = false, application = resolveApplication(void 0), includeSignupControl = false, includeMemberContent = false, includeBuilderLibrary = false, includeLeaderAdmissions = false) {
|
|
928
|
+
function chapterDb(mode, auth, includeNetworkNotes = false, application = resolveApplication(void 0), includeSignupControl = false, includeMemberContent = false, includeBuilderLibrary = false, includeLeaderAdmissions = false, includeNetworkPersonRegistry = false) {
|
|
846
929
|
const entities = {};
|
|
847
930
|
if (mode === "chapter") {
|
|
848
931
|
entities.applications = applicationsFor(application);
|
|
@@ -876,6 +959,9 @@ function chapterDb(mode, auth, includeNetworkNotes = false, application = resolv
|
|
|
876
959
|
entities.leaderAdmissionDeliveries = leaderAdmissionDeliveriesEntity;
|
|
877
960
|
entities.leaderAdmissionMutations = leaderAdmissionMutationsEntity;
|
|
878
961
|
}
|
|
962
|
+
if (includeNetworkPersonRegistry) {
|
|
963
|
+
Object.assign(entities, networkPersonEntities);
|
|
964
|
+
}
|
|
879
965
|
const schema = { entities, links: {} };
|
|
880
966
|
const rules = {};
|
|
881
967
|
for (const ns of Object.keys(entities)) {
|
|
@@ -1527,9 +1613,9 @@ var APPLICATION_LABELS = {
|
|
|
1527
1613
|
phone: "Phone",
|
|
1528
1614
|
state: "State"
|
|
1529
1615
|
};
|
|
1530
|
-
function humanize(
|
|
1531
|
-
const text4 =
|
|
1532
|
-
return text4 ? `${text4[0].toUpperCase()}${text4.slice(1)}` :
|
|
1616
|
+
function humanize(id5) {
|
|
1617
|
+
const text4 = id5.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
|
|
1618
|
+
return text4 ? `${text4[0].toUpperCase()}${text4.slice(1)}` : id5;
|
|
1533
1619
|
}
|
|
1534
1620
|
function applicationDefs(chapter) {
|
|
1535
1621
|
try {
|
|
@@ -1538,23 +1624,23 @@ function applicationDefs(chapter) {
|
|
|
1538
1624
|
return {};
|
|
1539
1625
|
}
|
|
1540
1626
|
}
|
|
1541
|
-
function applicationType(
|
|
1627
|
+
function applicationType(id5, def) {
|
|
1542
1628
|
if (def && ["string", "email", "url", "enum"].includes(def.type)) return def.type;
|
|
1543
|
-
return
|
|
1629
|
+
return id5 === "email" ? "email" : id5 === "linkedin" ? "url" : "string";
|
|
1544
1630
|
}
|
|
1545
1631
|
function applicationFlowFields(chapter, application = chapter.application) {
|
|
1546
1632
|
const defs = applicationDefs(chapter);
|
|
1547
|
-
return [...application.required, ...application.optional].map((
|
|
1548
|
-
const def = defs[
|
|
1549
|
-
const conditions = application.conditions[
|
|
1550
|
-
const type = applicationType(
|
|
1633
|
+
return [...application.required, ...application.optional].map((id5, order) => {
|
|
1634
|
+
const def = defs[id5];
|
|
1635
|
+
const conditions = application.conditions[id5];
|
|
1636
|
+
const type = applicationType(id5, def);
|
|
1551
1637
|
return {
|
|
1552
|
-
id:
|
|
1553
|
-
label: def?.label ?? APPLICATION_LABELS[
|
|
1638
|
+
id: id5,
|
|
1639
|
+
label: def?.label ?? APPLICATION_LABELS[id5] ?? humanize(id5),
|
|
1554
1640
|
type,
|
|
1555
|
-
required: application.required.includes(
|
|
1641
|
+
required: application.required.includes(id5),
|
|
1556
1642
|
order,
|
|
1557
|
-
maxLength: application.maxLen[
|
|
1643
|
+
maxLength: application.maxLen[id5] ?? application.defaultMaxLen,
|
|
1558
1644
|
...type === "enum" && def?.options ? { options: [...def.options] } : {},
|
|
1559
1645
|
...conditions ? { conditions: { ...conditions } } : {},
|
|
1560
1646
|
...type === "email" ? { emailIdentity: "literal" } : {}
|
|
@@ -1564,17 +1650,17 @@ function applicationFlowFields(chapter, application = chapter.application) {
|
|
|
1564
1650
|
function resolveFormationFlowFields(crm, formation) {
|
|
1565
1651
|
if (!formation.enabled) return [];
|
|
1566
1652
|
const def = crm.type(formation.type);
|
|
1567
|
-
return [...formation.required, ...formation.optional].map((
|
|
1568
|
-
const field = def.fields[
|
|
1653
|
+
return [...formation.required, ...formation.optional].map((id5, order) => {
|
|
1654
|
+
const field = def.fields[id5];
|
|
1569
1655
|
return {
|
|
1570
|
-
id:
|
|
1571
|
-
label: field.label ?? humanize(
|
|
1656
|
+
id: id5,
|
|
1657
|
+
label: field.label ?? humanize(id5),
|
|
1572
1658
|
type: field.type,
|
|
1573
|
-
required: formation.required.includes(
|
|
1659
|
+
required: formation.required.includes(id5),
|
|
1574
1660
|
order,
|
|
1575
|
-
maxLength: formation.maxLen[
|
|
1661
|
+
maxLength: formation.maxLen[id5] ?? formation.defaultMaxLen,
|
|
1576
1662
|
...field.options ? { options: [...field.options] } : {},
|
|
1577
|
-
...
|
|
1663
|
+
...id5 === def.emailField || field.type === "email" ? { emailIdentity: "literal" } : {}
|
|
1578
1664
|
};
|
|
1579
1665
|
});
|
|
1580
1666
|
}
|
|
@@ -1868,12 +1954,30 @@ function resolveNetwork(config, crm) {
|
|
|
1868
1954
|
return { targets, readers };
|
|
1869
1955
|
}
|
|
1870
1956
|
|
|
1957
|
+
// src/config-network-person.ts
|
|
1958
|
+
var SLUG2 = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
1959
|
+
function resolveNetworkPersonRegistry(mode, input, targetIds) {
|
|
1960
|
+
if (!input) return null;
|
|
1961
|
+
if (mode !== "hub") throw new Error("defineChapter.networkPersonRegistry: only hub mode may own network Person authority");
|
|
1962
|
+
if (input.mode !== "shadow") throw new Error('defineChapter.networkPersonRegistry.mode: must be "shadow"');
|
|
1963
|
+
const chapterIds = input.chapterIds ? [...input.chapterIds] : [...targetIds];
|
|
1964
|
+
if (chapterIds.length === 0) throw new Error("defineChapter.networkPersonRegistry.chapterIds: at least one chapter is required");
|
|
1965
|
+
if (new Set(chapterIds).size !== chapterIds.length || chapterIds.some((id5) => !SLUG2.test(id5))) {
|
|
1966
|
+
throw new Error("defineChapter.networkPersonRegistry.chapterIds: expected distinct lowercase slugs");
|
|
1967
|
+
}
|
|
1968
|
+
const unknown = chapterIds.filter((id5) => !targetIds.includes(id5));
|
|
1969
|
+
if (unknown.length) {
|
|
1970
|
+
throw new Error(`defineChapter.networkPersonRegistry.chapterIds: ${unknown.map((id5) => `"${id5}"`).join(", ")} are not configured network targets`);
|
|
1971
|
+
}
|
|
1972
|
+
return { mode: "shadow", chapterIds };
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1871
1975
|
// src/config-signup-control.ts
|
|
1872
|
-
var
|
|
1976
|
+
var SLUG3 = /^[a-z0-9][a-z0-9-]{1,62}$/;
|
|
1873
1977
|
var SECRET_NAME = /^[a-z][a-z0-9_]{1,127}$/;
|
|
1874
1978
|
function resolveSignupControl(input) {
|
|
1875
1979
|
if (!input) return null;
|
|
1876
|
-
if (!
|
|
1980
|
+
if (!SLUG3.test(input.sourceId)) {
|
|
1877
1981
|
throw new Error("defineChapter.signupControl.sourceId: must be a lowercase app slug");
|
|
1878
1982
|
}
|
|
1879
1983
|
if (input.stripeMode !== "test" && input.stripeMode !== "live") {
|
|
@@ -1887,12 +1991,12 @@ function resolveSignupControl(input) {
|
|
|
1887
1991
|
}
|
|
1888
1992
|
|
|
1889
1993
|
// src/config-member-content.ts
|
|
1890
|
-
var
|
|
1994
|
+
var SLUG4 = /^[a-z0-9][a-z0-9-]{1,62}$/;
|
|
1891
1995
|
var SECRET_NAME2 = /^[a-z][a-z0-9_]{1,127}$/;
|
|
1892
1996
|
function resolveMemberContent(input) {
|
|
1893
1997
|
if (!input) return null;
|
|
1894
1998
|
const parent = input.parent;
|
|
1895
|
-
if (parent && !
|
|
1999
|
+
if (parent && !SLUG4.test(parent.sourceId)) {
|
|
1896
2000
|
throw new Error("defineChapter.memberContent.parent.sourceId: must be a lowercase app slug");
|
|
1897
2001
|
}
|
|
1898
2002
|
const secretName = parent?.secretName?.trim() || "member_content_control_secret";
|
|
@@ -1907,7 +2011,7 @@ function resolveMemberContent(input) {
|
|
|
1907
2011
|
}
|
|
1908
2012
|
|
|
1909
2013
|
// src/config-builder-library.ts
|
|
1910
|
-
var
|
|
2014
|
+
var SLUG5 = /^[a-z0-9][a-z0-9-]{1,62}$/;
|
|
1911
2015
|
function resolveBuilderLibrary(mode, input, network = { targets: [], readers: [] }) {
|
|
1912
2016
|
if (!input) return null;
|
|
1913
2017
|
if (input.sources !== void 0 && !Array.isArray(input.sources)) {
|
|
@@ -1915,7 +2019,7 @@ function resolveBuilderLibrary(mode, input, network = { targets: [], readers: []
|
|
|
1915
2019
|
}
|
|
1916
2020
|
const seen = /* @__PURE__ */ new Set();
|
|
1917
2021
|
const sources = (input.sources ?? []).map((source, index) => {
|
|
1918
|
-
if (!source || typeof source !== "object" || !
|
|
2022
|
+
if (!source || typeof source !== "object" || !SLUG5.test(source.sourceId)) {
|
|
1919
2023
|
throw new Error(`defineChapter.builderLibrary.sources[${index}].sourceId: must be a lowercase app slug`);
|
|
1920
2024
|
}
|
|
1921
2025
|
if (source.sourceId === "built-not-found" && mode === "hub") {
|
|
@@ -1946,15 +2050,15 @@ function resolveBuilderLibrary(mode, input, network = { targets: [], readers: []
|
|
|
1946
2050
|
}
|
|
1947
2051
|
|
|
1948
2052
|
// src/config.ts
|
|
1949
|
-
var
|
|
2053
|
+
var SLUG6 = /^[a-z0-9][a-z0-9-]{1,62}$/;
|
|
1950
2054
|
function isResolvedCrm(x) {
|
|
1951
2055
|
return !!x && typeof x === "object" && "prepare" in x && typeof x.prepare === "function";
|
|
1952
2056
|
}
|
|
1953
2057
|
function defineChapter(config) {
|
|
1954
2058
|
if (!config || typeof config !== "object") throw new Error("defineChapter: a config object is required");
|
|
1955
|
-
const { id:
|
|
1956
|
-
if (typeof
|
|
1957
|
-
throw new Error(`defineChapter.id: must be a lowercase slug [a-z0-9-] (2-63 chars) \u2014 got ${JSON.stringify(
|
|
2059
|
+
const { id: id5, name } = config;
|
|
2060
|
+
if (typeof id5 !== "string" || !SLUG6.test(id5)) {
|
|
2061
|
+
throw new Error(`defineChapter.id: must be a lowercase slug [a-z0-9-] (2-63 chars) \u2014 got ${JSON.stringify(id5)}`);
|
|
1958
2062
|
}
|
|
1959
2063
|
if (typeof name !== "string" || name.trim() === "") throw new Error("defineChapter.name: a non-empty name is required");
|
|
1960
2064
|
const mode = config.mode ?? "chapter";
|
|
@@ -1977,6 +2081,11 @@ function defineChapter(config) {
|
|
|
1977
2081
|
const brand = { ...config.brand, wordmark: config.brand?.wordmark ?? name };
|
|
1978
2082
|
const copy = resolveChapterCopy(config.copy);
|
|
1979
2083
|
const network = resolveNetwork(config, crm);
|
|
2084
|
+
const networkPersonRegistry = resolveNetworkPersonRegistry(
|
|
2085
|
+
mode,
|
|
2086
|
+
config.networkPersonRegistry,
|
|
2087
|
+
network.targets.map((target) => target.id)
|
|
2088
|
+
);
|
|
1980
2089
|
const signupControl = resolveSignupControl(config.signupControl);
|
|
1981
2090
|
const memberContent = resolveMemberContent(config.memberContent);
|
|
1982
2091
|
const builderLibrary = resolveBuilderLibrary(mode, config.builderLibrary, network);
|
|
@@ -1995,7 +2104,8 @@ function defineChapter(config) {
|
|
|
1995
2104
|
Boolean(signupControl),
|
|
1996
2105
|
Boolean(memberContent),
|
|
1997
2106
|
Boolean(builderLibrary),
|
|
1998
|
-
network.targets.some((target) => target.admissionGrants)
|
|
2107
|
+
network.targets.some((target) => target.admissionGrants),
|
|
2108
|
+
Boolean(networkPersonRegistry)
|
|
1999
2109
|
);
|
|
2000
2110
|
const services = config.services ?? ["db", "calendar", "o11y"];
|
|
2001
2111
|
const account = config.account ?? "none";
|
|
@@ -2045,7 +2155,7 @@ function defineChapter(config) {
|
|
|
2045
2155
|
};
|
|
2046
2156
|
const chapter = {
|
|
2047
2157
|
config,
|
|
2048
|
-
id:
|
|
2158
|
+
id: id5,
|
|
2049
2159
|
name,
|
|
2050
2160
|
mode,
|
|
2051
2161
|
brand,
|
|
@@ -2054,6 +2164,7 @@ function defineChapter(config) {
|
|
|
2054
2164
|
signupControl,
|
|
2055
2165
|
memberContent,
|
|
2056
2166
|
builderLibrary,
|
|
2167
|
+
networkPersonRegistry,
|
|
2057
2168
|
formation,
|
|
2058
2169
|
crm,
|
|
2059
2170
|
auth,
|
|
@@ -2365,7 +2476,8 @@ function createChapterIntegration(chapter, options = {}) {
|
|
|
2365
2476
|
{ path: "/api/builder-library-control", expectedStatus: 401 },
|
|
2366
2477
|
{ path: "/api/admin/builder-library", expectedStatus: 401 },
|
|
2367
2478
|
{ path: "/api/admin/builder-library/manifest", expectedStatus: 401 }
|
|
2368
|
-
] : []
|
|
2479
|
+
] : [],
|
|
2480
|
+
...chapter.networkPersonRegistry ? [{ path: "/api/admin/network-person-registry", expectedStatus: 401 }] : []
|
|
2369
2481
|
],
|
|
2370
2482
|
runbooks
|
|
2371
2483
|
};
|
|
@@ -2373,7 +2485,7 @@ function createChapterIntegration(chapter, options = {}) {
|
|
|
2373
2485
|
|
|
2374
2486
|
// src/member-content-validation-helpers.ts
|
|
2375
2487
|
var ID = /^[a-z][a-z0-9-]{0,79}$/;
|
|
2376
|
-
var
|
|
2488
|
+
var SLUG7 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
2377
2489
|
var ROOT_KEYS = /* @__PURE__ */ new Set(["schemaVersion", "revision", "generatedAt", "source", "target", "pages", "upsellOverrides"]);
|
|
2378
2490
|
var SOURCE_KEYS = /* @__PURE__ */ new Set(["type", "appId"]);
|
|
2379
2491
|
var TARGET_KEYS = /* @__PURE__ */ new Set(["chapterId", "environment"]);
|
|
@@ -2479,14 +2591,14 @@ function validateMemberContentDocument(input, options = {}) {
|
|
|
2479
2591
|
continue;
|
|
2480
2592
|
}
|
|
2481
2593
|
unknownKeys(raw, PAGE_KEYS, path, errors);
|
|
2482
|
-
const
|
|
2594
|
+
const id5 = textValue(raw.id, `${path}.id`, errors, 80, true) ?? "";
|
|
2483
2595
|
const slug = textValue(raw.slug, `${path}.slug`, errors, 120, true) ?? "";
|
|
2484
2596
|
const title = textValue(raw.title, `${path}.title`, errors, MAX_TEXT, true) ?? "";
|
|
2485
|
-
if (
|
|
2486
|
-
if (slug && !
|
|
2487
|
-
if (ids.has(
|
|
2597
|
+
if (id5 && !ID.test(id5)) errors.push(`${path}.id must be a lowercase kebab-case id`);
|
|
2598
|
+
if (slug && !SLUG7.test(slug)) errors.push(`${path}.slug must be a lowercase URL slug`);
|
|
2599
|
+
if (ids.has(id5) || knownParentIds.has(id5)) errors.push(`${path}.id duplicates page "${id5}"`);
|
|
2488
2600
|
if (slugs.has(slug) || (options.parentPages ?? []).some((page) => page.slug === slug)) errors.push(`${path}.slug duplicates "${slug}"`);
|
|
2489
|
-
ids.add(
|
|
2601
|
+
ids.add(id5);
|
|
2490
2602
|
slugs.add(slug);
|
|
2491
2603
|
const navRaw = record(raw.navigation);
|
|
2492
2604
|
let navigation = { section: "General", order: index };
|
|
@@ -2542,7 +2654,7 @@ function validateMemberContentDocument(input, options = {}) {
|
|
|
2542
2654
|
else if (owner === "chapter") upsell = { owner, ...offer ? { offer } : {} };
|
|
2543
2655
|
}
|
|
2544
2656
|
}
|
|
2545
|
-
pages.push({ id:
|
|
2657
|
+
pages.push({ id: id5, slug, title, ...summary ? { summary } : {}, navigation, audience, ...teaserMarkdown ? { teaserMarkdown } : {}, bodyMarkdown, ...upsell ? { upsell } : {} });
|
|
2546
2658
|
}
|
|
2547
2659
|
const allIds = /* @__PURE__ */ new Set([...knownParentIds, ...ids]);
|
|
2548
2660
|
for (const [index, page] of pages.entries()) {
|
|
@@ -2748,8 +2860,8 @@ function resourceValue(value, path, errors) {
|
|
|
2748
2860
|
return null;
|
|
2749
2861
|
}
|
|
2750
2862
|
unknownKeys2(raw, RESOURCE_KEYS, path, errors);
|
|
2751
|
-
const
|
|
2752
|
-
if (
|
|
2863
|
+
const id5 = text(raw.id, `${path}.id`, errors, 80) ?? "";
|
|
2864
|
+
if (id5 && !ID2.test(id5)) errors.push(`${path}.id must be lowercase kebab-case`);
|
|
2753
2865
|
const kind = text(raw.kind, `${path}.kind`, errors) ?? "";
|
|
2754
2866
|
if (!KINDS.has(kind)) errors.push(`${path}.kind is unsupported`);
|
|
2755
2867
|
const title = text(raw.title, `${path}.title`, errors, 240) ?? "";
|
|
@@ -2806,7 +2918,7 @@ function resourceValue(value, path, errors) {
|
|
|
2806
2918
|
updatedAt: integer(provenanceRaw?.updatedAt, `${path}.provenance.updatedAt`, errors, 0),
|
|
2807
2919
|
...promotedFrom ? { promotedFrom } : {}
|
|
2808
2920
|
};
|
|
2809
|
-
return { id:
|
|
2921
|
+
return { id: id5, kind, title, ...summary ? { summary } : {}, tags, scope, status, revision, ...bodyMarkdown ? { bodyMarkdown } : {}, ...url ? { url } : {}, ...brandAsset ? { brandAsset } : {}, provenance };
|
|
2810
2922
|
}
|
|
2811
2923
|
function validateBuilderLibraryDocument(value, options = {}) {
|
|
2812
2924
|
const errors = [];
|
|
@@ -2837,7 +2949,7 @@ function validateBuilderLibraryDocument(value, options = {}) {
|
|
|
2837
2949
|
const inputs = Array.isArray(raw.resources) ? raw.resources : [];
|
|
2838
2950
|
if (inputs.length > MAX_RESOURCES) errors.push(`document.resources may contain at most ${MAX_RESOURCES} items`);
|
|
2839
2951
|
const resources = inputs.map((item, index) => resourceValue(item, `document.resources[${index}]`, errors)).filter(Boolean);
|
|
2840
|
-
const ids = resources.map(({ id:
|
|
2952
|
+
const ids = resources.map(({ id: id5 }) => id5);
|
|
2841
2953
|
if (new Set(ids).size !== ids.length) errors.push("document.resources ids must be unique");
|
|
2842
2954
|
for (const resource of resources) {
|
|
2843
2955
|
if (sourceType === "chapter" && (resource.scope.kind !== "chapter" || resource.scope.chapterId !== sourceAppId)) {
|
|
@@ -2992,9 +3104,9 @@ async function sendTemplated(deps, input) {
|
|
|
2992
3104
|
error = e instanceof Error ? e.message : String(e);
|
|
2993
3105
|
}
|
|
2994
3106
|
}
|
|
2995
|
-
const
|
|
3107
|
+
const id5 = deps.newId();
|
|
2996
3108
|
const row = {
|
|
2997
|
-
id:
|
|
3109
|
+
id: id5,
|
|
2998
3110
|
groupId: input.group.id,
|
|
2999
3111
|
to: decision.to,
|
|
3000
3112
|
template: input.template,
|
|
@@ -3008,7 +3120,7 @@ async function sendTemplated(deps, input) {
|
|
|
3008
3120
|
...messageId ? { messageId } : {},
|
|
3009
3121
|
...error ? { error } : {}
|
|
3010
3122
|
};
|
|
3011
|
-
await deps.db.transact([{ t: "update", ns: "emailLog", id:
|
|
3123
|
+
await deps.db.transact([{ t: "update", ns: "emailLog", id: id5, attrs: row }], error ? void 0 : { mutationId: `email:${input.dedupeKey}` });
|
|
3012
3124
|
return error ? { sent: false, reason: error } : { sent: true };
|
|
3013
3125
|
}
|
|
3014
3126
|
function emailGroupFrom(row) {
|
|
@@ -3196,14 +3308,14 @@ function validateAdmissionGrantDocument(input) {
|
|
|
3196
3308
|
const seenEmails = /* @__PURE__ */ new Set();
|
|
3197
3309
|
for (const [index, raw] of rawGrants.slice(0, MAX_GRANTS).entries()) {
|
|
3198
3310
|
const grant = raw && typeof raw === "object" ? raw : {};
|
|
3199
|
-
const
|
|
3311
|
+
const id5 = typeof grant.id === "string" ? grant.id : "";
|
|
3200
3312
|
const email = typeof grant.email === "string" ? grant.email.trim() : "";
|
|
3201
3313
|
const normalized = normalizeAdmissionEmail(email);
|
|
3202
3314
|
const decision = grant.decision;
|
|
3203
3315
|
const note = typeof grant.note === "string" ? grant.note.trim() : void 0;
|
|
3204
3316
|
const expiresAt = grant.expiresAt === void 0 ? void 0 : Number(grant.expiresAt);
|
|
3205
|
-
if (!ID3.test(
|
|
3206
|
-
if (seenIds.has(
|
|
3317
|
+
if (!ID3.test(id5)) errors.push(`document.grants[${index}].id must be an identifier`);
|
|
3318
|
+
if (seenIds.has(id5)) errors.push(`document.grants repeats id "${id5}"`);
|
|
3207
3319
|
if (!isAdmissionEmail(normalized)) errors.push(`document.grants[${index}].email must be valid`);
|
|
3208
3320
|
if (seenEmails.has(normalized)) errors.push(`document.grants repeats email "${normalized}"`);
|
|
3209
3321
|
if (decision !== "waive_interview" && decision !== "require_interview") {
|
|
@@ -3213,10 +3325,10 @@ function validateAdmissionGrantDocument(input) {
|
|
|
3213
3325
|
if (expiresAt !== void 0 && (!Number.isFinite(expiresAt) || expiresAt <= 0)) {
|
|
3214
3326
|
errors.push(`document.grants[${index}].expiresAt must be epoch milliseconds`);
|
|
3215
3327
|
}
|
|
3216
|
-
seenIds.add(
|
|
3328
|
+
seenIds.add(id5);
|
|
3217
3329
|
seenEmails.add(normalized);
|
|
3218
3330
|
grants.push({
|
|
3219
|
-
id:
|
|
3331
|
+
id: id5,
|
|
3220
3332
|
email,
|
|
3221
3333
|
decision,
|
|
3222
3334
|
...note ? { note } : {},
|
|
@@ -3287,8 +3399,8 @@ async function materializeAdmissionGrants(db, envelope, previous, receivedAt) {
|
|
|
3287
3399
|
const incomingIds = new Set(document.grants.map((grant) => `admission:parent:${document.source.appId}:${grant.id}`));
|
|
3288
3400
|
const ops = [];
|
|
3289
3401
|
for (const row of current) {
|
|
3290
|
-
const
|
|
3291
|
-
if (
|
|
3402
|
+
const id5 = String(row.id ?? "");
|
|
3403
|
+
if (id5 && !incomingIds.has(id5)) ops.push({ t: "update", ns: "admissionGrants", id: id5, attrs: {
|
|
3292
3404
|
active: false,
|
|
3293
3405
|
revokedAt: receivedAt,
|
|
3294
3406
|
revokedBy: document.source.actor,
|
|
@@ -3297,10 +3409,10 @@ async function materializeAdmissionGrants(db, envelope, previous, receivedAt) {
|
|
|
3297
3409
|
} });
|
|
3298
3410
|
}
|
|
3299
3411
|
for (const grant of document.grants) {
|
|
3300
|
-
const
|
|
3301
|
-
const existing = current.find((row) => row.id ===
|
|
3302
|
-
ops.push({ t: "update", ns: "admissionGrants", id:
|
|
3303
|
-
id:
|
|
3412
|
+
const id5 = `admission:parent:${document.source.appId}:${grant.id}`;
|
|
3413
|
+
const existing = current.find((row) => row.id === id5);
|
|
3414
|
+
ops.push({ t: "update", ns: "admissionGrants", id: id5, attrs: {
|
|
3415
|
+
id: id5,
|
|
3304
3416
|
sourceGrantId: grant.id,
|
|
3305
3417
|
sourceScope: "parent",
|
|
3306
3418
|
sourceId: document.source.appId,
|
|
@@ -3321,7 +3433,7 @@ async function materializeAdmissionGrants(db, envelope, previous, receivedAt) {
|
|
|
3321
3433
|
...!grant.note && existing?.note !== void 0 ? ["note"] : [],
|
|
3322
3434
|
...grant.expiresAt === void 0 && existing?.expiresAt !== void 0 ? ["expiresAt"] : []
|
|
3323
3435
|
];
|
|
3324
|
-
if (retract.length) ops.push({ t: "retract", ns: "admissionGrants", id:
|
|
3436
|
+
if (retract.length) ops.push({ t: "retract", ns: "admissionGrants", id: id5, attrs: retract });
|
|
3325
3437
|
}
|
|
3326
3438
|
if (previous?.active) ops.push({ t: "update", ns: "admissionGrantRevisions", id: previous.id, attrs: { active: false } });
|
|
3327
3439
|
const revisionId = `admission-revision:${document.source.appId}:${document.target.environment}:${document.revision}`;
|
|
@@ -3391,10 +3503,10 @@ function validateGiftOfferCatalog(input, tierIds) {
|
|
|
3391
3503
|
}
|
|
3392
3504
|
const allowed2 = /* @__PURE__ */ new Set(["id", "target", "billingMode", "stripePriceId", "priceCents", "currency", "redemptionLifetimeHours", "activeFrom", "activeUntil", "title", "description", "ctaLabel"]);
|
|
3393
3505
|
for (const key of Object.keys(item)) if (!allowed2.has(key)) errors.push(`${path}.${key} is not supported`);
|
|
3394
|
-
const
|
|
3395
|
-
if (
|
|
3396
|
-
if (ids.has(
|
|
3397
|
-
ids.add(
|
|
3506
|
+
const id5 = text2(item.id, `${path}.id`, errors, 80);
|
|
3507
|
+
if (id5 && !ID4.test(id5)) errors.push(`${path}.id must be a lowercase kebab-case id`);
|
|
3508
|
+
if (ids.has(id5)) errors.push(`${path}.id duplicates "${id5}"`);
|
|
3509
|
+
ids.add(id5);
|
|
3398
3510
|
const targetRaw = record3(item.target);
|
|
3399
3511
|
let target = { type: "entitlement", entitlementKey: "invalid" };
|
|
3400
3512
|
if (targetRaw?.type === "tier") {
|
|
@@ -3420,7 +3532,7 @@ function validateGiftOfferCatalog(input, tierIds) {
|
|
|
3420
3532
|
if (activeUntil !== void 0 && (!Number.isSafeInteger(activeUntil) || activeUntil < 1)) errors.push(`${path}.activeUntil must be epoch milliseconds`);
|
|
3421
3533
|
if (activeFrom !== void 0 && activeUntil !== void 0 && activeUntil <= activeFrom) errors.push(`${path}.activeUntil must follow activeFrom`);
|
|
3422
3534
|
offers.push({
|
|
3423
|
-
id:
|
|
3535
|
+
id: id5,
|
|
3424
3536
|
target,
|
|
3425
3537
|
billingMode: item.billingMode,
|
|
3426
3538
|
stripePriceId,
|
|
@@ -3833,9 +3945,9 @@ async function updateClerkUserMetadataByEmail(secretKey, email, input, fetchImpl
|
|
|
3833
3945
|
const found = await fetchImpl(`https://api.clerk.com/v1/users?email_address=${encodeURIComponent(email)}&limit=1`, { headers: auth });
|
|
3834
3946
|
if (!found.ok) return false;
|
|
3835
3947
|
const users = await found.json().catch(() => null);
|
|
3836
|
-
const
|
|
3837
|
-
if (!
|
|
3838
|
-
return updateClerkUserMetadata(secretKey,
|
|
3948
|
+
const id5 = Array.isArray(users) && typeof users[0]?.id === "string" ? users[0].id : void 0;
|
|
3949
|
+
if (!id5) return false;
|
|
3950
|
+
return updateClerkUserMetadata(secretKey, id5, input, fetchImpl);
|
|
3839
3951
|
}
|
|
3840
3952
|
async function createClerkUser(secretKey, input, fetchImpl = fetch) {
|
|
3841
3953
|
const { path, body } = clerkUserRequest(input);
|
|
@@ -3898,8 +4010,8 @@ async function clerkGetUserByEmail(secretKey, email, fetchImpl = fetch) {
|
|
|
3898
4010
|
const user = Array.isArray(data) ? data[0] : void 0;
|
|
3899
4011
|
return user ? toRecord(user) : null;
|
|
3900
4012
|
}
|
|
3901
|
-
async function clerkGetUser(secretKey,
|
|
3902
|
-
const data = await clerkGet(`/v1/users/${encodeURIComponent(
|
|
4013
|
+
async function clerkGetUser(secretKey, id5, fetchImpl = fetch) {
|
|
4014
|
+
const data = await clerkGet(`/v1/users/${encodeURIComponent(id5)}`, secretKey, fetchImpl).catch(() => null);
|
|
3903
4015
|
return data ? toRecord(data) : null;
|
|
3904
4016
|
}
|
|
3905
4017
|
async function clerkListUsers(secretKey, fetchImpl = fetch) {
|
|
@@ -3915,8 +4027,8 @@ async function clerkListUsers(secretKey, fetchImpl = fetch) {
|
|
|
3915
4027
|
}
|
|
3916
4028
|
return out;
|
|
3917
4029
|
}
|
|
3918
|
-
async function clerkSetRole(secretKey,
|
|
3919
|
-
const res = await fetchImpl(`${CLERK_API}/v1/users/${encodeURIComponent(
|
|
4030
|
+
async function clerkSetRole(secretKey, id5, role, fetchImpl = fetch) {
|
|
4031
|
+
const res = await fetchImpl(`${CLERK_API}/v1/users/${encodeURIComponent(id5)}/metadata`, {
|
|
3920
4032
|
method: "PATCH",
|
|
3921
4033
|
headers: { authorization: `Bearer ${secretKey}`, "content-type": "application/json" },
|
|
3922
4034
|
body: JSON.stringify({ public_metadata: { role } })
|
|
@@ -4482,7 +4594,7 @@ function membershipPageDocument(input, options = {}) {
|
|
|
4482
4594
|
}
|
|
4483
4595
|
|
|
4484
4596
|
// src/signup-control-validate.ts
|
|
4485
|
-
var
|
|
4597
|
+
var SLUG8 = /^[a-z0-9][a-z0-9-]{1,62}$/;
|
|
4486
4598
|
var ENVIRONMENT = /^[a-z][a-z0-9_-]{0,62}$/;
|
|
4487
4599
|
var TIER = /^[a-z][a-z0-9-]{0,79}$/;
|
|
4488
4600
|
var PRICE2 = /^price_[A-Za-z0-9]{12,}$/;
|
|
@@ -4528,10 +4640,10 @@ function tiersOf(value, errors) {
|
|
|
4528
4640
|
return [];
|
|
4529
4641
|
}
|
|
4530
4642
|
unknownKeys3(item, TIER_KEYS2, path, errors);
|
|
4531
|
-
const
|
|
4532
|
-
if (
|
|
4533
|
-
if (seen.has(
|
|
4534
|
-
seen.add(
|
|
4643
|
+
const id5 = text3(item.id, `${path}.id`, errors, 80);
|
|
4644
|
+
if (id5 && !TIER.test(id5)) errors.push(`${path}.id must be a lowercase kebab-case id`);
|
|
4645
|
+
if (seen.has(id5)) errors.push(`${path}.id duplicates "${id5}"`);
|
|
4646
|
+
seen.add(id5);
|
|
4535
4647
|
const name = text3(item.name, `${path}.name`, errors, 160);
|
|
4536
4648
|
if (typeof item.available !== "boolean") errors.push(`${path}.available must be boolean`);
|
|
4537
4649
|
if (!Number.isInteger(item.sortOrder) || Number(item.sortOrder) < 0) errors.push(`${path}.sortOrder must be a non-negative integer`);
|
|
@@ -4546,7 +4658,7 @@ function tiersOf(value, errors) {
|
|
|
4546
4658
|
}
|
|
4547
4659
|
const blurb = item.blurb === void 0 ? void 0 : text3(item.blurb, `${path}.blurb`, errors, 4e3);
|
|
4548
4660
|
return [{
|
|
4549
|
-
id:
|
|
4661
|
+
id: id5,
|
|
4550
4662
|
name,
|
|
4551
4663
|
available: item.available === true,
|
|
4552
4664
|
sortOrder: Number(item.sortOrder) || 0,
|
|
@@ -4641,8 +4753,8 @@ function validateSignupControlDocument(input) {
|
|
|
4641
4753
|
const appId = text3(source?.appId, "document.source.appId", errors, 63);
|
|
4642
4754
|
const chapterId = text3(target?.chapterId, "document.target.chapterId", errors, 63);
|
|
4643
4755
|
const environment = text3(target?.environment, "document.target.environment", errors, 63);
|
|
4644
|
-
if (appId && !
|
|
4645
|
-
if (chapterId && !
|
|
4756
|
+
if (appId && !SLUG8.test(appId)) errors.push("document.source.appId must be a lowercase app slug");
|
|
4757
|
+
if (chapterId && !SLUG8.test(chapterId)) errors.push("document.target.chapterId must be a lowercase app slug");
|
|
4646
4758
|
if (environment && !ENVIRONMENT.test(environment)) errors.push("document.target.environment is invalid");
|
|
4647
4759
|
if (target?.stripeMode !== "test" && target?.stripeMode !== "live") errors.push("document.target.stripeMode must be test or live");
|
|
4648
4760
|
const tiers2 = tiersOf(root.tiers, errors);
|
|
@@ -4919,7 +5031,7 @@ var exclusions = (chapterId, paidTierIds) => [
|
|
|
4919
5031
|
id: chapterId,
|
|
4920
5032
|
reason: "provider_identity",
|
|
4921
5033
|
paths: [
|
|
4922
|
-
...paidTierIds.map((
|
|
5034
|
+
...paidTierIds.map((id5) => `tiers[${id5}].stripePriceId`),
|
|
4923
5035
|
"groups.stripePublishableKey",
|
|
4924
5036
|
"applications.stripeCustomerId",
|
|
4925
5037
|
"applications.stripeSubscriptionId",
|
|
@@ -4961,9 +5073,9 @@ async function exportChapterPromotion(input) {
|
|
|
4961
5073
|
sourceIds: [`signup-control:${document.revision}`, document.source.appId, document.target.chapterId].sort(),
|
|
4962
5074
|
receiptDigests: [input.digest]
|
|
4963
5075
|
};
|
|
4964
|
-
const artifact = (kind,
|
|
5076
|
+
const artifact = (kind, id5, content) => ({
|
|
4965
5077
|
kind,
|
|
4966
|
-
id:
|
|
5078
|
+
id: id5,
|
|
4967
5079
|
sourceRevision: revision,
|
|
4968
5080
|
provenance: promotionProvenance,
|
|
4969
5081
|
content: (0, import_promotion.canonicalPromotionValue)(content)
|
|
@@ -5002,7 +5114,7 @@ async function exportChapterPromotion(input) {
|
|
|
5002
5114
|
}
|
|
5003
5115
|
|
|
5004
5116
|
// src/member-system-authority.ts
|
|
5005
|
-
var rows2 = (group) => group.fields.map((
|
|
5117
|
+
var rows2 = (group) => group.fields.map((id5) => ({ ...group, id: id5 }));
|
|
5006
5118
|
var MEMBER_SYSTEM_AUTHORITY_MATRIX = [
|
|
5007
5119
|
...rows2({
|
|
5008
5120
|
scope: "network",
|