@nlabs/reaktor 1.17.0 → 1.18.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.
Files changed (99) hide show
  1. package/README.md +182 -0
  2. package/docs/ASSISTANT.md +138 -0
  3. package/docs/GENERATION.md +15 -0
  4. package/docs/NATIVE_PUSH.md +56 -0
  5. package/lib/actions/alfredFaq.d.ts +80 -0
  6. package/lib/actions/alfredFaq.js +206 -0
  7. package/lib/actions/contentGeneration.d.ts +1 -0
  8. package/lib/actions/contentGeneration.js +25 -6
  9. package/lib/actions/conversations.d.ts +1 -1
  10. package/lib/actions/conversations.js +19 -9
  11. package/lib/actions/crud.js +26 -1
  12. package/lib/actions/index.d.ts +1 -0
  13. package/lib/actions/index.js +2 -1
  14. package/lib/actions/messages.js +23 -7
  15. package/lib/actions/users.js +57 -4
  16. package/lib/assistant/core.d.ts +53 -0
  17. package/lib/assistant/core.js +123 -0
  18. package/lib/assistant/faq.d.ts +26 -0
  19. package/lib/assistant/faq.js +238 -0
  20. package/lib/assistant/faqCore.d.ts +23 -0
  21. package/lib/assistant/faqCore.js +20 -0
  22. package/lib/assistant/index.d.ts +7 -0
  23. package/lib/assistant/index.js +5 -0
  24. package/lib/assistant/service.d.ts +35 -0
  25. package/lib/assistant/service.js +201 -0
  26. package/lib/durableChat/conversations.d.ts +62 -0
  27. package/lib/durableChat/conversations.js +729 -0
  28. package/lib/durableChat/errors.d.ts +6 -0
  29. package/lib/durableChat/errors.js +11 -0
  30. package/lib/durableChat/events.d.ts +22 -0
  31. package/lib/durableChat/events.js +50 -0
  32. package/lib/durableChat/index.d.ts +8 -0
  33. package/lib/durableChat/index.js +10 -0
  34. package/lib/durableChat/membership.d.ts +24 -0
  35. package/lib/durableChat/membership.js +85 -0
  36. package/lib/durableChat/messageTypes.d.ts +76 -0
  37. package/lib/durableChat/messageTypes.js +3 -0
  38. package/lib/durableChat/messages.d.ts +16 -0
  39. package/lib/durableChat/messages.js +257 -0
  40. package/lib/durableChat/transaction.d.ts +10 -0
  41. package/lib/durableChat/transaction.js +53 -0
  42. package/lib/durableChat/types.d.ts +81 -0
  43. package/lib/durableChat/types.js +3 -0
  44. package/lib/index.d.ts +4 -4
  45. package/lib/index.js +5 -3
  46. package/lib/lambdas/actions/websockets.js +4 -4
  47. package/lib/nativePush/graphql.d.ts +14 -0
  48. package/lib/nativePush/graphql.js +105 -0
  49. package/lib/nativePush/index.d.ts +7 -0
  50. package/lib/nativePush/index.js +9 -0
  51. package/lib/nativePush/migrations.d.ts +2 -0
  52. package/lib/nativePush/migrations.js +36 -0
  53. package/lib/nativePush/nativePushContract.fixture.d.ts +22 -0
  54. package/lib/nativePush/nativePushContract.fixture.js +27 -0
  55. package/lib/nativePush/payload.d.ts +2 -0
  56. package/lib/nativePush/payload.js +106 -0
  57. package/lib/nativePush/repository.d.ts +9 -0
  58. package/lib/nativePush/repository.js +120 -0
  59. package/lib/nativePush/service.d.ts +2 -0
  60. package/lib/nativePush/service.js +110 -0
  61. package/lib/nativePush/snsProvider.d.ts +17 -0
  62. package/lib/nativePush/snsProvider.js +165 -0
  63. package/lib/nativePush/types.d.ts +89 -0
  64. package/lib/nativePush/types.js +3 -0
  65. package/lib/organizations/accountLifecycle.d.ts +7 -0
  66. package/lib/organizations/accountLifecycle.js +106 -0
  67. package/lib/organizations/authorization.d.ts +9 -0
  68. package/lib/organizations/authorization.js +40 -0
  69. package/lib/organizations/billing.d.ts +38 -0
  70. package/lib/organizations/billing.js +277 -0
  71. package/lib/organizations/billingProvider.d.ts +4 -0
  72. package/lib/organizations/billingProvider.js +287 -0
  73. package/lib/organizations/billingUpdates.d.ts +9 -0
  74. package/lib/organizations/billingUpdates.js +388 -0
  75. package/lib/organizations/index.d.ts +10 -0
  76. package/lib/organizations/index.js +12 -0
  77. package/lib/organizations/mail.d.ts +10 -0
  78. package/lib/organizations/mail.js +60 -0
  79. package/lib/organizations/memberDirectory.d.ts +15 -0
  80. package/lib/organizations/memberDirectory.js +28 -0
  81. package/lib/organizations/membership.d.ts +19 -0
  82. package/lib/organizations/membership.js +248 -0
  83. package/lib/organizations/passwordRecovery.d.ts +9 -0
  84. package/lib/organizations/passwordRecovery.js +50 -0
  85. package/lib/organizations/plans.d.ts +6 -0
  86. package/lib/organizations/plans.js +40 -0
  87. package/lib/organizations/providerPagination.d.ts +6 -0
  88. package/lib/organizations/providerPagination.js +23 -0
  89. package/lib/organizations/reconciliation.d.ts +11 -0
  90. package/lib/organizations/reconciliation.js +400 -0
  91. package/lib/organizations/signup.d.ts +25 -0
  92. package/lib/organizations/signup.js +169 -0
  93. package/lib/organizations/store.d.ts +25 -0
  94. package/lib/organizations/store.js +167 -0
  95. package/lib/organizations/types.d.ts +138 -0
  96. package/lib/organizations/types.js +3 -0
  97. package/lib/organizations/verification.d.ts +3 -0
  98. package/lib/organizations/verification.js +51 -0
  99. package/package.json +16 -3
