@odla-ai/chapter 0.19.0 → 0.20.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 +87 -21
- package/dist/{chunk-GWY2ZTN7.js → chunk-LME2IHY5.js} +2 -50
- package/dist/chunk-LME2IHY5.js.map +1 -0
- package/dist/chunk-MKXHZMAP.js +51 -0
- package/dist/chunk-MKXHZMAP.js.map +1 -0
- package/dist/{chunk-D3QMK3ED.js → chunk-UIWFEESI.js} +611 -470
- package/dist/chunk-UIWFEESI.js.map +1 -0
- package/dist/index.cjs +176 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -9
- package/dist/index.d.ts +83 -9
- package/dist/index.js +176 -11
- package/dist/index.js.map +1 -1
- package/dist/types-D2fGiNG8.d.ts +366 -0
- package/dist/ui/admin/index.d.ts +37 -3
- package/dist/ui/admin/index.js +10 -1
- package/dist/ui/index.d.ts +2 -1
- package/dist/ui/index.js +13 -3
- package/dist/ui/member/index.d.ts +2 -25
- package/dist/ui/member/index.js +4 -2
- package/dist/worker/index.cjs +225 -24
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +45 -0
- package/dist/worker/index.d.ts +45 -0
- package/dist/worker/index.js +225 -24
- package/dist/worker/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-D3QMK3ED.js.map +0 -1
- package/dist/chunk-GWY2ZTN7.js.map +0 -1
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import { CrmConfig, Crm } from '@odla-ai/crm';
|
|
2
|
+
|
|
3
|
+
/** Which feature profile a site runs. `chapter` is the full public member site
|
|
4
|
+
* (join, Stripe membership, booking, member area, admin, CRM); `hub` is
|
|
5
|
+
* admin-only and CRM-focused (a directory/registry over the same CRM). */
|
|
6
|
+
type ChapterMode = "chapter" | "hub";
|
|
7
|
+
/** The scalar kinds an odla-db attribute can hold. */
|
|
8
|
+
type AttrType = "string" | "number" | "boolean" | "json";
|
|
9
|
+
/** One odla-db attribute: its type and index/uniqueness/optionality flags. */
|
|
10
|
+
interface Attr {
|
|
11
|
+
type: AttrType;
|
|
12
|
+
unique: boolean;
|
|
13
|
+
indexed: boolean;
|
|
14
|
+
optional: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** One odla-db namespace: its attribute map. */
|
|
17
|
+
interface Entity {
|
|
18
|
+
attrs: Record<string, Attr>;
|
|
19
|
+
}
|
|
20
|
+
/** A serialized odla-db schema fragment (namespaces + links). */
|
|
21
|
+
interface DbSchema {
|
|
22
|
+
entities: Record<string, Entity>;
|
|
23
|
+
links: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
/** Per-namespace CEL rule strings (deny-all is `"false"` for each action). */
|
|
26
|
+
interface Rule {
|
|
27
|
+
view: string;
|
|
28
|
+
create: string;
|
|
29
|
+
update: string;
|
|
30
|
+
delete: string;
|
|
31
|
+
}
|
|
32
|
+
/** Namespace → rule set. */
|
|
33
|
+
type DbRules = Record<string, Rule>;
|
|
34
|
+
/** Brand tokens that theme the site: palette, fonts, wordmark, nav, logos. */
|
|
35
|
+
interface ChapterBrand {
|
|
36
|
+
/** Palette overrides written into styles.css :root (e.g. `{ moss: "#2F3E34" }`
|
|
37
|
+
* or `--ui-*` token names). Applies in BOTH light and dark unless overridden
|
|
38
|
+
* by {@link paletteDark}. */
|
|
39
|
+
palette?: Record<string, string>;
|
|
40
|
+
/** Dark-mode palette overrides. Same shape as {@link palette}; emitted under
|
|
41
|
+
* `:root[data-theme="dark"]` and `@media (prefers-color-scheme: dark)`, so a
|
|
42
|
+
* site brands both modes. */
|
|
43
|
+
paletteDark?: Record<string, string>;
|
|
44
|
+
fonts?: {
|
|
45
|
+
display?: string;
|
|
46
|
+
body?: string;
|
|
47
|
+
numeral?: string;
|
|
48
|
+
};
|
|
49
|
+
/** Short glyph used in compact admin chrome. Defaults to the first three
|
|
50
|
+
* letters of the chapter name. */
|
|
51
|
+
badge?: string;
|
|
52
|
+
wordmark?: string;
|
|
53
|
+
tagline?: string;
|
|
54
|
+
/** Header/footer nav sections for the web-component chrome: label → entries. */
|
|
55
|
+
nav?: Record<string, ReadonlyArray<{
|
|
56
|
+
label: string;
|
|
57
|
+
href: string;
|
|
58
|
+
}>>;
|
|
59
|
+
logos?: string;
|
|
60
|
+
}
|
|
61
|
+
/** One follower site a leader can push CRM records to. The secret VALUE never
|
|
62
|
+
* lives in config: `secretName` names the leader tenant's vaulted copy of the
|
|
63
|
+
* follower's `network_share_secret`. */
|
|
64
|
+
interface ChapterNetworkTarget {
|
|
65
|
+
/** Stable lowercase slug used by the UI, audit tags, and default secret name. */
|
|
66
|
+
id: string;
|
|
67
|
+
/** Human-facing site name. Defaults to `id`. */
|
|
68
|
+
name?: string;
|
|
69
|
+
/** Absolute follower origin, e.g. `https://silver.example.com`. */
|
|
70
|
+
url: string;
|
|
71
|
+
/** Leader-vault key holding this follower's share secret. Defaults to
|
|
72
|
+
* `network_share_<id-with-underscores>`. */
|
|
73
|
+
secretName?: string;
|
|
74
|
+
/** Per-record-type field allowlist. If present, omitted types cannot be sent
|
|
75
|
+
* to this target. Without it, package-safe person/company defaults apply. */
|
|
76
|
+
fields?: Record<string, readonly string[]>;
|
|
77
|
+
}
|
|
78
|
+
/** Leader/follower network configuration. Followers need no code config to
|
|
79
|
+
* receive records; they only vault `network_share_secret`. */
|
|
80
|
+
interface ChapterNetwork {
|
|
81
|
+
targets?: readonly ChapterNetworkTarget[];
|
|
82
|
+
}
|
|
83
|
+
/** A validated network target carried on the resolved chapter engine. */
|
|
84
|
+
interface ResolvedNetworkTarget {
|
|
85
|
+
id: string;
|
|
86
|
+
name: string;
|
|
87
|
+
url: string;
|
|
88
|
+
secretName: string;
|
|
89
|
+
fields?: Record<string, readonly string[]>;
|
|
90
|
+
}
|
|
91
|
+
/** Fully-resolved leader network configuration. */
|
|
92
|
+
interface ResolvedNetwork {
|
|
93
|
+
targets: readonly ResolvedNetworkTarget[];
|
|
94
|
+
}
|
|
95
|
+
/** Membership pricing for the group row (chapter mode). */
|
|
96
|
+
interface ChapterPrices {
|
|
97
|
+
standardCents: number;
|
|
98
|
+
foundingDiscountCents?: number;
|
|
99
|
+
/** ISO currency, default "usd". */
|
|
100
|
+
currency?: string;
|
|
101
|
+
/** Billing interval, default "year". */
|
|
102
|
+
interval?: "year" | "month";
|
|
103
|
+
}
|
|
104
|
+
/** Membership policy + compliance copy stored on the group row. */
|
|
105
|
+
interface ChapterPolicy {
|
|
106
|
+
disclaimerText?: string;
|
|
107
|
+
refundPolicyText?: string;
|
|
108
|
+
trustCopy?: string;
|
|
109
|
+
commitmentText?: string;
|
|
110
|
+
normsText?: string;
|
|
111
|
+
}
|
|
112
|
+
/** One owner-editable transactional email template. */
|
|
113
|
+
interface EmailTemplate {
|
|
114
|
+
subject: string;
|
|
115
|
+
text: string;
|
|
116
|
+
enabled?: boolean;
|
|
117
|
+
}
|
|
118
|
+
/** Notification/reply/debug addresses + operational email templates. */
|
|
119
|
+
interface ChapterEmails {
|
|
120
|
+
notificationEmail: string;
|
|
121
|
+
replyTo?: string;
|
|
122
|
+
debugEmail?: string;
|
|
123
|
+
/** Operational lifecycle templates: adminNotification / paymentConfirmation /
|
|
124
|
+
* prepEmail / onboardingInvite, each `{ subject, text, enabled? }`. */
|
|
125
|
+
templates?: Record<string, EmailTemplate>;
|
|
126
|
+
}
|
|
127
|
+
/** Booking rules for the intro-call scheduler (stored as schedulingJson). */
|
|
128
|
+
interface ChapterScheduling {
|
|
129
|
+
slotMinutes?: number;
|
|
130
|
+
days?: readonly number[];
|
|
131
|
+
startHour?: number;
|
|
132
|
+
endHour?: number;
|
|
133
|
+
timezone?: string;
|
|
134
|
+
minNoticeHours?: number;
|
|
135
|
+
windowDays?: number;
|
|
136
|
+
summaryTemplate?: string;
|
|
137
|
+
}
|
|
138
|
+
/** How a signed-in user's role is determined.
|
|
139
|
+
*
|
|
140
|
+
* - `"claim"` reads a role ladder from a JWT claim (Silver & Salt's model:
|
|
141
|
+
* `provisional → member → admin`). Admin is the last (highest) rung; the
|
|
142
|
+
* read-only `superAdmins` tier sits above it.
|
|
143
|
+
* - `"table"` gates on the deny-all `admins` allowlist (Built Not Found's model):
|
|
144
|
+
* a binary "email is an admin or isn't", set only in odla Studio.
|
|
145
|
+
*
|
|
146
|
+
* Defaults: `"claim"` in `chapter` mode, `"table"` in `hub` mode. */
|
|
147
|
+
interface ChapterAuth {
|
|
148
|
+
source?: "claim" | "table";
|
|
149
|
+
/** JWT claim holding the role, for `source: "claim"`. Default `"role"`. */
|
|
150
|
+
claim?: string;
|
|
151
|
+
/** Role ladder low→high, for `source: "claim"`. The last entry is admin.
|
|
152
|
+
* Default `["provisional", "member", "admin"]`. */
|
|
153
|
+
ladder?: readonly string[];
|
|
154
|
+
/** Provision the read-only `superAdmins` tier table — the only tier that may
|
|
155
|
+
* create/modify admins, and (like every namespace) deny-all + written only in
|
|
156
|
+
* odla Studio. Default: `true` for `"claim"`, `false` for `"table"`. */
|
|
157
|
+
superAdmins?: boolean;
|
|
158
|
+
}
|
|
159
|
+
/** The fully-resolved auth policy (defaults applied) carried on the {@link Chapter}. */
|
|
160
|
+
interface ResolvedAuth {
|
|
161
|
+
source: "claim" | "table";
|
|
162
|
+
claim: string;
|
|
163
|
+
ladder: readonly string[];
|
|
164
|
+
/** The highest ladder rung (last entry) — the "admin" gate. */
|
|
165
|
+
adminRole: string;
|
|
166
|
+
superAdmins: boolean;
|
|
167
|
+
}
|
|
168
|
+
/** The application status pipeline. Which statuses exist, and the subsets a site
|
|
169
|
+
* allows a call to be booked from / an application approved from. Defaults to
|
|
170
|
+
* Silver & Salt's pipeline. Status never moves backwards (package-enforced). */
|
|
171
|
+
interface ChapterPipeline {
|
|
172
|
+
stages?: readonly string[];
|
|
173
|
+
bookableFrom?: readonly string[];
|
|
174
|
+
approvableFrom?: readonly string[];
|
|
175
|
+
/** The status a new application starts at. Default: the first stage. */
|
|
176
|
+
initial?: string;
|
|
177
|
+
}
|
|
178
|
+
/** The fully-resolved pipeline (defaults applied) carried on the {@link Chapter}. */
|
|
179
|
+
interface ResolvedPipeline {
|
|
180
|
+
stages: readonly string[];
|
|
181
|
+
bookableFrom: readonly string[];
|
|
182
|
+
approvableFrom: readonly string[];
|
|
183
|
+
initial: string;
|
|
184
|
+
}
|
|
185
|
+
/** The application (join form) validation surface — which string fields are
|
|
186
|
+
* required vs accepted, their max lengths, and the request body cap. Drives
|
|
187
|
+
* submit validation + the CRM slot projection; defaults to Silver & Salt's form.
|
|
188
|
+
* The `applications` schema attrs stay fixed (byte-equal to S&S); this is
|
|
189
|
+
* validation config, not schema generation. */
|
|
190
|
+
interface ChapterApplication {
|
|
191
|
+
required?: readonly string[];
|
|
192
|
+
optional?: readonly string[];
|
|
193
|
+
/** Per-field character cap. Fields not listed use `defaultMaxLen`. */
|
|
194
|
+
maxLen?: Record<string, number>;
|
|
195
|
+
defaultMaxLen?: number;
|
|
196
|
+
/** Max JSON request body in bytes. Default 32768. */
|
|
197
|
+
bodyCap?: number;
|
|
198
|
+
/** Reject a submit that carries no truthy `disclaimerAck` (400), instead of
|
|
199
|
+
* writing a row with no consent record. Default `false` for back-compat —
|
|
200
|
+
* but turn it on if the disclaimer is a compliance record: a missing ack is
|
|
201
|
+
* otherwise silent, permanent and unreconstructible. Failure is deterministic
|
|
202
|
+
* and surfaces on the first test submit, not intermittently in production. */
|
|
203
|
+
requireDisclaimerAck?: boolean;
|
|
204
|
+
/** Allowlist of fields that reach the Clerk account's client-readable
|
|
205
|
+
* `public_metadata.profile`. Default (unset) projects every non-identity
|
|
206
|
+
* configured field — convenient, but it also exposes free-text and
|
|
207
|
+
* third-party fields (`message`, `referral`). Set this to a curated list
|
|
208
|
+
* (e.g. `["phone", "state", "focus"]`) to keep confidential fields db-only.
|
|
209
|
+
* Expected to become required-in-spirit at 1.0. */
|
|
210
|
+
profileFields?: readonly string[];
|
|
211
|
+
/** Extra application fields carried into the one-way CRM projection, on top of
|
|
212
|
+
* the built-in identity/contact set. Each MUST be declared on your crm person
|
|
213
|
+
* type or the enrichment is dropped (the base person still projects). Default
|
|
214
|
+
* none. */
|
|
215
|
+
crmFields?: readonly string[];
|
|
216
|
+
/** Cap on the element count of array-valued fields (e.g. `focus`), so a client
|
|
217
|
+
* cannot post a 10k-element array into a row or into Clerk metadata.
|
|
218
|
+
* Non-primitive elements are dropped. Default 100. */
|
|
219
|
+
maxArrayLen?: number;
|
|
220
|
+
/** Validate that a field literally named `email` looks like an email address,
|
|
221
|
+
* returning a 400 rather than accepting input the downstream Clerk create will
|
|
222
|
+
* reject anyway. Default `true`; a valid application is never newly rejected. */
|
|
223
|
+
validateEmail?: boolean;
|
|
224
|
+
}
|
|
225
|
+
/** The fully-resolved application config carried on the {@link Chapter}. */
|
|
226
|
+
interface ResolvedApplication {
|
|
227
|
+
required: readonly string[];
|
|
228
|
+
optional: readonly string[];
|
|
229
|
+
maxLen: Record<string, number>;
|
|
230
|
+
defaultMaxLen: number;
|
|
231
|
+
bodyCap: number;
|
|
232
|
+
requireDisclaimerAck: boolean;
|
|
233
|
+
/** Resolved Clerk-metadata allowlist; `null` means "all non-identity fields". */
|
|
234
|
+
profileFields: readonly string[] | null;
|
|
235
|
+
crmFields: readonly string[];
|
|
236
|
+
maxArrayLen: number;
|
|
237
|
+
validateEmail: boolean;
|
|
238
|
+
}
|
|
239
|
+
/** The `defineChapter()` config a site fills in. */
|
|
240
|
+
interface ChapterConfig {
|
|
241
|
+
/** Slug: app id, tenant, group id, worker name. `[a-z0-9-]`. */
|
|
242
|
+
id: string;
|
|
243
|
+
name: string;
|
|
244
|
+
url?: string;
|
|
245
|
+
/** Default `"chapter"`. */
|
|
246
|
+
mode?: ChapterMode;
|
|
247
|
+
/** A `defineCrm()` config or a resolved `Crm`. Omit for the per-mode default. */
|
|
248
|
+
crm?: CrmConfig | Crm;
|
|
249
|
+
brand?: ChapterBrand;
|
|
250
|
+
/** Leader → follower delivery targets. Secret values stay in the leader
|
|
251
|
+
* tenant vault; see {@link ChapterNetworkTarget}. */
|
|
252
|
+
network?: ChapterNetwork;
|
|
253
|
+
thesis?: unknown;
|
|
254
|
+
/** Required in `chapter` mode. */
|
|
255
|
+
prices?: ChapterPrices;
|
|
256
|
+
policy?: ChapterPolicy;
|
|
257
|
+
/** `notificationEmail` required in `chapter` mode. */
|
|
258
|
+
emails?: ChapterEmails;
|
|
259
|
+
scheduling?: ChapterScheduling;
|
|
260
|
+
/** Application status pipeline (stages + bookable/approvable subsets). Defaults to S&S's. */
|
|
261
|
+
pipeline?: ChapterPipeline;
|
|
262
|
+
/** Join-form validation (required/optional fields, max lengths, body cap). */
|
|
263
|
+
application?: ChapterApplication;
|
|
264
|
+
/** Role source + ladder + super-admin tier. Defaults by mode (see {@link ChapterAuth}). */
|
|
265
|
+
auth?: ChapterAuth;
|
|
266
|
+
/** odla services (db implied). Default `["db","calendar","o11y"]`. */
|
|
267
|
+
services?: readonly string[];
|
|
268
|
+
/** Apply-time account provisioning. **Default `"none"`** — it provisions
|
|
269
|
+
* nothing, because the alternatives have an outbound side effect and a site
|
|
270
|
+
* that never made the choice must not be mailing people. `"create"` makes the
|
|
271
|
+
* Clerk account server-side (so join can say the account is ready);
|
|
272
|
+
* `"invite"` **emails the applicant a Clerk invitation**. Both non-default
|
|
273
|
+
* models need a `clerk_secret_key` vault secret to act. Opt in explicitly —
|
|
274
|
+
* leaving this unset provisions no accounts. */
|
|
275
|
+
account?: AccountModel;
|
|
276
|
+
/** WHEN lifecycle email fires. Addressing and content live on the group row
|
|
277
|
+
* (owner-editable at runtime); this is the trigger, which is a build-time
|
|
278
|
+
* decision. See {@link ChapterSends}. */
|
|
279
|
+
sends?: ChapterSends;
|
|
280
|
+
/** Site policy for admin operations (approve side effects, refund rules).
|
|
281
|
+
* See {@link ChapterOperations}. */
|
|
282
|
+
operations?: ChapterOperations;
|
|
283
|
+
}
|
|
284
|
+
/** Apply-time Clerk account provisioning model. */
|
|
285
|
+
type AccountModel = "invite" | "create" | "none";
|
|
286
|
+
/** Site policy for admin OPERATIONS: the DECISIONS, where the mechanics stay
|
|
287
|
+
* package-owned. Same model as {@link ChapterSends} — a site declares the rule,
|
|
288
|
+
* chapter enforces it. Distinct from {@link ChapterPolicy}, which is member-facing
|
|
289
|
+
* copy. (The privilege-escalation rules are NOT here: they are package-enforced
|
|
290
|
+
* in `canChangeRole`, gated on `auth.superAdmins`, so a site cannot weaken them.) */
|
|
291
|
+
interface ChapterOperations {
|
|
292
|
+
/** What approving an application does. */
|
|
293
|
+
onApprove?: {
|
|
294
|
+
/** Role to promote the applicant to in Clerk. Defaults to the ladder rung
|
|
295
|
+
* directly below admin (e.g. `"member"`); `false` promotes nobody. */
|
|
296
|
+
promoteTo?: string | false;
|
|
297
|
+
/** Group email template to send on approve. Default `"onboardingInvite"`;
|
|
298
|
+
* `false` sends nothing. */
|
|
299
|
+
send?: string | false;
|
|
300
|
+
};
|
|
301
|
+
/** Refund rules. */
|
|
302
|
+
refund?: {
|
|
303
|
+
/** Application statuses a refund may be issued from. Default: any status. */
|
|
304
|
+
allowedFrom?: readonly string[];
|
|
305
|
+
/** Also cancel the Stripe subscription. Default `true`. */
|
|
306
|
+
cancelSubscription?: boolean;
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
/** The fully-resolved {@link ChapterOperations} carried on the {@link Chapter}. */
|
|
310
|
+
interface ResolvedOperations {
|
|
311
|
+
onApprove: {
|
|
312
|
+
promoteTo: string | false;
|
|
313
|
+
send: string | false;
|
|
314
|
+
};
|
|
315
|
+
/** `allowedFrom: null` means "any status". */
|
|
316
|
+
refund: {
|
|
317
|
+
allowedFrom: readonly string[] | null;
|
|
318
|
+
cancelSubscription: boolean;
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
/** When the admin notification fires: on application `submit` (default), on the
|
|
322
|
+
* first successful `payment`, or `never` (the site drives it itself). */
|
|
323
|
+
type AdminNotificationTrigger = "submit" | "payment" | "never";
|
|
324
|
+
/** Send-policy config: the trigger for each lifecycle email chapter owns. */
|
|
325
|
+
interface ChapterSends {
|
|
326
|
+
adminNotification?: AdminNotificationTrigger;
|
|
327
|
+
}
|
|
328
|
+
/** Resolved send policy (every trigger present). */
|
|
329
|
+
interface ResolvedSends {
|
|
330
|
+
adminNotification: AdminNotificationTrigger;
|
|
331
|
+
}
|
|
332
|
+
/** The resolved engine `defineChapter()` returns. */
|
|
333
|
+
interface Chapter {
|
|
334
|
+
config: ChapterConfig;
|
|
335
|
+
id: string;
|
|
336
|
+
name: string;
|
|
337
|
+
url?: string;
|
|
338
|
+
mode: ChapterMode;
|
|
339
|
+
/** Resolved site identity. `wordmark` always falls back to `name`, so the
|
|
340
|
+
* admin/member UI never needs a second brand declaration. */
|
|
341
|
+
brand: ChapterBrand;
|
|
342
|
+
/** Validated follower targets for leader-driven record pushes. */
|
|
343
|
+
network: ResolvedNetwork;
|
|
344
|
+
/** Resolved CRM engine (from `defineCrm`). */
|
|
345
|
+
crm: Crm;
|
|
346
|
+
/** Resolved auth policy (source, claim, ladder, super-admin tier). */
|
|
347
|
+
auth: ResolvedAuth;
|
|
348
|
+
/** Resolved application status pipeline (stages + bookable/approvable subsets). */
|
|
349
|
+
pipeline: ResolvedPipeline;
|
|
350
|
+
/** Resolved join-form validation config. */
|
|
351
|
+
application: ResolvedApplication;
|
|
352
|
+
/** The chapter's own odla-db namespaces (mode-dependent; excludes `crm_*`). */
|
|
353
|
+
schema: DbSchema;
|
|
354
|
+
rules: DbRules;
|
|
355
|
+
services: readonly string[];
|
|
356
|
+
/** Resolved apply-time account provisioning model (default `"none"`). */
|
|
357
|
+
account: AccountModel;
|
|
358
|
+
/** Resolved send policy — when each lifecycle email fires. */
|
|
359
|
+
sends: ResolvedSends;
|
|
360
|
+
/** Resolved admin-operation policy (approve side effects, refund rules). */
|
|
361
|
+
operations: ResolvedOperations;
|
|
362
|
+
/** The seed `groups` row derived from config (chapter mode), else `null`. */
|
|
363
|
+
groupSeed(): Record<string, unknown> | null;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export type { Chapter as C, ChapterBrand as a };
|
package/dist/ui/admin/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { CrmClient, Crm, CrmRecord } from '@odla-ai/crm';
|
|
4
|
+
import { C as Chapter } from '../../types-D2fGiNG8.js';
|
|
4
5
|
|
|
5
6
|
/** What each admin section receives. `client` is a CrmClient bound to the
|
|
6
7
|
* signed-in admin's bearer token; `navigate` switches sections. */
|
|
@@ -16,6 +17,11 @@ interface AdminSection {
|
|
|
16
17
|
label: string;
|
|
17
18
|
render: (ctx: AdminSectionContext) => ReactNode;
|
|
18
19
|
}
|
|
20
|
+
/** How admin section state is reflected in the URL. Query routing is the
|
|
21
|
+
* host-independent default: `/admin/?tab=people` reloads through the same static
|
|
22
|
+
* file on SPA and multi-page sites alike. Path routing requires a host SPA
|
|
23
|
+
* fallback for every `/admin/<section>` URL. */
|
|
24
|
+
type AdminRouting = "query" | "path";
|
|
19
25
|
/** Wordmark shown in the gate and top bar. `name` is the plain-text identity (and
|
|
20
26
|
* the badge fallback); `wordmark` is an optional rich display node for brands
|
|
21
27
|
* whose typography can't be a plain string (e.g. an ampersand wrapped to render
|
|
@@ -25,11 +31,20 @@ type Brand = {
|
|
|
25
31
|
badge?: string;
|
|
26
32
|
wordmark?: ReactNode;
|
|
27
33
|
};
|
|
34
|
+
/** Resolve a section from the stable `?tab=` URL first, then a legacy path
|
|
35
|
+
* segment for backwards-compatible deep links. */
|
|
36
|
+
declare function adminSectionFromUrl(url: URL, basePath: string, sectionIds: readonly string[]): string;
|
|
37
|
+
/** Build the next section URL without depending on the static host's 404/SPA
|
|
38
|
+
* policy. Query mode collapses a legacy path route back to the admin mount. */
|
|
39
|
+
declare function adminSectionHref(current: URL, basePath: string, id: string, routing?: AdminRouting): string;
|
|
28
40
|
|
|
29
41
|
/** Props for {@link ChapterAdmin}. */
|
|
30
42
|
interface ChapterAdminProps {
|
|
31
|
-
/** The
|
|
32
|
-
|
|
43
|
+
/** The resolved site config. When present it supplies the brand and, unless
|
|
44
|
+
* `sections` is passed, the complete standard section catalog. */
|
|
45
|
+
chapter?: Chapter;
|
|
46
|
+
/** Explicit admin sections. Omit with `chapter` for the standard console. */
|
|
47
|
+
sections?: AdminSection[];
|
|
33
48
|
/** Admin mount path. The sign-in redirect + section routing derive from it,
|
|
34
49
|
* so the "bounce to home after sign-in" bug is impossible. Default "/admin". */
|
|
35
50
|
basePath?: string;
|
|
@@ -39,6 +54,10 @@ interface ChapterAdminProps {
|
|
|
39
54
|
crmBasePath?: string;
|
|
40
55
|
/** Origin for /api/config and /api/me. Default same origin. */
|
|
41
56
|
apiBase?: string;
|
|
57
|
+
/** Section URL strategy. Default `"query"` (`/admin/?tab=people`), which
|
|
58
|
+
* works with both SPA and ordinary static hosting. `"path"` requires the host
|
|
59
|
+
* to serve the admin entry for every `/admin/<section>` URL. */
|
|
60
|
+
routing?: AdminRouting;
|
|
42
61
|
}
|
|
43
62
|
/**
|
|
44
63
|
* The whole admin console for a chapter/hub: fetches the Clerk publishable key
|
|
@@ -49,6 +68,11 @@ interface ChapterAdminProps {
|
|
|
49
68
|
*/
|
|
50
69
|
declare function ChapterAdmin(props: ChapterAdminProps): react.JSX.Element;
|
|
51
70
|
|
|
71
|
+
/** Build the familiar admin surface from a chapter's configured CRM types.
|
|
72
|
+
* Hubs receive every CRM collection. Membership chapters additionally receive
|
|
73
|
+
* dashboard, meeting, availability, billing, and email operations. */
|
|
74
|
+
declare function defaultAdminSections(chapter: Chapter): AdminSection[];
|
|
75
|
+
|
|
52
76
|
/** Options for {@link peopleSection}. */
|
|
53
77
|
interface PeopleSectionOptions {
|
|
54
78
|
/** The chapter's resolved CRM engine — `chapter.crm` from defineChapter. */
|
|
@@ -155,6 +179,16 @@ interface RecordActionsProps {
|
|
|
155
179
|
* actions the record supports. */
|
|
156
180
|
declare function RecordActions({ getToken, record, roles, onChanged }: RecordActionsProps): react.JSX.Element | null;
|
|
157
181
|
|
|
182
|
+
/** Props for {@link NetworkShareActions}. */
|
|
183
|
+
interface NetworkShareActionsProps {
|
|
184
|
+
recordId: string;
|
|
185
|
+
recordType: string;
|
|
186
|
+
getToken: () => Promise<string | null>;
|
|
187
|
+
}
|
|
188
|
+
/** Render follower delivery buttons when this chapter configured network
|
|
189
|
+
* targets. Targets with an explicit type allowlist hide incompatible records. */
|
|
190
|
+
declare function NetworkShareActions(props: NetworkShareActionsProps): react.JSX.Element | null;
|
|
191
|
+
|
|
158
192
|
/** Fetch a JSON `/api/admin/*` route with the admin bearer token. Throws on a
|
|
159
193
|
* non-2xx (the body's `error`, else the status). */
|
|
160
194
|
declare function adminFetch<T = unknown>(getToken: () => Promise<string | null>, path: string, init?: RequestInit): Promise<T>;
|
|
@@ -188,4 +222,4 @@ declare function AdminNote({ children }: {
|
|
|
188
222
|
children: ReactNode;
|
|
189
223
|
}): react.JSX.Element;
|
|
190
224
|
|
|
191
|
-
export { AdminNote, AdminPage, type AdminResource, type AdminSection, type AdminSectionContext, type AvailabilitySectionOptions, type BillingSectionOptions, ChapterAdmin, type ChapterAdminProps, type CollectionSectionOptions, type DashboardSectionOptions, type EmailSectionOptions, type MeetingsSectionOptions, Panel, type PeopleSectionOptions, RecordActions, type RecordActionsProps, ThemeWarning, adminFetch, availabilitySection, billingSection, collectionSection, dashboardSection, emailSection, meetingsSection, peopleSection, useAdminResource };
|
|
225
|
+
export { AdminNote, AdminPage, type AdminResource, type AdminRouting, type AdminSection, type AdminSectionContext, type AvailabilitySectionOptions, type BillingSectionOptions, ChapterAdmin, type ChapterAdminProps, type CollectionSectionOptions, type DashboardSectionOptions, type EmailSectionOptions, type MeetingsSectionOptions, NetworkShareActions, type NetworkShareActionsProps, Panel, type PeopleSectionOptions, RecordActions, type RecordActionsProps, ThemeWarning, adminFetch, adminSectionFromUrl, adminSectionHref, availabilitySection, billingSection, collectionSection, dashboardSection, defaultAdminSections, emailSection, meetingsSection, peopleSection, useAdminResource };
|
package/dist/ui/admin/index.js
CHANGED
|
@@ -2,31 +2,40 @@ import {
|
|
|
2
2
|
AdminNote,
|
|
3
3
|
AdminPage,
|
|
4
4
|
ChapterAdmin,
|
|
5
|
+
NetworkShareActions,
|
|
5
6
|
Panel,
|
|
6
7
|
RecordActions,
|
|
7
8
|
ThemeWarning,
|
|
8
9
|
adminFetch,
|
|
10
|
+
adminSectionFromUrl,
|
|
11
|
+
adminSectionHref,
|
|
9
12
|
availabilitySection,
|
|
10
13
|
billingSection,
|
|
11
14
|
collectionSection,
|
|
12
15
|
dashboardSection,
|
|
16
|
+
defaultAdminSections,
|
|
13
17
|
emailSection,
|
|
14
18
|
meetingsSection,
|
|
15
19
|
peopleSection,
|
|
16
20
|
useAdminResource
|
|
17
|
-
} from "../../chunk-
|
|
21
|
+
} from "../../chunk-UIWFEESI.js";
|
|
22
|
+
import "../../chunk-MKXHZMAP.js";
|
|
18
23
|
export {
|
|
19
24
|
AdminNote,
|
|
20
25
|
AdminPage,
|
|
21
26
|
ChapterAdmin,
|
|
27
|
+
NetworkShareActions,
|
|
22
28
|
Panel,
|
|
23
29
|
RecordActions,
|
|
24
30
|
ThemeWarning,
|
|
25
31
|
adminFetch,
|
|
32
|
+
adminSectionFromUrl,
|
|
33
|
+
adminSectionHref,
|
|
26
34
|
availabilitySection,
|
|
27
35
|
billingSection,
|
|
28
36
|
collectionSection,
|
|
29
37
|
dashboardSection,
|
|
38
|
+
defaultAdminSections,
|
|
30
39
|
emailSection,
|
|
31
40
|
meetingsSection,
|
|
32
41
|
peopleSection,
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { AdminNote, AdminPage, AdminResource, AdminSection, AdminSectionContext, AvailabilitySectionOptions, BillingSectionOptions, ChapterAdmin, ChapterAdminProps, CollectionSectionOptions, DashboardSectionOptions, EmailSectionOptions, MeetingsSectionOptions, Panel, PeopleSectionOptions, RecordActions, RecordActionsProps, ThemeWarning, adminFetch, availabilitySection, billingSection, collectionSection, dashboardSection, emailSection, meetingsSection, peopleSection, useAdminResource } from './admin/index.js';
|
|
1
|
+
export { AdminNote, AdminPage, AdminResource, AdminRouting, AdminSection, AdminSectionContext, AvailabilitySectionOptions, BillingSectionOptions, ChapterAdmin, ChapterAdminProps, CollectionSectionOptions, DashboardSectionOptions, EmailSectionOptions, MeetingsSectionOptions, NetworkShareActions, NetworkShareActionsProps, Panel, PeopleSectionOptions, RecordActions, RecordActionsProps, ThemeWarning, adminFetch, adminSectionFromUrl, adminSectionHref, availabilitySection, billingSection, collectionSection, dashboardSection, defaultAdminSections, emailSection, meetingsSection, peopleSection, useAdminResource } from './admin/index.js';
|
|
2
2
|
export { ApiFn, BrandStyle, BrandStyleProps, JoinConfig, JoinIsland, JoinIslandProps, MembersArea, MembersAreaProps, PaymentStep, PaymentStepProps, RescheduleProps, Rescheduler, Slot, SlotPicker, SlotPickerClasses, SlotPickerProps, dayKey, dayLabel, fmtDate, fmtMoney, fullLabel, groupSlotsByDay, timeLabel, tzShort } from './member/index.js';
|
|
3
3
|
import 'react';
|
|
4
4
|
import '@odla-ai/crm';
|
|
5
|
+
import '../types-D2fGiNG8.js';
|
package/dist/ui/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
BrandStyle,
|
|
3
2
|
JoinIsland,
|
|
4
3
|
MembersArea,
|
|
5
4
|
PaymentStep,
|
|
@@ -13,24 +12,31 @@ import {
|
|
|
13
12
|
groupSlotsByDay,
|
|
14
13
|
timeLabel,
|
|
15
14
|
tzShort
|
|
16
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-LME2IHY5.js";
|
|
17
16
|
import {
|
|
18
17
|
AdminNote,
|
|
19
18
|
AdminPage,
|
|
20
19
|
ChapterAdmin,
|
|
20
|
+
NetworkShareActions,
|
|
21
21
|
Panel,
|
|
22
22
|
RecordActions,
|
|
23
23
|
ThemeWarning,
|
|
24
24
|
adminFetch,
|
|
25
|
+
adminSectionFromUrl,
|
|
26
|
+
adminSectionHref,
|
|
25
27
|
availabilitySection,
|
|
26
28
|
billingSection,
|
|
27
29
|
collectionSection,
|
|
28
30
|
dashboardSection,
|
|
31
|
+
defaultAdminSections,
|
|
29
32
|
emailSection,
|
|
30
33
|
meetingsSection,
|
|
31
34
|
peopleSection,
|
|
32
35
|
useAdminResource
|
|
33
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-UIWFEESI.js";
|
|
37
|
+
import {
|
|
38
|
+
BrandStyle
|
|
39
|
+
} from "../chunk-MKXHZMAP.js";
|
|
34
40
|
export {
|
|
35
41
|
AdminNote,
|
|
36
42
|
AdminPage,
|
|
@@ -38,6 +44,7 @@ export {
|
|
|
38
44
|
ChapterAdmin,
|
|
39
45
|
JoinIsland,
|
|
40
46
|
MembersArea,
|
|
47
|
+
NetworkShareActions,
|
|
41
48
|
Panel,
|
|
42
49
|
PaymentStep,
|
|
43
50
|
RecordActions,
|
|
@@ -45,12 +52,15 @@ export {
|
|
|
45
52
|
SlotPicker,
|
|
46
53
|
ThemeWarning,
|
|
47
54
|
adminFetch,
|
|
55
|
+
adminSectionFromUrl,
|
|
56
|
+
adminSectionHref,
|
|
48
57
|
availabilitySection,
|
|
49
58
|
billingSection,
|
|
50
59
|
collectionSection,
|
|
51
60
|
dashboardSection,
|
|
52
61
|
dayKey,
|
|
53
62
|
dayLabel,
|
|
63
|
+
defaultAdminSections,
|
|
54
64
|
emailSection,
|
|
55
65
|
fmtDate,
|
|
56
66
|
fmtMoney,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
+
import { a as ChapterBrand } from '../../types-D2fGiNG8.js';
|
|
4
|
+
import '@odla-ai/crm';
|
|
3
5
|
|
|
4
6
|
/** A bookable slot: a start instant in epoch milliseconds. */
|
|
5
7
|
interface Slot {
|
|
@@ -121,31 +123,6 @@ interface PaymentStepProps {
|
|
|
121
123
|
* → mount Stripe Elements → confirm. */
|
|
122
124
|
declare function PaymentStep(props: PaymentStepProps): react.JSX.Element;
|
|
123
125
|
|
|
124
|
-
/** Brand tokens that theme the site: palette, fonts, wordmark, nav, logos. */
|
|
125
|
-
interface ChapterBrand {
|
|
126
|
-
/** Palette overrides written into styles.css :root (e.g. `{ moss: "#2F3E34" }`
|
|
127
|
-
* or `--ui-*` token names). Applies in BOTH light and dark unless overridden
|
|
128
|
-
* by {@link paletteDark}. */
|
|
129
|
-
palette?: Record<string, string>;
|
|
130
|
-
/** Dark-mode palette overrides. Same shape as {@link palette}; emitted under
|
|
131
|
-
* `:root[data-theme="dark"]` and `@media (prefers-color-scheme: dark)`, so a
|
|
132
|
-
* site brands both modes. */
|
|
133
|
-
paletteDark?: Record<string, string>;
|
|
134
|
-
fonts?: {
|
|
135
|
-
display?: string;
|
|
136
|
-
body?: string;
|
|
137
|
-
numeral?: string;
|
|
138
|
-
};
|
|
139
|
-
wordmark?: string;
|
|
140
|
-
tagline?: string;
|
|
141
|
-
/** Header/footer nav sections for the web-component chrome: label → entries. */
|
|
142
|
-
nav?: Record<string, ReadonlyArray<{
|
|
143
|
-
label: string;
|
|
144
|
-
href: string;
|
|
145
|
-
}>>;
|
|
146
|
-
logos?: string;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
126
|
/** Props for {@link BrandStyle}. */
|
|
150
127
|
interface BrandStyleProps {
|
|
151
128
|
brand: ChapterBrand | undefined;
|
package/dist/ui/member/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
BrandStyle,
|
|
3
2
|
JoinIsland,
|
|
4
3
|
MembersArea,
|
|
5
4
|
PaymentStep,
|
|
@@ -13,7 +12,10 @@ import {
|
|
|
13
12
|
groupSlotsByDay,
|
|
14
13
|
timeLabel,
|
|
15
14
|
tzShort
|
|
16
|
-
} from "../../chunk-
|
|
15
|
+
} from "../../chunk-LME2IHY5.js";
|
|
16
|
+
import {
|
|
17
|
+
BrandStyle
|
|
18
|
+
} from "../../chunk-MKXHZMAP.js";
|
|
17
19
|
export {
|
|
18
20
|
BrandStyle,
|
|
19
21
|
JoinIsland,
|