@open-loyalty/mcp-server 1.0.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.
- package/LICENSE +21 -0
- package/README.md +654 -0
- package/dist/client/http.d.ts +8 -0
- package/dist/client/http.js +69 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +40 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +20 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.js +334 -0
- package/dist/tools/achievement.d.ts +983 -0
- package/dist/tools/achievement.js +311 -0
- package/dist/tools/admin.d.ts +153 -0
- package/dist/tools/admin.js +193 -0
- package/dist/tools/analytics.d.ts +162 -0
- package/dist/tools/analytics.js +245 -0
- package/dist/tools/apikey.d.ts +72 -0
- package/dist/tools/apikey.js +78 -0
- package/dist/tools/audit.d.ts +107 -0
- package/dist/tools/audit.js +90 -0
- package/dist/tools/badge.d.ts +135 -0
- package/dist/tools/badge.js +165 -0
- package/dist/tools/campaign.d.ts +1775 -0
- package/dist/tools/campaign.js +724 -0
- package/dist/tools/export.d.ts +110 -0
- package/dist/tools/export.js +147 -0
- package/dist/tools/import.d.ts +110 -0
- package/dist/tools/import.js +126 -0
- package/dist/tools/index.d.ts +22 -0
- package/dist/tools/index.js +527 -0
- package/dist/tools/member.d.ts +345 -0
- package/dist/tools/member.js +358 -0
- package/dist/tools/member.test.d.ts +1 -0
- package/dist/tools/member.test.js +213 -0
- package/dist/tools/points.d.ts +188 -0
- package/dist/tools/points.js +306 -0
- package/dist/tools/points.test.d.ts +1 -0
- package/dist/tools/points.test.js +292 -0
- package/dist/tools/reward.d.ts +261 -0
- package/dist/tools/reward.js +371 -0
- package/dist/tools/reward.test.d.ts +1 -0
- package/dist/tools/reward.test.js +240 -0
- package/dist/tools/role.d.ts +161 -0
- package/dist/tools/role.js +160 -0
- package/dist/tools/segment.d.ts +797 -0
- package/dist/tools/segment.js +299 -0
- package/dist/tools/store.d.ts +101 -0
- package/dist/tools/store.js +117 -0
- package/dist/tools/tierset.d.ts +288 -0
- package/dist/tools/tierset.js +244 -0
- package/dist/tools/transaction.d.ts +357 -0
- package/dist/tools/transaction.js +242 -0
- package/dist/tools/transaction.test.d.ts +1 -0
- package/dist/tools/transaction.test.js +235 -0
- package/dist/tools/wallet-type.d.ts +32 -0
- package/dist/tools/wallet-type.js +58 -0
- package/dist/tools/webhook.d.ts +179 -0
- package/dist/tools/webhook.js +171 -0
- package/dist/types/schemas/achievement.d.ts +1116 -0
- package/dist/types/schemas/achievement.js +172 -0
- package/dist/types/schemas/admin.d.ts +263 -0
- package/dist/types/schemas/admin.js +99 -0
- package/dist/types/schemas/analytics.d.ts +542 -0
- package/dist/types/schemas/analytics.js +130 -0
- package/dist/types/schemas/badge.d.ts +131 -0
- package/dist/types/schemas/badge.js +48 -0
- package/dist/types/schemas/campaign.d.ts +2005 -0
- package/dist/types/schemas/campaign.js +189 -0
- package/dist/types/schemas/common.d.ts +52 -0
- package/dist/types/schemas/common.js +26 -0
- package/dist/types/schemas/export.d.ts +127 -0
- package/dist/types/schemas/export.js +43 -0
- package/dist/types/schemas/import.d.ts +344 -0
- package/dist/types/schemas/import.js +68 -0
- package/dist/types/schemas/member.d.ts +443 -0
- package/dist/types/schemas/member.js +92 -0
- package/dist/types/schemas/points.d.ts +188 -0
- package/dist/types/schemas/points.js +54 -0
- package/dist/types/schemas/reward.d.ts +278 -0
- package/dist/types/schemas/reward.js +69 -0
- package/dist/types/schemas/role.d.ts +260 -0
- package/dist/types/schemas/role.js +75 -0
- package/dist/types/schemas/segment.d.ts +592 -0
- package/dist/types/schemas/segment.js +114 -0
- package/dist/types/schemas/tierset.d.ts +552 -0
- package/dist/types/schemas/tierset.js +87 -0
- package/dist/types/schemas/transaction.d.ts +1022 -0
- package/dist/types/schemas/transaction.js +63 -0
- package/dist/types/schemas/wallet-type.d.ts +99 -0
- package/dist/types/schemas/wallet-type.js +17 -0
- package/dist/types/schemas/webhook.d.ts +195 -0
- package/dist/types/schemas/webhook.js +39 -0
- package/dist/utils/cursor.d.ts +84 -0
- package/dist/utils/cursor.js +117 -0
- package/dist/utils/errors.d.ts +12 -0
- package/dist/utils/errors.js +69 -0
- package/dist/utils/pagination.d.ts +39 -0
- package/dist/utils/pagination.js +77 -0
- package/package.json +65 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { TotalSchema } from "./common.js";
|
|
3
|
+
export const LabelSchema = z.object({
|
|
4
|
+
key: z.string(),
|
|
5
|
+
value: z.string(),
|
|
6
|
+
});
|
|
7
|
+
export const TransactionHeaderSchema = z.object({
|
|
8
|
+
documentNumber: z.string(),
|
|
9
|
+
purchasedAt: z.string(),
|
|
10
|
+
documentType: z.enum(["sell", "return"]).optional(),
|
|
11
|
+
linkedDocumentNumber: z.string().optional(),
|
|
12
|
+
purchasePlace: z.string().optional(),
|
|
13
|
+
labels: z.array(LabelSchema).optional(),
|
|
14
|
+
});
|
|
15
|
+
export const TransactionItemSchema = z.object({
|
|
16
|
+
sku: z.string(),
|
|
17
|
+
name: z.string(),
|
|
18
|
+
grossValue: z.number(),
|
|
19
|
+
category: z.string(),
|
|
20
|
+
quantity: z.number().optional(),
|
|
21
|
+
highPrecisionQuantity: z.number().optional(),
|
|
22
|
+
maker: z.string().optional(),
|
|
23
|
+
labels: z.array(LabelSchema).optional(),
|
|
24
|
+
});
|
|
25
|
+
export const TransactionAddressSchema = z.object({
|
|
26
|
+
street: z.string().optional(),
|
|
27
|
+
address1: z.string().optional(),
|
|
28
|
+
province: z.string().optional(),
|
|
29
|
+
city: z.string().optional(),
|
|
30
|
+
postal: z.string().optional(),
|
|
31
|
+
country: z.string().optional(),
|
|
32
|
+
});
|
|
33
|
+
export const TransactionCustomerDataSchema = z.object({
|
|
34
|
+
customerId: z.string().optional(),
|
|
35
|
+
email: z.string().optional(),
|
|
36
|
+
name: z.string().optional(),
|
|
37
|
+
phone: z.string().optional(),
|
|
38
|
+
loyaltyCardNumber: z.string().optional(),
|
|
39
|
+
nip: z.string().optional(),
|
|
40
|
+
address: TransactionAddressSchema.optional(),
|
|
41
|
+
});
|
|
42
|
+
export const TransactionSchema = z.object({
|
|
43
|
+
transactionId: z.string(),
|
|
44
|
+
header: TransactionHeaderSchema,
|
|
45
|
+
items: z.array(TransactionItemSchema),
|
|
46
|
+
customerData: TransactionCustomerDataSchema.optional(),
|
|
47
|
+
customerId: z.string().optional(),
|
|
48
|
+
matched: z.boolean(),
|
|
49
|
+
grossValue: z.number(),
|
|
50
|
+
pointsEarned: z.number().optional(),
|
|
51
|
+
createdAt: z.string().optional(),
|
|
52
|
+
});
|
|
53
|
+
export const TransactionCreateInputSchema = z.object({
|
|
54
|
+
storeCode: z.string().optional(),
|
|
55
|
+
header: TransactionHeaderSchema,
|
|
56
|
+
items: z.array(TransactionItemSchema),
|
|
57
|
+
customerData: TransactionCustomerDataSchema.optional(),
|
|
58
|
+
channelId: z.string().optional(),
|
|
59
|
+
});
|
|
60
|
+
export const TransactionListResponseSchema = z.object({
|
|
61
|
+
items: z.array(TransactionSchema),
|
|
62
|
+
total: TotalSchema,
|
|
63
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const WalletTypeSchema: z.ZodObject<{
|
|
3
|
+
walletTypeId: z.ZodString;
|
|
4
|
+
code: z.ZodString;
|
|
5
|
+
name: z.ZodString;
|
|
6
|
+
unitSingularName: z.ZodOptional<z.ZodString>;
|
|
7
|
+
unitPluralName: z.ZodOptional<z.ZodString>;
|
|
8
|
+
active: z.ZodBoolean;
|
|
9
|
+
isDefault: z.ZodBoolean;
|
|
10
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
11
|
+
limits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
12
|
+
allowNegativeBalance: z.ZodOptional<z.ZodBoolean>;
|
|
13
|
+
}, "strip", z.ZodTypeAny, {
|
|
14
|
+
code: string;
|
|
15
|
+
walletTypeId: string;
|
|
16
|
+
name: string;
|
|
17
|
+
active: boolean;
|
|
18
|
+
isDefault: boolean;
|
|
19
|
+
unitSingularName?: string | undefined;
|
|
20
|
+
unitPluralName?: string | undefined;
|
|
21
|
+
createdAt?: string | undefined;
|
|
22
|
+
limits?: Record<string, unknown> | undefined;
|
|
23
|
+
allowNegativeBalance?: boolean | undefined;
|
|
24
|
+
}, {
|
|
25
|
+
code: string;
|
|
26
|
+
walletTypeId: string;
|
|
27
|
+
name: string;
|
|
28
|
+
active: boolean;
|
|
29
|
+
isDefault: boolean;
|
|
30
|
+
unitSingularName?: string | undefined;
|
|
31
|
+
unitPluralName?: string | undefined;
|
|
32
|
+
createdAt?: string | undefined;
|
|
33
|
+
limits?: Record<string, unknown> | undefined;
|
|
34
|
+
allowNegativeBalance?: boolean | undefined;
|
|
35
|
+
}>;
|
|
36
|
+
export declare const WalletTypeListResponseSchema: z.ZodObject<{
|
|
37
|
+
items: z.ZodArray<z.ZodObject<{
|
|
38
|
+
walletTypeId: z.ZodString;
|
|
39
|
+
code: z.ZodString;
|
|
40
|
+
name: z.ZodString;
|
|
41
|
+
unitSingularName: z.ZodOptional<z.ZodString>;
|
|
42
|
+
unitPluralName: z.ZodOptional<z.ZodString>;
|
|
43
|
+
active: z.ZodBoolean;
|
|
44
|
+
isDefault: z.ZodBoolean;
|
|
45
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
46
|
+
limits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
47
|
+
allowNegativeBalance: z.ZodOptional<z.ZodBoolean>;
|
|
48
|
+
}, "strip", z.ZodTypeAny, {
|
|
49
|
+
code: string;
|
|
50
|
+
walletTypeId: string;
|
|
51
|
+
name: string;
|
|
52
|
+
active: boolean;
|
|
53
|
+
isDefault: boolean;
|
|
54
|
+
unitSingularName?: string | undefined;
|
|
55
|
+
unitPluralName?: string | undefined;
|
|
56
|
+
createdAt?: string | undefined;
|
|
57
|
+
limits?: Record<string, unknown> | undefined;
|
|
58
|
+
allowNegativeBalance?: boolean | undefined;
|
|
59
|
+
}, {
|
|
60
|
+
code: string;
|
|
61
|
+
walletTypeId: string;
|
|
62
|
+
name: string;
|
|
63
|
+
active: boolean;
|
|
64
|
+
isDefault: boolean;
|
|
65
|
+
unitSingularName?: string | undefined;
|
|
66
|
+
unitPluralName?: string | undefined;
|
|
67
|
+
createdAt?: string | undefined;
|
|
68
|
+
limits?: Record<string, unknown> | undefined;
|
|
69
|
+
allowNegativeBalance?: boolean | undefined;
|
|
70
|
+
}>, "many">;
|
|
71
|
+
}, "strip", z.ZodTypeAny, {
|
|
72
|
+
items: {
|
|
73
|
+
code: string;
|
|
74
|
+
walletTypeId: string;
|
|
75
|
+
name: string;
|
|
76
|
+
active: boolean;
|
|
77
|
+
isDefault: boolean;
|
|
78
|
+
unitSingularName?: string | undefined;
|
|
79
|
+
unitPluralName?: string | undefined;
|
|
80
|
+
createdAt?: string | undefined;
|
|
81
|
+
limits?: Record<string, unknown> | undefined;
|
|
82
|
+
allowNegativeBalance?: boolean | undefined;
|
|
83
|
+
}[];
|
|
84
|
+
}, {
|
|
85
|
+
items: {
|
|
86
|
+
code: string;
|
|
87
|
+
walletTypeId: string;
|
|
88
|
+
name: string;
|
|
89
|
+
active: boolean;
|
|
90
|
+
isDefault: boolean;
|
|
91
|
+
unitSingularName?: string | undefined;
|
|
92
|
+
unitPluralName?: string | undefined;
|
|
93
|
+
createdAt?: string | undefined;
|
|
94
|
+
limits?: Record<string, unknown> | undefined;
|
|
95
|
+
allowNegativeBalance?: boolean | undefined;
|
|
96
|
+
}[];
|
|
97
|
+
}>;
|
|
98
|
+
export type WalletType = z.infer<typeof WalletTypeSchema>;
|
|
99
|
+
export type WalletTypeListResponse = z.infer<typeof WalletTypeListResponseSchema>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const WalletTypeSchema = z.object({
|
|
3
|
+
walletTypeId: z.string(),
|
|
4
|
+
code: z.string(),
|
|
5
|
+
name: z.string(),
|
|
6
|
+
unitSingularName: z.string().optional(),
|
|
7
|
+
unitPluralName: z.string().optional(),
|
|
8
|
+
active: z.boolean(),
|
|
9
|
+
isDefault: z.boolean(),
|
|
10
|
+
createdAt: z.string().optional(),
|
|
11
|
+
limits: z.record(z.unknown()).optional(),
|
|
12
|
+
allowNegativeBalance: z.boolean().optional(),
|
|
13
|
+
});
|
|
14
|
+
// API returns { items: [...] } not just an array
|
|
15
|
+
export const WalletTypeListResponseSchema = z.object({
|
|
16
|
+
items: z.array(WalletTypeSchema),
|
|
17
|
+
});
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const WebhookHeaderSchema: z.ZodObject<{
|
|
3
|
+
headerName: z.ZodString;
|
|
4
|
+
headerValue: z.ZodString;
|
|
5
|
+
}, "strip", z.ZodTypeAny, {
|
|
6
|
+
headerName: string;
|
|
7
|
+
headerValue: string;
|
|
8
|
+
}, {
|
|
9
|
+
headerName: string;
|
|
10
|
+
headerValue: string;
|
|
11
|
+
}>;
|
|
12
|
+
export type WebhookHeader = z.infer<typeof WebhookHeaderSchema>;
|
|
13
|
+
export declare const WebhookSubscriptionSchema: z.ZodObject<{
|
|
14
|
+
webhookSubscriptionId: z.ZodString;
|
|
15
|
+
eventName: z.ZodString;
|
|
16
|
+
url: z.ZodString;
|
|
17
|
+
headers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
18
|
+
headerName: z.ZodString;
|
|
19
|
+
headerValue: z.ZodString;
|
|
20
|
+
}, "strip", z.ZodTypeAny, {
|
|
21
|
+
headerName: string;
|
|
22
|
+
headerValue: string;
|
|
23
|
+
}, {
|
|
24
|
+
headerName: string;
|
|
25
|
+
headerValue: string;
|
|
26
|
+
}>, "many">>;
|
|
27
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, "strip", z.ZodTypeAny, {
|
|
29
|
+
url: string;
|
|
30
|
+
eventName: string;
|
|
31
|
+
webhookSubscriptionId: string;
|
|
32
|
+
headers?: {
|
|
33
|
+
headerName: string;
|
|
34
|
+
headerValue: string;
|
|
35
|
+
}[] | undefined;
|
|
36
|
+
createdAt?: string | undefined;
|
|
37
|
+
}, {
|
|
38
|
+
url: string;
|
|
39
|
+
eventName: string;
|
|
40
|
+
webhookSubscriptionId: string;
|
|
41
|
+
headers?: {
|
|
42
|
+
headerName: string;
|
|
43
|
+
headerValue: string;
|
|
44
|
+
}[] | undefined;
|
|
45
|
+
createdAt?: string | undefined;
|
|
46
|
+
}>;
|
|
47
|
+
export type WebhookSubscription = z.infer<typeof WebhookSubscriptionSchema>;
|
|
48
|
+
export declare const WebhookSubscriptionCreateInputSchema: z.ZodObject<{
|
|
49
|
+
eventName: z.ZodString;
|
|
50
|
+
url: z.ZodString;
|
|
51
|
+
headers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
52
|
+
headerName: z.ZodString;
|
|
53
|
+
headerValue: z.ZodString;
|
|
54
|
+
}, "strip", z.ZodTypeAny, {
|
|
55
|
+
headerName: string;
|
|
56
|
+
headerValue: string;
|
|
57
|
+
}, {
|
|
58
|
+
headerName: string;
|
|
59
|
+
headerValue: string;
|
|
60
|
+
}>, "many">>;
|
|
61
|
+
}, "strip", z.ZodTypeAny, {
|
|
62
|
+
url: string;
|
|
63
|
+
eventName: string;
|
|
64
|
+
headers?: {
|
|
65
|
+
headerName: string;
|
|
66
|
+
headerValue: string;
|
|
67
|
+
}[] | undefined;
|
|
68
|
+
}, {
|
|
69
|
+
url: string;
|
|
70
|
+
eventName: string;
|
|
71
|
+
headers?: {
|
|
72
|
+
headerName: string;
|
|
73
|
+
headerValue: string;
|
|
74
|
+
}[] | undefined;
|
|
75
|
+
}>;
|
|
76
|
+
export type WebhookSubscriptionCreateInput = z.infer<typeof WebhookSubscriptionCreateInputSchema>;
|
|
77
|
+
export declare const WebhookSubscriptionUpdateInputSchema: z.ZodObject<{
|
|
78
|
+
eventName: z.ZodOptional<z.ZodString>;
|
|
79
|
+
url: z.ZodOptional<z.ZodString>;
|
|
80
|
+
headers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
81
|
+
headerName: z.ZodString;
|
|
82
|
+
headerValue: z.ZodString;
|
|
83
|
+
}, "strip", z.ZodTypeAny, {
|
|
84
|
+
headerName: string;
|
|
85
|
+
headerValue: string;
|
|
86
|
+
}, {
|
|
87
|
+
headerName: string;
|
|
88
|
+
headerValue: string;
|
|
89
|
+
}>, "many">>;
|
|
90
|
+
}, "strip", z.ZodTypeAny, {
|
|
91
|
+
headers?: {
|
|
92
|
+
headerName: string;
|
|
93
|
+
headerValue: string;
|
|
94
|
+
}[] | undefined;
|
|
95
|
+
url?: string | undefined;
|
|
96
|
+
eventName?: string | undefined;
|
|
97
|
+
}, {
|
|
98
|
+
headers?: {
|
|
99
|
+
headerName: string;
|
|
100
|
+
headerValue: string;
|
|
101
|
+
}[] | undefined;
|
|
102
|
+
url?: string | undefined;
|
|
103
|
+
eventName?: string | undefined;
|
|
104
|
+
}>;
|
|
105
|
+
export type WebhookSubscriptionUpdateInput = z.infer<typeof WebhookSubscriptionUpdateInputSchema>;
|
|
106
|
+
export declare const WebhookEventTypesSchema: z.ZodObject<{
|
|
107
|
+
items: z.ZodArray<z.ZodString, "many">;
|
|
108
|
+
}, "strip", z.ZodTypeAny, {
|
|
109
|
+
items: string[];
|
|
110
|
+
}, {
|
|
111
|
+
items: string[];
|
|
112
|
+
}>;
|
|
113
|
+
export type WebhookEventTypes = z.infer<typeof WebhookEventTypesSchema>;
|
|
114
|
+
export declare const WebhookSubscriptionListResponseSchema: z.ZodObject<{
|
|
115
|
+
items: z.ZodArray<z.ZodObject<{
|
|
116
|
+
webhookSubscriptionId: z.ZodString;
|
|
117
|
+
eventName: z.ZodString;
|
|
118
|
+
url: z.ZodString;
|
|
119
|
+
headers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
120
|
+
headerName: z.ZodString;
|
|
121
|
+
headerValue: z.ZodString;
|
|
122
|
+
}, "strip", z.ZodTypeAny, {
|
|
123
|
+
headerName: string;
|
|
124
|
+
headerValue: string;
|
|
125
|
+
}, {
|
|
126
|
+
headerName: string;
|
|
127
|
+
headerValue: string;
|
|
128
|
+
}>, "many">>;
|
|
129
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
130
|
+
}, "strip", z.ZodTypeAny, {
|
|
131
|
+
url: string;
|
|
132
|
+
eventName: string;
|
|
133
|
+
webhookSubscriptionId: string;
|
|
134
|
+
headers?: {
|
|
135
|
+
headerName: string;
|
|
136
|
+
headerValue: string;
|
|
137
|
+
}[] | undefined;
|
|
138
|
+
createdAt?: string | undefined;
|
|
139
|
+
}, {
|
|
140
|
+
url: string;
|
|
141
|
+
eventName: string;
|
|
142
|
+
webhookSubscriptionId: string;
|
|
143
|
+
headers?: {
|
|
144
|
+
headerName: string;
|
|
145
|
+
headerValue: string;
|
|
146
|
+
}[] | undefined;
|
|
147
|
+
createdAt?: string | undefined;
|
|
148
|
+
}>, "many">;
|
|
149
|
+
total: z.ZodOptional<z.ZodObject<{
|
|
150
|
+
all: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
|
|
151
|
+
filtered: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
|
|
152
|
+
estimated: z.ZodOptional<z.ZodBoolean>;
|
|
153
|
+
}, "strip", z.ZodTypeAny, {
|
|
154
|
+
all?: string | number | undefined;
|
|
155
|
+
filtered?: string | number | undefined;
|
|
156
|
+
estimated?: boolean | undefined;
|
|
157
|
+
}, {
|
|
158
|
+
all?: string | number | undefined;
|
|
159
|
+
filtered?: string | number | undefined;
|
|
160
|
+
estimated?: boolean | undefined;
|
|
161
|
+
}>>;
|
|
162
|
+
}, "strip", z.ZodTypeAny, {
|
|
163
|
+
items: {
|
|
164
|
+
url: string;
|
|
165
|
+
eventName: string;
|
|
166
|
+
webhookSubscriptionId: string;
|
|
167
|
+
headers?: {
|
|
168
|
+
headerName: string;
|
|
169
|
+
headerValue: string;
|
|
170
|
+
}[] | undefined;
|
|
171
|
+
createdAt?: string | undefined;
|
|
172
|
+
}[];
|
|
173
|
+
total?: {
|
|
174
|
+
all?: string | number | undefined;
|
|
175
|
+
filtered?: string | number | undefined;
|
|
176
|
+
estimated?: boolean | undefined;
|
|
177
|
+
} | undefined;
|
|
178
|
+
}, {
|
|
179
|
+
items: {
|
|
180
|
+
url: string;
|
|
181
|
+
eventName: string;
|
|
182
|
+
webhookSubscriptionId: string;
|
|
183
|
+
headers?: {
|
|
184
|
+
headerName: string;
|
|
185
|
+
headerValue: string;
|
|
186
|
+
}[] | undefined;
|
|
187
|
+
createdAt?: string | undefined;
|
|
188
|
+
}[];
|
|
189
|
+
total?: {
|
|
190
|
+
all?: string | number | undefined;
|
|
191
|
+
filtered?: string | number | undefined;
|
|
192
|
+
estimated?: boolean | undefined;
|
|
193
|
+
} | undefined;
|
|
194
|
+
}>;
|
|
195
|
+
export type WebhookSubscriptionListResponse = z.infer<typeof WebhookSubscriptionListResponseSchema>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// Webhook header for custom headers in subscriptions
|
|
3
|
+
export const WebhookHeaderSchema = z.object({
|
|
4
|
+
headerName: z.string().describe("Header name."),
|
|
5
|
+
headerValue: z.string().describe("Header value."),
|
|
6
|
+
});
|
|
7
|
+
// Webhook subscription
|
|
8
|
+
export const WebhookSubscriptionSchema = z.object({
|
|
9
|
+
webhookSubscriptionId: z.string().describe("Unique webhook subscription ID (UUID)."),
|
|
10
|
+
eventName: z.string().describe("Event name this subscription listens to."),
|
|
11
|
+
url: z.string().describe("URL to send webhook events to."),
|
|
12
|
+
headers: z.array(WebhookHeaderSchema).optional().describe("Custom headers to include in webhook requests."),
|
|
13
|
+
createdAt: z.string().optional().describe("Creation timestamp (ISO format)."),
|
|
14
|
+
});
|
|
15
|
+
// Input schema for creating a webhook subscription
|
|
16
|
+
export const WebhookSubscriptionCreateInputSchema = z.object({
|
|
17
|
+
eventName: z.string().describe("Event name to subscribe to. Use webhook_events to discover available events."),
|
|
18
|
+
url: z.string().describe("URL to receive webhook events."),
|
|
19
|
+
headers: z.array(WebhookHeaderSchema).optional().describe("Custom headers to include in webhook requests."),
|
|
20
|
+
});
|
|
21
|
+
// Input schema for updating a webhook subscription
|
|
22
|
+
export const WebhookSubscriptionUpdateInputSchema = z.object({
|
|
23
|
+
eventName: z.string().optional().describe("Event name to subscribe to."),
|
|
24
|
+
url: z.string().optional().describe("URL to receive webhook events."),
|
|
25
|
+
headers: z.array(WebhookHeaderSchema).optional().describe("Custom headers to include in webhook requests."),
|
|
26
|
+
});
|
|
27
|
+
// Response schema for webhook event types list
|
|
28
|
+
export const WebhookEventTypesSchema = z.object({
|
|
29
|
+
items: z.array(z.string()).describe("List of available webhook event type names."),
|
|
30
|
+
});
|
|
31
|
+
// Response schema for webhook subscription list
|
|
32
|
+
export const WebhookSubscriptionListResponseSchema = z.object({
|
|
33
|
+
items: z.array(WebhookSubscriptionSchema),
|
|
34
|
+
total: z.object({
|
|
35
|
+
all: z.union([z.number(), z.string()]).optional(),
|
|
36
|
+
filtered: z.union([z.number(), z.string()]).optional(),
|
|
37
|
+
estimated: z.boolean().optional(),
|
|
38
|
+
}).optional(),
|
|
39
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor-based pagination utilities for Open Loyalty MCP.
|
|
3
|
+
*
|
|
4
|
+
* Since the Open Loyalty API only supports offset-based pagination (_page/_itemsOnPage),
|
|
5
|
+
* we implement client-side cursor emulation by encoding pagination state into opaque cursors.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Internal cursor data structure.
|
|
9
|
+
* Encoded as base64url JSON for the external cursor string.
|
|
10
|
+
*/
|
|
11
|
+
export interface CursorData {
|
|
12
|
+
/** Page number (1-indexed) */
|
|
13
|
+
p: number;
|
|
14
|
+
/** Items per page */
|
|
15
|
+
pp: number;
|
|
16
|
+
/** Version for future migrations */
|
|
17
|
+
v: number;
|
|
18
|
+
/** Optional timestamp for expiration (not currently enforced) */
|
|
19
|
+
ts?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Pagination metadata returned in list responses.
|
|
23
|
+
*/
|
|
24
|
+
export interface PaginationMeta {
|
|
25
|
+
/** Current cursor (encodes current page state) */
|
|
26
|
+
cursor: string;
|
|
27
|
+
/** Cursor for the next page, or undefined if no more pages */
|
|
28
|
+
nextCursor: string | undefined;
|
|
29
|
+
/** Whether there are more items after the current page */
|
|
30
|
+
hasMore: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Encode pagination state into an opaque cursor string.
|
|
34
|
+
* Uses base64url encoding of JSON data.
|
|
35
|
+
*
|
|
36
|
+
* @param data - Pagination state to encode
|
|
37
|
+
* @returns Opaque cursor string
|
|
38
|
+
*/
|
|
39
|
+
export declare function encodeCursor(data: Omit<CursorData, 'v'>): string;
|
|
40
|
+
/**
|
|
41
|
+
* Decode an opaque cursor string back to pagination state.
|
|
42
|
+
*
|
|
43
|
+
* @param cursor - Opaque cursor string
|
|
44
|
+
* @returns Decoded pagination state, or null if invalid
|
|
45
|
+
*/
|
|
46
|
+
export declare function decodeCursor(cursor: string): CursorData | null;
|
|
47
|
+
/**
|
|
48
|
+
* Build pagination metadata for a list response.
|
|
49
|
+
*
|
|
50
|
+
* @param page - Current page number (1-indexed)
|
|
51
|
+
* @param perPage - Items per page
|
|
52
|
+
* @param itemCount - Number of items returned in current page
|
|
53
|
+
* @param total - Total number of items (from API response, may be undefined)
|
|
54
|
+
* @returns Pagination metadata with cursors
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildPaginationMeta(page: number, perPage: number, itemCount: number, total?: number): PaginationMeta;
|
|
57
|
+
/**
|
|
58
|
+
* Pagination input that supports both cursor and page/perPage.
|
|
59
|
+
*/
|
|
60
|
+
export interface PaginationInput {
|
|
61
|
+
/** Opaque cursor from previous response (takes priority over page/perPage) */
|
|
62
|
+
cursor?: string;
|
|
63
|
+
/** Page number (1-indexed, used if no cursor) */
|
|
64
|
+
page?: number;
|
|
65
|
+
/** Items per page (used if no cursor) */
|
|
66
|
+
perPage?: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Resolved pagination parameters for API calls.
|
|
70
|
+
*/
|
|
71
|
+
export interface ResolvedPagination {
|
|
72
|
+
/** Page number to request (1-indexed) */
|
|
73
|
+
page: number;
|
|
74
|
+
/** Items per page */
|
|
75
|
+
perPage: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Resolve pagination input to concrete page/perPage values.
|
|
79
|
+
* If a cursor is provided and valid, it takes priority over page/perPage.
|
|
80
|
+
*
|
|
81
|
+
* @param input - Pagination input with optional cursor
|
|
82
|
+
* @returns Resolved page and perPage values
|
|
83
|
+
*/
|
|
84
|
+
export declare function resolvePaginationInput(input: PaginationInput): ResolvedPagination;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor-based pagination utilities for Open Loyalty MCP.
|
|
3
|
+
*
|
|
4
|
+
* Since the Open Loyalty API only supports offset-based pagination (_page/_itemsOnPage),
|
|
5
|
+
* we implement client-side cursor emulation by encoding pagination state into opaque cursors.
|
|
6
|
+
*/
|
|
7
|
+
/** Current cursor format version */
|
|
8
|
+
const CURSOR_VERSION = 1;
|
|
9
|
+
/**
|
|
10
|
+
* Encode pagination state into an opaque cursor string.
|
|
11
|
+
* Uses base64url encoding of JSON data.
|
|
12
|
+
*
|
|
13
|
+
* @param data - Pagination state to encode
|
|
14
|
+
* @returns Opaque cursor string
|
|
15
|
+
*/
|
|
16
|
+
export function encodeCursor(data) {
|
|
17
|
+
const cursorData = {
|
|
18
|
+
...data,
|
|
19
|
+
v: CURSOR_VERSION,
|
|
20
|
+
};
|
|
21
|
+
const json = JSON.stringify(cursorData);
|
|
22
|
+
// Use base64url encoding (URL-safe base64)
|
|
23
|
+
return Buffer.from(json, 'utf-8')
|
|
24
|
+
.toString('base64')
|
|
25
|
+
.replace(/\+/g, '-')
|
|
26
|
+
.replace(/\//g, '_')
|
|
27
|
+
.replace(/=+$/, '');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Decode an opaque cursor string back to pagination state.
|
|
31
|
+
*
|
|
32
|
+
* @param cursor - Opaque cursor string
|
|
33
|
+
* @returns Decoded pagination state, or null if invalid
|
|
34
|
+
*/
|
|
35
|
+
export function decodeCursor(cursor) {
|
|
36
|
+
try {
|
|
37
|
+
// Restore base64 from base64url
|
|
38
|
+
let base64 = cursor.replace(/-/g, '+').replace(/_/g, '/');
|
|
39
|
+
// Add padding if needed
|
|
40
|
+
const paddingNeeded = (4 - (base64.length % 4)) % 4;
|
|
41
|
+
base64 += '='.repeat(paddingNeeded);
|
|
42
|
+
const json = Buffer.from(base64, 'base64').toString('utf-8');
|
|
43
|
+
const data = JSON.parse(json);
|
|
44
|
+
// Validate required fields
|
|
45
|
+
if (typeof data.p !== 'number' || data.p < 1)
|
|
46
|
+
return null;
|
|
47
|
+
if (typeof data.pp !== 'number' || data.pp < 1)
|
|
48
|
+
return null;
|
|
49
|
+
if (typeof data.v !== 'number')
|
|
50
|
+
return null;
|
|
51
|
+
return data;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build pagination metadata for a list response.
|
|
59
|
+
*
|
|
60
|
+
* @param page - Current page number (1-indexed)
|
|
61
|
+
* @param perPage - Items per page
|
|
62
|
+
* @param itemCount - Number of items returned in current page
|
|
63
|
+
* @param total - Total number of items (from API response, may be undefined)
|
|
64
|
+
* @returns Pagination metadata with cursors
|
|
65
|
+
*/
|
|
66
|
+
export function buildPaginationMeta(page, perPage, itemCount, total) {
|
|
67
|
+
// Build current cursor
|
|
68
|
+
const cursor = encodeCursor({ p: page, pp: perPage });
|
|
69
|
+
// Determine if there are more pages
|
|
70
|
+
let hasMore = false;
|
|
71
|
+
if (total !== undefined && typeof total === 'number') {
|
|
72
|
+
// If we have total, calculate if there are more pages
|
|
73
|
+
hasMore = page * perPage < total;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// If no total, assume more pages if we got a full page of results
|
|
77
|
+
hasMore = itemCount >= perPage;
|
|
78
|
+
}
|
|
79
|
+
// Build next cursor if there are more pages
|
|
80
|
+
const nextCursor = hasMore
|
|
81
|
+
? encodeCursor({ p: page + 1, pp: perPage })
|
|
82
|
+
: undefined;
|
|
83
|
+
return {
|
|
84
|
+
cursor,
|
|
85
|
+
nextCursor,
|
|
86
|
+
hasMore,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** Default page number if not specified */
|
|
90
|
+
const DEFAULT_PAGE = 1;
|
|
91
|
+
/** Default items per page if not specified */
|
|
92
|
+
const DEFAULT_PER_PAGE = 25;
|
|
93
|
+
/**
|
|
94
|
+
* Resolve pagination input to concrete page/perPage values.
|
|
95
|
+
* If a cursor is provided and valid, it takes priority over page/perPage.
|
|
96
|
+
*
|
|
97
|
+
* @param input - Pagination input with optional cursor
|
|
98
|
+
* @returns Resolved page and perPage values
|
|
99
|
+
*/
|
|
100
|
+
export function resolvePaginationInput(input) {
|
|
101
|
+
// If cursor is provided, try to decode it
|
|
102
|
+
if (input.cursor) {
|
|
103
|
+
const cursorData = decodeCursor(input.cursor);
|
|
104
|
+
if (cursorData) {
|
|
105
|
+
return {
|
|
106
|
+
page: cursorData.p,
|
|
107
|
+
perPage: cursorData.pp,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Invalid cursor - fall through to page/perPage
|
|
111
|
+
}
|
|
112
|
+
// Use page/perPage with defaults
|
|
113
|
+
return {
|
|
114
|
+
page: input.page ?? DEFAULT_PAGE,
|
|
115
|
+
perPage: input.perPage ?? DEFAULT_PER_PAGE,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class OpenLoyaltyError extends Error {
|
|
2
|
+
code: string;
|
|
3
|
+
hint: string;
|
|
4
|
+
relatedTool: string;
|
|
5
|
+
constructor(options: {
|
|
6
|
+
code: string;
|
|
7
|
+
message: string;
|
|
8
|
+
hint: string;
|
|
9
|
+
relatedTool: string;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export declare function formatApiError(error: unknown, relatedTool: string): OpenLoyaltyError;
|