@useairfoil/producer-shopify 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +201 -0
- package/README.md +85 -248
- package/dist/index.d.mts +6993 -0
- package/dist/index.mjs +3 -0
- package/dist/main.d.mts +1 -0
- package/dist/main.mjs +700 -0
- package/dist/main.mjs.map +1 -0
- package/dist/manifest.d.mts +32 -0
- package/dist/manifest.mjs +51 -0
- package/dist/manifest.mjs.map +1 -0
- package/dist/{chunk-Bp6m_JJh.js → rolldown-runtime-D7D4PA-g.mjs} +4 -4
- package/dist/src-YBU_KSf5.mjs +2472 -0
- package/dist/src-YBU_KSf5.mjs.map +1 -0
- package/package.json +27 -27
- package/src/{auth.ts → api/auth.ts} +15 -35
- package/src/api/client.ts +429 -0
- package/src/api/graphql.ts +221 -0
- package/src/api/http.ts +25 -0
- package/src/connector.ts +266 -163
- package/src/create-table.ts +10 -0
- package/src/demo/customers.ts +412 -0
- package/src/demo/index.ts +31 -0
- package/src/demo/setup.ts +63 -0
- package/src/demo/shared.ts +114 -0
- package/src/index.ts +35 -21
- package/src/main.ts +14 -8
- package/src/manifest.ts +4 -55
- package/src/resources/carts/row.ts +82 -0
- package/src/resources/carts/webhook.ts +98 -0
- package/src/resources/customers/graphql.ts +175 -0
- package/src/resources/customers/row.ts +140 -0
- package/src/resources/customers/webhook.ts +30 -0
- package/src/resources/orders/graphql.ts +419 -0
- package/src/resources/orders/row.ts +306 -0
- package/src/resources/orders/webhook.ts +248 -0
- package/src/resources/products/graphql.ts +142 -0
- package/src/resources/products/row.ts +122 -0
- package/src/resources/products/webhook.ts +130 -0
- package/src/resources/refunds/graphql.ts +196 -0
- package/src/resources/refunds/row.ts +137 -0
- package/src/resources/refunds/webhook.ts +123 -0
- package/src/resources/shared.ts +300 -0
- package/src/sandbox.ts +3 -3
- package/src/start.ts +4 -6
- package/src/tables.ts +15 -0
- package/dist/index.d.ts +0 -965
- package/dist/index.js +0 -4
- package/dist/main.d.ts +0 -1
- package/dist/main.js +0 -49
- package/dist/main.js.map +0 -1
- package/dist/manifest-BFfx2LkS.js +0 -91
- package/dist/manifest-BFfx2LkS.js.map +0 -1
- package/dist/manifest-CPOEExQU.d.ts +0 -34
- package/dist/manifest.d.ts +0 -2
- package/dist/manifest.js +0 -3
- package/dist/src-DqmiLrYS.js +0 -984
- package/dist/src-DqmiLrYS.js.map +0 -1
- package/src/api.ts +0 -636
- package/src/schemas.ts +0 -319
- package/src/throttle.ts +0 -89
- package/src/transient-retry.ts +0 -74
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Iceberg } from "@useairfoil/connector-kit";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
|
|
4
|
+
export const ProductStatusSchema = Schema.Literals(["ACTIVE", "ARCHIVED", "DRAFT", "UNLISTED"]);
|
|
5
|
+
|
|
6
|
+
export const ProductVariantInventoryPolicySchema = Schema.Literals(["CONTINUE", "DENY"]);
|
|
7
|
+
|
|
8
|
+
const ProductImageSchema = Schema.Struct({
|
|
9
|
+
url: Schema.String.pipe(Schema.annotateKey({ description: "URL of the image." })),
|
|
10
|
+
altText: Schema.NullOr(Schema.String).pipe(
|
|
11
|
+
Schema.annotateKey({ description: "Alternative text for the image." }),
|
|
12
|
+
),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const ProductFeaturedMediaSchema = Schema.Struct({
|
|
16
|
+
image: Schema.NullOr(ProductImageSchema).pipe(
|
|
17
|
+
Schema.annotateKey({ description: "Image for the featured media." }),
|
|
18
|
+
),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export const ProductOptionSchema = Schema.Struct({
|
|
22
|
+
id: Schema.String.pipe(Schema.annotateKey({ description: "Unique product option identifier." })),
|
|
23
|
+
name: Schema.String.pipe(Schema.annotateKey({ description: "Name of the product option." })),
|
|
24
|
+
position: Schema.Int.pipe(
|
|
25
|
+
Schema.annotateKey({ description: "Position of the option on the product." }),
|
|
26
|
+
),
|
|
27
|
+
values: Schema.Array(Schema.String).pipe(
|
|
28
|
+
Schema.annotateKey({ description: "Values available for the option." }),
|
|
29
|
+
),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const ProductVariantSchema = Schema.Struct({
|
|
33
|
+
id: Schema.String.pipe(Schema.annotateKey({ description: "Unique product variant identifier." })),
|
|
34
|
+
legacyResourceId: Schema.String.pipe(
|
|
35
|
+
Schema.annotateKey({ description: "Numeric variant identifier stored as text." }),
|
|
36
|
+
),
|
|
37
|
+
title: Schema.String.pipe(Schema.annotateKey({ description: "Display title of the variant." })),
|
|
38
|
+
sku: Schema.NullOr(Schema.String).pipe(
|
|
39
|
+
Schema.annotateKey({ description: "Stock keeping unit for the variant." }),
|
|
40
|
+
),
|
|
41
|
+
barcode: Schema.NullOr(Schema.String).pipe(
|
|
42
|
+
Schema.annotateKey({ description: "Barcode for the variant." }),
|
|
43
|
+
),
|
|
44
|
+
price: Schema.String.pipe(Schema.annotateKey({ description: "Price of the variant." })),
|
|
45
|
+
compareAtPrice: Schema.NullOr(Schema.String).pipe(
|
|
46
|
+
Schema.annotateKey({ description: "Original price used for comparison." }),
|
|
47
|
+
),
|
|
48
|
+
inventoryPolicy: ProductVariantInventoryPolicySchema.pipe(
|
|
49
|
+
Schema.annotateKey({ description: "Behavior when the variant is out of stock." }),
|
|
50
|
+
),
|
|
51
|
+
taxable: Schema.Boolean.pipe(
|
|
52
|
+
Schema.annotateKey({ description: "Whether the variant is taxable." }),
|
|
53
|
+
),
|
|
54
|
+
createdAt: Schema.Date.pipe(
|
|
55
|
+
Schema.annotateKey({ description: "Time when the variant was created." }),
|
|
56
|
+
),
|
|
57
|
+
updatedAt: Schema.Date.pipe(
|
|
58
|
+
Schema.annotateKey({ description: "Time when the variant was last changed." }),
|
|
59
|
+
),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
export const ProductSchema = Schema.Struct({
|
|
63
|
+
id: Schema.String.pipe(Schema.annotateKey({ description: "Unique product identifier." })),
|
|
64
|
+
legacyResourceId: Schema.String.pipe(
|
|
65
|
+
Schema.annotateKey({ description: "Numeric product identifier stored as text." }),
|
|
66
|
+
),
|
|
67
|
+
title: Schema.String.pipe(Schema.annotateKey({ description: "Title of the product." })),
|
|
68
|
+
handle: Schema.String.pipe(Schema.annotateKey({ description: "URL handle for the product." })),
|
|
69
|
+
descriptionHtml: Schema.String.pipe(
|
|
70
|
+
Schema.annotateKey({ description: "Product description as HTML." }),
|
|
71
|
+
),
|
|
72
|
+
productType: Schema.String.pipe(
|
|
73
|
+
Schema.annotateKey({ description: "Merchant-defined product type." }),
|
|
74
|
+
),
|
|
75
|
+
vendor: Schema.String.pipe(Schema.annotateKey({ description: "Vendor of the product." })),
|
|
76
|
+
status: ProductStatusSchema.pipe(Schema.annotateKey({ description: "Current product status." })),
|
|
77
|
+
tags: Schema.Array(Schema.String).pipe(
|
|
78
|
+
Schema.annotateKey({ description: "Tags added to the product." }),
|
|
79
|
+
),
|
|
80
|
+
createdAt: Schema.Date.pipe(
|
|
81
|
+
Schema.annotateKey({ description: "Time when the product was created." }),
|
|
82
|
+
),
|
|
83
|
+
updatedAt: Schema.Date.pipe(
|
|
84
|
+
Schema.annotateKey({ description: "Time when the product was last changed." }),
|
|
85
|
+
),
|
|
86
|
+
publishedAt: Schema.NullOr(Schema.Date).pipe(
|
|
87
|
+
Schema.annotateKey({ description: "Time when the product was published." }),
|
|
88
|
+
),
|
|
89
|
+
templateSuffix: Schema.NullOr(Schema.String).pipe(
|
|
90
|
+
Schema.annotateKey({ description: "Theme template suffix used by the product." }),
|
|
91
|
+
),
|
|
92
|
+
featuredMedia: Schema.NullOr(ProductFeaturedMediaSchema).pipe(
|
|
93
|
+
Schema.annotateKey({ description: "Featured media for the product." }),
|
|
94
|
+
),
|
|
95
|
+
options: Schema.Array(ProductOptionSchema).pipe(
|
|
96
|
+
Schema.annotateKey({ description: "Options for the product." }),
|
|
97
|
+
),
|
|
98
|
+
variants: Schema.Array(ProductVariantSchema).pipe(
|
|
99
|
+
Schema.annotateKey({ description: "Variants of the product." }),
|
|
100
|
+
),
|
|
101
|
+
_deleted: Schema.optional(Schema.Boolean).pipe(
|
|
102
|
+
Schema.annotateKey({ description: "Whether the product was deleted." }),
|
|
103
|
+
),
|
|
104
|
+
})
|
|
105
|
+
.annotate({
|
|
106
|
+
description: "Products in a Shopify store.",
|
|
107
|
+
})
|
|
108
|
+
.pipe(Iceberg.identifier("id"));
|
|
109
|
+
|
|
110
|
+
export type ProductStatus = Schema.Schema.Type<typeof ProductStatusSchema>;
|
|
111
|
+
|
|
112
|
+
export type ProductVariantInventoryPolicy = Schema.Schema.Type<
|
|
113
|
+
typeof ProductVariantInventoryPolicySchema
|
|
114
|
+
>;
|
|
115
|
+
|
|
116
|
+
export type ProductFeaturedMedia = Schema.Schema.Type<typeof ProductFeaturedMediaSchema>;
|
|
117
|
+
|
|
118
|
+
export type ProductOption = Schema.Schema.Type<typeof ProductOptionSchema>;
|
|
119
|
+
|
|
120
|
+
export type ProductVariant = Schema.Schema.Type<typeof ProductVariantSchema>;
|
|
121
|
+
|
|
122
|
+
export type Product = Schema.Schema.Type<typeof ProductSchema>;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
|
|
3
|
+
import { gid, splitTags, upper } from "../shared";
|
|
4
|
+
import {
|
|
5
|
+
type Product,
|
|
6
|
+
type ProductFeaturedMedia,
|
|
7
|
+
type ProductOption,
|
|
8
|
+
ProductStatusSchema,
|
|
9
|
+
type ProductVariant,
|
|
10
|
+
ProductVariantInventoryPolicySchema,
|
|
11
|
+
} from "./row";
|
|
12
|
+
|
|
13
|
+
export const ProductWebhookImageSchema = Schema.Struct({
|
|
14
|
+
src: Schema.String,
|
|
15
|
+
alt: Schema.NullOr(Schema.String),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const ProductWebhookOptionSchema = Schema.Struct({
|
|
19
|
+
id: Schema.Number,
|
|
20
|
+
name: Schema.String,
|
|
21
|
+
position: Schema.Int,
|
|
22
|
+
values: Schema.Array(Schema.String),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const ProductWebhookVariantSchema = Schema.Struct({
|
|
26
|
+
admin_graphql_api_id: Schema.String,
|
|
27
|
+
id: Schema.Number,
|
|
28
|
+
title: Schema.String,
|
|
29
|
+
price: Schema.String,
|
|
30
|
+
inventory_policy: upper(ProductVariantInventoryPolicySchema),
|
|
31
|
+
compare_at_price: Schema.NullOr(Schema.String),
|
|
32
|
+
created_at: Schema.DateFromString,
|
|
33
|
+
updated_at: Schema.DateFromString,
|
|
34
|
+
taxable: Schema.Boolean,
|
|
35
|
+
barcode: Schema.NullOr(Schema.String),
|
|
36
|
+
sku: Schema.NullOr(Schema.String),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export const ProductWebhookVariantGidSchema = Schema.Struct({
|
|
40
|
+
admin_graphql_api_id: Schema.String,
|
|
41
|
+
updated_at: Schema.DateFromString,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export const ProductWebhookPayloadSchema = Schema.Struct({
|
|
45
|
+
id: Schema.Number,
|
|
46
|
+
admin_graphql_api_id: Schema.String,
|
|
47
|
+
body_html: Schema.NullOr(Schema.String),
|
|
48
|
+
created_at: Schema.DateFromString,
|
|
49
|
+
handle: Schema.String,
|
|
50
|
+
image: Schema.optional(Schema.NullOr(ProductWebhookImageSchema)),
|
|
51
|
+
options: Schema.Array(ProductWebhookOptionSchema),
|
|
52
|
+
product_type: Schema.String,
|
|
53
|
+
published_at: Schema.NullOr(Schema.DateFromString),
|
|
54
|
+
status: upper(ProductStatusSchema),
|
|
55
|
+
tags: Schema.String,
|
|
56
|
+
template_suffix: Schema.NullOr(Schema.String),
|
|
57
|
+
title: Schema.String,
|
|
58
|
+
updated_at: Schema.DateFromString,
|
|
59
|
+
variants: Schema.Array(ProductWebhookVariantSchema),
|
|
60
|
+
variant_gids: Schema.Array(ProductWebhookVariantGidSchema),
|
|
61
|
+
vendor: Schema.String,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
export const ProductDeleteWebhookPayloadSchema = Schema.Struct({ id: Schema.Number });
|
|
65
|
+
|
|
66
|
+
export const ProductEventSchema = Schema.Union([
|
|
67
|
+
Schema.Struct({
|
|
68
|
+
_tag: Schema.Literal("upsert"),
|
|
69
|
+
payload: Schema.toType(ProductWebhookPayloadSchema),
|
|
70
|
+
triggeredAt: Schema.Date,
|
|
71
|
+
}),
|
|
72
|
+
Schema.Struct({
|
|
73
|
+
_tag: Schema.Literal("delete"),
|
|
74
|
+
id: Schema.String,
|
|
75
|
+
version: Schema.Date,
|
|
76
|
+
}),
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
export type ProductWebhookImage = Schema.Schema.Type<typeof ProductWebhookImageSchema>;
|
|
80
|
+
|
|
81
|
+
export type ProductWebhookOption = Schema.Schema.Type<typeof ProductWebhookOptionSchema>;
|
|
82
|
+
|
|
83
|
+
export type ProductWebhookVariant = Schema.Schema.Type<typeof ProductWebhookVariantSchema>;
|
|
84
|
+
|
|
85
|
+
export type ProductWebhookPayload = Schema.Schema.Type<typeof ProductWebhookPayloadSchema>;
|
|
86
|
+
|
|
87
|
+
const normalizeProductOption = (option: ProductWebhookOption): ProductOption => ({
|
|
88
|
+
id: gid("ProductOption", option.id),
|
|
89
|
+
name: option.name,
|
|
90
|
+
position: option.position,
|
|
91
|
+
values: option.values,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const normalizeProductVariant = (variant: ProductWebhookVariant): ProductVariant => ({
|
|
95
|
+
id: variant.admin_graphql_api_id,
|
|
96
|
+
legacyResourceId: String(variant.id),
|
|
97
|
+
title: variant.title,
|
|
98
|
+
sku: variant.sku,
|
|
99
|
+
barcode: variant.barcode,
|
|
100
|
+
price: variant.price,
|
|
101
|
+
compareAtPrice: variant.compare_at_price,
|
|
102
|
+
inventoryPolicy: variant.inventory_policy,
|
|
103
|
+
taxable: variant.taxable,
|
|
104
|
+
createdAt: variant.created_at,
|
|
105
|
+
updatedAt: variant.updated_at,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const normalizeProductFeaturedMedia = (
|
|
109
|
+
image: ProductWebhookImage | null | undefined,
|
|
110
|
+
): ProductFeaturedMedia | null =>
|
|
111
|
+
image === null || image === undefined ? null : { image: { url: image.src, altText: image.alt } };
|
|
112
|
+
|
|
113
|
+
export const fromProductWebhook = (payload: ProductWebhookPayload): Product => ({
|
|
114
|
+
id: payload.admin_graphql_api_id,
|
|
115
|
+
legacyResourceId: String(payload.id),
|
|
116
|
+
title: payload.title,
|
|
117
|
+
handle: payload.handle,
|
|
118
|
+
descriptionHtml: payload.body_html ?? "",
|
|
119
|
+
productType: payload.product_type,
|
|
120
|
+
vendor: payload.vendor,
|
|
121
|
+
status: payload.status,
|
|
122
|
+
tags: splitTags(payload.tags),
|
|
123
|
+
createdAt: payload.created_at,
|
|
124
|
+
updatedAt: payload.updated_at,
|
|
125
|
+
publishedAt: payload.published_at,
|
|
126
|
+
templateSuffix: payload.template_suffix ?? "",
|
|
127
|
+
featuredMedia: normalizeProductFeaturedMedia(payload.image),
|
|
128
|
+
options: payload.options.map(normalizeProductOption),
|
|
129
|
+
variants: payload.variants.map(normalizeProductVariant),
|
|
130
|
+
});
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
GraphQLMoneyBagSchema,
|
|
5
|
+
MoneyBagFields,
|
|
6
|
+
type Nodes,
|
|
7
|
+
PageInfoFields,
|
|
8
|
+
connection,
|
|
9
|
+
fromGraphQL,
|
|
10
|
+
idRef,
|
|
11
|
+
normalizeAmount,
|
|
12
|
+
pageQuery,
|
|
13
|
+
} from "../shared";
|
|
14
|
+
import {
|
|
15
|
+
type Refund,
|
|
16
|
+
RestockTypeSchema,
|
|
17
|
+
TransactionKindSchema,
|
|
18
|
+
TransactionStatusSchema,
|
|
19
|
+
} from "./row";
|
|
20
|
+
|
|
21
|
+
const TransactionFields = `id kind status gateway test errorCode parentTransaction { id } createdAt processedAt amountSet { ${MoneyBagFields} }`;
|
|
22
|
+
|
|
23
|
+
const RefundLineItemFields = `id lineItem { id } quantity restockType location { id } subtotalSet { ${MoneyBagFields} } totalTaxSet { ${MoneyBagFields} }`;
|
|
24
|
+
|
|
25
|
+
const RefundShippingLineFields = `id shippingLine { id } subtotalAmountSet { ${MoneyBagFields} }`;
|
|
26
|
+
|
|
27
|
+
const OrderAdjustmentFields = `id reason amountSet { ${MoneyBagFields} } taxAmountSet { ${MoneyBagFields} }`;
|
|
28
|
+
|
|
29
|
+
export const RefundFields = `
|
|
30
|
+
id
|
|
31
|
+
legacyResourceId
|
|
32
|
+
note
|
|
33
|
+
createdAt
|
|
34
|
+
processedAt
|
|
35
|
+
duties { originalDuty { id } amountSet { ${MoneyBagFields} } }
|
|
36
|
+
transactions(first: 10) { nodes { ${TransactionFields} } ${PageInfoFields} }
|
|
37
|
+
refundLineItems(first: 50) { nodes { ${RefundLineItemFields} } ${PageInfoFields} }
|
|
38
|
+
refundShippingLines(first: 10) { nodes { ${RefundShippingLineFields} } ${PageInfoFields} }
|
|
39
|
+
orderAdjustments(first: 10) { nodes { ${OrderAdjustmentFields} } ${PageInfoFields} }
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
const refundConnectionQuery = (name: string, selection: string) => `#graphql
|
|
43
|
+
query ${name}($id: ID!, $first: Int!, $after: String) {
|
|
44
|
+
node: refund(id: $id) {
|
|
45
|
+
connection: ${selection}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
export const RefundTransactionsQuery = refundConnectionQuery(
|
|
51
|
+
"AirfoilRefundTransactions",
|
|
52
|
+
`transactions(first: $first, after: $after) { nodes { ${TransactionFields} } ${PageInfoFields} }`,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
export const RefundLineItemsQuery = refundConnectionQuery(
|
|
56
|
+
"AirfoilRefundLineItems",
|
|
57
|
+
`refundLineItems(first: $first, after: $after) { nodes { ${RefundLineItemFields} } ${PageInfoFields} }`,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
export const RefundShippingLinesQuery = refundConnectionQuery(
|
|
61
|
+
"AirfoilRefundShippingLines",
|
|
62
|
+
`refundShippingLines(first: $first, after: $after) { nodes { ${RefundShippingLineFields} } ${PageInfoFields} }`,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
export const RefundOrderAdjustmentsQuery = refundConnectionQuery(
|
|
66
|
+
"AirfoilRefundOrderAdjustments",
|
|
67
|
+
`orderAdjustments(first: $first, after: $after) { nodes { ${OrderAdjustmentFields} } ${PageInfoFields} }`,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
export const GraphQLRefundTransactionsSchema = connection(
|
|
71
|
+
Schema.Struct({
|
|
72
|
+
id: Schema.String,
|
|
73
|
+
kind: TransactionKindSchema,
|
|
74
|
+
status: TransactionStatusSchema,
|
|
75
|
+
gateway: Schema.NullOr(Schema.String),
|
|
76
|
+
test: Schema.Boolean,
|
|
77
|
+
errorCode: Schema.NullOr(Schema.String),
|
|
78
|
+
parentTransaction: idRef,
|
|
79
|
+
createdAt: Schema.DateFromString,
|
|
80
|
+
processedAt: Schema.NullOr(Schema.DateFromString),
|
|
81
|
+
amountSet: GraphQLMoneyBagSchema,
|
|
82
|
+
}),
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
export const GraphQLRefundLineItemsSchema = connection(
|
|
86
|
+
Schema.Struct({
|
|
87
|
+
id: Schema.NullOr(Schema.String),
|
|
88
|
+
lineItem: Schema.Struct({ id: Schema.String }),
|
|
89
|
+
quantity: Schema.Int,
|
|
90
|
+
restockType: RestockTypeSchema,
|
|
91
|
+
location: idRef,
|
|
92
|
+
subtotalSet: GraphQLMoneyBagSchema,
|
|
93
|
+
totalTaxSet: GraphQLMoneyBagSchema,
|
|
94
|
+
}),
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
export const GraphQLRefundShippingLinesSchema = connection(
|
|
98
|
+
Schema.Struct({
|
|
99
|
+
id: Schema.String,
|
|
100
|
+
shippingLine: idRef,
|
|
101
|
+
subtotalAmountSet: GraphQLMoneyBagSchema,
|
|
102
|
+
}),
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
export const GraphQLOrderAdjustmentsSchema = connection(
|
|
106
|
+
Schema.Struct({
|
|
107
|
+
id: Schema.String,
|
|
108
|
+
reason: Schema.NullOr(Schema.String),
|
|
109
|
+
amountSet: GraphQLMoneyBagSchema,
|
|
110
|
+
taxAmountSet: GraphQLMoneyBagSchema,
|
|
111
|
+
}),
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
export const GraphQLRefundNodeSchema = Schema.Struct({
|
|
115
|
+
id: Schema.String,
|
|
116
|
+
legacyResourceId: Schema.String,
|
|
117
|
+
note: Schema.NullOr(Schema.String),
|
|
118
|
+
createdAt: Schema.NullOr(Schema.DateFromString),
|
|
119
|
+
processedAt: Schema.DateFromString,
|
|
120
|
+
duties: Schema.NullOr(
|
|
121
|
+
Schema.Array(Schema.Struct({ originalDuty: idRef, amountSet: GraphQLMoneyBagSchema })),
|
|
122
|
+
),
|
|
123
|
+
transactions: GraphQLRefundTransactionsSchema,
|
|
124
|
+
refundLineItems: GraphQLRefundLineItemsSchema,
|
|
125
|
+
refundShippingLines: GraphQLRefundShippingLinesSchema,
|
|
126
|
+
orderAdjustments: GraphQLOrderAdjustmentsSchema,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
export type GraphQLRefundNode = Schema.Schema.Type<typeof GraphQLRefundNodeSchema>;
|
|
130
|
+
|
|
131
|
+
export const fromRefundNode = (
|
|
132
|
+
orderId: string,
|
|
133
|
+
node: GraphQLRefundNode,
|
|
134
|
+
nested: {
|
|
135
|
+
readonly transactions: Nodes<typeof GraphQLRefundTransactionsSchema>;
|
|
136
|
+
readonly refundLineItems: Nodes<typeof GraphQLRefundLineItemsSchema>;
|
|
137
|
+
readonly refundShippingLines: Nodes<typeof GraphQLRefundShippingLinesSchema>;
|
|
138
|
+
readonly orderAdjustments: Nodes<typeof GraphQLOrderAdjustmentsSchema>;
|
|
139
|
+
},
|
|
140
|
+
): Refund => ({
|
|
141
|
+
id: node.id,
|
|
142
|
+
legacyResourceId: node.legacyResourceId,
|
|
143
|
+
orderId,
|
|
144
|
+
note: node.note ?? "",
|
|
145
|
+
createdAt: node.createdAt,
|
|
146
|
+
processedAt: node.processedAt,
|
|
147
|
+
transactions: nested.transactions.map((transaction) => ({
|
|
148
|
+
id: transaction.id,
|
|
149
|
+
kind: transaction.kind,
|
|
150
|
+
status: transaction.status,
|
|
151
|
+
amount: normalizeAmount(transaction.amountSet.presentmentMoney.amount),
|
|
152
|
+
currencyCode: transaction.amountSet.presentmentMoney.currencyCode,
|
|
153
|
+
gateway: transaction.gateway,
|
|
154
|
+
test: transaction.test,
|
|
155
|
+
errorCode: transaction.errorCode,
|
|
156
|
+
parentTransactionId: transaction.parentTransaction?.id ?? null,
|
|
157
|
+
createdAt: transaction.createdAt,
|
|
158
|
+
processedAt: transaction.processedAt,
|
|
159
|
+
})),
|
|
160
|
+
refundLineItems: nested.refundLineItems.map((item) => ({
|
|
161
|
+
id: item.id,
|
|
162
|
+
lineItemId: item.lineItem.id,
|
|
163
|
+
quantity: item.quantity,
|
|
164
|
+
restockType: item.restockType,
|
|
165
|
+
locationId: item.location?.id ?? null,
|
|
166
|
+
subtotalSet: fromGraphQL.money(item.subtotalSet),
|
|
167
|
+
totalTaxSet: fromGraphQL.money(item.totalTaxSet),
|
|
168
|
+
})),
|
|
169
|
+
refundShippingLines: nested.refundShippingLines.map((line) => ({
|
|
170
|
+
id: line.id,
|
|
171
|
+
shippingLineId: line.shippingLine?.id ?? null,
|
|
172
|
+
subtotalAmountSet: fromGraphQL.money(line.subtotalAmountSet),
|
|
173
|
+
})),
|
|
174
|
+
orderAdjustments: nested.orderAdjustments.map((adjustment) => ({
|
|
175
|
+
id: adjustment.id,
|
|
176
|
+
reason: adjustment.reason,
|
|
177
|
+
amountSet: fromGraphQL.money(adjustment.amountSet),
|
|
178
|
+
taxAmountSet: fromGraphQL.money(adjustment.taxAmountSet),
|
|
179
|
+
})),
|
|
180
|
+
duties: (node.duties ?? []).map((duty) => ({
|
|
181
|
+
dutyId: duty.originalDuty?.id ?? null,
|
|
182
|
+
amountSet: fromGraphQL.money(duty.amountSet),
|
|
183
|
+
})),
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
export const OrderRefundsQuery = pageQuery(
|
|
187
|
+
"AirfoilOrderRefunds",
|
|
188
|
+
"orders",
|
|
189
|
+
`id refunds { ${RefundFields} }`,
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
export const GraphQLOrderRefundsDataSchema = Schema.Struct({
|
|
193
|
+
orders: connection(
|
|
194
|
+
Schema.Struct({ id: Schema.String, refunds: Schema.Array(GraphQLRefundNodeSchema) }),
|
|
195
|
+
),
|
|
196
|
+
});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Iceberg } from "@useairfoil/connector-kit";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
|
|
4
|
+
import { moneyBag } from "../shared";
|
|
5
|
+
|
|
6
|
+
export const TransactionKindSchema = Schema.Literals([
|
|
7
|
+
"SALE",
|
|
8
|
+
"CAPTURE",
|
|
9
|
+
"AUTHORIZATION",
|
|
10
|
+
"VOID",
|
|
11
|
+
"REFUND",
|
|
12
|
+
"CHANGE",
|
|
13
|
+
"EMV_AUTHORIZATION",
|
|
14
|
+
"SUGGESTED_REFUND",
|
|
15
|
+
]);
|
|
16
|
+
|
|
17
|
+
export const TransactionStatusSchema = Schema.Literals([
|
|
18
|
+
"SUCCESS",
|
|
19
|
+
"FAILURE",
|
|
20
|
+
"PENDING",
|
|
21
|
+
"ERROR",
|
|
22
|
+
"AWAITING_RESPONSE",
|
|
23
|
+
"UNKNOWN",
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
export const RestockTypeSchema = Schema.Literals([
|
|
27
|
+
"RETURN",
|
|
28
|
+
"CANCEL",
|
|
29
|
+
"LEGACY_RESTOCK",
|
|
30
|
+
"NO_RESTOCK",
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
export const RefundSchema = Schema.Struct({
|
|
34
|
+
id: Schema.String.pipe(Schema.annotateKey({ description: "Unique refund identifier." })),
|
|
35
|
+
legacyResourceId: Schema.String.pipe(
|
|
36
|
+
Schema.annotateKey({ description: "Numeric refund identifier stored as text." }),
|
|
37
|
+
),
|
|
38
|
+
orderId: Schema.String.pipe(Schema.annotateKey({ description: "Refunded order identifier." })),
|
|
39
|
+
note: Schema.NullOr(Schema.String).pipe(Schema.annotateKey({ description: "Refund note." })),
|
|
40
|
+
createdAt: Schema.NullOr(Schema.Date).pipe(
|
|
41
|
+
Schema.annotateKey({ description: "Time when the refund was created." }),
|
|
42
|
+
),
|
|
43
|
+
processedAt: Schema.Date.pipe(
|
|
44
|
+
Schema.annotateKey({ description: "Time when the refund was processed." }),
|
|
45
|
+
),
|
|
46
|
+
transactions: Schema.Array(
|
|
47
|
+
Schema.Struct({
|
|
48
|
+
id: Schema.String.pipe(Schema.annotateKey({ description: "Unique transaction identifier." })),
|
|
49
|
+
kind: TransactionKindSchema.pipe(Schema.annotateKey({ description: "Kind of transaction." })),
|
|
50
|
+
status: TransactionStatusSchema.pipe(
|
|
51
|
+
Schema.annotateKey({ description: "Status reported for the transaction." }),
|
|
52
|
+
),
|
|
53
|
+
amount: Schema.String.pipe(
|
|
54
|
+
Schema.annotateKey({ description: "Amount in the customer currency." }),
|
|
55
|
+
),
|
|
56
|
+
currencyCode: Schema.String.pipe(
|
|
57
|
+
Schema.annotateKey({ description: "Customer currency code." }),
|
|
58
|
+
),
|
|
59
|
+
gateway: Schema.NullOr(Schema.String).pipe(
|
|
60
|
+
Schema.annotateKey({ description: "Payment gateway." }),
|
|
61
|
+
),
|
|
62
|
+
test: Schema.Boolean.pipe(
|
|
63
|
+
Schema.annotateKey({ description: "Whether the transaction is a test." }),
|
|
64
|
+
),
|
|
65
|
+
errorCode: Schema.NullOr(Schema.String).pipe(
|
|
66
|
+
Schema.annotateKey({ description: "Gateway error code." }),
|
|
67
|
+
),
|
|
68
|
+
parentTransactionId: Schema.NullOr(Schema.String).pipe(
|
|
69
|
+
Schema.annotateKey({ description: "Transaction this one refunds." }),
|
|
70
|
+
),
|
|
71
|
+
createdAt: Schema.Date.pipe(
|
|
72
|
+
Schema.annotateKey({ description: "Time when the transaction was created." }),
|
|
73
|
+
),
|
|
74
|
+
processedAt: Schema.NullOr(Schema.Date).pipe(
|
|
75
|
+
Schema.annotateKey({ description: "Time when the transaction was processed." }),
|
|
76
|
+
),
|
|
77
|
+
}),
|
|
78
|
+
).pipe(Schema.annotateKey({ description: "Transactions that move the refunded money." })),
|
|
79
|
+
refundLineItems: Schema.Array(
|
|
80
|
+
Schema.Struct({
|
|
81
|
+
id: Schema.NullOr(Schema.String).pipe(
|
|
82
|
+
Schema.annotateKey({ description: "Unique refund line item identifier." }),
|
|
83
|
+
),
|
|
84
|
+
lineItemId: Schema.String.pipe(
|
|
85
|
+
Schema.annotateKey({ description: "Refunded order line item identifier." }),
|
|
86
|
+
),
|
|
87
|
+
quantity: Schema.Int.pipe(Schema.annotateKey({ description: "Quantity refunded." })),
|
|
88
|
+
restockType: RestockTypeSchema.pipe(
|
|
89
|
+
Schema.annotateKey({ description: "How the items were restocked." }),
|
|
90
|
+
),
|
|
91
|
+
locationId: Schema.NullOr(Schema.String).pipe(
|
|
92
|
+
Schema.annotateKey({ description: "Restock location identifier." }),
|
|
93
|
+
),
|
|
94
|
+
subtotalSet: moneyBag.pipe(Schema.annotateKey({ description: "Refunded subtotal." })),
|
|
95
|
+
totalTaxSet: moneyBag.pipe(Schema.annotateKey({ description: "Refunded tax." })),
|
|
96
|
+
}),
|
|
97
|
+
).pipe(Schema.annotateKey({ description: "Refunded order line items." })),
|
|
98
|
+
refundShippingLines: Schema.Array(
|
|
99
|
+
Schema.Struct({
|
|
100
|
+
id: Schema.String.pipe(
|
|
101
|
+
Schema.annotateKey({ description: "Unique refund shipping line identifier." }),
|
|
102
|
+
),
|
|
103
|
+
shippingLineId: Schema.NullOr(Schema.String).pipe(
|
|
104
|
+
Schema.annotateKey({ description: "Refunded shipping line." }),
|
|
105
|
+
),
|
|
106
|
+
subtotalAmountSet: moneyBag.pipe(
|
|
107
|
+
Schema.annotateKey({ description: "Refunded shipping amount." }),
|
|
108
|
+
),
|
|
109
|
+
}),
|
|
110
|
+
).pipe(Schema.annotateKey({ description: "Refunded shipping." })),
|
|
111
|
+
orderAdjustments: Schema.Array(
|
|
112
|
+
Schema.Struct({
|
|
113
|
+
id: Schema.String.pipe(
|
|
114
|
+
Schema.annotateKey({ description: "Unique order adjustment identifier." }),
|
|
115
|
+
),
|
|
116
|
+
reason: Schema.NullOr(Schema.String).pipe(
|
|
117
|
+
Schema.annotateKey({ description: "Reason for the adjustment." }),
|
|
118
|
+
),
|
|
119
|
+
amountSet: moneyBag.pipe(Schema.annotateKey({ description: "Adjustment amount." })),
|
|
120
|
+
taxAmountSet: moneyBag.pipe(Schema.annotateKey({ description: "Tax on the adjustment." })),
|
|
121
|
+
}),
|
|
122
|
+
).pipe(Schema.annotateKey({ description: "Refund discrepancy adjustments." })),
|
|
123
|
+
duties: Schema.Array(
|
|
124
|
+
Schema.Struct({
|
|
125
|
+
dutyId: Schema.NullOr(Schema.String).pipe(
|
|
126
|
+
Schema.annotateKey({ description: "Refunded duty identifier." }),
|
|
127
|
+
),
|
|
128
|
+
amountSet: moneyBag.pipe(Schema.annotateKey({ description: "Refunded duty amount." })),
|
|
129
|
+
}),
|
|
130
|
+
).pipe(Schema.annotateKey({ description: "Refunded duties." })),
|
|
131
|
+
})
|
|
132
|
+
.annotate({
|
|
133
|
+
description: "Refunds on orders in a Shopify store.",
|
|
134
|
+
})
|
|
135
|
+
.pipe(Iceberg.identifier("id"));
|
|
136
|
+
|
|
137
|
+
export type Refund = Schema.Schema.Type<typeof RefundSchema>;
|