@koda-sl/baker-cli 0.370.0-dev.0cc0d2b86 → 0.370.0-dev.1981aa822

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 CHANGED
@@ -3692,9 +3692,12 @@ baker shopify store # name, currency, home countr
3692
3692
  baker shopify products --search "snowboard" # what the store sells: price, sale price, stock, where it can be bought
3693
3693
  baker shopify products --stock out_of_stock # --stock in_stock|partly_out|out_of_stock, --collection <handle|id>
3694
3694
  baker shopify products --limit 10 --cursor <c> # page with meta.next_cursor (25 by default, up to 100)
3695
- baker shopify product <id|handle|link> # one product: options, prices by country, stock, photo imageIds
3695
+ baker shopify product <id|handle|link> # one product: options with buyUrl, prices by country, stock, photos, videos
3696
+ baker shopify product <handle> --content # its whole details: description, custom fields, subscriptions, translations
3697
+ baker shopify product <handle> --field "Size chart" # one custom field, whole
3698
+ baker shopify product <handle> --quantity 2 # buy links that put 2 of the option in the cart
3696
3699
  baker shopify product <id> --out-of-stock # only the options that are out of stock (page with --variants-cursor)
3697
- baker shopify collections --search "summer" # collections, with the handle --collection takes
3700
+ baker shopify collections --search "summer" # collections, with the handle --collection takes (--full: descriptions, images)
3698
3701
  baker shopify stock --limit 20 # every product with every option out, and every product with some out
3699
3702
  ```
3700
3703
 
@@ -3702,6 +3705,8 @@ baker shopify stock --limit 20 # every product with every op
3702
3705
  **`store`:** `--full` adds the admin link and every country. `capped: true` means a count stopped at its ceiling — `outOfStock` and `partlyOut` at 100, `collections` at 500 — so that count reads "that many or more"; a hint says which.
3703
3706
  **`products`:** `--search <words>`, `--collection <handle|id>`, `--stock`, `--limit <1-100>`, `--cursor`; `--full` adds vendor, type, option count, photo link, visibility and status. Every price, here and in `product` (`price`, `compareAt`, each option's price, `pricesByCountry`), is one string with its currency beside each amount: `"USD 785.95"`, `"USD 9.95 – USD 49.95"`. A row's `availability` is absent when the product is on the store, `link_only` when it is buyable only through its link, `not_for_sale` (with `status`) when it can't be bought on the online store.
3704
3707
  **`product`:** positional `<ref>` — the numeric id, the handle, a store product link (`…/products/<handle>`, even an all-digit handle), a Baker Products link, a Shopify admin product link (`admin.shopify.com/store/<shop>/products/<n>`), or `gid://shopify/Product/<n>`. Returns options (50 per page, `--variants-cursor` for more; 250 with `--full`), `outOptions` (up to 50, `outOptionsMore` for the rest), `pricesByCountry` when the store sells at more than one price, `photos[]` (`imageId` + a Baker-hosted `url`, never a Shopify link), `url` (the product's page in Baker) and `storeUrl`. `--full` adds the whole description, SEO, category, the admin link and each option's SKU, barcode, feed id and prices by country. `NOT_FOUND` carries a hint to search instead.
3708
+
3709
+ **Details and buy links (`product`):** every option carries `buyUrl` — the link for a page's buy button, following the store's own setting (`buyDestination`: `checkout`, `store_cart` or `product_page`) — with `buyUrlKind`, `unavailable` when it can't be bought, and `notes` for what a link can't do (`password_protected`, `subscription_only`, `subscription_optional`, `own_storefront`, `details_pending`). `--quantity <1-99>` sets how many it adds. `videos[]` lists the product's videos in the library (`videoId`, `playbackId`); `contentSummary` names what else Baker keeps. `--content` adds `content`: the formatted description, every custom field by its name (long values previewed, `truncated: true`), the rating, subscriptions, bundle, YouTube/Vimeo and 3D links, translations, and `unreadable` for content the store owner hasn't let Baker read yet. `--field <name|namespace.key>` returns one field whole. `--full` adds `--content`, all three links per option and each option's weight, unit price, shipping and tax. `store` adds `buyDestination`, `passwordProtected`, `languages`, `policies` (`--full`: their text, and the store's brand).
3705
3710
  **`collections`:** `--search <words>`; each row has `handle`, Shopify's product count and, on a store with an online store, `onStore`.
