@feedmepos/mf-menu 0.32.70 → 0.32.72-dev.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.
Files changed (75) hide show
  1. package/dist/{App-D2qKBNOI.js → App-DpBAxq_x.js} +6 -6
  2. package/dist/{ApplyProduct.vue_vue_type_script_setup_true_lang-DpuE1Txi.js → ApplyProduct.vue_vue_type_script_setup_true_lang-BE34SL6B.js} +12 -12
  3. package/dist/{ApplyProductDialog.vue_vue_type_script_setup_true_lang-CuhfoI6u.js → ApplyProductDialog.vue_vue_type_script_setup_true_lang-Cg4oaBql.js} +3 -3
  4. package/dist/{Catalog-B8DQ8HuW.js → Catalog-BCKu3av3.js} +20 -20
  5. package/dist/{Category-BlfQyXMP.js → Category-D8fstrW5.js} +4 -4
  6. package/dist/{Category-DXRKc5oR.js → Category-DRyJ8Y9S.js} +4 -4
  7. package/dist/{CookingGuide-jNeTimU7.js → CookingGuide-BKTlBPm-.js} +46 -46
  8. package/dist/{CustomAttributeChip.vue_vue_type_script_setup_true_lang-BMKqOTc3.js → CustomAttributeChip.vue_vue_type_script_setup_true_lang-BHqJGqLf.js} +1 -1
  9. package/dist/{Group-BDS80Kj0.js → Group-DMLdJAIA.js} +1 -1
  10. package/dist/{Group-BmU0_HFA.js → Group-_vEUeyva.js} +3 -3
  11. package/dist/{Group.vue_vue_type_script_setup_true_lang-hSxGRxop.js → Group.vue_vue_type_script_setup_true_lang-BEONKZuB.js} +7 -7
  12. package/dist/{GroupMarkupPriceDialog.vue_vue_type_script_setup_true_lang-CUNcxRnJ.js → GroupMarkupPriceDialog.vue_vue_type_script_setup_true_lang-B2pS71Xq.js} +24 -24
  13. package/dist/{ImportProductDialog.vue_vue_type_script_setup_true_lang-DjLnCfC5.js → ImportProductDialog.vue_vue_type_script_setup_true_lang-BHNmNXw0.js} +7 -7
  14. package/dist/{Ingredient-Czl2K5rQ.js → Ingredient-DeGrqMqN.js} +4 -4
  15. package/dist/{InventoryBinding.vue_vue_type_script_setup_true_lang-M8HxDzxj.js → InventoryBinding.vue_vue_type_script_setup_true_lang-DFOcD2mw.js} +2 -2
  16. package/dist/{LinkProductSideSheet-iwH-Ft7_.js → LinkProductSideSheet-BZNe2r8t.js} +4 -4
  17. package/dist/{MenuSetting-D-PtnHh_.js → MenuSetting-yb8w_Nwc.js} +7 -7
  18. package/dist/{OrderPacing-DpajUDfR.js → OrderPacing-DRApEr9x.js} +5 -5
  19. package/dist/{PrintRoute-CWzUI3D1.js → PrintRoute-DK3ZMajo.js} +10 -10
  20. package/dist/{Product-C341g4w7.js → Product-CBhhhicD.js} +1 -1
  21. package/dist/{Product.vue_vue_type_script_setup_true_lang-BRLo39YE.js → Product.vue_vue_type_script_setup_true_lang-CPgECJwS.js} +14 -14
  22. package/dist/ProductInternalTools-D8j9hMuA.js +439 -0
  23. package/dist/{Products-Dco1XgQd.js → Products-Db0Ihn6p.js} +55 -55
  24. package/dist/{Publish-sDveejeh.js → Publish-BFBUjUWu.js} +4 -4
  25. package/dist/{Recipe-MfXgmqtt.js → Recipe-B0r5vJz6.js} +5 -5
  26. package/dist/{RestaurantAttributesSelector.vue_vue_type_script_setup_true_lang-vtJwWImA.js → RestaurantAttributesSelector.vue_vue_type_script_setup_true_lang-C8Jk7KEh.js} +1 -1
  27. package/dist/{RuleView.vue_vue_type_script_setup_true_lang-ZnrzCXu3.js → RuleView.vue_vue_type_script_setup_true_lang-DPCcNBrm.js} +340 -340
  28. package/dist/{Scheduler-DKyhr6p8.js → Scheduler-yOdnbwyV.js} +17 -17
  29. package/dist/{ServingSequence-nEoPok72.js → ServingSequence-CEcYzZKq.js} +3 -3
  30. package/dist/{Setting-RWyx1jq2.js → Setting-CEwxLrwm.js} +5 -5
  31. package/dist/{Subcategory-B0smFoMD.js → Subcategory-b1NEH4Rt.js} +6 -6
  32. package/dist/{Takeaway-BVMZewQ0.js → Takeaway-BwGq2ti3.js} +4 -4
  33. package/dist/{Takeaway-BpwBR54Y.js → Takeaway-C4X3hjz2.js} +1 -1
  34. package/dist/{Takeaway.vue_vue_type_script_setup_true_lang-BTnFR11p.js → Takeaway.vue_vue_type_script_setup_true_lang-Da28Vzx1.js} +5 -5
  35. package/dist/{TranslationFieldSection.vue_vue_type_script_setup_true_lang-KNIxHJsf.js → TranslationFieldSection.vue_vue_type_script_setup_true_lang-DIP7cNpd.js} +1 -1
  36. package/dist/{TranslationSideSheet.vue_vue_type_script_setup_true_lang-Dznh3-H8.js → TranslationSideSheet.vue_vue_type_script_setup_true_lang-CCYzllV_.js} +2 -2
  37. package/dist/{TreeEditorOpenner.vue_vue_type_script_setup_true_lang-k3m88FlR.js → TreeEditorOpenner.vue_vue_type_script_setup_true_lang-e_pAe_Ob.js} +15 -15
  38. package/dist/{Unit-BzbHDW_L.js → Unit-DWGvi3C5.js} +2 -2
  39. package/dist/{Variant-BF_zXLDM.js → Variant-2YYwBJmZ.js} +3 -3
  40. package/dist/{_id_-BjGIzI2V.js → _id_-3pf3YlPS.js} +10 -10
  41. package/dist/{app-DDrm4hOt.js → app-D1p44Rbf.js} +37 -37
  42. package/dist/{app-qoGPYaSq.js → app-D6CmNX90.js} +1 -1
  43. package/dist/app.js +1 -1
  44. package/dist/apps/mf-menu/src/app.d.ts +20 -0
  45. package/dist/apps/mf-menu/src/components/feature/TreeEditor/composable/productImages.d.ts +80 -19
  46. package/dist/apps/mf-menu/tsconfig.app.tsbuildinfo +1 -1
  47. package/dist/assets/{override-menu-D1btUpWP.js → linked-status-B_5fbldk.js} +4 -4
  48. package/dist/assets/{menu-export-rYnoju7h.js → menu-export-Dje2CzXB.js} +3 -3
  49. package/dist/assets/{linked-status-CXL9skR7.js → override-menu-CpJc9-6f.js} +4 -4
  50. package/dist/assets/{validate-menu-R6zi6RGb.js → validate-menu-CpDDVAwU.js} +3 -3
  51. package/dist/{catalog-ByfbV1WF.js → catalog-Ds7c8bSK.js} +1 -1
  52. package/dist/{catalogSetting-qvKbsi8t.js → catalogSetting-qbnlvX9R.js} +1 -1
  53. package/dist/{currency-C5kmu6Ku.js → currency-BQjK22_U.js} +1 -1
  54. package/dist/dayjs.min-BjENDBB5.js +7 -0
  55. package/dist/{discardConfirm-rDbUqsKj.js → discardConfirm-DhbS0wLN.js} +1 -1
  56. package/dist/{index-B2Hnb8WK.js → index-BqB1Vagh.js} +6 -6
  57. package/dist/{index-COu9fsyr.js → index-C2rMjg4b.js} +1 -1
  58. package/dist/{index-BoVuN9fk.js → index-YU-FPKch.js} +5 -5
  59. package/dist/{index.vue_vue_type_script_setup_true_lang-Wm3L_CDm.js → index.vue_vue_type_script_setup_true_lang-DILo07iQ.js} +16618 -16607
  60. package/dist/{item-CcaqdD88.js → item-CN-mYmn-.js} +1627 -1626
  61. package/dist/{jszip.min-B-GfzNS3.js → jszip.min-DdiexxWX.js} +384 -384
  62. package/dist/{linkProducts-DXSk9ntt.js → linkProducts-DSa1bP0Z.js} +4 -4
  63. package/dist/{memberPricing-Bmv0qRtK.js → memberPricing-BLIgqSgU.js} +1 -1
  64. package/dist/{menu-BLbZDh7_.js → menu-kYSa55lO.js} +1 -1
  65. package/dist/{menuV2-BSGYEEJI.js → menuV2-BJ-6TZDX.js} +23 -23
  66. package/dist/mf-menu.css +1 -1
  67. package/dist/{order_pacing-DLrwnijs.js → order_pacing-CeCi-pP3.js} +5 -5
  68. package/dist/{priceTier-Bw0-wJJ0.js → priceTier-CsF1g5ie.js} +1 -1
  69. package/dist/{rules-Ciu45JMO.js → rules-C3jtb0rM.js} +3 -3
  70. package/dist/{scheduler-DYZ2PnDh.js → scheduler-DZpjPLLc.js} +5 -5
  71. package/dist/{toExcel-D6Rp5oOB.js → toExcel-DI9BOlMc.js} +2 -2
  72. package/dist/{unit-BR60ZgDQ.js → unit-DeNymCWc.js} +17 -17
  73. package/package.json +1 -1
  74. package/dist/ProductInternalTools-BUku68VS.js +0 -416
  75. package/dist/dayjs.min-D3WVCWf8.js +0 -7
