@fantastic.dev/better-stripe 0.17.1 → 0.19.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 (57) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +10 -1
  3. package/dist/client/connect/payouts.d.ts +3 -2
  4. package/dist/client/connect/payouts.d.ts.map +1 -1
  5. package/dist/client/connect/payouts.js.map +1 -1
  6. package/dist/client/connect/transferReceipt.d.ts +48 -0
  7. package/dist/client/connect/transferReceipt.d.ts.map +1 -0
  8. package/dist/client/connect/transferReceipt.js +296 -0
  9. package/dist/client/connect/transferReceipt.js.map +1 -0
  10. package/dist/client/index.d.ts +4 -8
  11. package/dist/client/index.d.ts.map +1 -1
  12. package/dist/client/index.js +5 -0
  13. package/dist/client/index.js.map +1 -1
  14. package/dist/client/payoutPolicy.d.ts +84 -0
  15. package/dist/client/payoutPolicy.d.ts.map +1 -0
  16. package/dist/client/payoutPolicy.js +266 -0
  17. package/dist/client/payoutPolicy.js.map +1 -0
  18. package/dist/component/_generated/component.d.ts +273 -0
  19. package/dist/component/_generated/component.d.ts.map +1 -1
  20. package/dist/component/earnings/triggers.d.ts +150 -0
  21. package/dist/component/earnings/triggers.d.ts.map +1 -1
  22. package/dist/component/payoutPolicy/helpers.d.ts +51 -0
  23. package/dist/component/payoutPolicy/helpers.d.ts.map +1 -0
  24. package/dist/component/payoutPolicy/helpers.js +68 -0
  25. package/dist/component/payoutPolicy/helpers.js.map +1 -0
  26. package/dist/component/payoutPolicy/mutations.d.ts +172 -0
  27. package/dist/component/payoutPolicy/mutations.d.ts.map +1 -0
  28. package/dist/component/payoutPolicy/mutations.js +191 -0
  29. package/dist/component/payoutPolicy/mutations.js.map +1 -0
  30. package/dist/component/payoutPolicy/queries.d.ts +97 -0
  31. package/dist/component/payoutPolicy/queries.d.ts.map +1 -0
  32. package/dist/component/payoutPolicy/queries.js +51 -0
  33. package/dist/component/payoutPolicy/queries.js.map +1 -0
  34. package/dist/component/payoutPolicy/schema.d.ts +396 -0
  35. package/dist/component/payoutPolicy/schema.d.ts.map +1 -0
  36. package/dist/component/payoutPolicy/schema.js +54 -0
  37. package/dist/component/payoutPolicy/schema.js.map +1 -0
  38. package/dist/component/schema.d.ts +131 -0
  39. package/dist/component/schema.js +3 -0
  40. package/dist/component/schema.js.map +1 -1
  41. package/docs/settlement.md +112 -0
  42. package/package.json +1 -1
  43. package/src/client/connect/payouts.ts +10 -8
  44. package/src/client/connect/transferReceipt.pagination.test.ts +209 -0
  45. package/src/client/connect/transferReceipt.test.ts +520 -0
  46. package/src/client/connect/transferReceipt.ts +422 -0
  47. package/src/client/index.ts +7 -11
  48. package/src/client/payoutPolicy.test.ts +320 -0
  49. package/src/client/payoutPolicy.ts +422 -0
  50. package/src/component/_generated/api.ts +6 -0
  51. package/src/component/_generated/component.ts +280 -0
  52. package/src/component/payout-policy.test.ts +248 -0
  53. package/src/component/payoutPolicy/helpers.ts +88 -0
  54. package/src/component/payoutPolicy/mutations.ts +225 -0
  55. package/src/component/payoutPolicy/queries.ts +56 -0
  56. package/src/component/payoutPolicy/schema.ts +67 -0
  57. package/src/component/schema.ts +3 -0
@@ -248,6 +248,81 @@ export declare const mutation: import("convex-helpers/server/customFunctions").C
248
248
  searchIndexes: {};
249
249
  vectorIndexes: {};
250
250
  };
