@porulle/adapter-shopify 0.77.1 → 0.78.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/catalog.d.ts +4 -2
- package/dist/catalog.js +11 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/catalog.ts +12 -2
package/dist/catalog.d.ts
CHANGED
|
@@ -8,9 +8,9 @@ import type { ShopifyGraphqlTarget } from "./graphql.js";
|
|
|
8
8
|
* single-query ceiling while halving the number of calls a large catalogue takes.
|
|
9
9
|
*/
|
|
10
10
|
export declare const CATALOG_PAGE_PRODUCTS = 50;
|
|
11
|
-
export declare const CATALOG_PAGE_QUERY = "query PorulleCatalogPage($first: Int!, $after: String) {\n shop { currencyCode }\n products(first: $first, after: $after, sortKey: ID) { pageInfo { hasNextPage endCursor } nodes { \n legacyResourceId title handle status descriptionHtml vendor productType tags onlineStoreUrl\n category { name }\n options { name position optionValues { name } }\n media(first: 20) { nodes { id alt mediaContentType ... on MediaImage { image { url } } } }\n variants(first: 25) { pageInfo { hasNextPage endCursor } nodes { \n legacyResourceId sku price compareAtPrice inventoryQuantity\n barcodes(first: 1) { nodes { value } }\n selectedOptions { name value }\n media(first: 1) { nodes { id } }\n inventoryItem { legacyResourceId measurement { weight { unit value } } } } } } }\n}";
|
|
11
|
+
export declare const CATALOG_PAGE_QUERY = "query PorulleCatalogPage($first: Int!, $after: String) {\n shop { currencyCode }\n products(first: $first, after: $after, sortKey: ID) { pageInfo { hasNextPage endCursor } nodes { \n legacyResourceId title handle status descriptionHtml vendor productType tags onlineStoreUrl\n category { id name }\n options { name position optionValues { name } }\n media(first: 20) { nodes { id alt mediaContentType ... on MediaImage { image { url } } } }\n variants(first: 25) { pageInfo { hasNextPage endCursor } nodes { \n legacyResourceId sku price compareAtPrice inventoryQuantity\n barcodes(first: 1) { nodes { value } }\n selectedOptions { name value }\n media(first: 1) { nodes { id } }\n inventoryItem { legacyResourceId measurement { weight { unit value } } } } } } }\n}";
|
|
12
12
|
export declare const VARIANTS_PAGE_QUERY = "query PorulleProductVariants($id: ID!, $after: String) {\n product(id: $id) { variants(first: 250, after: $after) { pageInfo { hasNextPage endCursor } nodes { \n legacyResourceId sku price compareAtPrice inventoryQuantity\n barcodes(first: 1) { nodes { value } }\n selectedOptions { name value }\n media(first: 1) { nodes { id } }\n inventoryItem { legacyResourceId measurement { weight { unit value } } } } } }\n}";
|
|
13
|
-
export declare const CATALOG_ITEMS_QUERY = "query PorulleCatalogItems($ids: [ID!]!) {\n shop { currencyCode }\n nodes(ids: $ids) { ... on Product { \n legacyResourceId title handle status descriptionHtml vendor productType tags onlineStoreUrl\n category { name }\n options { name position optionValues { name } }\n media(first: 20) { nodes { id alt mediaContentType ... on MediaImage { image { url } } } }\n variants(first: 25) { pageInfo { hasNextPage endCursor } nodes { \n legacyResourceId sku price compareAtPrice inventoryQuantity\n barcodes(first: 1) { nodes { value } }\n selectedOptions { name value }\n media(first: 1) { nodes { id } }\n inventoryItem { legacyResourceId measurement { weight { unit value } } } } } } }\n}";
|
|
13
|
+
export declare const CATALOG_ITEMS_QUERY = "query PorulleCatalogItems($ids: [ID!]!) {\n shop { currencyCode }\n nodes(ids: $ids) { ... on Product { \n legacyResourceId title handle status descriptionHtml vendor productType tags onlineStoreUrl\n category { id name }\n options { name position optionValues { name } }\n media(first: 20) { nodes { id alt mediaContentType ... on MediaImage { image { url } } } }\n variants(first: 25) { pageInfo { hasNextPage endCursor } nodes { \n legacyResourceId sku price compareAtPrice inventoryQuantity\n barcodes(first: 1) { nodes { value } }\n selectedOptions { name value }\n media(first: 1) { nodes { id } }\n inventoryItem { legacyResourceId measurement { weight { unit value } } } } } } }\n}";
|
|
14
14
|
declare const variantSchema: z.ZodObject<{
|
|
15
15
|
legacyResourceId: z.ZodString;
|
|
16
16
|
sku: z.ZodNullable<z.ZodString>;
|
|
@@ -53,6 +53,7 @@ declare const productSchema: z.ZodObject<{
|
|
|
53
53
|
tags: z.ZodArray<z.ZodString>;
|
|
54
54
|
onlineStoreUrl: z.ZodNullable<z.ZodString>;
|
|
55
55
|
category: z.ZodNullable<z.ZodObject<{
|
|
56
|
+
id: z.ZodString;
|
|
56
57
|
name: z.ZodString;
|
|
57
58
|
}, z.core.$strip>>;
|
|
58
59
|
options: z.ZodArray<z.ZodObject<{
|
|
@@ -130,6 +131,7 @@ export declare const catalogPageSchema: z.ZodObject<{
|
|
|
130
131
|
tags: z.ZodArray<z.ZodString>;
|
|
131
132
|
onlineStoreUrl: z.ZodNullable<z.ZodString>;
|
|
132
133
|
category: z.ZodNullable<z.ZodObject<{
|
|
134
|
+
id: z.ZodString;
|
|
133
135
|
name: z.ZodString;
|
|
134
136
|
}, z.core.$strip>>;
|
|
135
137
|
options: z.ZodArray<z.ZodObject<{
|
package/dist/catalog.js
CHANGED
|
@@ -20,7 +20,7 @@ const VARIANT_FIELDS = `
|
|
|
20
20
|
inventoryItem { legacyResourceId measurement { weight { unit value } } }`;
|
|
21
21
|
const PRODUCT_FIELDS = `
|
|
22
22
|
legacyResourceId title handle status descriptionHtml vendor productType tags onlineStoreUrl
|
|
23
|
-
category { name }
|
|
23
|
+
category { id name }
|
|
24
24
|
options { name position optionValues { name } }
|
|
25
25
|
media(first: ${MEDIA_PER_PRODUCT}) { nodes { id alt mediaContentType ... on MediaImage { image { url } } } }
|
|
26
26
|
variants(first: ${VARIANTS_WITH_PRODUCT}) { pageInfo { hasNextPage endCursor } nodes { ${VARIANT_FIELDS} } }`;
|
|
@@ -61,7 +61,7 @@ const productSchema = z.object({
|
|
|
61
61
|
productType: z.string(),
|
|
62
62
|
tags: z.array(z.string()),
|
|
63
63
|
onlineStoreUrl: z.string().nullable(),
|
|
64
|
-
category: z.object({ name: z.string() }).nullable(),
|
|
64
|
+
category: z.object({ id: z.string(), name: z.string() }).nullable(),
|
|
65
65
|
options: z.array(z.object({ name: z.string(), position: z.number(), optionValues: z.array(z.object({ name: z.string() })) })),
|
|
66
66
|
media: z.object({
|
|
67
67
|
nodes: z.array(z.object({
|
|
@@ -119,10 +119,18 @@ function catalogStatus(status) {
|
|
|
119
119
|
function slugify(value) {
|
|
120
120
|
return value.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
121
121
|
}
|
|
122
|
+
/** `gid://shopify/TaxonomyCategory/aa-1-4` → `aa-1-4`, the Standard Product Taxonomy's own id. */
|
|
123
|
+
function taxonomyCategoryId(gid) {
|
|
124
|
+
const id = gid.slice(gid.lastIndexOf("/") + 1);
|
|
125
|
+
return /^[a-z]{2}(-\d+)*$/.test(id) ? id : undefined;
|
|
126
|
+
}
|
|
122
127
|
export function toCatalogItem(product, variants, currency) {
|
|
123
128
|
const images = product.media.nodes.flatMap((media) => (media.mediaContentType === "IMAGE" && media.image ? [{ id: media.id, url: media.image.url, alt: media.alt }] : []));
|
|
124
129
|
const category = product.productType ? slugify(product.productType) : product.category ? slugify(product.category.name) : "";
|
|
125
130
|
const storefrontUrl = product.onlineStoreUrl;
|
|
131
|
+
// The merchant's (or Shopify's) Standard Product Taxonomy category, as Shopify's own id. A
|
|
132
|
+
// platform that classifies against the same taxonomy reads it instead of guessing from text.
|
|
133
|
+
const shopifyCategory = product.category ? taxonomyCategoryId(product.category.id) : undefined;
|
|
126
134
|
return {
|
|
127
135
|
externalId: product.legacyResourceId,
|
|
128
136
|
slug: product.handle,
|
|
@@ -164,6 +172,7 @@ export function toCatalogItem(product, variants, currency) {
|
|
|
164
172
|
// Only Shopify's own answer. Null means the product is not on the Online Store channel; a URL
|
|
165
173
|
// assembled from the handle would be a guess that 404s on any shop with a custom route.
|
|
166
174
|
...(storefrontUrl ? { storefrontUrl } : {}),
|
|
175
|
+
...(shopifyCategory ? { metadata: { shopifyTaxonomyCategoryId: shopifyCategory } } : {}),
|
|
167
176
|
};
|
|
168
177
|
}
|
|
169
178
|
/** Every variant of `product`: the ones read with it, then the rest a page at a time. */
|