@@ -1,5 +1,5 @@
1
1
  import { defineStore as r } from "pinia";
2
- import { J as a, K as s, L as l } from "./index.vue_vue_type_script_setup_true_lang-Wm3L_CDm.js";
2
+ import { K as a, L as s, M as l } from "./index.vue_vue_type_script_setup_true_lang-DILo07iQ.js";
3
3
  const u = {
4
4
  async read() {
5
5
  return a(await s().get("/public-setting"));
package/dist/app.js CHANGED
@@ -1,4 +1,4 @@
1
- import { F as e, i as r, j as o, o as t, r as i, u as p } from "./app-DDrm4hOt.js";
1
+ import { F as e, i as r, j as o, o as t, r as i, u as p } from "./app-D1p44Rbf.js";
2
2
  export {
3
3
  e as FmApp,
4
4
  r as i18nMessages,
@@ -1601,6 +1601,10 @@ export declare const i18nMessages: {
1601
1601
  };
1602
1602
  productInternalTools: {
1603
1603
  title: string;
1604
+ unreadable_images: {
1605
+ title: string;
1606
+ message: string;
1607
+ };
1604
1608
  };
1605
1609
  publish: {
1606
1610
  title: string;
@@ -3661,6 +3665,10 @@ export declare const i18nMessages: {
3661
3665
  };
3662
3666
  productInternalTools: {
3663
3667
  title: string;
3668
+ unreadable_images: {
3669
+ title: string;
3670
+ message: string;
3671
+ };
3664
3672
  };
3665
3673
  publish: {
3666
3674
  title: string;
@@ -5719,6 +5727,10 @@ export declare const i18nMessages: {
5719
5727
  };
5720
5728
  productInternalTools: {
5721
5729
  title: string;
5730
+ unreadable_images: {
5731
+ title: string;
5732
+ message: string;
5733
+ };
5722
5734
  };
5723
5735
  publish: {
5724
5736
  title: string;
@@ -7778,6 +7790,10 @@ export declare const i18nMessages: {
7778
7790
  };
7779
7791
  productInternalTools: {
7780
7792
  title: string;
7793
+ unreadable_images: {
7794
+ title: string;
7795
+ message: string;
7796
+ };
7781
7797
  };
7782
7798
  publish: {
7783
7799
  title: string;
@@ -9825,6 +9841,10 @@ export declare const i18nMessages: {
9825
9841
  };
9826
9842
  productInternalTools: {
9827
9843
  title: string;
9844
+ unreadable_images: {
9845
+ title: string;
9846
+ message: string;
9847
+ };
9828
9848
  };
9829
9849
  publish: {
9830
9850
  title: string;
@@ -47,20 +47,38 @@ export declare function validateImageFile(file: File): string | null;
47
47
  * The half of `validateImageFile` that is a real dead end.
48
48
  *
49
49
  * A file the browser cannot decode is refused outright, but being over
50
- * `MAX_IMAGE_BYTES` is not a reason to refuse a photo any more: the editor re-encodes it
51
- * under the limit (`canvasToFile`), which is the whole point of opening on upload. Call
52
- * sites that hand bytes straight to media-service Remy's output, a staged flush
53
- * still use the combined check, because nothing there can shrink a file.
50
+ * `MAX_IMAGE_BYTES` is not a reason to refuse a photo any more: every upload is re-encoded
51
+ * under the limit (`compressImageForUpload`), which is the whole point of opening on
52
+ * upload. The combined check is left for the base64 payload handed *to* Remy, which
53
+ * nothing shrinks on the way in.
54
54
  */
55
55
  export declare function validateImageType(file: File): string | null;
56
56
  /**
57
- * Longest edge the editor writes out.
57
+ * Longest edge an upload is allowed to keep.
58
58
  *
59
- * Generous media-service derives every ratio from this original, and 2400px still
60
- * covers a retina hero on the biggest POS screen but bounded, so a 48MP phone photo
61
- * cannot land as a 20 MB original that has to be re-encoded on every later edit.
59
+ * Every picked file is re-encoded to fit this box (`compressImageForUpload`), so it is
60
+ * the effective ceiling on what reaches media-service rather than just a cap the editor
61
+ * happens to respect. 2000px still covers a retina hero on the biggest POS screen, and
62
+ * it is what the pre-multi-image thumbnail flow wrote out, so nothing regresses against
63
+ * the images already in the wild.
62
64
  */
63
- export declare const MAX_IMAGE_EDGE = 2400;
65
+ export declare const MAX_IMAGE_EDGE = 2000;
66
+ /**
67
+ * What an upload is aimed at, as opposed to what the service will still accept.
68
+ *
69
+ * Exported because it is a contract, not a tuning knob: POS cannot render a large image —
70
+ * it crashes — so "did these bytes go through compression" is a question callers have to be
71
+ * able to ask (`meetsUploadBudget`), not just something this module does on the way past.
72
+ *
73
+ * `MAX_IMAGE_BYTES` is a 413 boundary, not a target, and using it as one is what merchants
74
+ * saw as "compression that does nothing": a heavy original re-encoded at `OUTPUT_QUALITY`
75
+ * landed at 8 MB, sat under the limit, and no further round ran. A 2000px JPEG of a real
76
+ * photo is a few hundred KB, so this sits just above where photography lands and below
77
+ * anything that would be heavy on a POS tile or a QR menu card. Enforced by the loop in
78
+ * `canvasToFile`, which spends quality to get here — a full-frame 2000x2000 photo does
79
+ * cross it and comes back one quality step down, which is the intended trade.
80
+ */
81
+ export declare const TARGET_UPLOAD_BYTES: number;
64
82
  /**
65
83
  * Encodes an edited canvas as a file guaranteed to be uploadable.
66
84
  *
@@ -70,8 +88,10 @@ export declare const MAX_IMAGE_EDGE = 2400;
70
88
  * the dead end this feature exists to remove. Quality is spent first and pixels second,
71
89
  * because a slightly softer photo beats a smaller one.
72
90
  *
73
- * PNG is kept only when the caller asks for it (a source with transparency); it has no
74
- * quality lever, so it is shrunk by size alone.
91
+ * Callers ask for JPEG (see `compressImageForUpload`); `mime` still honours a deliberate
92
+ * PNG, which has no quality lever and is shrunk by size alone. Lossy output is flattened
93
+ * onto white first, in place — every canvas reaching here is minted for this encode (a
94
+ * cropper result or `fileToCanvas` output), never one a caller keeps using.
75
95
  */
76
96
  export declare function canvasToFile(canvas: HTMLCanvasElement, options: {
77
97
  fileName: string;
@@ -80,16 +100,57 @@ export declare function canvasToFile(canvas: HTMLCanvasElement, options: {
80
100
  maxBytes?: number;
81
101
  }): Promise<File>;
82
102
  /**
83
- * Hands back the file untouched when it already fits `MAX_IMAGE_BYTES`, and otherwise
84
- * re-encodes it under the limit exactly as the editor would — same edge cap, same
85
- * PNG-stays-PNG rule.
103
+ * Whether a file already satisfies everything an upload guarantees, so re-encoding it would
104
+ * only cost a generation of JPEG loss.
105
+ *
106
+ * Deliberately strict on all three axes, because the consumer is unforgiving: POS crashes on
107
+ * a large image, so anything that cannot be proven compressed has to be compressed. JPEG is
108
+ * required rather than preferred — a PNG in budget today is still a format whose weight does
109
+ * not track its pixel count, and it is the format that produced the 8 MB "compressed" upload
110
+ * in the first place.
111
+ *
112
+ * `dimensions` is optional only because a caller that has not decoded the image yet cannot
113
+ * supply it; omitting it makes this answer the question for bytes and format alone, so a
114
+ * caller that can decode should pass it.
115
+ */
116
+ export declare function meetsUploadBudget(file: File, dimensions?: {
117
+ width: number;
118
+ height: number;
119
+ } | null): boolean;
120
+ /**
121
+ * Re-encodes a picked file as a `MAX_IMAGE_EDGE` / `OUTPUT_QUALITY` JPEG before upload.
122
+ *
123
+ * Unconditional, and unconditionally JPEG — both learned the hard way. The multi-image
124
+ * rewrite replaced the single-thumbnail flow's always-compress (4:3, 2000px, JPEG q0.75)
125
+ * with a plain size check, so a full-resolution phone photo reached media-service verbatim
126
+ * whenever it sat under `MAX_IMAGE_BYTES`; putting the edge cap back still kept a PNG
127
+ * source as PNG, and canvas PNG is lossless, so a 10 MB photo saved as PNG came back ~8 MB
128
+ * and counted as compressed. Product photos gain nothing from an alpha channel, so
129
+ * transparency is flattened onto white and everything leaves as JPEG. (The backfill script
130
+ * still keeps a genuinely transparent PNG as PNG: it rewrites production originals
131
+ * irreversibly, so changing what an already-approved image shows is a line it does not
132
+ * cross. A new upload is previewed in the editor before the merchant confirms it.)
86
133
  *
87
- * This is for the paths that upload a picked file without opening the editor (the
88
- * "upload the rest as-is" batch): they get the same guarantee a confirmed edit has,
89
- * instead of handing media-service bytes it will refuse with a 413.
134
+ * The only file handed back untouched is a JPEG that is already leaner than the encode
135
+ * one saved below `OUTPUT_QUALITY` grows if re-encoded, and skipping that spares it a
136
+ * second generation of loss for nothing. Restricted to JPEG sources on purpose, rather
137
+ * than "whatever is smaller": product images have no use for an alpha channel, so no
138
+ * upload path may leave a PNG or WebP in storage, and a JPEG source cannot carry
139
+ * transparency in the first place. The trade is known and accepted — a lean PNG of flat
140
+ * colour (a logo, a screenshot of a menu) re-encodes bigger, because JPEG spends bits on
141
+ * exactly the hard edges PNG stores for free. Every stored original being one format is
142
+ * worth that.
143
+ *
144
+ * Note what the passthrough cannot wave through: the encode it is compared against is
145
+ * bounded by `TARGET_UPLOAD_BYTES`, so a heavy original has nothing lean to tie with. The
146
+ * comparison used to be against a same-format encode, which is how a 10 MB PNG kept its
147
+ * own bytes.
148
+ */
149
+ export declare function compressImageForUpload(file: File, unreadableMessage?: string): Promise<File>;
150
+ /**
151
+ * Converts Remy's base64 result into a File. It is not compressed here — the caller runs
152
+ * it through `compressImageForUpload` like any other upload.
90
153
  */
91
- export declare function ensureUploadableImage(file: File, unreadableMessage?: string): Promise<File>;
92
- /** Converts Remy's base64 result into an uploadable file without re-encoding it. */
93
154
  export declare function dataUrlToFile(dataUrl: string, fileName?: string): Promise<File>;
94
155
  /** `confirm` needs the real pixel size, and only the browser has it before upload. */
95
156
  export declare function readImageDimensions(file: File, unreadableMessage?: string): Promise<{