@useairfoil/producer-shopify 0.2.0 → 0.2.1

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.
Files changed (60) hide show
  1. package/README.md +85 -248
  2. package/dist/index.d.mts +6993 -0
  3. package/dist/index.mjs +3 -0
  4. package/dist/main.d.mts +1 -0
  5. package/dist/main.mjs +698 -0
  6. package/dist/main.mjs.map +1 -0
  7. package/dist/manifest.d.mts +32 -0
  8. package/dist/manifest.mjs +51 -0
  9. package/dist/manifest.mjs.map +1 -0
  10. package/dist/{chunk-Bp6m_JJh.js → rolldown-runtime-D7D4PA-g.mjs} +4 -4
  11. package/dist/src-Bgvuhcfk.mjs +2473 -0
  12. package/dist/src-Bgvuhcfk.mjs.map +1 -0
  13. package/package.json +19 -19
  14. package/src/{auth.ts → api/auth.ts} +15 -35
  15. package/src/api/client.ts +429 -0
  16. package/src/api/graphql.ts +221 -0
  17. package/src/api/http.ts +25 -0
  18. package/src/connector.ts +266 -163
  19. package/src/create-table.ts +5 -0
  20. package/src/demo/customers.ts +412 -0
  21. package/src/demo/index.ts +31 -0
  22. package/src/demo/setup.ts +63 -0
  23. package/src/demo/shared.ts +114 -0
  24. package/src/index.ts +35 -21
  25. package/src/main.ts +8 -8
  26. package/src/manifest.ts +4 -55
  27. package/src/resources/carts/row.ts +58 -0
  28. package/src/resources/carts/webhook.ts +98 -0
  29. package/src/resources/customers/graphql.ts +175 -0
  30. package/src/resources/customers/row.ts +112 -0
  31. package/src/resources/customers/webhook.ts +30 -0
  32. package/src/resources/orders/graphql.ts +419 -0
  33. package/src/resources/orders/row.ts +180 -0
  34. package/src/resources/orders/webhook.ts +248 -0
  35. package/src/resources/products/graphql.ts +142 -0
  36. package/src/resources/products/row.ts +92 -0
  37. package/src/resources/products/webhook.ts +130 -0
  38. package/src/resources/refunds/graphql.ts +196 -0
  39. package/src/resources/refunds/row.ts +97 -0
  40. package/src/resources/refunds/webhook.ts +123 -0
  41. package/src/resources/shared.ts +293 -0
  42. package/src/sandbox.ts +3 -3
  43. package/src/start.ts +3 -5
  44. package/src/tables.ts +15 -0
  45. package/dist/index.d.ts +0 -965
  46. package/dist/index.js +0 -4
  47. package/dist/main.d.ts +0 -1
  48. package/dist/main.js +0 -49
  49. package/dist/main.js.map +0 -1
  50. package/dist/manifest-BFfx2LkS.js +0 -91
  51. package/dist/manifest-BFfx2LkS.js.map +0 -1
  52. package/dist/manifest-CPOEExQU.d.ts +0 -34
  53. package/dist/manifest.d.ts +0 -2
  54. package/dist/manifest.js +0 -3
  55. package/dist/src-DqmiLrYS.js +0 -984
  56. package/dist/src-DqmiLrYS.js.map +0 -1
  57. package/src/api.ts +0 -636
  58. package/src/schemas.ts +0 -319
  59. package/src/throttle.ts +0 -89
  60. package/src/transient-retry.ts +0 -74