@@ -0,0 +1,40 @@
1
+ /* Stream-transaction steps and ordered retry assertions must execute sequentially. */ /* eslint-disable no-await-in-loop */ import { organizationKey, organizationStoreFor, requireIdentifier } from './store.js';
2
+ export const organizationUserId = (context)=>{
3
+ if (!context.session?.userId) {
4
+ throw new Error('authentication_required');
5
+ }
6
+ return requireIdentifier(context.session.userId.replace(/^users\//, ''));
7
+ };
8
+ export const organizationAccessInTransaction = async (tx, context, organizationId, role)=>{
9
+ const userId = organizationUserId(context);
10
+ const organization = await tx.get('organizations', requireIdentifier(organizationId));
11
+ const membership = await tx.get('organizationMemberships', organizationKey(organizationId, userId));
12
+ const user = await tx.get('users', userId);
13
+ if (!organization || !membership || membership.status !== 'active' || user?.active !== true || role === 'admin' && membership.role !== 'admin' || role === 'owner' && organization.ownerUserId !== userId) {
14
+ throw new Error('organization_access_denied');
15
+ }
16
+ return {
17
+ membership,
18
+ organization,
19
+ userId
20
+ };
21
+ };
22
+ export const requireOrganizationAccess = (context, organizationId, role)=>organizationStoreFor(context).transaction((tx)=>organizationAccessInTransaction(tx, context, organizationId, role));
23
+ export const listOrganizations = (context)=>organizationStoreFor(context).transaction(async (tx)=>{
24
+ const userId = organizationUserId(context);
25
+ const memberships = await tx.find('organizationMemberships', {
26
+ status: 'active',
27
+ userId
28
+ });
29
+ const result = [];
30
+ for (const membership of memberships){
31
+ const access = await organizationAccessInTransaction(tx, context, membership.organizationId, 'member');
32
+ result.push({
33
+ ...access.organization,
34
+ canManage: access.membership.role === 'admin'
35
+ });
36
+ }
37
+ return result;
38
+ }); /* Stream-transaction steps and ordered retry assertions must execute sequentially. */ /* ArangoDB document metadata uses these reserved field names. */ /* eslint no-underscore-dangle: ["warn", {"allow": ["_key", "_rev", "_id"]}] */
39
+
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3IvcGFja2FnZXMvcmVha3Rvci9zcmMvb3JnYW5pemF0aW9ucy9hdXRob3JpemF0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIFN0cmVhbS10cmFuc2FjdGlvbiBzdGVwcyBhbmQgb3JkZXJlZCByZXRyeSBhc3NlcnRpb25zIG11c3QgZXhlY3V0ZSBzZXF1ZW50aWFsbHkuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1hd2FpdC1pbi1sb29wICovXG5pbXBvcnQge1xuICBvcmdhbml6YXRpb25LZXksXG4gIG9yZ2FuaXphdGlvblN0b3JlRm9yLFxuICByZXF1aXJlSWRlbnRpZmllcixcbiAgdHlwZSBPcmdhbml6YXRpb25UcmFuc2FjdGlvblxufSBmcm9tICcuL3N0b3JlLmpzJztcblxuaW1wb3J0IHR5cGUge0FwaUNvbnRleHR9IGZyb20gJy4uL3R5cGVzL2F1dGgudHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge09yZ2FuaXphdGlvbiwgT3JnYW5pemF0aW9uQWNjZXNzLCBPcmdhbml6YXRpb25NZW1iZXJzaGlwfSBmcm9tICcuL3R5cGVzLmpzJztcblxuZXhwb3J0IGNvbnN0IG9yZ2FuaXphdGlvblVzZXJJZCA9IChjb250ZXh0OiBBcGlDb250ZXh0KTogc3RyaW5nID0+IHtcbiAgaWYoIWNvbnRleHQuc2Vzc2lvbj8udXNlcklkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdhdXRoZW50aWNhdGlvbl9yZXF1aXJlZCcpO1xuICB9XG4gIHJldHVybiByZXF1aXJlSWRlbnRpZmllcihjb250ZXh0LnNlc3Npb24udXNlcklkLnJlcGxhY2UoL151c2Vyc1xcLy8sICcnKSk7XG59O1xuXG5leHBvcnQgY29uc3Qgb3JnYW5pemF0aW9uQWNjZXNzSW5UcmFuc2FjdGlvbiA9IGFzeW5jIChcbiAgdHg6IE9yZ2FuaXphdGlvblRyYW5zYWN0aW9uLFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICBvcmdhbml6YXRpb25JZDogc3RyaW5nLFxuICByb2xlOiAnbWVtYmVyJyB8ICdhZG1pbicgfCAnb3duZXInXG4pOiBQcm9taXNlPE9yZ2FuaXphdGlvbkFjY2Vzcz4gPT4ge1xuICBjb25zdCB1c2VySWQgPSBvcmdhbml6YXRpb25Vc2VySWQoY29udGV4dCk7XG4gIGNvbnN0IG9yZ2FuaXphdGlvbiA9IGF3YWl0IHR4LmdldDxPcmdhbml6YXRpb24+KCdvcmdhbml6YXRpb25zJywgcmVxdWlyZUlkZW50aWZpZXIob3JnYW5pemF0aW9uSWQpKTtcbiAgY29uc3QgbWVtYmVyc2hpcCA9IGF3YWl0IHR4LmdldDxPcmdhbml6YXRpb25NZW1iZXJzaGlwPihcbiAgICAnb3JnYW5pemF0aW9uTWVtYmVyc2hpcHMnLFxuICAgIG9yZ2FuaXphdGlvbktleShvcmdhbml6YXRpb25JZCwgdXNlcklkKVxuICApO1xuICBjb25zdCB1c2VyID0gYXdhaXQgdHguZ2V0PHthY3RpdmU/OiBib29sZWFufT4oJ3VzZXJzJywgdXNlcklkKTtcbiAgaWYoXG4gICAgIW9yZ2FuaXphdGlvbiB8fFxuICAgICFtZW1iZXJzaGlwIHx8XG4gICAgbWVtYmVyc2hpcC5zdGF0dXMgIT09ICdhY3RpdmUnIHx8XG4gICAgdXNlcj8uYWN0aXZlICE9PSB0cnVlIHx8XG4gICAgKHJvbGUgPT09ICdhZG1pbicgJiYgbWVtYmVyc2hpcC5yb2xlICE9PSAnYWRtaW4nKSB8fFxuICAgIChyb2xlID09PSAnb3duZXInICYmIG9yZ2FuaXphdGlvbi5vd25lclVzZXJJZCAhPT0gdXNlcklkKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ29yZ2FuaXphdGlvbl9hY2Nlc3NfZGVuaWVkJyk7XG4gIH1cbiAgcmV0dXJuIHttZW1iZXJzaGlwLCBvcmdhbml6YXRpb24sIHVzZXJJZH07XG59O1xuXG5leHBvcnQgY29uc3QgcmVxdWlyZU9yZ2FuaXphdGlvbkFjY2VzcyA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgb3JnYW5pemF0aW9uSWQ6IHN0cmluZyxcbiAgcm9sZTogJ21lbWJlcicgfCAnYWRtaW4nIHwgJ293bmVyJ1xuKTogUHJvbWlzZTxPcmdhbml6YXRpb25BY2Nlc3M+ID0+XG4gIG9yZ2FuaXphdGlvblN0b3JlRm9yKGNvbnRleHQpLnRyYW5zYWN0aW9uKCh0eCkgPT5cbiAgICBvcmdhbml6YXRpb25BY2Nlc3NJblRyYW5zYWN0aW9uKHR4LCBjb250ZXh0LCBvcmdhbml6YXRpb25JZCwgcm9sZSlcbiAgKTtcblxuZXhwb3J0IGNvbnN0IGxpc3RPcmdhbml6YXRpb25zID0gKGNvbnRleHQ6IEFwaUNvbnRleHQpOiBQcm9taXNlPChPcmdhbml6YXRpb24gJiB7Y2FuTWFuYWdlOiBib29sZWFufSlbXT4gPT5cbiAgb3JnYW5pemF0aW9uU3RvcmVGb3IoY29udGV4dCkudHJhbnNhY3Rpb24oYXN5bmMgKHR4KSA9PiB7XG4gICAgY29uc3QgdXNlcklkID0gb3JnYW5pemF0aW9uVXNlcklkKGNvbnRleHQpO1xuICAgIGNvbnN0IG1lbWJlcnNoaXBzID0gYXdhaXQgdHguZmluZDxPcmdhbml6YXRpb25NZW1iZXJzaGlwPignb3JnYW5pemF0aW9uTWVtYmVyc2hpcHMnLCB7XG4gICAgICBzdGF0dXM6ICdhY3RpdmUnLFxuICAgICAgdXNlcklkXG4gICAgfSk7XG4gICAgY29uc3QgcmVzdWx0OiAoT3JnYW5pemF0aW9uICYge2Nhbk1hbmFnZTogYm9vbGVhbn0pW10gPSBbXTtcbiAgICBmb3IoY29uc3QgbWVtYmVyc2hpcCBvZiBtZW1iZXJzaGlwcykge1xuICAgICAgY29uc3QgYWNjZXNzID0gYXdhaXQgb3JnYW5pemF0aW9uQWNjZXNzSW5UcmFuc2FjdGlvbih0eCwgY29udGV4dCwgbWVtYmVyc2hpcC5vcmdhbml6YXRpb25JZCwgJ21lbWJlcicpO1xuICAgICAgcmVzdWx0LnB1c2goey4uLmFjY2Vzcy5vcmdhbml6YXRpb24sIGNhbk1hbmFnZTogYWNjZXNzLm1lbWJlcnNoaXAucm9sZSA9PT0gJ2FkbWluJ30pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9KTtcbi8qIFN0cmVhbS10cmFuc2FjdGlvbiBzdGVwcyBhbmQgb3JkZXJlZCByZXRyeSBhc3NlcnRpb25zIG11c3QgZXhlY3V0ZSBzZXF1ZW50aWFsbHkuICovXG5cbi8qIEFyYW5nb0RCIGRvY3VtZW50IG1ldGFkYXRhIHVzZXMgdGhlc2UgcmVzZXJ2ZWQgZmllbGQgbmFtZXMuICovXG4vKiBlc2xpbnQgbm8tdW5kZXJzY29yZS1kYW5nbGU6IFtcIndhcm5cIiwge1wiYWxsb3dcIjogW1wiX2tleVwiLCBcIl9yZXZcIiwgXCJfaWRcIl19XSAqL1xuIl0sIm5hbWVzIjpbIm9yZ2FuaXphdGlvbktleSIsIm9yZ2FuaXphdGlvblN0b3JlRm9yIiwicmVxdWlyZUlkZW50aWZpZXIiLCJvcmdhbml6YXRpb25Vc2VySWQiLCJjb250ZXh0Iiwic2Vzc2lvbiIsInVzZXJJZCIsIkVycm9yIiwicmVwbGFjZSIsIm9yZ2FuaXphdGlvbkFjY2Vzc0luVHJhbnNhY3Rpb24iLCJ0eCIsIm9yZ2FuaXphdGlvbklkIiwicm9sZSIsIm9yZ2FuaXphdGlvbiIsImdldCIsIm1lbWJlcnNoaXAiLCJ1c2VyIiwic3RhdHVzIiwiYWN0aXZlIiwib3duZXJVc2VySWQiLCJyZXF1aXJlT3JnYW5pemF0aW9uQWNjZXNzIiwidHJhbnNhY3Rpb24iLCJsaXN0T3JnYW5pemF0aW9ucyIsIm1lbWJlcnNoaXBzIiwiZmluZCIsInJlc3VsdCIsImFjY2VzcyIsInB1c2giLCJjYW5NYW5hZ2UiXSwibWFwcGluZ3MiOiJBQUFBLG9GQUFvRixHQUNwRixtQ0FBbUMsR0FDbkMsU0FDRUEsZUFBZSxFQUNmQyxvQkFBb0IsRUFDcEJDLGlCQUFpQixRQUVaLGFBQWE7QUFLcEIsT0FBTyxNQUFNQyxxQkFBcUIsQ0FBQ0M7SUFDakMsSUFBRyxDQUFDQSxRQUFRQyxPQUFPLEVBQUVDLFFBQVE7UUFDM0IsTUFBTSxJQUFJQyxNQUFNO0lBQ2xCO0lBQ0EsT0FBT0wsa0JBQWtCRSxRQUFRQyxPQUFPLENBQUNDLE1BQU0sQ0FBQ0UsT0FBTyxDQUFDLFlBQVk7QUFDdEUsRUFBRTtBQUVGLE9BQU8sTUFBTUMsa0NBQWtDLE9BQzdDQyxJQUNBTixTQUNBTyxnQkFDQUM7SUFFQSxNQUFNTixTQUFTSCxtQkFBbUJDO0lBQ2xDLE1BQU1TLGVBQWUsTUFBTUgsR0FBR0ksR0FBRyxDQUFlLGlCQUFpQlosa0JBQWtCUztJQUNuRixNQUFNSSxhQUFhLE1BQU1MLEdBQUdJLEdBQUcsQ0FDN0IsMkJBQ0FkLGdCQUFnQlcsZ0JBQWdCTDtJQUVsQyxNQUFNVSxPQUFPLE1BQU1OLEdBQUdJLEdBQUcsQ0FBcUIsU0FBU1I7SUFDdkQsSUFDRSxDQUFDTyxnQkFDRCxDQUFDRSxjQUNEQSxXQUFXRSxNQUFNLEtBQUssWUFDdEJELE1BQU1FLFdBQVcsUUFDaEJOLFNBQVMsV0FBV0csV0FBV0gsSUFBSSxLQUFLLFdBQ3hDQSxTQUFTLFdBQVdDLGFBQWFNLFdBQVcsS0FBS2IsUUFDbEQ7UUFDQSxNQUFNLElBQUlDLE1BQU07SUFDbEI7SUFDQSxPQUFPO1FBQUNRO1FBQVlGO1FBQWNQO0lBQU07QUFDMUMsRUFBRTtBQUVGLE9BQU8sTUFBTWMsNEJBQTRCLENBQ3ZDaEIsU0FDQU8sZ0JBQ0FDLE9BRUFYLHFCQUFxQkcsU0FBU2lCLFdBQVcsQ0FBQyxDQUFDWCxLQUN6Q0QsZ0NBQWdDQyxJQUFJTixTQUFTTyxnQkFBZ0JDLE9BQzdEO0FBRUosT0FBTyxNQUFNVSxvQkFBb0IsQ0FBQ2xCLFVBQ2hDSCxxQkFBcUJHLFNBQVNpQixXQUFXLENBQUMsT0FBT1g7UUFDL0MsTUFBTUosU0FBU0gsbUJBQW1CQztRQUNsQyxNQUFNbUIsY0FBYyxNQUFNYixHQUFHYyxJQUFJLENBQXlCLDJCQUEyQjtZQUNuRlAsUUFBUTtZQUNSWDtRQUNGO1FBQ0EsTUFBTW1CLFNBQWtELEVBQUU7UUFDMUQsS0FBSSxNQUFNVixjQUFjUSxZQUFhO1lBQ25DLE1BQU1HLFNBQVMsTUFBTWpCLGdDQUFnQ0MsSUFBSU4sU0FBU1csV0FBV0osY0FBYyxFQUFFO1lBQzdGYyxPQUFPRSxJQUFJLENBQUM7Z0JBQUMsR0FBR0QsT0FBT2IsWUFBWTtnQkFBRWUsV0FBV0YsT0FBT1gsVUFBVSxDQUFDSCxJQUFJLEtBQUs7WUFBTztRQUNwRjtRQUNBLE9BQU9hO0lBQ1QsR0FBRyxDQUNMLG9GQUFvRixJQUVwRiwrREFBK0QsSUFDL0QsNkVBQTZFIn0=
@@ -0,0 +1,38 @@
1
+ import { type OrganizationTransaction } from './store.js';
2
+ import type { ApiContext } from '../types/auth.types.js';
3
+ import type { CheckoutResult, MembershipChange, OrganizationMembership, OveragePreference, PlanKey, ProviderSubscription, SeatChangeQuote, SubscriptionSummary } from './types.js';
4
+ export type CheckoutAttempt = Readonly<{
5
+ generation: number;
6
+ key: string;
7
+ leaseExpires: number;
8
+ owner: string;
9
+ plan: PlanKey;
10
+ quantity: number;
11
+ sequence: number;
12
+ session?: CheckoutResult;
13
+ }>;
14
+ export type OrganizationBilling = Readonly<{
15
+ checkout?: CheckoutAttempt;
16
+ customerId: string;
17
+ organizationId: string;
18
+ overage?: OveragePreference;
19
+ pendingChange?: string | null;
20
+ periodEnd?: number | null;
21
+ plan?: PlanKey | null;
22
+ status?: string;
23
+ subscription?: ProviderSubscription | null;
24
+ }>;
25
+ export declare const requireBillingAdmin: (tx: OrganizationTransaction, context: ApiContext, organizationId: string) => Promise<{
26
+ membership: OrganizationMembership;
27
+ organization: import("./types.js").Organization;
28
+ userId: string;
29
+ email: string;
30
+ }>;
31
+ export declare const getOrganizationSubscription: (context: ApiContext, organizationId: string) => Promise<SubscriptionSummary>;
32
+ export declare const createOrganizationCheckout: (context: ApiContext, organizationId: string, plan: PlanKey, requestId: string) => Promise<{
33
+ url: string;
34
+ }>;
35
+ export declare const createOrganizationBillingPortal: (context: ApiContext, organizationId: string) => Promise<{
36
+ url: string;
37
+ }>;
38
+ export declare const quoteOrganizationSeatChange: (context: ApiContext, organizationId: string, change: MembershipChange) => Promise<SeatChangeQuote>;
@@ -0,0 +1,277 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { organizationAccessInTransaction } from './authorization.js';
3
+ import { getOrganizationBillingProvider, organizationBillingMode } from './billingProvider.js';
4
+ import { activeMemberCount } from './membership.js';
5
+ import { calculateSeatCharge, getOrganizationPlan } from './plans.js';
6
+ import { organizationKey, organizationStoreFor, requireIdentifier } from './store.js';
7
+ export const requireBillingAdmin = async (tx, context, organizationId)=>{
8
+ const access = await organizationAccessInTransaction(tx, context, organizationId, 'admin');
9
+ const user = await tx.get('users', access.userId);
10
+ if (!user?.verifiedEmail) {
11
+ throw new Error('email_verification_required');
12
+ }
13
+ return {
14
+ ...access,
15
+ email: user.email
16
+ };
17
+ };
18
+ const requireBillingEnabled = ()=>{
19
+ if (organizationBillingMode() !== 'test') {
20
+ throw new Error('billing_disabled');
21
+ }
22
+ };
23
+ export const getOrganizationSubscription = (context, organizationId)=>organizationStoreFor(context).transaction(async (tx)=>{
24
+ const access = await organizationAccessInTransaction(tx, context, organizationId, 'member');
25
+ const billing = await tx.get('organizationBilling', organizationId);
26
+ const activeMembers = await activeMemberCount(tx, organizationId);
27
+ const charge = billing?.plan ? calculateSeatCharge(billing.plan, activeMembers) : {
28
+ extraSeats: Math.max(0, activeMembers - 10),
29
+ monthlyCents: 0
30
+ };
31
+ const jobs = await tx.find('organizationBillingJobs', {
32
+ organizationId,
33
+ status: 'pending'
34
+ });
35
+ return {
36
+ activeMembers,
37
+ billingMode: organizationBillingMode(),
38
+ canManage: access.membership.role === 'admin',
39
+ estimatedMonthlyCents: charge.monthlyCents,
40
+ extraSeats: charge.extraSeats,
41
+ metersEnabled: false,
42
+ organizationId,
43
+ overage: billing?.overage || {
44
+ enabled: false,
45
+ monthlyCapCents: 0,
46
+ revision: 0
47
+ },
48
+ pendingChange: billing?.pendingChange || null,
49
+ periodEnd: billing?.periodEnd || null,
50
+ plan: billing?.plan || null,
51
+ reconciliationPending: jobs.some((job)=>job.kind !== 'mail'),
52
+ status: billing?.status || 'none'
53
+ };
54
+ });
55
+ export const createOrganizationCheckout = async (context, organizationId, plan, requestId)=>{
56
+ getOrganizationPlan(plan);
57
+ requireIdentifier(requestId);
58
+ requireBillingEnabled();
59
+ const store = organizationStoreFor(context);
60
+ const owner = randomUUID();
61
+ const pending = await store.transaction(async (tx)=>{
62
+ const access = await requireBillingAdmin(tx, context, organizationId);
63
+ const old = await tx.get('organizationBilling', organizationId);
64
+ if (old?.plan && ![
65
+ 'canceled',
66
+ 'incomplete_expired'
67
+ ].includes(old.status || '')) {
68
+ throw new Error('subscription_exists');
69
+ }
70
+ if (old?.subscription && (await tx.find('organizationBillingJobs', {
71
+ organizationId,
72
+ status: 'pending'
73
+ })).some((job)=>job.kind !== 'mail')) {
74
+ throw new Error('billing_reconciliation_pending');
75
+ }
76
+ const previous = old?.checkout;
77
+ if (previous?.session && previous.session.expiresAt > Date.now()) {
78
+ if (previous.plan !== plan) {
79
+ throw new Error('checkout_in_progress');
80
+ }
81
+ return {
82
+ cached: previous.session.url
83
+ };
84
+ }
85
+ if (previous && previous.leaseExpires > Date.now()) {
86
+ throw new Error('checkout_busy');
87
+ }
88
+ // An unknown provider outcome must retain its key, even beyond Stripe's 24h cache.
89
+ if (previous && !previous.session && previous.plan !== plan) {
90
+ throw new Error('checkout_in_progress');
91
+ }
92
+ const generation = previous ? previous.generation + Number(Boolean(previous.session)) : 1;
93
+ const quantity = calculateSeatCharge(plan, await activeMemberCount(tx, organizationId)).extraSeats;
94
+ const checkout = previous && !previous.session ? {
95
+ ...previous,
96
+ leaseExpires: Date.now() + 60000,
97
+ owner
98
+ } : {
99
+ generation,
100
+ key: organizationKey('checkout', organizationId, String(generation)),
101
+ leaseExpires: Date.now() + 60000,
102
+ owner,
103
+ plan,
104
+ quantity,
105
+ sequence: access.organization.revision
106
+ };
107
+ const billing = {
108
+ ...old,
109
+ checkout,
110
+ customerId: old?.customerId || '',
111
+ organizationId
112
+ };
113
+ await tx.put('organizationBilling', organizationId, billing, old);
114
+ return {
115
+ billing,
116
+ email: access.email
117
+ };
118
+ });
119
+ if ('cached' in pending) {
120
+ return {
121
+ url: pending.cached
122
+ };
123
+ }
124
+ const fenced = async (patch)=>store.transaction(async (tx)=>{
125
+ const current = await tx.get('organizationBilling', organizationId);
126
+ if (current?.checkout?.owner !== owner) {
127
+ throw new Error('checkout_lease_lost');
128
+ }
129
+ await tx.put('organizationBilling', organizationId, {
130
+ ...current,
131
+ ...patch
132
+ }, current);
133
+ });
134
+ try {
135
+ const provider = await getOrganizationBillingProvider();
136
+ let { customerId } = pending.billing;
137
+ if (!customerId) {
138
+ customerId = await provider.customer(organizationId, pending.email);
139
+ await fenced({
140
+ customerId
141
+ });
142
+ }
143
+ if (await provider.retrieve(customerId)) {
144
+ throw new Error('subscription_exists');
145
+ }
146
+ const attempt = pending.billing.checkout;
147
+ await store.transaction(async (tx)=>{
148
+ await requireBillingAdmin(tx, context, organizationId);
149
+ const current = await tx.get('organizationBilling', organizationId);
150
+ if (current?.checkout?.owner !== owner) {
151
+ throw new Error('checkout_lease_lost');
152
+ }
153
+ });
154
+ const session = await provider.checkout(customerId, attempt.plan, attempt.quantity, attempt.key);
155
+ // Persist the exact provider outcome before exposing its redirect.
156
+ await fenced({
157
+ checkout: {
158
+ ...attempt,
159
+ leaseExpires: 0,
160
+ owner: '',
161
+ session
162
+ }
163
+ });
164
+ if (session.expiresAt <= Date.now() || !session.url) {
165
+ throw new Error('checkout_expired');
166
+ }
167
+ return {
168
+ url: session.url
169
+ };
170
+ } catch (error) {
171
+ await store.transaction(async (tx)=>{
172
+ const current = await tx.get('organizationBilling', organizationId);
173
+ if (current?.checkout?.owner === owner) {
174
+ await tx.put('organizationBilling', organizationId, {
175
+ ...current,
176
+ checkout: {
177
+ ...current.checkout,
178
+ leaseExpires: 0,
179
+ owner: ''
180
+ }
181
+ }, current);
182
+ }
183
+ });
184
+ if (error instanceof Error && [
185
+ 'subscription_exists',
186
+ 'checkout_expired',
187
+ 'checkout_in_progress',
188
+ 'checkout_lease_lost'
189
+ ].includes(error.message)) {
190
+ throw error;
191
+ }
192
+ throw new Error('billing_provider_unavailable');
193
+ }
194
+ };
195
+ export const createOrganizationBillingPortal = async (context, organizationId)=>{
196
+ requireBillingEnabled();
197
+ const customerId = await organizationStoreFor(context).transaction(async (tx)=>{
198
+ await requireBillingAdmin(tx, context, organizationId);
199
+ const billing = await tx.get('organizationBilling', organizationId);
200
+ if (!billing?.customerId) {
201
+ throw new Error('billing_customer_required');
202
+ }
203
+ return billing.customerId;
204
+ });
205
+ const provider = await getOrganizationBillingProvider();
206
+ return {
207
+ url: await provider.portal(customerId)
208
+ };
209
+ };
210
+ export const quoteOrganizationSeatChange = async (context, organizationId, change)=>{
211
+ requireBillingEnabled();
212
+ const store = organizationStoreFor(context);
213
+ const intent = await store.transaction(async (tx)=>{
214
+ const access = await requireBillingAdmin(tx, context, organizationId);
215
+ const member = await tx.get('organizationMemberships', organizationKey(organizationId, requireIdentifier(change.userId)));
216
+ if (!member || member.revision !== change.expectedRevision || ![
217
+ 'admin',
218
+ 'member'
219
+ ].includes(change.role) || ![
220
+ 'active',
221
+ 'deactivated'
222
+ ].includes(change.status)) {
223
+ throw new Error('invalid_membership');
224
+ }
225
+ if (member.userId === access.organization.ownerUserId && (change.role !== 'admin' || change.status !== 'active')) {
226
+ throw new Error('ownership_transfer_required');
227
+ }
228
+ const user = await tx.get('users', change.userId);
229
+ if (change.status === 'active' && (!user?.active || !user.verifiedEmail)) {
230
+ throw new Error('verified_active_user_required');
231
+ }
232
+ const billing = await tx.get('organizationBilling', organizationId);
233
+ if (!billing?.customerId || billing.status !== 'active') {
234
+ throw new Error('billing_not_ready');
235
+ }
236
+ const quantity = Math.max(0, await activeMemberCount(tx, organizationId) + Number(change.status === 'active') - Number(member.status === 'active') - 10);
237
+ return {
238
+ customerId: billing.customerId,
239
+ organization: access.organization,
240
+ quantity
241
+ };
242
+ });
243
+ const provider = await getOrganizationBillingProvider();
244
+ const subscription = await provider.retrieve(intent.customerId);
245
+ if (!subscription || subscription.status !== 'active') {
246
+ throw new Error('billing_not_ready');
247
+ }
248
+ const effectiveAt = Date.now();
249
+ const prorationCents = await provider.preview(subscription, subscription.plan, intent.quantity, effectiveAt);
250
+ const quote = {
251
+ currency: 'usd',
252
+ expiresAt: effectiveAt + 300000,
253
+ organizationRevision: intent.organization.revision,
254
+ prorationCents,
255
+ quantity: intent.quantity,
256
+ quoteId: randomUUID()
257
+ };
258
+ await store.transaction(async (tx)=>{
259
+ const access = await requireBillingAdmin(tx, context, organizationId);
260
+ if (access.organization.revision !== quote.organizationRevision) {
261
+ throw new Error('revision_conflict');
262
+ }
263
+ await tx.put('organizationBillingQuotes', quote.quoteId, {
264
+ ...quote,
265
+ effectiveAt,
266
+ expectedRevision: change.expectedRevision,
267
+ organizationId,
268
+ role: change.role,
269
+ status: change.status,
270
+ used: false,
271
+ userId: change.userId
272
+ });
273
+ });
274
+ return quote;
275
+ };
276
+
277
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3IvcGFja2FnZXMvcmVha3Rvci9zcmMvb3JnYW5pemF0aW9ucy9iaWxsaW5nLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7cmFuZG9tVVVJRH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuXG5pbXBvcnQge29yZ2FuaXphdGlvbkFjY2Vzc0luVHJhbnNhY3Rpb259IGZyb20gJy4vYXV0aG9yaXphdGlvbi5qcyc7XG5pbXBvcnQge2dldE9yZ2FuaXphdGlvbkJpbGxpbmdQcm92aWRlciwgb3JnYW5pemF0aW9uQmlsbGluZ01vZGV9IGZyb20gJy4vYmlsbGluZ1Byb3ZpZGVyLmpzJztcbmltcG9ydCB7YWN0aXZlTWVtYmVyQ291bnR9IGZyb20gJy4vbWVtYmVyc2hpcC5qcyc7XG5pbXBvcnQge2NhbGN1bGF0ZVNlYXRDaGFyZ2UsIGdldE9yZ2FuaXphdGlvblBsYW59IGZyb20gJy4vcGxhbnMuanMnO1xuaW1wb3J0IHtcbiAgb3JnYW5pemF0aW9uS2V5LFxuICBvcmdhbml6YXRpb25TdG9yZUZvcixcbiAgcmVxdWlyZUlkZW50aWZpZXIsXG4gIHR5cGUgT3JnYW5pemF0aW9uVHJhbnNhY3Rpb25cbn0gZnJvbSAnLi9zdG9yZS5qcyc7XG5cbmltcG9ydCB0eXBlIHtBcGlDb250ZXh0fSBmcm9tICcuLi90eXBlcy9hdXRoLnR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgQ2hlY2tvdXRSZXN1bHQsXG4gIE1lbWJlcnNoaXBDaGFuZ2UsXG4gIE9yZ2FuaXphdGlvbk1lbWJlcnNoaXAsXG4gIE92ZXJhZ2VQcmVmZXJlbmNlLFxuICBQbGFuS2V5LFxuICBQcm92aWRlclN1YnNjcmlwdGlvbixcbiAgU2VhdENoYW5nZVF1b3RlLFxuICBTdWJzY3JpcHRpb25TdW1tYXJ5XG59IGZyb20gJy4vdHlwZXMuanMnO1xuXG5leHBvcnQgdHlwZSBDaGVja291dEF0dGVtcHQgPSBSZWFkb25seTx7XG4gIGdlbmVyYXRpb246IG51bWJlcjtcbiAga2V5OiBzdHJpbmc7XG4gIGxlYXNlRXhwaXJlczogbnVtYmVyO1xuICBvd25lcjogc3RyaW5nO1xuICBwbGFuOiBQbGFuS2V5O1xuICBxdWFudGl0eTogbnVtYmVyO1xuICBzZXF1ZW5jZTogbnVtYmVyO1xuICBzZXNzaW9uPzogQ2hlY2tvdXRSZXN1bHQ7XG59PjtcbmV4cG9ydCB0eXBlIE9yZ2FuaXphdGlvbkJpbGxpbmcgPSBSZWFkb25seTx7XG4gIGNoZWNrb3V0PzogQ2hlY2tvdXRBdHRlbXB0O1xuICBjdXN0b21lcklkOiBzdHJpbmc7XG4gIG9yZ2FuaXphdGlvbklkOiBzdHJpbmc7XG4gIG92ZXJhZ2U/OiBPdmVyYWdlUHJlZmVyZW5jZTtcbiAgcGVuZGluZ0NoYW5nZT86IHN0cmluZyB8IG51bGw7XG4gIHBlcmlvZEVuZD86IG51bWJlciB8IG51bGw7XG4gIHBsYW4/OiBQbGFuS2V5IHwgbnVsbDtcbiAgc3RhdHVzPzogc3RyaW5nO1xuICBzdWJzY3JpcHRpb24/OiBQcm92aWRlclN1YnNjcmlwdGlvbiB8IG51bGw7XG59PjtcblxuZXhwb3J0IGNvbnN0IHJlcXVpcmVCaWxsaW5nQWRtaW4gPSBhc3luYyAoXG4gIHR4OiBPcmdhbml6YXRpb25UcmFuc2FjdGlvbixcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgb3JnYW5pemF0aW9uSWQ6IHN0cmluZ1xuKSA9PiB7XG4gIGNvbnN0IGFjY2VzcyA9IGF3YWl0IG9yZ2FuaXphdGlvbkFjY2Vzc0luVHJhbnNhY3Rpb24odHgsIGNvbnRleHQsIG9yZ2FuaXphdGlvbklkLCAnYWRtaW4nKTtcbiAgY29uc3QgdXNlciA9IGF3YWl0IHR4LmdldDx7ZW1haWw6IHN0cmluZzsgdmVyaWZpZWRFbWFpbDogYm9vbGVhbn0+KCd1c2VycycsIGFjY2Vzcy51c2VySWQpO1xuICBpZighdXNlcj8udmVyaWZpZWRFbWFpbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignZW1haWxfdmVyaWZpY2F0aW9uX3JlcXVpcmVkJyk7XG4gIH1cbiAgcmV0dXJuIHsuLi5hY2Nlc3MsIGVtYWlsOiB1c2VyLmVtYWlsfTtcbn07XG5jb25zdCByZXF1aXJlQmlsbGluZ0VuYWJsZWQgPSAoKTogdm9pZCA9PiB7XG4gIGlmKG9yZ2FuaXphdGlvbkJpbGxpbmdNb2RlKCkgIT09ICd0ZXN0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignYmlsbGluZ19kaXNhYmxlZCcpO1xuICB9XG59O1xuZXhwb3J0IGNvbnN0IGdldE9yZ2FuaXphdGlvblN1YnNjcmlwdGlvbiA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgb3JnYW5pemF0aW9uSWQ6IHN0cmluZ1xuKTogUHJvbWlzZTxTdWJzY3JpcHRpb25TdW1tYXJ5PiA9PlxuICBvcmdhbml6YXRpb25TdG9yZUZvcihjb250ZXh0KS50cmFuc2FjdGlvbihhc3luYyAodHgpID0+IHtcbiAgICBjb25zdCBhY2Nlc3MgPSBhd2FpdCBvcmdhbml6YXRpb25BY2Nlc3NJblRyYW5zYWN0aW9uKHR4LCBjb250ZXh0LCBvcmdhbml6YXRpb25JZCwgJ21lbWJlcicpO1xuICAgIGNvbnN0IGJpbGxpbmcgPSBhd2FpdCB0eC5nZXQ8T3JnYW5pemF0aW9uQmlsbGluZz4oJ29yZ2FuaXphdGlvbkJpbGxpbmcnLCBvcmdhbml6YXRpb25JZCk7XG4gICAgY29uc3QgYWN0aXZlTWVtYmVycyA9IGF3YWl0IGFjdGl2ZU1lbWJlckNvdW50KHR4LCBvcmdhbml6YXRpb25JZCk7XG4gICAgY29uc3QgY2hhcmdlID0gYmlsbGluZz8ucGxhblxuICAgICAgPyBjYWxjdWxhdGVTZWF0Q2hhcmdlKGJpbGxpbmcucGxhbiwgYWN0aXZlTWVtYmVycylcbiAgICAgIDoge2V4dHJhU2VhdHM6IE1hdGgubWF4KDAsIGFjdGl2ZU1lbWJlcnMgLSAxMCksIG1vbnRobHlDZW50czogMH07XG4gICAgY29uc3Qgam9icyA9IGF3YWl0IHR4LmZpbmQ8e2tpbmQ6IHN0cmluZ30+KCdvcmdhbml6YXRpb25CaWxsaW5nSm9icycsIHtcbiAgICAgIG9yZ2FuaXphdGlvbklkLFxuICAgICAgc3RhdHVzOiAncGVuZGluZydcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgYWN0aXZlTWVtYmVycyxcbiAgICAgIGJpbGxpbmdNb2RlOiBvcmdhbml6YXRpb25CaWxsaW5nTW9kZSgpLFxuICAgICAgY2FuTWFuYWdlOiBhY2Nlc3MubWVtYmVyc2hpcC5yb2xlID09PSAnYWRtaW4nLFxuICAgICAgZXN0aW1hdGVkTW9udGhseUNlbnRzOiBjaGFyZ2UubW9udGhseUNlbnRzLFxuICAgICAgZXh0cmFTZWF0czogY2hhcmdlLmV4dHJhU2VhdHMsXG4gICAgICBtZXRlcnNFbmFibGVkOiBmYWxzZSxcbiAgICAgIG9yZ2FuaXphdGlvbklkLFxuICAgICAgb3ZlcmFnZTogYmlsbGluZz8ub3ZlcmFnZSB8fCB7ZW5hYmxlZDogZmFsc2UsIG1vbnRobHlDYXBDZW50czogMCwgcmV2aXNpb246IDB9LFxuICAgICAgcGVuZGluZ0NoYW5nZTogYmlsbGluZz8ucGVuZGluZ0NoYW5nZSB8fCBudWxsLFxuICAgICAgcGVyaW9kRW5kOiBiaWxsaW5nPy5wZXJpb2RFbmQgfHwgbnVsbCxcbiAgICAgIHBsYW46IGJpbGxpbmc/LnBsYW4gfHwgbnVsbCxcbiAgICAgIHJlY29uY2lsaWF0aW9uUGVuZGluZzogam9icy5zb21lKChqb2IpID0+IGpvYi5raW5kICE9PSAnbWFpbCcpLFxuICAgICAgc3RhdHVzOiBiaWxsaW5nPy5zdGF0dXMgfHwgJ25vbmUnXG4gICAgfTtcbiAgfSk7XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVPcmdhbml6YXRpb25DaGVja291dCA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgb3JnYW5pemF0aW9uSWQ6IHN0cmluZyxcbiAgcGxhbjogUGxhbktleSxcbiAgcmVxdWVzdElkOiBzdHJpbmdcbik6IFByb21pc2U8e3VybDogc3RyaW5nfT4gPT4ge1xuICBnZXRPcmdhbml6YXRpb25QbGFuKHBsYW4pO1xuICByZXF1aXJlSWRlbnRpZmllcihyZXF1ZXN0SWQpO1xuICByZXF1aXJlQmlsbGluZ0VuYWJsZWQoKTtcbiAgY29uc3Qgc3RvcmUgPSBvcmdhbml6YXRpb25TdG9yZUZvcihjb250ZXh0KTtcbiAgY29uc3Qgb3duZXIgPSByYW5kb21VVUlEKCk7XG4gIGNvbnN0IHBlbmRpbmcgPSBhd2FpdCBzdG9yZS50cmFuc2FjdGlvbihhc3luYyAodHgpID0+IHtcbiAgICBjb25zdCBhY2Nlc3MgPSBhd2FpdCByZXF1aXJlQmlsbGluZ0FkbWluKHR4LCBjb250ZXh0LCBvcmdhbml6YXRpb25JZCk7XG4gICAgY29uc3Qgb2xkID0gYXdhaXQgdHguZ2V0PE9yZ2FuaXphdGlvbkJpbGxpbmc+KCdvcmdhbml6YXRpb25CaWxsaW5nJywgb3JnYW5pemF0aW9uSWQpO1xuICAgIGlmKG9sZD8ucGxhbiAmJiAhWydjYW5jZWxlZCcsICdpbmNvbXBsZXRlX2V4cGlyZWQnXS5pbmNsdWRlcyhvbGQuc3RhdHVzIHx8ICcnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdWJzY3JpcHRpb25fZXhpc3RzJyk7XG4gICAgfVxuICAgIGlmKG9sZD8uc3Vic2NyaXB0aW9uICYmIChhd2FpdCB0eC5maW5kPHtraW5kOiBzdHJpbmd9Pignb3JnYW5pemF0aW9uQmlsbGluZ0pvYnMnLCB7b3JnYW5pemF0aW9uSWQsIHN0YXR1czogJ3BlbmRpbmcnfSkpLnNvbWUoKGpvYikgPT4gam9iLmtpbmQgIT09ICdtYWlsJykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYmlsbGluZ19yZWNvbmNpbGlhdGlvbl9wZW5kaW5nJyk7XG4gICAgfVxuICAgIGNvbnN0IHByZXZpb3VzID0gb2xkPy5jaGVja291dDtcbiAgICBpZihwcmV2aW91cz8uc2Vzc2lvbiAmJiBwcmV2aW91cy5zZXNzaW9uLmV4cGlyZXNBdCA+IERhdGUubm93KCkpIHtcbiAgICAgIGlmKHByZXZpb3VzLnBsYW4gIT09IHBsYW4pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjaGVja291dF9pbl9wcm9ncmVzcycpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtjYWNoZWQ6IHByZXZpb3VzLnNlc3Npb24udXJsfTtcbiAgICB9XG4gICAgaWYocHJldmlvdXMgJiYgcHJldmlvdXMubGVhc2VFeHBpcmVzID4gRGF0ZS5ub3coKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjaGVja291dF9idXN5Jyk7XG4gICAgfVxuICAgIC8vIEFuIHVua25vd24gcHJvdmlkZXIgb3V0Y29tZSBtdXN0IHJldGFpbiBpdHMga2V5LCBldmVuIGJleW9uZCBTdHJpcGUncyAyNGggY2FjaGUuXG4gICAgaWYocHJldmlvdXMgJiYgIXByZXZpb3VzLnNlc3Npb24gJiYgcHJldmlvdXMucGxhbiAhPT0gcGxhbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjaGVja291dF9pbl9wcm9ncmVzcycpO1xuICAgIH1cbiAgICBjb25zdCBnZW5lcmF0aW9uID0gcHJldmlvdXMgPyBwcmV2aW91cy5nZW5lcmF0aW9uICsgTnVtYmVyKEJvb2xlYW4ocHJldmlvdXMuc2Vzc2lvbikpIDogMTtcbiAgICBjb25zdCBxdWFudGl0eSA9IGNhbGN1bGF0ZVNlYXRDaGFyZ2UocGxhbiwgYXdhaXQgYWN0aXZlTWVtYmVyQ291bnQodHgsIG9yZ2FuaXphdGlvbklkKSkuZXh0cmFTZWF0cztcbiAgICBjb25zdCBjaGVja291dDogQ2hlY2tvdXRBdHRlbXB0ID1cbiAgICAgIHByZXZpb3VzICYmICFwcmV2aW91cy5zZXNzaW9uXG4gICAgICAgID8gey4uLnByZXZpb3VzLCBsZWFzZUV4cGlyZXM6IERhdGUubm93KCkgKyA2MDAwMCwgb3duZXJ9XG4gICAgICAgIDoge1xuICAgICAgICAgIGdlbmVyYXRpb24sXG4gICAgICAgICAga2V5OiBvcmdhbml6YXRpb25LZXkoJ2NoZWNrb3V0Jywgb3JnYW5pemF0aW9uSWQsIFN0cmluZyhnZW5lcmF0aW9uKSksXG4gICAgICAgICAgbGVhc2VFeHBpcmVzOiBEYXRlLm5vdygpICsgNjAwMDAsXG4gICAgICAgICAgb3duZXIsXG4gICAgICAgICAgcGxhbixcbiAgICAgICAgICBxdWFudGl0eSxcbiAgICAgICAgICBzZXF1ZW5jZTogYWNjZXNzLm9yZ2FuaXphdGlvbi5yZXZpc2lvblxuICAgICAgICB9O1xuICAgIGNvbnN0IGJpbGxpbmc6IE9yZ2FuaXphdGlvbkJpbGxpbmcgPSB7XG4gICAgICAuLi5vbGQsXG4gICAgICBjaGVja291dCxcbiAgICAgIGN1c3RvbWVySWQ6IG9sZD8uY3VzdG9tZXJJZCB8fCAnJyxcbiAgICAgIG9yZ2FuaXphdGlvbklkXG4gICAgfTtcbiAgICBhd2FpdCB0eC5wdXQoJ29yZ2FuaXphdGlvbkJpbGxpbmcnLCBvcmdhbml6YXRpb25JZCwgYmlsbGluZywgb2xkKTtcbiAgICByZXR1cm4ge2JpbGxpbmcsIGVtYWlsOiBhY2Nlc3MuZW1haWx9O1xuICB9KTtcbiAgaWYoJ2NhY2hlZCcgaW4gcGVuZGluZykge1xuICAgIHJldHVybiB7dXJsOiBwZW5kaW5nLmNhY2hlZCF9O1xuICB9XG4gIGNvbnN0IGZlbmNlZCA9IGFzeW5jIChwYXRjaDogUGFydGlhbDxPcmdhbml6YXRpb25CaWxsaW5nPik6IFByb21pc2U8dm9pZD4gPT5cbiAgICBzdG9yZS50cmFuc2FjdGlvbihhc3luYyAodHgpID0+IHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBhd2FpdCB0eC5nZXQ8T3JnYW5pemF0aW9uQmlsbGluZz4oJ29yZ2FuaXphdGlvbkJpbGxpbmcnLCBvcmdhbml6YXRpb25JZCk7XG4gICAgICBpZihjdXJyZW50Py5jaGVja291dD8ub3duZXIgIT09IG93bmVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY2hlY2tvdXRfbGVhc2VfbG9zdCcpO1xuICAgICAgfVxuICAgICAgYXdhaXQgdHgucHV0KCdvcmdhbml6YXRpb25CaWxsaW5nJywgb3JnYW5pemF0aW9uSWQsIHsuLi5jdXJyZW50LCAuLi5wYXRjaH0sIGN1cnJlbnQpO1xuICAgIH0pO1xuICB0cnkge1xuICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZ2V0T3JnYW5pemF0aW9uQmlsbGluZ1Byb3ZpZGVyKCk7XG4gICAgbGV0IHtjdXN0b21lcklkfSA9IChwZW5kaW5nLmJpbGxpbmchKTtcbiAgICBpZighY3VzdG9tZXJJZCkge1xuICAgICAgY3VzdG9tZXJJZCA9IGF3YWl0IHByb3ZpZGVyLmN1c3RvbWVyKG9yZ2FuaXphdGlvbklkLCBwZW5kaW5nLmVtYWlsISk7XG4gICAgICBhd2FpdCBmZW5jZWQoe2N1c3RvbWVySWR9KTtcbiAgICB9XG4gICAgaWYoYXdhaXQgcHJvdmlkZXIucmV0cmlldmUoY3VzdG9tZXJJZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc3Vic2NyaXB0aW9uX2V4aXN0cycpO1xuICAgIH1cbiAgICBjb25zdCBhdHRlbXB0ID0gcGVuZGluZy5iaWxsaW5nIS5jaGVja291dCE7XG4gICAgYXdhaXQgc3RvcmUudHJhbnNhY3Rpb24oYXN5bmMgKHR4KSA9PiB7XG4gICAgICBhd2FpdCByZXF1aXJlQmlsbGluZ0FkbWluKHR4LCBjb250ZXh0LCBvcmdhbml6YXRpb25JZCk7XG4gICAgICBjb25zdCBjdXJyZW50ID0gYXdhaXQgdHguZ2V0PE9yZ2FuaXphdGlvbkJpbGxpbmc+KCdvcmdhbml6YXRpb25CaWxsaW5nJywgb3JnYW5pemF0aW9uSWQpO1xuICAgICAgaWYoY3VycmVudD8uY2hlY2tvdXQ/Lm93bmVyICE9PSBvd25lcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NoZWNrb3V0X2xlYXNlX2xvc3QnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBzZXNzaW9uID0gYXdhaXQgcHJvdmlkZXIuY2hlY2tvdXQoY3VzdG9tZXJJZCwgYXR0ZW1wdC5wbGFuLCBhdHRlbXB0LnF1YW50aXR5LCBhdHRlbXB0LmtleSk7XG4gICAgLy8gUGVyc2lzdCB0aGUgZXhhY3QgcHJvdmlkZXIgb3V0Y29tZSBiZWZvcmUgZXhwb3NpbmcgaXRzIHJlZGlyZWN0LlxuICAgIGF3YWl0IGZlbmNlZCh7Y2hlY2tvdXQ6IHsuLi5hdHRlbXB0LCBsZWFzZUV4cGlyZXM6IDAsIG93bmVyOiAnJywgc2Vzc2lvbn19KTtcbiAgICBpZihzZXNzaW9uLmV4cGlyZXNBdCA8PSBEYXRlLm5vdygpIHx8ICFzZXNzaW9uLnVybCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjaGVja291dF9leHBpcmVkJyk7XG4gICAgfVxuICAgIHJldHVybiB7dXJsOiBzZXNzaW9uLnVybH07XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBhd2FpdCBzdG9yZS50cmFuc2FjdGlvbihhc3luYyAodHgpID0+IHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBhd2FpdCB0eC5nZXQ8T3JnYW5pemF0aW9uQmlsbGluZz4oJ29yZ2FuaXphdGlvbkJpbGxpbmcnLCBvcmdhbml6YXRpb25JZCk7XG4gICAgICBpZihjdXJyZW50Py5jaGVja291dD8ub3duZXIgPT09IG93bmVyKSB7XG4gICAgICAgIGF3YWl0IHR4LnB1dChcbiAgICAgICAgICAnb3JnYW5pemF0aW9uQmlsbGluZycsXG4gICAgICAgICAgb3JnYW5pemF0aW9uSWQsXG4gICAgICAgICAgey4uLmN1cnJlbnQsIGNoZWNrb3V0OiB7Li4uY3VycmVudC5jaGVja291dCwgbGVhc2VFeHBpcmVzOiAwLCBvd25lcjogJyd9fSxcbiAgICAgICAgICBjdXJyZW50XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYoXG4gICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmXG4gICAgICBbJ3N1YnNjcmlwdGlvbl9leGlzdHMnLCAnY2hlY2tvdXRfZXhwaXJlZCcsICdjaGVja291dF9pbl9wcm9ncmVzcycsICdjaGVja291dF9sZWFzZV9sb3N0J10uaW5jbHVkZXMoXG4gICAgICAgIGVycm9yLm1lc3NhZ2VcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JpbGxpbmdfcHJvdmlkZXJfdW5hdmFpbGFibGUnKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZU9yZ2FuaXphdGlvbkJpbGxpbmdQb3J0YWwgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIG9yZ2FuaXphdGlvbklkOiBzdHJpbmdcbik6IFByb21pc2U8e3VybDogc3RyaW5nfT4gPT4ge1xuICByZXF1aXJlQmlsbGluZ0VuYWJsZWQoKTtcbiAgY29uc3QgY3VzdG9tZXJJZCA9IGF3YWl0IG9yZ2FuaXphdGlvblN0b3JlRm9yKGNvbnRleHQpLnRyYW5zYWN0aW9uKGFzeW5jICh0eCkgPT4ge1xuICAgIGF3YWl0IHJlcXVpcmVCaWxsaW5nQWRtaW4odHgsIGNvbnRleHQsIG9yZ2FuaXphdGlvbklkKTtcbiAgICBjb25zdCBiaWxsaW5nID0gYXdhaXQgdHguZ2V0PE9yZ2FuaXphdGlvbkJpbGxpbmc+KCdvcmdhbml6YXRpb25CaWxsaW5nJywgb3JnYW5pemF0aW9uSWQpO1xuICAgIGlmKCFiaWxsaW5nPy5jdXN0b21lcklkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2JpbGxpbmdfY3VzdG9tZXJfcmVxdWlyZWQnKTtcbiAgICB9XG4gICAgcmV0dXJuIGJpbGxpbmcuY3VzdG9tZXJJZDtcbiAgfSk7XG4gIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZ2V0T3JnYW5pemF0aW9uQmlsbGluZ1Byb3ZpZGVyKCk7XG4gIHJldHVybiB7dXJsOiBhd2FpdCBwcm92aWRlci5wb3J0YWwoY3VzdG9tZXJJZCl9O1xufTtcblxuZXhwb3J0IGNvbnN0IHF1b3RlT3JnYW5pemF0aW9uU2VhdENoYW5nZSA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgb3JnYW5pemF0aW9uSWQ6IHN0cmluZyxcbiAgY2hhbmdlOiBNZW1iZXJzaGlwQ2hhbmdlXG4pOiBQcm9taXNlPFNlYXRDaGFuZ2VRdW90ZT4gPT4ge1xuICByZXF1aXJlQmlsbGluZ0VuYWJsZWQoKTtcbiAgY29uc3Qgc3RvcmUgPSBvcmdhbml6YXRpb25TdG9yZUZvcihjb250ZXh0KTtcbiAgY29uc3QgaW50ZW50ID0gYXdhaXQgc3RvcmUudHJhbnNhY3Rpb24oYXN5bmMgKHR4KSA9PiB7XG4gICAgY29uc3QgYWNjZXNzID0gYXdhaXQgcmVxdWlyZUJpbGxpbmdBZG1pbih0eCwgY29udGV4dCwgb3JnYW5pemF0aW9uSWQpO1xuICAgIGNvbnN0IG1lbWJlciA9IGF3YWl0IHR4LmdldDxPcmdhbml6YXRpb25NZW1iZXJzaGlwPihcbiAgICAgICdvcmdhbml6YXRpb25NZW1iZXJzaGlwcycsXG4gICAgICBvcmdhbml6YXRpb25LZXkob3JnYW5pemF0aW9uSWQsIHJlcXVpcmVJZGVudGlmaWVyKGNoYW5nZS51c2VySWQpKVxuICAgICk7XG4gICAgaWYoXG4gICAgICAhbWVtYmVyIHx8XG4gICAgICBtZW1iZXIucmV2aXNpb24gIT09IGNoYW5nZS5leHBlY3RlZFJldmlzaW9uIHx8XG4gICAgICAhWydhZG1pbicsICdtZW1iZXInXS5pbmNsdWRlcyhjaGFuZ2Uucm9sZSkgfHxcbiAgICAgICFbJ2FjdGl2ZScsICdkZWFjdGl2YXRlZCddLmluY2x1ZGVzKGNoYW5nZS5zdGF0dXMpXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWRfbWVtYmVyc2hpcCcpO1xuICAgIH1cbiAgICBpZihcbiAgICAgIG1lbWJlci51c2VySWQgPT09IGFjY2Vzcy5vcmdhbml6YXRpb24ub3duZXJVc2VySWQgJiZcbiAgICAgIChjaGFuZ2Uucm9sZSAhPT0gJ2FkbWluJyB8fCBjaGFuZ2Uuc3RhdHVzICE9PSAnYWN0aXZlJylcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignb3duZXJzaGlwX3RyYW5zZmVyX3JlcXVpcmVkJyk7XG4gICAgfVxuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0eC5nZXQ8e2FjdGl2ZTogYm9vbGVhbjsgdmVyaWZpZWRFbWFpbDogYm9vbGVhbn0+KCd1c2VycycsIGNoYW5nZS51c2VySWQpO1xuICAgIGlmKGNoYW5nZS5zdGF0dXMgPT09ICdhY3RpdmUnICYmICghdXNlcj8uYWN0aXZlIHx8ICF1c2VyLnZlcmlmaWVkRW1haWwpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZlcmlmaWVkX2FjdGl2ZV91c2VyX3JlcXVpcmVkJyk7XG4gICAgfVxuICAgIGNvbnN0IGJpbGxpbmcgPSBhd2FpdCB0eC5nZXQ8T3JnYW5pemF0aW9uQmlsbGluZz4oJ29yZ2FuaXphdGlvbkJpbGxpbmcnLCBvcmdhbml6YXRpb25JZCk7XG4gICAgaWYoIWJpbGxpbmc/LmN1c3RvbWVySWQgfHwgYmlsbGluZy5zdGF0dXMgIT09ICdhY3RpdmUnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2JpbGxpbmdfbm90X3JlYWR5Jyk7XG4gICAgfVxuICAgIGNvbnN0IHF1YW50aXR5ID0gTWF0aC5tYXgoXG4gICAgICAwLFxuICAgICAgKGF3YWl0IGFjdGl2ZU1lbWJlckNvdW50KHR4LCBvcmdhbml6YXRpb25JZCkpICtcbiAgICAgICAgTnVtYmVyKGNoYW5nZS5zdGF0dXMgPT09ICdhY3RpdmUnKSAtXG4gICAgICAgIE51bWJlcihtZW1iZXIuc3RhdHVzID09PSAnYWN0aXZlJykgLVxuICAgICAgICAxMFxuICAgICk7XG4gICAgcmV0dXJuIHtjdXN0b21lcklkOiBiaWxsaW5nLmN1c3RvbWVySWQsIG9yZ2FuaXphdGlvbjogYWNjZXNzLm9yZ2FuaXphdGlvbiwgcXVhbnRpdHl9O1xuICB9KTtcbiAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBnZXRPcmdhbml6YXRpb25CaWxsaW5nUHJvdmlkZXIoKTtcbiAgY29uc3Qgc3Vic2NyaXB0aW9uID0gYXdhaXQgcHJvdmlkZXIucmV0cmlldmUoaW50ZW50LmN1c3RvbWVySWQpO1xuICBpZighc3Vic2NyaXB0aW9uIHx8IHN1YnNjcmlwdGlvbi5zdGF0dXMgIT09ICdhY3RpdmUnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdiaWxsaW5nX25vdF9yZWFkeScpO1xuICB9XG4gIGNvbnN0IGVmZmVjdGl2ZUF0ID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgcHJvcmF0aW9uQ2VudHMgPSBhd2FpdCBwcm92aWRlci5wcmV2aWV3KFxuICAgIHN1YnNjcmlwdGlvbixcbiAgICBzdWJzY3JpcHRpb24ucGxhbixcbiAgICBpbnRlbnQucXVhbnRpdHksXG4gICAgZWZmZWN0aXZlQXRcbiAgKTtcbiAgY29uc3QgcXVvdGU6IFNlYXRDaGFuZ2VRdW90ZSA9IHtcbiAgICBjdXJyZW5jeTogJ3VzZCcsXG4gICAgZXhwaXJlc0F0OiBlZmZlY3RpdmVBdCArIDMwMDAwMCxcbiAgICBvcmdhbml6YXRpb25SZXZpc2lvbjogaW50ZW50Lm9yZ2FuaXphdGlvbi5yZXZpc2lvbixcbiAgICBwcm9yYXRpb25DZW50cyxcbiAgICBxdWFudGl0eTogaW50ZW50LnF1YW50aXR5LFxuICAgIHF1b3RlSWQ6IHJhbmRvbVVVSUQoKVxuICB9O1xuICBhd2FpdCBzdG9yZS50cmFuc2FjdGlvbihhc3luYyAodHgpID0+IHtcbiAgICBjb25zdCBhY2Nlc3MgPSBhd2FpdCByZXF1aXJlQmlsbGluZ0FkbWluKHR4LCBjb250ZXh0LCBvcmdhbml6YXRpb25JZCk7XG4gICAgaWYoYWNjZXNzLm9yZ2FuaXphdGlvbi5yZXZpc2lvbiAhPT0gcXVvdGUub3JnYW5pemF0aW9uUmV2aXNpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncmV2aXNpb25fY29uZmxpY3QnKTtcbiAgICB9XG4gICAgYXdhaXQgdHgucHV0KCdvcmdhbml6YXRpb25CaWxsaW5nUXVvdGVzJywgcXVvdGUucXVvdGVJZCwge1xuICAgICAgLi4ucXVvdGUsXG4gICAgICBlZmZlY3RpdmVBdCxcbiAgICAgIGV4cGVjdGVkUmV2aXNpb246IGNoYW5nZS5leHBlY3RlZFJldmlzaW9uLFxuICAgICAgb3JnYW5pemF0aW9uSWQsXG4gICAgICByb2xlOiBjaGFuZ2Uucm9sZSxcbiAgICAgIHN0YXR1czogY2hhbmdlLnN0YXR1cyxcbiAgICAgIHVzZWQ6IGZhbHNlLFxuICAgICAgdXNlcklkOiBjaGFuZ2UudXNlcklkXG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gcXVvdGU7XG59O1xuIl0sIm5hbWVzIjpbInJhbmRvbVVVSUQiLCJvcmdhbml6YXRpb25BY2Nlc3NJblRyYW5zYWN0aW9uIiwiZ2V0T3JnYW5pemF0aW9uQmlsbGluZ1Byb3ZpZGVyIiwib3JnYW5pemF0aW9uQmlsbGluZ01vZGUiLCJhY3RpdmVNZW1iZXJDb3VudCIsImNhbGN1bGF0ZVNlYXRDaGFyZ2UiLCJnZXRPcmdhbml6YXRpb25QbGFuIiwib3JnYW5pemF0aW9uS2V5Iiwib3JnYW5pemF0aW9uU3RvcmVGb3IiLCJyZXF1aXJlSWRlbnRpZmllciIsInJlcXVpcmVCaWxsaW5nQWRtaW4iLCJ0eCIsImNvbnRleHQiLCJvcmdhbml6YXRpb25JZCIsImFjY2VzcyIsInVzZXIiLCJnZXQiLCJ1c2VySWQiLCJ2ZXJpZmllZEVtYWlsIiwiRXJyb3IiLCJlbWFpbCIsInJlcXVpcmVCaWxsaW5nRW5hYmxlZCIsImdldE9yZ2FuaXphdGlvblN1YnNjcmlwdGlvbiIsInRyYW5zYWN0aW9uIiwiYmlsbGluZyIsImFjdGl2ZU1lbWJlcnMiLCJjaGFyZ2UiLCJwbGFuIiwiZXh0cmFTZWF0cyIsIk1hdGgiLCJtYXgiLCJtb250aGx5Q2VudHMiLCJqb2JzIiwiZmluZCIsInN0YXR1cyIsImJpbGxpbmdNb2RlIiwiY2FuTWFuYWdlIiwibWVtYmVyc2hpcCIsInJvbGUiLCJlc3RpbWF0ZWRNb250aGx5Q2VudHMiLCJtZXRlcnNFbmFibGVkIiwib3ZlcmFnZSIsImVuYWJsZWQiLCJtb250aGx5Q2FwQ2VudHMiLCJyZXZpc2lvbiIsInBlbmRpbmdDaGFuZ2UiLCJwZXJpb2RFbmQiLCJyZWNvbmNpbGlhdGlvblBlbmRpbmciLCJzb21lIiwiam9iIiwia2luZCIsImNyZWF0ZU9yZ2FuaXphdGlvbkNoZWNrb3V0IiwicmVxdWVzdElkIiwic3RvcmUiLCJvd25lciIsInBlbmRpbmciLCJvbGQiLCJpbmNsdWRlcyIsInN1YnNjcmlwdGlvbiIsInByZXZpb3VzIiwiY2hlY2tvdXQiLCJzZXNzaW9uIiwiZXhwaXJlc0F0IiwiRGF0ZSIsIm5vdyIsImNhY2hlZCIsInVybCIsImxlYXNlRXhwaXJlcyIsImdlbmVyYXRpb24iLCJOdW1iZXIiLCJCb29sZWFuIiwicXVhbnRpdHkiLCJrZXkiLCJTdHJpbmciLCJzZXF1ZW5jZSIsIm9yZ2FuaXphdGlvbiIsImN1c3RvbWVySWQiLCJwdXQiLCJmZW5jZWQiLCJwYXRjaCIsImN1cnJlbnQiLCJwcm92aWRlciIsImN1c3RvbWVyIiwicmV0cmlldmUiLCJhdHRlbXB0IiwiZXJyb3IiLCJtZXNzYWdlIiwiY3JlYXRlT3JnYW5pemF0aW9uQmlsbGluZ1BvcnRhbCIsInBvcnRhbCIsInF1b3RlT3JnYW5pemF0aW9uU2VhdENoYW5nZSIsImNoYW5nZSIsImludGVudCIsIm1lbWJlciIsImV4cGVjdGVkUmV2aXNpb24iLCJvd25lclVzZXJJZCIsImFjdGl2ZSIsImVmZmVjdGl2ZUF0IiwicHJvcmF0aW9uQ2VudHMiLCJwcmV2aWV3IiwicXVvdGUiLCJjdXJyZW5jeSIsIm9yZ2FuaXphdGlvblJldmlzaW9uIiwicXVvdGVJZCIsInVzZWQiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVFBLFVBQVUsUUFBTyxjQUFjO0FBRXZDLFNBQVFDLCtCQUErQixRQUFPLHFCQUFxQjtBQUNuRSxTQUFRQyw4QkFBOEIsRUFBRUMsdUJBQXVCLFFBQU8sdUJBQXVCO0FBQzdGLFNBQVFDLGlCQUFpQixRQUFPLGtCQUFrQjtBQUNsRCxTQUFRQyxtQkFBbUIsRUFBRUMsbUJBQW1CLFFBQU8sYUFBYTtBQUNwRSxTQUNFQyxlQUFlLEVBQ2ZDLG9CQUFvQixFQUNwQkMsaUJBQWlCLFFBRVosYUFBYTtBQW9DcEIsT0FBTyxNQUFNQyxzQkFBc0IsT0FDakNDLElBQ0FDLFNBQ0FDO0lBRUEsTUFBTUMsU0FBUyxNQUFNYixnQ0FBZ0NVLElBQUlDLFNBQVNDLGdCQUFnQjtJQUNsRixNQUFNRSxPQUFPLE1BQU1KLEdBQUdLLEdBQUcsQ0FBMEMsU0FBU0YsT0FBT0csTUFBTTtJ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
@@ -0,0 +1,4 @@
1
+ import type { BillingMode, BillingProvider, VerifiedBillingEvent } from './types.js';
2
+ export declare const organizationBillingMode: () => BillingMode;
3
+ export declare const verifyOrganizationBillingEvent: (body: string | Buffer, signature: string) => VerifiedBillingEvent;
4
+ export declare const getOrganizationBillingProvider: () => Promise<BillingProvider>;