@expresscsv/sdk 0.1.17 → 0.1.19
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 +121 -1
- package/dist/index.d.cts +21 -5
- package/dist/index.d.mts +21 -5
- package/dist/index.d.ts +21 -5
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
A TypeScript SDK for embedding the [ExpressCSV](https://expresscsv.com) CSV import widget into any web application. Define a schema, open the widget, and receive validated, typed data in chunks.
|
|
7
7
|
|
|
8
|
+
If you want to define schemas in shared or backend code without any frontend dependencies, use [`@expresscsv/schemas`](https://www.npmjs.com/package/@expresscsv/schemas) for the schema definition itself, then pass that schema into `@expresscsv/sdk`.
|
|
9
|
+
|
|
8
10
|
## Installation
|
|
9
11
|
|
|
10
12
|
```bash
|
|
@@ -55,6 +57,8 @@ importer.open({
|
|
|
55
57
|
});
|
|
56
58
|
```
|
|
57
59
|
|
|
60
|
+
If your schema is assembled dynamically at runtime, still use `x.row(...)`. Just note that dynamic schema assembly can widen TypeScript inference, so use it intentionally when you need runtime-driven columns.
|
|
61
|
+
|
|
58
62
|
Your `publishableKey` is available from the [ExpressCSV dashboard](https://expresscsv.com). Two key types are available: **production** keys for live usage, and **dev/testing** keys that provide unlimited test imports.
|
|
59
63
|
|
|
60
64
|
## Webhook Delivery
|
|
@@ -112,6 +116,8 @@ interface WebhookPayload {
|
|
|
112
116
|
}
|
|
113
117
|
```
|
|
114
118
|
|
|
119
|
+
When you already have a schema, prefer `InferWebhookPayload<typeof schema>` from `@expresscsv/schemas` instead of rewriting this object shape by hand.
|
|
120
|
+
|
|
115
121
|
Example payload:
|
|
116
122
|
|
|
117
123
|
```json
|
|
@@ -150,6 +156,25 @@ Your endpoint should return a **2xx** status code to acknowledge each chunk. Non
|
|
|
150
156
|
|
|
151
157
|
Chunks are delivered **serially** — the next chunk is only sent after the previous one succeeds.
|
|
152
158
|
|
|
159
|
+
If your schema is defined in shared or backend code with `@expresscsv/schemas`, you can reuse the built-in webhook payload helper when handling deliveries:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
import express from "express";
|
|
163
|
+
import type { InferWebhookPayload } from "@expresscsv/schemas";
|
|
164
|
+
import { employeeSchema } from "../shared/employee-schema";
|
|
165
|
+
|
|
166
|
+
const app = express();
|
|
167
|
+
app.use(express.json());
|
|
168
|
+
|
|
169
|
+
app.post("/webhooks/csv-import", async (req, res) => {
|
|
170
|
+
const payload = req.body as InferWebhookPayload<typeof employeeSchema>;
|
|
171
|
+
|
|
172
|
+
await db.insertMany("users", payload.records);
|
|
173
|
+
|
|
174
|
+
res.status(200).json({ ok: true });
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
153
178
|
Below is a minimal Express.js example:
|
|
154
179
|
|
|
155
180
|
```typescript
|
|
@@ -241,6 +266,40 @@ const importer = new CSVImporter({
|
|
|
241
266
|
});
|
|
242
267
|
```
|
|
243
268
|
|
|
269
|
+
## Template Downloads
|
|
270
|
+
|
|
271
|
+
Generated templates can include example rows that match your schema.
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
import { CSVImporter, x, type Infer } from "@expresscsv/sdk";
|
|
275
|
+
|
|
276
|
+
const candidateSchema = x.row({
|
|
277
|
+
firstName: x.string().label("First Name"),
|
|
278
|
+
email: x.string().email().label("Email"),
|
|
279
|
+
role: x.select([
|
|
280
|
+
{ label: "Admin", value: "admin" },
|
|
281
|
+
{ label: "Editor", value: "editor" },
|
|
282
|
+
]).label("Role"),
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const importer = new CSVImporter({
|
|
286
|
+
schema: candidateSchema,
|
|
287
|
+
publishableKey: "your-publishable-key",
|
|
288
|
+
importIdentifier: "candidate-import",
|
|
289
|
+
templateDownload: {
|
|
290
|
+
source: "generate",
|
|
291
|
+
formats: ["csv", "xlsx"],
|
|
292
|
+
exampleRows: () => [
|
|
293
|
+
{
|
|
294
|
+
firstName: "Alice",
|
|
295
|
+
email: "alice@example.com",
|
|
296
|
+
role: "admin",
|
|
297
|
+
},
|
|
298
|
+
],
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
```
|
|
302
|
+
|
|
244
303
|
## Theming and Styling
|
|
245
304
|
|
|
246
305
|
Customize the widget's appearance with the `theme`, `colorMode`, `customCSS`, and `fonts` options.
|
|
@@ -375,6 +434,8 @@ const importer = new CSVImporter({
|
|
|
375
434
|
|
|
376
435
|
The `x` schema builder provides a type-safe, fluent API for defining your CSV structure.
|
|
377
436
|
|
|
437
|
+
For apps that share schema definitions with backend code or webhook handlers, prefer defining the schema in `@expresscsv/schemas` and importing it into your frontend. That keeps schema authoring free of widget/runtime dependencies.
|
|
438
|
+
|
|
378
439
|
### Field Types
|
|
379
440
|
|
|
380
441
|
```typescript
|
|
@@ -413,6 +474,65 @@ const schema = x.row({
|
|
|
413
474
|
});
|
|
414
475
|
```
|
|
415
476
|
|
|
477
|
+
### Runtime-Built Schemas
|
|
478
|
+
|
|
479
|
+
For a fixed schema, keep everything in a normal `x.row(...)` definition:
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
const schema = x.row({
|
|
483
|
+
email: x.string().email().label("Email"),
|
|
484
|
+
lifecycleStage: x
|
|
485
|
+
.select([
|
|
486
|
+
{ label: "Lead", value: "lead" },
|
|
487
|
+
{ label: "Customer", value: "customer" },
|
|
488
|
+
{ label: "Churned", value: "churned" },
|
|
489
|
+
])
|
|
490
|
+
.label("Lifecycle Stage"),
|
|
491
|
+
accountOwner: x.string().label("Account Owner").optional(),
|
|
492
|
+
contractValue: x.number().currency("USD").label("Contract Value").optional(),
|
|
493
|
+
});
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
`x.row(...)` also works for runtime-built schemas, which is useful when the shape depends on account data, user preferences, or enabled custom fields.
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
import { x } from "@expresscsv/sdk";
|
|
500
|
+
|
|
501
|
+
function buildCustomerSchema(options: {
|
|
502
|
+
collectCrmId: boolean;
|
|
503
|
+
collectHealthScore: boolean;
|
|
504
|
+
collectSegment: boolean;
|
|
505
|
+
}) {
|
|
506
|
+
return x.row({
|
|
507
|
+
email: x.string().email().label("Email"),
|
|
508
|
+
companyName: x.string().label("Company Name"),
|
|
509
|
+
...(options.collectCrmId ? { crmId: x.string().label("CRM ID") } : {}),
|
|
510
|
+
...(options.collectHealthScore
|
|
511
|
+
? { healthScore: x.number().label("Health Score") }
|
|
512
|
+
: {}),
|
|
513
|
+
...(options.collectSegment
|
|
514
|
+
? {
|
|
515
|
+
segment: x
|
|
516
|
+
.select([
|
|
517
|
+
{ label: "SMB", value: "smb" },
|
|
518
|
+
{ label: "Mid-Market", value: "mid-market" },
|
|
519
|
+
{ label: "Enterprise", value: "enterprise" },
|
|
520
|
+
])
|
|
521
|
+
.label("Segment"),
|
|
522
|
+
}
|
|
523
|
+
: {}),
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const schema = buildCustomerSchema({
|
|
528
|
+
collectCrmId: true,
|
|
529
|
+
collectHealthScore: true,
|
|
530
|
+
collectSegment: false,
|
|
531
|
+
});
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
Dynamic schema assembly preserves the same runtime parsing behavior, but it can widen `Infer<typeof schema>` because the exact keys are no longer fully known to TypeScript. Use it intentionally.
|
|
535
|
+
|
|
416
536
|
### Common Modifiers
|
|
417
537
|
|
|
418
538
|
All field types support:
|
|
@@ -571,7 +691,7 @@ new CSVImporter(options: SDKOptions)
|
|
|
571
691
|
| `fonts` | `Record<string, ECSVFontSource>` | No | - | Custom font sources |
|
|
572
692
|
| `stepDisplay` | `'progressBar' \| 'segmented' \| 'numbered'` | No | `'progressBar'` | Step indicator style |
|
|
573
693
|
| `previewSchemaBeforeUpload` | `boolean` | No | `true` | Show schema preview before upload |
|
|
574
|
-
| `templateDownload` | `
|
|
694
|
+
| `templateDownload` | `TemplateDownloadOptions<TSchema>` | No | - | Template download configuration with optional schema-typed example rows |
|
|
575
695
|
| `saveSession` | `boolean` | No | - | Persist session state |
|
|
576
696
|
| `locale` | `DeepPartial<ExpressCSVLocaleInput>` | No | - | Localization overrides |
|
|
577
697
|
|
package/dist/index.d.cts
CHANGED
|
@@ -1256,6 +1256,7 @@ export declare class CSVImporter<TSchema extends ExType<unknown, ExBaseDef, unkn
|
|
|
1256
1256
|
private cachedSchemaJson;
|
|
1257
1257
|
private initCompletePromise;
|
|
1258
1258
|
private resolveInitComplete;
|
|
1259
|
+
private resolvedTemplateDownload;
|
|
1259
1260
|
constructor(options: SDKOptions<TSchema>);
|
|
1260
1261
|
/**
|
|
1261
1262
|
* Enhanced state management
|
|
@@ -3126,6 +3127,11 @@ declare class ExRow<T extends ExRowShape> extends ExType<{
|
|
|
3126
3127
|
* Factory method to create an ExRow validator for a row of data
|
|
3127
3128
|
*
|
|
3128
3129
|
* @param shape - Object defining the structure of fields in the row
|
|
3130
|
+
*
|
|
3131
|
+
* Object literals preserve exact key inference. If callers build the shape
|
|
3132
|
+
* through a widened variable or conditional assembly, TypeScript may widen
|
|
3133
|
+
* the resulting row type as well.
|
|
3134
|
+
*
|
|
3129
3135
|
* @returns A new ExRow instance
|
|
3130
3136
|
*/
|
|
3131
3137
|
static create<T extends ExRowShape>(shape: T): ExRow<T>;
|
|
@@ -3770,7 +3776,7 @@ export declare interface SDKOptions<TSchema extends ExType<unknown, ExBaseDef, u
|
|
|
3770
3776
|
fonts?: Record<string, ECSVFontSource>;
|
|
3771
3777
|
stepDisplay?: 'progressBar' | 'segmented' | 'numbered';
|
|
3772
3778
|
previewSchemaBeforeUpload?: boolean;
|
|
3773
|
-
templateDownload?:
|
|
3779
|
+
templateDownload?: TemplateDownloadOptions<TSchema>;
|
|
3774
3780
|
saveSession?: boolean;
|
|
3775
3781
|
locale?: DeepPartial<ExpressCSVLocaleInput>;
|
|
3776
3782
|
disableStatusStep?: boolean;
|
|
@@ -3827,18 +3833,28 @@ export declare interface TailwindThemeVars {
|
|
|
3827
3833
|
|
|
3828
3834
|
/**
|
|
3829
3835
|
* Configuration for template download in the upload step.
|
|
3830
|
-
* When `source` is `"generate"`, a
|
|
3831
|
-
*
|
|
3836
|
+
* When `source` is `"generate"`, a template file is created client-side
|
|
3837
|
+
* from the schema column names and optional example rows.
|
|
3832
3838
|
*/
|
|
3833
|
-
declare interface TemplateDownloadConfig {
|
|
3839
|
+
export declare interface TemplateDownloadConfig {
|
|
3834
3840
|
source: 'generate';
|
|
3835
3841
|
formats?: TemplateDownloadFormat[];
|
|
3842
|
+
exampleRows?: TemplateDownloadExampleRow[];
|
|
3836
3843
|
}
|
|
3837
3844
|
|
|
3845
|
+
/**
|
|
3846
|
+
* A serializable example row used to populate generated templates.
|
|
3847
|
+
*/
|
|
3848
|
+
export declare type TemplateDownloadExampleRow = Record<string, unknown>;
|
|
3849
|
+
|
|
3838
3850
|
/**
|
|
3839
3851
|
* Template download format
|
|
3840
3852
|
*/
|
|
3841
|
-
declare type TemplateDownloadFormat = 'csv' | 'xlsx';
|
|
3853
|
+
export declare type TemplateDownloadFormat = 'csv' | 'xlsx';
|
|
3854
|
+
|
|
3855
|
+
export declare type TemplateDownloadOptions<TSchema extends ExType<unknown, ExBaseDef, unknown>> = Omit<TemplateDownloadConfig, 'exampleRows'> & {
|
|
3856
|
+
exampleRows?: Infer<TSchema>[] | (() => Infer<TSchema>[]);
|
|
3857
|
+
};
|
|
3842
3858
|
|
|
3843
3859
|
/**
|
|
3844
3860
|
* A branded string type for locale entries that require interpolation via `{variable}` syntax.
|
package/dist/index.d.mts
CHANGED
|
@@ -1256,6 +1256,7 @@ export declare class CSVImporter<TSchema extends ExType<unknown, ExBaseDef, unkn
|
|
|
1256
1256
|
private cachedSchemaJson;
|
|
1257
1257
|
private initCompletePromise;
|
|
1258
1258
|
private resolveInitComplete;
|
|
1259
|
+
private resolvedTemplateDownload;
|
|
1259
1260
|
constructor(options: SDKOptions<TSchema>);
|
|
1260
1261
|
/**
|
|
1261
1262
|
* Enhanced state management
|
|
@@ -3126,6 +3127,11 @@ declare class ExRow<T extends ExRowShape> extends ExType<{
|
|
|
3126
3127
|
* Factory method to create an ExRow validator for a row of data
|
|
3127
3128
|
*
|
|
3128
3129
|
* @param shape - Object defining the structure of fields in the row
|
|
3130
|
+
*
|
|
3131
|
+
* Object literals preserve exact key inference. If callers build the shape
|
|
3132
|
+
* through a widened variable or conditional assembly, TypeScript may widen
|
|
3133
|
+
* the resulting row type as well.
|
|
3134
|
+
*
|
|
3129
3135
|
* @returns A new ExRow instance
|
|
3130
3136
|
*/
|
|
3131
3137
|
static create<T extends ExRowShape>(shape: T): ExRow<T>;
|
|
@@ -3770,7 +3776,7 @@ export declare interface SDKOptions<TSchema extends ExType<unknown, ExBaseDef, u
|
|
|
3770
3776
|
fonts?: Record<string, ECSVFontSource>;
|
|
3771
3777
|
stepDisplay?: 'progressBar' | 'segmented' | 'numbered';
|
|
3772
3778
|
previewSchemaBeforeUpload?: boolean;
|
|
3773
|
-
templateDownload?:
|
|
3779
|
+
templateDownload?: TemplateDownloadOptions<TSchema>;
|
|
3774
3780
|
saveSession?: boolean;
|
|
3775
3781
|
locale?: DeepPartial<ExpressCSVLocaleInput>;
|
|
3776
3782
|
disableStatusStep?: boolean;
|
|
@@ -3827,18 +3833,28 @@ export declare interface TailwindThemeVars {
|
|
|
3827
3833
|
|
|
3828
3834
|
/**
|
|
3829
3835
|
* Configuration for template download in the upload step.
|
|
3830
|
-
* When `source` is `"generate"`, a
|
|
3831
|
-
*
|
|
3836
|
+
* When `source` is `"generate"`, a template file is created client-side
|
|
3837
|
+
* from the schema column names and optional example rows.
|
|
3832
3838
|
*/
|
|
3833
|
-
declare interface TemplateDownloadConfig {
|
|
3839
|
+
export declare interface TemplateDownloadConfig {
|
|
3834
3840
|
source: 'generate';
|
|
3835
3841
|
formats?: TemplateDownloadFormat[];
|
|
3842
|
+
exampleRows?: TemplateDownloadExampleRow[];
|
|
3836
3843
|
}
|
|
3837
3844
|
|
|
3845
|
+
/**
|
|
3846
|
+
* A serializable example row used to populate generated templates.
|
|
3847
|
+
*/
|
|
3848
|
+
export declare type TemplateDownloadExampleRow = Record<string, unknown>;
|
|
3849
|
+
|
|
3838
3850
|
/**
|
|
3839
3851
|
* Template download format
|
|
3840
3852
|
*/
|
|
3841
|
-
declare type TemplateDownloadFormat = 'csv' | 'xlsx';
|
|
3853
|
+
export declare type TemplateDownloadFormat = 'csv' | 'xlsx';
|
|
3854
|
+
|
|
3855
|
+
export declare type TemplateDownloadOptions<TSchema extends ExType<unknown, ExBaseDef, unknown>> = Omit<TemplateDownloadConfig, 'exampleRows'> & {
|
|
3856
|
+
exampleRows?: Infer<TSchema>[] | (() => Infer<TSchema>[]);
|
|
3857
|
+
};
|
|
3842
3858
|
|
|
3843
3859
|
/**
|
|
3844
3860
|
* A branded string type for locale entries that require interpolation via `{variable}` syntax.
|
package/dist/index.d.ts
CHANGED
|
@@ -1256,6 +1256,7 @@ export declare class CSVImporter<TSchema extends ExType<unknown, ExBaseDef, unkn
|
|
|
1256
1256
|
private cachedSchemaJson;
|
|
1257
1257
|
private initCompletePromise;
|
|
1258
1258
|
private resolveInitComplete;
|
|
1259
|
+
private resolvedTemplateDownload;
|
|
1259
1260
|
constructor(options: SDKOptions<TSchema>);
|
|
1260
1261
|
/**
|
|
1261
1262
|
* Enhanced state management
|
|
@@ -3126,6 +3127,11 @@ declare class ExRow<T extends ExRowShape> extends ExType<{
|
|
|
3126
3127
|
* Factory method to create an ExRow validator for a row of data
|
|
3127
3128
|
*
|
|
3128
3129
|
* @param shape - Object defining the structure of fields in the row
|
|
3130
|
+
*
|
|
3131
|
+
* Object literals preserve exact key inference. If callers build the shape
|
|
3132
|
+
* through a widened variable or conditional assembly, TypeScript may widen
|
|
3133
|
+
* the resulting row type as well.
|
|
3134
|
+
*
|
|
3129
3135
|
* @returns A new ExRow instance
|
|
3130
3136
|
*/
|
|
3131
3137
|
static create<T extends ExRowShape>(shape: T): ExRow<T>;
|
|
@@ -3770,7 +3776,7 @@ export declare interface SDKOptions<TSchema extends ExType<unknown, ExBaseDef, u
|
|
|
3770
3776
|
fonts?: Record<string, ECSVFontSource>;
|
|
3771
3777
|
stepDisplay?: 'progressBar' | 'segmented' | 'numbered';
|
|
3772
3778
|
previewSchemaBeforeUpload?: boolean;
|
|
3773
|
-
templateDownload?:
|
|
3779
|
+
templateDownload?: TemplateDownloadOptions<TSchema>;
|
|
3774
3780
|
saveSession?: boolean;
|
|
3775
3781
|
locale?: DeepPartial<ExpressCSVLocaleInput>;
|
|
3776
3782
|
disableStatusStep?: boolean;
|
|
@@ -3827,18 +3833,28 @@ export declare interface TailwindThemeVars {
|
|
|
3827
3833
|
|
|
3828
3834
|
/**
|
|
3829
3835
|
* Configuration for template download in the upload step.
|
|
3830
|
-
* When `source` is `"generate"`, a
|
|
3831
|
-
*
|
|
3836
|
+
* When `source` is `"generate"`, a template file is created client-side
|
|
3837
|
+
* from the schema column names and optional example rows.
|
|
3832
3838
|
*/
|
|
3833
|
-
declare interface TemplateDownloadConfig {
|
|
3839
|
+
export declare interface TemplateDownloadConfig {
|
|
3834
3840
|
source: 'generate';
|
|
3835
3841
|
formats?: TemplateDownloadFormat[];
|
|
3842
|
+
exampleRows?: TemplateDownloadExampleRow[];
|
|
3836
3843
|
}
|
|
3837
3844
|
|
|
3845
|
+
/**
|
|
3846
|
+
* A serializable example row used to populate generated templates.
|
|
3847
|
+
*/
|
|
3848
|
+
export declare type TemplateDownloadExampleRow = Record<string, unknown>;
|
|
3849
|
+
|
|
3838
3850
|
/**
|
|
3839
3851
|
* Template download format
|
|
3840
3852
|
*/
|
|
3841
|
-
declare type TemplateDownloadFormat = 'csv' | 'xlsx';
|
|
3853
|
+
export declare type TemplateDownloadFormat = 'csv' | 'xlsx';
|
|
3854
|
+
|
|
3855
|
+
export declare type TemplateDownloadOptions<TSchema extends ExType<unknown, ExBaseDef, unknown>> = Omit<TemplateDownloadConfig, 'exampleRows'> & {
|
|
3856
|
+
exampleRows?: Infer<TSchema>[] | (() => Infer<TSchema>[]);
|
|
3857
|
+
};
|
|
3842
3858
|
|
|
3843
3859
|
/**
|
|
3844
3860
|
* A branded string type for locale entries that require interpolation via `{variable}` syntax.
|