@keystrokehq/shopify 0.0.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.
- package/README.md +178 -0
- package/dist/_official/index.d.mts +3 -0
- package/dist/_official/index.mjs +3 -0
- package/dist/_runtime/index.d.mts +56 -0
- package/dist/_runtime/index.mjs +3 -0
- package/dist/articles.d.mts +174 -0
- package/dist/articles.mjs +252 -0
- package/dist/blogs.d.mts +113 -0
- package/dist/blogs.mjs +174 -0
- package/dist/client.d.mts +22 -0
- package/dist/client.mjs +90 -0
- package/dist/collections.d.mts +140 -0
- package/dist/collections.mjs +209 -0
- package/dist/connection.d.mts +2 -0
- package/dist/connection.mjs +3 -0
- package/dist/customers.d.mts +161 -0
- package/dist/customers.mjs +225 -0
- package/dist/events.d.mts +181 -0
- package/dist/events.mjs +67 -0
- package/dist/factory-DC-gY8L0.mjs +8 -0
- package/dist/fulfillments.d.mts +99 -0
- package/dist/fulfillments.mjs +167 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +1 -0
- package/dist/integration-BN3pjCz4.mjs +204 -0
- package/dist/integration-BwDBsGX-.d.mts +71 -0
- package/dist/inventory.d.mts +103 -0
- package/dist/inventory.mjs +182 -0
- package/dist/locations.d.mts +47 -0
- package/dist/locations.mjs +81 -0
- package/dist/messaging.d.mts +1 -0
- package/dist/messaging.mjs +1 -0
- package/dist/operation-helpers-CKEDIx0o.mjs +21 -0
- package/dist/orders.d.mts +229 -0
- package/dist/orders.mjs +271 -0
- package/dist/products.d.mts +155 -0
- package/dist/products.mjs +171 -0
- package/dist/provider-app-DHxVZI6q.d.mts +37 -0
- package/dist/schemas.d.mts +233 -0
- package/dist/schemas.mjs +164 -0
- package/dist/shop.d.mts +20 -0
- package/dist/shop.mjs +31 -0
- package/dist/triggers.d.mts +23 -0
- package/dist/triggers.mjs +138 -0
- package/dist/webhook-management-BmIxO0vr.mjs +150 -0
- package/package.json +130 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { a as shopifyAppCredentialSet, t as shopify } from "./integration-BN3pjCz4.mjs";
|
|
2
|
+
import { shopifyOrderCancelledEventSchema, shopifyOrderCreatedEventSchema, shopifyOrderFulfilledEventSchema, shopifyOrderUpdatedEventSchema, shopifyOrderWebhookPayloadSchema, shopifyProductCreatedEventSchema, shopifyProductDeletedEventSchema, shopifyProductUpdatedEventSchema, shopifyProductWebhookPayloadSchema } from "./events.mjs";
|
|
3
|
+
import { t as SHOPIFY_WEBHOOK_RUNTIME_DEFINITIONS } from "./webhook-management-BmIxO0vr.mjs";
|
|
4
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
5
|
+
import { createWebhookTriggerBindingFactory } from "@keystrokehq/integration-authoring";
|
|
6
|
+
|
|
7
|
+
//#region src/verification.ts
|
|
8
|
+
function getHeader(headers, name) {
|
|
9
|
+
const normalizedName = name.toLowerCase();
|
|
10
|
+
for (const [key, value] of Object.entries(headers)) if (key.toLowerCase() === normalizedName) return value;
|
|
11
|
+
}
|
|
12
|
+
function verifyShopifyWebhook(request, webhookSecret) {
|
|
13
|
+
const signature = getHeader(request.headers, "x-shopify-hmac-sha256");
|
|
14
|
+
if (!signature) return false;
|
|
15
|
+
const expectedDigest = createHmac("sha256", webhookSecret).update(request.rawBody, "utf8").digest("base64");
|
|
16
|
+
const signatureBuffer = Buffer.from(signature, "utf8");
|
|
17
|
+
const expectedBuffer = Buffer.from(expectedDigest, "utf8");
|
|
18
|
+
if (signatureBuffer.length !== expectedBuffer.length) return false;
|
|
19
|
+
return timingSafeEqual(signatureBuffer, expectedBuffer);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/triggers.ts
|
|
24
|
+
function getWebhookPath(topic) {
|
|
25
|
+
const definition = SHOPIFY_WEBHOOK_RUNTIME_DEFINITIONS.find((candidate) => candidate.eventTopic === topic);
|
|
26
|
+
if (!definition) throw new Error(`Unsupported Shopify webhook topic: ${topic}`);
|
|
27
|
+
return definition.path;
|
|
28
|
+
}
|
|
29
|
+
function extractStringField(payload, fieldNames) {
|
|
30
|
+
for (const fieldName of fieldNames) {
|
|
31
|
+
const value = payload[fieldName];
|
|
32
|
+
if (typeof value === "string" && value.length > 0) return value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function extractNumberField(payload, fieldNames) {
|
|
36
|
+
for (const fieldName of fieldNames) {
|
|
37
|
+
const value = payload[fieldName];
|
|
38
|
+
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function buildShopifyWebhookEventId(topic, payload) {
|
|
42
|
+
return `${topic}:${extractStringField(payload, ["admin_graphql_api_id"]) ?? extractNumberField(payload, ["id"]) ?? "unknown-resource"}:${extractStringField(payload, [
|
|
43
|
+
"updated_at",
|
|
44
|
+
"created_at",
|
|
45
|
+
"cancelled_at",
|
|
46
|
+
"processed_at",
|
|
47
|
+
"published_at"
|
|
48
|
+
]) ?? "unknown-time"}`;
|
|
49
|
+
}
|
|
50
|
+
function createShopifyWebhookBindingFactory(config) {
|
|
51
|
+
return createWebhookTriggerBindingFactory({
|
|
52
|
+
defaultName: config.defaultName,
|
|
53
|
+
defaultDescription: config.defaultDescription,
|
|
54
|
+
path: getWebhookPath(config.topic),
|
|
55
|
+
method: "POST",
|
|
56
|
+
payload: config.payloadSchema,
|
|
57
|
+
credentialSets: [shopify, shopifyAppCredentialSet],
|
|
58
|
+
verify: (request, ctx) => {
|
|
59
|
+
const appCredentials = ctx.credentials["shopify-app"];
|
|
60
|
+
if (!verifyShopifyWebhook(request, appCredentials.webhookSecret)) throw new Error("Invalid Shopify webhook signature.");
|
|
61
|
+
},
|
|
62
|
+
mapPayload: (payload) => config.eventSchema.parse({
|
|
63
|
+
eventId: buildShopifyWebhookEventId(config.topic, payload),
|
|
64
|
+
topic: config.topic,
|
|
65
|
+
resourceId: extractStringField(payload, ["admin_graphql_api_id"]) ?? extractNumberField(payload, ["id"]),
|
|
66
|
+
occurredAt: extractStringField(payload, [
|
|
67
|
+
"updated_at",
|
|
68
|
+
"created_at",
|
|
69
|
+
"cancelled_at",
|
|
70
|
+
"processed_at",
|
|
71
|
+
"published_at"
|
|
72
|
+
]),
|
|
73
|
+
payload
|
|
74
|
+
}),
|
|
75
|
+
response: { successStatus: 200 }
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const productCreatedBinding = createShopifyWebhookBindingFactory({
|
|
79
|
+
topic: "products/create",
|
|
80
|
+
defaultName: "Shopify Product Created",
|
|
81
|
+
defaultDescription: "Trigger when a Shopify product is created.",
|
|
82
|
+
payloadSchema: shopifyProductWebhookPayloadSchema,
|
|
83
|
+
eventSchema: shopifyProductCreatedEventSchema
|
|
84
|
+
});
|
|
85
|
+
const productUpdatedBinding = createShopifyWebhookBindingFactory({
|
|
86
|
+
topic: "products/update",
|
|
87
|
+
defaultName: "Shopify Product Updated",
|
|
88
|
+
defaultDescription: "Trigger when a Shopify product is updated.",
|
|
89
|
+
payloadSchema: shopifyProductWebhookPayloadSchema,
|
|
90
|
+
eventSchema: shopifyProductUpdatedEventSchema
|
|
91
|
+
});
|
|
92
|
+
const productDeletedBinding = createShopifyWebhookBindingFactory({
|
|
93
|
+
topic: "products/delete",
|
|
94
|
+
defaultName: "Shopify Product Deleted",
|
|
95
|
+
defaultDescription: "Trigger when a Shopify product is deleted.",
|
|
96
|
+
payloadSchema: shopifyProductWebhookPayloadSchema,
|
|
97
|
+
eventSchema: shopifyProductDeletedEventSchema
|
|
98
|
+
});
|
|
99
|
+
const orderCreatedBinding = createShopifyWebhookBindingFactory({
|
|
100
|
+
topic: "orders/create",
|
|
101
|
+
defaultName: "Shopify Order Created",
|
|
102
|
+
defaultDescription: "Trigger when a Shopify order is created.",
|
|
103
|
+
payloadSchema: shopifyOrderWebhookPayloadSchema,
|
|
104
|
+
eventSchema: shopifyOrderCreatedEventSchema
|
|
105
|
+
});
|
|
106
|
+
const orderUpdatedBinding = createShopifyWebhookBindingFactory({
|
|
107
|
+
topic: "orders/updated",
|
|
108
|
+
defaultName: "Shopify Order Updated",
|
|
109
|
+
defaultDescription: "Trigger when a Shopify order is updated.",
|
|
110
|
+
payloadSchema: shopifyOrderWebhookPayloadSchema,
|
|
111
|
+
eventSchema: shopifyOrderUpdatedEventSchema
|
|
112
|
+
});
|
|
113
|
+
const orderCancelledBinding = createShopifyWebhookBindingFactory({
|
|
114
|
+
topic: "orders/cancelled",
|
|
115
|
+
defaultName: "Shopify Order Cancelled",
|
|
116
|
+
defaultDescription: "Trigger when a Shopify order is cancelled.",
|
|
117
|
+
payloadSchema: shopifyOrderWebhookPayloadSchema,
|
|
118
|
+
eventSchema: shopifyOrderCancelledEventSchema
|
|
119
|
+
});
|
|
120
|
+
const orderFulfilledBinding = createShopifyWebhookBindingFactory({
|
|
121
|
+
topic: "orders/fulfilled",
|
|
122
|
+
defaultName: "Shopify Order Fulfilled",
|
|
123
|
+
defaultDescription: "Trigger when a Shopify order is fulfilled.",
|
|
124
|
+
payloadSchema: shopifyOrderWebhookPayloadSchema,
|
|
125
|
+
eventSchema: shopifyOrderFulfilledEventSchema
|
|
126
|
+
});
|
|
127
|
+
const webhooks = Object.freeze({
|
|
128
|
+
productCreated: (options) => productCreatedBinding(options),
|
|
129
|
+
productUpdated: (options) => productUpdatedBinding(options),
|
|
130
|
+
productDeleted: (options) => productDeletedBinding(options),
|
|
131
|
+
orderCreated: (options) => orderCreatedBinding(options),
|
|
132
|
+
orderUpdated: (options) => orderUpdatedBinding(options),
|
|
133
|
+
orderCancelled: (options) => orderCancelledBinding(options),
|
|
134
|
+
orderFulfilled: (options) => orderFulfilledBinding(options)
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
//#endregion
|
|
138
|
+
export { webhooks };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { shopifyGlobalIdSchema, shopifyUserErrorSchema } from "./schemas.mjs";
|
|
2
|
+
import { createShopifyClient } from "./client.mjs";
|
|
3
|
+
import { shopifyWebhookSubscriptionTopicSchema, shopifyWebhookTopicSchema } from "./events.mjs";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
//#region src/webhook-management.ts
|
|
7
|
+
const shopifyWebhookRuntimeDefinitionSchema = z.object({
|
|
8
|
+
eventTopic: shopifyWebhookTopicSchema,
|
|
9
|
+
subscriptionTopic: shopifyWebhookSubscriptionTopicSchema,
|
|
10
|
+
path: z.string().min(1)
|
|
11
|
+
});
|
|
12
|
+
const SHOPIFY_WEBHOOK_RUNTIME_DEFINITIONS = [
|
|
13
|
+
{
|
|
14
|
+
eventTopic: "products/create",
|
|
15
|
+
subscriptionTopic: "PRODUCTS_CREATE",
|
|
16
|
+
path: "/shopify/products/create"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
eventTopic: "products/update",
|
|
20
|
+
subscriptionTopic: "PRODUCTS_UPDATE",
|
|
21
|
+
path: "/shopify/products/update"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
eventTopic: "products/delete",
|
|
25
|
+
subscriptionTopic: "PRODUCTS_DELETE",
|
|
26
|
+
path: "/shopify/products/delete"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
eventTopic: "orders/create",
|
|
30
|
+
subscriptionTopic: "ORDERS_CREATE",
|
|
31
|
+
path: "/shopify/orders/create"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
eventTopic: "orders/updated",
|
|
35
|
+
subscriptionTopic: "ORDERS_UPDATED",
|
|
36
|
+
path: "/shopify/orders/updated"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
eventTopic: "orders/cancelled",
|
|
40
|
+
subscriptionTopic: "ORDERS_CANCELLED",
|
|
41
|
+
path: "/shopify/orders/cancelled"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
eventTopic: "orders/fulfilled",
|
|
45
|
+
subscriptionTopic: "ORDERS_FULFILLED",
|
|
46
|
+
path: "/shopify/orders/fulfilled"
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
const webhookSubscriptionSchema = z.object({
|
|
50
|
+
id: shopifyGlobalIdSchema,
|
|
51
|
+
topic: shopifyWebhookSubscriptionTopicSchema,
|
|
52
|
+
uri: z.string().url()
|
|
53
|
+
});
|
|
54
|
+
const listWebhookSubscriptionsResponseSchema = z.object({ webhookSubscriptions: z.object({ nodes: z.array(webhookSubscriptionSchema) }) });
|
|
55
|
+
const createWebhookSubscriptionResponseSchema = z.object({ webhookSubscriptionCreate: z.object({
|
|
56
|
+
webhookSubscription: webhookSubscriptionSchema.nullable(),
|
|
57
|
+
userErrors: z.array(shopifyUserErrorSchema)
|
|
58
|
+
}) });
|
|
59
|
+
const deleteWebhookSubscriptionResponseSchema = z.object({ webhookSubscriptionDelete: z.object({
|
|
60
|
+
deletedWebhookSubscriptionId: shopifyGlobalIdSchema.nullable(),
|
|
61
|
+
userErrors: z.array(shopifyUserErrorSchema)
|
|
62
|
+
}) });
|
|
63
|
+
function assertNoUserErrors(userErrors) {
|
|
64
|
+
if (userErrors.length === 0) return;
|
|
65
|
+
const message = userErrors.map((error) => error.field && error.field.length > 0 ? `${error.field.join(".")}: ${error.message}` : error.message).join("; ");
|
|
66
|
+
throw new Error(`Shopify webhook subscription error: ${message}`);
|
|
67
|
+
}
|
|
68
|
+
function buildShopifyWebhookCallbackUri(baseUrl, path) {
|
|
69
|
+
return new URL(path, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`).toString();
|
|
70
|
+
}
|
|
71
|
+
async function listShopifyWebhookSubscriptions(credentials) {
|
|
72
|
+
return (await createShopifyClient(credentials).graphql(`
|
|
73
|
+
query ListWebhookSubscriptions($topics: [WebhookSubscriptionTopic!]) {
|
|
74
|
+
webhookSubscriptions(first: 50, topics: $topics) {
|
|
75
|
+
nodes {
|
|
76
|
+
id
|
|
77
|
+
topic
|
|
78
|
+
uri
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
`, listWebhookSubscriptionsResponseSchema, { variables: { topics: SHOPIFY_WEBHOOK_RUNTIME_DEFINITIONS.map((definition) => definition.subscriptionTopic) } })).webhookSubscriptions.nodes;
|
|
83
|
+
}
|
|
84
|
+
async function createShopifyWebhookSubscription(credentials, topic, uri) {
|
|
85
|
+
const response = await createShopifyClient(credentials).graphql(`
|
|
86
|
+
mutation CreateWebhookSubscription(
|
|
87
|
+
$topic: WebhookSubscriptionTopic!
|
|
88
|
+
$webhookSubscription: WebhookSubscriptionInput!
|
|
89
|
+
) {
|
|
90
|
+
webhookSubscriptionCreate(topic: $topic, webhookSubscription: $webhookSubscription) {
|
|
91
|
+
webhookSubscription {
|
|
92
|
+
id
|
|
93
|
+
topic
|
|
94
|
+
uri
|
|
95
|
+
}
|
|
96
|
+
userErrors {
|
|
97
|
+
field
|
|
98
|
+
message
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
`, createWebhookSubscriptionResponseSchema, { variables: {
|
|
103
|
+
topic,
|
|
104
|
+
webhookSubscription: { uri }
|
|
105
|
+
} });
|
|
106
|
+
assertNoUserErrors(response.webhookSubscriptionCreate.userErrors);
|
|
107
|
+
if (!response.webhookSubscriptionCreate.webhookSubscription) throw new Error(`Shopify did not return the created webhook subscription for ${topic}.`);
|
|
108
|
+
return response.webhookSubscriptionCreate.webhookSubscription;
|
|
109
|
+
}
|
|
110
|
+
async function deleteShopifyWebhookSubscription(credentials, id) {
|
|
111
|
+
const response = await createShopifyClient(credentials).graphql(`
|
|
112
|
+
mutation DeleteWebhookSubscription($id: ID!) {
|
|
113
|
+
webhookSubscriptionDelete(id: $id) {
|
|
114
|
+
deletedWebhookSubscriptionId
|
|
115
|
+
userErrors {
|
|
116
|
+
field
|
|
117
|
+
message
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
`, deleteWebhookSubscriptionResponseSchema, { variables: { id } });
|
|
122
|
+
assertNoUserErrors(response.webhookSubscriptionDelete.userErrors);
|
|
123
|
+
if (!response.webhookSubscriptionDelete.deletedWebhookSubscriptionId) throw new Error(`Shopify did not confirm deletion for webhook subscription ${id}.`);
|
|
124
|
+
return response.webhookSubscriptionDelete.deletedWebhookSubscriptionId;
|
|
125
|
+
}
|
|
126
|
+
async function ensureShopifyWebhookSubscriptions(credentials, callbackBaseUrl) {
|
|
127
|
+
const existing = await listShopifyWebhookSubscriptions(credentials);
|
|
128
|
+
const kept = [];
|
|
129
|
+
const created = [];
|
|
130
|
+
const deleted = [];
|
|
131
|
+
for (const definition of SHOPIFY_WEBHOOK_RUNTIME_DEFINITIONS) {
|
|
132
|
+
const expectedUri = buildShopifyWebhookCallbackUri(callbackBaseUrl, definition.path);
|
|
133
|
+
const matches = existing.filter((subscription) => subscription.topic === definition.subscriptionTopic);
|
|
134
|
+
const canonical = matches.find((subscription) => subscription.uri === expectedUri);
|
|
135
|
+
if (canonical) kept.push(canonical.id);
|
|
136
|
+
for (const subscription of matches) if (!canonical || subscription.id !== canonical.id) deleted.push(await deleteShopifyWebhookSubscription(credentials, subscription.id));
|
|
137
|
+
if (!canonical) {
|
|
138
|
+
const createdSubscription = await createShopifyWebhookSubscription(credentials, definition.subscriptionTopic, expectedUri);
|
|
139
|
+
created.push(createdSubscription.id);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
kept,
|
|
144
|
+
created,
|
|
145
|
+
deleted
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
//#endregion
|
|
150
|
+
export { listShopifyWebhookSubscriptions as i, buildShopifyWebhookCallbackUri as n, ensureShopifyWebhookSubscriptions as r, SHOPIFY_WEBHOOK_RUNTIME_DEFINITIONS as t };
|
package/package.json
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@keystrokehq/shopify",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.mts",
|
|
10
|
+
"default": "./dist/index.mjs"
|
|
11
|
+
},
|
|
12
|
+
"./messaging": {
|
|
13
|
+
"types": "./dist/messaging.d.mts",
|
|
14
|
+
"default": "./dist/messaging.mjs"
|
|
15
|
+
},
|
|
16
|
+
"./connection": {
|
|
17
|
+
"types": "./dist/connection.d.mts",
|
|
18
|
+
"default": "./dist/connection.mjs"
|
|
19
|
+
},
|
|
20
|
+
"./client": {
|
|
21
|
+
"types": "./dist/client.d.mts",
|
|
22
|
+
"default": "./dist/client.mjs"
|
|
23
|
+
},
|
|
24
|
+
"./schemas": {
|
|
25
|
+
"types": "./dist/schemas.d.mts",
|
|
26
|
+
"default": "./dist/schemas.mjs"
|
|
27
|
+
},
|
|
28
|
+
"./events": {
|
|
29
|
+
"types": "./dist/events.d.mts",
|
|
30
|
+
"default": "./dist/events.mjs"
|
|
31
|
+
},
|
|
32
|
+
"./shop": {
|
|
33
|
+
"types": "./dist/shop.d.mts",
|
|
34
|
+
"default": "./dist/shop.mjs"
|
|
35
|
+
},
|
|
36
|
+
"./products": {
|
|
37
|
+
"types": "./dist/products.d.mts",
|
|
38
|
+
"default": "./dist/products.mjs"
|
|
39
|
+
},
|
|
40
|
+
"./collections": {
|
|
41
|
+
"types": "./dist/collections.d.mts",
|
|
42
|
+
"default": "./dist/collections.mjs"
|
|
43
|
+
},
|
|
44
|
+
"./orders": {
|
|
45
|
+
"types": "./dist/orders.d.mts",
|
|
46
|
+
"default": "./dist/orders.mjs"
|
|
47
|
+
},
|
|
48
|
+
"./customers": {
|
|
49
|
+
"types": "./dist/customers.d.mts",
|
|
50
|
+
"default": "./dist/customers.mjs"
|
|
51
|
+
},
|
|
52
|
+
"./blogs": {
|
|
53
|
+
"types": "./dist/blogs.d.mts",
|
|
54
|
+
"default": "./dist/blogs.mjs"
|
|
55
|
+
},
|
|
56
|
+
"./articles": {
|
|
57
|
+
"types": "./dist/articles.d.mts",
|
|
58
|
+
"default": "./dist/articles.mjs"
|
|
59
|
+
},
|
|
60
|
+
"./inventory": {
|
|
61
|
+
"types": "./dist/inventory.d.mts",
|
|
62
|
+
"default": "./dist/inventory.mjs"
|
|
63
|
+
},
|
|
64
|
+
"./locations": {
|
|
65
|
+
"types": "./dist/locations.d.mts",
|
|
66
|
+
"default": "./dist/locations.mjs"
|
|
67
|
+
},
|
|
68
|
+
"./fulfillments": {
|
|
69
|
+
"types": "./dist/fulfillments.d.mts",
|
|
70
|
+
"default": "./dist/fulfillments.mjs"
|
|
71
|
+
},
|
|
72
|
+
"./triggers": {
|
|
73
|
+
"types": "./dist/triggers.d.mts",
|
|
74
|
+
"default": "./dist/triggers.mjs"
|
|
75
|
+
},
|
|
76
|
+
"./_official": {
|
|
77
|
+
"types": "./dist/_official/index.d.mts",
|
|
78
|
+
"default": "./dist/_official/index.mjs"
|
|
79
|
+
},
|
|
80
|
+
"./_runtime": {
|
|
81
|
+
"types": "./dist/_runtime/index.d.mts",
|
|
82
|
+
"default": "./dist/_runtime/index.mjs"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"files": [
|
|
86
|
+
"dist",
|
|
87
|
+
"README.md",
|
|
88
|
+
"LICENSE"
|
|
89
|
+
],
|
|
90
|
+
"scripts": {
|
|
91
|
+
"typecheck": "tsgo --build",
|
|
92
|
+
"build": "tsdown",
|
|
93
|
+
"lint": "biome check .",
|
|
94
|
+
"test:unit": "vitest run --passWithNoTests --project unit",
|
|
95
|
+
"test:int": "vitest run --passWithNoTests --project int",
|
|
96
|
+
"prepublishOnly": "pnpm build && pnpm test:unit",
|
|
97
|
+
"lint:fix": "biome check --write ."
|
|
98
|
+
},
|
|
99
|
+
"dependencies": {
|
|
100
|
+
"@shopify/admin-api-client": "^1.1.2",
|
|
101
|
+
"@keystrokehq/credential-connection": "^0.0.1",
|
|
102
|
+
"@keystrokehq/integration-authoring": "^0.0.1",
|
|
103
|
+
"@keystrokehq/core": "^0.0.5",
|
|
104
|
+
"zod": "^4.3.6"
|
|
105
|
+
},
|
|
106
|
+
"devDependencies": {
|
|
107
|
+
"@types/node": "catalog:",
|
|
108
|
+
"@keystrokehq/test-utils": "workspace:*",
|
|
109
|
+
"@keystrokehq/typescript-config": "workspace:*",
|
|
110
|
+
"tsdown": "catalog:",
|
|
111
|
+
"typescript": "catalog:",
|
|
112
|
+
"vitest": "catalog:"
|
|
113
|
+
},
|
|
114
|
+
"keywords": [
|
|
115
|
+
"shopify",
|
|
116
|
+
"keystroke",
|
|
117
|
+
"integration",
|
|
118
|
+
"commerce"
|
|
119
|
+
],
|
|
120
|
+
"repository": {
|
|
121
|
+
"type": "git",
|
|
122
|
+
"url": "https://github.com/keystrokehq/integrations",
|
|
123
|
+
"directory": "integrations/shopify"
|
|
124
|
+
},
|
|
125
|
+
"license": "MIT",
|
|
126
|
+
"publishConfig": {
|
|
127
|
+
"access": "public",
|
|
128
|
+
"registry": "https://registry.npmjs.org/"
|
|
129
|
+
}
|
|
130
|
+
}
|