@koda-sl/baker-cli 0.369.0-dev.ba2803c37 → 0.370.0-dev.0cc0d2b86

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
@@ -3699,8 +3699,9 @@ baker shopify stock --limit 20 # every product with every op
3699
3699
  ```
3700
3700
 
3701
3701
  **`meta.store`** is on every answer: `connection` (`connected` · `needs_reconnect` · `disconnected`), `catalog` (`starting` · `importing` · `ready` · `failed`, with `importProgress` while importing), `unreadable` (products Baker couldn't read; `unreadableCapped` past 100), `checksFailing` (Baker couldn't check the store for changes lately), `storefront` (`online_store`, or `own` for a store that sells through its own site) and `lastActivity` (when Baker last heard from the store — not a promise the copy is current). `hints[]` turn each of these into what to tell the user.
3702
+ **`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.
3702
3703
  **`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.
3703
- **`product`:** positional `<ref>` — the numeric id, the handle, a store product link (`…/products/<handle>`, even an all-digit handle), a Baker Products link, 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.
3704
+ **`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.
3704
3705
  **`collections`:** `--search <words>`; each row has `handle`, Shopify's product count and, on a store with an online store, `onStore`.
3705
3706
  **`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.
3706
3707
 
package/dist/cli.js CHANGED
@@ -64579,6 +64579,8 @@ var shopifyStockRequestSchema = z50.object({
64579
64579
  var AMOUNT = String.raw`[A-Z]{3} \d+(?:\.\d+)?`;
64580
64580
  var shopifyPriceSchema = z50.string().regex(new RegExp(`^${AMOUNT}$`), "a price is '<CURRENCY> <amount>'");
64581
64581
  var shopifyPriceRangeSchema = z50.string().regex(new RegExp(`^${AMOUNT}(?: \u2013 ${AMOUNT})?$`), "a price range is '<CURRENCY> <min> \u2013 <CURRENCY> <max>'");
64582
+ var SHOPIFY_STOCK_COUNT_CAP = 100;
64583
+ var SHOPIFY_COLLECTION_COUNT_CAP = 500;
64582
64584
  var shopifyStoreSummarySchema = z50.object({
64583
64585
  name: z50.string(),
64584
64586
  domain: z50.string(),
@@ -64589,7 +64591,7 @@ var shopifyStoreSummarySchema = z50.object({
64589
64591
  collections: z50.number(),
64590
64592
  outOfStock: z50.number(),
64591
64593
  partlyOut: z50.number(),
64592
- /** A count stopped at its cap: 100 for stock counts, 500 for collections. */
64594
+ /** A count stopped at its cap: `SHOPIFY_STOCK_COUNT_CAP` for stock counts, `SHOPIFY_COLLECTION_COUNT_CAP` for collections. */
64593
64595
  capped: z50.literal(true).optional(),
64594
64596
  pricePoints: z50.array(
64595
64597
  z50.object({
@@ -64799,7 +64801,8 @@ function productsHints(answer, options) {
64799
64801
  if (answer.nextCursor)
64800
64802
  hints2.push(`More products: rerun with \`--cursor ${answer.nextCursor}\` and the same filters.`);
