import { createSync } from 'nango';
import { z } from 'zod';
const DynamicFieldMetadata = z.object({
configurations: z.array(z.object({
model: z.string(),
fields: z.array(z.object({
id: z.string(),
name: z.string(),
type: z.string()
}))
}))
});
const OutputData = z.object({
id: z.string(),
model: z.string(),
data: z.record(z.any())
});
const sync = createSync({
description: 'Fetch all fields of a dynamic model',
version: '1.0.0',
frequency: 'every hour',
autoStart: false,
syncType: 'full',
endpoints: [
{
method: 'GET',
path: '/dynamic',
group: 'Dynamic Data'
}
],
models: {
OutputData: OutputData
},
metadata: DynamicFieldMetadata,
exec: async (nango) => {
const metadata = await nango.getMetadata<z.infer<typeof DynamicFieldMetadata>>();
// Process each model configuration
for (const config of metadata.configurations) {
const { model, fields } = config;
// Construct SOQL query with field selection
const fieldNames = fields.map(f => f.name).join(',');
const soqlQuery = `SELECT ${fieldNames} FROM ${model}`;
// Query Salesforce API using SOQL
const response = await nango.get({
endpoint: `/services/data/v59.0/query`,
params: {
q: soqlQuery
}
});
// Map response to OutputData format and save
const mappedData = response.data.records.map(record => ({
id: record.Id,
model: model,
data: fields.reduce((acc, field) => {
acc[field.name] = record[field.name];
return acc;
}, {} as Record<string, any>)
}));
// Save the batch of records
await nango.batchSave(mappedData, 'OutputData');
}
await nango.deleteRecordsFromPreviousExecutions('OutputData');
}
});