@odla-ai/chapter 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -41
- package/dist/chunk-NTZSXAFT.js +411 -0
- package/dist/chunk-NTZSXAFT.js.map +1 -0
- package/dist/{chunk-ILGUJXSB.js → chunk-OYXNI6VR.js} +275 -93
- package/dist/chunk-OYXNI6VR.js.map +1 -0
- package/dist/{chunk-IWW5VAAC.js → chunk-VCC4S6JU.js} +230 -202
- package/dist/chunk-VCC4S6JU.js.map +1 -0
- package/dist/{types-CgWUQ2MH.d.ts → copy-context-pDogTR4x.d.ts} +78 -20
- package/dist/index.cjs +322 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +90 -24
- package/dist/index.d.ts +90 -24
- package/dist/index.js +322 -3
- package/dist/index.js.map +1 -1
- package/dist/ui/admin/index.d.ts +31 -28
- package/dist/ui/admin/index.js +8 -3
- package/dist/ui/index.d.ts +3 -3
- package/dist/ui/index.js +11 -5
- package/dist/ui/member/index.d.ts +128 -12
- package/dist/ui/member/index.js +10 -4
- package/dist/worker/index.cjs +180 -130
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +67 -19
- package/dist/worker/index.d.ts +67 -19
- package/dist/worker/index.js +180 -130
- package/dist/worker/index.js.map +1 -1
- package/package.json +11 -11
- package/runbooks/adopt-existing.md +23 -5
- package/runbooks/greenfield.md +95 -15
- package/dist/chunk-ILGUJXSB.js.map +0 -1
- package/dist/chunk-IWW5VAAC.js.map +0 -1
- package/dist/chunk-VZPBTTO3.js +0 -91
- package/dist/chunk-VZPBTTO3.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
import { CrmConfig, Crm, CrmRecord } from '@odla-ai/crm';
|
|
2
2
|
|
|
3
|
+
/** Complete default language resolved beneath partial Chapter copy overrides. */
|
|
4
|
+
declare const DEFAULT_CHAPTER_COPY: ChapterCopy;
|
|
5
|
+
/** Resolve a partial copy contract and validate every supplied leaf. */
|
|
6
|
+
declare function resolveChapterCopy(input?: ChapterCopyInput): ChapterCopy;
|
|
7
|
+
/** Replace `{name}` placeholders without interpreting the resulting text as HTML. */
|
|
8
|
+
declare function formatChapterCopy(template: string, values: Readonly<Record<string, string | number>>): string;
|
|
9
|
+
|
|
10
|
+
type TextFields<Key extends string> = {
|
|
11
|
+
[Field in Key]: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Complete user-visible language owned by Chapter's packaged surfaces.
|
|
15
|
+
*
|
|
16
|
+
* Copy is serializable text; use render slots when presentation needs markup and
|
|
17
|
+
* `formatChapterCopy()` for typed placeholders.
|
|
18
|
+
*/
|
|
19
|
+
interface ChapterCopy {
|
|
20
|
+
common: TextFields<"loading" | "saved" | "unknown">;
|
|
21
|
+
join: {
|
|
22
|
+
form: TextFields<"submit" | "submitting" | "submitFailed" | "unexpectedFailure">;
|
|
23
|
+
booking: TextFields<"unavailable" | "loadFailed" | "slotTaken" | "failed" | "loading" | "book" | "booking">;
|
|
24
|
+
payment: TextFields<"setupFailed" | "preparing" | "pending" | "processing" | "payAndContinue" | "incomplete">;
|
|
25
|
+
done: TextFields<"label" | "calendarInvite" | "memberArea">;
|
|
26
|
+
};
|
|
27
|
+
members: {
|
|
28
|
+
loadFailed: string;
|
|
29
|
+
account: TextFields<"signOut" | "adminConsole">;
|
|
30
|
+
provisional: TextFields<"cardLabel" | "applicationNeeded" | "applicationNeededBody" | "apply" | "refunded" | "refundedBody" | "active" | "renews" | "introductionCall" | "calendarInvite" | "joinCall" | "bookCall" | "bookCallBody" | "chooseTime">;
|
|
31
|
+
full: TextFields<"welcome">;
|
|
32
|
+
reschedule: TextFields<"changeTime" | "unavailable" | "loadFailed" | "slotGone" | "loading" | "noTimes" | "rescheduling" | "keepTime">;
|
|
33
|
+
};
|
|
34
|
+
admin: {
|
|
35
|
+
auth: TextFields<"checking" | "notAuthorized" | "accountNotAuthorized" | "thisAccount" | "signOut" | "loading" | "signInNotConfigured" | "missingPublishableKey" | "noWorkspaces" | "signInTagline">;
|
|
36
|
+
shell: TextFields<"adminRole" | "adminConsole" | "adminName" | "navigationLabel">;
|
|
37
|
+
workspaces: TextFields<"dashboard" | "overview" | "billing" | "people" | "settings" | "calendar" | "email" | "dashboardViewsLabel" | "settingsViewsLabel" | "collectionsLabel">;
|
|
38
|
+
dashboard: TextFields<"loading" | "loadFailed" | "upcomingCalls" | "callsNeedAttention" | "noUpcomingCalls" | "drift" | "open" | "meet" | "applications" | "newMembers" | "newMembersUnavailable" | "revenueAdded" | "revenue" | "revenueUnavailable" | "pipeline" | "pipelineLabel" | "thisWeek" | "noChange" | "activeMemberships" | "annualRunRate" | "testMode">;
|
|
39
|
+
billing: TextFields<"loading" | "loadFailed" | "notConfigured" | "active" | "annualized" | "renewingSoon" | "pastDue" | "subscriptions" | "testMode" | "truncated" | "name" | "email" | "application" | "subscription" | "cancelling" | "amount" | "renews">;
|
|
40
|
+
availability: TextFields<"loading" | "loadFailed" | "saved" | "title" | "days" | "startHour" | "endHour" | "slotMinutes" | "minNoticeHours" | "windowDays" | "timezone" | "summaryTemplate" | "save"> & {
|
|
41
|
+
dayLabels: readonly string[];
|
|
42
|
+
};
|
|
43
|
+
email: TextFields<"loading" | "loadFailed" | "saved" | "sent" | "testFailed" | "delivery" | "notificationAddress" | "replyTo" | "debugInbox" | "debugInboxHint" | "sendTest" | "enabled" | "subject" | "body" | "save" | "sendLog" | "sentColumn" | "templateColumn" | "statusColumn" | "toColumn" | "failed" | "redirected" | "delivered">;
|
|
44
|
+
meetings: TextFields<"loading" | "loadFailed" | "cancelConfirm" | "newStartPrompt" | "parseFailed" | "agenda" | "empty" | "unknown" | "drift" | "meet" | "reschedule" | "cancel">;
|
|
45
|
+
network: TextFields<"title" | "allowlistDescription" | "sharing" | "shareWith" | "shared" | "shareFailed" | "deliveryFailed">;
|
|
46
|
+
records: TextFields<"workflowMissing" | "comms" | "commsHistory" | "scheduling" | "billing" | "notes" | "access" | "sharing" | "lifecycle" | "role" | "superAdminHint" | "noAccount" | "approve" | "refund" | "approved" | "refunded" | "roleSet" | "messageSent" | "messageNotSent" | "loadingTemplates" | "template" | "chooseTemplate" | "sending" | "send" | "noMessages" | "message" | "newStartPrompt" | "parseFailed" | "cancelConfirm" | "callCancelled" | "callRescheduled" | "noApplication" | "loadingMeetings" | "noMeetings" | "joinMeeting" | "openCalendar" | "reschedule" | "cancel">;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
type DeepPartial<T> = T extends readonly (infer Item)[] ? readonly Item[] : T extends object ? {
|
|
50
|
+
[Key in keyof T]?: DeepPartial<T[Key]>;
|
|
51
|
+
} : T;
|
|
52
|
+
/** Recursively partial copy overrides accepted by `defineChapter({ copy })`. */
|
|
53
|
+
type ChapterCopyInput = DeepPartial<ChapterCopy>;
|
|
54
|
+
|
|
3
55
|
/** Which feature profile a site runs. `chapter` is the full public member site
|
|
4
56
|
* (join, Stripe membership, booking, member area, admin, CRM); `hub` is
|
|
5
57
|
* admin-only and CRM-focused (a directory/registry over the same CRM). */
|
|
@@ -93,6 +145,8 @@ interface ChapterBrandTokens {
|
|
|
93
145
|
interface ChapterBrand {
|
|
94
146
|
/** Preloaded @odla-ai/ui theme name used by ThemeScope. */
|
|
95
147
|
theme?: string;
|
|
148
|
+
/** Named accent family supplied by the selected @odla-ai/ui theme. */
|
|
149
|
+
accent?: string;
|
|
96
150
|
/** Admin/application color mode. Explicit light is the safe default. */
|
|
97
151
|
colorScheme?: "light" | "dark" | "system";
|
|
98
152
|
tokens?: ChapterBrandTokens;
|
|
@@ -105,6 +159,9 @@ interface ChapterBrand {
|
|
|
105
159
|
* `:root[data-theme="dark"]` and `@media (prefers-color-scheme: dark)`, so a
|
|
106
160
|
* site brands both modes. */
|
|
107
161
|
paletteDark?: Record<string, string>;
|
|
162
|
+
/** Full token map for `.ui-invert` islands. A compiled custom theme normally
|
|
163
|
+
* uses its dark map here so inverted content never inherits stale composites. */
|
|
164
|
+
paletteInvert?: Record<string, string>;
|
|
108
165
|
fonts?: {
|
|
109
166
|
display?: string;
|
|
110
167
|
body?: string;
|
|
@@ -260,17 +317,13 @@ interface ChapterApplication {
|
|
|
260
317
|
/** Max JSON request body in bytes. Default 32768. */
|
|
261
318
|
bodyCap?: number;
|
|
262
319
|
/** Reject a submit that carries no truthy `disclaimerAck` (400), instead of
|
|
263
|
-
* writing a row with no consent record. Default `false`
|
|
264
|
-
*
|
|
265
|
-
* otherwise silent, permanent and unreconstructible. Failure is deterministic
|
|
266
|
-
* and surfaces on the first test submit, not intermittently in production. */
|
|
320
|
+
* writing a row with no consent record. Default `true`. Set `false`
|
|
321
|
+
* deliberately only when the site renders no consent control. */
|
|
267
322
|
requireDisclaimerAck?: boolean;
|
|
268
323
|
/** Allowlist of fields that reach the Clerk account's client-readable
|
|
269
|
-
* `public_metadata.profile`. Default
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
* (e.g. `["phone", "state", "focus"]`) to keep confidential fields db-only.
|
|
273
|
-
* Expected to become required-in-spirit at 1.0. */
|
|
324
|
+
* `public_metadata.profile`. Default `[]`, so application details remain
|
|
325
|
+
* db-only. Set a curated list (e.g. `["phone", "state", "focus"]`) for
|
|
326
|
+
* fields the browser may read. */
|
|
274
327
|
profileFields?: readonly string[];
|
|
275
328
|
/** Extra application fields carried into the one-way CRM projection, on top of
|
|
276
329
|
* the built-in identity/contact set. Each MUST be declared on your crm person
|
|
@@ -294,8 +347,8 @@ interface ResolvedApplication {
|
|
|
294
347
|
defaultMaxLen: number;
|
|
295
348
|
bodyCap: number;
|
|
296
349
|
requireDisclaimerAck: boolean;
|
|
297
|
-
/** Resolved Clerk-metadata allowlist
|
|
298
|
-
profileFields: readonly string[]
|
|
350
|
+
/** Resolved Clerk-metadata allowlist. Empty means no profile projection. */
|
|
351
|
+
profileFields: readonly string[];
|
|
299
352
|
crmFields: readonly string[];
|
|
300
353
|
maxArrayLen: number;
|
|
301
354
|
validateEmail: boolean;
|
|
@@ -311,6 +364,9 @@ interface ChapterConfig {
|
|
|
311
364
|
/** A `defineCrm()` config or a resolved `Crm`. Omit for the per-mode default. */
|
|
312
365
|
crm?: CrmConfig | Crm;
|
|
313
366
|
brand?: ChapterBrand;
|
|
367
|
+
/** User-visible language for packaged Chapter surfaces. Recursively partial;
|
|
368
|
+
* `defineChapter()` resolves every omitted leaf from the package defaults. */
|
|
369
|
+
copy?: ChapterCopyInput;
|
|
314
370
|
/** Leader → follower delivery targets. Secret values stay in the leader
|
|
315
371
|
* tenant vault; see {@link ChapterNetworkTarget}. */
|
|
316
372
|
network?: ChapterNetwork;
|
|
@@ -329,13 +385,10 @@ interface ChapterConfig {
|
|
|
329
385
|
auth?: ChapterAuth;
|
|
330
386
|
/** odla services (db implied). Default `["db","calendar","o11y"]`. */
|
|
331
387
|
services?: readonly string[];
|
|
332
|
-
/** Apply-time account provisioning.
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
* `"invite"` **emails the applicant a Clerk invitation**. Both non-default
|
|
337
|
-
* models need a `clerk_secret_key` vault secret to act. Opt in explicitly —
|
|
338
|
-
* leaving this unset provisions no accounts. */
|
|
388
|
+
/** Apply-time account provisioning. Required in `chapter` mode so a site must
|
|
389
|
+
* make the decision explicitly. `"none"` provisions nothing, `"create"` makes
|
|
390
|
+
* the Clerk account server-side, and `"invite"` emails a real invitation.
|
|
391
|
+
* Both side-effecting models need a `clerk_secret_key` vault secret. */
|
|
339
392
|
account?: AccountModel;
|
|
340
393
|
/** WHEN lifecycle email fires. Addressing and content live on the group row
|
|
341
394
|
* (owner-editable at runtime); this is the trigger, which is a build-time
|
|
@@ -403,6 +456,8 @@ interface Chapter {
|
|
|
403
456
|
/** Resolved site identity. `wordmark` always falls back to `name`, so the
|
|
404
457
|
* admin/member UI never needs a second brand declaration. */
|
|
405
458
|
brand: ChapterBrand;
|
|
459
|
+
/** Fully resolved user-visible text for packaged Chapter surfaces. */
|
|
460
|
+
copy: ChapterCopy;
|
|
406
461
|
/** Validated follower targets for leader-driven record pushes. */
|
|
407
462
|
network: ResolvedNetwork;
|
|
408
463
|
/** Resolved CRM engine (from `defineCrm`). */
|
|
@@ -417,7 +472,7 @@ interface Chapter {
|
|
|
417
472
|
schema: DbSchema;
|
|
418
473
|
rules: DbRules;
|
|
419
474
|
services: readonly string[];
|
|
420
|
-
/** Resolved apply-time account provisioning model
|
|
475
|
+
/** Resolved apply-time account provisioning model. */
|
|
421
476
|
account: AccountModel;
|
|
422
477
|
/** Resolved send policy — when each lifecycle email fires. */
|
|
423
478
|
sends: ResolvedSends;
|
|
@@ -803,10 +858,10 @@ declare function hasDisclaimerAck(fields: Record<string, unknown>): boolean;
|
|
|
803
858
|
/**
|
|
804
859
|
* The applicant profile written to the Clerk account's client-readable
|
|
805
860
|
* `public_metadata.profile`. Projects each configured non-identity field, plus
|
|
806
|
-
* `focus` (clamped)
|
|
807
|
-
*
|
|
808
|
-
*
|
|
809
|
-
*
|
|
861
|
+
* `focus` (clamped), but ONLY those in `application.profileFields`, so a site
|
|
862
|
+
* keeps confidential fields (`message`, `referral`) db-only. Derived from
|
|
863
|
+
* config, so a site's own field names project without this package knowing
|
|
864
|
+
* them. Pure; returns `undefined` when there is nothing to write.
|
|
810
865
|
*/
|
|
811
866
|
declare function applicantProfile(chapter: Chapter, fields: Record<string, unknown>): Record<string, unknown> | undefined;
|
|
812
867
|
/** A validated submission, or a 400-worthy validation error the route returns.
|
|
@@ -1243,6 +1298,17 @@ declare function memberSession(user: SessionUser, opts: {
|
|
|
1243
1298
|
declare function brandTokens(brand: ChapterBrand | undefined, options?: {
|
|
1244
1299
|
selector?: string;
|
|
1245
1300
|
}): string;
|
|
1301
|
+
/** Structural output accepted from `@odla-ai/brand`'s pure token compiler. */
|
|
1302
|
+
interface CompiledChapterBrandTokens {
|
|
1303
|
+
light: Record<string, string>;
|
|
1304
|
+
dark: Record<string, string>;
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Turn a complete compiled token pair into Chapter's brand contract without
|
|
1308
|
+
* coupling Chapter's runtime to the brand-book/agent package. Explicit values in
|
|
1309
|
+
* `base` win, so a host can make final per-site adjustments after compilation.
|
|
1310
|
+
*/
|
|
1311
|
+
declare function chapterBrandFromTokens(compiled: CompiledChapterBrandTokens, base?: ChapterBrand): ChapterBrand;
|
|
1246
1312
|
|
|
1247
1313
|
/** A `meetings` row, as far as reconciliation cares. */
|
|
1248
1314
|
interface MeetingForReconcile {
|
|
@@ -1404,4 +1470,4 @@ type ApplicationBookingPatch = {
|
|
|
1404
1470
|
* already there (never backward). */
|
|
1405
1471
|
declare function applicationBookingUpdate(currentStatus: string, startAt: number, htmlLink?: string | null): ApplicationBookingPatch;
|
|
1406
1472
|
|
|
1407
|
-
export { type AccountModel, type AdminNotificationTrigger, type Applicant, type ApplicationBookingPatch, type ApplicationRecord, type ApplicationSummary, type Attr, type AttrType, type Chapter, type ChapterApplication, type ChapterAuth, type ChapterBrand, type ChapterConfig, type ChapterDb, type ChapterEmails, type ChapterIntegrationDescriptor, type ChapterIntegrationOptions, type ChapterMode, type ChapterNetwork, type ChapterNetworkTarget, type ChapterOperations, type ChapterPipeline, type ChapterPolicy, type ChapterPrices, type ChapterScheduling, type ChapterSends, type ClerkInviteInput, type ClerkResult, type ClerkUserInput, type ClerkUserRecord, DEFAULT_SHARE_FIELDS, type DashboardMetricData, type DashboardMetricSeries, type DbOp, type DbRules, type DbSchema, type DeliveryDecision, type EmailGroup, type EmailTemplate, type EmailTemplateRow, type Entity, type ExistingMeeting, type GuardResult, type IntegrationDescriptor, type IntegrationProvision, type IntegrationSecret, type IntegrationSetting, type IntegrationSync, type JoinConfigGroup, type LiveEvent, type MailSender, type MeetingForReconcile, type MeetingRecord, type MeetingReschedulePatch, type MemberApplication, type MemberSession, type NewMeetingRow, type NotifyDeps, type NotifyInput, type NotifyResult, type PaymentsGroup, type ProjectionDeps, type ReconcileDecision, type ResolvedApplication, type ResolvedAuth, type ResolvedNetwork, type ResolvedNetworkTarget, type ResolvedOperations, type ResolvedPipeline, type ResolvedScheduling, type ResolvedSends, type RoleChangeContext, type Rule, SCHEDULING_DEFAULTS, type SchedulingErrors, type SecretMode, type SecretStore, type SessionUser, type SharedBusiness, type SharedPerson, type SharedRecord, type StripeEvent, type StripeResult, type SubmitResult, type WebhookEvent, applicantProfile, applicationBookingUpdate, applicationSummary, backfillCrm, bookingDecision, brandTokens, bucketSeries, buildGroupSeed, canApprove, canBook, canChangeRole, canTransition, canceledPatch, chapterDb, clampArray, clerkGetUser, clerkGetUserByEmail, clerkIntegration, clerkInviteRequest, clerkListUsers, clerkSetRole, clerkUserRequest, createChapterIntegration, createClerkInvitation, createClerkUser, dashboardMetricData, defaultCrm, defineChapter, emailGroupFrom, endForSlot, findApplicationRef, firstPaymentPatch, getVaultSecret, hasDisclaimerAck, introIdempotencyKey, isAdminRole, isAlreadySent, isReconcilable, isSlotAvailable, isValidEmail, joinConfig, meetingCreateRow, meetingRescheduleUpdate, memberApplication, memberSession, networkSourceTag, normalizeSharedRecord, normalizeWebhookEvent, paymentsReady, personInputFromApp, planDelivery, projectApplicant, projectSharedRecord, reconcileMeetings, refundedPatch, render, renderSummary, renderTemplateBody, renewalPatch, resolveApplication, resolveAuth, resolvePipeline, resolveScheduling, roleFromClaim, sendTemplated, sharedPersonInput, sharedRecordFromCrm, slotWindow, stageIndex, stripeCall, stripeForm, subAnnualCents, submitApplication, subscriptionIdempotencyKey, syncApplicationToCrm, validateScheduling, verifyStripeSignature, webhookMutationId };
|
|
1473
|
+
export { type AccountModel, type AdminNotificationTrigger, type Applicant, type ApplicationBookingPatch, type ApplicationRecord, type ApplicationSummary, type Attr, type AttrType, type Chapter, type ChapterApplication, type ChapterAuth, type ChapterBrand, type ChapterConfig, type ChapterCopy, type ChapterCopyInput, type ChapterDb, type ChapterEmails, type ChapterIntegrationDescriptor, type ChapterIntegrationOptions, type ChapterMode, type ChapterNetwork, type ChapterNetworkTarget, type ChapterOperations, type ChapterPipeline, type ChapterPolicy, type ChapterPrices, type ChapterScheduling, type ChapterSends, type ClerkInviteInput, type ClerkResult, type ClerkUserInput, type ClerkUserRecord, type CompiledChapterBrandTokens, DEFAULT_CHAPTER_COPY, DEFAULT_SHARE_FIELDS, type DashboardMetricData, type DashboardMetricSeries, type DbOp, type DbRules, type DbSchema, type DeliveryDecision, type EmailGroup, type EmailTemplate, type EmailTemplateRow, type Entity, type ExistingMeeting, type GuardResult, type IntegrationDescriptor, type IntegrationProvision, type IntegrationSecret, type IntegrationSetting, type IntegrationSync, type JoinConfigGroup, type LiveEvent, type MailSender, type MeetingForReconcile, type MeetingRecord, type MeetingReschedulePatch, type MemberApplication, type MemberSession, type NewMeetingRow, type NotifyDeps, type NotifyInput, type NotifyResult, type PaymentsGroup, type ProjectionDeps, type ReconcileDecision, type ResolvedApplication, type ResolvedAuth, type ResolvedNetwork, type ResolvedNetworkTarget, type ResolvedOperations, type ResolvedPipeline, type ResolvedScheduling, type ResolvedSends, type RoleChangeContext, type Rule, SCHEDULING_DEFAULTS, type SchedulingErrors, type SecretMode, type SecretStore, type SessionUser, type SharedBusiness, type SharedPerson, type SharedRecord, type StripeEvent, type StripeResult, type SubmitResult, type WebhookEvent, applicantProfile, applicationBookingUpdate, applicationSummary, backfillCrm, bookingDecision, brandTokens, bucketSeries, buildGroupSeed, canApprove, canBook, canChangeRole, canTransition, canceledPatch, chapterBrandFromTokens, chapterDb, clampArray, clerkGetUser, clerkGetUserByEmail, clerkIntegration, clerkInviteRequest, clerkListUsers, clerkSetRole, clerkUserRequest, createChapterIntegration, createClerkInvitation, createClerkUser, dashboardMetricData, defaultCrm, defineChapter, emailGroupFrom, endForSlot, findApplicationRef, firstPaymentPatch, formatChapterCopy, getVaultSecret, hasDisclaimerAck, introIdempotencyKey, isAdminRole, isAlreadySent, isReconcilable, isSlotAvailable, isValidEmail, joinConfig, meetingCreateRow, meetingRescheduleUpdate, memberApplication, memberSession, networkSourceTag, normalizeSharedRecord, normalizeWebhookEvent, paymentsReady, personInputFromApp, planDelivery, projectApplicant, projectSharedRecord, reconcileMeetings, refundedPatch, render, renderSummary, renderTemplateBody, renewalPatch, resolveApplication, resolveAuth, resolveChapterCopy, resolvePipeline, resolveScheduling, roleFromClaim, sendTemplated, sharedPersonInput, sharedRecordFromCrm, slotWindow, stageIndex, stripeCall, stripeForm, subAnnualCents, submitApplication, subscriptionIdempotencyKey, syncApplicationToCrm, validateScheduling, verifyStripeSignature, webhookMutationId };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
import { CrmConfig, Crm, CrmRecord } from '@odla-ai/crm';
|
|
2
2
|
|
|
3
|
+
/** Complete default language resolved beneath partial Chapter copy overrides. */
|
|
4
|
+
declare const DEFAULT_CHAPTER_COPY: ChapterCopy;
|
|
5
|
+
/** Resolve a partial copy contract and validate every supplied leaf. */
|
|
6
|
+
declare function resolveChapterCopy(input?: ChapterCopyInput): ChapterCopy;
|
|
7
|
+
/** Replace `{name}` placeholders without interpreting the resulting text as HTML. */
|
|
8
|
+
declare function formatChapterCopy(template: string, values: Readonly<Record<string, string | number>>): string;
|
|
9
|
+
|
|
10
|
+
type TextFields<Key extends string> = {
|
|
11
|
+
[Field in Key]: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Complete user-visible language owned by Chapter's packaged surfaces.
|
|
15
|
+
*
|
|
16
|
+
* Copy is serializable text; use render slots when presentation needs markup and
|
|
17
|
+
* `formatChapterCopy()` for typed placeholders.
|
|
18
|
+
*/
|
|
19
|
+
interface ChapterCopy {
|
|
20
|
+
common: TextFields<"loading" | "saved" | "unknown">;
|
|
21
|
+
join: {
|
|
22
|
+
form: TextFields<"submit" | "submitting" | "submitFailed" | "unexpectedFailure">;
|
|
23
|
+
booking: TextFields<"unavailable" | "loadFailed" | "slotTaken" | "failed" | "loading" | "book" | "booking">;
|
|
24
|
+
payment: TextFields<"setupFailed" | "preparing" | "pending" | "processing" | "payAndContinue" | "incomplete">;
|
|
25
|
+
done: TextFields<"label" | "calendarInvite" | "memberArea">;
|
|
26
|
+
};
|
|
27
|
+
members: {
|
|
28
|
+
loadFailed: string;
|
|
29
|
+
account: TextFields<"signOut" | "adminConsole">;
|
|
30
|
+
provisional: TextFields<"cardLabel" | "applicationNeeded" | "applicationNeededBody" | "apply" | "refunded" | "refundedBody" | "active" | "renews" | "introductionCall" | "calendarInvite" | "joinCall" | "bookCall" | "bookCallBody" | "chooseTime">;
|
|
31
|
+
full: TextFields<"welcome">;
|
|
32
|
+
reschedule: TextFields<"changeTime" | "unavailable" | "loadFailed" | "slotGone" | "loading" | "noTimes" | "rescheduling" | "keepTime">;
|
|
33
|
+
};
|
|
34
|
+
admin: {
|
|
35
|
+
auth: TextFields<"checking" | "notAuthorized" | "accountNotAuthorized" | "thisAccount" | "signOut" | "loading" | "signInNotConfigured" | "missingPublishableKey" | "noWorkspaces" | "signInTagline">;
|
|
36
|
+
shell: TextFields<"adminRole" | "adminConsole" | "adminName" | "navigationLabel">;
|
|
37
|
+
workspaces: TextFields<"dashboard" | "overview" | "billing" | "people" | "settings" | "calendar" | "email" | "dashboardViewsLabel" | "settingsViewsLabel" | "collectionsLabel">;
|
|
38
|
+
dashboard: TextFields<"loading" | "loadFailed" | "upcomingCalls" | "callsNeedAttention" | "noUpcomingCalls" | "drift" | "open" | "meet" | "applications" | "newMembers" | "newMembersUnavailable" | "revenueAdded" | "revenue" | "revenueUnavailable" | "pipeline" | "pipelineLabel" | "thisWeek" | "noChange" | "activeMemberships" | "annualRunRate" | "testMode">;
|
|
39
|
+
billing: TextFields<"loading" | "loadFailed" | "notConfigured" | "active" | "annualized" | "renewingSoon" | "pastDue" | "subscriptions" | "testMode" | "truncated" | "name" | "email" | "application" | "subscription" | "cancelling" | "amount" | "renews">;
|
|
40
|
+
availability: TextFields<"loading" | "loadFailed" | "saved" | "title" | "days" | "startHour" | "endHour" | "slotMinutes" | "minNoticeHours" | "windowDays" | "timezone" | "summaryTemplate" | "save"> & {
|
|
41
|
+
dayLabels: readonly string[];
|
|
42
|
+
};
|
|
43
|
+
email: TextFields<"loading" | "loadFailed" | "saved" | "sent" | "testFailed" | "delivery" | "notificationAddress" | "replyTo" | "debugInbox" | "debugInboxHint" | "sendTest" | "enabled" | "subject" | "body" | "save" | "sendLog" | "sentColumn" | "templateColumn" | "statusColumn" | "toColumn" | "failed" | "redirected" | "delivered">;
|
|
44
|
+
meetings: TextFields<"loading" | "loadFailed" | "cancelConfirm" | "newStartPrompt" | "parseFailed" | "agenda" | "empty" | "unknown" | "drift" | "meet" | "reschedule" | "cancel">;
|
|
45
|
+
network: TextFields<"title" | "allowlistDescription" | "sharing" | "shareWith" | "shared" | "shareFailed" | "deliveryFailed">;
|
|
46
|
+
records: TextFields<"workflowMissing" | "comms" | "commsHistory" | "scheduling" | "billing" | "notes" | "access" | "sharing" | "lifecycle" | "role" | "superAdminHint" | "noAccount" | "approve" | "refund" | "approved" | "refunded" | "roleSet" | "messageSent" | "messageNotSent" | "loadingTemplates" | "template" | "chooseTemplate" | "sending" | "send" | "noMessages" | "message" | "newStartPrompt" | "parseFailed" | "cancelConfirm" | "callCancelled" | "callRescheduled" | "noApplication" | "loadingMeetings" | "noMeetings" | "joinMeeting" | "openCalendar" | "reschedule" | "cancel">;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
type DeepPartial<T> = T extends readonly (infer Item)[] ? readonly Item[] : T extends object ? {
|
|
50
|
+
[Key in keyof T]?: DeepPartial<T[Key]>;
|
|
51
|
+
} : T;
|
|
52
|
+
/** Recursively partial copy overrides accepted by `defineChapter({ copy })`. */
|
|
53
|
+
type ChapterCopyInput = DeepPartial<ChapterCopy>;
|
|
54
|
+
|
|
3
55
|
/** Which feature profile a site runs. `chapter` is the full public member site
|
|
4
56
|
* (join, Stripe membership, booking, member area, admin, CRM); `hub` is
|
|
5
57
|
* admin-only and CRM-focused (a directory/registry over the same CRM). */
|
|
@@ -93,6 +145,8 @@ interface ChapterBrandTokens {
|
|
|
93
145
|
interface ChapterBrand {
|
|
94
146
|
/** Preloaded @odla-ai/ui theme name used by ThemeScope. */
|
|
95
147
|
theme?: string;
|
|
148
|
+
/** Named accent family supplied by the selected @odla-ai/ui theme. */
|
|
149
|
+
accent?: string;
|
|
96
150
|
/** Admin/application color mode. Explicit light is the safe default. */
|
|
97
151
|
colorScheme?: "light" | "dark" | "system";
|
|
98
152
|
tokens?: ChapterBrandTokens;
|
|
@@ -105,6 +159,9 @@ interface ChapterBrand {
|
|
|
105
159
|
* `:root[data-theme="dark"]` and `@media (prefers-color-scheme: dark)`, so a
|
|
106
160
|
* site brands both modes. */
|
|
107
161
|
paletteDark?: Record<string, string>;
|
|
162
|
+
/** Full token map for `.ui-invert` islands. A compiled custom theme normally
|
|
163
|
+
* uses its dark map here so inverted content never inherits stale composites. */
|
|
164
|
+
paletteInvert?: Record<string, string>;
|
|
108
165
|
fonts?: {
|
|
109
166
|
display?: string;
|
|
110
167
|
body?: string;
|
|
@@ -260,17 +317,13 @@ interface ChapterApplication {
|
|
|
260
317
|
/** Max JSON request body in bytes. Default 32768. */
|
|
261
318
|
bodyCap?: number;
|
|
262
319
|
/** Reject a submit that carries no truthy `disclaimerAck` (400), instead of
|
|
263
|
-
* writing a row with no consent record. Default `false`
|
|
264
|
-
*
|
|
265
|
-
* otherwise silent, permanent and unreconstructible. Failure is deterministic
|
|
266
|
-
* and surfaces on the first test submit, not intermittently in production. */
|
|
320
|
+
* writing a row with no consent record. Default `true`. Set `false`
|
|
321
|
+
* deliberately only when the site renders no consent control. */
|
|
267
322
|
requireDisclaimerAck?: boolean;
|
|
268
323
|
/** Allowlist of fields that reach the Clerk account's client-readable
|
|
269
|
-
* `public_metadata.profile`. Default
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
* (e.g. `["phone", "state", "focus"]`) to keep confidential fields db-only.
|
|
273
|
-
* Expected to become required-in-spirit at 1.0. */
|
|
324
|
+
* `public_metadata.profile`. Default `[]`, so application details remain
|
|
325
|
+
* db-only. Set a curated list (e.g. `["phone", "state", "focus"]`) for
|
|
326
|
+
* fields the browser may read. */
|
|
274
327
|
profileFields?: readonly string[];
|
|
275
328
|
/** Extra application fields carried into the one-way CRM projection, on top of
|
|
276
329
|
* the built-in identity/contact set. Each MUST be declared on your crm person
|
|
@@ -294,8 +347,8 @@ interface ResolvedApplication {
|
|
|
294
347
|
defaultMaxLen: number;
|
|
295
348
|
bodyCap: number;
|
|
296
349
|
requireDisclaimerAck: boolean;
|
|
297
|
-
/** Resolved Clerk-metadata allowlist
|
|
298
|
-
profileFields: readonly string[]
|
|
350
|
+
/** Resolved Clerk-metadata allowlist. Empty means no profile projection. */
|
|
351
|
+
profileFields: readonly string[];
|
|
299
352
|
crmFields: readonly string[];
|
|
300
353
|
maxArrayLen: number;
|
|
301
354
|
validateEmail: boolean;
|
|
@@ -311,6 +364,9 @@ interface ChapterConfig {
|
|
|
311
364
|
/** A `defineCrm()` config or a resolved `Crm`. Omit for the per-mode default. */
|
|
312
365
|
crm?: CrmConfig | Crm;
|
|
313
366
|
brand?: ChapterBrand;
|
|
367
|
+
/** User-visible language for packaged Chapter surfaces. Recursively partial;
|
|
368
|
+
* `defineChapter()` resolves every omitted leaf from the package defaults. */
|
|
369
|
+
copy?: ChapterCopyInput;
|
|
314
370
|
/** Leader → follower delivery targets. Secret values stay in the leader
|
|
315
371
|
* tenant vault; see {@link ChapterNetworkTarget}. */
|
|
316
372
|
network?: ChapterNetwork;
|
|
@@ -329,13 +385,10 @@ interface ChapterConfig {
|
|
|
329
385
|
auth?: ChapterAuth;
|
|
330
386
|
/** odla services (db implied). Default `["db","calendar","o11y"]`. */
|
|
331
387
|
services?: readonly string[];
|
|
332
|
-
/** Apply-time account provisioning.
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
* `"invite"` **emails the applicant a Clerk invitation**. Both non-default
|
|
337
|
-
* models need a `clerk_secret_key` vault secret to act. Opt in explicitly —
|
|
338
|
-
* leaving this unset provisions no accounts. */
|
|
388
|
+
/** Apply-time account provisioning. Required in `chapter` mode so a site must
|
|
389
|
+
* make the decision explicitly. `"none"` provisions nothing, `"create"` makes
|
|
390
|
+
* the Clerk account server-side, and `"invite"` emails a real invitation.
|
|
391
|
+
* Both side-effecting models need a `clerk_secret_key` vault secret. */
|
|
339
392
|
account?: AccountModel;
|
|
340
393
|
/** WHEN lifecycle email fires. Addressing and content live on the group row
|
|
341
394
|
* (owner-editable at runtime); this is the trigger, which is a build-time
|
|
@@ -403,6 +456,8 @@ interface Chapter {
|
|
|
403
456
|
/** Resolved site identity. `wordmark` always falls back to `name`, so the
|
|
404
457
|
* admin/member UI never needs a second brand declaration. */
|
|
405
458
|
brand: ChapterBrand;
|
|
459
|
+
/** Fully resolved user-visible text for packaged Chapter surfaces. */
|
|
460
|
+
copy: ChapterCopy;
|
|
406
461
|
/** Validated follower targets for leader-driven record pushes. */
|
|
407
462
|
network: ResolvedNetwork;
|
|
408
463
|
/** Resolved CRM engine (from `defineCrm`). */
|
|
@@ -417,7 +472,7 @@ interface Chapter {
|
|
|
417
472
|
schema: DbSchema;
|
|
418
473
|
rules: DbRules;
|
|
419
474
|
services: readonly string[];
|
|
420
|
-
/** Resolved apply-time account provisioning model
|
|
475
|
+
/** Resolved apply-time account provisioning model. */
|
|
421
476
|
account: AccountModel;
|
|
422
477
|
/** Resolved send policy — when each lifecycle email fires. */
|
|
423
478
|
sends: ResolvedSends;
|
|
@@ -803,10 +858,10 @@ declare function hasDisclaimerAck(fields: Record<string, unknown>): boolean;
|
|
|
803
858
|
/**
|
|
804
859
|
* The applicant profile written to the Clerk account's client-readable
|
|
805
860
|
* `public_metadata.profile`. Projects each configured non-identity field, plus
|
|
806
|
-
* `focus` (clamped)
|
|
807
|
-
*
|
|
808
|
-
*
|
|
809
|
-
*
|
|
861
|
+
* `focus` (clamped), but ONLY those in `application.profileFields`, so a site
|
|
862
|
+
* keeps confidential fields (`message`, `referral`) db-only. Derived from
|
|
863
|
+
* config, so a site's own field names project without this package knowing
|
|
864
|
+
* them. Pure; returns `undefined` when there is nothing to write.
|
|
810
865
|
*/
|
|
811
866
|
declare function applicantProfile(chapter: Chapter, fields: Record<string, unknown>): Record<string, unknown> | undefined;
|
|
812
867
|
/** A validated submission, or a 400-worthy validation error the route returns.
|
|
@@ -1243,6 +1298,17 @@ declare function memberSession(user: SessionUser, opts: {
|
|
|
1243
1298
|
declare function brandTokens(brand: ChapterBrand | undefined, options?: {
|
|
1244
1299
|
selector?: string;
|
|
1245
1300
|
}): string;
|
|
1301
|
+
/** Structural output accepted from `@odla-ai/brand`'s pure token compiler. */
|
|
1302
|
+
interface CompiledChapterBrandTokens {
|
|
1303
|
+
light: Record<string, string>;
|
|
1304
|
+
dark: Record<string, string>;
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Turn a complete compiled token pair into Chapter's brand contract without
|
|
1308
|
+
* coupling Chapter's runtime to the brand-book/agent package. Explicit values in
|
|
1309
|
+
* `base` win, so a host can make final per-site adjustments after compilation.
|
|
1310
|
+
*/
|
|
1311
|
+
declare function chapterBrandFromTokens(compiled: CompiledChapterBrandTokens, base?: ChapterBrand): ChapterBrand;
|
|
1246
1312
|
|
|
1247
1313
|
/** A `meetings` row, as far as reconciliation cares. */
|
|
1248
1314
|
interface MeetingForReconcile {
|
|
@@ -1404,4 +1470,4 @@ type ApplicationBookingPatch = {
|
|
|
1404
1470
|
* already there (never backward). */
|
|
1405
1471
|
declare function applicationBookingUpdate(currentStatus: string, startAt: number, htmlLink?: string | null): ApplicationBookingPatch;
|
|
1406
1472
|
|
|
1407
|
-
export { type AccountModel, type AdminNotificationTrigger, type Applicant, type ApplicationBookingPatch, type ApplicationRecord, type ApplicationSummary, type Attr, type AttrType, type Chapter, type ChapterApplication, type ChapterAuth, type ChapterBrand, type ChapterConfig, type ChapterDb, type ChapterEmails, type ChapterIntegrationDescriptor, type ChapterIntegrationOptions, type ChapterMode, type ChapterNetwork, type ChapterNetworkTarget, type ChapterOperations, type ChapterPipeline, type ChapterPolicy, type ChapterPrices, type ChapterScheduling, type ChapterSends, type ClerkInviteInput, type ClerkResult, type ClerkUserInput, type ClerkUserRecord, DEFAULT_SHARE_FIELDS, type DashboardMetricData, type DashboardMetricSeries, type DbOp, type DbRules, type DbSchema, type DeliveryDecision, type EmailGroup, type EmailTemplate, type EmailTemplateRow, type Entity, type ExistingMeeting, type GuardResult, type IntegrationDescriptor, type IntegrationProvision, type IntegrationSecret, type IntegrationSetting, type IntegrationSync, type JoinConfigGroup, type LiveEvent, type MailSender, type MeetingForReconcile, type MeetingRecord, type MeetingReschedulePatch, type MemberApplication, type MemberSession, type NewMeetingRow, type NotifyDeps, type NotifyInput, type NotifyResult, type PaymentsGroup, type ProjectionDeps, type ReconcileDecision, type ResolvedApplication, type ResolvedAuth, type ResolvedNetwork, type ResolvedNetworkTarget, type ResolvedOperations, type ResolvedPipeline, type ResolvedScheduling, type ResolvedSends, type RoleChangeContext, type Rule, SCHEDULING_DEFAULTS, type SchedulingErrors, type SecretMode, type SecretStore, type SessionUser, type SharedBusiness, type SharedPerson, type SharedRecord, type StripeEvent, type StripeResult, type SubmitResult, type WebhookEvent, applicantProfile, applicationBookingUpdate, applicationSummary, backfillCrm, bookingDecision, brandTokens, bucketSeries, buildGroupSeed, canApprove, canBook, canChangeRole, canTransition, canceledPatch, chapterDb, clampArray, clerkGetUser, clerkGetUserByEmail, clerkIntegration, clerkInviteRequest, clerkListUsers, clerkSetRole, clerkUserRequest, createChapterIntegration, createClerkInvitation, createClerkUser, dashboardMetricData, defaultCrm, defineChapter, emailGroupFrom, endForSlot, findApplicationRef, firstPaymentPatch, getVaultSecret, hasDisclaimerAck, introIdempotencyKey, isAdminRole, isAlreadySent, isReconcilable, isSlotAvailable, isValidEmail, joinConfig, meetingCreateRow, meetingRescheduleUpdate, memberApplication, memberSession, networkSourceTag, normalizeSharedRecord, normalizeWebhookEvent, paymentsReady, personInputFromApp, planDelivery, projectApplicant, projectSharedRecord, reconcileMeetings, refundedPatch, render, renderSummary, renderTemplateBody, renewalPatch, resolveApplication, resolveAuth, resolvePipeline, resolveScheduling, roleFromClaim, sendTemplated, sharedPersonInput, sharedRecordFromCrm, slotWindow, stageIndex, stripeCall, stripeForm, subAnnualCents, submitApplication, subscriptionIdempotencyKey, syncApplicationToCrm, validateScheduling, verifyStripeSignature, webhookMutationId };
|
|
1473
|
+
export { type AccountModel, type AdminNotificationTrigger, type Applicant, type ApplicationBookingPatch, type ApplicationRecord, type ApplicationSummary, type Attr, type AttrType, type Chapter, type ChapterApplication, type ChapterAuth, type ChapterBrand, type ChapterConfig, type ChapterCopy, type ChapterCopyInput, type ChapterDb, type ChapterEmails, type ChapterIntegrationDescriptor, type ChapterIntegrationOptions, type ChapterMode, type ChapterNetwork, type ChapterNetworkTarget, type ChapterOperations, type ChapterPipeline, type ChapterPolicy, type ChapterPrices, type ChapterScheduling, type ChapterSends, type ClerkInviteInput, type ClerkResult, type ClerkUserInput, type ClerkUserRecord, type CompiledChapterBrandTokens, DEFAULT_CHAPTER_COPY, DEFAULT_SHARE_FIELDS, type DashboardMetricData, type DashboardMetricSeries, type DbOp, type DbRules, type DbSchema, type DeliveryDecision, type EmailGroup, type EmailTemplate, type EmailTemplateRow, type Entity, type ExistingMeeting, type GuardResult, type IntegrationDescriptor, type IntegrationProvision, type IntegrationSecret, type IntegrationSetting, type IntegrationSync, type JoinConfigGroup, type LiveEvent, type MailSender, type MeetingForReconcile, type MeetingRecord, type MeetingReschedulePatch, type MemberApplication, type MemberSession, type NewMeetingRow, type NotifyDeps, type NotifyInput, type NotifyResult, type PaymentsGroup, type ProjectionDeps, type ReconcileDecision, type ResolvedApplication, type ResolvedAuth, type ResolvedNetwork, type ResolvedNetworkTarget, type ResolvedOperations, type ResolvedPipeline, type ResolvedScheduling, type ResolvedSends, type RoleChangeContext, type Rule, SCHEDULING_DEFAULTS, type SchedulingErrors, type SecretMode, type SecretStore, type SessionUser, type SharedBusiness, type SharedPerson, type SharedRecord, type StripeEvent, type StripeResult, type SubmitResult, type WebhookEvent, applicantProfile, applicationBookingUpdate, applicationSummary, backfillCrm, bookingDecision, brandTokens, bucketSeries, buildGroupSeed, canApprove, canBook, canChangeRole, canTransition, canceledPatch, chapterBrandFromTokens, chapterDb, clampArray, clerkGetUser, clerkGetUserByEmail, clerkIntegration, clerkInviteRequest, clerkListUsers, clerkSetRole, clerkUserRequest, createChapterIntegration, createClerkInvitation, createClerkUser, dashboardMetricData, defaultCrm, defineChapter, emailGroupFrom, endForSlot, findApplicationRef, firstPaymentPatch, formatChapterCopy, getVaultSecret, hasDisclaimerAck, introIdempotencyKey, isAdminRole, isAlreadySent, isReconcilable, isSlotAvailable, isValidEmail, joinConfig, meetingCreateRow, meetingRescheduleUpdate, memberApplication, memberSession, networkSourceTag, normalizeSharedRecord, normalizeWebhookEvent, paymentsReady, personInputFromApp, planDelivery, projectApplicant, projectSharedRecord, reconcileMeetings, refundedPatch, render, renderSummary, renderTemplateBody, renewalPatch, resolveApplication, resolveAuth, resolveChapterCopy, resolvePipeline, resolveScheduling, roleFromClaim, sendTemplated, sharedPersonInput, sharedRecordFromCrm, slotWindow, stageIndex, stripeCall, stripeForm, subAnnualCents, submitApplication, subscriptionIdempotencyKey, syncApplicationToCrm, validateScheduling, verifyStripeSignature, webhookMutationId };
|