@odla-ai/chapter 0.40.1 → 0.40.2

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.
@@ -1648,7 +1648,14 @@ async function createClerkUser(secretKey, input, fetchImpl = fetch) {
1648
1648
  headers: { authorization: `Bearer ${secretKey}`, "content-type": "application/json" },
1649
1649
  body: JSON.stringify(body)
1650
1650
  });
1651
- if (res.ok) return { ok: true, status: res.status };
1651
+ if (res.ok) {
1652
+ const body2 = typeof res.json === "function" ? await res.json().catch(() => null) : null;
1653
+ return {
1654
+ ok: true,
1655
+ status: res.status,
1656
+ ...typeof body2?.id === "string" && body2.id ? { userId: body2.id } : {}
1657
+ };
1658
+ }
1652
1659
  const healed = heal(res.status);
1653
1660
  const repair = input.repairMetadata ?? {
1654
1661
  ...input.publicMetadata !== void 0 ? { publicMetadata: input.publicMetadata } : {},
@@ -1698,6 +1705,34 @@ async function syncApplicantPrivateMetadata(db, chapter, applicationId, fields,
1698
1705
  return false;
1699
1706
  }
1700
1707
  }
1708
+ var AccountProvisioningError = class extends Error {
1709
+ constructor(code, status) {
1710
+ super(code);
1711
+ this.code = code;
1712
+ this.status = status;
1713
+ }
1714
+ code;
1715
+ status;
1716
+ name = "AccountProvisioningError";
1717
+ };
1718
+ async function provisionApplicantForRoute(db, chapter, applicationId, fields) {
1719
+ try {
1720
+ await provisionApplicant(db, chapter, applicationId, fields);
1721
+ return null;
1722
+ } catch (error) {
1723
+ if (!(error instanceof AccountProvisioningError)) throw error;
1724
+ return {
1725
+ status: error.status,
1726
+ body: {
1727
+ error: {
1728
+ code: error.code,
1729
+ message: error.code === "clerk_secret_unavailable" ? "account provisioning credential is unavailable" : "account provisioning failed"
1730
+ },
1731
+ applicationId
1732
+ }
1733
+ };
1734
+ }
1735
+ }
1701
1736
  async function provisionApplicant(db, chapter, applicationId, fields) {
1702
1737
  const email = typeof fields.email === "string" ? fields.email : "";
1703
1738
  if (!email) return;
@@ -1722,9 +1757,9 @@ async function provisionApplicant(db, chapter, applicationId, fields) {
1722
1757
  } catch {
1723
1758
  }
1724
1759
  if (chapter.account === "none") return;
1760
+ const secret = await getVaultSecret(db, "clerk_secret_key");
1761
+ if (!secret) throw new AccountProvisioningError("clerk_secret_unavailable", 503);
1725
1762
  try {
1726
- const secret = await getVaultSecret(db, "clerk_secret_key");
1727
- if (!secret) return;
1728
1763
  const privateMetadata = applicantPrivateMetadata(chapter, applicationId, fields);
1729
1764
  if (chapter.account === "create") {
1730
1765
  const result = await createClerkUser(secret, {
@@ -1737,11 +1772,13 @@ async function provisionApplicant(db, chapter, applicationId, fields) {
1737
1772
  privateMetadata: applicantPrivateMetadata(chapter, applicationId, fields, true)
1738
1773
  }
1739
1774
  });
1740
- if (result.ok && (!result.existed || result.refreshed)) {
1741
- await markPrivateMetadataSynced(db, applicationId);
1775
+ if (!result.ok || result.existed && !result.refreshed) {
1776
+ throw new AccountProvisioningError("clerk_account_provisioning_failed", 502);
1742
1777
  }
1778
+ await markPrivateMetadataSynced(db, applicationId, result.userId);
1743
1779
  } else {
1744
1780
  const result = await createClerkInvitation(secret, { email });
1781
+ if (!result.ok) throw new AccountProvisioningError("clerk_account_provisioning_failed", 502);
1745
1782
  if (result.existed) {
1746
1783
  const refreshed = await updateClerkUserMetadataByEmail(secret, email, {
1747
1784
  publicMetadata: publicProfileRemoval,
@@ -1750,7 +1787,9 @@ async function provisionApplicant(db, chapter, applicationId, fields) {
1750
1787
  if (refreshed) await markPrivateMetadataSynced(db, applicationId);
1751
1788
  }
1752
1789
  }
1753
- } catch {
1790
+ } catch (error) {
1791
+ if (error instanceof AccountProvisioningError) throw error;
1792
+ throw new AccountProvisioningError("clerk_account_provisioning_failed", 502);
1754
1793
  }
1755
1794
  }
1756
1795
  async function notifyAdminOfApplication(db, env, chapterId, applicationId, fields) {
@@ -1974,8 +2013,9 @@ var handleMember = async (req, url, env, ctx) => {
1974
2013
  if (effectiveChapter.sends.adminNotification === "submit") {
1975
2014
  await notifyAdminOfApplication(db, env, chapter.id, result.id, parsed);
1976
2015
  }
1977
- await provisionApplicant(db, effectiveChapter, result.id, parsed);
1978
2016
  }
2017
+ const provisioningFailure = await provisionApplicantForRoute(db, effectiveChapter, result.id, parsed);
2018
+ if (provisioningFailure) return json(provisioningFailure.body, provisioningFailure.status);
1979
2019
  const apps = (await db.query({ applications: { $: { where: { id: result.id }, limit: 1 } } })).applications;
1980
2020
  const canonical2 = Array.isArray(apps) ? apps[0] : void 0;
1981
2021
  const groups = (await db.query({ groups: { $: { where: { id: chapter.id }, limit: 1 } } })).groups;