251
+ payoutPolicies: {
252
+ document: {
253
+ _creationTime: number;
254
+ _id: import("convex/values").GenericId<"payoutPolicies">;
255
+ accountId: string;
256
+ country: string;
257
+ holdDeadline?: number | undefined;
258
+ mode: "custom" | "stripe_managed";
259
+ operationKey: string;
260
+ ownerKey: string;
261
+ previousSchedule?: {
262
+ interval: "daily" | "manual" | "monthly" | "weekly";
263
+ monthlyDays?: number[] | undefined;
264
+ weeklyDays?: string[] | undefined;
265
+ } | undefined;
266
+ revision: number;
267
+ status: "changing" | "ready";
268
+ thresholds: {
269
+ amount: number;
270
+ currency: string;
271
+ }[];
272
+ };
273
+ fieldPaths: "_id" | ("_creationTime" | "accountId" | "country" | "holdDeadline" | "mode" | "operationKey" | "ownerKey" | "previousSchedule" | "previousSchedule.interval" | "previousSchedule.monthlyDays" | "previousSchedule.weeklyDays" | "revision" | "status" | "thresholds");
274
+ indexes: {
275
+ by_id: ["_id"];
276
+ by_creation_time: ["_creationTime"];
277
+ by_account: ["accountId", "_creationTime"];
278
+ by_deadline: ["holdDeadline", "_creationTime"];
279
+ };
280
+ searchIndexes: {};
281
+ vectorIndexes: {};
282
+ };
283
+ payoutPolicyOperations: {
284
+ document: {
285
+ _creationTime: number;
286
+ _id: import("convex/values").GenericId<"payoutPolicyOperations">;
287
+ accountId: string;
288
+ attempted?: boolean | undefined;
289
+ country: string;
290
+ expectedRevision: number;
291
+ mode: "custom" | "stripe_managed";
292
+ observedAt?: number | undefined;
293
+ observedSchedule: {
294
+ interval: "daily" | "manual" | "monthly" | "weekly";
295
+ monthlyDays?: number[] | undefined;
296
+ weeklyDays?: string[] | undefined;
297
+ };
298
+ operationKey: string;
299
+ ownerKey: string;
300
+ previousSchedule: {
301
+ interval: "daily" | "manual" | "monthly" | "weekly";
302
+ monthlyDays?: number[] | undefined;
303
+ weeklyDays?: string[] | undefined;
304
+ };
305
+ revision: number;
306
+ status: "canceled" | "complete" | "pending";
307
+ targetSchedule: {
308
+ interval: "daily" | "manual" | "monthly" | "weekly";
309
+ monthlyDays?: number[] | undefined;
310
+ weeklyDays?: string[] | undefined;
311
+ };
312
+ thresholds: {
313
+ amount: number;
314
+ currency: string;
315
+ }[];
316
+ };
317
+ fieldPaths: "_id" | ("_creationTime" | "accountId" | "attempted" | "country" | "expectedRevision" | "mode" | "observedAt" | "observedSchedule" | "observedSchedule.interval" | "observedSchedule.monthlyDays" | "observedSchedule.weeklyDays" | "operationKey" | "ownerKey" | "previousSchedule" | "previousSchedule.interval" | "previousSchedule.monthlyDays" | "previousSchedule.weeklyDays" | "revision" | "status" | "targetSchedule" | "targetSchedule.interval" | "targetSchedule.monthlyDays" | "targetSchedule.weeklyDays" | "thresholds");
318
+ indexes: {
319
+ by_id: ["_id"];
320
+ by_creation_time: ["_creationTime"];
321
+ by_operation: ["operationKey", "_creationTime"];
322
+ };
323
+ searchIndexes: {};
324
+ vectorIndexes: {};
325
+ };
251
326
  payouts: {
252
327
  document: {
253
328
  _creationTime: number;
@@ -894,6 +969,81 @@ export declare const mutation: import("convex-helpers/server/customFunctions").C
894
969
  searchIndexes: {};
895
970
  vectorIndexes: {};
896
971
  };
972
+ payoutPolicies: {
973
+ document: {
974
+ _creationTime: number;
975
+ _id: import("convex/values").GenericId<"payoutPolicies">;
976
+ accountId: string;
977
+ country: string;
978
+ holdDeadline?: number | undefined;
979
+ mode: "custom" | "stripe_managed";
980
+ operationKey: string;
981
+ ownerKey: string;
982
+ previousSchedule?: {
983
+ interval: "daily" | "manual" | "monthly" | "weekly";
984
+ monthlyDays?: number[] | undefined;
985
+ weeklyDays?: string[] | undefined;
986
+ } | undefined;
987
+ revision: number;
988
+ status: "changing" | "ready";
989
+ thresholds: {
990
+ amount: number;
991
+ currency: string;
992
+ }[];
993
+ };
994
+ fieldPaths: "_id" | ("_creationTime" | "accountId" | "country" | "holdDeadline" | "mode" | "operationKey" | "ownerKey" | "previousSchedule" | "previousSchedule.interval" | "previousSchedule.monthlyDays" | "previousSchedule.weeklyDays" | "revision" | "status" | "thresholds");
995
+ indexes: {
996
+ by_id: ["_id"];
997
+ by_creation_time: ["_creationTime"];
998
+ by_account: ["accountId", "_creationTime"];
999
+ by_deadline: ["holdDeadline", "_creationTime"];
1000
+ };
1001
+ searchIndexes: {};
1002
+ vectorIndexes: {};
1003
+ };
1004
+ payoutPolicyOperations: {
1005
+ document: {
1006
+ _creationTime: number;
1007
+ _id: import("convex/values").GenericId<"payoutPolicyOperations">;
1008
+ accountId: string;
1009
+ attempted?: boolean | undefined;
1010
+ country: string;
1011
+ expectedRevision: number;
1012
+ mode: "custom" | "stripe_managed";
1013
+ observedAt?: number | undefined;
1014
+ observedSchedule: {
1015
+ interval: "daily" | "manual" | "monthly" | "weekly";
1016
+ monthlyDays?: number[] | undefined;
1017
+ weeklyDays?: string[] | undefined;
1018
+ };
1019
+ operationKey: string;
1020
+ ownerKey: string;
1021
+ previousSchedule: {
1022
+ interval: "daily" | "manual" | "monthly" | "weekly";
1023
+ monthlyDays?: number[] | undefined;
1024
+ weeklyDays?: string[] | undefined;
1025
+ };
1026
+ revision: number;
1027
+ status: "canceled" | "complete" | "pending";
1028
+ targetSchedule: {
1029
+ interval: "daily" | "manual" | "monthly" | "weekly";
1030
+ monthlyDays?: number[] | undefined;
1031
+ weeklyDays?: string[] | undefined;
1032
+ };
1033
+ thresholds: {
1034
+ amount: number;
1035
+ currency: string;
1036
+ }[];
1037
+ };
1038
+ fieldPaths: "_id" | ("_creationTime" | "accountId" | "attempted" | "country" | "expectedRevision" | "mode" | "observedAt" | "observedSchedule" | "observedSchedule.interval" | "observedSchedule.monthlyDays" | "observedSchedule.weeklyDays" | "operationKey" | "ownerKey" | "previousSchedule" | "previousSchedule.interval" | "previousSchedule.monthlyDays" | "previousSchedule.weeklyDays" | "revision" | "status" | "targetSchedule" | "targetSchedule.interval" | "targetSchedule.monthlyDays" | "targetSchedule.weeklyDays" | "thresholds");
1039
+ indexes: {
1040
+ by_id: ["_id"];
1041
+ by_creation_time: ["_creationTime"];
1042
+ by_operation: ["operationKey", "_creationTime"];
1043
+ };
1044
+ searchIndexes: {};
1045
+ vectorIndexes: {};
1046
+ };
897
1047
  payouts: {
898
1048
  document: {
899
1049
  _creationTime: number;
@@ -1 +1 @@
1
- {"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../../src/component/earnings/triggers.ts"],"names":[],"mappings":"AA+FA,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCAA0D,CAAC"}
1
+ {"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../../src/component/earnings/triggers.ts"],"names":[],"mappings":"AA+FA,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCAA0D,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { Infer } from "convex/values";
2
+ import type { QueryCtx, MutationCtx } from "../_generated/server.js";
3
+ import type { schedule, thresholds } from "./schema.js";
4
+ export declare function canonicalSchedule(value: Infer<typeof schedule>): {
5
+ interval: "weekly";
6
+ weeklyDays: string[];
7
+ monthlyDays?: undefined;
8
+ } | {
9
+ weeklyDays?: undefined;
10
+ interval: "monthly";
11
+ monthlyDays: number[];
12
+ } | {
13
+ weeklyDays?: undefined;
14
+ monthlyDays?: undefined;
15
+ interval: "daily" | "manual";
16
+ };
17
+ export declare function canonicalThresholds(values: Infer<typeof thresholds>, custom: boolean): {
18
+ amount: number;
19
+ currency: string;
20
+ }[];
21
+ export declare function validateScope(scope: {
22
+ accountId: string;
23
+ ownerKey: string;
24
+ }): void;
25
+ export declare function readPolicy(ctx: QueryCtx | MutationCtx, scope: {
26
+ accountId: string;
27
+ ownerKey: string;
28
+ }): Promise<{
29
+ _creationTime: number;
30
+ _id: import("convex/values").GenericId<"payoutPolicies">;
31
+ accountId: string;
32
+ country: string;
33
+ holdDeadline?: number | undefined;
34
+ mode: "custom" | "stripe_managed";
35
+ operationKey: string;
36
+ ownerKey: string;
37
+ previousSchedule?: {
38
+ interval: "daily" | "manual" | "monthly" | "weekly";
39
+ monthlyDays?: number[] | undefined;
40
+ weeklyDays?: string[] | undefined;
41
+ } | undefined;
42
+ revision: number;
43
+ status: "changing" | "ready";
44
+ thresholds: {
45
+ amount: number;
46
+ currency: string;
47
+ }[];
48
+ } | null>;
49
+ export declare const same: (a: unknown, b: unknown) => boolean;
50
+ export declare function holdingDays(country: string): 10 | 90 | 730;
51
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/component/payoutPolicy/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,QAAQ,CAAC;;;;;;;;;;;;EAoC9D;AACD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,KAAK,CAAC,OAAO,UAAU,CAAC,EAChC,MAAM,EAAE,OAAO;;;IAgBhB;AACD,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,QAQ3E;AACD,wBAAsB,UAAU,CAC9B,GAAG,EAAE,QAAQ,GAAG,WAAW,EAC3B,KAAK,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;UAU/C;AACD,eAAO,MAAM,IAAI,MAAO,OAAO,KAAK,OAAO,YACF,CAAC;AAC1C,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,iBAI1C"}
@@ -0,0 +1,68 @@
1
+ export function canonicalSchedule(value) {
2
+ const weekdays = [
3
+ "monday",
4
+ "tuesday",
5
+ "wednesday",
6
+ "thursday",
7
+ "friday",
8
+ "saturday",
9
+ "sunday",
10
+ ];
11
+ if (value.interval === "weekly") {
12
+ const days = value.weeklyDays;
13
+ if (!days?.length ||
14
+ days.length > 7 ||
15
+ new Set(days).size !== days.length ||
16
+ days.some((day) => !weekdays.includes(day)))
17
+ throw new Error("Invalid weekly payout schedule.");
18
+ return { interval: value.interval, weeklyDays: [...days].sort() };
19
+ }
20
+ if (value.interval === "monthly") {
21
+ const days = value.monthlyDays;
22
+ if (!days?.length ||
23
+ days.length > 31 ||
24
+ new Set(days).size !== days.length ||
25
+ days.some((day) => !Number.isInteger(day) || day < 1 || day > 31))
26
+ throw new Error("Invalid monthly payout schedule.");
27
+ return {
28
+ interval: value.interval,
29
+ monthlyDays: [...days].sort((a, b) => a - b),
30
+ };
31
+ }
32
+ return { interval: value.interval };
33
+ }
34
+ export function canonicalThresholds(values, custom) {
35
+ if ((custom && !values.length) ||
36
+ values.length > 50 ||
37
+ (!custom && values.length) ||
38
+ new Set(values.map((v) => v.currency)).size !== values.length ||
39
+ values.some((v) => !Number.isSafeInteger(v.amount) ||
40
+ v.amount <= 0 ||
41
+ !/^[a-z]{3}$/.test(v.currency)))
42
+ throw new Error("Invalid custom payout thresholds.");
43
+ return [...values].sort((a, b) => a.currency.localeCompare(b.currency));
44
+ }
45
+ export function validateScope(scope) {
46
+ if (!/^acct_\w+$/.test(scope.accountId) ||
47
+ scope.accountId.length > 80 ||
48
+ !scope.ownerKey.trim() ||
49
+ scope.ownerKey.length > 200)
50
+ throw new Error("Invalid payout policy identity.");
51
+ }
52
+ export async function readPolicy(ctx, scope) {
53
+ validateScope(scope);
54
+ const value = await ctx.db
55
+ .query("payoutPolicies")
56
+ .withIndex("by_account", (q) => q.eq("accountId", scope.accountId))
57
+ .unique();
58
+ if (value && value.ownerKey !== scope.ownerKey)
59
+ throw new Error("Payout policy owner does not match.");
60
+ return value;
61
+ }
62
+ export const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
63
+ export function holdingDays(country) {
64
+ if (!/^[A-Z]{2}$/.test(country))
65
+ throw new Error("A verified account country is required.");
66
+ return country === "TH" ? 10 : country === "US" ? 730 : 90;
67
+ }
68
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/component/payoutPolicy/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,172 @@
1
+ export declare const prepare: import("convex/server").RegisteredMutation<"public", {
2
+ accountId: string;
3
+ country: string;
4
+ expectedRevision: number;
5
+ mode: "custom" | "stripe_managed";
6
+ observedAt?: number | undefined;
7
+ observedSchedule: {
8
+ interval: "daily" | "manual" | "monthly" | "weekly";
9
+ monthlyDays?: number[] | undefined;
10
+ weeklyDays?: string[] | undefined;
11
+ };
12
+ operationKey: string;
13
+ ownerKey: string;
14
+ thresholds: {
15
+ amount: number;
16
+ currency: string;
17
+ }[];
18
+ }, Promise<{
19
+ _creationTime: number;
20
+ _id: import("convex/values").GenericId<"payoutPolicyOperations">;
21
+ accountId: string;
22
+ attempted?: boolean | undefined;
23
+ country: string;
24
+ expectedRevision: number;
25
+ mode: "custom" | "stripe_managed";
26
+ observedAt?: number | undefined;
27
+ observedSchedule: {
28
+ interval: "daily" | "manual" | "monthly" | "weekly";
29
+ monthlyDays?: number[] | undefined;
30
+ weeklyDays?: string[] | undefined;
31
+ };
32
+ operationKey: string;
33
+ ownerKey: string;
34
+ previousSchedule: {
35
+ interval: "daily" | "manual" | "monthly" | "weekly";
36
+ monthlyDays?: number[] | undefined;
37
+ weeklyDays?: string[] | undefined;
38
+ };
39
+ revision: number;
40
+ status: "canceled" | "complete" | "pending";
41
+ targetSchedule: {
42
+ interval: "daily" | "manual" | "monthly" | "weekly";
43
+ monthlyDays?: number[] | undefined;
44
+ weeklyDays?: string[] | undefined;
45
+ };
46
+ thresholds: {
47
+ amount: number;
48
+ currency: string;
49
+ }[];
50
+ }>>;
51
+ export declare const confirm: import("convex/server").RegisteredMutation<"public", {
52
+ accountId: string;
53
+ observedSchedule: {
54
+ interval: "daily" | "manual" | "monthly" | "weekly";
55
+ monthlyDays?: number[] | undefined;
56
+ weeklyDays?: string[] | undefined;
57
+ };
58
+ operationKey: string;
59
+ ownerKey: string;
60
+ }, Promise<{
61
+ _creationTime: number;
62
+ _id: import("convex/values").GenericId<"payoutPolicyOperations">;
63
+ accountId: string;
64
+ attempted?: boolean | undefined;
65
+ country: string;
66
+ expectedRevision: number;
67
+ mode: "custom" | "stripe_managed";
68
+ observedAt?: number | undefined;
69
+ observedSchedule: {
70
+ interval: "daily" | "manual" | "monthly" | "weekly";
71
+ monthlyDays?: number[] | undefined;
72
+ weeklyDays?: string[] | undefined;
73
+ };
74
+ operationKey: string;
75
+ ownerKey: string;
76
+ previousSchedule: {
77
+ interval: "daily" | "manual" | "monthly" | "weekly";
78
+ monthlyDays?: number[] | undefined;
79
+ weeklyDays?: string[] | undefined;
80
+ };
81
+ revision: number;
82
+ status: "canceled" | "complete" | "pending";
83
+ targetSchedule: {
84
+ interval: "daily" | "manual" | "monthly" | "weekly";
85
+ monthlyDays?: number[] | undefined;
86
+ weeklyDays?: string[] | undefined;
87
+ };
88
+ thresholds: {
89
+ amount: number;
90
+ currency: string;
91
+ }[];
92
+ }>>;
93
+ export declare const beginAttempt: import("convex/server").RegisteredMutation<"public", {
94
+ accountId: string;
95
+ operationKey: string;
96
+ ownerKey: string;
97
+ }, Promise<{
98
+ _creationTime: number;
99
+ _id: import("convex/values").GenericId<"payoutPolicyOperations">;
100
+ accountId: string;
101
+ attempted?: boolean | undefined;
102
+ country: string;
103
+ expectedRevision: number;
104
+ mode: "custom" | "stripe_managed";
105
+ observedAt?: number | undefined;
106
+ observedSchedule: {
107
+ interval: "daily" | "manual" | "monthly" | "weekly";
108
+ monthlyDays?: number[] | undefined;
109
+ weeklyDays?: string[] | undefined;
110
+ };
111
+ operationKey: string;
112
+ ownerKey: string;
113
+ previousSchedule: {
114
+ interval: "daily" | "manual" | "monthly" | "weekly";
115
+ monthlyDays?: number[] | undefined;
116
+ weeklyDays?: string[] | undefined;
117
+ };
118
+ revision: number;
119
+ status: "canceled" | "complete" | "pending";
120
+ targetSchedule: {
121
+ interval: "daily" | "manual" | "monthly" | "weekly";
122
+ monthlyDays?: number[] | undefined;
123
+ weeklyDays?: string[] | undefined;
124
+ };
125
+ thresholds: {
126
+ amount: number;
127
+ currency: string;
128
+ }[];
129
+ }>>;
130
+ export declare const cancelUnattempted: import("convex/server").RegisteredMutation<"public", {
131
+ accountId: string;
132
+ observedSchedule: {
133
+ interval: "daily" | "manual" | "monthly" | "weekly";
134
+ monthlyDays?: number[] | undefined;
135
+ weeklyDays?: string[] | undefined;
136
+ };
137
+ operationKey: string;
138
+ ownerKey: string;
139
+ }, Promise<{
140
+ _creationTime: number;
141
+ _id: import("convex/values").GenericId<"payoutPolicyOperations">;
142
+ accountId: string;
143
+ attempted?: boolean | undefined;
144
+ country: string;
145
+ expectedRevision: number;
146
+ mode: "custom" | "stripe_managed";
147
+ observedAt?: number | undefined;
148
+ observedSchedule: {
149
+ interval: "daily" | "manual" | "monthly" | "weekly";
150
+ monthlyDays?: number[] | undefined;
151
+ weeklyDays?: string[] | undefined;
152
+ };
153
+ operationKey: string;
154
+ ownerKey: string;
155
+ previousSchedule: {
156
+ interval: "daily" | "manual" | "monthly" | "weekly";
157
+ monthlyDays?: number[] | undefined;
158
+ weeklyDays?: string[] | undefined;
159
+ };
160
+ revision: number;
161
+ status: "canceled" | "complete" | "pending";
162
+ targetSchedule: {
163
+ interval: "daily" | "manual" | "monthly" | "weekly";
164
+ monthlyDays?: number[] | undefined;
165
+ weeklyDays?: string[] | undefined;
166
+ };
167
+ thresholds: {
168
+ amount: number;
169
+ currency: string;
170
+ }[];
171
+ }>>;
172
+ //# sourceMappingURL=mutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutations.d.ts","sourceRoot":"","sources":["../../../src/component/payoutPolicy/mutations.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GlB,CAAC;AACH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuClB,CAAC;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsBvB,CAAC;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsC5B,CAAC"}
@@ -0,0 +1,191 @@
1
+ import { v } from "convex/values";
2
+ import { mutation } from "../_generated/server.js";
3
+ import { prepareFields, operationDoc, scopeFields, schedule, } from "./schema.js";
4
+ import { canonicalSchedule, canonicalThresholds, readPolicy, holdingDays, same, validateScope, } from "./helpers.js";
5
+ export const prepare = mutation({
6
+ args: prepareFields,
7
+ returns: operationDoc,
8
+ handler: async (ctx, input) => {
9
+ validateScope(input);
10
+ if (!input.operationKey.trim() ||
11
+ input.operationKey.length > 180 ||
12
+ /[\r\n]/.test(input.operationKey) ||
13
+ !Number.isSafeInteger(input.expectedRevision) ||
14
+ input.expectedRevision < -1 ||
15
+ input.expectedRevision >= Number.MAX_SAFE_INTEGER)
16
+ throw new Error("Invalid payout policy operation identity or revision.");
17
+ const days = holdingDays(input.country);
18
+ const args = {
19
+ ...input,
20
+ observedSchedule: canonicalSchedule(input.observedSchedule),
21
+ thresholds: canonicalThresholds(input.thresholds, input.mode === "custom"),
22
+ };
23
+ const old = await ctx.db
24
+ .query("payoutPolicyOperations")
25
+ .withIndex("by_operation", (q) => q.eq("operationKey", args.operationKey))
26
+ .unique();
27
+ if (old) {
28
+ if (old.accountId !== args.accountId ||
29
+ old.ownerKey !== args.ownerKey ||
30
+ old.expectedRevision !== args.expectedRevision ||
31
+ old.mode !== args.mode ||
32
+ old.country !== args.country ||
33
+ old.observedAt !== args.observedAt ||
34
+ !same(old.thresholds, args.thresholds) ||
35
+ !same(old.observedSchedule, args.observedSchedule))
36
+ throw new Error("Payout policy operation identity cannot be reused.");
37
+ return old;
38
+ }
39
+ if (input.observedAt !== undefined &&
40
+ (!Number.isSafeInteger(input.observedAt) ||
41
+ input.observedAt > Date.now() ||
42
+ input.observedAt < Date.now() - 600000))
43
+ throw new Error("Payout policy observation is stale or in the future.");
44
+ const policy = await readPolicy(ctx, args);
45
+ if (policy?.status === "changing")
46
+ throw new Error("A payout policy operation is pending.");
47
+ if ((policy?.revision ?? -1) !== args.expectedRevision)
48
+ throw new Error("Payout policy revision changed.");
49
+ if (policy?.mode === "custom" &&
50
+ args.observedSchedule.interval !== "manual")
51
+ throw new Error("Payout schedule drift requires reconciliation.");
52
+ if (policy?.mode === "custom" &&
53
+ policy.country !== args.country &&
54
+ args.mode === "custom")
55
+ throw new Error("Payout policy country changed.");
56
+ if (args.mode === "custom" &&
57
+ policy?.mode !== "custom" &&
58
+ args.observedSchedule.interval === "manual")
59
+ throw new Error("An existing manual schedule requires migration.");
60
+ const previousSchedule = policy?.mode === "custom"
61
+ ? policy.previousSchedule
62
+ : args.observedSchedule;
63
+ const targetSchedule = args.mode === "custom"
64
+ ? { interval: "manual" }
65
+ : previousSchedule;
66
+ const revision = args.expectedRevision + 1;
67
+ const operationId = await ctx.db.insert("payoutPolicyOperations", {
68
+ ...args,
69
+ revision,
70
+ previousSchedule,
71
+ targetSchedule,
72
+ status: "pending",
73
+ });
74
+ const next = {
75
+ accountId: args.accountId,
76
+ ownerKey: args.ownerKey,
77
+ revision,
78
+ mode: policy?.mode ?? "stripe_managed",
79
+ thresholds: policy?.thresholds ?? [],
80
+ status: "changing",
81
+ operationKey: args.operationKey,
82
+ country: args.country,
83
+ previousSchedule,
84
+ holdDeadline: policy?.holdDeadline ??
85
+ (args.mode === "custom"
86
+ ? (args.observedAt ?? Date.now()) + days * 86400000
87
+ : undefined),
88
+ };
89
+ if (policy)
90
+ await ctx.db.patch("payoutPolicies", policy._id, next);
91
+ else
92
+ await ctx.db.insert("payoutPolicies", next);
93
+ return (await ctx.db.get("payoutPolicyOperations", operationId));
94
+ },
95
+ });
96
+ export const confirm = mutation({
97
+ args: {
98
+ ...scopeFields,
99
+ operationKey: v.string(),
100
+ observedSchedule: schedule,
101
+ },
102
+ returns: operationDoc,
103
+ handler: async (ctx, args) => {
104
+ const policy = await readPolicy(ctx, args);
105
+ const op = await ctx.db
106
+ .query("payoutPolicyOperations")
107
+ .withIndex("by_operation", (q) => q.eq("operationKey", args.operationKey))
108
+ .unique();
109
+ if (!op || op.accountId !== args.accountId || op.ownerKey !== args.ownerKey)
110
+ throw new Error("Payout policy operation identity does not match.");
111
+ if (!same(canonicalSchedule(args.observedSchedule), op.targetSchedule))
112
+ throw new Error("Provider payout schedule was not confirmed.");
113
+ if (op.status === "complete")
114
+ return op;
115
+ if (op.status === "canceled")
116
+ throw new Error("Payout policy operation was canceled.");
117
+ if (!policy ||
118
+ policy.operationKey !== op.operationKey ||
119
+ policy.revision !== op.revision)
120
+ throw new Error("Payout policy revision changed.");
121
+ await ctx.db.patch("payoutPolicyOperations", op._id, {
122
+ status: "complete",
123
+ });
124
+ await ctx.db.patch("payoutPolicies", policy._id, {
125
+ mode: op.mode,
126
+ thresholds: op.thresholds,
127
+ status: "ready",
128
+ ...(op.mode === "stripe_managed"
129
+ ? { previousSchedule: undefined, holdDeadline: undefined }
130
+ : {}),
131
+ });
132
+ return (await ctx.db.get("payoutPolicyOperations", op._id));
133
+ },
134
+ });
135
+ export const beginAttempt = mutation({
136
+ args: { ...scopeFields, operationKey: v.string() },
137
+ returns: operationDoc,
138
+ handler: async (ctx, args) => {
139
+ const policy = await readPolicy(ctx, args);
140
+ const op = await ctx.db
141
+ .query("payoutPolicyOperations")
142
+ .withIndex("by_operation", (q) => q.eq("operationKey", args.operationKey))
143
+ .unique();
144
+ if (!op ||
145
+ op.accountId !== args.accountId ||
146
+ op.ownerKey !== args.ownerKey ||
147
+ op.status !== "pending" ||
148
+ policy?.operationKey !== op.operationKey ||
149
+ policy.status !== "changing")
150
+ throw new Error("Payout policy operation is not pending.");
151
+ if (!op.attempted)
152
+ await ctx.db.patch("payoutPolicyOperations", op._id, { attempted: true });
153
+ return (await ctx.db.get("payoutPolicyOperations", op._id));
154
+ },
155
+ });
156
+ export const cancelUnattempted = mutation({
157
+ args: {
158
+ ...scopeFields,
159
+ operationKey: v.string(),
160
+ observedSchedule: schedule,
161
+ },
162
+ returns: operationDoc,
163
+ handler: async (ctx, args) => {
164
+ const policy = await readPolicy(ctx, args);
165
+ const op = await ctx.db
166
+ .query("payoutPolicyOperations")
167
+ .withIndex("by_operation", (q) => q.eq("operationKey", args.operationKey))
168
+ .unique();
169
+ if (!op ||
170
+ op.accountId !== args.accountId ||
171
+ op.ownerKey !== args.ownerKey ||
172
+ op.attempted ||
173
+ op.status !== "pending" ||
174
+ policy?.operationKey !== op.operationKey ||
175
+ policy.status !== "changing")
176
+ throw new Error("An attempted payout policy operation cannot be canceled.");
177
+ if (!same(canonicalSchedule(args.observedSchedule), op.observedSchedule))
178
+ throw new Error("Provider schedule changed before cancellation.");
179
+ await ctx.db.patch("payoutPolicyOperations", op._id, {
180
+ status: "canceled",
181
+ });
182
+ await ctx.db.patch("payoutPolicies", policy._id, {
183
+ status: "ready",
184
+ ...(policy.mode === "stripe_managed"
185
+ ? { previousSchedule: undefined, holdDeadline: undefined }
186
+ : {}),
187
+ });
188
+ return (await ctx.db.get("payoutPolicyOperations", op._id));
189
+ },
190
+ });
191
+ //# sourceMappingURL=mutations.js.map