@devwithbobby/loops 0.1.10 → 0.1.11
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/dist/component/convex.config.d.ts.map +1 -1
- package/dist/component/convex.config.js +1 -0
- package/dist/component/lib.d.ts +6 -0
- package/dist/component/lib.d.ts.map +1 -1
- package/dist/component/lib.js +80 -0
- package/package.json +1 -1
- package/src/component/convex.config.ts +1 -0
- package/src/component/lib.ts +85 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convex.config.d.ts","sourceRoot":"","sources":["../../src/component/convex.config.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,SAAS,KAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"convex.config.d.ts","sourceRoot":"","sources":["../../src/component/convex.config.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,SAAS,KAA2B,CAAC;AAwB3C,eAAe,SAAS,CAAC"}
|
|
@@ -9,6 +9,7 @@ component.export(api, {
|
|
|
9
9
|
unsubscribeContact: api.lib.unsubscribeContact,
|
|
10
10
|
resubscribeContact: api.lib.resubscribeContact,
|
|
11
11
|
countContacts: api.lib.countContacts,
|
|
12
|
+
listContacts: api.lib.listContacts,
|
|
12
13
|
sendTransactional: api.lib.sendTransactional,
|
|
13
14
|
sendEvent: api.lib.sendEvent,
|
|
14
15
|
sendCampaign: api.lib.sendCampaign,
|
package/dist/component/lib.d.ts
CHANGED
|
@@ -15,6 +15,12 @@ export declare const logEmailOperation: any;
|
|
|
15
15
|
* Can filter by audience criteria (userGroup, source, subscribed status)
|
|
16
16
|
*/
|
|
17
17
|
export declare const countContacts: any;
|
|
18
|
+
/**
|
|
19
|
+
* List contacts from the database with pagination
|
|
20
|
+
* Can filter by audience criteria (userGroup, source, subscribed status)
|
|
21
|
+
* Returns actual contact data, not just a count
|
|
22
|
+
*/
|
|
23
|
+
export declare const listContacts: any;
|
|
18
24
|
/**
|
|
19
25
|
* Add or update a contact in Loops
|
|
20
26
|
* This function tries to create a contact, and if the email already exists (409),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/component/lib.ts"],"names":[],"mappings":"AA0BA;;GAEG;AACH,eAAO,MAAM,YAAY,KA6CvB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa,KAexB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB,KAgC5B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,aAAa,KAwCxB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,UAAU,KAiHrB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa,KAoDxB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB,KAqD5B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,SAAS,KAgCpB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa,KA8BxB,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,YAAY,KAiHvB,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,WAAW,KAyDtB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,KA2DtB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,KAyD9B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,KA+B7B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,KA+B7B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,mBAAmB,KAwC9B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,eAAe,KAwC1B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa,KAgDxB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAsGlC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KA6ClC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,mBAAmB,KA6C9B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,KA8B/B,CAAC"}
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/component/lib.ts"],"names":[],"mappings":"AA0BA;;GAEG;AACH,eAAO,MAAM,YAAY,KA6CvB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa,KAexB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB,KAgC5B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,aAAa,KAwCxB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,YAAY,KA8EvB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,UAAU,KAiHrB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa,KAoDxB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB,KAqD5B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,SAAS,KAgCpB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa,KA8BxB,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,YAAY,KAiHvB,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,WAAW,KAyDtB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,KA2DtB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,KAyD9B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,KA+B7B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,KA+B7B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,mBAAmB,KAwC9B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,eAAe,KAwC1B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa,KAgDxB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAsGlC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KA6ClC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,mBAAmB,KA6C9B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,KA8B/B,CAAC"}
|
package/dist/component/lib.js
CHANGED
|
@@ -175,6 +175,86 @@ export const countContacts = zq({
|
|
|
175
175
|
return contacts.length;
|
|
176
176
|
},
|
|
177
177
|
});
|
|
178
|
+
/**
|
|
179
|
+
* List contacts from the database with pagination
|
|
180
|
+
* Can filter by audience criteria (userGroup, source, subscribed status)
|
|
181
|
+
* Returns actual contact data, not just a count
|
|
182
|
+
*/
|
|
183
|
+
export const listContacts = zq({
|
|
184
|
+
args: z.object({
|
|
185
|
+
userGroup: z.string().optional(),
|
|
186
|
+
source: z.string().optional(),
|
|
187
|
+
subscribed: z.boolean().optional(),
|
|
188
|
+
limit: z.number().min(1).max(1000).default(100),
|
|
189
|
+
offset: z.number().min(0).default(0),
|
|
190
|
+
}),
|
|
191
|
+
returns: z.object({
|
|
192
|
+
contacts: z.array(z.object({
|
|
193
|
+
_id: z.string(),
|
|
194
|
+
email: z.string(),
|
|
195
|
+
firstName: z.string().optional(),
|
|
196
|
+
lastName: z.string().optional(),
|
|
197
|
+
userId: z.string().optional(),
|
|
198
|
+
source: z.string().optional(),
|
|
199
|
+
subscribed: z.boolean(),
|
|
200
|
+
userGroup: z.string().optional(),
|
|
201
|
+
loopsContactId: z.string().optional(),
|
|
202
|
+
createdAt: z.number(),
|
|
203
|
+
updatedAt: z.number(),
|
|
204
|
+
})),
|
|
205
|
+
total: z.number(),
|
|
206
|
+
limit: z.number(),
|
|
207
|
+
offset: z.number(),
|
|
208
|
+
hasMore: z.boolean(),
|
|
209
|
+
}),
|
|
210
|
+
handler: async (ctx, args) => {
|
|
211
|
+
let allContacts;
|
|
212
|
+
// Get all contacts matching the filters
|
|
213
|
+
if (args.userGroup !== undefined) {
|
|
214
|
+
allContacts = await ctx.db
|
|
215
|
+
.query("contacts")
|
|
216
|
+
.withIndex("userGroup", (q) => q.eq("userGroup", args.userGroup))
|
|
217
|
+
.collect();
|
|
218
|
+
}
|
|
219
|
+
else if (args.source !== undefined) {
|
|
220
|
+
allContacts = await ctx.db
|
|
221
|
+
.query("contacts")
|
|
222
|
+
.withIndex("source", (q) => q.eq("source", args.source))
|
|
223
|
+
.collect();
|
|
224
|
+
}
|
|
225
|
+
else if (args.subscribed !== undefined) {
|
|
226
|
+
allContacts = await ctx.db
|
|
227
|
+
.query("contacts")
|
|
228
|
+
.withIndex("subscribed", (q) => q.eq("subscribed", args.subscribed))
|
|
229
|
+
.collect();
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
allContacts = await ctx.db.query("contacts").collect();
|
|
233
|
+
}
|
|
234
|
+
// Apply additional filters (for cases where we need to filter by multiple criteria)
|
|
235
|
+
if (args.userGroup !== undefined && allContacts) {
|
|
236
|
+
allContacts = allContacts.filter((c) => c.userGroup === args.userGroup);
|
|
237
|
+
}
|
|
238
|
+
if (args.source !== undefined && allContacts) {
|
|
239
|
+
allContacts = allContacts.filter((c) => c.source === args.source);
|
|
240
|
+
}
|
|
241
|
+
if (args.subscribed !== undefined && allContacts) {
|
|
242
|
+
allContacts = allContacts.filter((c) => c.subscribed === args.subscribed);
|
|
243
|
+
}
|
|
244
|
+
// Sort by createdAt (newest first)
|
|
245
|
+
allContacts.sort((a, b) => b.createdAt - a.createdAt);
|
|
246
|
+
const total = allContacts.length;
|
|
247
|
+
const paginatedContacts = allContacts.slice(args.offset, args.offset + args.limit);
|
|
248
|
+
const hasMore = args.offset + args.limit < total;
|
|
249
|
+
return {
|
|
250
|
+
contacts: paginatedContacts,
|
|
251
|
+
total,
|
|
252
|
+
limit: args.limit,
|
|
253
|
+
offset: args.offset,
|
|
254
|
+
hasMore,
|
|
255
|
+
};
|
|
256
|
+
},
|
|
257
|
+
});
|
|
178
258
|
/**
|
|
179
259
|
* Add or update a contact in Loops
|
|
180
260
|
* This function tries to create a contact, and if the email already exists (409),
|
package/package.json
CHANGED
|
@@ -10,6 +10,7 @@ const component = defineComponent("loops");
|
|
|
10
10
|
unsubscribeContact: api.lib.unsubscribeContact,
|
|
11
11
|
resubscribeContact: api.lib.resubscribeContact,
|
|
12
12
|
countContacts: api.lib.countContacts,
|
|
13
|
+
listContacts: api.lib.listContacts,
|
|
13
14
|
sendTransactional: api.lib.sendTransactional,
|
|
14
15
|
sendEvent: api.lib.sendEvent,
|
|
15
16
|
sendCampaign: api.lib.sendCampaign,
|
package/src/component/lib.ts
CHANGED
|
@@ -177,6 +177,91 @@ export const countContacts = zq({
|
|
|
177
177
|
},
|
|
178
178
|
});
|
|
179
179
|
|
|
180
|
+
/**
|
|
181
|
+
* List contacts from the database with pagination
|
|
182
|
+
* Can filter by audience criteria (userGroup, source, subscribed status)
|
|
183
|
+
* Returns actual contact data, not just a count
|
|
184
|
+
*/
|
|
185
|
+
export const listContacts = zq({
|
|
186
|
+
args: z.object({
|
|
187
|
+
userGroup: z.string().optional(),
|
|
188
|
+
source: z.string().optional(),
|
|
189
|
+
subscribed: z.boolean().optional(),
|
|
190
|
+
limit: z.number().min(1).max(1000).default(100),
|
|
191
|
+
offset: z.number().min(0).default(0),
|
|
192
|
+
}),
|
|
193
|
+
returns: z.object({
|
|
194
|
+
contacts: z.array(
|
|
195
|
+
z.object({
|
|
196
|
+
_id: z.string(),
|
|
197
|
+
email: z.string(),
|
|
198
|
+
firstName: z.string().optional(),
|
|
199
|
+
lastName: z.string().optional(),
|
|
200
|
+
userId: z.string().optional(),
|
|
201
|
+
source: z.string().optional(),
|
|
202
|
+
subscribed: z.boolean(),
|
|
203
|
+
userGroup: z.string().optional(),
|
|
204
|
+
loopsContactId: z.string().optional(),
|
|
205
|
+
createdAt: z.number(),
|
|
206
|
+
updatedAt: z.number(),
|
|
207
|
+
}),
|
|
208
|
+
),
|
|
209
|
+
total: z.number(),
|
|
210
|
+
limit: z.number(),
|
|
211
|
+
offset: z.number(),
|
|
212
|
+
hasMore: z.boolean(),
|
|
213
|
+
}),
|
|
214
|
+
handler: async (ctx, args) => {
|
|
215
|
+
let allContacts;
|
|
216
|
+
|
|
217
|
+
// Get all contacts matching the filters
|
|
218
|
+
if (args.userGroup !== undefined) {
|
|
219
|
+
allContacts = await ctx.db
|
|
220
|
+
.query("contacts")
|
|
221
|
+
.withIndex("userGroup", (q) => q.eq("userGroup", args.userGroup))
|
|
222
|
+
.collect();
|
|
223
|
+
} else if (args.source !== undefined) {
|
|
224
|
+
allContacts = await ctx.db
|
|
225
|
+
.query("contacts")
|
|
226
|
+
.withIndex("source", (q) => q.eq("source", args.source))
|
|
227
|
+
.collect();
|
|
228
|
+
} else if (args.subscribed !== undefined) {
|
|
229
|
+
allContacts = await ctx.db
|
|
230
|
+
.query("contacts")
|
|
231
|
+
.withIndex("subscribed", (q) => q.eq("subscribed", args.subscribed))
|
|
232
|
+
.collect();
|
|
233
|
+
} else {
|
|
234
|
+
allContacts = await ctx.db.query("contacts").collect();
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Apply additional filters (for cases where we need to filter by multiple criteria)
|
|
238
|
+
if (args.userGroup !== undefined && allContacts) {
|
|
239
|
+
allContacts = allContacts.filter((c) => c.userGroup === args.userGroup);
|
|
240
|
+
}
|
|
241
|
+
if (args.source !== undefined && allContacts) {
|
|
242
|
+
allContacts = allContacts.filter((c) => c.source === args.source);
|
|
243
|
+
}
|
|
244
|
+
if (args.subscribed !== undefined && allContacts) {
|
|
245
|
+
allContacts = allContacts.filter((c) => c.subscribed === args.subscribed);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Sort by createdAt (newest first)
|
|
249
|
+
allContacts.sort((a, b) => b.createdAt - a.createdAt);
|
|
250
|
+
|
|
251
|
+
const total = allContacts.length;
|
|
252
|
+
const paginatedContacts = allContacts.slice(args.offset, args.offset + args.limit);
|
|
253
|
+
const hasMore = args.offset + args.limit < total;
|
|
254
|
+
|
|
255
|
+
return {
|
|
256
|
+
contacts: paginatedContacts,
|
|
257
|
+
total,
|
|
258
|
+
limit: args.limit,
|
|
259
|
+
offset: args.offset,
|
|
260
|
+
hasMore,
|
|
261
|
+
};
|
|
262
|
+
},
|
|
263
|
+
});
|
|
264
|
+
|
|
180
265
|
/**
|
|
181
266
|
* Add or update a contact in Loops
|
|
182
267
|
* This function tries to create a contact, and if the email already exists (409),
|