@odla-ai/chapter 0.42.1 → 0.42.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/dist/{chunk-JXFYOUDL.js → chunk-4HS2JPE2.js} +11 -1
- package/dist/chunk-4HS2JPE2.js.map +1 -0
- package/dist/{chunk-MMDWXTJU.js → chunk-7MEVZEL2.js} +49 -3
- package/dist/chunk-7MEVZEL2.js.map +1 -0
- package/dist/{chunk-S7CND3R5.js → chunk-VWDEHUNI.js} +2 -2
- package/dist/{copy-context-BNUzbL5g.d.ts → copy-context-Bh1EZvCg.d.ts} +10 -2
- package/dist/index.cjs +98 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -4
- package/dist/index.d.ts +41 -4
- package/dist/index.js +98 -10
- package/dist/index.js.map +1 -1
- package/dist/ui/admin/index.d.ts +14 -3
- package/dist/ui/admin/index.js +4 -2
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +5 -3
- package/dist/ui/member/index.d.ts +2 -2
- package/dist/ui/member/index.js +2 -2
- package/dist/worker/index.cjs +551 -156
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +56 -3
- package/dist/worker/index.d.ts +56 -3
- package/dist/worker/index.js +527 -132
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-JXFYOUDL.js.map +0 -1
- package/dist/chunk-MMDWXTJU.js.map +0 -1
- /package/dist/{chunk-S7CND3R5.js.map → chunk-VWDEHUNI.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
formatChapterCopy,
|
|
3
3
|
useChapterCopy
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4HS2JPE2.js";
|
|
5
5
|
import {
|
|
6
6
|
collectFormFields
|
|
7
7
|
} from "./chunk-IVXVECKR.js";
|
|
@@ -1524,4 +1524,4 @@ export {
|
|
|
1524
1524
|
membershipApplicationHref,
|
|
1525
1525
|
MembershipCards
|
|
1526
1526
|
};
|
|
1527
|
-
//# sourceMappingURL=chunk-
|
|
1527
|
+
//# sourceMappingURL=chunk-VWDEHUNI.js.map
|
|
@@ -24,7 +24,7 @@ type TextFields$1<Key extends string> = {
|
|
|
24
24
|
[Field in Key]: string;
|
|
25
25
|
};
|
|
26
26
|
/** User-visible language for sharing, delivery state, and leader rollups. */
|
|
27
|
-
type AdminNetworkCopy = TextFields$1<"title" | "allowlistDescription" | "sharing" | "shareWith" | "shared" | "shareFailed" | "deliveryFailed" | "loadingRollup" | "loadRollupFailed" | "overview" | "configuredFollowers" | "reachableFollowers" | "recordsAcrossFollowers" | "noFollowers" | "followers" | "available" | "unavailable" | "recordTotals" | "noRecordTotals">;
|
|
27
|
+
type AdminNetworkCopy = TextFields$1<"title" | "allowlistDescription" | "sharing" | "shareWith" | "shared" | "shareFailed" | "deliveryFailed" | "loadingRollup" | "loadRollupFailed" | "overview" | "configuredFollowers" | "reachableFollowers" | "recordsAcrossFollowers" | "noFollowers" | "followers" | "available" | "unavailable" | "transportReachable" | "transportUnavailable" | "transportNotChecked" | "bindingTransport" | "urlTransport" | "activeConfiguration" | "noActiveConfiguration" | "publicSiteAvailable" | "publicSiteUnavailable" | "publicSiteNotChecked" | "recordTotals" | "noRecordTotals">;
|
|
28
28
|
|
|
29
29
|
type TextFields<Key extends string> = {
|
|
30
30
|
[Field in Key]: string;
|
|
@@ -193,6 +193,9 @@ interface ChapterNetworkTarget {
|
|
|
193
193
|
/** Record types on which this leader permits remote lifecycle transitions.
|
|
194
194
|
* The follower must independently opt in and remains pipeline authority. */
|
|
195
195
|
stageTransitions?: readonly string[];
|
|
196
|
+
/** Allow package-owned desired admission decisions for existing leader CRM
|
|
197
|
+
* people to be delivered to this target. Omitted means default deny. */
|
|
198
|
+
admissionGrants?: boolean;
|
|
196
199
|
}
|
|
197
200
|
/** One signed peer allowed to browse a privacy-bounded projection of this
|
|
198
201
|
* site's CRM. The follower owns this allowlist; a leader target declaration
|
|
@@ -202,7 +205,7 @@ interface ChapterNetworkReader {
|
|
|
202
205
|
id: string;
|
|
203
206
|
/** Per-record-type field allowlist. Omitted types and fields never leave
|
|
204
207
|
* this site. Record id, name, stage, and timestamps are bounded metadata. */
|
|
205
|
-
fields
|
|
208
|
+
fields?: Record<string, readonly string[]>;
|
|
206
209
|
/** Record types on which this reader may append an explicitly shared note.
|
|
207
210
|
* Omitted by default: browse permission never silently grants write access.
|
|
208
211
|
* Shared notes land in the follower CRM activity feed. */
|
|
@@ -214,6 +217,9 @@ interface ChapterNetworkReader {
|
|
|
214
217
|
/** Local CRM record types on which this reader may request a lifecycle
|
|
215
218
|
* transition. Chapter still enforces the local pipeline and gates. */
|
|
216
219
|
stageTransitions?: readonly string[];
|
|
220
|
+
/** Accept signed desired admission decisions from this reader. Independent
|
|
221
|
+
* of record browsing; an admission-only reader may omit `fields`. */
|
|
222
|
+
admissionGrants?: boolean;
|
|
217
223
|
}
|
|
218
224
|
/** Leader/follower network configuration. A follower needs no code config to
|
|
219
225
|
* receive pushed records. It must explicitly declare `readers` before any peer
|
|
@@ -258,6 +264,7 @@ interface ResolvedNetworkTarget {
|
|
|
258
264
|
sharedNotes: readonly string[];
|
|
259
265
|
editableFields: Record<string, readonly string[]>;
|
|
260
266
|
stageTransitions: readonly string[];
|
|
267
|
+
admissionGrants?: boolean;
|
|
261
268
|
}
|
|
262
269
|
/** A validated follower-owned record projection for one signed reader. */
|
|
263
270
|
interface ResolvedNetworkReader {
|
|
@@ -266,6 +273,7 @@ interface ResolvedNetworkReader {
|
|
|
266
273
|
sharedNotes: readonly string[];
|
|
267
274
|
editableFields: Record<string, readonly string[]>;
|
|
268
275
|
stageTransitions: readonly string[];
|
|
276
|
+
admissionGrants?: boolean;
|
|
269
277
|
}
|
|
270
278
|
/** Fully-resolved leader network configuration. */
|
|
271
279
|
interface ResolvedNetwork {
|
package/dist/index.cjs
CHANGED
|
@@ -486,6 +486,50 @@ var admissionGrantRevisionsEntity = {
|
|
|
486
486
|
receivedAt: attr2("number", { indexed: true })
|
|
487
487
|
}
|
|
488
488
|
};
|
|
489
|
+
var leaderAdmissionAssignmentsEntity = {
|
|
490
|
+
attrs: {
|
|
491
|
+
id: id(),
|
|
492
|
+
targetId: attr2("string", { indexed: true }),
|
|
493
|
+
personId: attr2("string", { indexed: true }),
|
|
494
|
+
grantId: attr2("string", { indexed: true }),
|
|
495
|
+
decision: attr2("string", { indexed: true }),
|
|
496
|
+
note: attr2("string", { optional: true }),
|
|
497
|
+
expiresAt: attr2("number", { optional: true, indexed: true }),
|
|
498
|
+
active: attr2("boolean", { indexed: true }),
|
|
499
|
+
lastMutationId: attr2("string", { indexed: true }),
|
|
500
|
+
lastRequestDigest: attr2("string"),
|
|
501
|
+
createdAt: attr2("number", { indexed: true }),
|
|
502
|
+
createdBy: attr2("string", { indexed: true }),
|
|
503
|
+
updatedAt: attr2("number", { indexed: true }),
|
|
504
|
+
updatedBy: attr2("string", { indexed: true })
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
var leaderAdmissionDeliveriesEntity = {
|
|
508
|
+
attrs: {
|
|
509
|
+
id: id(),
|
|
510
|
+
targetId: attr2("string", { indexed: true }),
|
|
511
|
+
environment: attr2("string", { indexed: true }),
|
|
512
|
+
revision: attr2("number", { indexed: true }),
|
|
513
|
+
digest: attr2("string", { indexed: true }),
|
|
514
|
+
envelope: attr2("json"),
|
|
515
|
+
status: attr2("string", { indexed: true }),
|
|
516
|
+
attempts: attr2("number", { indexed: true }),
|
|
517
|
+
lastAttemptAt: attr2("number", { optional: true, indexed: true }),
|
|
518
|
+
lastError: attr2("string", { optional: true }),
|
|
519
|
+
acknowledgedAt: attr2("number", { optional: true, indexed: true }),
|
|
520
|
+
updatedAt: attr2("number", { indexed: true })
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
var leaderAdmissionMutationsEntity = {
|
|
524
|
+
attrs: {
|
|
525
|
+
id: id(),
|
|
526
|
+
targetId: attr2("string", { indexed: true }),
|
|
527
|
+
personId: attr2("string", { indexed: true }),
|
|
528
|
+
requestDigest: attr2("string", { indexed: true }),
|
|
529
|
+
revision: attr2("number", { indexed: true }),
|
|
530
|
+
createdAt: attr2("number", { indexed: true })
|
|
531
|
+
}
|
|
532
|
+
};
|
|
489
533
|
|
|
490
534
|
// src/schema-gifts.ts
|
|
491
535
|
var attr3 = (type, flags = {}) => ({
|
|
@@ -757,7 +801,7 @@ var emailLog = {
|
|
|
757
801
|
sentAt: attr4("number", { indexed: true })
|
|
758
802
|
}
|
|
759
803
|
};
|
|
760
|
-
function chapterDb(mode, auth, includeNetworkNotes = false, application = resolveApplication(void 0), includeSignupControl = false, includeMemberContent = false, includeBuilderLibrary = false) {
|
|
804
|
+
function chapterDb(mode, auth, includeNetworkNotes = false, application = resolveApplication(void 0), includeSignupControl = false, includeMemberContent = false, includeBuilderLibrary = false, includeLeaderAdmissions = false) {
|
|
761
805
|
const entities = {};
|
|
762
806
|
if (mode === "chapter") {
|
|
763
807
|
entities.applications = applicationsFor(application);
|
|
@@ -785,6 +829,11 @@ function chapterDb(mode, auth, includeNetworkNotes = false, application = resolv
|
|
|
785
829
|
entities.builderLibraryControls = builderLibraryControls;
|
|
786
830
|
entities.builderLibraryLocal = builderLibraryLocal;
|
|
787
831
|
}
|
|
832
|
+
if (includeLeaderAdmissions) {
|
|
833
|
+
entities.leaderAdmissionAssignments = leaderAdmissionAssignmentsEntity;
|
|
834
|
+
entities.leaderAdmissionDeliveries = leaderAdmissionDeliveriesEntity;
|
|
835
|
+
entities.leaderAdmissionMutations = leaderAdmissionMutationsEntity;
|
|
836
|
+
}
|
|
788
837
|
const schema = { entities, links: {} };
|
|
789
838
|
const rules = {};
|
|
790
839
|
for (const ns of Object.keys(entities)) {
|
|
@@ -1214,6 +1263,16 @@ var DEFAULT_ADMIN_COPY = {
|
|
|
1214
1263
|
followers: "Followers",
|
|
1215
1264
|
available: "available",
|
|
1216
1265
|
unavailable: "unavailable",
|
|
1266
|
+
transportReachable: "transport reachable",
|
|
1267
|
+
transportUnavailable: "transport unavailable",
|
|
1268
|
+
transportNotChecked: "transport not checked",
|
|
1269
|
+
bindingTransport: "service binding {binding}",
|
|
1270
|
+
urlTransport: "public URL transport",
|
|
1271
|
+
activeConfiguration: "active configuration r{revision}",
|
|
1272
|
+
noActiveConfiguration: "no active managed configuration",
|
|
1273
|
+
publicSiteAvailable: "public site reachable",
|
|
1274
|
+
publicSiteUnavailable: "public site unavailable",
|
|
1275
|
+
publicSiteNotChecked: "public site not probed",
|
|
1217
1276
|
recordTotals: "Portfolio records",
|
|
1218
1277
|
noRecordTotals: "No aggregate records are available yet."
|
|
1219
1278
|
},
|
|
@@ -1591,6 +1650,13 @@ function validateStageTransitions(opts) {
|
|
|
1591
1650
|
throw new Error(`${opts.path}: must contain unique, readable CRM types with pipelines`);
|
|
1592
1651
|
}
|
|
1593
1652
|
}
|
|
1653
|
+
function validateAdmissionCapability(path, enabled, crm) {
|
|
1654
|
+
if (!enabled) return;
|
|
1655
|
+
const person = crm.config.types.person;
|
|
1656
|
+
if (!person?.emailField || person.fields[person.emailField]?.type !== "email") {
|
|
1657
|
+
throw new Error(`${path}: requires a CRM person type with an emailField`);
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1594
1660
|
function resolveNetwork(config, crm) {
|
|
1595
1661
|
const seen = /* @__PURE__ */ new Set();
|
|
1596
1662
|
const targets = [];
|
|
@@ -1664,6 +1730,11 @@ function resolveNetwork(config, crm) {
|
|
|
1664
1730
|
crm,
|
|
1665
1731
|
readable: readableFields
|
|
1666
1732
|
});
|
|
1733
|
+
validateAdmissionCapability(
|
|
1734
|
+
`defineChapter.network.targets.${target.id}.admissionGrants`,
|
|
1735
|
+
target.admissionGrants,
|
|
1736
|
+
crm
|
|
1737
|
+
);
|
|
1667
1738
|
targets.push({
|
|
1668
1739
|
id: target.id,
|
|
1669
1740
|
name: target.name?.trim() || target.id,
|
|
@@ -1673,7 +1744,8 @@ function resolveNetwork(config, crm) {
|
|
|
1673
1744
|
...fields ? { fields } : {},
|
|
1674
1745
|
sharedNotes,
|
|
1675
1746
|
editableFields,
|
|
1676
|
-
stageTransitions
|
|
1747
|
+
stageTransitions,
|
|
1748
|
+
...target.admissionGrants === true ? { admissionGrants: true } : {}
|
|
1677
1749
|
});
|
|
1678
1750
|
}
|
|
1679
1751
|
const readerIds = /* @__PURE__ */ new Set();
|
|
@@ -1686,9 +1758,12 @@ function resolveNetwork(config, crm) {
|
|
|
1686
1758
|
throw new Error(`defineChapter.network.readers: duplicate reader "${reader.id}"`);
|
|
1687
1759
|
}
|
|
1688
1760
|
readerIds.add(reader.id);
|
|
1689
|
-
const
|
|
1690
|
-
|
|
1691
|
-
|
|
1761
|
+
const readerFields = reader.fields ?? {};
|
|
1762
|
+
const entries = Object.entries(readerFields);
|
|
1763
|
+
if (entries.length === 0 && !reader.admissionGrants) {
|
|
1764
|
+
throw new Error(
|
|
1765
|
+
`defineChapter.network.readers.${reader.id}.fields: at least one CRM type is required unless this is an admission-only reader`
|
|
1766
|
+
);
|
|
1692
1767
|
}
|
|
1693
1768
|
for (const [type, names] of entries) {
|
|
1694
1769
|
if (!FIELD.test(type) || names.length === 0 || names.some((name) => !FIELD.test(name))) {
|
|
@@ -1718,23 +1793,35 @@ function resolveNetwork(config, crm) {
|
|
|
1718
1793
|
path: `defineChapter.network.readers.${reader.id}.sharedNotes`,
|
|
1719
1794
|
values: sharedNotes,
|
|
1720
1795
|
crm,
|
|
1721
|
-
fields:
|
|
1796
|
+
fields: readerFields
|
|
1722
1797
|
});
|
|
1723
1798
|
const editableFields = reader.editableFields ?? {};
|
|
1724
1799
|
validateEditableFields({
|
|
1725
1800
|
path: `defineChapter.network.readers.${reader.id}.editableFields`,
|
|
1726
1801
|
values: editableFields,
|
|
1727
1802
|
crm,
|
|
1728
|
-
readable:
|
|
1803
|
+
readable: readerFields
|
|
1729
1804
|
});
|
|
1730
1805
|
const stageTransitions = reader.stageTransitions ?? [];
|
|
1731
1806
|
validateStageTransitions({
|
|
1732
1807
|
path: `defineChapter.network.readers.${reader.id}.stageTransitions`,
|
|
1733
1808
|
values: stageTransitions,
|
|
1734
1809
|
crm,
|
|
1735
|
-
readable:
|
|
1810
|
+
readable: readerFields
|
|
1811
|
+
});
|
|
1812
|
+
validateAdmissionCapability(
|
|
1813
|
+
`defineChapter.network.readers.${reader.id}.admissionGrants`,
|
|
1814
|
+
reader.admissionGrants,
|
|
1815
|
+
crm
|
|
1816
|
+
);
|
|
1817
|
+
readers.push({
|
|
1818
|
+
id: reader.id,
|
|
1819
|
+
fields: readerFields,
|
|
1820
|
+
sharedNotes,
|
|
1821
|
+
editableFields,
|
|
1822
|
+
stageTransitions,
|
|
1823
|
+
...reader.admissionGrants === true ? { admissionGrants: true } : {}
|
|
1736
1824
|
});
|
|
1737
|
-
readers.push({ id: reader.id, fields: reader.fields, sharedNotes, editableFields, stageTransitions });
|
|
1738
1825
|
}
|
|
1739
1826
|
return { targets, readers };
|
|
1740
1827
|
}
|
|
@@ -1865,7 +1952,8 @@ function defineChapter(config) {
|
|
|
1865
1952
|
application,
|
|
1866
1953
|
Boolean(signupControl),
|
|
1867
1954
|
Boolean(memberContent),
|
|
1868
|
-
Boolean(builderLibrary)
|
|
1955
|
+
Boolean(builderLibrary),
|
|
1956
|
+
network.targets.some((target) => target.admissionGrants)
|
|
1869
1957
|
);
|
|
1870
1958
|
const services = config.services ?? ["db", "calendar", "o11y"];
|
|
1871
1959
|
const account = config.account ?? "none";
|