@expresscsv/sdk 0.1.17 → 0.1.18
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 +84 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- 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, use `x.dynamicRow(...)` instead of `x.row(...)`. It keeps the same runtime parsing behavior while intentionally widening TypeScript inference for runtime-built shapes.
|
|
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
|
|
@@ -375,6 +400,8 @@ const importer = new CSVImporter({
|
|
|
375
400
|
|
|
376
401
|
The `x` schema builder provides a type-safe, fluent API for defining your CSV structure.
|
|
377
402
|
|
|
403
|
+
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.
|
|
404
|
+
|
|
378
405
|
### Field Types
|
|
379
406
|
|
|
380
407
|
```typescript
|
|
@@ -413,6 +440,63 @@ const schema = x.row({
|
|
|
413
440
|
});
|
|
414
441
|
```
|
|
415
442
|
|
|
443
|
+
### Runtime-Built Schemas
|
|
444
|
+
|
|
445
|
+
For a fixed schema, keep everything in a normal `x.row(...)` definition:
|
|
446
|
+
|
|
447
|
+
```typescript
|
|
448
|
+
const schema = x.row({
|
|
449
|
+
email: x.string().email().label("Email"),
|
|
450
|
+
lifecycleStage: x
|
|
451
|
+
.select([
|
|
452
|
+
{ label: "Lead", value: "lead" },
|
|
453
|
+
{ label: "Customer", value: "customer" },
|
|
454
|
+
{ label: "Churned", value: "churned" },
|
|
455
|
+
])
|
|
456
|
+
.label("Lifecycle Stage"),
|
|
457
|
+
accountOwner: x.string().label("Account Owner").optional(),
|
|
458
|
+
contractValue: x.number().currency("USD").label("Contract Value").optional(),
|
|
459
|
+
});
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
`x.dynamicRow(...)` lets you build the row at runtime, which is useful when the schema depends on account data, user preferences, or enabled custom fields.
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
import { x } from "@expresscsv/sdk";
|
|
466
|
+
|
|
467
|
+
function buildCustomerSchema(options: {
|
|
468
|
+
collectCrmId: boolean;
|
|
469
|
+
collectHealthScore: boolean;
|
|
470
|
+
collectSegment: boolean;
|
|
471
|
+
}) {
|
|
472
|
+
return x.dynamicRow({
|
|
473
|
+
email: x.string().email().label("Email"),
|
|
474
|
+
companyName: x.string().label("Company Name"),
|
|
475
|
+
...(options.collectCrmId ? { crmId: x.string().label("CRM ID") } : {}),
|
|
476
|
+
...(options.collectHealthScore
|
|
477
|
+
? { healthScore: x.number().label("Health Score") }
|
|
478
|
+
: {}),
|
|
479
|
+
...(options.collectSegment
|
|
480
|
+
? {
|
|
481
|
+
segment: x
|
|
482
|
+
.select([
|
|
483
|
+
{ label: "SMB", value: "smb" },
|
|
484
|
+
{ label: "Mid-Market", value: "mid-market" },
|
|
485
|
+
{ label: "Enterprise", value: "enterprise" },
|
|
486
|
+
])
|
|
487
|
+
.label("Segment"),
|
|
488
|
+
}
|
|
489
|
+
: {}),
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
const schema = buildCustomerSchema({
|
|
494
|
+
collectCrmId: true,
|
|
495
|
+
collectHealthScore: true,
|
|
496
|
+
collectSegment: false,
|
|
497
|
+
});
|
|
498
|
+
```
|
|
499
|
+
|
|
416
500
|
### Common Modifiers
|
|
417
501
|
|
|
418
502
|
All field types support:
|
package/dist/index.d.cts
CHANGED
|
@@ -3129,6 +3129,13 @@ declare class ExRow<T extends ExRowShape> extends ExType<{
|
|
|
3129
3129
|
* @returns A new ExRow instance
|
|
3130
3130
|
*/
|
|
3131
3131
|
static create<T extends ExRowShape>(shape: T): ExRow<T>;
|
|
3132
|
+
/**
|
|
3133
|
+
* Factory method for runtime-built row shapes.
|
|
3134
|
+
*
|
|
3135
|
+
* This intentionally widens the returned type to ExRow<ExRowShape> so callers
|
|
3136
|
+
* can assemble fields conditionally without relying on exact key inference.
|
|
3137
|
+
*/
|
|
3138
|
+
static createDynamic(shape: ExRowShape): ExRow<ExRowShape>;
|
|
3132
3139
|
/**
|
|
3133
3140
|
* Specifies columns that can be null/optional with conditional logic
|
|
3134
3141
|
*
|
|
@@ -3930,6 +3937,7 @@ export declare const x: {
|
|
|
3930
3937
|
time: typeof ExTime.create;
|
|
3931
3938
|
datetime: typeof ExDatetime.create;
|
|
3932
3939
|
row: typeof ExRow.create;
|
|
3940
|
+
dynamicRow: typeof ExRow.createDynamic;
|
|
3933
3941
|
select: typeof ExSelect.create;
|
|
3934
3942
|
multiselect: typeof ExMultiselect.create;
|
|
3935
3943
|
infer: <T extends ExType<unknown, ExBaseDef, unknown>>(_schema: T) => Infer<T>;
|
package/dist/index.d.mts
CHANGED
|
@@ -3129,6 +3129,13 @@ declare class ExRow<T extends ExRowShape> extends ExType<{
|
|
|
3129
3129
|
* @returns A new ExRow instance
|
|
3130
3130
|
*/
|
|
3131
3131
|
static create<T extends ExRowShape>(shape: T): ExRow<T>;
|
|
3132
|
+
/**
|
|
3133
|
+
* Factory method for runtime-built row shapes.
|
|
3134
|
+
*
|
|
3135
|
+
* This intentionally widens the returned type to ExRow<ExRowShape> so callers
|
|
3136
|
+
* can assemble fields conditionally without relying on exact key inference.
|
|
3137
|
+
*/
|
|
3138
|
+
static createDynamic(shape: ExRowShape): ExRow<ExRowShape>;
|
|
3132
3139
|
/**
|
|
3133
3140
|
* Specifies columns that can be null/optional with conditional logic
|
|
3134
3141
|
*
|
|
@@ -3930,6 +3937,7 @@ export declare const x: {
|
|
|
3930
3937
|
time: typeof ExTime.create;
|
|
3931
3938
|
datetime: typeof ExDatetime.create;
|
|
3932
3939
|
row: typeof ExRow.create;
|
|
3940
|
+
dynamicRow: typeof ExRow.createDynamic;
|
|
3933
3941
|
select: typeof ExSelect.create;
|
|
3934
3942
|
multiselect: typeof ExMultiselect.create;
|
|
3935
3943
|
infer: <T extends ExType<unknown, ExBaseDef, unknown>>(_schema: T) => Infer<T>;
|
package/dist/index.d.ts
CHANGED
|
@@ -3129,6 +3129,13 @@ declare class ExRow<T extends ExRowShape> extends ExType<{
|
|
|
3129
3129
|
* @returns A new ExRow instance
|
|
3130
3130
|
*/
|
|
3131
3131
|
static create<T extends ExRowShape>(shape: T): ExRow<T>;
|
|
3132
|
+
/**
|
|
3133
|
+
* Factory method for runtime-built row shapes.
|
|
3134
|
+
*
|
|
3135
|
+
* This intentionally widens the returned type to ExRow<ExRowShape> so callers
|
|
3136
|
+
* can assemble fields conditionally without relying on exact key inference.
|
|
3137
|
+
*/
|
|
3138
|
+
static createDynamic(shape: ExRowShape): ExRow<ExRowShape>;
|
|
3132
3139
|
/**
|
|
3133
3140
|
* Specifies columns that can be null/optional with conditional logic
|
|
3134
3141
|
*
|
|
@@ -3930,6 +3937,7 @@ export declare const x: {
|
|
|
3930
3937
|
time: typeof ExTime.create;
|
|
3931
3938
|
datetime: typeof ExDatetime.create;
|
|
3932
3939
|
row: typeof ExRow.create;
|
|
3940
|
+
dynamicRow: typeof ExRow.createDynamic;
|
|
3933
3941
|
select: typeof ExSelect.create;
|
|
3934
3942
|
multiselect: typeof ExMultiselect.create;
|
|
3935
3943
|
infer: <T extends ExType<unknown, ExBaseDef, unknown>>(_schema: T) => Infer<T>;
|