@fantastic.dev/better-stripe 0.17.1 → 0.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 (50) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +7 -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/index.d.ts +4 -8
  7. package/dist/client/index.d.ts.map +1 -1
  8. package/dist/client/index.js +5 -0
  9. package/dist/client/index.js.map +1 -1
  10. package/dist/client/payoutPolicy.d.ts +81 -0
  11. package/dist/client/payoutPolicy.d.ts.map +1 -0
  12. package/dist/client/payoutPolicy.js +262 -0
  13. package/dist/client/payoutPolicy.js.map +1 -0
  14. package/dist/component/_generated/component.d.ts +273 -0
  15. package/dist/component/_generated/component.d.ts.map +1 -1
  16. package/dist/component/earnings/triggers.d.ts +150 -0
  17. package/dist/component/earnings/triggers.d.ts.map +1 -1
  18. package/dist/component/payoutPolicy/helpers.d.ts +51 -0
  19. package/dist/component/payoutPolicy/helpers.d.ts.map +1 -0
  20. package/dist/component/payoutPolicy/helpers.js +68 -0
  21. package/dist/component/payoutPolicy/helpers.js.map +1 -0
  22. package/dist/component/payoutPolicy/mutations.d.ts +172 -0
  23. package/dist/component/payoutPolicy/mutations.d.ts.map +1 -0
  24. package/dist/component/payoutPolicy/mutations.js +191 -0
  25. package/dist/component/payoutPolicy/mutations.js.map +1 -0
  26. package/dist/component/payoutPolicy/queries.d.ts +97 -0
  27. package/dist/component/payoutPolicy/queries.d.ts.map +1 -0
  28. package/dist/component/payoutPolicy/queries.js +51 -0
  29. package/dist/component/payoutPolicy/queries.js.map +1 -0
  30. package/dist/component/payoutPolicy/schema.d.ts +396 -0
  31. package/dist/component/payoutPolicy/schema.d.ts.map +1 -0
  32. package/dist/component/payoutPolicy/schema.js +54 -0
  33. package/dist/component/payoutPolicy/schema.js.map +1 -0
  34. package/dist/component/schema.d.ts +131 -0
  35. package/dist/component/schema.js +3 -0
  36. package/dist/component/schema.js.map +1 -1
  37. package/docs/settlement.md +62 -0
  38. package/package.json +1 -1
  39. package/src/client/connect/payouts.ts +10 -8
  40. package/src/client/index.ts +7 -11
  41. package/src/client/payoutPolicy.test.ts +320 -0
  42. package/src/client/payoutPolicy.ts +409 -0
  43. package/src/component/_generated/api.ts +6 -0
  44. package/src/component/_generated/component.ts +280 -0
  45. package/src/component/payout-policy.test.ts +248 -0
  46. package/src/component/payoutPolicy/helpers.ts +88 -0
  47. package/src/component/payoutPolicy/mutations.ts +225 -0
  48. package/src/component/payoutPolicy/queries.ts +56 -0
  49. package/src/component/payoutPolicy/schema.ts +67 -0
  50. package/src/component/schema.ts +3 -0
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutations.js","sourceRoot":"","sources":["../../../src/component/payoutPolicy/mutations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ export declare const get: import("convex/server").RegisteredQuery<"public", {
2
+ accountId: string;
3
+ ownerKey: string;
4
+ }, Promise<{
5
+ _creationTime: number;
6
+ _id: import("convex/values").GenericId<"payoutPolicies">;
7
+ accountId: string;
8
+ country: string;
9
+ holdDeadline?: number | undefined;
10
+ mode: "custom" | "stripe_managed";
11
+ operationKey: string;
12
+ ownerKey: string;
13
+ previousSchedule?: {
14
+ interval: "daily" | "manual" | "monthly" | "weekly";
15
+ monthlyDays?: number[] | undefined;
16
+ weeklyDays?: string[] | undefined;
17
+ } | undefined;
18
+ revision: number;
19
+ status: "changing" | "ready";
20
+ thresholds: {
21
+ amount: number;
22
+ currency: string;
23
+ }[];
24
+ } | null>>;
25
+ export declare const operation: import("convex/server").RegisteredQuery<"public", {
26
+ accountId: string;
27
+ operationKey: string;
28
+ ownerKey: string;
29
+ }, Promise<{
30
+ _creationTime: number;
31
+ _id: import("convex/values").GenericId<"payoutPolicyOperations">;
32
+ accountId: string;
33
+ attempted?: boolean | undefined;
34
+ country: string;
35
+ expectedRevision: number;
36
+ mode: "custom" | "stripe_managed";
37
+ observedAt?: number | undefined;
38
+ observedSchedule: {
39
+ interval: "daily" | "manual" | "monthly" | "weekly";
40
+ monthlyDays?: number[] | undefined;
41
+ weeklyDays?: string[] | undefined;
42
+ };
43
+ operationKey: string;
44
+ ownerKey: string;
45
+ previousSchedule: {
46
+ interval: "daily" | "manual" | "monthly" | "weekly";
47
+ monthlyDays?: number[] | undefined;
48
+ weeklyDays?: string[] | undefined;
49
+ };
50
+ revision: number;
51
+ status: "canceled" | "complete" | "pending";
52
+ targetSchedule: {
53
+ interval: "daily" | "manual" | "monthly" | "weekly";
54
+ monthlyDays?: number[] | undefined;
55
+ weeklyDays?: string[] | undefined;
56
+ };
57
+ thresholds: {
58
+ amount: number;
59
+ currency: string;
60
+ }[];
61
+ } | null>>;
62
+ export declare const due: import("convex/server").RegisteredQuery<"public", {
63
+ now: number;
64
+ paginationOpts: {
65
+ id?: number;
66
+ endCursor?: string | null;
67
+ maximumRowsRead?: number;
68
+ maximumBytesRead?: number;
69
+ numItems: number;
70
+ cursor: string | null;
71
+ };
72
+ }, Promise<{
73
+ page: {
74
+ _creationTime: number;
75
+ _id: import("convex/values").GenericId<"payoutPolicies">;
76
+ accountId: string;
77
+ country: string;
78
+ holdDeadline?: number | undefined;
79
+ mode: "custom" | "stripe_managed";
80
+ operationKey: string;
81
+ ownerKey: string;
82
+ previousSchedule?: {
83
+ interval: "daily" | "manual" | "monthly" | "weekly";
84
+ monthlyDays?: number[] | undefined;
85
+ weeklyDays?: string[] | undefined;
86
+ } | undefined;
87
+ revision: number;
88
+ status: "changing" | "ready";
89
+ thresholds: {
90
+ amount: number;
91
+ currency: string;
92
+ }[];
93
+ }[];
94
+ continueCursor: string;
95
+ isDone: boolean;
96
+ }>>;
97
+ //# sourceMappingURL=queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../src/component/payoutPolicy/queries.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;UAId,CAAC;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAgBpB,CAAC;AACH,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4Bd,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { paginationOptsValidator } from "convex/server";
2
+ import { v } from "convex/values";
3
+ import { query } from "../_generated/server.js";
4
+ import { scopeFields, policyDoc, operationDoc } from "./schema.js";
5
+ import { readPolicy, validateScope } from "./helpers.js";
6
+ export const get = query({
7
+ args: scopeFields,
8
+ returns: v.union(policyDoc, v.null()),
9
+ handler: readPolicy,
10
+ });
11
+ export const operation = query({
12
+ args: { ...scopeFields, operationKey: v.string() },
13
+ returns: v.union(operationDoc, v.null()),
14
+ handler: async (ctx, args) => {
15
+ validateScope(args);
16
+ const op = await ctx.db
17
+ .query("payoutPolicyOperations")
18
+ .withIndex("by_operation", (q) => q.eq("operationKey", args.operationKey))
19
+ .unique();
20
+ if (op &&
21
+ (op.accountId !== args.accountId || op.ownerKey !== args.ownerKey))
22
+ throw new Error("Payout policy operation identity does not match.");
23
+ return op;
24
+ },
25
+ });
26
+ export const due = query({
27
+ args: { now: v.number(), paginationOpts: paginationOptsValidator },
28
+ returns: v.object({
29
+ page: v.array(policyDoc),
30
+ continueCursor: v.string(),
31
+ isDone: v.boolean(),
32
+ }),
33
+ handler: async (ctx, args) => {
34
+ if (!Number.isSafeInteger(args.now) ||
35
+ args.now < 0 ||
36
+ !Number.isInteger(args.paginationOpts.numItems) ||
37
+ args.paginationOpts.numItems < 1 ||
38
+ args.paginationOpts.numItems > 100)
39
+ throw new Error("Invalid payout policy due page.");
40
+ const page = await ctx.db
41
+ .query("payoutPolicies")
42
+ .withIndex("by_deadline", (q) => q.gt("holdDeadline", 0).lte("holdDeadline", args.now))
43
+ .paginate(args.paginationOpts);
44
+ return {
45
+ page: page.page,
46
+ continueCursor: page.continueCursor,
47
+ isDone: page.isDone,
48
+ };
49
+ },
50
+ });
51
+ //# sourceMappingURL=queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../../src/component/payoutPolicy/queries.ts"],"names":[],"mappings":"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"}