@odla-ai/chapter 0.48.0 → 0.48.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +62 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -20
- package/dist/index.d.ts +22 -20
- package/dist/index.js +62 -21
- package/dist/index.js.map +1 -1
- package/dist/worker/index.cjs +183 -126
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.js +183 -126
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -270,6 +270,13 @@ module.exports = __toCommonJS(src_exports);
|
|
|
270
270
|
// src/config.ts
|
|
271
271
|
var import_crm2 = require("@odla-ai/crm");
|
|
272
272
|
|
|
273
|
+
// src/schema-account-policy.ts
|
|
274
|
+
var chapterAccountPolicy = { attrs: {
|
|
275
|
+
id: { type: "string", unique: true, indexed: true, optional: false },
|
|
276
|
+
metadata: { type: "string", unique: false, indexed: false, optional: false },
|
|
277
|
+
roles: { type: "json", unique: false, indexed: false, optional: false }
|
|
278
|
+
} };
|
|
279
|
+
|
|
273
280
|
// src/member.ts
|
|
274
281
|
var import_crm = require("@odla-ai/crm");
|
|
275
282
|
|
|
@@ -393,8 +400,10 @@ async function submitApplication(db, chapter, fields, opts) {
|
|
|
393
400
|
if (fields.focus !== void 0) row2.focus = clampArray(fields.focus, app.maxArrayLen);
|
|
394
401
|
if (opts.groupId) row2.groupId = opts.groupId;
|
|
395
402
|
if (opts.runtime) row2.stripeRuntime = opts.runtime;
|
|
403
|
+
if (chapter.account !== "none") row2.clerkAccountPending = true;
|
|
396
404
|
if (typeof fields.email === "string" && isValidEmail(fields.email.trim())) {
|
|
397
405
|
row2.emailNormalized = normalizeChapterEmail(fields.email);
|
|
406
|
+
row2.signupEmailKey = row2.emailNormalized;
|
|
398
407
|
}
|
|
399
408
|
if (opts.admissionGrant?.decision === "waive_interview") {
|
|
400
409
|
row2.admissionGrantId = opts.admissionGrant.id;
|
|
@@ -418,11 +427,21 @@ async function submitApplication(db, chapter, fields, opts) {
|
|
|
418
427
|
consumedApplicationId: id10
|
|
419
428
|
} });
|
|
420
429
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
430
|
+
try {
|
|
431
|
+
const { duplicate } = await db.transact(
|
|
432
|
+
ops,
|
|
433
|
+
opts.submissionId ? { mutationId: `join:${opts.submissionId}` } : void 0
|
|
434
|
+
);
|
|
435
|
+
return { ok: true, id: id10, duplicate, status: chapter.pipeline.initial, disclaimerAckAt: acked ? opts.now : null };
|
|
436
|
+
} catch (error) {
|
|
437
|
+
if (error.code === "unique_violation") return {
|
|
438
|
+
ok: false,
|
|
439
|
+
code: "account_already_exists",
|
|
440
|
+
status: 409,
|
|
441
|
+
error: "An account or application already exists for this email. Please sign in to continue."
|
|
442
|
+
};
|
|
443
|
+
throw error;
|
|
444
|
+
}
|
|
426
445
|
}
|
|
427
446
|
function joinConfig(group, paymentsReady2, tiers2 = [], conditions = {}) {
|
|
428
447
|
return {
|
|
@@ -497,6 +516,9 @@ var applicationAttrs = {
|
|
|
497
516
|
refundPolicyAckAt: attr("number", { optional: true }),
|
|
498
517
|
prepEmailSentAt: attr("number", { optional: true }),
|
|
499
518
|
canceled: attr("boolean", { optional: true }),
|
|
519
|
+
signupEmailKey: attr("string", { unique: true, indexed: true, optional: true }),
|
|
520
|
+
clerkInvitationSentAt: attr("number", { optional: true }),
|
|
521
|
+
clerkAccountPending: attr("boolean", { optional: true }),
|
|
500
522
|
emailNormalized: attr("string", { indexed: true, optional: true }),
|
|
501
523
|
admissionGrantId: attr("string", { unique: true, indexed: true, optional: true }),
|
|
502
524
|
admissionSource: attr("string", { indexed: true, optional: true }),
|
|
@@ -1169,6 +1191,7 @@ function chapterDb(mode, auth, includeNetworkNotes = false, application = resolv
|
|
|
1169
1191
|
entities.memberContentLocal = memberContentLocal;
|
|
1170
1192
|
}
|
|
1171
1193
|
}
|
|
1194
|
+
if (auth.source !== "table") entities.chapterAccountPolicy = chapterAccountPolicy;
|
|
1172
1195
|
if (auth.source === "table") entities.admins = admins;
|
|
1173
1196
|
if (auth.superAdminSource === "table") entities.superAdmins = superAdmins;
|
|
1174
1197
|
if (includeNetworkNotes) entities.networkNotes = networkNotes;
|
|
@@ -3248,6 +3271,12 @@ function createChapterIntegration(chapter, options = {}) {
|
|
|
3248
3271
|
...emails?.debugEmail ? { debugEmail: emails.debugEmail } : {}
|
|
3249
3272
|
});
|
|
3250
3273
|
const seeds = [...crmDesc.seeds ?? []];
|
|
3274
|
+
if (chapter.auth.source !== "table") seeds.push({
|
|
3275
|
+
id: "account-policy",
|
|
3276
|
+
ns: "chapterAccountPolicy",
|
|
3277
|
+
key: { attr: "id", value: chapter.id },
|
|
3278
|
+
attrs: { metadata: chapter.auth.source === "clerk" ? "private" : "public", roles: [...chapter.auth.ladder] }
|
|
3279
|
+
});
|
|
3251
3280
|
const group = chapter.groupSeed();
|
|
3252
3281
|
if (group) {
|
|
3253
3282
|
seeds.push({ id: "group", ns: "groups", key: { attr: "id", value: chapter.id }, attrs: { ...group, createdAt: now } });
|
|
@@ -7411,8 +7440,30 @@ async function stripeCall(sk, method, path, params, idempotencyKey) {
|
|
|
7411
7440
|
);
|
|
7412
7441
|
}
|
|
7413
7442
|
|
|
7443
|
+
// src/clerk-signup.ts
|
|
7444
|
+
async function findSignupAccount(secret, email, fetchImpl = fetch) {
|
|
7445
|
+
const response = await fetchImpl(`https://api.clerk.com/v1/users?email_address=${encodeURIComponent(normalizeChapterEmail(email))}&limit=2`, {
|
|
7446
|
+
headers: { authorization: `Bearer ${secret}` },
|
|
7447
|
+
redirect: "manual",
|
|
7448
|
+
signal: AbortSignal.timeout(5e3)
|
|
7449
|
+
});
|
|
7450
|
+
if (!response.ok) throw new Error("signup account lookup unavailable");
|
|
7451
|
+
const users = await response.json();
|
|
7452
|
+
if (!Array.isArray(users) || users.length > 1 || users.length === 1 && (typeof users[0]?.id !== "string" || !users[0].id)) {
|
|
7453
|
+
throw new Error("signup account lookup unavailable");
|
|
7454
|
+
}
|
|
7455
|
+
return users[0] ?? null;
|
|
7456
|
+
}
|
|
7457
|
+
function belongsToSignup(account, applicationId) {
|
|
7458
|
+
return typeof applicationId === "string" && applicationId.length > 0 && account.private_metadata?.applicationId === applicationId;
|
|
7459
|
+
}
|
|
7460
|
+
|
|
7414
7461
|
// src/clerk.ts
|
|
7415
|
-
|
|
7462
|
+
async function rejectedCreate(res) {
|
|
7463
|
+
const body = typeof res.json === "function" ? await res.json().catch(() => null) : null;
|
|
7464
|
+
const existed = Array.isArray(body?.errors) && body.errors.some((error) => error?.code === "form_identifier_exists" || error?.code === "duplicate_record");
|
|
7465
|
+
return { ok: false, status: res.status, ...existed ? { existed: true } : {} };
|
|
7466
|
+
}
|
|
7416
7467
|
function clerkInviteRequest(input) {
|
|
7417
7468
|
return {
|
|
7418
7469
|
path: "/v1/invitations",
|
|
@@ -7431,7 +7482,7 @@ async function createClerkInvitation(secretKey, input, fetchImpl = fetch) {
|
|
|
7431
7482
|
headers: { authorization: `Bearer ${secretKey}`, "content-type": "application/json" },
|
|
7432
7483
|
body: JSON.stringify(body)
|
|
7433
7484
|
});
|
|
7434
|
-
return res.ok ? { ok: true, status: res.status } :
|
|
7485
|
+
return res.ok ? { ok: true, status: res.status } : rejectedCreate(res);
|
|
7435
7486
|
}
|
|
7436
7487
|
function clerkUserRequest(input) {
|
|
7437
7488
|
return {
|
|
@@ -7483,20 +7534,10 @@ async function createClerkUser(secretKey, input, fetchImpl = fetch) {
|
|
|
7483
7534
|
...typeof body2?.id === "string" && body2.id ? { userId: body2.id } : {}
|
|
7484
7535
|
};
|
|
7485
7536
|
}
|
|
7486
|
-
const
|
|
7487
|
-
|
|
7488
|
-
const
|
|
7489
|
-
|
|
7490
|
-
...input.publicMetadata !== void 0 ? { publicMetadata: input.publicMetadata } : {},
|
|
7491
|
-
...input.privateMetadata !== void 0 ? { privateMetadata: input.privateMetadata } : {}
|
|
7492
|
-
};
|
|
7493
|
-
if (!healed.existed || repair.publicMetadata === void 0 && repair.privateMetadata === void 0) return healed;
|
|
7494
|
-
const userId = await existingClerkUserId(secretKey, input.email, fetchImpl).catch(() => null);
|
|
7495
|
-
const refreshed = userId ? await updateClerkUserMetadata(secretKey, userId, {
|
|
7496
|
-
...repair.publicMetadata !== void 0 ? { publicMetadata: repair.publicMetadata } : {},
|
|
7497
|
-
...repair.privateMetadata !== void 0 ? { privateMetadata: repair.privateMetadata } : {}
|
|
7498
|
-
}, fetchImpl).catch(() => false) : false;
|
|
7499
|
-
return { ...healed, refreshed, ...refreshed && userId ? { userId } : {} };
|
|
7537
|
+
const failure = await rejectedCreate(res);
|
|
7538
|
+
if (!failure.existed) return failure;
|
|
7539
|
+
const account = await findSignupAccount(secretKey, input.email, fetchImpl).catch(() => null);
|
|
7540
|
+
return account && belongsToSignup(account, input.privateMetadata?.applicationId) ? { ok: true, status: res.status, existed: true, userId: account.id } : failure;
|
|
7500
7541
|
}
|
|
7501
7542
|
|
|
7502
7543
|
// src/clerk-roles.ts
|