@odla-ai/chapter 0.7.0 → 0.8.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 +61 -13
- package/dist/index.cjs +30 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +30 -3
- package/dist/index.js.map +1 -1
- package/dist/worker/index.cjs +29 -4
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +9 -0
- package/dist/worker/index.d.ts +9 -0
- package/dist/worker/index.js +29 -4
- package/dist/worker/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -210,7 +210,14 @@ interface ChapterConfig {
|
|
|
210
210
|
auth?: ChapterAuth;
|
|
211
211
|
/** odla services (db implied). Default `["db","calendar","o11y"]`. */
|
|
212
212
|
services?: readonly string[];
|
|
213
|
-
|
|
213
|
+
/** Apply-time account provisioning: `"invite"` (default) mints a Clerk
|
|
214
|
+
* invitation, `"create"` makes the account server-side (so join can say the
|
|
215
|
+
* account is ready), `"none"` skips it. Any of these needs a `clerk_secret_key`
|
|
216
|
+
* vault secret to act. */
|
|
217
|
+
account?: AccountModel;
|
|
218
|
+
}
|
|
219
|
+
/** Apply-time Clerk account provisioning model. */
|
|
220
|
+
type AccountModel = "invite" | "create" | "none";
|
|
214
221
|
/** The resolved engine `defineChapter()` returns. */
|
|
215
222
|
interface Chapter {
|
|
216
223
|
config: ChapterConfig;
|
|
@@ -230,6 +237,8 @@ interface Chapter {
|
|
|
230
237
|
schema: DbSchema;
|
|
231
238
|
rules: DbRules;
|
|
232
239
|
services: readonly string[];
|
|
240
|
+
/** Resolved apply-time account provisioning model (default `"invite"`). */
|
|
241
|
+
account: AccountModel;
|
|
233
242
|
/** The seed `groups` row derived from config (chapter mode), else `null`. */
|
|
234
243
|
groupSeed(): Record<string, unknown> | null;
|
|
235
244
|
}
|
|
@@ -711,6 +720,25 @@ declare function createClerkInvitation(secretKey: string, input: ClerkInviteInpu
|
|
|
711
720
|
ok: boolean;
|
|
712
721
|
status: number;
|
|
713
722
|
}>;
|
|
723
|
+
/** Inputs for a server-side Clerk user create. */
|
|
724
|
+
interface ClerkUserInput {
|
|
725
|
+
email: string;
|
|
726
|
+
firstName?: string;
|
|
727
|
+
lastName?: string;
|
|
728
|
+
}
|
|
729
|
+
/** Build the Clerk Backend API user-create request. The account is created
|
|
730
|
+
* passwordless (the member signs in via the site's Clerk flow), so join step 3
|
|
731
|
+
* can say the account is ready — the "create" alternative to an invitation. */
|
|
732
|
+
declare function clerkUserRequest(input: ClerkUserInput): {
|
|
733
|
+
path: string;
|
|
734
|
+
body: Record<string, unknown>;
|
|
735
|
+
};
|
|
736
|
+
/** Create the applicant's Clerk account server-side. A repeat for a known email
|
|
737
|
+
* returns non-ok; the caller swallows it (best-effort at apply time). */
|
|
738
|
+
declare function createClerkUser(secretKey: string, input: ClerkUserInput, fetchImpl?: typeof fetch): Promise<{
|
|
739
|
+
ok: boolean;
|
|
740
|
+
status: number;
|
|
741
|
+
}>;
|
|
714
742
|
|
|
715
743
|
/** An application row, as far as the session cares about it. */
|
|
716
744
|
interface ApplicationRecord {
|
|
@@ -934,4 +962,4 @@ type ApplicationBookingPatch = {
|
|
|
934
962
|
* already there (never backward). */
|
|
935
963
|
declare function applicationBookingUpdate(currentStatus: string, startAt: number, htmlLink?: string | null): ApplicationBookingPatch;
|
|
936
964
|
|
|
937
|
-
export { 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 ChapterPipeline, type ChapterPolicy, type ChapterPrices, type ChapterScheduling, type ClerkInviteInput, type DbOp, type DbRules, type DbSchema, type DeliveryDecision, type EmailGroup, type EmailTemplate, type EmailTemplateRow, type Entity, type ExistingMeeting, type GuardResult, 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 ResolvedPipeline, type ResolvedScheduling, type RoleChangeContext, type Rule, SCHEDULING_DEFAULTS, type SecretStore, type SessionUser, type SharedPerson, type StripeEvent, type SubmitResult, type WebhookEvent, applicationBookingUpdate, applicationSummary, bookingDecision, brandTokens, buildGroupSeed, canApprove, canBook, canChangeRole, canTransition, canceledPatch, chapterDb, clerkInviteRequest, createChapterIntegration, createClerkInvitation, defaultCrm, defineChapter, emailGroupFrom, endForSlot, findApplicationRef, firstPaymentPatch, getVaultSecret, introIdempotencyKey, isAdminRole, isAlreadySent, isReconcilable, isSlotAvailable, joinConfig, meetingCreateRow, meetingRescheduleUpdate, memberApplication, memberSession, normalizeWebhookEvent, paymentsReady, planDelivery, projectApplicant, projectSharedRecord, reconcileMeetings, refundedPatch, render, renderSummary, renderTemplateBody, renewalPatch, resolveApplication, resolveAuth, resolvePipeline, resolveScheduling, roleFromClaim, sendTemplated, sharedPersonInput, slotWindow, stageIndex, stripeForm, submitApplication, subscriptionIdempotencyKey, verifyStripeSignature, webhookMutationId };
|
|
965
|
+
export { type AccountModel, 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 ChapterPipeline, type ChapterPolicy, type ChapterPrices, type ChapterScheduling, type ClerkInviteInput, type ClerkUserInput, type DbOp, type DbRules, type DbSchema, type DeliveryDecision, type EmailGroup, type EmailTemplate, type EmailTemplateRow, type Entity, type ExistingMeeting, type GuardResult, 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 ResolvedPipeline, type ResolvedScheduling, type RoleChangeContext, type Rule, SCHEDULING_DEFAULTS, type SecretStore, type SessionUser, type SharedPerson, type StripeEvent, type SubmitResult, type WebhookEvent, applicationBookingUpdate, applicationSummary, bookingDecision, brandTokens, buildGroupSeed, canApprove, canBook, canChangeRole, canTransition, canceledPatch, chapterDb, clerkInviteRequest, clerkUserRequest, createChapterIntegration, createClerkInvitation, createClerkUser, defaultCrm, defineChapter, emailGroupFrom, endForSlot, findApplicationRef, firstPaymentPatch, getVaultSecret, introIdempotencyKey, isAdminRole, isAlreadySent, isReconcilable, isSlotAvailable, joinConfig, meetingCreateRow, meetingRescheduleUpdate, memberApplication, memberSession, normalizeWebhookEvent, paymentsReady, planDelivery, projectApplicant, projectSharedRecord, reconcileMeetings, refundedPatch, render, renderSummary, renderTemplateBody, renewalPatch, resolveApplication, resolveAuth, resolvePipeline, resolveScheduling, roleFromClaim, sendTemplated, sharedPersonInput, slotWindow, stageIndex, stripeForm, submitApplication, subscriptionIdempotencyKey, verifyStripeSignature, webhookMutationId };
|
package/dist/index.d.ts
CHANGED
|
@@ -210,7 +210,14 @@ interface ChapterConfig {
|
|
|
210
210
|
auth?: ChapterAuth;
|
|
211
211
|
/** odla services (db implied). Default `["db","calendar","o11y"]`. */
|
|
212
212
|
services?: readonly string[];
|
|
213
|
-
|
|
213
|
+
/** Apply-time account provisioning: `"invite"` (default) mints a Clerk
|
|
214
|
+
* invitation, `"create"` makes the account server-side (so join can say the
|
|
215
|
+
* account is ready), `"none"` skips it. Any of these needs a `clerk_secret_key`
|
|
216
|
+
* vault secret to act. */
|
|
217
|
+
account?: AccountModel;
|
|
218
|
+
}
|
|
219
|
+
/** Apply-time Clerk account provisioning model. */
|
|
220
|
+
type AccountModel = "invite" | "create" | "none";
|
|
214
221
|
/** The resolved engine `defineChapter()` returns. */
|
|
215
222
|
interface Chapter {
|
|
216
223
|
config: ChapterConfig;
|
|
@@ -230,6 +237,8 @@ interface Chapter {
|
|
|
230
237
|
schema: DbSchema;
|
|
231
238
|
rules: DbRules;
|
|
232
239
|
services: readonly string[];
|
|
240
|
+
/** Resolved apply-time account provisioning model (default `"invite"`). */
|
|
241
|
+
account: AccountModel;
|
|
233
242
|
/** The seed `groups` row derived from config (chapter mode), else `null`. */
|
|
234
243
|
groupSeed(): Record<string, unknown> | null;
|
|
235
244
|
}
|
|
@@ -711,6 +720,25 @@ declare function createClerkInvitation(secretKey: string, input: ClerkInviteInpu
|
|
|
711
720
|
ok: boolean;
|
|
712
721
|
status: number;
|
|
713
722
|
}>;
|
|
723
|
+
/** Inputs for a server-side Clerk user create. */
|
|
724
|
+
interface ClerkUserInput {
|
|
725
|
+
email: string;
|
|
726
|
+
firstName?: string;
|
|
727
|
+
lastName?: string;
|
|
728
|
+
}
|
|
729
|
+
/** Build the Clerk Backend API user-create request. The account is created
|
|
730
|
+
* passwordless (the member signs in via the site's Clerk flow), so join step 3
|
|
731
|
+
* can say the account is ready — the "create" alternative to an invitation. */
|
|
732
|
+
declare function clerkUserRequest(input: ClerkUserInput): {
|
|
733
|
+
path: string;
|
|
734
|
+
body: Record<string, unknown>;
|
|
735
|
+
};
|
|
736
|
+
/** Create the applicant's Clerk account server-side. A repeat for a known email
|
|
737
|
+
* returns non-ok; the caller swallows it (best-effort at apply time). */
|
|
738
|
+
declare function createClerkUser(secretKey: string, input: ClerkUserInput, fetchImpl?: typeof fetch): Promise<{
|
|
739
|
+
ok: boolean;
|
|
740
|
+
status: number;
|
|
741
|
+
}>;
|
|
714
742
|
|
|
715
743
|
/** An application row, as far as the session cares about it. */
|
|
716
744
|
interface ApplicationRecord {
|
|
@@ -934,4 +962,4 @@ type ApplicationBookingPatch = {
|
|
|
934
962
|
* already there (never backward). */
|
|
935
963
|
declare function applicationBookingUpdate(currentStatus: string, startAt: number, htmlLink?: string | null): ApplicationBookingPatch;
|
|
936
964
|
|
|
937
|
-
export { 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 ChapterPipeline, type ChapterPolicy, type ChapterPrices, type ChapterScheduling, type ClerkInviteInput, type DbOp, type DbRules, type DbSchema, type DeliveryDecision, type EmailGroup, type EmailTemplate, type EmailTemplateRow, type Entity, type ExistingMeeting, type GuardResult, 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 ResolvedPipeline, type ResolvedScheduling, type RoleChangeContext, type Rule, SCHEDULING_DEFAULTS, type SecretStore, type SessionUser, type SharedPerson, type StripeEvent, type SubmitResult, type WebhookEvent, applicationBookingUpdate, applicationSummary, bookingDecision, brandTokens, buildGroupSeed, canApprove, canBook, canChangeRole, canTransition, canceledPatch, chapterDb, clerkInviteRequest, createChapterIntegration, createClerkInvitation, defaultCrm, defineChapter, emailGroupFrom, endForSlot, findApplicationRef, firstPaymentPatch, getVaultSecret, introIdempotencyKey, isAdminRole, isAlreadySent, isReconcilable, isSlotAvailable, joinConfig, meetingCreateRow, meetingRescheduleUpdate, memberApplication, memberSession, normalizeWebhookEvent, paymentsReady, planDelivery, projectApplicant, projectSharedRecord, reconcileMeetings, refundedPatch, render, renderSummary, renderTemplateBody, renewalPatch, resolveApplication, resolveAuth, resolvePipeline, resolveScheduling, roleFromClaim, sendTemplated, sharedPersonInput, slotWindow, stageIndex, stripeForm, submitApplication, subscriptionIdempotencyKey, verifyStripeSignature, webhookMutationId };
|
|
965
|
+
export { type AccountModel, 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 ChapterPipeline, type ChapterPolicy, type ChapterPrices, type ChapterScheduling, type ClerkInviteInput, type ClerkUserInput, type DbOp, type DbRules, type DbSchema, type DeliveryDecision, type EmailGroup, type EmailTemplate, type EmailTemplateRow, type Entity, type ExistingMeeting, type GuardResult, 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 ResolvedPipeline, type ResolvedScheduling, type RoleChangeContext, type Rule, SCHEDULING_DEFAULTS, type SecretStore, type SessionUser, type SharedPerson, type StripeEvent, type SubmitResult, type WebhookEvent, applicationBookingUpdate, applicationSummary, bookingDecision, brandTokens, buildGroupSeed, canApprove, canBook, canChangeRole, canTransition, canceledPatch, chapterDb, clerkInviteRequest, clerkUserRequest, createChapterIntegration, createClerkInvitation, createClerkUser, defaultCrm, defineChapter, emailGroupFrom, endForSlot, findApplicationRef, firstPaymentPatch, getVaultSecret, introIdempotencyKey, isAdminRole, isAlreadySent, isReconcilable, isSlotAvailable, joinConfig, meetingCreateRow, meetingRescheduleUpdate, memberApplication, memberSession, normalizeWebhookEvent, paymentsReady, planDelivery, projectApplicant, projectSharedRecord, reconcileMeetings, refundedPatch, render, renderSummary, renderTemplateBody, renewalPatch, resolveApplication, resolveAuth, resolvePipeline, resolveScheduling, roleFromClaim, sendTemplated, sharedPersonInput, slotWindow, stageIndex, stripeForm, submitApplication, subscriptionIdempotencyKey, verifyStripeSignature, webhookMutationId };
|
package/dist/index.js
CHANGED
|
@@ -226,7 +226,7 @@ Warmly,
|
|
|
226
226
|
${name}`;
|
|
227
227
|
return {
|
|
228
228
|
adminNotification: {
|
|
229
|
-
subject: `New application
|
|
229
|
+
subject: `New application: {{firstName}} {{lastName}}`,
|
|
230
230
|
text: `A new application came in for ${name}.
|
|
231
231
|
|
|
232
232
|
Name: {{firstName}} {{lastName}}
|
|
@@ -245,7 +245,7 @@ Your membership payment is confirmed. We'll be in touch to schedule your intro c
|
|
|
245
245
|
Looking forward to our call at {{meetingTime}}. {{meetingLink}}${sign}`
|
|
246
246
|
},
|
|
247
247
|
onboardingInvite: {
|
|
248
|
-
subject: `You're in
|
|
248
|
+
subject: `You're in, ${name}`,
|
|
249
249
|
text: `Hi {{firstName}},
|
|
250
250
|
|
|
251
251
|
Welcome to ${name}. Your member area is here: {{membersUrl}}${sign}`
|
|
@@ -470,6 +470,10 @@ function defineChapter(config) {
|
|
|
470
470
|
const application = resolveApplication(config.application);
|
|
471
471
|
const { schema, rules } = chapterDb(mode, auth);
|
|
472
472
|
const services = config.services ?? ["db", "calendar", "o11y"];
|
|
473
|
+
const account = config.account ?? "invite";
|
|
474
|
+
if (account !== "invite" && account !== "create" && account !== "none") {
|
|
475
|
+
throw new Error(`defineChapter.account: must be "invite", "create", or "none" \u2014 got "${String(account)}"`);
|
|
476
|
+
}
|
|
473
477
|
const chapter = {
|
|
474
478
|
config,
|
|
475
479
|
id: id2,
|
|
@@ -482,6 +486,7 @@ function defineChapter(config) {
|
|
|
482
486
|
schema,
|
|
483
487
|
rules,
|
|
484
488
|
services,
|
|
489
|
+
account,
|
|
485
490
|
groupSeed: () => mode === "chapter" ? buildGroupSeed(config) : null
|
|
486
491
|
};
|
|
487
492
|
if (config.url !== void 0) chapter.url = config.url;
|
|
@@ -508,7 +513,7 @@ function createChapterIntegration(chapter, options = {}) {
|
|
|
508
513
|
}
|
|
509
514
|
return {
|
|
510
515
|
id: "chapter",
|
|
511
|
-
title: `Chapter
|
|
516
|
+
title: `Chapter: ${chapter.name}`,
|
|
512
517
|
npm: "@odla-ai/chapter",
|
|
513
518
|
schema: {
|
|
514
519
|
entities: { ...crmDesc.schema.entities, ...chapter.schema.entities },
|
|
@@ -778,6 +783,26 @@ async function createClerkInvitation(secretKey, input, fetchImpl = fetch) {
|
|
|
778
783
|
});
|
|
779
784
|
return { ok: res.ok, status: res.status };
|
|
780
785
|
}
|
|
786
|
+
function clerkUserRequest(input) {
|
|
787
|
+
return {
|
|
788
|
+
path: "/v1/users",
|
|
789
|
+
body: {
|
|
790
|
+
email_address: [input.email],
|
|
791
|
+
skip_password_requirement: true,
|
|
792
|
+
...input.firstName ? { first_name: input.firstName } : {},
|
|
793
|
+
...input.lastName ? { last_name: input.lastName } : {}
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
async function createClerkUser(secretKey, input, fetchImpl = fetch) {
|
|
798
|
+
const { path, body } = clerkUserRequest(input);
|
|
799
|
+
const res = await fetchImpl(`https://api.clerk.com${path}`, {
|
|
800
|
+
method: "POST",
|
|
801
|
+
headers: { authorization: `Bearer ${secretKey}`, "content-type": "application/json" },
|
|
802
|
+
body: JSON.stringify(body)
|
|
803
|
+
});
|
|
804
|
+
return { ok: res.ok, status: res.status };
|
|
805
|
+
}
|
|
781
806
|
|
|
782
807
|
// src/session.ts
|
|
783
808
|
function applicationSummary(app) {
|
|
@@ -980,8 +1005,10 @@ export {
|
|
|
980
1005
|
canceledPatch,
|
|
981
1006
|
chapterDb,
|
|
982
1007
|
clerkInviteRequest,
|
|
1008
|
+
clerkUserRequest,
|
|
983
1009
|
createChapterIntegration,
|
|
984
1010
|
createClerkInvitation,
|
|
1011
|
+
createClerkUser,
|
|
985
1012
|
defaultCrm,
|
|
986
1013
|
defineChapter,
|
|
987
1014
|
emailGroupFrom,
|