import { createSync } from 'nango';
import { z } from 'zod';
const WindowMetadata = z.object({
fromDate: z.string().optional(),
toDate: z.string().optional(),
useMetadata: z.boolean().optional()
});
const sync = createSync({
description: 'Window time based sync for large datasets',
version: '1.0.0',
frequency: 'every day',
autoStart: true,
syncType: 'incremental',
endpoints: [
{
method: 'GET',
path: '/data',
group: 'Data'
}
],
models: {
DataRecord: z.object({
id: z.string(),
created_at: z.string(),
data: z.any()
})
},
metadata: WindowMetadata,
exec: async (nango) => {
// 1. Load metadata and determine the overall date range
const metadata = await nango.getMetadata<z.infer<typeof WindowMetadata>>();
const lookBackPeriodInYears = 5;
const { startDate, endDate } = calculateDateRange(metadata, lookBackPeriodInYears);
let currentStartDate = new Date(startDate);
// 2. Iterate over each time window (e.g., month)
while (currentStartDate < endDate) {
let currentEndDate = new Date(currentStartDate);
currentEndDate.setMonth(currentEndDate.getMonth() + 1);
currentEndDate.setDate(1);
if (currentEndDate > endDate) {
currentEndDate = new Date(endDate);
}
// 3. Fetch and process data for the current window
const data = await fetchDataForWindow(currentStartDate, currentEndDate);
await processAndSaveData(data);
// 4. Update metadata to track progress
await nango.updateMetadata({
fromDate: currentEndDate.toISOString().split("T")[0],
toDate: endDate.toISOString().split("T")[0],
useMetadata: currentEndDate < endDate,
});
currentStartDate = new Date(currentEndDate.getTime());
if (currentStartDate >= endDate) {
await nango.updateMetadata({
fromDate: endDate.toISOString().split("T")[0],
toDate: endDate.toISOString().split("T")[0],
useMetadata: false,
});
break;
}
}
// 5. Optionally, handle incremental updates after the full windowed sync
if (!metadata.useMetadata) {
// ... (incremental sync logic)
}
}
});
async function fetchDataForWindow(start: Date, end: Date) {
// Implement provider-specific logic to fetch data for the window
return [];
}
async function processAndSaveData(data: any[]) {
// Implement logic to process and save data
}