@@ -0,0 +1,2473 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
+ import { ShopifyConfigDef, manifest } from "./manifest.mjs";
3
+ import * as Schema$1 from "effect/Schema";
4
+ import { Auth, Connector, ConnectorError, Cursor, Fetch, Iceberg, Metrics, Resource, Telemetry, Webhook } from "@useairfoil/connector-kit";
5
+ import { Config, Context, Data, Duration, Effect, Layer, Option, Predicate, Redacted, Schedule, Schema, SchemaTransformation, Stream } from "effect";
6
+ import { HttpClient, HttpClientRequest, HttpClientResponse, HttpServerResponse } from "effect/http";
7
+ import { createHmac, timingSafeEqual } from "node:crypto";
8
+ //#region src/resources/shared.ts
9
+ const field = (fieldId, description) => Iceberg.field(fieldId, { description });
10
+ const PageInfoSchema = Schema$1.Struct({
11
+ hasNextPage: Schema$1.Boolean,
12
+ endCursor: Schema$1.NullOr(Schema$1.String)
13
+ });
14
+ const gid = (type, id) => `gid://shopify/${type}/${id}`;
15
+ const normalizeAmount = (amount) => amount.includes(".") ? amount.replace(/0+$/, "").replace(/\.$/, "") : amount;
16
+ const emptyText = (value) => value ?? "";
17
+ const splitTags = (value) => value.split(",").map((tag) => tag.trim()).filter((tag) => tag.length > 0);
18
+ const moneyBag = (baseId) => Schema$1.Struct({
19
+ shopMoney: Schema$1.Struct({
20
+ amount: Schema$1.String.pipe(field(baseId + 3, "Amount in the shop currency.")),
21
+ currencyCode: Schema$1.String.pipe(field(baseId + 4, "Shop currency code."))
22
+ }).pipe(field(baseId + 1, "Amount in the shop currency.")),
23
+ presentmentMoney: Schema$1.Struct({
24
+ amount: Schema$1.String.pipe(field(baseId + 5, "Amount in the customer currency.")),
25
+ currencyCode: Schema$1.String.pipe(field(baseId + 6, "Customer currency code."))
26
+ }).pipe(field(baseId + 2, "Amount in the customer currency."))
27
+ });
28
+ const address = (baseId) => Schema$1.Struct({
29
+ firstName: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 1, "First name.")),
30
+ lastName: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 2, "Last name.")),
31
+ name: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 3, "Full name.")),
32
+ company: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 4, "Company name.")),
33
+ address1: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 5, "First address line.")),
34
+ address2: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 6, "Second address line.")),
35
+ city: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 7, "City.")),
36
+ province: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 8, "Province or state.")),
37
+ provinceCode: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 9, "Province or state code.")),
38
+ country: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 10, "Country.")),
39
+ countryCode: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 11, "Two-letter country code.")),
40
+ zip: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 12, "Postal code.")),
41
+ phone: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 13, "Phone number.")),
42
+ latitude: Schema$1.NullOr(Schema$1.Finite).pipe(field(baseId + 14, "Latitude.")),
43
+ longitude: Schema$1.NullOr(Schema$1.Finite).pipe(field(baseId + 15, "Longitude."))
44
+ });
45
+ const attributes = (baseId) => Schema$1.Array(Schema$1.Struct({
46
+ key: Schema$1.String.pipe(field(baseId + 2, "Attribute name.")),
47
+ value: Schema$1.NullOr(Schema$1.String).pipe(field(baseId + 3, "Attribute value."))
48
+ }).annotate({ fieldId: baseId + 1 }));
49
+ const taxLines = (baseId) => Schema$1.Array(Schema$1.Struct({
50
+ title: Schema$1.String.pipe(field(baseId + 2, "Tax name.")),
51
+ rate: Schema$1.NullOr(Schema$1.Finite).pipe(field(baseId + 3, "Tax rate as a fraction.")),
52
+ priceSet: moneyBag(baseId + 10).pipe(field(baseId + 4, "Tax amount."))
53
+ }).annotate({ fieldId: baseId + 1 }));
54
+ const discountAllocations = (baseId) => Schema$1.Array(Schema$1.Struct({
55
+ discountApplicationIndex: Schema$1.Int.pipe(field(baseId + 2, "Index of the order discount application.")),
56
+ amountSet: moneyBag(baseId + 10).pipe(field(baseId + 3, "Allocated discount amount."))
57
+ }).annotate({ fieldId: baseId + 1 }));
58
+ const RestMoneyBagSchema = Schema$1.Struct({
59
+ shop_money: Schema$1.Struct({
60
+ amount: Schema$1.String,
61
+ currency_code: Schema$1.String
62
+ }),
63
+ presentment_money: Schema$1.Struct({
64
+ amount: Schema$1.String,
65
+ currency_code: Schema$1.String
66
+ })
67
+ });
68
+ const nullableText = Schema$1.NullOr(Schema$1.String);
69
+ const RestAddressSchema = Schema$1.Struct({
70
+ first_name: nullableText,
71
+ last_name: nullableText,
72
+ name: nullableText,
73
+ company: nullableText,
74
+ address1: nullableText,
75
+ address2: nullableText,
76
+ city: nullableText,
77
+ province: nullableText,
78
+ province_code: nullableText,
79
+ country: nullableText,
80
+ country_code: nullableText,
81
+ zip: nullableText,
82
+ phone: nullableText,
83
+ latitude: Schema$1.NullOr(Schema$1.Number),
84
+ longitude: Schema$1.NullOr(Schema$1.Number)
85
+ });
86
+ const RestAttributeSchema = Schema$1.Struct({
87
+ name: Schema$1.String,
88
+ value: Schema$1.NullOr(Schema$1.String)
89
+ });
90
+ const RestTaxLineSchema = Schema$1.Struct({
91
+ title: Schema$1.String,
92
+ rate: Schema$1.NullOr(Schema$1.Number),
93
+ price_set: RestMoneyBagSchema
94
+ });
95
+ const RestDiscountAllocationSchema = Schema$1.Struct({
96
+ discount_application_index: Schema$1.Int,
97
+ amount_set: RestMoneyBagSchema
98
+ });
99
+ const fromRest = {
100
+ money: (bag) => ({
101
+ shopMoney: {
102
+ amount: normalizeAmount(bag.shop_money.amount),
103
+ currencyCode: bag.shop_money.currency_code
104
+ },
105
+ presentmentMoney: {
106
+ amount: normalizeAmount(bag.presentment_money.amount),
107
+ currencyCode: bag.presentment_money.currency_code
108
+ }
109
+ }),
110
+ address: (value) => ({
111
+ firstName: value.first_name,
112
+ lastName: value.last_name,
113
+ name: value.name,
114
+ company: value.company,
115
+ address1: value.address1,
116
+ address2: value.address2,
117
+ city: value.city,
118
+ province: value.province,
119
+ provinceCode: value.province_code,
120
+ country: value.country,
121
+ countryCode: value.country_code,
122
+ zip: value.zip,
123
+ phone: value.phone,
124
+ latitude: value.latitude,
125
+ longitude: value.longitude
126
+ }),
127
+ attribute: (value) => ({
128
+ key: value.name,
129
+ value: value.value
130
+ }),
131
+ taxLine: (value) => ({
132
+ title: value.title,
133
+ rate: value.rate,
134
+ priceSet: fromRest.money(value.price_set)
135
+ }),
136
+ discountAllocation: (value) => ({
137
+ discountApplicationIndex: value.discount_application_index,
138
+ amountSet: fromRest.money(value.amount_set)
139
+ })
140
+ };
141
+ const MoneyBagFields = `shopMoney { amount currencyCode } presentmentMoney { amount currencyCode }`;
142
+ const AddressFields = `firstName lastName name company address1 address2 city province provinceCode country countryCodeV2 zip phone latitude longitude`;
143
+ const TaxLineFields = `title rate priceSet { ${MoneyBagFields} }`;
144
+ const DiscountAllocationFields = `allocatedAmountSet { ${MoneyBagFields} } discountApplication { index }`;
145
+ const GraphQLMoneyBagSchema = Schema$1.Struct({
146
+ shopMoney: Schema$1.Struct({
147
+ amount: Schema$1.String,
148
+ currencyCode: Schema$1.String
149
+ }),
150
+ presentmentMoney: Schema$1.Struct({
151
+ amount: Schema$1.String,
152
+ currencyCode: Schema$1.String
153
+ })
154
+ });
155
+ const GraphQLAddressSchema = Schema$1.Struct({
156
+ firstName: Schema$1.NullOr(Schema$1.String),
157
+ lastName: Schema$1.NullOr(Schema$1.String),
158
+ name: Schema$1.NullOr(Schema$1.String),
159
+ company: Schema$1.NullOr(Schema$1.String),
160
+ address1: Schema$1.NullOr(Schema$1.String),
161
+ address2: Schema$1.NullOr(Schema$1.String),
162
+ city: Schema$1.NullOr(Schema$1.String),
163
+ province: Schema$1.NullOr(Schema$1.String),
164
+ provinceCode: Schema$1.NullOr(Schema$1.String),
165
+ country: Schema$1.NullOr(Schema$1.String),
166
+ countryCodeV2: Schema$1.NullOr(Schema$1.String),
167
+ zip: Schema$1.NullOr(Schema$1.String),
168
+ phone: Schema$1.NullOr(Schema$1.String),
169
+ latitude: Schema$1.NullOr(Schema$1.Number),
170
+ longitude: Schema$1.NullOr(Schema$1.Number)
171
+ });
172
+ const GraphQLAttributeSchema = Schema$1.Struct({
173
+ key: Schema$1.String,
174
+ value: Schema$1.NullOr(Schema$1.String)
175
+ });
176
+ const GraphQLTaxLineSchema = Schema$1.Struct({
177
+ title: Schema$1.String,
178
+ rate: Schema$1.NullOr(Schema$1.Number),
179
+ priceSet: GraphQLMoneyBagSchema
180
+ });
181
+ const GraphQLDiscountAllocationSchema = Schema$1.Struct({
182
+ allocatedAmountSet: GraphQLMoneyBagSchema,
183
+ discountApplication: Schema$1.Struct({ index: Schema$1.Int })
184
+ });
185
+ const connection = (node) => Schema$1.Struct({
186
+ nodes: Schema$1.Array(node),
187
+ pageInfo: PageInfoSchema
188
+ });
189
+ const fromGraphQL = {
190
+ money: (bag) => ({
191
+ shopMoney: {
192
+ amount: normalizeAmount(bag.shopMoney.amount),
193
+ currencyCode: bag.shopMoney.currencyCode
194
+ },
195
+ presentmentMoney: {
196
+ amount: normalizeAmount(bag.presentmentMoney.amount),
197
+ currencyCode: bag.presentmentMoney.currencyCode
198
+ }
199
+ }),
200
+ address: ({ countryCodeV2, ...value }) => ({
201
+ ...value,
202
+ countryCode: countryCodeV2
203
+ }),
204
+ taxLine: (value) => ({
205
+ title: value.title,
206
+ rate: value.rate,
207
+ priceSet: fromGraphQL.money(value.priceSet)
208
+ }),
209
+ discountAllocation: (value) => ({
210
+ discountApplicationIndex: value.discountApplication.index,
211
+ amountSet: fromGraphQL.money(value.allocatedAmountSet)
212
+ })
213
+ };
214
+ const upper = (literals) => Schema$1.String.pipe(Schema$1.decode(SchemaTransformation.toUpperCase()), Schema$1.decodeTo(literals));
215
+ const PageInfoFields = `pageInfo { hasNextPage endCursor }`;
216
+ const idRef = Schema$1.NullOr(Schema$1.Struct({ id: Schema$1.String }));
217
+ const pageQuery = (name, connection, fields) => `#graphql
218
+ query ${name}($first: Int!, $after: String) {
219
+ ${connection}(first: $first, after: $after) {
220
+ nodes {
221
+ ${fields}
222
+ }
223
+ pageInfo {
224
+ hasNextPage
225
+ endCursor
226
+ }
227
+ }
228
+ }
229
+ `;
230
+ //#endregion
231
+ //#region src/resources/carts/webhook.ts
232
+ const JsonStringSchema = Schema$1.flip(Schema$1.fromJsonString(Schema$1.Unknown));
233
+ const CartWebhookLineItemSchema = Schema$1.Struct({
234
+ id: Schema$1.Number,
235
+ properties: Schema$1.Union([Schema$1.Null, JsonStringSchema]),
236
+ quantity: Schema$1.Int,
237
+ variant_id: Schema$1.Number,
238
+ key: Schema$1.String,
239
+ discounted_price: Schema$1.String,
240
+ discounts: JsonStringSchema,
241
+ gift_card: Schema$1.Boolean,
242
+ grams: Schema$1.Int,
243
+ line_price: Schema$1.String,
244
+ original_line_price: Schema$1.String,
245
+ original_price: Schema$1.String,
246
+ price: Schema$1.String,
247
+ product_id: Schema$1.Number,
248
+ sku: Schema$1.NullOr(Schema$1.String),
249
+ taxable: Schema$1.Boolean,
250
+ title: Schema$1.String,
251
+ total_discount: Schema$1.String,
252
+ vendor: Schema$1.String,
253
+ discounted_price_set: RestMoneyBagSchema,
254
+ line_price_set: RestMoneyBagSchema,
255
+ original_line_price_set: RestMoneyBagSchema,
256
+ price_set: RestMoneyBagSchema,
257
+ total_discount_set: RestMoneyBagSchema,
258
+ parent_relationship: Schema$1.Union([Schema$1.Null, JsonStringSchema])
259
+ });
260
+ const CartWebhookPayloadSchema = Schema$1.Struct({
261
+ id: Schema$1.String,
262
+ token: Schema$1.String,
263
+ line_items: Schema$1.Array(CartWebhookLineItemSchema),
264
+ note: Schema$1.NullOr(Schema$1.String),
265
+ updated_at: Schema$1.DateFromString,
266
+ created_at: Schema$1.DateFromString
267
+ });
268
+ const CartWebhookEventSchema = Schema$1.Struct({
269
+ id: Schema$1.String,
270
+ token: Schema$1.String,
271
+ line_items: Schema$1.Array(Schema$1.toType(CartWebhookLineItemSchema)),
272
+ note: Schema$1.NullOr(Schema$1.String),
273
+ updated_at: Schema$1.Date,
274
+ created_at: Schema$1.Date,
275
+ topic: Schema$1.Literals(["carts/create", "carts/update"])
276
+ });
277
+ const normalizeCartLineItem = (item) => ({
278
+ id: String(item.id),
279
+ properties: item.properties,
280
+ quantity: item.quantity,
281
+ variantId: gid("ProductVariant", item.variant_id),
282
+ key: item.key,
283
+ discountedPrice: normalizeAmount(item.discounted_price),
284
+ discounts: item.discounts,
285
+ giftCard: item.gift_card,
286
+ grams: item.grams,
287
+ linePrice: normalizeAmount(item.line_price),
288
+ originalLinePrice: normalizeAmount(item.original_line_price),
289
+ originalPrice: normalizeAmount(item.original_price),
290
+ price: normalizeAmount(item.price),
291
+ productId: gid("Product", item.product_id),
292
+ sku: item.sku,
293
+ taxable: item.taxable,
294
+ title: item.title,
295
+ totalDiscount: normalizeAmount(item.total_discount),
296
+ vendor: item.vendor,
297
+ discountedPriceSet: fromRest.money(item.discounted_price_set),
298
+ linePriceSet: fromRest.money(item.line_price_set),
299
+ originalLinePriceSet: fromRest.money(item.original_line_price_set),
300
+ priceSet: fromRest.money(item.price_set),
301
+ totalDiscountSet: fromRest.money(item.total_discount_set),
302
+ parentRelationship: item.parent_relationship
303
+ });
304
+ const fromCartWebhook = (payload) => ({
305
+ id: payload.id,
306
+ token: payload.token,
307
+ topic: payload.topic,
308
+ lineItems: payload.line_items.map(normalizeCartLineItem),
309
+ note: payload.note ?? "",
310
+ updatedAt: payload.updated_at,
311
+ createdAt: payload.created_at
312
+ });
313
+ //#endregion
314
+ //#region src/resources/products/row.ts
315
+ const ProductStatusSchema = Schema$1.Literals([
316
+ "ACTIVE",
317
+ "ARCHIVED",
318
+ "DRAFT",
319
+ "UNLISTED"
320
+ ]);
321
+ const ProductVariantInventoryPolicySchema = Schema$1.Literals(["CONTINUE", "DENY"]);
322
+ const ProductImageSchema = Schema$1.Struct({
323
+ url: Schema$1.String.pipe(field(202, "URL of the image.")),
324
+ altText: Schema$1.NullOr(Schema$1.String).pipe(field(203, "Alternative text for the image."))
325
+ });
326
+ const ProductFeaturedMediaSchema = Schema$1.Struct({ image: Schema$1.NullOr(ProductImageSchema).pipe(field(201, "Image for the featured media.")) });
327
+ const ProductOptionSchema = Schema$1.Struct({
328
+ id: Schema$1.String.pipe(field(302, "Unique product option identifier.")),
329
+ name: Schema$1.String.pipe(field(303, "Name of the product option.")),
330
+ position: Schema$1.Int.pipe(field(304, "Position of the option on the product.")),
331
+ values: Schema$1.Array(Schema$1.String.annotate({ fieldId: 306 })).pipe(field(305, "Values available for the option."))
332
+ });
333
+ const ProductVariantSchema = Schema$1.Struct({
334
+ id: Schema$1.String.pipe(field(402, "Unique product variant identifier.")),
335
+ legacyResourceId: Schema$1.String.pipe(field(403, "Numeric variant identifier stored as text.")),
336
+ title: Schema$1.String.pipe(field(404, "Display title of the variant.")),
337
+ sku: Schema$1.NullOr(Schema$1.String).pipe(field(405, "Stock keeping unit for the variant.")),
338
+ barcode: Schema$1.NullOr(Schema$1.String).pipe(field(406, "Barcode for the variant.")),
339
+ price: Schema$1.String.pipe(field(407, "Price of the variant.")),
340
+ compareAtPrice: Schema$1.NullOr(Schema$1.String).pipe(field(408, "Original price used for comparison.")),
341
+ inventoryPolicy: ProductVariantInventoryPolicySchema.pipe(field(409, "Behavior when the variant is out of stock.")),
342
+ taxable: Schema$1.Boolean.pipe(field(410, "Whether the variant is taxable.")),
343
+ createdAt: Schema$1.Date.pipe(field(411, "Time when the variant was created.")),
344
+ updatedAt: Schema$1.Date.pipe(field(412, "Time when the variant was last changed."))
345
+ });
346
+ const ProductSchema = Schema$1.Struct({
347
+ id: Schema$1.String.pipe(field(1, "Unique product identifier.")),
348
+ legacyResourceId: Schema$1.String.pipe(field(2, "Numeric product identifier stored as text.")),
349
+ title: Schema$1.String.pipe(field(3, "Title of the product.")),
350
+ handle: Schema$1.String.pipe(field(4, "URL handle for the product.")),
351
+ descriptionHtml: Schema$1.String.pipe(field(5, "Product description as HTML.")),
352
+ productType: Schema$1.String.pipe(field(6, "Merchant-defined product type.")),
353
+ vendor: Schema$1.String.pipe(field(7, "Vendor of the product.")),
354
+ status: ProductStatusSchema.pipe(field(8, "Current product status.")),
355
+ tags: Schema$1.Array(Schema$1.String.annotate({ fieldId: 101 })).pipe(field(9, "Tags added to the product.")),
356
+ createdAt: Schema$1.Date.pipe(field(10, "Time when the product was created.")),
357
+ updatedAt: Schema$1.Date.pipe(field(11, "Time when the product was last changed.")),
358
+ publishedAt: Schema$1.NullOr(Schema$1.Date).pipe(field(12, "Time when the product was published.")),
359
+ templateSuffix: Schema$1.NullOr(Schema$1.String).pipe(field(13, "Theme template suffix used by the product.")),
360
+ featuredMedia: Schema$1.NullOr(ProductFeaturedMediaSchema).pipe(field(14, "Featured media for the product.")),
361
+ options: Schema$1.Array(ProductOptionSchema.annotate({ fieldId: 301 })).pipe(field(15, "Options for the product.")),
362
+ variants: Schema$1.Array(ProductVariantSchema.annotate({ fieldId: 401 })).pipe(field(16, "Variants of the product.")),
363
+ _deleted: Schema$1.optional(Schema$1.Boolean).pipe(field(17, "Whether the product was deleted."))
364
+ }).annotate({ description: "Products in a Shopify store." }).pipe(Iceberg.identifier("id"));
365
+ //#endregion
366
+ //#region src/resources/products/webhook.ts
367
+ const ProductWebhookImageSchema = Schema$1.Struct({
368
+ src: Schema$1.String,
369
+ alt: Schema$1.NullOr(Schema$1.String)
370
+ });
371
+ const ProductWebhookOptionSchema = Schema$1.Struct({
372
+ id: Schema$1.Number,
373
+ name: Schema$1.String,
374
+ position: Schema$1.Int,
375
+ values: Schema$1.Array(Schema$1.String)
376
+ });
377
+ const ProductWebhookVariantSchema = Schema$1.Struct({
378
+ admin_graphql_api_id: Schema$1.String,
379
+ id: Schema$1.Number,
380
+ title: Schema$1.String,
381
+ price: Schema$1.String,
382
+ inventory_policy: upper(ProductVariantInventoryPolicySchema),
383
+ compare_at_price: Schema$1.NullOr(Schema$1.String),
384
+ created_at: Schema$1.DateFromString,
385
+ updated_at: Schema$1.DateFromString,
386
+ taxable: Schema$1.Boolean,
387
+ barcode: Schema$1.NullOr(Schema$1.String),
388
+ sku: Schema$1.NullOr(Schema$1.String)
389
+ });
390
+ const ProductWebhookVariantGidSchema = Schema$1.Struct({
391
+ admin_graphql_api_id: Schema$1.String,
392
+ updated_at: Schema$1.DateFromString
393
+ });
394
+ const ProductWebhookPayloadSchema = Schema$1.Struct({
395
+ id: Schema$1.Number,
396
+ admin_graphql_api_id: Schema$1.String,
397
+ body_html: Schema$1.NullOr(Schema$1.String),
398
+ created_at: Schema$1.DateFromString,
399
+ handle: Schema$1.String,
400
+ image: Schema$1.optional(Schema$1.NullOr(ProductWebhookImageSchema)),
401
+ options: Schema$1.Array(ProductWebhookOptionSchema),
402
+ product_type: Schema$1.String,
403
+ published_at: Schema$1.NullOr(Schema$1.DateFromString),
404
+ status: upper(ProductStatusSchema),
405
+ tags: Schema$1.String,
406
+ template_suffix: Schema$1.NullOr(Schema$1.String),
407
+ title: Schema$1.String,
408
+ updated_at: Schema$1.DateFromString,
409
+ variants: Schema$1.Array(ProductWebhookVariantSchema),
410
+ variant_gids: Schema$1.Array(ProductWebhookVariantGidSchema),
411
+ vendor: Schema$1.String
412
+ });
413
+ const ProductDeleteWebhookPayloadSchema = Schema$1.Struct({ id: Schema$1.Number });
414
+ const ProductEventSchema = Schema$1.Union([Schema$1.Struct({
415
+ _tag: Schema$1.Literal("upsert"),
416
+ payload: Schema$1.toType(ProductWebhookPayloadSchema),
417
+ triggeredAt: Schema$1.Date
418
+ }), Schema$1.Struct({
419
+ _tag: Schema$1.Literal("delete"),
420
+ id: Schema$1.String,
421
+ version: Schema$1.Date
422
+ })]);
423
+ const normalizeProductOption = (option) => ({
424
+ id: gid("ProductOption", option.id),
425
+ name: option.name,
426
+ position: option.position,
427
+ values: option.values
428
+ });
429
+ const normalizeProductVariant = (variant) => ({
430
+ id: variant.admin_graphql_api_id,
431
+ legacyResourceId: String(variant.id),
432
+ title: variant.title,
433
+ sku: variant.sku,
434
+ barcode: variant.barcode,
435
+ price: variant.price,
436
+ compareAtPrice: variant.compare_at_price,
437
+ inventoryPolicy: variant.inventory_policy,
438
+ taxable: variant.taxable,
439
+ createdAt: variant.created_at,
440
+ updatedAt: variant.updated_at
441
+ });
442
+ const normalizeProductFeaturedMedia = (image) => image === null || image === void 0 ? null : { image: {
443
+ url: image.src,
444
+ altText: image.alt
445
+ } };
446
+ const fromProductWebhook = (payload) => ({
447
+ id: payload.admin_graphql_api_id,
448
+ legacyResourceId: String(payload.id),
449
+ title: payload.title,
450
+ handle: payload.handle,
451
+ descriptionHtml: payload.body_html ?? "",
452
+ productType: payload.product_type,
453
+ vendor: payload.vendor,
454
+ status: payload.status,
455
+ tags: splitTags(payload.tags),
456
+ createdAt: payload.created_at,
457
+ updatedAt: payload.updated_at,
458
+ publishedAt: payload.published_at,
459
+ templateSuffix: payload.template_suffix ?? "",
460
+ featuredMedia: normalizeProductFeaturedMedia(payload.image),
461
+ options: payload.options.map(normalizeProductOption),
462
+ variants: payload.variants.map(normalizeProductVariant)
463
+ });
464
+ //#endregion
465
+ //#region src/resources/customers/row.ts
466
+ const CustomerStateSchema = Schema$1.Literals([
467
+ "DECLINED",
468
+ "DISABLED",
469
+ "ENABLED",
470
+ "INVITED"
471
+ ]);
472
+ const EmailMarketingStateSchema = Schema$1.Literals([
473
+ "INVALID",
474
+ "NOT_SUBSCRIBED",
475
+ "PENDING",
476
+ "REDACTED",
477
+ "SUBSCRIBED",
478
+ "UNSUBSCRIBED"
479
+ ]);
480
+ const SmsMarketingStateSchema = Schema$1.Literals([
481
+ "NOT_SUBSCRIBED",
482
+ "PENDING",
483
+ "SUBSCRIBED",
484
+ "UNSUBSCRIBED",
485
+ "REDACTED"
486
+ ]);
487
+ const MarketingOptInLevelSchema = Schema$1.Literals([
488
+ "SINGLE_OPT_IN",
489
+ "CONFIRMED_OPT_IN",
490
+ "UNKNOWN"
491
+ ]);
492
+ const ConsentCollectedFromSchema = Schema$1.Literals(["SHOPIFY", "OTHER"]);
493
+ const ProductSubscriberStatusSchema = Schema$1.Literals([
494
+ "ACTIVE",
495
+ "CANCELLED",
496
+ "EXPIRED",
497
+ "FAILED",
498
+ "NEVER_SUBSCRIBED",
499
+ "PAUSED"
500
+ ]);
501
+ const CustomerAddressSchema = Schema$1.Struct({
502
+ id: Schema$1.String.pipe(field(121, "Unique address identifier.")),
503
+ ...address(121).fields
504
+ });
505
+ const CustomerSchema = Schema$1.Struct({
506
+ id: Schema$1.String.pipe(field(1, "Unique customer identifier.")),
507
+ legacyResourceId: Schema$1.String.pipe(field(2, "Numeric customer identifier stored as text.")),
508
+ firstName: Schema$1.NullOr(Schema$1.String).pipe(field(3, "First name.")),
509
+ lastName: Schema$1.NullOr(Schema$1.String).pipe(field(4, "Last name.")),
510
+ displayName: Schema$1.String.pipe(field(5, "Full name shown in Shopify.")),
511
+ email: Schema$1.NullOr(Schema$1.String).pipe(field(6, "Default email address.")),
512
+ emailMarketingState: Schema$1.NullOr(EmailMarketingStateSchema).pipe(field(7, "Email marketing consent state.")),
513
+ emailMarketingOptInLevel: Schema$1.NullOr(MarketingOptInLevelSchema).pipe(field(8, "Email marketing opt-in level.")),
514
+ emailMarketingUpdatedAt: Schema$1.NullOr(Schema$1.Date).pipe(field(9, "Time when email marketing consent last changed.")),
515
+ phone: Schema$1.NullOr(Schema$1.String).pipe(field(10, "Default phone number.")),
516
+ smsMarketingState: Schema$1.NullOr(SmsMarketingStateSchema).pipe(field(11, "SMS marketing consent state.")),
517
+ smsMarketingOptInLevel: Schema$1.NullOr(MarketingOptInLevelSchema).pipe(field(12, "SMS marketing opt-in level.")),
518
+ smsMarketingUpdatedAt: Schema$1.NullOr(Schema$1.Date).pipe(field(13, "Time when SMS marketing consent last changed.")),
519
+ smsMarketingCollectedFrom: Schema$1.NullOr(ConsentCollectedFromSchema).pipe(field(14, "Where SMS marketing consent was collected.")),
520
+ note: Schema$1.NullOr(Schema$1.String).pipe(field(15, "Merchant note about the customer.")),
521
+ state: CustomerStateSchema.pipe(field(16, "Customer account state.")),
522
+ verifiedEmail: Schema$1.Boolean.pipe(field(17, "Whether the email address is verified.")),
523
+ taxExempt: Schema$1.Boolean.pipe(field(18, "Whether the customer is exempt from tax.")),
524
+ taxExemptions: Schema$1.Array(Schema$1.String.annotate({ fieldId: 100 })).pipe(field(19, "Tax exemptions that apply to the customer.")),
525
+ tags: Schema$1.Array(Schema$1.String.annotate({ fieldId: 101 })).pipe(field(20, "Tags added to the customer.")),
526
+ locale: Schema$1.NullOr(Schema$1.String).pipe(field(21, "Customer language.")),
527
+ numberOfOrders: Schema$1.Int.pipe(field(22, "Number of orders the customer placed.")),
528
+ amountSpent: Schema$1.Struct({
529
+ amount: Schema$1.String.pipe(field(111, "Amount spent.")),
530
+ currencyCode: Schema$1.String.pipe(field(112, "Shop currency code."))
531
+ }).pipe(field(23, "Total amount spent in the shop currency.")),
532
+ lastOrderId: Schema$1.NullOr(Schema$1.String).pipe(field(24, "Most recent order identifier.")),
533
+ productSubscriberStatus: Schema$1.NullOr(ProductSubscriberStatusSchema).pipe(field(25, "Subscription status for products.")),
534
+ dataSaleOptOut: Schema$1.NullOr(Schema$1.Boolean).pipe(field(26, "Whether the customer opted out of data sale.")),
535
+ defaultAddressId: Schema$1.NullOr(Schema$1.String).pipe(field(27, "Default address identifier.")),
536
+ addresses: Schema$1.Array(CustomerAddressSchema.annotate({ fieldId: 120 })).pipe(field(28, "Saved addresses.")),
537
+ createdAt: Schema$1.Date.pipe(field(29, "Time when the customer was created.")),
538
+ updatedAt: Schema$1.Date.pipe(field(30, "Time when the customer was last changed.")),
539
+ _deleted: Schema$1.optional(Schema$1.Boolean).pipe(field(31, "Whether the customer was deleted."))
540
+ }).annotate({ description: "Customers in a Shopify store." }).pipe(Iceberg.identifier("id"));
541
+ //#endregion
542
+ //#region src/resources/customers/graphql.ts
543
+ const CustomerAddressNodeFields = `id ${AddressFields}`;
544
+ const CustomerFields = `
545
+ id
546
+ legacyResourceId
547
+ firstName
548
+ lastName
549
+ displayName
550
+ note
551
+ state
552
+ verifiedEmail
553
+ taxExempt
554
+ taxExemptions
555
+ tags
556
+ locale
557
+ numberOfOrders
558
+ amountSpent { amount currencyCode }
559
+ lastOrder { id }
560
+ productSubscriberStatus
561
+ dataSaleOptOut
562
+ defaultEmailAddress { emailAddress marketingState marketingOptInLevel marketingUpdatedAt }
563
+ defaultPhoneNumber { phoneNumber }
564
+ smsMarketingConsent { marketingState marketingOptInLevel consentUpdatedAt consentCollectedFrom }
565
+ defaultAddress { id }
566
+ addressesV2(first: 25) {
567
+ nodes { ${CustomerAddressNodeFields} }
568
+ pageInfo { hasNextPage endCursor }
569
+ }
570
+ createdAt
571
+ updatedAt
572
+ `;
573
+ const CustomerAddressesQuery = `#graphql
574
+ query AirfoilCustomerAddresses($id: ID!, $first: Int!, $after: String) {
575
+ node: customer(id: $id) {
576
+ connection: addressesV2(first: $first, after: $after) {
577
+ nodes { ${CustomerAddressNodeFields} }
578
+ pageInfo { hasNextPage endCursor }
579
+ }
580
+ }
581
+ }
582
+ `;
583
+ const CustomerByIdQuery = `#graphql
584
+ query AirfoilCustomerById($id: ID!) {
585
+ customer(id: $id) { ${CustomerFields} }
586
+ }
587
+ `;
588
+ const GraphQLCustomerAddressesSchema = connection(Schema$1.Struct({
589
+ id: Schema$1.String,
590
+ ...GraphQLAddressSchema.fields
591
+ }));
592
+ const GraphQLCustomerNodeSchema = Schema$1.Struct({
593
+ id: Schema$1.String,
594
+ legacyResourceId: Schema$1.String,
595
+ firstName: Schema$1.NullOr(Schema$1.String),
596
+ lastName: Schema$1.NullOr(Schema$1.String),
597
+ displayName: Schema$1.String,
598
+ note: Schema$1.NullOr(Schema$1.String),
599
+ state: CustomerStateSchema,
600
+ verifiedEmail: Schema$1.Boolean,
601
+ taxExempt: Schema$1.Boolean,
602
+ taxExemptions: Schema$1.Array(Schema$1.String),
603
+ tags: Schema$1.Array(Schema$1.String),
604
+ locale: Schema$1.String,
605
+ numberOfOrders: Schema$1.NumberFromString,
606
+ amountSpent: Schema$1.Struct({
607
+ amount: Schema$1.String,
608
+ currencyCode: Schema$1.String
609
+ }),
610
+ lastOrder: Schema$1.NullOr(Schema$1.Struct({ id: Schema$1.String })),
611
+ productSubscriberStatus: ProductSubscriberStatusSchema,
612
+ dataSaleOptOut: Schema$1.Boolean,
613
+ defaultEmailAddress: Schema$1.NullOr(Schema$1.Struct({
614
+ emailAddress: Schema$1.String,
615
+ marketingState: EmailMarketingStateSchema,
616
+ marketingOptInLevel: Schema$1.NullOr(MarketingOptInLevelSchema),
617
+ marketingUpdatedAt: Schema$1.NullOr(Schema$1.DateFromString)
618
+ })),
619
+ defaultPhoneNumber: Schema$1.NullOr(Schema$1.Struct({ phoneNumber: Schema$1.String })),
620
+ smsMarketingConsent: Schema$1.NullOr(Schema$1.Struct({
621
+ marketingState: SmsMarketingStateSchema,
622
+ marketingOptInLevel: MarketingOptInLevelSchema,
623
+ consentUpdatedAt: Schema$1.NullOr(Schema$1.DateFromString),
624
+ consentCollectedFrom: Schema$1.NullOr(ConsentCollectedFromSchema)
625
+ })),
626
+ defaultAddress: Schema$1.NullOr(Schema$1.Struct({ id: Schema$1.String })),
627
+ addressesV2: GraphQLCustomerAddressesSchema,
628
+ createdAt: Schema$1.DateFromString,
629
+ updatedAt: Schema$1.DateFromString
630
+ });
631
+ const addressId = (value) => value.replace(/\?.*$/, "");
632
+ const normalizeCustomerNode = (node, addresses) => ({
633
+ id: node.id,
634
+ legacyResourceId: node.legacyResourceId,
635
+ firstName: emptyText(node.firstName),
636
+ lastName: emptyText(node.lastName),
637
+ displayName: node.displayName,
638
+ email: node.defaultEmailAddress?.emailAddress ?? "",
639
+ emailMarketingState: node.defaultEmailAddress?.marketingState ?? null,
640
+ emailMarketingOptInLevel: node.defaultEmailAddress?.marketingOptInLevel ?? null,
641
+ emailMarketingUpdatedAt: node.defaultEmailAddress?.marketingUpdatedAt ?? null,
642
+ phone: node.defaultPhoneNumber?.phoneNumber ?? "",
643
+ smsMarketingState: node.smsMarketingConsent?.marketingState ?? null,
644
+ smsMarketingOptInLevel: node.smsMarketingConsent?.marketingOptInLevel ?? null,
645
+ smsMarketingUpdatedAt: node.smsMarketingConsent?.consentUpdatedAt ?? null,
646
+ smsMarketingCollectedFrom: node.smsMarketingConsent?.consentCollectedFrom ?? null,
647
+ note: emptyText(node.note),
648
+ state: node.state,
649
+ verifiedEmail: node.verifiedEmail,
650
+ taxExempt: node.taxExempt,
651
+ taxExemptions: node.taxExemptions,
652
+ tags: node.tags,
653
+ locale: node.locale,
654
+ numberOfOrders: node.numberOfOrders,
655
+ amountSpent: {
656
+ amount: normalizeAmount(node.amountSpent.amount),
657
+ currencyCode: node.amountSpent.currencyCode
658
+ },
659
+ lastOrderId: node.lastOrder?.id ?? "",
660
+ productSubscriberStatus: node.productSubscriberStatus,
661
+ dataSaleOptOut: node.dataSaleOptOut,
662
+ defaultAddressId: node.defaultAddress === null ? "" : addressId(node.defaultAddress.id),
663
+ addresses: addresses.map(({ id, ...value }) => ({
664
+ id: addressId(id),
665
+ ...fromGraphQL.address(value)
666
+ })),
667
+ createdAt: node.createdAt,
668
+ updatedAt: node.updatedAt
669
+ });
670
+ const CustomersQuery = pageQuery("AirfoilCustomers", "customers", CustomerFields);
671
+ const GraphQLCustomersDataSchema = Schema$1.Struct({ customers: connection(GraphQLCustomerNodeSchema) });
672
+ const GraphQLCustomerByIdDataSchema = Schema$1.Struct({ customer: Schema$1.NullOr(GraphQLCustomerNodeSchema) });
673
+ //#endregion
674
+ //#region src/resources/orders/row.ts
675
+ const OrderCancelReasonSchema = Schema$1.Literals([
676
+ "CUSTOMER",
677
+ "DECLINED",
678
+ "FRAUD",
679
+ "INVENTORY",
680
+ "STAFF",
681
+ "OTHER"
682
+ ]);
683
+ const OrderFinancialStatusSchema = Schema$1.Literals([
684
+ "PENDING",
685
+ "AUTHORIZED",
686
+ "PARTIALLY_PAID",
687
+ "PARTIALLY_REFUNDED",
688
+ "VOIDED",
689
+ "PAID",
690
+ "REFUNDED",
691
+ "EXPIRED"
692
+ ]);
693
+ const DiscountApplicationTypeSchema = Schema$1.Literals([
694
+ "DISCOUNT_CODE",
695
+ "MANUAL",
696
+ "AUTOMATIC",
697
+ "SCRIPT"
698
+ ]);
699
+ const DiscountAllocationMethodSchema = Schema$1.Literals([
700
+ "ACROSS",
701
+ "EACH",
702
+ "ONE"
703
+ ]);
704
+ const DiscountTargetSelectionSchema = Schema$1.Literals([
705
+ "ALL",
706
+ "ENTITLED",
707
+ "EXPLICIT"
708
+ ]);
709
+ const DiscountTargetTypeSchema = Schema$1.Literals(["LINE_ITEM", "SHIPPING_LINE"]);
710
+ const DiscountValueTypeSchema = Schema$1.Literals(["PERCENTAGE", "FIXED_AMOUNT"]);
711
+ const DiscountApplicationSchema = Schema$1.Struct({
712
+ index: Schema$1.Int.pipe(field(161, "Position used by discount allocations.")),
713
+ type: DiscountApplicationTypeSchema.pipe(field(162, "How the discount was applied.")),
714
+ code: Schema$1.NullOr(Schema$1.String).pipe(field(163, "Discount code.")),
715
+ title: Schema$1.NullOr(Schema$1.String).pipe(field(164, "Discount title.")),
716
+ description: Schema$1.NullOr(Schema$1.String).pipe(field(165, "Manual discount description.")),
717
+ allocationMethod: DiscountAllocationMethodSchema.pipe(field(166, "How the value is split.")),
718
+ targetSelection: DiscountTargetSelectionSchema.pipe(field(167, "Which lines are targeted.")),
719
+ targetType: DiscountTargetTypeSchema.pipe(field(168, "Kind of lines targeted.")),
720
+ valueType: DiscountValueTypeSchema.pipe(field(169, "Whether the value is a percent.")),
721
+ value: Schema$1.String.pipe(field(170, "Percent or amount in the customer currency."))
722
+ });
723
+ const ShippingLineSchema = Schema$1.Struct({
724
+ id: Schema$1.NullOr(Schema$1.String).pipe(field(501, "Unique shipping line identifier.")),
725
+ title: Schema$1.String.pipe(field(502, "Shipping method title.")),
726
+ code: Schema$1.NullOr(Schema$1.String).pipe(field(503, "Shipping rate code.")),
727
+ source: Schema$1.NullOr(Schema$1.String).pipe(field(504, "Source of the shipping rate.")),
728
+ carrierIdentifier: Schema$1.NullOr(Schema$1.String).pipe(field(505, "Carrier service identifier.")),
729
+ phone: Schema$1.NullOr(Schema$1.String).pipe(field(506, "Phone number for the shipping line.")),
730
+ isRemoved: Schema$1.Boolean.pipe(field(507, "Whether the line was removed by an edit.")),
731
+ originalPriceSet: moneyBag(520).pipe(field(508, "Price before discounts.")),
732
+ discountedPriceSet: moneyBag(530).pipe(field(509, "Price after discounts.")),
733
+ currentDiscountedPriceSet: moneyBag(540).pipe(field(510, "Price after discounts, edits, and refunds.")),
734
+ taxLines: taxLines(550).pipe(field(511, "Taxes on the shipping line.")),
735
+ discountAllocations: discountAllocations(570).pipe(field(512, "Discounts on the line."))
736
+ });
737
+ const OrderLineItemSchema = Schema$1.Struct({
738
+ id: Schema$1.String.pipe(field(601, "Unique line item identifier.")),
739
+ name: Schema$1.String.pipe(field(602, "Product and variant name.")),
740
+ title: Schema$1.String.pipe(field(603, "Product title.")),
741
+ variantTitle: Schema$1.NullOr(Schema$1.String).pipe(field(604, "Variant title.")),
742
+ sku: Schema$1.NullOr(Schema$1.String).pipe(field(605, "Stock keeping unit.")),
743
+ vendor: Schema$1.NullOr(Schema$1.String).pipe(field(606, "Product vendor.")),
744
+ productId: Schema$1.NullOr(Schema$1.String).pipe(field(607, "Product identifier.")),
745
+ variantId: Schema$1.NullOr(Schema$1.String).pipe(field(608, "Product variant identifier.")),
746
+ quantity: Schema$1.Int.pipe(field(609, "Quantity when the order was placed.")),
747
+ currentQuantity: Schema$1.Int.pipe(field(610, "Quantity after removals and refunds.")),
748
+ taxable: Schema$1.Boolean.pipe(field(611, "Whether the line item is taxable.")),
749
+ requiresShipping: Schema$1.Boolean.pipe(field(612, "Whether the line item needs shipping.")),
750
+ isGiftCard: Schema$1.Boolean.pipe(field(613, "Whether the line item is a gift card.")),
751
+ originalUnitPriceSet: moneyBag(630).pipe(field(614, "Unit price before discounts.")),
752
+ totalDiscountSet: moneyBag(640).pipe(field(615, "Total discount on the line.")),
753
+ taxLines: taxLines(650).pipe(field(616, "Taxes on the line.")),
754
+ discountAllocations: discountAllocations(670).pipe(field(617, "Discounts on the line.")),
755
+ customAttributes: attributes(690).pipe(field(618, "Custom line properties."))
756
+ });
757
+ const OrderSchema = Schema$1.Struct({
758
+ id: Schema$1.String.pipe(field(1, "Unique order identifier.")),
759
+ legacyResourceId: Schema$1.String.pipe(field(2, "Numeric order identifier stored as text.")),
760
+ name: Schema$1.String.pipe(field(3, "Order name shown to the merchant.")),
761
+ email: Schema$1.NullOr(Schema$1.String).pipe(field(4, "Email used for the order.")),
762
+ phone: Schema$1.NullOr(Schema$1.String).pipe(field(5, "Phone used for the order.")),
763
+ customerId: Schema$1.NullOr(Schema$1.String).pipe(field(6, "Customer identifier.")),
764
+ customerLocale: Schema$1.NullOr(Schema$1.String).pipe(field(7, "Customer language.")),
765
+ customerAcceptsMarketing: Schema$1.Boolean.pipe(field(8, "Whether the buyer accepts marketing.")),
766
+ billingAddress: Schema$1.NullOr(address(100)).pipe(field(9, "Billing address.")),
767
+ shippingAddress: Schema$1.NullOr(address(120)).pipe(field(10, "Shipping address.")),
768
+ note: Schema$1.NullOr(Schema$1.String).pipe(field(11, "Order note.")),
769
+ customAttributes: attributes(140).pipe(field(12, "Custom order attributes.")),
770
+ tags: Schema$1.Array(Schema$1.String.annotate({ fieldId: 150 })).pipe(field(13, "Tags added to the order.")),
771
+ confirmationNumber: Schema$1.NullOr(Schema$1.String).pipe(field(14, "Confirmation number.")),
772
+ poNumber: Schema$1.NullOr(Schema$1.String).pipe(field(15, "Purchase order number.")),
773
+ sourceName: Schema$1.NullOr(Schema$1.String).pipe(field(16, "Channel that created the order.")),
774
+ sourceIdentifier: Schema$1.NullOr(Schema$1.String).pipe(field(17, "Identifier from the source.")),
775
+ appId: Schema$1.NullOr(Schema$1.String).pipe(field(18, "App that created the order.")),
776
+ paymentGatewayNames: Schema$1.Array(Schema$1.String.annotate({ fieldId: 152 })).pipe(field(19, "Payment gateways used.")),
777
+ test: Schema$1.Boolean.pipe(field(20, "Whether the order is a test order.")),
778
+ taxesIncluded: Schema$1.Boolean.pipe(field(21, "Whether prices include taxes.")),
779
+ taxExempt: Schema$1.Boolean.pipe(field(22, "Whether the order is exempt from tax.")),
780
+ dutiesIncluded: Schema$1.Boolean.pipe(field(23, "Whether prices include duties.")),
781
+ estimatedTaxes: Schema$1.Boolean.pipe(field(24, "Whether taxes are estimates.")),
782
+ totalWeight: Schema$1.NullOr(Schema$1.Int).pipe(field(25, "Total weight in grams.")),
783
+ displayFinancialStatus: Schema$1.NullOr(OrderFinancialStatusSchema).pipe(field(26, "Payment status of the order.")),
784
+ cancelReason: Schema$1.NullOr(OrderCancelReasonSchema).pipe(field(27, "Reason the order was cancelled.")),
785
+ cancelledAt: Schema$1.NullOr(Schema$1.Date).pipe(field(28, "Time when the order was cancelled.")),
786
+ closedAt: Schema$1.NullOr(Schema$1.Date).pipe(field(29, "Time when the order was closed.")),
787
+ processedAt: Schema$1.Date.pipe(field(30, "Time when the order was processed.")),
788
+ createdAt: Schema$1.Date.pipe(field(31, "Time when the order was created.")),
789
+ updatedAt: Schema$1.Date.pipe(field(32, "Time when the order was last changed.")),
790
+ currencyCode: Schema$1.String.pipe(field(33, "Shop currency code.")),
791
+ presentmentCurrencyCode: Schema$1.String.pipe(field(34, "Customer currency code.")),
792
+ discountCodes: Schema$1.Array(Schema$1.String.annotate({ fieldId: 151 })).pipe(field(35, "Discount codes used.")),
793
+ discountApplications: Schema$1.Array(DiscountApplicationSchema.annotate({ fieldId: 160 })).pipe(field(36, "Discounts applied to the order.")),
794
+ subtotalPriceSet: Schema$1.NullOr(moneyBag(200)).pipe(field(37, "Subtotal when the order was placed.")),
795
+ currentSubtotalPriceSet: moneyBag(210).pipe(field(38, "Subtotal after edits and refunds.")),
796
+ totalDiscountsSet: Schema$1.NullOr(moneyBag(220)).pipe(field(39, "Discounts when the order was placed.")),
797
+ currentTotalDiscountsSet: moneyBag(230).pipe(field(40, "Discounts after edits and refunds.")),
798
+ totalShippingPriceSet: moneyBag(240).pipe(field(41, "Shipping when the order was placed.")),
799
+ currentShippingPriceSet: moneyBag(250).pipe(field(42, "Shipping after edits and refunds.")),
800
+ totalTaxSet: Schema$1.NullOr(moneyBag(260)).pipe(field(43, "Tax when the order was placed.")),
801
+ currentTotalTaxSet: moneyBag(270).pipe(field(44, "Tax after edits and refunds.")),
802
+ originalTotalDutiesSet: Schema$1.NullOr(moneyBag(280)).pipe(field(45, "Duties when the order was placed.")),
803
+ currentTotalDutiesSet: Schema$1.NullOr(moneyBag(290)).pipe(field(46, "Duties after edits and refunds.")),
804
+ totalPriceSet: moneyBag(300).pipe(field(47, "Total when the order was placed.")),
805
+ currentTotalPriceSet: moneyBag(310).pipe(field(48, "Total after edits and refunds.")),
806
+ taxLines: taxLines(400).pipe(field(49, "Taxes when the order was placed.")),
807
+ shippingLines: Schema$1.Array(ShippingLineSchema.annotate({ fieldId: 500 })).pipe(field(50, "Shipping lines, including removed ones.")),
808
+ lineItems: Schema$1.Array(OrderLineItemSchema.annotate({ fieldId: 600 })).pipe(field(51, "Line items in the order.")),
809
+ _deleted: Schema$1.optional(Schema$1.Boolean).pipe(field(52, "Whether the order was deleted."))
810
+ }).annotate({ description: "Orders in a Shopify store." }).pipe(Iceberg.identifier("id"));
811
+ //#endregion
812
+ //#region src/resources/orders/graphql.ts
813
+ const LineItemFields = `
814
+ id
815
+ name
816
+ title
817
+ variantTitle
818
+ sku
819
+ vendor
820
+ product { id }
821
+ variant { id }
822
+ quantity
823
+ currentQuantity
824
+ taxable
825
+ requiresShipping
826
+ isGiftCard
827
+ originalUnitPriceSet { ${MoneyBagFields} }
828
+ totalDiscountSet { ${MoneyBagFields} }
829
+ taxLines { ${TaxLineFields} }
830
+ discountAllocations { ${DiscountAllocationFields} }
831
+ customAttributes { key value }
832
+ `;
833
+ const ShippingLineFields = `
834
+ id
835
+ title
836
+ code
837
+ source
838
+ carrierIdentifier
839
+ phone
840
+ isRemoved
841
+ originalPriceSet { ${MoneyBagFields} }
842
+ discountedPriceSet { ${MoneyBagFields} }
843
+ currentDiscountedPriceSet { ${MoneyBagFields} }
844
+ taxLines { ${TaxLineFields} }
845
+ discountAllocations { ${DiscountAllocationFields} }
846
+ `;
847
+ const DiscountApplicationFields = `
848
+ __typename
849
+ index
850
+ allocationMethod
851
+ targetSelection
852
+ targetType
853
+ value {
854
+ __typename
855
+ ... on MoneyV2 { amount }
856
+ ... on PricingPercentageValue { percentage }
857
+ }
858
+ ... on DiscountCodeApplication { code }
859
+ ... on ManualDiscountApplication { title description }
860
+ ... on AutomaticDiscountApplication { title }
861
+ ... on ScriptDiscountApplication { title }
862
+ `;
863
+ const OrderFields = `
864
+ id
865
+ legacyResourceId
866
+ name
867
+ email
868
+ phone
869
+ customer { id }
870
+ customerLocale
871
+ customerAcceptsMarketing
872
+ billingAddress { ${AddressFields} }
873
+ shippingAddress { ${AddressFields} }
874
+ note
875
+ customAttributes { key value }
876
+ tags
877
+ confirmationNumber
878
+ poNumber
879
+ sourceName
880
+ sourceIdentifier
881
+ app { id }
882
+ paymentGatewayNames
883
+ test
884
+ taxesIncluded
885
+ taxExempt
886
+ dutiesIncluded
887
+ estimatedTaxes
888
+ totalWeight
889
+ displayFinancialStatus
890
+ cancelReason
891
+ cancelledAt
892
+ closedAt
893
+ processedAt
894
+ createdAt
895
+ updatedAt
896
+ currencyCode
897
+ presentmentCurrencyCode
898
+ discountCodes
899
+ discountApplications(first: 25) { nodes { ${DiscountApplicationFields} } ${PageInfoFields} }
900
+ subtotalPriceSet { ${MoneyBagFields} }
901
+ currentSubtotalPriceSet { ${MoneyBagFields} }
902
+ totalDiscountsSet { ${MoneyBagFields} }
903
+ currentTotalDiscountsSet { ${MoneyBagFields} }
904
+ totalShippingPriceSet { ${MoneyBagFields} }
905
+ currentShippingPriceSet { ${MoneyBagFields} }
906
+ totalTaxSet { ${MoneyBagFields} }
907
+ currentTotalTaxSet { ${MoneyBagFields} }
908
+ originalTotalDutiesSet { ${MoneyBagFields} }
909
+ currentTotalDutiesSet { ${MoneyBagFields} }
910
+ totalPriceSet { ${MoneyBagFields} }
911
+ currentTotalPriceSet { ${MoneyBagFields} }
912
+ taxLines { ${TaxLineFields} }
913
+ shippingLines(first: 25, includeRemovals: true) { nodes { ${ShippingLineFields} } ${PageInfoFields} }
914
+ lineItems(first: 50) { nodes { ${LineItemFields} } ${PageInfoFields} }
915
+ `;
916
+ const orderConnectionQuery = (name, selection) => `#graphql
917
+ query ${name}($id: ID!, $first: Int!, $after: String) {
918
+ node: order(id: $id) {
919
+ connection: ${selection}
920
+ }
921
+ }
922
+ `;
923
+ const OrderLineItemsQuery = orderConnectionQuery("AirfoilOrderLineItems", `lineItems(first: $first, after: $after) { nodes { ${LineItemFields} } ${PageInfoFields} }`);
924
+ const OrderShippingLinesQuery = orderConnectionQuery("AirfoilOrderShippingLines", `shippingLines(first: $first, after: $after, includeRemovals: true) { nodes { ${ShippingLineFields} } ${PageInfoFields} }`);
925
+ const OrderDiscountApplicationsQuery = orderConnectionQuery("AirfoilOrderDiscountApplications", `discountApplications(first: $first, after: $after) { nodes { ${DiscountApplicationFields} } ${PageInfoFields} }`);
926
+ const GraphQLLineItemsSchema = connection(Schema$1.Struct({
927
+ id: Schema$1.String,
928
+ name: Schema$1.String,
929
+ title: Schema$1.String,
930
+ variantTitle: Schema$1.NullOr(Schema$1.String),
931
+ sku: Schema$1.NullOr(Schema$1.String),
932
+ vendor: Schema$1.NullOr(Schema$1.String),
933
+ product: idRef,
934
+ variant: idRef,
935
+ quantity: Schema$1.Int,
936
+ currentQuantity: Schema$1.Int,
937
+ taxable: Schema$1.Boolean,
938
+ requiresShipping: Schema$1.Boolean,
939
+ isGiftCard: Schema$1.Boolean,
940
+ originalUnitPriceSet: GraphQLMoneyBagSchema,
941
+ totalDiscountSet: GraphQLMoneyBagSchema,
942
+ taxLines: Schema$1.Array(GraphQLTaxLineSchema),
943
+ discountAllocations: Schema$1.Array(GraphQLDiscountAllocationSchema),
944
+ customAttributes: Schema$1.Array(GraphQLAttributeSchema)
945
+ }));
946
+ const GraphQLShippingLinesSchema = connection(Schema$1.Struct({
947
+ id: Schema$1.NullOr(Schema$1.String),
948
+ title: Schema$1.String,
949
+ code: Schema$1.NullOr(Schema$1.String),
950
+ source: Schema$1.NullOr(Schema$1.String),
951
+ carrierIdentifier: Schema$1.NullOr(Schema$1.String),
952
+ phone: Schema$1.NullOr(Schema$1.String),
953
+ isRemoved: Schema$1.Boolean,
954
+ originalPriceSet: GraphQLMoneyBagSchema,
955
+ discountedPriceSet: GraphQLMoneyBagSchema,
956
+ currentDiscountedPriceSet: GraphQLMoneyBagSchema,
957
+ taxLines: Schema$1.Array(GraphQLTaxLineSchema),
958
+ discountAllocations: Schema$1.Array(GraphQLDiscountAllocationSchema)
959
+ }));
960
+ const discountApplicationBase = {
961
+ index: Schema$1.Int,
962
+ allocationMethod: DiscountAllocationMethodSchema,
963
+ targetSelection: DiscountTargetSelectionSchema,
964
+ targetType: DiscountTargetTypeSchema,
965
+ value: Schema$1.Union([Schema$1.Struct({
966
+ __typename: Schema$1.Literal("MoneyV2"),
967
+ amount: Schema$1.String
968
+ }), Schema$1.Struct({
969
+ __typename: Schema$1.Literal("PricingPercentageValue"),
970
+ percentage: Schema$1.Number
971
+ })])
972
+ };
973
+ const GraphQLDiscountApplicationsSchema = connection(Schema$1.Union([
974
+ Schema$1.Struct({
975
+ __typename: Schema$1.Literal("DiscountCodeApplication"),
976
+ code: Schema$1.String,
977
+ ...discountApplicationBase
978
+ }),
979
+ Schema$1.Struct({
980
+ __typename: Schema$1.Literal("ManualDiscountApplication"),
981
+ title: Schema$1.String,
982
+ description: Schema$1.NullOr(Schema$1.String),
983
+ ...discountApplicationBase
984
+ }),
985
+ Schema$1.Struct({
986
+ __typename: Schema$1.Literals(["AutomaticDiscountApplication", "ScriptDiscountApplication"]),
987
+ title: Schema$1.String,
988
+ ...discountApplicationBase
989
+ })
990
+ ]));
991
+ const GraphQLOrderNodeSchema = Schema$1.Struct({
992
+ id: Schema$1.String,
993
+ legacyResourceId: Schema$1.String,
994
+ name: Schema$1.String,
995
+ email: Schema$1.NullOr(Schema$1.String),
996
+ phone: Schema$1.NullOr(Schema$1.String),
997
+ customer: idRef,
998
+ customerLocale: Schema$1.NullOr(Schema$1.String),
999
+ customerAcceptsMarketing: Schema$1.Boolean,
1000
+ billingAddress: Schema$1.NullOr(GraphQLAddressSchema),
1001
+ shippingAddress: Schema$1.NullOr(GraphQLAddressSchema),
1002
+ note: Schema$1.NullOr(Schema$1.String),
1003
+ customAttributes: Schema$1.Array(GraphQLAttributeSchema),
1004
+ tags: Schema$1.Array(Schema$1.String),
1005
+ confirmationNumber: Schema$1.NullOr(Schema$1.String),
1006
+ poNumber: Schema$1.NullOr(Schema$1.String),
1007
+ sourceName: Schema$1.NullOr(Schema$1.String),
1008
+ sourceIdentifier: Schema$1.NullOr(Schema$1.String),
1009
+ app: idRef,
1010
+ paymentGatewayNames: Schema$1.Array(Schema$1.String),
1011
+ test: Schema$1.Boolean,
1012
+ taxesIncluded: Schema$1.Boolean,
1013
+ taxExempt: Schema$1.Boolean,
1014
+ dutiesIncluded: Schema$1.Boolean,
1015
+ estimatedTaxes: Schema$1.Boolean,
1016
+ totalWeight: Schema$1.NullOr(Schema$1.NumberFromString),
1017
+ displayFinancialStatus: Schema$1.NullOr(OrderFinancialStatusSchema),
1018
+ cancelReason: Schema$1.NullOr(OrderCancelReasonSchema),
1019
+ cancelledAt: Schema$1.NullOr(Schema$1.DateFromString),
1020
+ closedAt: Schema$1.NullOr(Schema$1.DateFromString),
1021
+ processedAt: Schema$1.DateFromString,
1022
+ createdAt: Schema$1.DateFromString,
1023
+ updatedAt: Schema$1.DateFromString,
1024
+ currencyCode: Schema$1.String,
1025
+ presentmentCurrencyCode: Schema$1.String,
1026
+ discountCodes: Schema$1.Array(Schema$1.String),
1027
+ discountApplications: GraphQLDiscountApplicationsSchema,
1028
+ subtotalPriceSet: Schema$1.NullOr(GraphQLMoneyBagSchema),
1029
+ currentSubtotalPriceSet: GraphQLMoneyBagSchema,
1030
+ totalDiscountsSet: Schema$1.NullOr(GraphQLMoneyBagSchema),
1031
+ currentTotalDiscountsSet: GraphQLMoneyBagSchema,
1032
+ totalShippingPriceSet: GraphQLMoneyBagSchema,
1033
+ currentShippingPriceSet: GraphQLMoneyBagSchema,
1034
+ totalTaxSet: Schema$1.NullOr(GraphQLMoneyBagSchema),
1035
+ currentTotalTaxSet: GraphQLMoneyBagSchema,
1036
+ originalTotalDutiesSet: Schema$1.NullOr(GraphQLMoneyBagSchema),
1037
+ currentTotalDutiesSet: Schema$1.NullOr(GraphQLMoneyBagSchema),
1038
+ totalPriceSet: GraphQLMoneyBagSchema,
1039
+ currentTotalPriceSet: GraphQLMoneyBagSchema,
1040
+ taxLines: Schema$1.Array(GraphQLTaxLineSchema),
1041
+ shippingLines: GraphQLShippingLinesSchema,
1042
+ lineItems: GraphQLLineItemsSchema
1043
+ });
1044
+ const discountApplicationType = {
1045
+ DiscountCodeApplication: "DISCOUNT_CODE",
1046
+ ManualDiscountApplication: "MANUAL",
1047
+ AutomaticDiscountApplication: "AUTOMATIC",
1048
+ ScriptDiscountApplication: "SCRIPT"
1049
+ };
1050
+ const fromOrderNode = (node, nested) => ({
1051
+ id: node.id,
1052
+ legacyResourceId: node.legacyResourceId,
1053
+ name: node.name,
1054
+ email: emptyText(node.email),
1055
+ phone: emptyText(node.phone),
1056
+ customerId: node.customer?.id ?? "",
1057
+ customerLocale: emptyText(node.customerLocale),
1058
+ customerAcceptsMarketing: node.customerAcceptsMarketing,
1059
+ billingAddress: node.billingAddress ? fromGraphQL.address(node.billingAddress) : null,
1060
+ shippingAddress: node.shippingAddress ? fromGraphQL.address(node.shippingAddress) : null,
1061
+ note: emptyText(node.note),
1062
+ customAttributes: node.customAttributes,
1063
+ tags: node.tags,
1064
+ confirmationNumber: emptyText(node.confirmationNumber),
1065
+ poNumber: emptyText(node.poNumber),
1066
+ sourceName: emptyText(node.sourceName),
1067
+ sourceIdentifier: emptyText(node.sourceIdentifier),
1068
+ appId: node.app?.id ?? "",
1069
+ paymentGatewayNames: node.paymentGatewayNames,
1070
+ test: node.test,
1071
+ taxesIncluded: node.taxesIncluded,
1072
+ taxExempt: node.taxExempt,
1073
+ dutiesIncluded: node.dutiesIncluded,
1074
+ estimatedTaxes: node.estimatedTaxes,
1075
+ totalWeight: node.totalWeight,
1076
+ displayFinancialStatus: node.displayFinancialStatus,
1077
+ cancelReason: node.cancelReason,
1078
+ cancelledAt: node.cancelledAt,
1079
+ closedAt: node.closedAt,
1080
+ processedAt: node.processedAt,
1081
+ createdAt: node.createdAt,
1082
+ updatedAt: node.updatedAt,
1083
+ currencyCode: node.currencyCode,
1084
+ presentmentCurrencyCode: node.presentmentCurrencyCode,
1085
+ discountCodes: node.discountCodes,
1086
+ discountApplications: nested.discountApplications.map((application) => ({
1087
+ index: application.index,
1088
+ type: discountApplicationType[application.__typename],
1089
+ code: application.__typename === "DiscountCodeApplication" ? application.code : null,
1090
+ title: application.__typename === "DiscountCodeApplication" ? null : application.title,
1091
+ description: application.__typename === "ManualDiscountApplication" ? application.description : null,
1092
+ allocationMethod: application.allocationMethod,
1093
+ targetSelection: application.targetSelection,
1094
+ targetType: application.targetType,
1095
+ valueType: application.value.__typename === "MoneyV2" ? "FIXED_AMOUNT" : "PERCENTAGE",
1096
+ value: application.value.__typename === "MoneyV2" ? normalizeAmount(application.value.amount) : normalizeAmount(String(application.value.percentage))
1097
+ })),
1098
+ subtotalPriceSet: node.subtotalPriceSet ? fromGraphQL.money(node.subtotalPriceSet) : null,
1099
+ currentSubtotalPriceSet: fromGraphQL.money(node.currentSubtotalPriceSet),
1100
+ totalDiscountsSet: node.totalDiscountsSet ? fromGraphQL.money(node.totalDiscountsSet) : null,
1101
+ currentTotalDiscountsSet: fromGraphQL.money(node.currentTotalDiscountsSet),
1102
+ totalShippingPriceSet: fromGraphQL.money(node.totalShippingPriceSet),
1103
+ currentShippingPriceSet: fromGraphQL.money(node.currentShippingPriceSet),
1104
+ totalTaxSet: node.totalTaxSet ? fromGraphQL.money(node.totalTaxSet) : null,
1105
+ currentTotalTaxSet: fromGraphQL.money(node.currentTotalTaxSet),
1106
+ originalTotalDutiesSet: node.originalTotalDutiesSet ? fromGraphQL.money(node.originalTotalDutiesSet) : null,
1107
+ currentTotalDutiesSet: node.currentTotalDutiesSet ? fromGraphQL.money(node.currentTotalDutiesSet) : null,
1108
+ totalPriceSet: fromGraphQL.money(node.totalPriceSet),
1109
+ currentTotalPriceSet: fromGraphQL.money(node.currentTotalPriceSet),
1110
+ taxLines: node.taxLines.map(fromGraphQL.taxLine),
1111
+ shippingLines: nested.shippingLines.map((line) => ({
1112
+ id: line.id,
1113
+ title: line.title,
1114
+ code: line.code,
1115
+ source: line.source,
1116
+ carrierIdentifier: line.carrierIdentifier,
1117
+ phone: line.phone,
1118
+ isRemoved: line.isRemoved,
1119
+ originalPriceSet: fromGraphQL.money(line.originalPriceSet),
1120
+ discountedPriceSet: fromGraphQL.money(line.discountedPriceSet),
1121
+ currentDiscountedPriceSet: fromGraphQL.money(line.currentDiscountedPriceSet),
1122
+ taxLines: line.taxLines.map(fromGraphQL.taxLine),
1123
+ discountAllocations: line.discountAllocations.map(fromGraphQL.discountAllocation)
1124
+ })),
1125
+ lineItems: nested.lineItems.map((item) => ({
1126
+ id: item.id,
1127
+ name: item.name,
1128
+ title: item.title,
1129
+ variantTitle: item.variantTitle,
1130
+ sku: item.sku,
1131
+ vendor: item.vendor,
1132
+ productId: item.product?.id ?? null,
1133
+ variantId: item.variant?.id ?? null,
1134
+ quantity: item.quantity,
1135
+ currentQuantity: item.currentQuantity,
1136
+ taxable: item.taxable,
1137
+ requiresShipping: item.requiresShipping,
1138
+ isGiftCard: item.isGiftCard,
1139
+ originalUnitPriceSet: fromGraphQL.money(item.originalUnitPriceSet),
1140
+ totalDiscountSet: fromGraphQL.money(item.totalDiscountSet),
1141
+ taxLines: item.taxLines.map(fromGraphQL.taxLine),
1142
+ discountAllocations: item.discountAllocations.map(fromGraphQL.discountAllocation),
1143
+ customAttributes: item.customAttributes
1144
+ }))
1145
+ });
1146
+ const OrdersQuery = pageQuery("AirfoilOrders", "orders", OrderFields);
1147
+ const GraphQLOrdersDataSchema = Schema$1.Struct({ orders: connection(GraphQLOrderNodeSchema) });
1148
+ //#endregion
1149
+ //#region src/resources/products/graphql.ts
1150
+ const ProductVariantFields = `
1151
+ id
1152
+ legacyResourceId
1153
+ title
1154
+ sku
1155
+ barcode
1156
+ price
1157
+ compareAtPrice
1158
+ inventoryPolicy
1159
+ taxable
1160
+ createdAt
1161
+ updatedAt
1162
+ `;
1163
+ const ProductFields = `
1164
+ id
1165
+ legacyResourceId
1166
+ title
1167
+ handle
1168
+ descriptionHtml
1169
+ productType
1170
+ vendor
1171
+ status
1172
+ tags
1173
+ createdAt
1174
+ updatedAt
1175
+ publishedAt
1176
+ templateSuffix
1177
+ featuredMedia { ... on MediaImage { image { url altText } } }
1178
+ options(first: 100) { id name position values }
1179
+ variants(first: 25) { nodes { ${ProductVariantFields} } pageInfo { hasNextPage endCursor } }
1180
+ `;
1181
+ const ProductByIdQuery = `#graphql
1182
+ query AirfoilProductById($id: ID!) {
1183
+ product(id: $id) { ${ProductFields} }
1184
+ }
1185
+ `;
1186
+ const ProductVariantsQuery = `#graphql
1187
+ query AirfoilProductVariants($id: ID!, $first: Int!, $after: String) {
1188
+ node: product(id: $id) {
1189
+ connection: variants(first: $first, after: $after) {
1190
+ nodes { ${ProductVariantFields} }
1191
+ pageInfo { hasNextPage endCursor }
1192
+ }
1193
+ }
1194
+ }
1195
+ `;
1196
+ const ProductsQuery = pageQuery("AirfoilProducts", "products", ProductFields);
1197
+ const GraphQLProductVariantNodeSchema = Schema$1.Struct({
1198
+ id: Schema$1.String,
1199
+ legacyResourceId: Schema$1.String,
1200
+ title: Schema$1.String,
1201
+ sku: Schema$1.NullOr(Schema$1.String),
1202
+ barcode: Schema$1.NullOr(Schema$1.String),
1203
+ price: Schema$1.String,
1204
+ compareAtPrice: Schema$1.NullOr(Schema$1.String),
1205
+ inventoryPolicy: ProductVariantInventoryPolicySchema,
1206
+ taxable: Schema$1.Boolean,
1207
+ createdAt: Schema$1.DateFromString,
1208
+ updatedAt: Schema$1.DateFromString
1209
+ });
1210
+ const GraphQLFeaturedMediaSchema = Schema$1.Struct({ image: Schema$1.optional(Schema$1.NullOr(Schema$1.Struct({
1211
+ url: Schema$1.String,
1212
+ altText: Schema$1.NullOr(Schema$1.String)
1213
+ }))) });
1214
+ const GraphQLProductNodeSchema = Schema$1.Struct({
1215
+ id: Schema$1.String,
1216
+ legacyResourceId: Schema$1.String,
1217
+ title: Schema$1.String,
1218
+ handle: Schema$1.String,
1219
+ descriptionHtml: Schema$1.String,
1220
+ productType: Schema$1.String,
1221
+ vendor: Schema$1.String,
1222
+ status: ProductStatusSchema,
1223
+ tags: Schema$1.Array(Schema$1.String),
1224
+ createdAt: Schema$1.DateFromString,
1225
+ updatedAt: Schema$1.DateFromString,
1226
+ publishedAt: Schema$1.NullOr(Schema$1.DateFromString),
1227
+ templateSuffix: Schema$1.NullOr(Schema$1.String),
1228
+ featuredMedia: Schema$1.NullOr(GraphQLFeaturedMediaSchema),
1229
+ options: Schema$1.Array(ProductOptionSchema),
1230
+ variants: connection(GraphQLProductVariantNodeSchema)
1231
+ });
1232
+ const GraphQLProductsDataSchema = Schema$1.Struct({ products: connection(GraphQLProductNodeSchema) });
1233
+ const GraphQLProductByIdDataSchema = Schema$1.Struct({ product: Schema$1.NullOr(GraphQLProductNodeSchema) });
1234
+ const normalizeProductNode = (node, variants) => ({
1235
+ id: node.id,
1236
+ legacyResourceId: node.legacyResourceId,
1237
+ title: node.title,
1238
+ handle: node.handle,
1239
+ descriptionHtml: node.descriptionHtml,
1240
+ productType: node.productType,
1241
+ vendor: node.vendor,
1242
+ status: node.status,
1243
+ tags: node.tags,
1244
+ createdAt: node.createdAt,
1245
+ updatedAt: node.updatedAt,
1246
+ publishedAt: node.publishedAt,
1247
+ templateSuffix: node.templateSuffix ?? "",
1248
+ featuredMedia: node.featuredMedia === null || node.featuredMedia.image === void 0 ? null : { image: node.featuredMedia.image },
1249
+ options: node.options,
1250
+ variants
1251
+ });
1252
+ //#endregion
1253
+ //#region src/resources/refunds/row.ts
1254
+ const TransactionKindSchema = Schema$1.Literals([
1255
+ "SALE",
1256
+ "CAPTURE",
1257
+ "AUTHORIZATION",
1258
+ "VOID",
1259
+ "REFUND",
1260
+ "CHANGE",
1261
+ "EMV_AUTHORIZATION",
1262
+ "SUGGESTED_REFUND"
1263
+ ]);
1264
+ const TransactionStatusSchema = Schema$1.Literals([
1265
+ "SUCCESS",
1266
+ "FAILURE",
1267
+ "PENDING",
1268
+ "ERROR",
1269
+ "AWAITING_RESPONSE",
1270
+ "UNKNOWN"
1271
+ ]);
1272
+ const RestockTypeSchema = Schema$1.Literals([
1273
+ "RETURN",
1274
+ "CANCEL",
1275
+ "LEGACY_RESTOCK",
1276
+ "NO_RESTOCK"
1277
+ ]);
1278
+ const RefundSchema = Schema$1.Struct({
1279
+ id: Schema$1.String.pipe(field(1, "Unique refund identifier.")),
1280
+ legacyResourceId: Schema$1.String.pipe(field(2, "Numeric refund identifier stored as text.")),
1281
+ orderId: Schema$1.String.pipe(field(3, "Refunded order identifier.")),
1282
+ note: Schema$1.NullOr(Schema$1.String).pipe(field(4, "Refund note.")),
1283
+ createdAt: Schema$1.NullOr(Schema$1.Date).pipe(field(5, "Time when the refund was created.")),
1284
+ processedAt: Schema$1.Date.pipe(field(6, "Time when the refund was processed.")),
1285
+ transactions: Schema$1.Array(Schema$1.Struct({
1286
+ id: Schema$1.String.pipe(field(101, "Unique transaction identifier.")),
1287
+ kind: TransactionKindSchema.pipe(field(102, "Kind of transaction.")),
1288
+ status: TransactionStatusSchema.pipe(field(103, "Status reported for the transaction.")),
1289
+ amount: Schema$1.String.pipe(field(104, "Amount in the customer currency.")),
1290
+ currencyCode: Schema$1.String.pipe(field(105, "Customer currency code.")),
1291
+ gateway: Schema$1.NullOr(Schema$1.String).pipe(field(106, "Payment gateway.")),
1292
+ test: Schema$1.Boolean.pipe(field(107, "Whether the transaction is a test.")),
1293
+ errorCode: Schema$1.NullOr(Schema$1.String).pipe(field(108, "Gateway error code.")),
1294
+ parentTransactionId: Schema$1.NullOr(Schema$1.String).pipe(field(109, "Transaction this one refunds.")),
1295
+ createdAt: Schema$1.Date.pipe(field(110, "Time when the transaction was created.")),
1296
+ processedAt: Schema$1.NullOr(Schema$1.Date).pipe(field(111, "Time when the transaction was processed."))
1297
+ }).annotate({ fieldId: 100 })).pipe(field(7, "Transactions that move the refunded money.")),
1298
+ refundLineItems: Schema$1.Array(Schema$1.Struct({
1299
+ id: Schema$1.NullOr(Schema$1.String).pipe(field(201, "Unique refund line item identifier.")),
1300
+ lineItemId: Schema$1.String.pipe(field(202, "Refunded order line item identifier.")),
1301
+ quantity: Schema$1.Int.pipe(field(203, "Quantity refunded.")),
1302
+ restockType: RestockTypeSchema.pipe(field(204, "How the items were restocked.")),
1303
+ locationId: Schema$1.NullOr(Schema$1.String).pipe(field(205, "Restock location identifier.")),
1304
+ subtotalSet: moneyBag(210).pipe(field(206, "Refunded subtotal.")),
1305
+ totalTaxSet: moneyBag(220).pipe(field(207, "Refunded tax."))
1306
+ }).annotate({ fieldId: 200 })).pipe(field(8, "Refunded order line items.")),
1307
+ refundShippingLines: Schema$1.Array(Schema$1.Struct({
1308
+ id: Schema$1.String.pipe(field(301, "Unique refund shipping line identifier.")),
1309
+ shippingLineId: Schema$1.NullOr(Schema$1.String).pipe(field(302, "Refunded shipping line.")),
1310
+ subtotalAmountSet: moneyBag(310).pipe(field(303, "Refunded shipping amount."))
1311
+ }).annotate({ fieldId: 300 })).pipe(field(9, "Refunded shipping.")),
1312
+ orderAdjustments: Schema$1.Array(Schema$1.Struct({
1313
+ id: Schema$1.String.pipe(field(401, "Unique order adjustment identifier.")),
1314
+ reason: Schema$1.NullOr(Schema$1.String).pipe(field(402, "Reason for the adjustment.")),
1315
+ amountSet: moneyBag(410).pipe(field(403, "Adjustment amount.")),
1316
+ taxAmountSet: moneyBag(420).pipe(field(404, "Tax on the adjustment."))
1317
+ }).annotate({ fieldId: 400 })).pipe(field(10, "Refund discrepancy adjustments.")),
1318
+ duties: Schema$1.Array(Schema$1.Struct({
1319
+ dutyId: Schema$1.NullOr(Schema$1.String).pipe(field(501, "Refunded duty identifier.")),
1320
+ amountSet: moneyBag(510).pipe(field(502, "Refunded duty amount."))
1321
+ }).annotate({ fieldId: 500 })).pipe(field(11, "Refunded duties."))
1322
+ }).annotate({ description: "Refunds on orders in a Shopify store." }).pipe(Iceberg.identifier("id"));
1323
+ //#endregion
1324
+ //#region src/resources/refunds/graphql.ts
1325
+ const TransactionFields = `id kind status gateway test errorCode parentTransaction { id } createdAt processedAt amountSet { ${MoneyBagFields} }`;
1326
+ const RefundLineItemFields = `id lineItem { id } quantity restockType location { id } subtotalSet { ${MoneyBagFields} } totalTaxSet { ${MoneyBagFields} }`;
1327
+ const RefundShippingLineFields = `id shippingLine { id } subtotalAmountSet { ${MoneyBagFields} }`;
1328
+ const OrderAdjustmentFields = `id reason amountSet { ${MoneyBagFields} } taxAmountSet { ${MoneyBagFields} }`;
1329
+ const RefundFields = `
1330
+ id
1331
+ legacyResourceId
1332
+ note
1333
+ createdAt
1334
+ processedAt
1335
+ duties { originalDuty { id } amountSet { ${MoneyBagFields} } }
1336
+ transactions(first: 10) { nodes { ${TransactionFields} } ${PageInfoFields} }
1337
+ refundLineItems(first: 50) { nodes { ${RefundLineItemFields} } ${PageInfoFields} }
1338
+ refundShippingLines(first: 10) { nodes { ${RefundShippingLineFields} } ${PageInfoFields} }
1339
+ orderAdjustments(first: 10) { nodes { ${OrderAdjustmentFields} } ${PageInfoFields} }
1340
+ `;
1341
+ const refundConnectionQuery = (name, selection) => `#graphql
1342
+ query ${name}($id: ID!, $first: Int!, $after: String) {
1343
+ node: refund(id: $id) {
1344
+ connection: ${selection}
1345
+ }
1346
+ }
1347
+ `;
1348
+ const RefundTransactionsQuery = refundConnectionQuery("AirfoilRefundTransactions", `transactions(first: $first, after: $after) { nodes { ${TransactionFields} } ${PageInfoFields} }`);
1349
+ const RefundLineItemsQuery = refundConnectionQuery("AirfoilRefundLineItems", `refundLineItems(first: $first, after: $after) { nodes { ${RefundLineItemFields} } ${PageInfoFields} }`);
1350
+ const RefundShippingLinesQuery = refundConnectionQuery("AirfoilRefundShippingLines", `refundShippingLines(first: $first, after: $after) { nodes { ${RefundShippingLineFields} } ${PageInfoFields} }`);
1351
+ const RefundOrderAdjustmentsQuery = refundConnectionQuery("AirfoilRefundOrderAdjustments", `orderAdjustments(first: $first, after: $after) { nodes { ${OrderAdjustmentFields} } ${PageInfoFields} }`);
1352
+ const GraphQLRefundTransactionsSchema = connection(Schema$1.Struct({
1353
+ id: Schema$1.String,
1354
+ kind: TransactionKindSchema,
1355
+ status: TransactionStatusSchema,
1356
+ gateway: Schema$1.NullOr(Schema$1.String),
1357
+ test: Schema$1.Boolean,
1358
+ errorCode: Schema$1.NullOr(Schema$1.String),
1359
+ parentTransaction: idRef,
1360
+ createdAt: Schema$1.DateFromString,
1361
+ processedAt: Schema$1.NullOr(Schema$1.DateFromString),
1362
+ amountSet: GraphQLMoneyBagSchema
1363
+ }));
1364
+ const GraphQLRefundLineItemsSchema = connection(Schema$1.Struct({
1365
+ id: Schema$1.NullOr(Schema$1.String),
1366
+ lineItem: Schema$1.Struct({ id: Schema$1.String }),
1367
+ quantity: Schema$1.Int,
1368
+ restockType: RestockTypeSchema,
1369
+ location: idRef,
1370
+ subtotalSet: GraphQLMoneyBagSchema,
1371
+ totalTaxSet: GraphQLMoneyBagSchema
1372
+ }));
1373
+ const GraphQLRefundShippingLinesSchema = connection(Schema$1.Struct({
1374
+ id: Schema$1.String,
1375
+ shippingLine: idRef,
1376
+ subtotalAmountSet: GraphQLMoneyBagSchema
1377
+ }));
1378
+ const GraphQLOrderAdjustmentsSchema = connection(Schema$1.Struct({
1379
+ id: Schema$1.String,
1380
+ reason: Schema$1.NullOr(Schema$1.String),
1381
+ amountSet: GraphQLMoneyBagSchema,
1382
+ taxAmountSet: GraphQLMoneyBagSchema
1383
+ }));
1384
+ const GraphQLRefundNodeSchema = Schema$1.Struct({
1385
+ id: Schema$1.String,
1386
+ legacyResourceId: Schema$1.String,
1387
+ note: Schema$1.NullOr(Schema$1.String),
1388
+ createdAt: Schema$1.NullOr(Schema$1.DateFromString),
1389
+ processedAt: Schema$1.DateFromString,
1390
+ duties: Schema$1.NullOr(Schema$1.Array(Schema$1.Struct({
1391
+ originalDuty: idRef,
1392
+ amountSet: GraphQLMoneyBagSchema
1393
+ }))),
1394
+ transactions: GraphQLRefundTransactionsSchema,
1395
+ refundLineItems: GraphQLRefundLineItemsSchema,
1396
+ refundShippingLines: GraphQLRefundShippingLinesSchema,
1397
+ orderAdjustments: GraphQLOrderAdjustmentsSchema
1398
+ });
1399
+ const fromRefundNode = (orderId, node, nested) => ({
1400
+ id: node.id,
1401
+ legacyResourceId: node.legacyResourceId,
1402
+ orderId,
1403
+ note: node.note ?? "",
1404
+ createdAt: node.createdAt,
1405
+ processedAt: node.processedAt,
1406
+ transactions: nested.transactions.map((transaction) => ({
1407
+ id: transaction.id,
1408
+ kind: transaction.kind,
1409
+ status: transaction.status,
1410
+ amount: normalizeAmount(transaction.amountSet.presentmentMoney.amount),
1411
+ currencyCode: transaction.amountSet.presentmentMoney.currencyCode,
1412
+ gateway: transaction.gateway,
1413
+ test: transaction.test,
1414
+ errorCode: transaction.errorCode,
1415
+ parentTransactionId: transaction.parentTransaction?.id ?? null,
1416
+ createdAt: transaction.createdAt,
1417
+ processedAt: transaction.processedAt
1418
+ })),
1419
+ refundLineItems: nested.refundLineItems.map((item) => ({
1420
+ id: item.id,
1421
+ lineItemId: item.lineItem.id,
1422
+ quantity: item.quantity,
1423
+ restockType: item.restockType,
1424
+ locationId: item.location?.id ?? null,
1425
+ subtotalSet: fromGraphQL.money(item.subtotalSet),
1426
+ totalTaxSet: fromGraphQL.money(item.totalTaxSet)
1427
+ })),
1428
+ refundShippingLines: nested.refundShippingLines.map((line) => ({
1429
+ id: line.id,
1430
+ shippingLineId: line.shippingLine?.id ?? null,
1431
+ subtotalAmountSet: fromGraphQL.money(line.subtotalAmountSet)
1432
+ })),
1433
+ orderAdjustments: nested.orderAdjustments.map((adjustment) => ({
1434
+ id: adjustment.id,
1435
+ reason: adjustment.reason,
1436
+ amountSet: fromGraphQL.money(adjustment.amountSet),
1437
+ taxAmountSet: fromGraphQL.money(adjustment.taxAmountSet)
1438
+ })),
1439
+ duties: (node.duties ?? []).map((duty) => ({
1440
+ dutyId: duty.originalDuty?.id ?? null,
1441
+ amountSet: fromGraphQL.money(duty.amountSet)
1442
+ }))
1443
+ });
1444
+ const OrderRefundsQuery = pageQuery("AirfoilOrderRefunds", "orders", `id refunds { ${RefundFields} }`);
1445
+ const GraphQLOrderRefundsDataSchema = Schema$1.Struct({ orders: connection(Schema$1.Struct({
1446
+ id: Schema$1.String,
1447
+ refunds: Schema$1.Array(GraphQLRefundNodeSchema)
1448
+ })) });
1449
+ //#endregion
1450
+ //#region src/api/auth.ts
1451
+ var ShopifyAuthError = class extends Data.TaggedError("ShopifyAuthError") {};
1452
+ var ShopifyAuth = class extends Context.Service()("@useairfoil/producer-shopify/ShopifyAuth") {};
1453
+ const TokenResponseSchema = Schema.Struct({
1454
+ access_token: Schema.String,
1455
+ expires_in: Schema.Number
1456
+ });
1457
+ const ErrorResponseSchema = Schema.Struct({ error: Schema.Literals(["shop_not_permitted", "invalid_client"]) });
1458
+ const shopUrl = (shopDomain) => `https://${shopDomain.replace(/^https?:\/\//i, "").replace(/\/+$/g, "")}`;
1459
+ const errorMessages = {
1460
+ shop_not_permitted: "The Shopify app and store must belong to the same Shopify organization",
1461
+ invalid_client: "The Shopify client ID or client secret is invalid",
1462
+ exchange_failed: "Shopify authentication failed"
1463
+ };
1464
+ const errorFor = (reason) => new ShopifyAuthError({
1465
+ reason,
1466
+ message: errorMessages[reason]
1467
+ });
1468
+ const decodeRejectedResponse = (response) => HttpClientResponse.schemaBodyJson(ErrorResponseSchema)(response).pipe(Effect.map((body) => body.error), Effect.catch(() => Effect.succeed("exchange_failed")));
1469
+ const make$3 = Effect.fnUntraced(function* (config) {
1470
+ const client = yield* HttpClient.HttpClient;
1471
+ const endpoint = `${shopUrl(config.shopDomain)}/admin/oauth/access_token`;
1472
+ return yield* Auth.makeTokenCache({ acquire: Effect.scoped(Effect.gen(function* () {
1473
+ const request = HttpClientRequest.post(endpoint).pipe(HttpClientRequest.bodyUrlParams({
1474
+ grant_type: "client_credentials",
1475
+ client_id: config.clientId,
1476
+ client_secret: Redacted.value(config.clientSecret)
1477
+ }));
1478
+ const response = yield* client.execute(request).pipe(Effect.mapError(() => errorFor("exchange_failed")));
1479
+ const successfulResponse = yield* HttpClientResponse.filterStatusOk(response).pipe(Effect.catchTag("HttpClientError", () => decodeRejectedResponse(response).pipe(Effect.flatMap((reason) => Effect.fail(errorFor(reason))))));
1480
+ const body = yield* HttpClientResponse.schemaBodyJson(TokenResponseSchema)(successfulResponse).pipe(Effect.mapError(() => errorFor("exchange_failed")));
1481
+ return {
1482
+ value: Redacted.make(body.access_token),
1483
+ expiresIn: Duration.seconds(body.expires_in)
1484
+ };
1485
+ })) });
1486
+ });
1487
+ const layer$2 = (config) => Layer.effect(ShopifyAuth)(make$3(config));
1488
+ //#endregion
1489
+ //#region src/api/http.ts
1490
+ const isResponse = (value) => Predicate.hasProperty(value, HttpClientResponse.TypeId);
1491
+ const retrySchedule = (options) => Metrics.retrySchedule({
1492
+ connector: manifest.name,
1493
+ baseDelay: options.baseDelay,
1494
+ times: options.maxRetries
1495
+ }).pipe(Schedule.modifyDelay(({ input, duration }) => {
1496
+ if (!isResponse(input) || input.status !== 429) return Effect.succeed(duration);
1497
+ const seconds = Number(input.headers["retry-after"]);
1498
+ return Effect.succeed(Number.isFinite(seconds) ? Duration.seconds(seconds) : duration);
1499
+ }));
1500
+ //#endregion
1501
+ //#region src/api/graphql.ts
1502
+ const SHOPIFY_API_VERSION = "2026-07";
1503
+ const maxRetries = 5;
1504
+ const retryBaseDelay = Duration.millis(500);
1505
+ const requestTimeout = Duration.minutes(2);
1506
+ const ThrottleStatusSchema = Schema.Struct({
1507
+ maximumAvailable: Schema.Number,
1508
+ currentlyAvailable: Schema.Number,
1509
+ restoreRate: Schema.Number
1510
+ });
1511
+ const GraphQLResponseSchema = Schema.Struct({
1512
+ data: Schema.optional(Schema.Unknown),
1513
+ errors: Schema.optional(Schema.Array(Schema.Struct({ extensions: Schema.optional(Schema.Struct({ code: Schema.optional(Schema.String) })) }))),
1514
+ extensions: Schema.optional(Schema.Struct({ cost: Schema.optional(Schema.Struct({
1515
+ requestedQueryCost: Schema.optional(Schema.Number),
1516
+ throttleStatus: Schema.optional(ThrottleStatusSchema)
1517
+ })) }))
1518
+ });
1519
+ const retryableCodes = ["THROTTLED", "INTERNAL_SERVER_ERROR"];
1520
+ /** How long Shopify needs to restore the query's cost, when it says so. */
1521
+ const throttleWait = (response) => {
1522
+ const cost = response.extensions?.cost;
1523
+ const status = cost?.throttleStatus;
1524
+ if (cost?.requestedQueryCost === void 0 || status === void 0) return Option.none();
1525
+ const deficit = cost.requestedQueryCost - status.currentlyAvailable;
1526
+ return Option.some(Duration.millis(Math.ceil(deficit / status.restoreRate * 1e3)));
1527
+ };
1528
+ var Retryable = class extends Data.TaggedError("Retryable") {};
1529
+ const make$2 = Effect.fnUntraced(function* (config) {
1530
+ const auth = yield* ShopifyAuth;
1531
+ const client = (yield* HttpClient.HttpClient).pipe(HttpClient.mapRequestEffect((request) => auth.get.pipe(Effect.map((token) => HttpClientRequest.setHeader(request, "X-Shopify-Access-Token", Redacted.value(token))))), HttpClient.mapRequest(HttpClientRequest.acceptJson), HttpClient.retryTransient({ schedule: retrySchedule({
1532
+ maxRetries,
1533
+ baseDelay: retryBaseDelay
1534
+ }) }));
1535
+ const endpoint = `${shopUrl(config.shopDomain)}/admin/api/${SHOPIFY_API_VERSION}/graphql.json`;
1536
+ const graphqlRetrySchedule = Schedule.exponential(retryBaseDelay).pipe(Schedule.jittered, Schedule.upTo({ times: maxRetries }), Schedule.modifyDelay(({ input, duration }) => Effect.succeed(input instanceof Retryable ? Option.match(input.wait, {
1537
+ onNone: () => duration,
1538
+ onSome: (wait) => Duration.max(wait, retryBaseDelay)
1539
+ }) : duration)));
1540
+ const fetchGraphQL = (options) => {
1541
+ const fail = (message, cause, annotation) => Effect.logWarning(message).pipe(Effect.annotateLogs({
1542
+ operationName: options.operationName,
1543
+ body: JSON.stringify(cause)
1544
+ }), Effect.andThen(Telemetry.annotateError(annotation, cause)), Effect.andThen(Effect.fail(new ConnectorError({
1545
+ message,
1546
+ cause
1547
+ }))));
1548
+ const decodeError = (error) => Telemetry.annotateError("api_decode", error).pipe(Effect.andThen(Effect.fail(new ConnectorError({
1549
+ message: "Shopify GraphQL response schema decode failed",
1550
+ cause: error
1551
+ }))));
1552
+ return Effect.gen(function* () {
1553
+ const request = HttpClientRequest.post(endpoint).pipe(HttpClientRequest.bodyJsonUnsafe({
1554
+ query: options.query,
1555
+ variables: options.variables ?? {}
1556
+ }));
1557
+ const response = yield* client.execute(request).pipe(Effect.tapError((error) => Telemetry.annotateError("api_http", error)), Effect.mapError((error) => error._tag === "ShopifyAuthError" ? new ConnectorError({
1558
+ message: error.message,
1559
+ cause: error
1560
+ }) : new ConnectorError({
1561
+ message: "Shopify GraphQL request failed",
1562
+ cause: error
1563
+ })));
1564
+ const body = yield* response.json.pipe(Effect.tapError((error) => Telemetry.annotateError("api_json", error)), Effect.mapError((error) => new ConnectorError({
1565
+ message: "Shopify GraphQL returned invalid JSON",
1566
+ cause: error
1567
+ })));
1568
+ if (response.status < 200 || response.status >= 300) return yield* fail("Shopify GraphQL returned non-2xx status", {
1569
+ status: response.status,
1570
+ body,
1571
+ operationName: options.operationName
1572
+ }, "api_status");
1573
+ const graphql = yield* Schema.decodeUnknownEffect(GraphQLResponseSchema)(body).pipe(Effect.catch(decodeError));
1574
+ if (graphql.errors !== void 0 && graphql.errors.length > 0) {
1575
+ const codes = graphql.errors.map((error) => error.extensions?.code);
1576
+ const code = retryableCodes.find((retryable) => codes.includes(retryable));
1577
+ if (code !== void 0) return yield* new Retryable({
1578
+ code,
1579
+ wait: code === "THROTTLED" ? throttleWait(graphql) : Option.none(),
1580
+ body
1581
+ });
1582
+ return yield* fail("Shopify GraphQL returned errors", body, "api_graphql");
1583
+ }
1584
+ return yield* Schema.decodeUnknownEffect(options.schema)(graphql.data).pipe(Effect.catch(decodeError));
1585
+ }).pipe(Effect.withSpan(Telemetry.SpanName.apiFetch, {
1586
+ kind: "client",
1587
+ attributes: { [Telemetry.Attr.apiPath]: `graphql:${options.operationName}` }
1588
+ })).pipe(Effect.retry({
1589
+ schedule: graphqlRetrySchedule.pipe(Schedule.tap(({ input, duration }) => input instanceof Retryable ? Effect.logWarning("Shopify GraphQL request returned a retryable error, retrying").pipe(Effect.annotateLogs({
1590
+ operationName: options.operationName,
1591
+ code: input.code,
1592
+ waitMillis: Duration.toMillis(duration)
1593
+ }), Effect.andThen(Metrics.recordApiRetry({
1594
+ connector: manifest.name,
1595
+ reason: input.code === "THROTTLED" ? "rate_limit" : "server_error"
1596
+ }))) : Effect.void)),
1597
+ while: (error) => error._tag === "Retryable"
1598
+ }), Effect.catchTag("Retryable", (error) => fail("Shopify GraphQL returned errors", error.body, "api_graphql"))).pipe(Effect.timeoutOrElse({
1599
+ duration: requestTimeout,
1600
+ orElse: () => Effect.fail(new ConnectorError({ message: "Shopify GraphQL request timed out" }))
1601
+ }));
1602
+ };
1603
+ return fetchGraphQL;
1604
+ });
1605
+ //#endregion
1606
+ //#region src/api/client.ts
1607
+ var client_exports = /* @__PURE__ */ __exportAll({
1608
+ ShopifyApiClient: () => ShopifyApiClient,
1609
+ layer: () => layer$1,
1610
+ layerConfig: () => layerConfig$1,
1611
+ make: () => make$1
1612
+ });
1613
+ var ShopifyApiClient = class extends Context.Service()("@useairfoil/producer-shopify/ShopifyApiClient") {};
1614
+ const CustomersAccessQuery = `#graphql
1615
+ query AirfoilCustomersAccess {
1616
+ customers(first: 1) {
1617
+ nodes {
1618
+ id
1619
+ defaultEmailAddress { emailAddress }
1620
+ defaultPhoneNumber { phoneNumber }
1621
+ defaultAddress { address1 }
1622
+ }
1623
+ }
1624
+ }
1625
+ `;
1626
+ const OrdersAccessQuery = `#graphql
1627
+ query AirfoilOrdersAccess {
1628
+ orders(first: 1) {
1629
+ nodes {
1630
+ id
1631
+ email
1632
+ phone
1633
+ shippingAddress { address1 }
1634
+ }
1635
+ }
1636
+ }
1637
+ `;
1638
+ const ProductsAccessQuery = `#graphql
1639
+ query AirfoilProductsAccess {
1640
+ products(first: 1) {
1641
+ nodes {
1642
+ id
1643
+ }
1644
+ }
1645
+ }
1646
+ `;
1647
+ const ShopIdentityQuery = `#graphql
1648
+ query AirfoilShopIdentity {
1649
+ shop {
1650
+ id
1651
+ }
1652
+ }
1653
+ `;
1654
+ const ShopIdentitySchema = Schema.Struct({ shop: Schema.Struct({ id: Schema.String }) });
1655
+ const ProductsAccessSchema = Schema.Struct({ products: Schema.Struct({ nodes: Schema.Array(Schema.Struct({ id: Schema.String })) }) });
1656
+ const OrdersAccessSchema = Schema.Struct({ orders: Schema.Struct({ nodes: Schema.Array(Schema.Struct({ id: Schema.String })) }) });
1657
+ const CustomersAccessSchema = Schema.Struct({ customers: Schema.Struct({ nodes: Schema.Array(Schema.Struct({ id: Schema.String })) }) });
1658
+ const nestedPageSchema = (connection) => Schema.Struct({ node: Schema.NullOr(Schema.Struct({ connection })) });
1659
+ const make$1 = Effect.fnUntraced(function* (config) {
1660
+ const fetchGraphQL = yield* make$2(config);
1661
+ const nextPageCursor = (pageInfo) => pageInfo.hasNextPage ? Option.fromNullishOr(pageInfo.endCursor) : Option.none();
1662
+ const fetchProductById = (id) => fetchGraphQL({
1663
+ operationName: "AirfoilProductById",
1664
+ query: ProductByIdQuery,
1665
+ variables: { id },
1666
+ schema: GraphQLProductByIdDataSchema
1667
+ }).pipe(Effect.flatMap((data) => {
1668
+ const node = data.product;
1669
+ if (node === null) return Effect.succeed(Option.none());
1670
+ return loadProduct(node).pipe(Effect.map(Option.some));
1671
+ }));
1672
+ const followConnection = (first, options) => Option.match(nextPageCursor(first.pageInfo), {
1673
+ onNone: () => Effect.succeed(first.nodes),
1674
+ onSome: (initialCursor) => Stream.paginate(initialCursor, (after) => fetchGraphQL({
1675
+ operationName: options.operationName,
1676
+ query: options.query,
1677
+ variables: {
1678
+ id: options.id,
1679
+ first: 100,
1680
+ after
1681
+ },
1682
+ schema: options.schema
1683
+ }).pipe(Effect.flatMap(({ node }) => node === null ? Effect.fail(new ConnectorError({ message: `Shopify record disappeared during ${options.operationName}` })) : Effect.succeed([node.connection.nodes, nextPageCursor(node.connection.pageInfo)])))).pipe(Stream.runCollect, Effect.map((rest) => [...first.nodes, ...rest]))
1684
+ });
1685
+ const loadOrder = (node) => Effect.all({
1686
+ discountApplications: followConnection(node.discountApplications, {
1687
+ id: node.id,
1688
+ operationName: "AirfoilOrderDiscountApplications",
1689
+ query: OrderDiscountApplicationsQuery,
1690
+ schema: nestedPageSchema(GraphQLDiscountApplicationsSchema)
1691
+ }),
1692
+ shippingLines: followConnection(node.shippingLines, {
1693
+ id: node.id,
1694
+ operationName: "AirfoilOrderShippingLines",
1695
+ query: OrderShippingLinesQuery,
1696
+ schema: nestedPageSchema(GraphQLShippingLinesSchema)
1697
+ }),
1698
+ lineItems: followConnection(node.lineItems, {
1699
+ id: node.id,
1700
+ operationName: "AirfoilOrderLineItems",
1701
+ query: OrderLineItemsQuery,
1702
+ schema: nestedPageSchema(GraphQLLineItemsSchema)
1703
+ })
1704
+ }).pipe(Effect.map((nested) => fromOrderNode(node, nested)));
1705
+ const loadRefund = (orderId, node) => Effect.all({
1706
+ transactions: followConnection(node.transactions, {
1707
+ id: node.id,
1708
+ operationName: "AirfoilRefundTransactions",
1709
+ query: RefundTransactionsQuery,
1710
+ schema: nestedPageSchema(GraphQLRefundTransactionsSchema)
1711
+ }),
1712
+ refundLineItems: followConnection(node.refundLineItems, {
1713
+ id: node.id,
1714
+ operationName: "AirfoilRefundLineItems",
1715
+ query: RefundLineItemsQuery,
1716
+ schema: nestedPageSchema(GraphQLRefundLineItemsSchema)
1717
+ }),
1718
+ refundShippingLines: followConnection(node.refundShippingLines, {
1719
+ id: node.id,
1720
+ operationName: "AirfoilRefundShippingLines",
1721
+ query: RefundShippingLinesQuery,
1722
+ schema: nestedPageSchema(GraphQLRefundShippingLinesSchema)
1723
+ }),
1724
+ orderAdjustments: followConnection(node.orderAdjustments, {
1725
+ id: node.id,
1726
+ operationName: "AirfoilRefundOrderAdjustments",
1727
+ query: RefundOrderAdjustmentsQuery,
1728
+ schema: nestedPageSchema(GraphQLOrderAdjustmentsSchema)
1729
+ })
1730
+ }).pipe(Effect.map((nested) => fromRefundNode(orderId, node, nested)));
1731
+ const loadCustomer = (node) => followConnection(node.addressesV2, {
1732
+ id: node.id,
1733
+ operationName: "AirfoilCustomerAddresses",
1734
+ query: CustomerAddressesQuery,
1735
+ schema: nestedPageSchema(GraphQLCustomerAddressesSchema)
1736
+ }).pipe(Effect.map((addresses) => normalizeCustomerNode(node, addresses)));
1737
+ const loadProduct = (node) => followConnection(node.variants, {
1738
+ id: node.id,
1739
+ operationName: "AirfoilProductVariants",
1740
+ query: ProductVariantsQuery,
1741
+ schema: nestedPageSchema(connection(GraphQLProductVariantNodeSchema))
1742
+ }).pipe(Effect.map((variants) => normalizeProductNode(node, variants)));
1743
+ const toPage = (pageInfo, items) => items.pipe(Effect.map((loaded) => ({
1744
+ items: loaded,
1745
+ endCursor: pageInfo.endCursor,
1746
+ hasMore: pageInfo.hasNextPage
1747
+ })));
1748
+ const fetchProducts = (options) => fetchGraphQL({
1749
+ operationName: "AirfoilProducts",
1750
+ query: ProductsQuery,
1751
+ variables: {
1752
+ first: options.first,
1753
+ after: options.after ?? null
1754
+ },
1755
+ schema: GraphQLProductsDataSchema
1756
+ }).pipe(Effect.flatMap(({ products }) => toPage(products.pageInfo, Effect.forEach(products.nodes, loadProduct))));
1757
+ const fetchOrders = (options) => fetchGraphQL({
1758
+ operationName: "AirfoilOrders",
1759
+ query: OrdersQuery,
1760
+ variables: {
1761
+ first: options.first,
1762
+ after: options.after ?? null
1763
+ },
1764
+ schema: GraphQLOrdersDataSchema
1765
+ }).pipe(Effect.flatMap(({ orders }) => toPage(orders.pageInfo, Effect.forEach(orders.nodes, loadOrder))));
1766
+ const fetchRefunds = (options) => fetchGraphQL({
1767
+ operationName: "AirfoilOrderRefunds",
1768
+ query: OrderRefundsQuery,
1769
+ variables: {
1770
+ first: options.first,
1771
+ after: options.after ?? null
1772
+ },
1773
+ schema: GraphQLOrderRefundsDataSchema
1774
+ }).pipe(Effect.flatMap(({ orders }) => toPage(orders.pageInfo, Effect.forEach(orders.nodes, (order) => Effect.forEach(order.refunds, (refund) => loadRefund(order.id, refund))).pipe(Effect.map((refunds) => refunds.flat())))));
1775
+ const fetchCustomers = (options) => fetchGraphQL({
1776
+ operationName: "AirfoilCustomers",
1777
+ query: CustomersQuery,
1778
+ variables: {
1779
+ first: options.first,
1780
+ after: options.after ?? null
1781
+ },
1782
+ schema: GraphQLCustomersDataSchema
1783
+ }).pipe(Effect.flatMap(({ customers }) => toPage(customers.pageInfo, Effect.forEach(customers.nodes, loadCustomer))));
1784
+ const fetchCustomerById = (id) => fetchGraphQL({
1785
+ operationName: "AirfoilCustomerById",
1786
+ query: CustomerByIdQuery,
1787
+ variables: { id },
1788
+ schema: GraphQLCustomerByIdDataSchema
1789
+ }).pipe(Effect.flatMap(({ customer }) => customer === null ? Effect.succeed(Option.none()) : loadCustomer(customer).pipe(Effect.map(Option.some))));
1790
+ const checkCustomersAccess = fetchGraphQL({
1791
+ operationName: "AirfoilCustomersAccess",
1792
+ query: CustomersAccessQuery,
1793
+ schema: CustomersAccessSchema
1794
+ }).pipe(Effect.asVoid);
1795
+ const checkOrdersAccess = fetchGraphQL({
1796
+ operationName: "AirfoilOrdersAccess",
1797
+ query: OrdersAccessQuery,
1798
+ schema: OrdersAccessSchema
1799
+ }).pipe(Effect.asVoid);
1800
+ return {
1801
+ checkConnection: fetchGraphQL({
1802
+ operationName: "AirfoilShopIdentity",
1803
+ query: ShopIdentityQuery,
1804
+ schema: ShopIdentitySchema
1805
+ }).pipe(Effect.asVoid),
1806
+ checkProductsAccess: fetchGraphQL({
1807
+ operationName: "AirfoilProductsAccess",
1808
+ query: ProductsAccessQuery,
1809
+ schema: ProductsAccessSchema
1810
+ }).pipe(Effect.asVoid),
1811
+ checkOrdersAccess,
1812
+ checkCustomersAccess,
1813
+ fetchGraphQL,
1814
+ fetchProducts,
1815
+ fetchProductById,
1816
+ fetchOrders,
1817
+ fetchRefunds,
1818
+ fetchCustomers,
1819
+ fetchCustomerById
1820
+ };
1821
+ });
1822
+ const layer$1 = (config) => Layer.effect(ShopifyApiClient)(make$1(config));
1823
+ const layerConfig$1 = (config) => Layer.effect(ShopifyApiClient)(Config.unwrap(config).pipe(Effect.flatMap(make$1)));
1824
+ //#endregion
1825
+ //#region src/resources/carts/row.ts
1826
+ const CartLineItemSchema = Schema$1.Struct({
1827
+ id: Schema$1.String.pipe(field(102, "Unique cart line identifier.")),
1828
+ properties: Schema$1.NullOr(Schema$1.String).pipe(field(103, "Custom line properties stored as JSON.")),
1829
+ quantity: Schema$1.Int.pipe(field(104, "Quantity of the cart line.")),
1830
+ variantId: Schema$1.String.pipe(field(105, "Product variant identifier.")),
1831
+ key: Schema$1.String.pipe(field(106, "Unique key for the cart line.")),
1832
+ discountedPrice: Schema$1.String.pipe(field(107, "Price after discounts.")),
1833
+ discounts: Schema$1.String.pipe(field(108, "Line discounts stored as JSON.")),
1834
+ giftCard: Schema$1.Boolean.pipe(field(109, "Whether the line is a gift card.")),
1835
+ grams: Schema$1.Int.pipe(field(110, "Weight of the line in grams.")),
1836
+ linePrice: Schema$1.String.pipe(field(111, "Total price for the line.")),
1837
+ originalLinePrice: Schema$1.String.pipe(field(112, "Line price before discounts.")),
1838
+ originalPrice: Schema$1.String.pipe(field(113, "Unit price before discounts.")),
1839
+ price: Schema$1.String.pipe(field(114, "Current unit price.")),
1840
+ productId: Schema$1.String.pipe(field(115, "Product identifier.")),
1841
+ sku: Schema$1.NullOr(Schema$1.String).pipe(field(116, "Stock keeping unit for the line.")),
1842
+ taxable: Schema$1.Boolean.pipe(field(117, "Whether the line is taxable.")),
1843
+ title: Schema$1.String.pipe(field(118, "Title of the cart line.")),
1844
+ totalDiscount: Schema$1.String.pipe(field(119, "Total discount for the line.")),
1845
+ vendor: Schema$1.String.pipe(field(120, "Vendor of the product.")),
1846
+ discountedPriceSet: moneyBag(200).pipe(field(121, "Price after discounts.")),
1847
+ linePriceSet: moneyBag(210).pipe(field(122, "Total price for the line.")),
1848
+ originalLinePriceSet: moneyBag(220).pipe(field(123, "Line price before discounts.")),
1849
+ priceSet: moneyBag(230).pipe(field(124, "Current unit price.")),
1850
+ totalDiscountSet: moneyBag(240).pipe(field(125, "Total discount for the line.")),
1851
+ parentRelationship: Schema$1.NullOr(Schema$1.String).pipe(field(126, "Parent relationship stored as JSON."))
1852
+ });
1853
+ const CartSchema = Schema$1.Struct({
1854
+ id: Schema$1.String.pipe(field(1, "Unique cart identifier.")),
1855
+ token: Schema$1.String.pipe(field(2, "Token for the cart.")),
1856
+ topic: Schema$1.Literals(["carts/create", "carts/update"]).pipe(field(3, "Webhook topic that last changed the cart.")),
1857
+ lineItems: Schema$1.Array(CartLineItemSchema.annotate({ fieldId: 101 })).pipe(field(4, "Items in the cart.")),
1858
+ note: Schema$1.NullOr(Schema$1.String).pipe(field(5, "Note added to the cart.")),
1859
+ updatedAt: Schema$1.Date.pipe(field(6, "Time when the cart was last changed.")),
1860
+ createdAt: Schema$1.Date.pipe(field(7, "Time when the cart was created."))
1861
+ }).annotate({ description: "Latest state of each cart in a Shopify store." }).pipe(Iceberg.identifier("id"));
1862
+ //#endregion
1863
+ //#region src/resources/customers/webhook.ts
1864
+ const CustomerWebhookPayloadSchema = Schema$1.Struct({
1865
+ admin_graphql_api_id: Schema$1.String,
1866
+ updated_at: Schema$1.DateFromString
1867
+ });
1868
+ const CustomerPurchaseSummaryPayloadSchema = Schema$1.Struct({
1869
+ customerId: Schema$1.String,
1870
+ occurredAt: Schema$1.DateFromString
1871
+ });
1872
+ const CustomerEmailConsentPayloadSchema = Schema$1.Struct({ customer_id: Schema$1.Number });
1873
+ const CustomerSmsConsentPayloadSchema = Schema$1.Struct({ id: Schema$1.Number });
1874
+ const CustomerTagsPayloadSchema = Schema$1.Struct({
1875
+ customerId: Schema$1.String,
1876
+ occurredAt: Schema$1.DateFromString
1877
+ });
1878
+ const CustomerDeleteWebhookPayloadSchema = Schema$1.Struct({ id: Schema$1.Number });
1879
+ const CustomerEventSchema = Schema$1.Struct({
1880
+ _tag: Schema$1.Literals(["refresh", "delete"]),
1881
+ id: Schema$1.String,
1882
+ version: Schema$1.Date
1883
+ });
1884
+ //#endregion
1885
+ //#region src/resources/orders/webhook.ts
1886
+ const nullableMoney = Schema$1.NullOr(RestMoneyBagSchema);
1887
+ const RestShippingLineSchema = Schema$1.Struct({
1888
+ id: Schema$1.NullOr(Schema$1.Number),
1889
+ title: Schema$1.String,
1890
+ code: Schema$1.NullOr(Schema$1.String),
1891
+ source: Schema$1.NullOr(Schema$1.String),
1892
+ carrier_identifier: Schema$1.NullOr(Schema$1.String),
1893
+ phone: Schema$1.NullOr(Schema$1.String),
1894
+ is_removed: Schema$1.Boolean,
1895
+ price_set: RestMoneyBagSchema,
1896
+ discounted_price_set: RestMoneyBagSchema,
1897
+ current_discounted_price_set: RestMoneyBagSchema,
1898
+ tax_lines: Schema$1.Array(RestTaxLineSchema),
1899
+ discount_allocations: Schema$1.Array(RestDiscountAllocationSchema)
1900
+ });
1901
+ const RestLineItemSchema = Schema$1.Struct({
1902
+ admin_graphql_api_id: Schema$1.String,
1903
+ name: Schema$1.String,
1904
+ title: Schema$1.String,
1905
+ variant_title: Schema$1.NullOr(Schema$1.String),
1906
+ sku: Schema$1.NullOr(Schema$1.String),
1907
+ vendor: Schema$1.NullOr(Schema$1.String),
1908
+ product_id: Schema$1.NullOr(Schema$1.Number),
1909
+ variant_id: Schema$1.NullOr(Schema$1.Number),
1910
+ quantity: Schema$1.Int,
1911
+ current_quantity: Schema$1.Int,
1912
+ taxable: Schema$1.Boolean,
1913
+ requires_shipping: Schema$1.Boolean,
1914
+ gift_card: Schema$1.Boolean,
1915
+ price_set: RestMoneyBagSchema,
1916
+ total_discount_set: RestMoneyBagSchema,
1917
+ tax_lines: Schema$1.Array(RestTaxLineSchema),
1918
+ discount_allocations: Schema$1.Array(RestDiscountAllocationSchema),
1919
+ properties: Schema$1.Array(RestAttributeSchema)
1920
+ });
1921
+ const RestDiscountApplicationSchema = Schema$1.Struct({
1922
+ type: upper(DiscountApplicationTypeSchema),
1923
+ code: Schema$1.optional(Schema$1.NullOr(Schema$1.String)),
1924
+ title: Schema$1.optional(Schema$1.NullOr(Schema$1.String)),
1925
+ description: Schema$1.optional(Schema$1.NullOr(Schema$1.String)),
1926
+ allocation_method: upper(DiscountAllocationMethodSchema),
1927
+ target_selection: upper(DiscountTargetSelectionSchema),
1928
+ target_type: upper(DiscountTargetTypeSchema),
1929
+ value_type: upper(DiscountValueTypeSchema),
1930
+ value: Schema$1.String
1931
+ });
1932
+ const OrderWebhookPayloadSchema = Schema$1.Struct({
1933
+ id: Schema$1.Number,
1934
+ admin_graphql_api_id: Schema$1.String,
1935
+ name: Schema$1.String,
1936
+ email: Schema$1.NullOr(Schema$1.String),
1937
+ phone: Schema$1.NullOr(Schema$1.String),
1938
+ customer: Schema$1.NullOr(Schema$1.Struct({ admin_graphql_api_id: Schema$1.String })),
1939
+ customer_locale: Schema$1.NullOr(Schema$1.String),
1940
+ buyer_accepts_marketing: Schema$1.Boolean,
1941
+ billing_address: Schema$1.NullOr(RestAddressSchema),
1942
+ shipping_address: Schema$1.NullOr(RestAddressSchema),
1943
+ note: Schema$1.NullOr(Schema$1.String),
1944
+ note_attributes: Schema$1.Array(RestAttributeSchema),
1945
+ tags: Schema$1.String,
1946
+ confirmation_number: Schema$1.NullOr(Schema$1.String),
1947
+ po_number: Schema$1.NullOr(Schema$1.String),
1948
+ source_name: Schema$1.NullOr(Schema$1.String),
1949
+ source_identifier: Schema$1.NullOr(Schema$1.String),
1950
+ app_id: Schema$1.NullOr(Schema$1.Number),
1951
+ payment_gateway_names: Schema$1.Array(Schema$1.String),
1952
+ test: Schema$1.Boolean,
1953
+ taxes_included: Schema$1.Boolean,
1954
+ tax_exempt: Schema$1.Boolean,
1955
+ duties_included: Schema$1.Boolean,
1956
+ estimated_taxes: Schema$1.Boolean,
1957
+ total_weight: Schema$1.NullOr(Schema$1.Int),
1958
+ financial_status: Schema$1.NullOr(upper(OrderFinancialStatusSchema)),
1959
+ cancel_reason: Schema$1.NullOr(upper(OrderCancelReasonSchema)),
1960
+ cancelled_at: Schema$1.NullOr(Schema$1.DateFromString),
1961
+ closed_at: Schema$1.NullOr(Schema$1.DateFromString),
1962
+ processed_at: Schema$1.DateFromString,
1963
+ created_at: Schema$1.DateFromString,
1964
+ updated_at: Schema$1.DateFromString,
1965
+ currency: Schema$1.String,
1966
+ presentment_currency: Schema$1.String,
1967
+ discount_codes: Schema$1.Array(Schema$1.Struct({ code: Schema$1.String })),
1968
+ discount_applications: Schema$1.Array(RestDiscountApplicationSchema),
1969
+ subtotal_price_set: nullableMoney,
1970
+ current_subtotal_price_set: RestMoneyBagSchema,
1971
+ total_discounts_set: nullableMoney,
1972
+ current_total_discounts_set: RestMoneyBagSchema,
1973
+ total_shipping_price_set: RestMoneyBagSchema,
1974
+ current_shipping_price_set: RestMoneyBagSchema,
1975
+ total_tax_set: nullableMoney,
1976
+ current_total_tax_set: RestMoneyBagSchema,
1977
+ original_total_duties_set: nullableMoney,
1978
+ current_total_duties_set: nullableMoney,
1979
+ total_price_set: RestMoneyBagSchema,
1980
+ current_total_price_set: RestMoneyBagSchema,
1981
+ tax_lines: Schema$1.Array(RestTaxLineSchema),
1982
+ shipping_lines: Schema$1.Array(RestShippingLineSchema),
1983
+ line_items: Schema$1.Array(RestLineItemSchema)
1984
+ });
1985
+ const OrderDeleteWebhookPayloadSchema = Schema$1.Struct({ id: Schema$1.Number });
1986
+ const OrderEventSchema = Schema$1.Union([Schema$1.Struct({
1987
+ _tag: Schema$1.Literal("upsert"),
1988
+ payload: Schema$1.toType(OrderWebhookPayloadSchema)
1989
+ }), Schema$1.Struct({
1990
+ _tag: Schema$1.Literal("delete"),
1991
+ id: Schema$1.String,
1992
+ version: Schema$1.Date
1993
+ })]);
1994
+ const orMoney = (bag) => bag === null ? null : fromRest.money(bag);
1995
+ const fromOrderWebhook = (payload) => ({
1996
+ id: payload.admin_graphql_api_id,
1997
+ legacyResourceId: String(payload.id),
1998
+ name: payload.name,
1999
+ email: emptyText(payload.email),
2000
+ phone: emptyText(payload.phone),
2001
+ customerId: payload.customer?.admin_graphql_api_id ?? "",
2002
+ customerLocale: emptyText(payload.customer_locale),
2003
+ customerAcceptsMarketing: payload.buyer_accepts_marketing,
2004
+ billingAddress: payload.billing_address ? fromRest.address(payload.billing_address) : null,
2005
+ shippingAddress: payload.shipping_address ? fromRest.address(payload.shipping_address) : null,
2006
+ note: emptyText(payload.note),
2007
+ customAttributes: payload.note_attributes.map(fromRest.attribute),
2008
+ tags: splitTags(payload.tags),
2009
+ confirmationNumber: emptyText(payload.confirmation_number),
2010
+ poNumber: emptyText(payload.po_number),
2011
+ sourceName: emptyText(payload.source_name),
2012
+ sourceIdentifier: emptyText(payload.source_identifier),
2013
+ appId: payload.app_id === null ? "" : gid("App", payload.app_id),
2014
+ paymentGatewayNames: payload.payment_gateway_names,
2015
+ test: payload.test,
2016
+ taxesIncluded: payload.taxes_included,
2017
+ taxExempt: payload.tax_exempt,
2018
+ dutiesIncluded: payload.duties_included,
2019
+ estimatedTaxes: payload.estimated_taxes,
2020
+ totalWeight: payload.total_weight,
2021
+ displayFinancialStatus: payload.financial_status,
2022
+ cancelReason: payload.cancel_reason,
2023
+ cancelledAt: payload.cancelled_at,
2024
+ closedAt: payload.closed_at,
2025
+ processedAt: payload.processed_at,
2026
+ createdAt: payload.created_at,
2027
+ updatedAt: payload.updated_at,
2028
+ currencyCode: payload.currency,
2029
+ presentmentCurrencyCode: payload.presentment_currency,
2030
+ discountCodes: payload.discount_codes.map((discount) => discount.code),
2031
+ discountApplications: payload.discount_applications.map((application, index) => ({
2032
+ index,
2033
+ type: application.type,
2034
+ code: application.type === "DISCOUNT_CODE" ? application.code ?? null : null,
2035
+ title: application.type === "DISCOUNT_CODE" ? null : application.title ?? null,
2036
+ description: application.type === "MANUAL" ? application.description ?? null : null,
2037
+ allocationMethod: application.allocation_method,
2038
+ targetSelection: application.target_selection,
2039
+ targetType: application.target_type,
2040
+ valueType: application.value_type,
2041
+ value: normalizeAmount(application.value)
2042
+ })),
2043
+ subtotalPriceSet: orMoney(payload.subtotal_price_set),
2044
+ currentSubtotalPriceSet: fromRest.money(payload.current_subtotal_price_set),
2045
+ totalDiscountsSet: orMoney(payload.total_discounts_set),
2046
+ currentTotalDiscountsSet: fromRest.money(payload.current_total_discounts_set),
2047
+ totalShippingPriceSet: fromRest.money(payload.total_shipping_price_set),
2048
+ currentShippingPriceSet: fromRest.money(payload.current_shipping_price_set),
2049
+ totalTaxSet: orMoney(payload.total_tax_set),
2050
+ currentTotalTaxSet: fromRest.money(payload.current_total_tax_set),
2051
+ originalTotalDutiesSet: orMoney(payload.original_total_duties_set),
2052
+ currentTotalDutiesSet: orMoney(payload.current_total_duties_set),
2053
+ totalPriceSet: fromRest.money(payload.total_price_set),
2054
+ currentTotalPriceSet: fromRest.money(payload.current_total_price_set),
2055
+ taxLines: payload.tax_lines.map(fromRest.taxLine),
2056
+ shippingLines: payload.shipping_lines.map((line) => ({
2057
+ id: line.id === null ? null : gid("ShippingLine", line.id),
2058
+ title: line.title,
2059
+ code: line.code,
2060
+ source: line.source,
2061
+ carrierIdentifier: line.carrier_identifier,
2062
+ phone: line.phone,
2063
+ isRemoved: line.is_removed,
2064
+ originalPriceSet: fromRest.money(line.price_set),
2065
+ discountedPriceSet: fromRest.money(line.discounted_price_set),
2066
+ currentDiscountedPriceSet: fromRest.money(line.current_discounted_price_set),
2067
+ taxLines: line.tax_lines.map(fromRest.taxLine),
2068
+ discountAllocations: line.discount_allocations.map(fromRest.discountAllocation)
2069
+ })),
2070
+ lineItems: payload.line_items.map((item) => ({
2071
+ id: item.admin_graphql_api_id,
2072
+ name: item.name,
2073
+ title: item.title,
2074
+ variantTitle: item.variant_title,
2075
+ sku: item.sku,
2076
+ vendor: item.vendor,
2077
+ productId: item.product_id === null ? null : gid("Product", item.product_id),
2078
+ variantId: item.variant_id === null ? null : gid("ProductVariant", item.variant_id),
2079
+ quantity: item.quantity,
2080
+ currentQuantity: item.current_quantity,
2081
+ taxable: item.taxable,
2082
+ requiresShipping: item.requires_shipping,
2083
+ isGiftCard: item.gift_card,
2084
+ originalUnitPriceSet: fromRest.money(item.price_set),
2085
+ totalDiscountSet: fromRest.money(item.total_discount_set),
2086
+ taxLines: item.tax_lines.map(fromRest.taxLine),
2087
+ discountAllocations: item.discount_allocations.map(fromRest.discountAllocation),
2088
+ customAttributes: item.properties.map(fromRest.attribute)
2089
+ }))
2090
+ });
2091
+ //#endregion
2092
+ //#region src/resources/refunds/webhook.ts
2093
+ const RefundWebhookPayloadSchema = Schema$1.Struct({
2094
+ id: Schema$1.Number,
2095
+ admin_graphql_api_id: Schema$1.String,
2096
+ order_id: Schema$1.Number,
2097
+ note: Schema$1.NullOr(Schema$1.String),
2098
+ created_at: Schema$1.NullOr(Schema$1.DateFromString),
2099
+ processed_at: Schema$1.DateFromString,
2100
+ transactions: Schema$1.Array(Schema$1.Struct({
2101
+ admin_graphql_api_id: Schema$1.String,
2102
+ kind: upper(TransactionKindSchema),
2103
+ status: upper(TransactionStatusSchema),
2104
+ amount: Schema$1.String,
2105
+ currency: Schema$1.String,
2106
+ gateway: Schema$1.NullOr(Schema$1.String),
2107
+ test: Schema$1.Boolean,
2108
+ error_code: Schema$1.NullOr(Schema$1.String),
2109
+ parent_id: Schema$1.NullOr(Schema$1.Number),
2110
+ created_at: Schema$1.DateFromString,
2111
+ processed_at: Schema$1.NullOr(Schema$1.DateFromString)
2112
+ })),
2113
+ refund_line_items: Schema$1.Array(Schema$1.Struct({
2114
+ id: Schema$1.Number,
2115
+ line_item_id: Schema$1.Number,
2116
+ quantity: Schema$1.Int,
2117
+ restock_type: upper(RestockTypeSchema),
2118
+ location_id: Schema$1.NullOr(Schema$1.Number),
2119
+ subtotal_set: RestMoneyBagSchema,
2120
+ total_tax_set: RestMoneyBagSchema
2121
+ })),
2122
+ refund_shipping_lines: Schema$1.Array(Schema$1.Struct({
2123
+ id: Schema$1.Number,
2124
+ shipping_line_id: Schema$1.NullOr(Schema$1.Number),
2125
+ subtotal_amount_set: RestMoneyBagSchema
2126
+ })),
2127
+ order_adjustments: Schema$1.Array(Schema$1.Struct({
2128
+ id: Schema$1.Number,
2129
+ kind: Schema$1.NullOr(Schema$1.String),
2130
+ reason: Schema$1.NullOr(Schema$1.String),
2131
+ amount_set: RestMoneyBagSchema,
2132
+ tax_amount_set: RestMoneyBagSchema
2133
+ })),
2134
+ duties: Schema$1.Array(Schema$1.Struct({
2135
+ duty_id: Schema$1.NullOr(Schema$1.Number),
2136
+ amount_set: RestMoneyBagSchema
2137
+ }))
2138
+ });
2139
+ const RefundEventSchema = Schema$1.toType(RefundWebhookPayloadSchema);
2140
+ const fromRefundWebhook = (payload) => ({
2141
+ id: payload.admin_graphql_api_id,
2142
+ legacyResourceId: String(payload.id),
2143
+ orderId: gid("Order", payload.order_id),
2144
+ note: payload.note ?? "",
2145
+ createdAt: payload.created_at,
2146
+ processedAt: payload.processed_at,
2147
+ transactions: payload.transactions.map((transaction) => ({
2148
+ id: transaction.admin_graphql_api_id,
2149
+ kind: transaction.kind,
2150
+ status: transaction.status,
2151
+ amount: normalizeAmount(transaction.amount),
2152
+ currencyCode: transaction.currency,
2153
+ gateway: transaction.gateway,
2154
+ test: transaction.test,
2155
+ errorCode: transaction.error_code?.toUpperCase() ?? null,
2156
+ parentTransactionId: transaction.parent_id === null ? null : gid("OrderTransaction", transaction.parent_id),
2157
+ createdAt: transaction.created_at,
2158
+ processedAt: transaction.processed_at
2159
+ })),
2160
+ refundLineItems: payload.refund_line_items.map((item) => ({
2161
+ id: gid("RefundLineItem", item.id),
2162
+ lineItemId: gid("LineItem", item.line_item_id),
2163
+ quantity: item.quantity,
2164
+ restockType: item.restock_type,
2165
+ locationId: item.location_id === null ? null : gid("Location", item.location_id),
2166
+ subtotalSet: fromRest.money(item.subtotal_set),
2167
+ totalTaxSet: fromRest.money(item.total_tax_set)
2168
+ })),
2169
+ refundShippingLines: payload.refund_shipping_lines.map((line) => ({
2170
+ id: gid("RefundShippingLine", line.id),
2171
+ shippingLineId: line.shipping_line_id === null ? null : gid("ShippingLine", line.shipping_line_id),
2172
+ subtotalAmountSet: fromRest.money(line.subtotal_amount_set)
2173
+ })),
2174
+ orderAdjustments: payload.order_adjustments.filter((adjustment) => adjustment.kind !== "shipping_refund").map((adjustment) => ({
2175
+ id: gid("OrderAdjustment", adjustment.id),
2176
+ reason: adjustment.reason?.toUpperCase().replaceAll(" ", "_") ?? null,
2177
+ amountSet: fromRest.money(adjustment.amount_set),
2178
+ taxAmountSet: fromRest.money(adjustment.tax_amount_set)
2179
+ })),
2180
+ duties: payload.duties.map((duty) => ({
2181
+ dutyId: duty.duty_id === null ? null : gid("Duty", duty.duty_id),
2182
+ amountSet: fromRest.money(duty.amount_set)
2183
+ }))
2184
+ });
2185
+ //#endregion
2186
+ //#region src/connector.ts
2187
+ var connector_exports = /* @__PURE__ */ __exportAll({
2188
+ ShopifyConfigDef: () => ShopifyConfigDef,
2189
+ ShopifyConnector: () => ShopifyConnector,
2190
+ layer: () => layer,
2191
+ layerConfig: () => layerConfig,
2192
+ make: () => make,
2193
+ manifest: () => manifest
2194
+ });
2195
+ const isValidWebhookSignature = (rawBody, signature, secret) => {
2196
+ if (!signature) return false;
2197
+ const digest = createHmac("sha256", secret).update(Buffer.from(rawBody)).digest();
2198
+ const provided = Buffer.from(signature, "base64");
2199
+ return provided.length === digest.length && timingSafeEqual(digest, provided);
2200
+ };
2201
+ const decodeTriggeredAt = (value) => Option.getOrNull(Schema.decodeUnknownOption(Schema.DateFromString)(value));
2202
+ const backfillPages = (fetchPage) => Fetch.page({
2203
+ pageCursor: Cursor.string(),
2204
+ cutoff: Cursor.isoDateTime(),
2205
+ fetch: ({ pageCursor }) => fetchPage({
2206
+ first: 50,
2207
+ after: typeof pageCursor === "string" ? pageCursor : void 0
2208
+ }).pipe(Effect.map((page) => ({
2209
+ rows: page.items,
2210
+ nextPageCursor: page.endCursor ?? void 0,
2211
+ hasMore: page.hasMore
2212
+ })))
2213
+ });
2214
+ const make = Effect.fnUntraced(function* (config) {
2215
+ const api = yield* ShopifyApiClient;
2216
+ const Products = Resource.entity({
2217
+ name: "products",
2218
+ rowSchema: ProductSchema,
2219
+ version: "updatedAt",
2220
+ check: api.checkProductsAccess,
2221
+ backfill: backfillPages(api.fetchProducts),
2222
+ webhook: {
2223
+ schema: ProductEventSchema,
2224
+ handler: ({ payload }) => {
2225
+ if (payload._tag === "delete") return Effect.succeed([{
2226
+ id: payload.id,
2227
+ updatedAt: payload.version,
2228
+ _deleted: true
2229
+ }]);
2230
+ const product = payload.payload;
2231
+ if (product.variants.length === product.variant_gids.length) return Effect.succeed([fromProductWebhook(product)]);
2232
+ const triggeredAt = payload.triggeredAt;
2233
+ return Effect.gen(function* () {
2234
+ const refetched = yield* api.fetchProductById(product.admin_graphql_api_id);
2235
+ if (Option.isSome(refetched)) return [refetched.value];
2236
+ return [{
2237
+ id: product.admin_graphql_api_id,
2238
+ updatedAt: triggeredAt,
2239
+ _deleted: true
2240
+ }];
2241
+ });
2242
+ }
2243
+ }
2244
+ });
2245
+ const Customers = Resource.entity({
2246
+ name: "customers",
2247
+ rowSchema: CustomerSchema,
2248
+ version: "updatedAt",
2249
+ check: api.checkCustomersAccess,
2250
+ backfill: backfillPages(api.fetchCustomers),
2251
+ webhook: {
2252
+ schema: CustomerEventSchema,
2253
+ handler: ({ payload: { _tag, id, version } }) => Effect.gen(function* () {
2254
+ const customer = _tag === "refresh" ? yield* api.fetchCustomerById(id) : Option.none();
2255
+ return Option.isNone(customer) ? [{
2256
+ id,
2257
+ updatedAt: version,
2258
+ _deleted: true
2259
+ }] : [customer.value];
2260
+ })
2261
+ }
2262
+ });
2263
+ const Orders = Resource.entity({
2264
+ name: "orders",
2265
+ rowSchema: OrderSchema,
2266
+ version: "updatedAt",
2267
+ check: api.checkOrdersAccess,
2268
+ backfill: backfillPages(api.fetchOrders),
2269
+ webhook: {
2270
+ schema: OrderEventSchema,
2271
+ handler: ({ payload }) => Effect.succeed(payload._tag === "delete" ? [{
2272
+ id: payload.id,
2273
+ updatedAt: payload.version,
2274
+ _deleted: true
2275
+ }] : [fromOrderWebhook(payload.payload)])
2276
+ }
2277
+ });
2278
+ const Refunds = Resource.entity({
2279
+ name: "refunds",
2280
+ rowSchema: RefundSchema,
2281
+ version: "processedAt",
2282
+ check: api.checkOrdersAccess,
2283
+ backfill: backfillPages(api.fetchRefunds),
2284
+ webhook: {
2285
+ schema: RefundEventSchema,
2286
+ handler: ({ payload }) => Effect.succeed([fromRefundWebhook(payload)])
2287
+ }
2288
+ });
2289
+ const Carts = Resource.entity({
2290
+ name: "carts",
2291
+ rowSchema: CartSchema,
2292
+ version: "updatedAt",
2293
+ check: api.checkConnection,
2294
+ webhook: {
2295
+ schema: CartWebhookEventSchema,
2296
+ handler: ({ payload }) => Effect.succeed([fromCartWebhook(payload)])
2297
+ }
2298
+ });
2299
+ const webhookRoute = Webhook.route({
2300
+ path: "/webhooks/shopify",
2301
+ ackMode: "after-ingest",
2302
+ schema: Schema.Unknown,
2303
+ handler: ({ request, rawBody, payload: json, to }) => Effect.gen(function* () {
2304
+ const signature = request.headers["x-shopify-hmac-sha256"];
2305
+ if (!isValidWebhookSignature(rawBody, signature, Redacted.value(config.webhookSecret))) return HttpServerResponse.jsonUnsafe({
2306
+ ok: false,
2307
+ error: "Shopify webhook verification failed"
2308
+ }, { status: 401 });
2309
+ const topic = request.headers["x-shopify-topic"] ?? "";
2310
+ const decode = (schema) => Schema.decodeUnknownOption(schema)(json);
2311
+ const invalid = HttpServerResponse.jsonUnsafe({
2312
+ ok: false,
2313
+ error: `Invalid Shopify webhook for ${topic}`
2314
+ }, { status: 400 });
2315
+ const triggeredAt = decodeTriggeredAt(request.headers["x-shopify-triggered-at"]);
2316
+ if (triggeredAt === null) return invalid;
2317
+ switch (topic) {
2318
+ case "products/create":
2319
+ case "products/update": {
2320
+ const payload = decode(ProductWebhookPayloadSchema);
2321
+ if (Option.isNone(payload)) return invalid;
2322
+ yield* to(Products, {
2323
+ _tag: "upsert",
2324
+ payload: payload.value,
2325
+ triggeredAt
2326
+ });
2327
+ break;
2328
+ }
2329
+ case "products/delete": {
2330
+ const payload = decode(ProductDeleteWebhookPayloadSchema);
2331
+ if (Option.isNone(payload)) return invalid;
2332
+ yield* to(Products, {
2333
+ _tag: "delete",
2334
+ id: gid("Product", payload.value.id),
2335
+ version: triggeredAt
2336
+ });
2337
+ break;
2338
+ }
2339
+ case "carts/create":
2340
+ case "carts/update": {
2341
+ const payload = decode(CartWebhookPayloadSchema);
2342
+ if (Option.isNone(payload)) return invalid;
2343
+ yield* to(Carts, {
2344
+ ...payload.value,
2345
+ topic
2346
+ });
2347
+ break;
2348
+ }
2349
+ case "customers/create":
2350
+ case "customers/disable":
2351
+ case "customers/enable":
2352
+ case "customers/update": {
2353
+ const payload = decode(CustomerWebhookPayloadSchema);
2354
+ if (Option.isNone(payload)) return invalid;
2355
+ yield* to(Customers, {
2356
+ _tag: "refresh",
2357
+ id: payload.value.admin_graphql_api_id,
2358
+ version: payload.value.updated_at
2359
+ });
2360
+ break;
2361
+ }
2362
+ case "customers/purchasing_summary": {
2363
+ const payload = decode(CustomerPurchaseSummaryPayloadSchema);
2364
+ if (Option.isNone(payload)) return invalid;
2365
+ yield* to(Customers, {
2366
+ _tag: "refresh",
2367
+ id: payload.value.customerId,
2368
+ version: payload.value.occurredAt
2369
+ });
2370
+ break;
2371
+ }
2372
+ case "customers_email_marketing_consent/update": {
2373
+ const payload = decode(CustomerEmailConsentPayloadSchema);
2374
+ if (Option.isNone(payload)) return invalid;
2375
+ yield* to(Customers, {
2376
+ _tag: "refresh",
2377
+ id: gid("Customer", payload.value.customer_id),
2378
+ version: triggeredAt
2379
+ });
2380
+ break;
2381
+ }
2382
+ case "customers_marketing_consent/update": {
2383
+ const payload = decode(CustomerSmsConsentPayloadSchema);
2384
+ if (Option.isNone(payload)) return invalid;
2385
+ yield* to(Customers, {
2386
+ _tag: "refresh",
2387
+ id: gid("Customer", payload.value.id),
2388
+ version: triggeredAt
2389
+ });
2390
+ break;
2391
+ }
2392
+ case "customer.tags_added":
2393
+ case "customer.tags_removed": {
2394
+ const payload = decode(CustomerTagsPayloadSchema);
2395
+ if (Option.isNone(payload)) return invalid;
2396
+ yield* to(Customers, {
2397
+ _tag: "refresh",
2398
+ id: payload.value.customerId,
2399
+ version: payload.value.occurredAt
2400
+ });
2401
+ break;
2402
+ }
2403
+ case "customers/delete": {
2404
+ const payload = decode(CustomerDeleteWebhookPayloadSchema);
2405
+ if (Option.isNone(payload)) return invalid;
2406
+ yield* to(Customers, {
2407
+ _tag: "delete",
2408
+ id: gid("Customer", payload.value.id),
2409
+ version: triggeredAt
2410
+ });
2411
+ break;
2412
+ }
2413
+ case "orders/create":
2414
+ case "orders/updated": {
2415
+ const payload = decode(OrderWebhookPayloadSchema);
2416
+ if (Option.isNone(payload)) return invalid;
2417
+ yield* to(Orders, {
2418
+ _tag: "upsert",
2419
+ payload: payload.value
2420
+ });
2421
+ break;
2422
+ }
2423
+ case "orders/delete": {
2424
+ const payload = decode(OrderDeleteWebhookPayloadSchema);
2425
+ if (Option.isNone(payload)) return invalid;
2426
+ yield* to(Orders, {
2427
+ _tag: "delete",
2428
+ id: gid("Order", payload.value.id),
2429
+ version: triggeredAt
2430
+ });
2431
+ break;
2432
+ }
2433
+ case "refunds/create": {
2434
+ const payload = decode(RefundWebhookPayloadSchema);
2435
+ if (Option.isNone(payload)) return invalid;
2436
+ yield* to(Refunds, payload.value);
2437
+ break;
2438
+ }
2439
+ default: yield* Effect.logWarning("Ignoring unknown Shopify webhook topic").pipe(Effect.annotateLogs({ topic }));
2440
+ }
2441
+ return HttpServerResponse.jsonUnsafe({ ok: true });
2442
+ })
2443
+ });
2444
+ return Connector.define({
2445
+ name: "producer-shopify",
2446
+ title: "Shopify",
2447
+ resources: [
2448
+ Products,
2449
+ Carts,
2450
+ Customers,
2451
+ Orders,
2452
+ Refunds
2453
+ ],
2454
+ webhooks: [webhookRoute]
2455
+ });
2456
+ });
2457
+ var ShopifyConnector = class extends Context.Service()("@useairfoil/producer-shopify/ShopifyConnector") {};
2458
+ const layer = (config) => {
2459
+ const authLayer = layer$2(config);
2460
+ const apiLayer = layer$1(config).pipe(Layer.provide(authLayer));
2461
+ return Layer.effect(ShopifyConnector)(make(config).pipe(Effect.annotateLogs({ component: "producer-shopify" }))).pipe(Layer.provide(apiLayer));
2462
+ };
2463
+ const layerConfig = (config) => Layer.unwrap(Config.unwrap(config).pipe(Effect.map(layer)));
2464
+ //#endregion
2465
+ //#region src/index.ts
2466
+ const ShopifyNormalize = {
2467
+ productWebhook: fromProductWebhook,
2468
+ cartWebhook: fromCartWebhook
2469
+ };
2470
+ //#endregion
2471
+ export { CartWebhookPayloadSchema as C, normalizeAmount as E, ProductVariantSchema as S, gid as T, ProductWebhookPayloadSchema as _, RefundWebhookPayloadSchema as a, ProductStatusSchema as b, OrderWebhookPayloadSchema as c, CartSchema as d, client_exports as f, ProductDeleteWebhookPayloadSchema as g, CustomerSchema as h, layerConfig as i, fromOrderWebhook as l, OrderSchema as m, ShopifyConnector as n, fromRefundWebhook as o, RefundSchema as p, connector_exports as r, OrderDeleteWebhookPayloadSchema as s, ShopifyNormalize as t, CartLineItemSchema as u, ProductOptionSchema as v, PageInfoSchema as w, ProductVariantInventoryPolicySchema as x, ProductSchema as y };
2472
+
2473
+ //# sourceMappingURL=src-Bgvuhcfk.mjs.map