3706
3711
  **`stock`:** `--collection`, `--limit <1-200>` (default 50 per list), `--full` (SKUs and Baker links). Options that keep selling at zero or don't track stock are not out of stock.
3707
3712
 
package/dist/cli.js CHANGED
@@ -8136,7 +8136,8 @@ var videoSourceSchema = z29.enum([
8136
8136
  "twitter",
8137
8137
  "vimeo",
8138
8138
  "vk",
8139
- "youtube"
8139
+ "youtube",
8140
+ "shopify"
8140
8141
  ]);
8141
8142
  var videoTranscriptSegmentSchema = z29.object({
8142
8143
  text: z29.string(),
@@ -64540,6 +64541,15 @@ var shopifyStoreConnectionSchema = z50.enum(["connected", "needs_reconnect", "di
64540
64541
  var shopifyCatalogStateSchema = z50.enum(["starting", "importing", "ready", "failed"]);
64541
64542
  var shopifyStorefrontSchema = z50.enum(["online_store", "own"]);
64542
64543
  var shopifyAvailabilitySchema = z50.enum(["link_only", "not_for_sale"]);
64544
+ var shopifyBuyDestinationSchema = z50.enum(["checkout", "store_cart", "product_page"]);
64545
+ var shopifyBuyNoteSchema = z50.enum([
64546
+ "subscription_only",
64547
+ "subscription_optional",
64548
+ "password_protected",
64549
+ "own_storefront",
64550
+ "details_pending"
64551
+ ]);
64552
+ var shopifyUnreadablePartSchema = z50.enum(["metaobjects", "definitions", "languages", "policies"]);
64543
64553
  var shopifyStoreStateSchema = z50.object({
64544
64554
  name: z50.string(),
64545
64555
  connection: shopifyStoreConnectionSchema,
@@ -64564,13 +64574,24 @@ var shopifyProductsRequestSchema = z50.object({
64564
64574
  cursor: z50.string().optional(),
64565
64575
  full: flag.optional()
64566
64576
  });
64577
+ var SHOPIFY_MAX_BUY_QUANTITY = 99;
64567
64578
  var shopifyProductRequestSchema = z50.object({
64568
64579
  ref: z50.string().min(1).max(500),
64569
64580
  variantsCursor: z50.string().optional(),
64570
64581
  outOfStock: flag.optional(),
64582
+ full: flag.optional(),
64583
+ /** The product's whole details: formatted description, custom fields, subscriptions, translations. */
64584
+ content: flag.optional(),
64585
+ /** One custom field whole, by its name or `namespace.key`. */
64586
+ field: z50.string().min(1).max(200).optional(),
64587
+ /** How many of the option each buy link puts in the cart (1-99, default 1). */
64588
+ quantity: z50.coerce.number().int().min(1).max(SHOPIFY_MAX_BUY_QUANTITY).optional()
64589
+ });
64590
+ var shopifyCollectionsRequestSchema = z50.object({
64591
+ search: z50.string().max(200).optional(),
64592
+ /** Each collection's description, image and SEO. */
64571
64593
  full: flag.optional()
64572
64594
  });
64573
- var shopifyCollectionsRequestSchema = z50.object({ search: z50.string().max(200).optional() });
64574
64595
  var shopifyStockRequestSchema = z50.object({
64575
64596
  collection: z50.string().min(1).max(500).optional(),
64576
64597
  limit: z50.coerce.number().int().min(1).max(200).optional(),
@@ -64602,8 +64623,35 @@ var shopifyStoreSummarySchema = z50.object({
64602
64623
  })
64603
64624
  ).optional(),
64604
64625
  productsUrl: z50.string(),
64626
+ /** Where the buy links send a shopper (S3b): the store's own setting, checkout unless changed. */
64627
+ buyDestination: shopifyBuyDestinationSchema,
64628
+ /** The store asks for a password before anyone can see it: a buy link meets it first. */
64629
+ passwordProtected: z50.literal(true).optional(),
64630
+ /** The store's published languages, primary first. */
64631
+ languages: z50.array(z50.object({ locale: z50.string(), name: z50.string(), primary: z50.boolean() })).optional(),
64632
+ policies: z50.array(
64633
+ z50.object({
64634
+ type: z50.string(),
64635
+ title: z50.string(),
64636
+ url: z50.string().optional(),
64637
+ // --full
64638
+ text: z50.string().optional()
64639
+ })
64640
+ ).optional(),
64641
+ /** Store content Baker can't read until the store owner accepts Baker's new permissions. */
64642
+ unreadable: z50.array(shopifyUnreadablePartSchema).optional(),
64605
64643
  // --full
64606
- adminUrl: z50.string().optional()
64644
+ adminUrl: z50.string().optional(),
64645
+ brand: z50.object({
64646
+ slogan: z50.string().optional(),
64647
+ shortDescription: z50.string().optional(),
64648
+ logoUrl: z50.string().optional(),
64649
+ squareLogoUrl: z50.string().optional(),
64650
+ coverImageUrl: z50.string().optional(),
64651
+ colors: z50.array(
64652
+ z50.object({ role: z50.string(), background: z50.string().optional(), foreground: z50.string().optional() })
64653
+ )
64654
+ }).optional()
64607
64655
  });
64608
64656
  var shopifyStoreResponseSchema = z50.object({
64609
64657
  store: shopifyStoreStateSchema,
@@ -64645,7 +64693,20 @@ var shopifyVariantSchema = z50.object({
64645
64693
  compareAtPrice: shopifyPriceSchema.optional(),
64646
64694
  stock: shopifyOptionStockSchema,
64647
64695
  quantity: z50.number().optional(),
64696
+ /** The link for the page's buy button: never build a Shopify link by hand. Absent when the option can't be bought. */
64697
+ buyUrl: z50.string().optional(),
64698
+ buyUrlKind: shopifyBuyDestinationSchema.optional(),
64699
+ /** Why there is no buy link. */
64700
+ unavailable: z50.enum(["not_for_sale", "out_of_stock"]).optional(),
64701
+ notes: z50.array(shopifyBuyNoteSchema).optional(),
64648
64702
  // --full
64703
+ checkout: z50.string().optional(),
64704
+ storeCart: z50.string().optional(),
64705
+ productPage: z50.string().optional(),
64706
+ weight: z50.string().optional(),
64707
+ unitPrice: z50.string().optional(),
64708
+ requiresShipping: z50.boolean().optional(),
64709
+ taxable: z50.boolean().optional(),
64649
64710
  sku: z50.string().optional(),
64650
64711
  barcode: z50.string().optional(),
64651
64712
  selectedOptions: z50.array(z50.object({ name: z50.string(), value: z50.string() })).optional(),
@@ -64653,6 +64714,92 @@ var shopifyVariantSchema = z50.object({
64653
64714
  inventoryPolicy: z50.enum(["DENY", "CONTINUE"]).optional(),
64654
64715
  prices: z50.array(countryPriceSchema).optional()
64655
64716
  });
64717
+ var shopifyProductVideoSchema = z50.object({
64718
+ videoId: z50.string(),
64719
+ playbackId: z50.string(),
64720
+ alt: z50.string().optional(),
64721
+ /** Seconds. */
64722
+ duration: z50.number().optional()
64723
+ });
64724
+ var shopifyFieldRefSchema = z50.object({
64725
+ kind: z50.enum(["image", "file", "video", "product", "variant", "collection", "metaobject", "other"]),
64726
+ id: z50.string(),
64727
+ url: z50.string().optional(),
64728
+ mimeType: z50.string().optional(),
64729
+ alt: z50.string().optional(),
64730
+ /** A product's or a collection's title, from Baker's copy. */
64731
+ title: z50.string().optional(),
64732
+ /** An image brought into the library: its imageId, to place like the product's photos. */
64733
+ imageId: z50.string().optional(),
64734
+ /** A custom content entry (a size chart, a care guide): its name and fields. */
64735
+ entry: z50.object({
64736
+ name: z50.string(),
64737
+ fields: z50.array(z50.object({ name: z50.string(), text: z50.string(), truncated: z50.literal(true).optional() }))
64738
+ }).optional()
64739
+ });
64740
+ var shopifyProductFieldSchema = z50.object({
64741
+ name: z50.string(),
64742
+ /** `namespace.key`: what `--field` takes when two fields share a name. */
64743
+ key: z50.string(),
64744
+ type: z50.string(),
64745
+ owner: z50.enum(["product", "option"]),
64746
+ variantId: z50.string().optional(),
64747
+ text: z50.string(),
64748
+ html: z50.string().optional(),
64749
+ refs: z50.array(shopifyFieldRefSchema).optional(),
64750
+ refsMore: z50.number().optional(),
64751
+ /** The text or the list is longer than shown: `--field <key>` returns it whole. */
64752
+ truncated: z50.literal(true).optional(),
64753
+ /** The store owner hasn't let Baker read what this field points at yet. */
64754
+ unreadable: z50.literal(true).optional()
64755
+ });
64756
+ var shopifyProductContentSchema = z50.object({
64757
+ descriptionHtml: z50.string(),
64758
+ descriptionTruncated: z50.literal(true).optional(),
64759
+ category: z50.string().optional(),
64760
+ giftCard: z50.literal(true).optional(),
64761
+ fields: z50.array(shopifyProductFieldSchema),
64762
+ rating: z50.object({ value: z50.number(), scaleMax: z50.number(), count: z50.number().optional() }).optional(),
64763
+ /** Subscriptions the product can be bought with; `subscriptionOnly` when only by subscription. */
64764
+ subscriptions: z50.array(
64765
+ z50.object({ name: z50.string(), plans: z50.array(z50.object({ name: z50.string(), category: z50.string().optional() })) })
64766
+ ).optional(),
64767
+ subscriptionOnly: z50.literal(true).optional(),
64768
+ /** YouTube or Vimeo videos and 3D models: links with their preview image. */
64769
+ mediaLinks: z50.array(
64770
+ z50.object({
64771
+ kind: z50.enum(["external_video", "model_3d"]),
64772
+ url: z50.string(),
64773
+ embedUrl: z50.string().optional(),
64774
+ previewUrl: z50.string().optional(),
64775
+ alt: z50.string().optional()
64776
+ })
64777
+ ),
64778
+ bundle: z50.array(z50.object({ productId: z50.string(), title: z50.string().optional(), quantity: z50.number() })).optional(),
64779
+ combinedListing: z50.object({ role: z50.string(), parentProductId: z50.string().optional(), childProductIds: z50.array(z50.string()) }).optional(),
64780
+ translations: z50.array(
64781
+ z50.object({
64782
+ locale: z50.string(),
64783
+ title: z50.string().optional(),
64784
+ description: z50.string().optional(),
64785
+ seoTitle: z50.string().optional(),
64786
+ seoDescription: z50.string().optional(),
64787
+ options: z50.array(
64788
+ z50.object({
64789
+ name: z50.string(),
64790
+ translatedName: z50.string().optional(),
64791
+ values: z50.array(z50.object({ value: z50.string(), translated: z50.string().optional() }))
64792
+ })
64793
+ ),
64794
+ truncated: z50.literal(true).optional()
64795
+ })
64796
+ ),
64797
+ /** Content the store owner hasn't let Baker read yet. */
64798
+ unreadable: z50.array(shopifyUnreadablePartSchema).optional(),
64799
+ /** Baker hasn't read this product's details yet, or Shopify didn't send some of them. */
64800
+ pending: z50.literal(true).optional(),
64801
+ failure: z50.string().optional()
64802
+ });
64656
64803
  var shopifyProductDetailSchema = z50.object({
64657
64804
  productId: z50.string(),
64658
64805
  title: z50.string(),
@@ -64690,6 +64837,19 @@ var shopifyProductDetailSchema = z50.object({
64690
64837
  ).optional(),
64691
64838
  /** When Baker last read this product from the store. */
64692
64839
  observedAt: z50.string(),
64840
+ /** What else Baker keeps about it, in a line: "formatted description, 2 videos, Size chart, 4.7★ from 120 reviews". */
64841
+ contentSummary: z50.string().optional(),
64842
+ /** Its Shopify videos in the video library: place one with `<Video playbackId=…/>`. */
64843
+ videos: z50.array(shopifyProductVideoSchema),
64844
+ videosAdding: z50.number(),
64845
+ videosNotBrought: z50.number(),
64846
+ /** Where the buy links send a shopper, and how many each puts in the cart. */
64847
+ buyDestination: shopifyBuyDestinationSchema,
64848
+ quantity: z50.number(),
64849
+ /** --content (or --full): the whole of it. */
64850
+ content: shopifyProductContentSchema.optional(),
64851
+ /** --field: one custom field, whole. */
64852
+ field: shopifyProductFieldSchema.optional(),
64693
64853
  // --full
64694
64854
  visibility: shopifyVisibilitySchema.optional(),
64695
64855
  seo: z50.object({ title: z50.string().optional(), description: z50.string().optional() }).optional(),
@@ -64706,7 +64866,11 @@ var shopifyCollectionRowSchema = z50.object({
64706
64866
  handle: z50.string(),
64707
64867
  /** Shopify's count at Baker's last read. */
64708
64868
  products: z50.number(),
64709
- onStore: z50.boolean().optional()
64869
+ onStore: z50.boolean().optional(),
64870
+ // --full
64871
+ description: z50.string().optional(),
64872
+ imageUrl: z50.string().optional(),
64873
+ seo: z50.object({ title: z50.string().optional(), description: z50.string().optional() }).optional()
64710
64874
  });
64711
64875
  var shopifyCollectionsResponseSchema = z50.object({
64712
64876
  store: shopifyStoreStateSchema,
@@ -64848,8 +65012,56 @@ function stockHintsFor(product) {
64848
65012
  }
64849
65013
  return hints2;
64850
65014
  }
65015
+ var BUY_NOTES = {
65016
+ password_protected: "The store asks for a password before anyone can see it: a shopper following a buy link meets it first \u2014 tell the user before sending traffic.",
65017
+ subscription_optional: "It can also be bought by subscription, but a buy link can only add it once \u2014 say so if the page promotes the subscription.",
65018
+ own_storefront: "The store sells through its own storefront: buy links go straight to Shopify's checkout.",
65019
+ details_pending: "Baker hasn't read this product's details yet (subscriptions among them): its buy links may change.",
65020
+ subscription_only: "It's sold only by subscription, which a buy link can't carry: its buy link is the product page, where the shopper picks the plan."
65021
+ };
65022
+ function buyHints(product) {
65023
+ const hints2 = [];
65024
+ if (product.variants.some((variant) => variant.buyUrl)) {
65025
+ hints2.push(
65026
+ `Use each option's \`buyUrl\` for the page's buy button \u2014 never build a Shopify link yourself (it follows the store's setting: ${product.buyDestination.replace("_", " ")}; \`--quantity <n>\` sets how many).`
65027
+ );
65028
+ }
65029
+ const notes = new Set(product.variants.flatMap((variant) => variant.notes ?? []));
65030
+ for (const note of notes) hints2.push(BUY_NOTES[note]);
65031
+ return hints2;
65032
+ }
65033
+ function contentHints(product) {
65034
+ const hints2 = [];
65035
+ const [video] = product.videos;
65036
+ if (video) {
65037
+ hints2.push(
65038
+ `Its videos are already in the video library: place one with \`<Video playbackId="${video.playbackId}" />\` \u2014 never a Shopify video link.`
65039
+ );
65040
+ }
65041
+ if (product.videosNotBrought > 0) {
65042
+ hints2.push(
65043
+ `${product.videosNotBrought} more videos stay in Shopify (Baker keeps up to 5 per product); use the ones listed.`
65044
+ );
65045
+ }
65046
+ if (product.videosAdding > 0) hints2.push(`${product.videosAdding} videos are still being added.`);
65047
+ if (product.contentSummary && !product.content) {
65048
+ hints2.push(
65049
+ "For a landing or an ad, read the whole of it with `--content` (formatted description, custom fields, subscriptions, translations)."
65050
+ );
65051
+ }
65052
+ const truncated = product.content?.fields.find((field) => field.truncated);
65053
+ if (truncated) {
65054
+ hints2.push(`Some fields are shown in part: read one whole with \`--field ${truncated.key}\`.`);
65055
+ }
65056
+ if (product.content?.unreadable?.length || product.content?.fields.some((field) => field.unreadable)) {
65057
+ hints2.push(
65058
+ "Some content isn't readable yet: ask the user to open Baker in their Shopify admin and accept the new permissions."
65059
+ );
65060
+ }
65061
+ return hints2;
65062
+ }
64851
65063
  function productHints(product, store) {
64852
- const hints2 = [...photoHints(product), ...stockHintsFor(product)];
65064
+ const hints2 = [...photoHints(product), ...stockHintsFor(product), ...buyHints(product), ...contentHints(product)];
64853
65065
  if (product.availability === "not_for_sale") {
64854
65066
  hints2.push(
64855
65067
  `Can't be bought on the online store (${(product.status ?? "hidden").toLowerCase()}): a page or ad linking to it sends people to a page they can't buy from.`
@@ -64899,6 +65111,16 @@ function stockHints(answer, limit) {
64899
65111
  }
64900
65112
  function storeHints(summary) {
64901
65113
  const hints2 = ["Share the Products page link (productsUrl) when the user wants to browse the catalog."];
65114
+ if (summary.unreadable?.length) {
65115
+ hints2.push(
65116
+ "Some of the store's content isn't readable yet: ask the user to open Baker in their Shopify admin and accept the new permissions."
65117
+ );
65118
+ }
65119
+ if (summary.passwordProtected) {
65120
+ hints2.push(
65121
+ "The store asks for a password before anyone can see it: shoppers from a landing or an ad meet it first."
65122
+ );
65123
+ }
64902
65124
  if (summary.capped) {
64903
65125
  const atCeiling = [
64904
65126
  summary.outOfStock >= SHOPIFY_STOCK_COUNT_CAP ? `${SHOPIFY_STOCK_COUNT_CAP} or more products out of stock` : null,
@@ -64972,8 +65194,13 @@ var fullArg = {
64972
65194
  };
64973
65195
  registerSchema({
64974
65196
  command: "shopify.store",
64975
- description: 'Start here for the connected Shopify store: its name, currency, home country, how many products and collections it has, how many products are out of stock or partly out, the prices by country it sells at (only when it has more than one), and the link to the Products page in Baker. `capped: true` means a count stopped at its ceiling (100 out of stock or partly out, 500 collections): say "100 or more", never the number as exact. `meta.store` says whether Baker\'s copy is complete and whether Baker can still reach the store.',
64976
- args: { full: { ...fullArg, description: "Add the store's products page in Shopify admin and every country" } }
65197
+ description: 'Start here for the connected Shopify store: its name, currency, home country, how many products and collections it has, how many products are out of stock or partly out, the prices by country it sells at (only when it has more than one), where its buy links send a shopper (`buyDestination`: checkout, store_cart or product_page), its languages and policies, whether it asks for a password, and the link to the Products page in Baker. `capped: true` means a count stopped at its ceiling (100 out of stock or partly out, 500 collections): say "100 or more", never the number as exact. `meta.store` says whether Baker\'s copy is complete and whether Baker can still reach the store.',
65198
+ args: {
65199
+ full: {
65200
+ ...fullArg,
65201
+ description: "Add the store's products page in Shopify admin, every country, each policy's text and the store's brand"
65202
+ }
65203
+ }
64977
65204
  });
64978
65205
  registerSchema({
64979
65206
  command: "shopify.products",
@@ -65002,7 +65229,7 @@ registerSchema({
65002
65229
  });
65003
65230
  registerSchema({
65004
65231
  command: "shopify.product",
65005
- description: "One product of the connected store \u2014 accepts its id, its handle, a link to it on the store, in Baker or in Shopify admin. Returns its options with price and stock, prices by country, the options out of stock, its collections, and its photos' library imageIds to place on a landing (`baker images download <imageIds> --out src/pages/<page>/_images/`) or pass to a creative. `--out-of-stock` lists only the options out of stock.",
65232
+ description: "One product of the connected store \u2014 accepts its id, its handle, a link to it on the store, in Baker or in Shopify admin. Returns its options with price, stock and `buyUrl` (the link for a page's buy button \u2014 never build a Shopify link yourself), prices by country, the options out of stock, its collections, its photos' library imageIds to place on a landing (`baker images download <imageIds> --out src/pages/<page>/_images/`) or pass to a creative, its videos' playbackIds (`<Video playbackId=\u2026/>`), and `contentSummary`: what else Baker keeps about it. Start here for a landing from a product: add `--content` for the formatted description, every custom field by its name (a size chart, care instructions), the rating, subscriptions and translations; `--field <name>` returns one field whole. `--out-of-stock` lists only the options out of stock.",
65006
65233
  args: {
65007
65234
  ref: { type: "positional", description: "Product id, handle, or a link to the product", required: true },
65008
65235
  "variants-cursor": {
@@ -65016,16 +65243,35 @@ registerSchema({
65016
65243
  required: false,
65017
65244
  default: false
65018
65245
  },
65246
+ content: {
65247
+ type: "boolean",
65248
+ description: "Its whole details: formatted description, custom fields by name (long ones previewed), rating, subscriptions, YouTube/3D links, translations",
65249
+ required: false,
65250
+ default: false
65251
+ },
65252
+ field: {
65253
+ type: "string",
65254
+ description: 'One custom field whole, by its name or its key (e.g. "Size chart" or custom.size_chart)',
65255
+ required: false
65256
+ },
65257
+ quantity: {
65258
+ type: "number",
65259
+ description: "How many of the option each buy link puts in the cart, 1-99 (default 1)",
65260
+ required: false
65261
+ },
65019
65262
  full: {
65020
65263
  ...fullArg,
65021
- description: "Whole description, SEO, category, admin link, 250 options per page with SKU and prices by country"
65264
+ description: "Its details (as --content), whole description, SEO, category, admin link, 250 options per page with SKU, prices by country, every buy link and each option's weight, unit price, shipping and tax"
65022
65265
  }
65023
65266
  }
65024
65267
  });
65025
65268
  registerSchema({
65026
65269
  command: "shopify.collections",
65027
- description: "The connected store's collections, with the handle `--collection` takes and how many products Shopify counts in each.",
65028
- args: { search: { type: "string", description: "Words in the collection's title or handle", required: false } }
65270
+ description: "The connected store's collections, with the handle `--collection` takes and how many products Shopify counts in each. `--full` adds each one's description, image and SEO.",
65271
+ args: {
65272
+ search: { type: "string", description: "Words in the collection's title or handle", required: false },
65273
+ full: { ...fullArg, description: "Add each collection's description, image and SEO" }
65274
+ }
65029
65275
  });
65030
65276
  registerSchema({
65031
65277
  command: "shopify.stock",
@@ -65102,7 +65348,7 @@ var productsCommand = defineCommand209({
65102
65348
  var productCommand = defineCommand209({
65103
65349
  meta: {
65104
65350
  name: "product",
65105
- description: "One product: options, prices by country, stock, photo imageIds. Accepts an id, handle or link. Example: baker shopify product the-complete-snowboard"
65351
+ description: "One product: options with buy links, prices by country, stock, photo imageIds, video playbackIds. Accepts an id, handle or link. Example: baker shopify product the-complete-snowboard --content"
65106
65352
  },
65107
65353
  args: {
65108
65354
  ref: { type: "positional", description: "Product id, handle, or a link to the product", required: true },
@@ -65112,6 +65358,18 @@ var productCommand = defineCommand209({
65112
65358
  required: false
65113
65359
  },
65114
65360
  "out-of-stock": { type: "boolean", description: "Only the options out of stock", required: false, default: false },
65361
+ content: {
65362
+ type: "boolean",
65363
+ description: "Its whole details: formatted description, custom fields, subscriptions, translations",
65364
+ required: false,
65365
+ default: false
65366
+ },
65367
+ field: { type: "string", description: "One custom field whole, by its name or key", required: false },
65368
+ quantity: {
65369
+ type: "string",
65370
+ description: "How many each buy link puts in the cart, 1-99 (default 1)",
65371
+ required: false
65372
+ },
65115
65373
  full: { type: "boolean", description: "Everything Baker keeps about it", required: false, default: false }
65116
65374
  },
65117
65375
  run: async ({ args: args5 }) => {
@@ -65129,6 +65387,9 @@ var productCommand = defineCommand209({
65129
65387
  ref: args5.ref,
65130
65388
  variantsCursor: args5["variants-cursor"],
65131
65389
  outOfStock: args5["out-of-stock"],
65390
+ content: args5.content,
65391
+ field: args5.field,
65392
+ quantity: args5.quantity,
65132
65393
  full: args5.full
65133
65394
  })
65134
65395
  );
@@ -65144,14 +65405,17 @@ var productCommand = defineCommand209({
65144
65405
  var collectionsCommand = defineCommand209({
65145
65406
  meta: {
65146
65407
  name: "collections",
65147
- description: "The store's collections, with the handles --collection takes. Example: baker shopify collections"
65408
+ description: "The store's collections, with the handles --collection takes. Example: baker shopify collections --full"
65409
+ },
65410
+ args: {
65411
+ search: { type: "string", description: "Words in the title or handle", required: false },
65412
+ full: { type: "boolean", description: "Add description, image and SEO", required: false, default: false }
65148
65413
  },
65149
- args: { search: { type: "string", description: "Words in the title or handle", required: false } },
65150
65414
  run: async ({ args: args5 }) => {
65151
65415
  try {
65152
65416
  const answer = await apiGet(
65153
65417
  "/api/shopify/collections",
65154
- params({ search: args5.search })
65418
+ params({ search: args5.search, full: args5.full })
65155
65419
  );
65156
65420
  emit2(
65157
65421
  answer.collections,
@@ -65197,13 +65461,18 @@ Examples:
65197
65461
  baker shopify store # currency, countries, how many products, what is out of stock
65198
65462
  baker shopify products --search "snowboard" # what we sell, with price and stock
65199
65463
  baker shopify products --stock out_of_stock # --stock in_stock|partly_out|out_of_stock, --collection <handle>
65200
- baker shopify product the-complete-snowboard # one product: options, prices by country, photo imageIds
65464
+ baker shopify product the-complete-snowboard # one product: options with buyUrl, prices, photos, videos
65465
+ baker shopify product <handle> --content # its whole details: description, custom fields, subscriptions
65466
+ baker shopify product <handle> --field "Size chart" # one custom field, whole
65467
+ baker shopify product <handle> --quantity 2 # buy links that put 2 in the cart
65201
65468
  baker shopify product <id> --out-of-stock # only its options that are out of stock
65202
65469
  baker shopify stock # every product with options out of stock
65203
65470
  baker shopify collections # collections, with handles for --collection
65204
65471
 
65205
65472
  Product photos are already in the image library: place them by imageId
65206
65473
  (baker images download <imageIds> --out src/pages/<page>/_images/), never by a cdn.shopify.com link.
65474
+ Product videos are in the video library: place them with <Video playbackId="\u2026" />.
65475
+ A page's buy button uses the option's buyUrl \u2014 never build a Shopify link yourself.
65207
65476
  NO_SHOPIFY_CONNECTION means no store is connected: follow error.fix. SHOPIFY_NOT_AVAILABLE means it cannot be
65208
65477
  connected here yet: carry on without it.
65209
65478
  Full guide: __tooling__/docs/tools/baker/shopify.md`