@tallyui/connector-vendure 1.0.0
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/dist/index.d.ts +69 -0
- package/dist/index.js +423 -0
- package/package.json +32 -0
- package/src/__tests__/product-traits.test.ts +248 -0
- package/src/index.ts +73 -0
- package/src/replication/products.test.ts +204 -0
- package/src/replication/products.ts +148 -0
- package/src/schemas/products.ts +110 -0
- package/src/sync/products.ts +154 -0
- package/src/traits/product.ts +91 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ProductTraits, CollectionSync, ReplicationAdapter, TallyConnector } from '@tallyui/core';
|
|
2
|
+
import { RxJsonSchema } from 'rxdb';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* RxDB schema for Vendure products.
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the Vendure GraphQL Admin API product shape. Key differences:
|
|
8
|
+
* - Uses `name` (like WooCommerce, unlike Medusa's `title`)
|
|
9
|
+
* - Prices are integers in cents on `variants[].priceWithTax`
|
|
10
|
+
* - Images use `assets[].preview` and `featuredAsset.preview`
|
|
11
|
+
* - Categories are `collections[].name`
|
|
12
|
+
* - Stock level is a string (`IN_STOCK`, `OUT_OF_STOCK`, `LOW_STOCK`)
|
|
13
|
+
* - No native barcode field (custom fields only)
|
|
14
|
+
*/
|
|
15
|
+
declare const vendureProductSchema: RxJsonSchema<any>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Vendure product trait implementations.
|
|
19
|
+
*
|
|
20
|
+
* Key differences from other connectors:
|
|
21
|
+
* - Product name is `name` (same as WooCommerce, unlike Medusa's `title`)
|
|
22
|
+
* - Price is on `variants[].priceWithTax` (integer cents, like Medusa)
|
|
23
|
+
* - Images use `featuredAsset.preview` and `assets[].preview`
|
|
24
|
+
* - Stock status is a string from the Shop API: 'IN_STOCK', 'OUT_OF_STOCK', 'LOW_STOCK'
|
|
25
|
+
* - Categories are `collections[].name` (Vendure's equivalent of categories)
|
|
26
|
+
* - No native sale price — Vendure handles sales via promotions at checkout
|
|
27
|
+
* - No native barcode field — uses custom fields if configured
|
|
28
|
+
*/
|
|
29
|
+
declare const vendureProductTraits: ProductTraits;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Vendure product sync implementation.
|
|
33
|
+
*
|
|
34
|
+
* Uses the Admin GraphQL API. Vendure uses offset-based pagination
|
|
35
|
+
* with `take` and `skip` options.
|
|
36
|
+
*/
|
|
37
|
+
declare const vendureProductSync: CollectionSync;
|
|
38
|
+
|
|
39
|
+
type VendureProductCheckpoint = {
|
|
40
|
+
skip: number;
|
|
41
|
+
updatedAt: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Replication adapter for Vendure products.
|
|
45
|
+
*
|
|
46
|
+
* Implements pull (GraphQL query with offset pagination and updatedAt
|
|
47
|
+
* filtering) and push (GraphQL updateProduct mutation). Designed for
|
|
48
|
+
* use with RxDB's replicateRxCollection.
|
|
49
|
+
*/
|
|
50
|
+
declare const vendureProductReplication: ReplicationAdapter<any, VendureProductCheckpoint>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Vendure connector for Tally UI.
|
|
54
|
+
*
|
|
55
|
+
* Connects to Vendure backends via the Admin GraphQL API.
|
|
56
|
+
* Products are stored in RxDB using a schema that mirrors the Vendure API shape.
|
|
57
|
+
*
|
|
58
|
+
* ```ts
|
|
59
|
+
* import { vendureConnector } from '@tallyui/connector-vendure';
|
|
60
|
+
* import { ConnectorProvider } from '@tallyui/core';
|
|
61
|
+
*
|
|
62
|
+
* <ConnectorProvider connector={vendureConnector}>
|
|
63
|
+
* <App />
|
|
64
|
+
* </ConnectorProvider>
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
declare const vendureConnector: TallyConnector;
|
|
68
|
+
|
|
69
|
+
export { vendureConnector, vendureProductReplication, vendureProductSchema, vendureProductSync, vendureProductTraits };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
// src/schemas/products.ts
|
|
2
|
+
var vendureProductSchema = {
|
|
3
|
+
version: 0,
|
|
4
|
+
primaryKey: "id",
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
id: { type: "string", maxLength: 100 },
|
|
8
|
+
name: { type: "string" },
|
|
9
|
+
slug: { type: "string", maxLength: 255 },
|
|
10
|
+
description: { type: "string" },
|
|
11
|
+
enabled: { type: "boolean" },
|
|
12
|
+
featuredAsset: {
|
|
13
|
+
type: ["object", "null"],
|
|
14
|
+
properties: {
|
|
15
|
+
id: { type: "string" },
|
|
16
|
+
preview: { type: "string" }
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
assets: {
|
|
20
|
+
type: "array",
|
|
21
|
+
items: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
id: { type: "string" },
|
|
25
|
+
preview: { type: "string" }
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
collections: {
|
|
30
|
+
type: "array",
|
|
31
|
+
items: {
|
|
32
|
+
type: "object",
|
|
33
|
+
properties: {
|
|
34
|
+
id: { type: "string" },
|
|
35
|
+
name: { type: "string" },
|
|
36
|
+
slug: { type: "string" }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
facetValues: {
|
|
41
|
+
type: "array",
|
|
42
|
+
items: {
|
|
43
|
+
type: "object",
|
|
44
|
+
properties: {
|
|
45
|
+
id: { type: "string" },
|
|
46
|
+
name: { type: "string" },
|
|
47
|
+
code: { type: "string" },
|
|
48
|
+
facet: {
|
|
49
|
+
type: "object",
|
|
50
|
+
properties: {
|
|
51
|
+
id: { type: "string" },
|
|
52
|
+
name: { type: "string" }
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
variants: {
|
|
59
|
+
type: "array",
|
|
60
|
+
items: {
|
|
61
|
+
type: "object",
|
|
62
|
+
properties: {
|
|
63
|
+
id: { type: "string" },
|
|
64
|
+
name: { type: "string" },
|
|
65
|
+
sku: { type: "string" },
|
|
66
|
+
price: { type: "number" },
|
|
67
|
+
priceWithTax: { type: "number" },
|
|
68
|
+
currencyCode: { type: "string" },
|
|
69
|
+
stockLevel: { type: "string" },
|
|
70
|
+
stockOnHand: { type: "number" },
|
|
71
|
+
trackInventory: { type: "string" },
|
|
72
|
+
featuredAsset: {
|
|
73
|
+
type: ["object", "null"],
|
|
74
|
+
properties: {
|
|
75
|
+
id: { type: "string" },
|
|
76
|
+
preview: { type: "string" }
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
options: {
|
|
80
|
+
type: "array",
|
|
81
|
+
items: {
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
id: { type: "string" },
|
|
85
|
+
name: { type: "string" },
|
|
86
|
+
code: { type: "string" }
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
customFields: { type: "object" }
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
updatedAt: { type: "string", maxLength: 50 }
|
|
95
|
+
},
|
|
96
|
+
required: ["id"],
|
|
97
|
+
indexes: ["slug", "updatedAt"]
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// src/traits/product.ts
|
|
101
|
+
var vendureProductTraits = {
|
|
102
|
+
getId: (doc) => String(doc.id),
|
|
103
|
+
getName: (doc) => doc.name ?? "",
|
|
104
|
+
getSku: (doc) => doc.variants?.[0]?.sku || void 0,
|
|
105
|
+
getPrice: (doc) => {
|
|
106
|
+
const amount = doc.variants?.[0]?.priceWithTax;
|
|
107
|
+
if (amount == null) return void 0;
|
|
108
|
+
return (amount / 100).toFixed(2);
|
|
109
|
+
},
|
|
110
|
+
getRegularPrice: (doc) => {
|
|
111
|
+
const amount = doc.variants?.[0]?.priceWithTax;
|
|
112
|
+
if (amount == null) return void 0;
|
|
113
|
+
return (amount / 100).toFixed(2);
|
|
114
|
+
},
|
|
115
|
+
getSalePrice: () => {
|
|
116
|
+
return void 0;
|
|
117
|
+
},
|
|
118
|
+
isOnSale: () => {
|
|
119
|
+
return false;
|
|
120
|
+
},
|
|
121
|
+
getImageUrl: (doc) => doc.featuredAsset?.preview || doc.assets?.[0]?.preview || void 0,
|
|
122
|
+
getImageUrls: (doc) => (doc.assets ?? []).map((a) => a.preview).filter(Boolean),
|
|
123
|
+
getDescription: (doc) => doc.description || void 0,
|
|
124
|
+
getStockStatus: (doc) => {
|
|
125
|
+
const variant = doc.variants?.[0];
|
|
126
|
+
if (!variant) return "unknown";
|
|
127
|
+
const level = variant.stockLevel;
|
|
128
|
+
if (level === "IN_STOCK" || level === "LOW_STOCK") return "instock";
|
|
129
|
+
if (level === "OUT_OF_STOCK") return "outofstock";
|
|
130
|
+
if (variant.stockOnHand != null) {
|
|
131
|
+
return variant.stockOnHand > 0 ? "instock" : "outofstock";
|
|
132
|
+
}
|
|
133
|
+
return "unknown";
|
|
134
|
+
},
|
|
135
|
+
getStockQuantity: (doc) => {
|
|
136
|
+
return doc.variants?.[0]?.stockOnHand ?? null;
|
|
137
|
+
},
|
|
138
|
+
hasVariants: (doc) => (doc.variants?.length ?? 0) > 1,
|
|
139
|
+
getType: (doc) => {
|
|
140
|
+
if ((doc.variants?.length ?? 0) > 1) return "variable";
|
|
141
|
+
return "simple";
|
|
142
|
+
},
|
|
143
|
+
getBarcode: (doc) => {
|
|
144
|
+
return doc.variants?.[0]?.customFields?.barcode || void 0;
|
|
145
|
+
},
|
|
146
|
+
getCategoryNames: (doc) => (doc.collections ?? []).map((c) => c.name).filter(Boolean)
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// src/sync/products.ts
|
|
150
|
+
var PRODUCT_LIST_QUERY = `
|
|
151
|
+
query GetProducts($options: ProductListOptions) {
|
|
152
|
+
products(options: $options) {
|
|
153
|
+
items {
|
|
154
|
+
id
|
|
155
|
+
updatedAt
|
|
156
|
+
}
|
|
157
|
+
totalItems
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
`;
|
|
161
|
+
var PRODUCT_DETAIL_QUERY = `
|
|
162
|
+
query GetProduct($id: ID!) {
|
|
163
|
+
product(id: $id) {
|
|
164
|
+
id
|
|
165
|
+
createdAt
|
|
166
|
+
updatedAt
|
|
167
|
+
name
|
|
168
|
+
slug
|
|
169
|
+
description
|
|
170
|
+
enabled
|
|
171
|
+
featuredAsset { id preview }
|
|
172
|
+
assets { id preview }
|
|
173
|
+
collections { id name slug }
|
|
174
|
+
facetValues { id name code facet { id name } }
|
|
175
|
+
variants {
|
|
176
|
+
id
|
|
177
|
+
name
|
|
178
|
+
sku
|
|
179
|
+
price
|
|
180
|
+
priceWithTax
|
|
181
|
+
currencyCode
|
|
182
|
+
stockLevel
|
|
183
|
+
stockOnHand
|
|
184
|
+
trackInventory
|
|
185
|
+
featuredAsset { id preview }
|
|
186
|
+
options { id name code }
|
|
187
|
+
customFields
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
`;
|
|
192
|
+
var vendureProductSync = {
|
|
193
|
+
fetchAllIds: async (context) => {
|
|
194
|
+
const entries = [];
|
|
195
|
+
const take = 100;
|
|
196
|
+
let skip = 0;
|
|
197
|
+
let totalItems = Infinity;
|
|
198
|
+
while (skip < totalItems) {
|
|
199
|
+
const res = await gql(context, PRODUCT_LIST_QUERY, {
|
|
200
|
+
options: { take, skip }
|
|
201
|
+
});
|
|
202
|
+
const data = res.data?.products;
|
|
203
|
+
if (!data) break;
|
|
204
|
+
totalItems = data.totalItems;
|
|
205
|
+
for (const item of data.items ?? []) {
|
|
206
|
+
entries.push({
|
|
207
|
+
id: String(item.id),
|
|
208
|
+
dateModified: item.updatedAt
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
skip += take;
|
|
212
|
+
}
|
|
213
|
+
return entries;
|
|
214
|
+
},
|
|
215
|
+
fetchByIds: async (ids, context) => {
|
|
216
|
+
const products = [];
|
|
217
|
+
for (const id of ids) {
|
|
218
|
+
const res = await gql(context, PRODUCT_DETAIL_QUERY, { id });
|
|
219
|
+
if (res.data?.product) {
|
|
220
|
+
products.push(res.data.product);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return products;
|
|
224
|
+
},
|
|
225
|
+
fetchModifiedAfter: async (date, context) => {
|
|
226
|
+
const products = [];
|
|
227
|
+
const take = 100;
|
|
228
|
+
let skip = 0;
|
|
229
|
+
let totalItems = Infinity;
|
|
230
|
+
while (skip < totalItems) {
|
|
231
|
+
const res = await gql(context, PRODUCT_LIST_QUERY, {
|
|
232
|
+
options: {
|
|
233
|
+
take,
|
|
234
|
+
skip,
|
|
235
|
+
filter: {
|
|
236
|
+
updatedAt: { after: date }
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
const data = res.data?.products;
|
|
241
|
+
if (!data) break;
|
|
242
|
+
totalItems = data.totalItems;
|
|
243
|
+
for (const item of data.items ?? []) {
|
|
244
|
+
const detail = await gql(context, PRODUCT_DETAIL_QUERY, { id: item.id });
|
|
245
|
+
if (detail.data?.product) {
|
|
246
|
+
products.push(detail.data.product);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
skip += take;
|
|
250
|
+
}
|
|
251
|
+
return products;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
async function gql(context, query, variables) {
|
|
255
|
+
const res = await fetch(`${context.baseUrl}/admin-api`, {
|
|
256
|
+
method: "POST",
|
|
257
|
+
headers: {
|
|
258
|
+
"Content-Type": "application/json",
|
|
259
|
+
...context.headers
|
|
260
|
+
},
|
|
261
|
+
body: JSON.stringify({ query, variables }),
|
|
262
|
+
signal: context.signal
|
|
263
|
+
});
|
|
264
|
+
if (!res.ok) throw new Error(`Vendure API error: ${res.status}`);
|
|
265
|
+
return res.json();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// src/replication/products.ts
|
|
269
|
+
var PRODUCT_LIST_QUERY2 = `
|
|
270
|
+
query GetProducts($options: ProductListOptions) {
|
|
271
|
+
products(options: $options) {
|
|
272
|
+
items {
|
|
273
|
+
id
|
|
274
|
+
createdAt
|
|
275
|
+
updatedAt
|
|
276
|
+
name
|
|
277
|
+
slug
|
|
278
|
+
description
|
|
279
|
+
enabled
|
|
280
|
+
featuredAsset { id preview }
|
|
281
|
+
assets { id preview }
|
|
282
|
+
collections { id name slug }
|
|
283
|
+
facetValues { id name code facet { id name } }
|
|
284
|
+
variants {
|
|
285
|
+
id
|
|
286
|
+
name
|
|
287
|
+
sku
|
|
288
|
+
price
|
|
289
|
+
priceWithTax
|
|
290
|
+
currencyCode
|
|
291
|
+
stockLevel
|
|
292
|
+
stockOnHand
|
|
293
|
+
trackInventory
|
|
294
|
+
featuredAsset { id preview }
|
|
295
|
+
options { id name code }
|
|
296
|
+
customFields
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
totalItems
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
`;
|
|
303
|
+
var UPDATE_PRODUCT_MUTATION = `
|
|
304
|
+
mutation UpdateProduct($input: UpdateProductInput!) {
|
|
305
|
+
updateProduct(input: $input) {
|
|
306
|
+
id
|
|
307
|
+
updatedAt
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
`;
|
|
311
|
+
async function gql2(context, query, variables) {
|
|
312
|
+
const res = await fetch(`${context.baseUrl}/admin-api`, {
|
|
313
|
+
method: "POST",
|
|
314
|
+
headers: {
|
|
315
|
+
"Content-Type": "application/json",
|
|
316
|
+
...context.headers
|
|
317
|
+
},
|
|
318
|
+
body: JSON.stringify({ query, variables }),
|
|
319
|
+
signal: context.signal
|
|
320
|
+
});
|
|
321
|
+
if (!res.ok) throw new Error(`Vendure API error: ${res.status}`);
|
|
322
|
+
return res.json();
|
|
323
|
+
}
|
|
324
|
+
var vendureProductReplication = {
|
|
325
|
+
pull: {
|
|
326
|
+
async handler(lastCheckpoint, batchSize, context) {
|
|
327
|
+
const options = {
|
|
328
|
+
take: batchSize,
|
|
329
|
+
skip: lastCheckpoint?.skip ?? 0
|
|
330
|
+
};
|
|
331
|
+
if (lastCheckpoint?.updatedAt) {
|
|
332
|
+
options.filter = {
|
|
333
|
+
updatedAt: { after: lastCheckpoint.updatedAt }
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
const res = await gql2(context, PRODUCT_LIST_QUERY2, { options });
|
|
337
|
+
if (res.errors?.length) {
|
|
338
|
+
throw new Error(`Vendure GraphQL error: ${res.errors[0].message}`);
|
|
339
|
+
}
|
|
340
|
+
const data = res.data?.products;
|
|
341
|
+
const products = data?.items ?? [];
|
|
342
|
+
const documents = products.map((p) => ({ ...p, _deleted: false }));
|
|
343
|
+
const nextSkip = products.length < batchSize ? 0 : (lastCheckpoint?.skip ?? 0) + products.length;
|
|
344
|
+
const checkpoint = products.length > 0 ? {
|
|
345
|
+
skip: nextSkip,
|
|
346
|
+
updatedAt: products[products.length - 1].updatedAt
|
|
347
|
+
} : lastCheckpoint ?? { skip: 0, updatedAt: "" };
|
|
348
|
+
return { documents, checkpoint };
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
push: {
|
|
352
|
+
async handler(changeRows, context) {
|
|
353
|
+
const conflicts = [];
|
|
354
|
+
for (const row of changeRows) {
|
|
355
|
+
const doc = row.newDocumentState;
|
|
356
|
+
try {
|
|
357
|
+
const res = await gql2(context, UPDATE_PRODUCT_MUTATION, {
|
|
358
|
+
input: doc
|
|
359
|
+
});
|
|
360
|
+
if (res.errors?.length) {
|
|
361
|
+
if (row.assumedMasterState) {
|
|
362
|
+
conflicts.push({ ...row.assumedMasterState, _deleted: false });
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
} catch {
|
|
366
|
+
if (row.assumedMasterState) {
|
|
367
|
+
conflicts.push({ ...row.assumedMasterState, _deleted: false });
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return conflicts;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
// src/index.ts
|
|
377
|
+
var vendureConnector = {
|
|
378
|
+
id: "vendure",
|
|
379
|
+
name: "Vendure",
|
|
380
|
+
description: "Connect to Vendure backends via the Admin GraphQL API",
|
|
381
|
+
icon: void 0,
|
|
382
|
+
auth: {
|
|
383
|
+
type: "Vendure Admin API",
|
|
384
|
+
fields: [
|
|
385
|
+
{
|
|
386
|
+
key: "url",
|
|
387
|
+
label: "Backend URL",
|
|
388
|
+
type: "url",
|
|
389
|
+
placeholder: "https://my-vendure-server.com",
|
|
390
|
+
required: true
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
key: "auth_token",
|
|
394
|
+
label: "Auth Token",
|
|
395
|
+
type: "password",
|
|
396
|
+
placeholder: "vendure-auth-token from login",
|
|
397
|
+
required: true
|
|
398
|
+
}
|
|
399
|
+
],
|
|
400
|
+
getHeaders: (credentials) => ({
|
|
401
|
+
Authorization: `Bearer ${credentials.auth_token}`
|
|
402
|
+
})
|
|
403
|
+
},
|
|
404
|
+
schemas: {
|
|
405
|
+
products: vendureProductSchema
|
|
406
|
+
},
|
|
407
|
+
traits: {
|
|
408
|
+
product: vendureProductTraits
|
|
409
|
+
},
|
|
410
|
+
sync: {
|
|
411
|
+
products: vendureProductSync
|
|
412
|
+
},
|
|
413
|
+
replication: {
|
|
414
|
+
products: vendureProductReplication
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
export {
|
|
418
|
+
vendureConnector,
|
|
419
|
+
vendureProductReplication,
|
|
420
|
+
vendureProductSchema,
|
|
421
|
+
vendureProductSync,
|
|
422
|
+
vendureProductTraits
|
|
423
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tallyui/connector-vendure",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Vendure connector for Tally UI",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"source": "./src/index.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"source": "./src/index.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src"
|
|
19
|
+
],
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"@tallyui/core": "0.2.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"rxdb": "16.21.1"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"test": "echo \"no tests yet\""
|
|
31
|
+
}
|
|
32
|
+
}
|