64801
64803
  if (answer.products.length === 0 && !answer.nextCursor) {
64802
- if (options.filtered) hints2.push("No products match; drop `--search`/`--stock`/`--collection`.");
64804
+ if (options.paged) hints2.push("No more products: the earlier pages were the whole list.");
64805
+ else if (options.filtered) hints2.push("No products match; drop `--search`/`--stock`/`--collection`.");
64803
64806
  else if (cleanAndReady(answer.store)) hints2.push("The store has no products yet.");
64804
64807
  else {
64805
64808
  hints2.push(
@@ -64873,15 +64876,17 @@ function productHints(product, store) {
64873
64876
  function stockHints(answer, limit) {
64874
64877
  const hints2 = [];
64875
64878
  const any = answer.outOfStock.length > 0 || answer.partlyOut.length > 0;
64876
- if (!any) hints2.push("Nothing is out of stock.");
64877
- else {
64879
+ const unfinished = answer.more.outOfStock || answer.more.partlyOut;
64880
+ const pageThrough = "page through with `baker shopify products --stock out_of_stock` / `--stock partly_out` (and the same `--collection`)";
64881
+ if (any) {
64878
64882
  hints2.push(
64879
64883
  "Before promoting these, check which ads and pages point at them; pausing or swapping them is a staged change."
64880
64884
  );
64881
- }
64882
- if (answer.more.outOfStock || answer.more.partlyOut) {
64885
+ } else if (!unfinished) hints2.push("Nothing is out of stock.");
64886
+ if (unfinished) {
64887
+ const full = answer.more.outOfStock && answer.outOfStock.length >= limit || answer.more.partlyOut && answer.partlyOut.length >= limit;
64883
64888
  hints2.push(
64884
- `More than ${limit} products in a list; raise \`--limit\` (up to 200) or page through with \`baker shopify products --stock out_of_stock\` / \`--stock partly_out\`.`
64889
+ full ? `More than ${limit} products in a list; raise \`--limit\` (up to 200) or ${pageThrough}.` : `Baker didn't check every product in one go, so these lists may be missing some \u2014 don't say nothing else is out of stock; ${pageThrough}.`
64885
64890
  );
64886
64891
  }
64887
64892
  const big = answer.partlyOut.find((row) => row.outOptionsMore);
@@ -64892,8 +64897,19 @@ function stockHints(answer, limit) {
64892
64897
  }
64893
64898
  return hints2;
64894
64899
  }
64895
- function storeHints() {
64896
- return ["Share the Products page link (productsUrl) when the user wants to browse the catalog."];
64900
+ function storeHints(summary) {
64901
+ const hints2 = ["Share the Products page link (productsUrl) when the user wants to browse the catalog."];
64902
+ if (summary.capped) {
64903
+ const atCeiling = [
64904
+ summary.outOfStock >= SHOPIFY_STOCK_COUNT_CAP ? `${SHOPIFY_STOCK_COUNT_CAP} or more products out of stock` : null,
64905
+ summary.partlyOut >= SHOPIFY_STOCK_COUNT_CAP ? `${SHOPIFY_STOCK_COUNT_CAP} or more products partly out` : null,
64906
+ summary.collections >= SHOPIFY_COLLECTION_COUNT_CAP ? `${SHOPIFY_COLLECTION_COUNT_CAP} or more collections` : null
64907
+ ].filter((count2) => count2 !== null);
64908
+ hints2.push(
64909
+ `Some counts stopped at Baker's ceiling: say ${atCeiling.join(", ")} \u2014 never the number as exact. \`baker shopify stock\` and \`baker shopify products --stock out_of_stock\` page through them.`
64910
+ );
64911
+ }
64912
+ return hints2;
64897
64913
  }
64898
64914
 
64899
64915
  // src/commands/shopify/refusal.ts
@@ -64956,7 +64972,7 @@ var fullArg = {
64956
64972
  };
64957
64973
  registerSchema({
64958
64974
  command: "shopify.store",
64959
- 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. `meta.store` says whether Baker's copy is complete and whether Baker can still reach the 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.',
64960
64976
  args: { full: { ...fullArg, description: "Add the store's products page in Shopify admin and every country" } }
64961
64977
  });
64962
64978
  registerSchema({
@@ -64986,7 +65002,7 @@ registerSchema({
64986
65002
  });
64987
65003
  registerSchema({
64988
65004
  command: "shopify.product",
64989
- description: "One product of the connected store \u2014 accepts its id, its handle, a link to it on the store or in Baker. 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.",
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.",
64990
65006
  args: {
64991
65007
  ref: { type: "positional", description: "Product id, handle, or a link to the product", required: true },
64992
65008
  "variants-cursor": {
@@ -65031,7 +65047,7 @@ var storeCommand = defineCommand209({
65031
65047
  run: async ({ args: args5 }) => {
65032
65048
  try {
65033
65049
  const answer = await apiGet("/api/shopify/store", params({ full: args5.full }));
65034
- emit2(answer.summary, { store: answer.store }, [...storeStateHints(answer.store), ...storeHints()]);
65050
+ emit2(answer.summary, { store: answer.store }, [...storeStateHints(answer.store), ...storeHints(answer.summary)]);
65035
65051
  } catch (err) {
65036
65052
  fail9(err);
65037
65053
  }
@@ -65076,7 +65092,7 @@ var productsCommand = defineCommand209({
65076
65092
  count: answer.products.length,
65077
65093
  ...answer.nextCursor ? { next_cursor: answer.nextCursor } : {}
65078
65094
  },
65079
- [...storeStateHints(answer.store), ...productsHints(answer, { filtered })]
65095
+ [...storeStateHints(answer.store), ...productsHints(answer, { filtered, paged: Boolean(args5.cursor) })]
65080
65096
  );
65081
65097
  } catch (err) {
65082
65098
  fail9(err);