@expresscsv/react 0.1.22 → 0.1.23
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/README.md +59 -217
- package/dist/index.d.cts +51 -52
- package/dist/index.d.mts +51 -52
- package/dist/index.d.ts +51 -52
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,17 +48,19 @@ function App() {
|
|
|
48
48
|
console.log(
|
|
49
49
|
`Chunk ${chunk.currentChunkIndex + 1}/${chunk.totalChunks}`
|
|
50
50
|
);
|
|
51
|
+
console.log("Session:", chunk.sessionId);
|
|
52
|
+
console.log("Idempotency key:", chunk.chunkIdempotencyKey);
|
|
51
53
|
console.log("Records:", chunk.records);
|
|
52
54
|
next();
|
|
53
55
|
},
|
|
54
|
-
onComplete: () => {
|
|
55
|
-
console.log("All chunks processed");
|
|
56
|
+
onComplete: ({ sessionId }) => {
|
|
57
|
+
console.log("All chunks processed for", sessionId);
|
|
56
58
|
},
|
|
57
|
-
onCancel: () => {
|
|
58
|
-
console.log("User cancelled");
|
|
59
|
+
onCancel: ({ sessionId }) => {
|
|
60
|
+
console.log("User cancelled", sessionId);
|
|
59
61
|
},
|
|
60
|
-
onError: (error) => {
|
|
61
|
-
console.error("Import error
|
|
62
|
+
onError: (error, { sessionId }) => {
|
|
63
|
+
console.error("Import error for", sessionId, error);
|
|
62
64
|
},
|
|
63
65
|
});
|
|
64
66
|
};
|
|
@@ -273,200 +275,50 @@ const { open } = useExpressCSV({
|
|
|
273
275
|
});
|
|
274
276
|
```
|
|
275
277
|
|
|
276
|
-
##
|
|
278
|
+
## Delivery
|
|
277
279
|
|
|
278
|
-
|
|
280
|
+
ExpressCSV delivers imported data through `onData`. Your app receives validated chunks in the browser and can forward them to your backend using whatever request shape fits your stack.
|
|
279
281
|
|
|
280
282
|
```tsx
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
function App() {
|
|
289
|
-
const { open } = useExpressCSV({
|
|
290
|
-
schema,
|
|
291
|
-
getSessionToken: async () => fetchSessionToken(),
|
|
292
|
-
importIdentifier: "user-import",
|
|
293
|
-
title: "Import Users",
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
const handleImport = () => {
|
|
297
|
-
open({
|
|
298
|
-
webhook: {
|
|
299
|
-
url: "https://api.example.com/webhooks/csv-import",
|
|
300
|
-
method: "POST",
|
|
301
|
-
headers: {
|
|
302
|
-
Authorization: "Bearer your-api-token",
|
|
303
|
-
},
|
|
304
|
-
metadata: {
|
|
305
|
-
source: "react-app",
|
|
306
|
-
userId: "user-123",
|
|
307
|
-
},
|
|
308
|
-
},
|
|
309
|
-
onComplete: () => {
|
|
310
|
-
console.log("Webhook delivery initiated");
|
|
311
|
-
},
|
|
312
|
-
onError: (error) => {
|
|
313
|
-
console.error("Delivery error:", error);
|
|
283
|
+
open({
|
|
284
|
+
chunkSize: 500,
|
|
285
|
+
onData: async (chunk, next) => {
|
|
286
|
+
const response = await fetch("/api/import-users/chunks", {
|
|
287
|
+
method: "POST",
|
|
288
|
+
headers: {
|
|
289
|
+
"Content-Type": "application/json",
|
|
314
290
|
},
|
|
291
|
+
body: JSON.stringify({
|
|
292
|
+
sessionId: chunk.sessionId,
|
|
293
|
+
chunkIdempotencyKey: chunk.chunkIdempotencyKey,
|
|
294
|
+
records: chunk.records,
|
|
295
|
+
currentChunkIndex: chunk.currentChunkIndex,
|
|
296
|
+
totalChunks: chunk.totalChunks,
|
|
297
|
+
totalRecords: chunk.totalRecords,
|
|
298
|
+
}),
|
|
315
299
|
});
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
return <button onClick={handleImport}>Import CSV via Webhook</button>;
|
|
319
|
-
}
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
### Webhook Payload Structure
|
|
323
300
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
interface WebhookPayload {
|
|
328
|
-
/** Imported records for this chunk, matching your schema */
|
|
329
|
-
records: Record<string, unknown>[];
|
|
330
|
-
/** 0-based index of the current chunk */
|
|
331
|
-
chunkIndex: number;
|
|
332
|
-
/** Total number of chunks in this delivery */
|
|
333
|
-
totalChunks: number;
|
|
334
|
-
/** Total number of records across all chunks */
|
|
335
|
-
totalRecords: number;
|
|
336
|
-
/** Present only if you passed `metadata` in `WebhookConfig` */
|
|
337
|
-
metadata?: Record<string, unknown>;
|
|
338
|
-
/** Delivery context added by ExpressCSV */
|
|
339
|
-
delivery: {
|
|
340
|
-
environmentName: string;
|
|
341
|
-
environmentType: string;
|
|
342
|
-
teamSlug: string;
|
|
343
|
-
importIdentifier: string;
|
|
344
|
-
deliveryId: string;
|
|
345
|
-
timestamp: string; // ISO 8601
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
When you already have a schema, prefer `InferWebhookPayload<typeof schema>` from `@expresscsv/schemas` instead of rewriting this object shape by hand.
|
|
351
|
-
|
|
352
|
-
Example payload:
|
|
353
|
-
|
|
354
|
-
```json
|
|
355
|
-
{
|
|
356
|
-
"records": [
|
|
357
|
-
{ "name": "Alice Johnson", "email": "alice@example.com" },
|
|
358
|
-
{ "name": "Bob Smith", "email": "bob@example.com" }
|
|
359
|
-
],
|
|
360
|
-
"chunkIndex": 0,
|
|
361
|
-
"totalChunks": 3,
|
|
362
|
-
"totalRecords": 2500,
|
|
363
|
-
"metadata": {
|
|
364
|
-
"source": "react-app",
|
|
365
|
-
"userId": "user-123"
|
|
366
|
-
},
|
|
367
|
-
"delivery": {
|
|
368
|
-
"environmentName": "Production",
|
|
369
|
-
"environmentType": "production",
|
|
370
|
-
"teamSlug": "my-team",
|
|
371
|
-
"importIdentifier": "user-import",
|
|
372
|
-
"deliveryId": "del_abc123",
|
|
373
|
-
"timestamp": "2026-03-02T14:30:00.000Z"
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
The request includes a `Content-Type: application/json` header plus any custom `headers` you specified in `WebhookConfig`.
|
|
379
|
-
|
|
380
|
-
### Handling Webhooks on Your Server
|
|
381
|
-
|
|
382
|
-
Your endpoint should return a **2xx** status code to acknowledge each chunk. Non-2xx responses trigger the following retry behaviour:
|
|
383
|
-
|
|
384
|
-
- **5xx** and **429** responses are retried automatically (up to 5 attempts per chunk).
|
|
385
|
-
- **4xx** responses (except 429) are treated as permanent failures and are **not** retried.
|
|
386
|
-
|
|
387
|
-
Chunks are delivered **serially** — the next chunk is only sent after the previous one succeeds.
|
|
388
|
-
|
|
389
|
-
If your schema lives in shared or backend code via `@expresscsv/schemas`, you can reuse the built-in webhook payload helper in your webhook handler:
|
|
390
|
-
|
|
391
|
-
```typescript
|
|
392
|
-
import express from "express";
|
|
393
|
-
import type { InferWebhookPayload } from "@expresscsv/schemas";
|
|
394
|
-
import { candidateSchema } from "../shared/candidate-schema";
|
|
395
|
-
|
|
396
|
-
const app = express();
|
|
397
|
-
app.use(express.json());
|
|
398
|
-
|
|
399
|
-
app.post("/webhooks/csv-import", async (req, res) => {
|
|
400
|
-
const payload = req.body as InferWebhookPayload<typeof candidateSchema>;
|
|
401
|
-
|
|
402
|
-
await importCandidates(payload.records);
|
|
403
|
-
|
|
404
|
-
res.status(200).json({ ok: true });
|
|
405
|
-
});
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
Below is a minimal Express.js example:
|
|
409
|
-
|
|
410
|
-
```typescript
|
|
411
|
-
import express from "express";
|
|
412
|
-
|
|
413
|
-
const app = express();
|
|
414
|
-
app.use(express.json());
|
|
415
|
-
|
|
416
|
-
app.post("/webhooks/csv-import", async (req, res) => {
|
|
417
|
-
const token = req.headers.authorization;
|
|
418
|
-
if (token !== "Bearer your-api-token") {
|
|
419
|
-
return res.status(401).json({ error: "Unauthorized" });
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const { records, chunkIndex, totalChunks, totalRecords, metadata, delivery } =
|
|
423
|
-
req.body;
|
|
424
|
-
|
|
425
|
-
try {
|
|
426
|
-
// Process the records — e.g. insert into your database
|
|
427
|
-
await db.insertMany("users", records);
|
|
428
|
-
|
|
429
|
-
console.log(
|
|
430
|
-
`Chunk ${chunkIndex + 1}/${totalChunks} processed ` +
|
|
431
|
-
`(${records.length} records, delivery ${delivery.deliveryId})`
|
|
432
|
-
);
|
|
433
|
-
|
|
434
|
-
res.status(200).json({ success: true });
|
|
435
|
-
} catch (error) {
|
|
436
|
-
// Return 500 so ExpressCSV retries this chunk
|
|
437
|
-
console.error("Failed to process chunk:", error);
|
|
438
|
-
res.status(500).json({ error: "Internal server error" });
|
|
439
|
-
}
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
app.listen(3000);
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
**Tips:**
|
|
446
|
-
|
|
447
|
-
- Use `delivery.deliveryId` and `chunkIndex` to **deduplicate** retried chunks (the same chunk may be delivered more than once on retry).
|
|
448
|
-
- Use `chunkIndex` and `totalChunks` to track progress and know when the full import is complete (`chunkIndex === totalChunks - 1` for the last chunk).
|
|
449
|
-
- Store `metadata` alongside imported records if you need to correlate the import with a specific user or action in your app.
|
|
450
|
-
|
|
451
|
-
### Combined Local Callback and Webhook
|
|
301
|
+
if (!response.ok) {
|
|
302
|
+
throw new Error("Backend rejected this import chunk");
|
|
303
|
+
}
|
|
452
304
|
|
|
453
|
-
```tsx
|
|
454
|
-
open({
|
|
455
|
-
chunkSize: 500,
|
|
456
|
-
onData: async (chunk, next) => {
|
|
457
|
-
await saveToLocalDatabase(chunk.records);
|
|
458
305
|
next();
|
|
459
306
|
},
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
headers: { Authorization: "Bearer your-api-token" },
|
|
463
|
-
},
|
|
464
|
-
onComplete: () => {
|
|
465
|
-
console.log("Local processing and webhook delivery complete");
|
|
307
|
+
onComplete: ({ sessionId }) => {
|
|
308
|
+
console.log("Import complete for", sessionId);
|
|
466
309
|
},
|
|
467
310
|
});
|
|
468
311
|
```
|
|
469
312
|
|
|
313
|
+
Each delivered chunk includes:
|
|
314
|
+
|
|
315
|
+
- `records`
|
|
316
|
+
- `sessionId`
|
|
317
|
+
- `chunkIdempotencyKey`
|
|
318
|
+
- `currentChunkIndex`
|
|
319
|
+
- `totalChunks`
|
|
320
|
+
- `totalRecords`
|
|
321
|
+
|
|
470
322
|
## Advanced Example
|
|
471
323
|
|
|
472
324
|
```tsx
|
|
@@ -508,13 +360,14 @@ function CandidateImporter() {
|
|
|
508
360
|
await importCandidates(chunk.records);
|
|
509
361
|
next();
|
|
510
362
|
},
|
|
511
|
-
onComplete: () => {
|
|
512
|
-
setStatus(
|
|
363
|
+
onComplete: ({ sessionId }) => {
|
|
364
|
+
setStatus(`Import complete: ${sessionId}`);
|
|
513
365
|
},
|
|
514
|
-
onError: (error) => {
|
|
515
|
-
setStatus(`Error: ${error.message}`);
|
|
366
|
+
onError: (error, { sessionId }) => {
|
|
367
|
+
setStatus(`Error in ${sessionId}: ${error.message}`);
|
|
516
368
|
},
|
|
517
|
-
onCancel: () => {
|
|
369
|
+
onCancel: ({ sessionId }) => {
|
|
370
|
+
console.log("Cancelled session", sessionId);
|
|
518
371
|
setStatus(null);
|
|
519
372
|
},
|
|
520
373
|
});
|
|
@@ -562,37 +415,37 @@ function useExpressCSV<TSchema>(
|
|
|
562
415
|
| `fonts` | `Record<string, ECSVFontSource>` | No | - | Custom font sources |
|
|
563
416
|
| `stepDisplay` | `'progressBar' \| 'segmented' \| 'numbered'` | No | `'progressBar'` | Step indicator style |
|
|
564
417
|
| `previewSchemaBeforeUpload` | `boolean` | No | `true` | Show schema preview before upload |
|
|
418
|
+
| `aiColumnMatching` | `boolean` | No | `true` | Enable AI-assisted column matching |
|
|
419
|
+
| `aiTransform` | `boolean` | No | `true` | Enable AI-assisted transform generation |
|
|
565
420
|
| `templateDownload` | `TemplateDownloadOptions<TSchema>` | No | - | Template download configuration with optional schema-typed example rows |
|
|
566
|
-
| `
|
|
421
|
+
| `storage` | `{ type: "local" } \| { type: "custom", ... }` | No | - | Enable Recovered Sessions with the built-in local backend or a custom adapter implementing `get`, `set`, and `remove` |
|
|
567
422
|
| `locale` | `DeepPartial<ExpressCSVLocaleInput>` | No | - | Localization overrides |
|
|
423
|
+
| `disableStatusStep` | `boolean` | No | - | Skip the success/error status screen |
|
|
568
424
|
|
|
569
425
|
#### Return Value
|
|
570
426
|
|
|
571
427
|
| Property | Type | Description |
|
|
572
428
|
|---|---|---|
|
|
573
|
-
| `open` | `(options: OpenOptions) => void` | Opens the importer. Requires
|
|
429
|
+
| `open` | `(options: OpenOptions) => void` | Opens the importer. Requires `onData` for delivery. |
|
|
574
430
|
| `importerState` | `ImporterState` | Current importer lifecycle state (reactive) |
|
|
575
431
|
| `isInitialising` | `boolean` | `true` while the importer is initializing or opening |
|
|
576
432
|
| `isOpen` | `boolean` | `true` while the importer is open |
|
|
577
433
|
|
|
578
434
|
### `OpenOptions<T>`
|
|
579
435
|
|
|
580
|
-
Options passed to `open()`.
|
|
436
|
+
Options passed to `open()`.
|
|
581
437
|
|
|
582
438
|
| Option | Type | Required | Description |
|
|
583
439
|
|---|---|---|---|
|
|
584
|
-
| `onData` | `(chunk: RecordsChunk<T>, next: () => void) => void` |
|
|
585
|
-
| `webhook` | `WebhookConfig` | * | Webhook endpoint for server-side delivery |
|
|
440
|
+
| `onData` | `(chunk: RecordsChunk<T>, next: () => void) => void` | Yes | Callback for each delivered chunk. Call `next()` to continue. |
|
|
586
441
|
| `chunkSize` | `number` | No | Records per chunk (default: 1000) |
|
|
587
|
-
| `onComplete` | `() => void` | No | Called when all chunks have been processed |
|
|
588
|
-
| `onCancel` | `() => void` | No | Called when the user cancels the import |
|
|
589
|
-
| `onError` | `(error: Error) => void` | No | Called when an error occurs |
|
|
442
|
+
| `onComplete` | `(context: { sessionId: string }) => void` | No | Called when all chunks have been processed |
|
|
443
|
+
| `onCancel` | `(context: { sessionId: string }) => void` | No | Called when the user cancels the import |
|
|
444
|
+
| `onError` | `(error: Error, context: { sessionId: string }) => void` | No | Called when an error occurs |
|
|
590
445
|
| `onImporterOpen` | `() => void` | No | Called when the importer opens |
|
|
591
|
-
| `onImporterClose` | `(reason:
|
|
446
|
+
| `onImporterClose` | `(reason: 'user_close' \| 'cancel' \| 'complete' \| 'error') => void` | No | Called when the importer closes |
|
|
592
447
|
| `onStepChange` | `(stepId, previousStepId?) => void` | No | Called when the wizard step changes |
|
|
593
448
|
|
|
594
|
-
\* At least one of `onData` or `webhook` is required.
|
|
595
|
-
|
|
596
449
|
### `RecordsChunk<T>`
|
|
597
450
|
|
|
598
451
|
```typescript
|
|
@@ -601,19 +454,8 @@ interface RecordsChunk<T> {
|
|
|
601
454
|
totalChunks: number;
|
|
602
455
|
currentChunkIndex: number;
|
|
603
456
|
totalRecords: number;
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
### `WebhookConfig`
|
|
608
|
-
|
|
609
|
-
```typescript
|
|
610
|
-
interface WebhookConfig {
|
|
611
|
-
url: string;
|
|
612
|
-
headers?: Record<string, string>;
|
|
613
|
-
method?: "POST" | "PUT" | "PATCH";
|
|
614
|
-
timeout?: number;
|
|
615
|
-
retries?: number;
|
|
616
|
-
metadata?: Record<string, unknown>;
|
|
457
|
+
sessionId: string;
|
|
458
|
+
chunkIdempotencyKey: string;
|
|
617
459
|
}
|
|
618
460
|
```
|
|
619
461
|
|
|
@@ -621,7 +463,7 @@ interface WebhookConfig {
|
|
|
621
463
|
|
|
622
464
|
The `x` schema builder provides a type-safe, fluent API for defining your CSV structure.
|
|
623
465
|
|
|
624
|
-
For apps that share schemas with backend code
|
|
466
|
+
For apps that share schemas with backend code, prefer defining the schema in `@expresscsv/schemas` and importing it into your React app. That keeps schema authoring free of React and importer dependencies.
|
|
625
467
|
|
|
626
468
|
#### Field Types
|
|
627
469
|
|
package/dist/index.d.cts
CHANGED
|
@@ -1878,6 +1878,13 @@ declare const CurrencyCodes: readonly [{
|
|
|
1878
1878
|
readonly numeric: "932";
|
|
1879
1879
|
}];
|
|
1880
1880
|
|
|
1881
|
+
export declare type CustomStorageOptions = {
|
|
1882
|
+
type: 'custom';
|
|
1883
|
+
get: (key: StorageKey) => Promise<StoredSession | null>;
|
|
1884
|
+
set: (key: StorageKey, value: StoredSession) => Promise<void>;
|
|
1885
|
+
remove: (key: StorageKey) => Promise<void>;
|
|
1886
|
+
};
|
|
1887
|
+
|
|
1881
1888
|
declare interface DatetimeOptions {
|
|
1882
1889
|
message?: string;
|
|
1883
1890
|
}
|
|
@@ -1886,19 +1893,9 @@ export declare type DeepPartial<T> = {
|
|
|
1886
1893
|
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
1887
1894
|
};
|
|
1888
1895
|
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
export declare type DeliveryOptions<T> = RequireAtLeastOne<DeliveryOptionsBase<T>, 'onData' | 'webhook'>;
|
|
1893
|
-
|
|
1894
|
-
/**
|
|
1895
|
-
* Base delivery options - at least one must be provided
|
|
1896
|
-
*/
|
|
1897
|
-
declare interface DeliveryOptionsBase<T> {
|
|
1898
|
-
/** Local callback for processing chunks */
|
|
1899
|
-
onData?: (chunk: RecordsChunk<T>, next: () => void) => void | Promise<void>;
|
|
1900
|
-
/** Webhook configuration for remote delivery */
|
|
1901
|
-
webhook?: WebhookConfig;
|
|
1896
|
+
export declare interface DeliveryOptions<T> {
|
|
1897
|
+
/** Callback for processing delivered chunks */
|
|
1898
|
+
onData: (chunk: RecordsChunk<T>, next: () => void) => void | Promise<void>;
|
|
1902
1899
|
}
|
|
1903
1900
|
|
|
1904
1901
|
/**
|
|
@@ -3498,10 +3495,19 @@ export declare enum ImporterState {
|
|
|
3498
3495
|
DESTROYED = "destroyed"
|
|
3499
3496
|
}
|
|
3500
3497
|
|
|
3498
|
+
export declare interface ImportSessionContext {
|
|
3499
|
+
/** Generated session ID for the current import run */
|
|
3500
|
+
sessionId: string;
|
|
3501
|
+
}
|
|
3502
|
+
|
|
3501
3503
|
export declare type Infer<T extends ExType<unknown, ExBaseDef, unknown>> = T extends ExType<infer Output, ExBaseDef, unknown> ? Output : never;
|
|
3502
3504
|
|
|
3503
3505
|
declare type IPAddressVersion = 'v4' | 'v6' | 'all';
|
|
3504
3506
|
|
|
3507
|
+
export declare type LocalStorageOptions = {
|
|
3508
|
+
type: 'local';
|
|
3509
|
+
};
|
|
3510
|
+
|
|
3505
3511
|
declare interface MultiselectOptions {
|
|
3506
3512
|
enforceCaseSensitiveMatch?: boolean;
|
|
3507
3513
|
message?: string;
|
|
@@ -3509,17 +3515,17 @@ declare interface MultiselectOptions {
|
|
|
3509
3515
|
|
|
3510
3516
|
/**
|
|
3511
3517
|
* Options for the open() method
|
|
3512
|
-
* Requires
|
|
3518
|
+
* Requires an onData callback for delivery
|
|
3513
3519
|
*/
|
|
3514
|
-
export declare type OpenOptions<T> =
|
|
3520
|
+
export declare type OpenOptions<T> = DeliveryOptions<T> & {
|
|
3515
3521
|
/** Number of records per chunk (default: 1000) */
|
|
3516
3522
|
chunkSize?: number;
|
|
3517
3523
|
/** Called when all chunks have been processed */
|
|
3518
|
-
onComplete?: () => void;
|
|
3524
|
+
onComplete?: (context: ImportSessionContext) => void;
|
|
3519
3525
|
/** Called when the user cancels the import */
|
|
3520
|
-
onCancel?: () => void;
|
|
3526
|
+
onCancel?: (context: ImportSessionContext) => void;
|
|
3521
3527
|
/** Called when an error occurs */
|
|
3522
|
-
onError?: (error: Error) => void;
|
|
3528
|
+
onError?: (error: Error, context: ImportSessionContext) => void;
|
|
3523
3529
|
/** Called when the importer opens */
|
|
3524
3530
|
onImporterOpen?: () => void;
|
|
3525
3531
|
/** Called when the importer closes */
|
|
@@ -3528,6 +3534,17 @@ export declare type OpenOptions<T> = RequireAtLeastOne<DeliveryOptionsBase<T>, '
|
|
|
3528
3534
|
onStepChange?: (stepId: ExpressCSVStep, previousStepId?: ExpressCSVStep) => void;
|
|
3529
3535
|
};
|
|
3530
3536
|
|
|
3537
|
+
declare interface PersistedImportSessionData {
|
|
3538
|
+
data: PersistedImportSessionPayload;
|
|
3539
|
+
}
|
|
3540
|
+
|
|
3541
|
+
declare type PersistedImportSessionKey = string;
|
|
3542
|
+
|
|
3543
|
+
declare type PersistedImportSessionPayload = {
|
|
3544
|
+
rowData: Record<string, unknown>[];
|
|
3545
|
+
columnKeys: string[];
|
|
3546
|
+
};
|
|
3547
|
+
|
|
3531
3548
|
declare type PhoneNumberFormat = 'international' | 'national' | 'both';
|
|
3532
3549
|
|
|
3533
3550
|
declare type PhoneNumberOutput = 'e164' | 'formatted' | 'digits';
|
|
@@ -3634,6 +3651,10 @@ export declare interface RecordsChunk<T> {
|
|
|
3634
3651
|
currentChunkIndex: number;
|
|
3635
3652
|
/** Total number of records across all chunks */
|
|
3636
3653
|
totalRecords: number;
|
|
3654
|
+
/** Generated session ID for the current import run */
|
|
3655
|
+
sessionId: string;
|
|
3656
|
+
/** Stable per-chunk idempotency key */
|
|
3657
|
+
chunkIdempotencyKey: string;
|
|
3637
3658
|
}
|
|
3638
3659
|
|
|
3639
3660
|
declare type RefineBatchResultItem = {
|
|
@@ -3665,13 +3686,6 @@ declare type RefineResultItem = {
|
|
|
3665
3686
|
};
|
|
3666
3687
|
};
|
|
3667
3688
|
|
|
3668
|
-
/**
|
|
3669
|
-
* Type helper that requires at least one of the specified keys to be present
|
|
3670
|
-
*/
|
|
3671
|
-
declare type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & {
|
|
3672
|
-
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
|
|
3673
|
-
}[Keys];
|
|
3674
|
-
|
|
3675
3689
|
declare interface SelectOption<TValue extends string | number = string | number> {
|
|
3676
3690
|
label: string;
|
|
3677
3691
|
value: TValue;
|
|
@@ -3684,6 +3698,14 @@ declare interface SelectOptions {
|
|
|
3684
3698
|
message?: string;
|
|
3685
3699
|
}
|
|
3686
3700
|
|
|
3701
|
+
export declare type StorageKey = PersistedImportSessionKey;
|
|
3702
|
+
|
|
3703
|
+
export declare type StorageOptions = LocalStorageOptions | CustomStorageOptions;
|
|
3704
|
+
|
|
3705
|
+
export declare type StoredSession = PersistedImportSessionData;
|
|
3706
|
+
|
|
3707
|
+
export declare type StoredSessionData = PersistedImportSessionPayload;
|
|
3708
|
+
|
|
3687
3709
|
declare type StripBrand<T> = {
|
|
3688
3710
|
[K in keyof T]: T[K] extends TemplateString<string> ? string : T[K] extends object ? StripBrand<T[K]> : T[K];
|
|
3689
3711
|
};
|
|
@@ -3772,7 +3794,7 @@ declare interface URLOptions {
|
|
|
3772
3794
|
message?: string;
|
|
3773
3795
|
}
|
|
3774
3796
|
|
|
3775
|
-
export declare function useExpressCSV<TSchema extends ExType<unknown, ExBaseDef, unknown>>({ schema, title, importIdentifier, getSessionToken, debug, preload, theme, colorMode, customCSS, fonts, stepDisplay, previewSchemaBeforeUpload, templateDownload,
|
|
3797
|
+
export declare function useExpressCSV<TSchema extends ExType<unknown, ExBaseDef, unknown>>({ schema, title, importIdentifier, getSessionToken, debug, preload, theme, colorMode, customCSS, fonts, stepDisplay, previewSchemaBeforeUpload, aiColumnMatching, aiTransform, templateDownload, storage, locale, disableStatusStep, }: UseExpressCSVOptions<TSchema>): {
|
|
3776
3798
|
open: (options: OpenOptions<Infer<TSchema>>) => void;
|
|
3777
3799
|
importerState: ImporterState;
|
|
3778
3800
|
isInitialising: boolean;
|
|
@@ -3792,8 +3814,10 @@ export declare interface UseExpressCSVOptions<TSchema extends ExType<unknown, Ex
|
|
|
3792
3814
|
fonts?: Record<string, ECSVFontSource>;
|
|
3793
3815
|
stepDisplay?: 'progressBar' | 'segmented' | 'numbered';
|
|
3794
3816
|
previewSchemaBeforeUpload?: boolean;
|
|
3817
|
+
aiColumnMatching?: boolean;
|
|
3818
|
+
aiTransform?: boolean;
|
|
3795
3819
|
templateDownload?: TemplateDownloadOptions<TSchema>;
|
|
3796
|
-
|
|
3820
|
+
storage?: StorageOptions;
|
|
3797
3821
|
locale?: DeepPartial<ExpressCSVLocaleInput>;
|
|
3798
3822
|
disableStatusStep?: boolean;
|
|
3799
3823
|
}
|
|
@@ -3806,31 +3830,6 @@ declare interface ValidatorCheck {
|
|
|
3806
3830
|
message?: string;
|
|
3807
3831
|
}
|
|
3808
3832
|
|
|
3809
|
-
/**
|
|
3810
|
-
* Webhook configuration for remote delivery of results
|
|
3811
|
-
*/
|
|
3812
|
-
export declare interface WebhookConfig {
|
|
3813
|
-
/** The URL to send webhook requests to */
|
|
3814
|
-
url: string;
|
|
3815
|
-
/** Optional HTTP headers to include in the request */
|
|
3816
|
-
headers?: Record<string, string>;
|
|
3817
|
-
/** HTTP method to use (default: 'POST') */
|
|
3818
|
-
method?: 'POST' | 'PUT' | 'PATCH';
|
|
3819
|
-
/** Request timeout in milliseconds (default: 30000) */
|
|
3820
|
-
timeout?: number;
|
|
3821
|
-
/** Number of retry attempts on failure (default: 0) */
|
|
3822
|
-
retries?: number;
|
|
3823
|
-
/** Arbitrary developer-provided metadata */
|
|
3824
|
-
metadata?: Record<string, unknown>;
|
|
3825
|
-
/**
|
|
3826
|
-
* Whether to wait for the delivery service to confirm the webhook was
|
|
3827
|
-
* successfully received before considering the import complete.
|
|
3828
|
-
* When false, the import completes as soon as all chunks are queued.
|
|
3829
|
-
* Default: false
|
|
3830
|
-
*/
|
|
3831
|
-
awaitWebhookArrival?: boolean;
|
|
3832
|
-
}
|
|
3833
|
-
|
|
3834
3833
|
export declare const x: {
|
|
3835
3834
|
string: typeof ExString.create;
|
|
3836
3835
|
number: typeof ExNumber.create;
|