@feedmepos/mf-miniprogram-v2 0.2.2-dev.11 → 0.2.2-dev.13

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.
@@ -1,8 +1,8 @@
1
1
  import { defineComponent as b, computed as p, ref as w, onMounted as D, onScopeDispose as A, resolveComponent as B, openBlock as c, createElementBlock as a, createElementVNode as C, toDisplayString as l, unref as r, Fragment as Z, renderList as E, normalizeStyle as U, createVNode as d, withCtx as H, createTextVNode as g, createCommentVNode as G } from "vue";
2
2
  import { useRoute as S } from "vue-router";
3
- import { a as O } from "./routes-Boz_WlNM.js";
3
+ import { a as O } from "./routes-DXQSkGM7.js";
4
4
  import { b as j, c as N, e as q } from "./controlPlane-CoEgf9BA.js";
5
- import { u as I } from "./portalContext-C4HL_0kl.js";
5
+ import { u as I } from "./portalContext-DCwZcTKL.js";
6
6
  import { p as u } from "./portalNavigation-DOF4Ah49.js";
7
7
  import { i as R, u as T } from "./useBrandKit-BlKlqpo2.js";
8
8
  import { _ as K } from "./StatusBadge.vue_vue_type_script_setup_true_lang-Bh9Eoe_H.js";
@@ -1,9 +1,9 @@
1
1
  import { defineComponent as U, ref as j, onMounted as B, resolveComponent as I, openBlock as n, createBlock as P, withCtx as C, createVNode as r, createElementVNode as o, toDisplayString as _, createElementBlock as d, Fragment as D, createCommentVNode as S, onScopeDispose as A, createTextVNode as F, renderList as O, unref as g } from "vue";
2
2
  import { useRoute as E, useRouter as Y } from "vue-router";
3
3
  import { useDialog as z } from "@feedmepos/ui-library";
4
- import { a as R } from "./routes-Boz_WlNM.js";
4
+ import { a as R } from "./routes-DXQSkGM7.js";
5
5
  import { c as x, e as L, a as H } from "./controlPlane-CoEgf9BA.js";
6
- import { u as J } from "./portalContext-C4HL_0kl.js";
6
+ import { u as J } from "./portalContext-DCwZcTKL.js";
7
7
  import { w as N } from "./portalNavigation-DOF4Ah49.js";
8
8
  import { m as G } from "./index-D5qXvcfE.js";
9
9
  import { A as K } from "./AppTemplatePicker-C0lZyhK2.js";
@@ -1,7 +1,7 @@
1
1
  import { defineComponent as F, openBlock as e, createElementBlock as n, createElementVNode as o, toDisplayString as d, createCommentVNode as k, ref as w, computed as m, onMounted as q, resolveComponent as f, createVNode as p, unref as i, Fragment as v, renderList as b, normalizeClass as A, createBlock as y, withCtx as R } from "vue";
2
2
  import { useRoute as z } from "vue-router";
3
3
  import { _ as T } from "./_plugin-vue_export-helper-CHgC5LLL.js";
4
- import { u as D, c as G, f as K, _ as h, t as O } from "./useModuleCatalog-DqECds3F.js";
4
+ import { u as D, c as G, f as K, _ as h, t as O } from "./useModuleCatalog-CVi8031k.js";
5
5
  const P = { class: "card" }, U = { class: "card__head" }, j = { class: "card__name fm-typo-en-body-md-600 text-portal-text-primary" }, H = { class: "card__version fm-typo-en-body-sm-400 text-portal-text-muted" }, J = { class: "card__description fm-typo-en-body-sm-400 text-portal-text-muted" }, Q = { class: "card__tags" }, W = { class: "card__tag card__tag--tier fm-typo-en-body-sm-600" }, X = {
6
6
  key: 0,
7
7
  class: "card__tag card__tag--slot fm-typo-en-body-sm-400"
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as C, ref as M, computed as u, watch as T, resolveComponent as g, openBlock as n, createElementBlock as l, createElementVNode as e, toDisplayString as i, createCommentVNode as _, Fragment as I, renderList as S, createVNode as k, onMounted as B, unref as d, withCtx as L, createBlock as v } from "vue";
2
2
  import { useRoute as N, useRouter as P } from "vue-router";
3
- import { m as q, i as A, u as F, _ as w } from "./useModuleCatalog-DqECds3F.js";
3
+ import { m as q, i as A, u as F, _ as w } from "./useModuleCatalog-CVi8031k.js";
4
4
  import { useDialog as V } from "@feedmepos/ui-library";
5
5
  import { _ as E } from "./_plugin-vue_export-helper-CHgC5LLL.js";
6
6
  const R = { class: "detail" }, j = { class: "detail__head" }, z = { class: "detail__name fm-typo-en-title-sm-600 text-portal-text-primary" }, K = { class: "detail__version fm-typo-en-body-md-400 text-portal-text-muted" }, O = {
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as p, resolveComponent as i, openBlock as l, createElementBlock as m, createElementVNode as o, createVNode as r, unref as t, withCtx as u, createTextVNode as c } from "vue";
2
2
  import { useRoute as d } from "vue-router";
3
- import { u as g } from "./portalContext-C4HL_0kl.js";
3
+ import { u as g } from "./portalContext-DCwZcTKL.js";
4
4
  import { w as f } from "./portalNavigation-DOF4Ah49.js";
5
5
  import { P as k } from "./PortalIcon-DO0VrIoY.js";
6
6
  const w = { class: "portal-page" }, y = { class: "portal-page-inner" }, b = { class: "portal-section portal-empty" }, E = /* @__PURE__ */ p({
@@ -3,7 +3,7 @@ import { useRoute as N } from "vue-router";
3
3
  import { e as _, a as $ } from "./index-D5qXvcfE.js";
4
4
  import { l as B, e as E } from "./controlPlane-CoEgf9BA.js";
5
5
  import { useCoreStore as F } from "@feedmepos/mf-common";
6
- import { u as U } from "./portalContext-C4HL_0kl.js";
6
+ import { u as U } from "./portalContext-DCwZcTKL.js";
7
7
  import { l as V } from "./portalNavigation-DOF4Ah49.js";
8
8
  import { _ as q } from "./_plugin-vue_export-helper-CHgC5LLL.js";
9
9
  const L = { class: "portal-page" }, R = { class: "portal-page-inner settings-page" }, T = { class: "portal-page-heading" }, D = ["href"], H = {
@@ -0,0 +1,297 @@
1
+ import { defineComponent as Y, ref as r, computed as D, resolveComponent as h, openBlock as n, createBlock as S, withCtx as I, createVNode as d, createElementVNode as s, toDisplayString as c, createCommentVNode as F, unref as J, createElementBlock as p, onMounted as oe, onScopeDispose as ne, createTextVNode as k, Fragment as K, renderList as se } from "vue";
2
+ import { a as A } from "./routes-DXQSkGM7.js";
3
+ import { useDialog as ie } from "@feedmepos/ui-library";
4
+ import { c as P, e as E } from "./controlPlane-CoEgf9BA.js";
5
+ import { _ as re } from "./StatusBadge.vue_vue_type_script_setup_true_lang-Bh9Eoe_H.js";
6
+ import { _ as Q } from "./_plugin-vue_export-helper-CHgC5LLL.js";
7
+ const de = ["qsr", "coffee", "tea"], W = [
8
+ // `label` and `description` are MERCHANT-FACING: the portal's picker renders
9
+ // them, and they are the only thing a merchant chooses on. Say what the app does
10
+ // for their customers, never which package it is built from — the SDK is real and
11
+ // load-bearing and means nothing to the person making this decision.
12
+ {
13
+ id: "miniprogram-vue",
14
+ label: "Phone ordering app",
15
+ description: "Menu browsing, cart and checkout, membership and rewards, and order history — for customers ordering on their own phone.",
16
+ industries: [],
17
+ environments: ["dev", "prod"],
18
+ default: !0
19
+ },
20
+ {
21
+ id: "miniprogram-vue-v2",
22
+ label: "Phone, kiosk and tablet",
23
+ description: "Everything in the phone app, plus self-order kiosk and in-store tablet surfaces sharing the same menu, cart and membership.",
24
+ industries: [],
25
+ // Dev only, deliberately. It has never been provisioned end-to-end: the
26
+ // preview proxy, the component-library unpack and the release build have
27
+ // only been exercised locally. Add 'prod' after a real merchant has run
28
+ // through all three.
29
+ environments: ["dev"]
30
+ }
31
+ ], ue = {
32
+ key: 2,
33
+ class: "portal-error",
34
+ role: "alert"
35
+ }, ce = /* @__PURE__ */ Y({
36
+ __name: "TemplateChoiceDialog",
37
+ props: {
38
+ choice: {}
39
+ },
40
+ emits: ["saved", "close"],
41
+ setup(x, { emit: g }) {
42
+ var B, U, L, R, O, z, M, j;
43
+ const i = x, C = g, m = r(((B = i.choice) == null ? void 0 : B.id) ?? ""), v = r(((U = i.choice) == null ? void 0 : U.appTemplateId) ?? ((L = W[0]) == null ? void 0 : L.id) ?? ""), b = r(((R = i.choice) == null ? void 0 : R.restaurantStyle) ?? "qsr"), f = r(((O = i.choice) == null ? void 0 : O.label) ?? ""), y = r(((z = i.choice) == null ? void 0 : z.description) ?? ""), T = r((((M = i.choice) == null ? void 0 : M.industries) ?? []).join(", ")), V = r(((j = i.choice) == null ? void 0 : j.default) ?? !1), e = r(!1), u = r(""), l = D(() => !!i.choice), t = W.map((_) => ({ label: _.label, value: _.id })), w = D(() => v.value === "miniprogram-vue-v2"), X = de.map((_) => ({ label: _, value: _ })), N = D(
44
+ () => !e.value && f.value.trim().length > 0 && y.value.trim().length > 0 && (l.value ? !0 : /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(m.value.trim()))
45
+ );
46
+ async function Z() {
47
+ if (!N.value) return;
48
+ e.value = !0, u.value = "";
49
+ const _ = {
50
+ ...l.value ? {} : { id: m.value.trim() },
51
+ appTemplateId: v.value,
52
+ label: f.value.trim(),
53
+ description: y.value.trim(),
54
+ industries: T.value.split(",").map((a) => a.trim()).filter(Boolean),
55
+ default: V.value,
56
+ ...w.value ? { restaurantStyle: b.value } : {}
57
+ };
58
+ try {
59
+ await P(
60
+ l.value ? A.appTemplateChoice(i.choice.id) : A.appTemplateChoices(),
61
+ { method: l.value ? "PATCH" : "POST", body: JSON.stringify(_) }
62
+ ), C("saved");
63
+ } catch (a) {
64
+ u.value = E(a);
65
+ } finally {
66
+ e.value = !1;
67
+ }
68
+ }
69
+ return (_, a) => {
70
+ const $ = h("FmTextField"), q = h("FmSelect"), ee = h("FmTextarea"), te = h("FmSwitch"), G = h("FmButton"), ae = h("FmCard"), le = h("FmForm");
71
+ return n(), S(le, { onValidationSuccess: Z }, {
72
+ default: I(() => [
73
+ d(ae, { class: "template-choice-dialog" }, {
74
+ default: I(() => {
75
+ var H;
76
+ return [
77
+ s("h2", null, c(l.value ? `Edit ${(H = x.choice) == null ? void 0 : H.label}` : "New template choice"), 1),
78
+ l.value ? F("", !0) : (n(), S($, {
79
+ key: 0,
80
+ modelValue: m.value,
81
+ "onUpdate:modelValue": a[0] || (a[0] = (o) => m.value = o),
82
+ label: "Choice id",
83
+ placeholder: "e.g. miniprogram-vue-v2-bakery",
84
+ "helper-text": "Lowercase, kebab-case. Cannot be changed after creation.",
85
+ disabled: e.value,
86
+ rules: [(o) => /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(o.trim()) || "Lowercase kebab-case, e.g. miniprogram-vue-v2-bakery"]
87
+ }, null, 8, ["modelValue", "disabled", "rules"])),
88
+ d(q, {
89
+ modelValue: v.value,
90
+ "onUpdate:modelValue": a[1] || (a[1] = (o) => v.value = o),
91
+ label: "Physical template",
92
+ items: J(t),
93
+ disabled: e.value || l.value
94
+ }, null, 8, ["modelValue", "items", "disabled"]),
95
+ w.value ? (n(), S(q, {
96
+ key: 1,
97
+ modelValue: b.value,
98
+ "onUpdate:modelValue": a[2] || (a[2] = (o) => b.value = o),
99
+ label: "Restaurant style",
100
+ "helper-text": "Only styles templates/miniprogram-vue-v2/src/brand/recipes.ts already implements.",
101
+ items: J(X),
102
+ disabled: e.value
103
+ }, null, 8, ["modelValue", "items", "disabled"])) : F("", !0),
104
+ d($, {
105
+ modelValue: f.value,
106
+ "onUpdate:modelValue": a[3] || (a[3] = (o) => f.value = o),
107
+ label: "Label",
108
+ placeholder: "Shown to merchants in the picker",
109
+ disabled: e.value
110
+ }, null, 8, ["modelValue", "disabled"]),
111
+ d(ee, {
112
+ modelValue: y.value,
113
+ "onUpdate:modelValue": a[4] || (a[4] = (o) => y.value = o),
114
+ label: "Description",
115
+ placeholder: "One or two sentences on what the merchant gets",
116
+ disabled: e.value
117
+ }, null, 8, ["modelValue", "disabled"]),
118
+ d($, {
119
+ modelValue: T.value,
120
+ "onUpdate:modelValue": a[5] || (a[5] = (o) => T.value = o),
121
+ label: "Industries (comma-separated)",
122
+ placeholder: "e.g. Food & beverage",
123
+ disabled: e.value
124
+ }, null, 8, ["modelValue", "disabled"]),
125
+ d(te, {
126
+ modelValue: V.value,
127
+ "onUpdate:modelValue": a[6] || (a[6] = (o) => V.value = o),
128
+ label: "Default choice",
129
+ sublabel: "Used when a provision request names none",
130
+ disabled: e.value
131
+ }, null, 8, ["modelValue", "disabled"]),
132
+ u.value ? (n(), p("p", ue, c(u.value), 1)) : F("", !0),
133
+ s("footer", null, [
134
+ d(G, {
135
+ label: "Cancel",
136
+ variant: "tertiary",
137
+ disabled: e.value,
138
+ onClick: a[7] || (a[7] = (o) => C("close"))
139
+ }, null, 8, ["disabled"]),
140
+ d(G, {
141
+ label: l.value ? "Save" : "Create",
142
+ type: "submit",
143
+ loading: e.value,
144
+ disabled: !N.value
145
+ }, null, 8, ["label", "loading", "disabled"])
146
+ ])
147
+ ];
148
+ }),
149
+ _: 1
150
+ })
151
+ ]),
152
+ _: 1
153
+ });
154
+ };
155
+ }
156
+ }), me = /* @__PURE__ */ Q(ce, [["__scopeId", "data-v-2b30dcea"]]), pe = { class: "portal-page" }, ve = { class: "portal-page-inner" }, be = { class: "portal-page-heading" }, _e = {
157
+ key: 0,
158
+ class: "portal-error",
159
+ role: "alert"
160
+ }, he = {
161
+ key: 1,
162
+ role: "status"
163
+ }, fe = {
164
+ key: 2,
165
+ class: "template-choices__list",
166
+ "aria-label": "Template choices"
167
+ }, ye = { class: "template-choices__name" }, ge = { class: "template-choices__label" }, Ce = { key: 0 }, ke = { class: "template-choices__id" }, Te = { class: "template-choices__meta" }, Ve = ["datetime"], we = { class: "template-choices__actions" }, Se = /* @__PURE__ */ Y({
168
+ __name: "TemplateCenterView",
169
+ setup(x) {
170
+ const g = ie(), i = r([]), C = r(!0), m = r(""), v = new AbortController();
171
+ async function b() {
172
+ C.value = !0, m.value = "";
173
+ try {
174
+ const e = await P(A.appTemplateChoices(), {
175
+ signal: v.signal
176
+ });
177
+ i.value = e.choices;
178
+ } catch (e) {
179
+ v.signal.aborted || (m.value = E(e));
180
+ } finally {
181
+ C.value = !1;
182
+ }
183
+ }
184
+ function f(e) {
185
+ g.open({
186
+ title: e ? `Edit ${e.label}` : "New template choice",
187
+ dialogComponent: me,
188
+ dialogComponentProps: {
189
+ choice: e,
190
+ onClose: () => g.close(),
191
+ onSaved: () => {
192
+ g.close(), b();
193
+ }
194
+ }
195
+ });
196
+ }
197
+ async function y(e, u) {
198
+ try {
199
+ await P(
200
+ u === "archived" ? A.appTemplateChoiceArchive(e.id) : A.appTemplateChoiceRestore(e.id),
201
+ { method: "POST" }
202
+ ), await b();
203
+ } catch (l) {
204
+ m.value = E(l);
205
+ }
206
+ }
207
+ function T(e) {
208
+ g.open({
209
+ title: `Archive ${e.label}?`,
210
+ message: "It stops appearing for new projects. Merchants already provisioned from it are unaffected — it is never consulted again after provisioning.",
211
+ primaryActions: { text: "Archive", close: !0, variant: "primary" },
212
+ secondaryActions: { text: "Cancel", close: !0, variant: "tertiary" }
213
+ }).onPrimary(() => void y(e, "archived"));
214
+ }
215
+ function V(e) {
216
+ return new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(new Date(e));
217
+ }
218
+ return oe(() => void b()), ne(() => v.abort()), (e, u) => {
219
+ const l = h("FmButton");
220
+ return n(), p("div", pe, [
221
+ s("div", ve, [
222
+ s("header", be, [
223
+ u[1] || (u[1] = s("div", null, [
224
+ s("p", { class: "portal-eyebrow" }, "Internal"),
225
+ s("h1", null, "Template Center")
226
+ ], -1)),
227
+ d(l, {
228
+ label: "New choice",
229
+ icon: "add",
230
+ onClick: u[0] || (u[0] = (t) => f())
231
+ })
232
+ ]),
233
+ m.value ? (n(), p("p", _e, [
234
+ k(c(m.value) + " ", 1),
235
+ d(l, {
236
+ label: "Retry",
237
+ variant: "tertiary",
238
+ onClick: b
239
+ })
240
+ ])) : C.value ? (n(), p("p", he, "Loading template choices…")) : (n(), p("section", fe, [
241
+ (n(!0), p(K, null, se(i.value, (t) => (n(), p("article", {
242
+ key: t.id,
243
+ class: "template-choices__row"
244
+ }, [
245
+ s("div", ye, [
246
+ s("span", ge, [
247
+ k(c(t.label), 1),
248
+ t.default ? (n(), p("span", Ce, " · Default")) : F("", !0)
249
+ ]),
250
+ s("span", ke, c(t.id), 1),
251
+ s("span", Te, [
252
+ k(c(t.appTemplateId), 1),
253
+ t.restaurantStyle ? (n(), p(K, { key: 0 }, [
254
+ k(" · " + c(t.restaurantStyle), 1)
255
+ ], 64)) : F("", !0),
256
+ k(" · " + c(t.industries.join(", ") || "General-purpose") + " · " + c((t.environments ?? []).join(", ")), 1)
257
+ ])
258
+ ]),
259
+ d(re, {
260
+ variant: t.status === "active" ? "success" : "neutral"
261
+ }, {
262
+ default: I(() => [
263
+ k(c(t.status === "active" ? "Active" : "Archived"), 1)
264
+ ]),
265
+ _: 2
266
+ }, 1032, ["variant"]),
267
+ s("time", {
268
+ datetime: t.updatedAt
269
+ }, c(V(t.updatedAt)), 9, Ve),
270
+ s("div", we, [
271
+ d(l, {
272
+ label: "Edit",
273
+ variant: "secondary",
274
+ onClick: (w) => f(t)
275
+ }, null, 8, ["onClick"]),
276
+ t.status === "active" ? (n(), S(l, {
277
+ key: 0,
278
+ label: "Archive",
279
+ variant: "tertiary",
280
+ onClick: (w) => T(t)
281
+ }, null, 8, ["onClick"])) : (n(), S(l, {
282
+ key: 1,
283
+ label: "Restore",
284
+ variant: "tertiary",
285
+ onClick: (w) => y(t, "active")
286
+ }, null, 8, ["onClick"]))
287
+ ])
288
+ ]))), 128))
289
+ ]))
290
+ ])
291
+ ]);
292
+ };
293
+ }
294
+ }), Pe = /* @__PURE__ */ Q(Se, [["__scopeId", "data-v-da7cd846"]]);
295
+ export {
296
+ Pe as default
297
+ };
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as c, watchEffect as a, openBlock as n, createElementBlock as p } from "vue";
2
2
  import { useRoute as i, useRouter as u } from "vue-router";
3
- import { u as l } from "./portalContext-C4HL_0kl.js";
3
+ import { u as l } from "./portalContext-DCwZcTKL.js";
4
4
  import { w as m, a as f } from "./portalNavigation-DOF4Ah49.js";
5
5
  const _ = {
6
6
  class: "portal-loading",
package/dist/app.js CHANGED
@@ -4,24 +4,24 @@ const o = [
4
4
  path: "/platforms/mobile",
5
5
  name: "miniprogram-v2-mobile-projects",
6
6
  meta: { title: "Mobile" },
7
- component: () => import("./MobileProjectsView-QbURgYLB.js")
7
+ component: () => import("./MobileProjectsView-BZw9pWnK.js")
8
8
  },
9
9
  {
10
10
  path: "/",
11
11
  name: "miniprogram-v2-ecosystem",
12
12
  meta: { title: "Ecosystem" },
13
13
  beforeEnter: (e) => ["workspace", "releases", "sessions"].includes(String(e.query.view)) ? { name: "miniprogram-v2-control", query: e.query } : !0,
14
- component: () => import("./EcosystemView-BgjtBJy_.js")
14
+ component: () => import("./EcosystemView-sb7DUkNL.js")
15
15
  },
16
16
  {
17
17
  path: "/workspace",
18
18
  name: "miniprogram-v2-control",
19
- component: () => import("./WorkspaceEntryView-e2EUnq9A.js")
19
+ component: () => import("./WorkspaceEntryView-hNqYjBTr.js")
20
20
  },
21
21
  {
22
22
  path: "/p/:projectId/:view(workspace|releases|sessions)?",
23
23
  name: "miniprogram-v2-project",
24
- component: () => import("./ControlPlaneView-BN9srEtl.js")
24
+ component: () => import("./ControlPlaneView-C7Eg9mU3.js")
25
25
  },
26
26
  {
27
27
  path: "/brand-kit",
@@ -33,13 +33,13 @@ const o = [
33
33
  path: "/pages",
34
34
  name: "miniprogram-v2-pages",
35
35
  meta: { title: "Pages" },
36
- component: () => import("./PagesView-CegMd6GC.js")
36
+ component: () => import("./PagesView-DTGhet9j.js")
37
37
  },
38
38
  {
39
39
  path: "/settings",
40
40
  name: "miniprogram-v2-settings",
41
41
  meta: { title: "Settings" },
42
- component: () => import("./PortalSettingsView-Bqw8tMZb.js")
42
+ component: () => import("./PortalSettingsView-BrO2Yt65.js")
43
43
  },
44
44
  ...["tablet", "kiosk"].map((e) => ({
45
45
  path: `/platforms/${e}`,
@@ -53,7 +53,7 @@ const o = [
53
53
  path: "/modules",
54
54
  name: "miniprogram-v2-module-center",
55
55
  meta: { title: "Module library" },
56
- component: () => import("./ModuleCenterView-DyMr3iWV.js")
56
+ component: () => import("./ModuleCenterView-CQrJ9pyE.js")
57
57
  },
58
58
  {
59
59
  // Keyed by the module's directory name, which is what the catalog, the
@@ -61,16 +61,25 @@ const o = [
61
61
  path: "/modules/:name",
62
62
  name: "miniprogram-v2-module-detail",
63
63
  meta: { title: "Module library" },
64
- component: () => import("./ModuleDetailView-BeXK89Cs.js")
64
+ component: () => import("./ModuleDetailView-CpBktRqD.js")
65
+ },
66
+ {
67
+ // Internal-only: no nav entry links here, reached by typing the URL. The
68
+ // `beforeEach` guard in `./index.ts` checks `meta.requiresAdmin` and sends a
69
+ // non-admin to the same place an unmatched URL goes, below.
70
+ path: "/internal/template-center",
71
+ name: "miniprogram-v2-template-center",
72
+ meta: { title: "Template Center", requiresAdmin: !0 },
73
+ component: () => import("./TemplateCenterView-BjA03jMI.js")
65
74
  },
66
75
  {
67
76
  path: "/:pathMatch(.*)*",
68
77
  redirect: (e) => ({ name: "miniprogram-v2-ecosystem", query: e.query, params: {} })
69
78
  }
70
- ], r = {}, a = t(() => import("./App-agMiJ0tU.js")), i = t(() => import("./LegacyWorkspaceEntry-opz_kWz9.js"));
79
+ ], r = {}, a = t(() => import("./App-CR0BBDaq.js")), n = t(() => import("./LegacyWorkspaceEntry-opz_kWz9.js"));
71
80
  export {
72
81
  a as FmApp,
73
- i as MiniprogramWorkspace,
82
+ n as MiniprogramWorkspace,
74
83
  r as i18nMessages,
75
84
  o as routes
76
85
  };
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feedmepos/mf-miniprogram-v2",
3
- "version": "0.2.2-dev.11",
3
+ "version": "0.2.2-dev.13",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -1,4 +1,4 @@
1
- import { a as b } from "./routes-Boz_WlNM.js";
1
+ import { a as b } from "./routes-DXQSkGM7.js";
2
2
  import { useCoreStore as d } from "@feedmepos/mf-common";
3
3
  import { c as g, e as h } from "./controlPlane-CoEgf9BA.js";
4
4
  import { provide as y, computed as f, ref as c, watch as C, onScopeDispose as w, inject as x } from "vue";
@@ -0,0 +1,66 @@
1
+ const o = (e, s) => `/api/businesses/${e}/projects/${s}`, r = {
2
+ projects: (e) => `/api/businesses/${e}/projects`,
3
+ portalContext: (e) => `/api/businesses/${e}/portal-context`,
4
+ project: (e, s) => o(e, s),
5
+ provision: (e, s) => `${o(e, s)}/provision`,
6
+ refreshSlug: (e, s) => `${o(e, s)}/refresh-slug`,
7
+ sessions: (e, s) => `${o(e, s)}/sessions`,
8
+ session: (e, s, i) => `${o(e, s)}/sessions/${i}`,
9
+ messages: (e, s, i) => `${r.session(e, s, i)}/messages`,
10
+ startStatus: (e, s, i) => `${r.session(e, s, i)}/start-status`,
11
+ changes: (e, s, i, a = !1) => `${r.session(e, s, i)}/changes${a ? "?refresh=1" : ""}`,
12
+ checkpoints: (e, s, i) => `${r.session(e, s, i)}/checkpoints`,
13
+ aiBillingPreflight: (e, s, i) => `${r.session(e, s, i)}/ai-billing/preflight`,
14
+ restoreCheckpoint: (e, s, i, a) => `${r.checkpoints(e, s, i)}/${a}/restore`,
15
+ previewBridgeTicket: (e, s, i) => `${r.session(e, s, i)}/preview-bridge/ticket`,
16
+ previewBridgeSocket: (e, s, i) => `${r.session(e, s, i)}/preview-bridge/socket`,
17
+ uploads: (e, s, i, a = "") => `${r.session(e, s, i)}/uploads${a ? `?${a}` : ""}`,
18
+ archive: (e, s, i) => `${r.session(e, s, i)}/archive`,
19
+ commit: (e, s, i) => `${r.session(e, s, i)}/commit`,
20
+ resume: (e, s, i) => `${r.session(e, s, i)}/resume`,
21
+ restartPreview: (e, s, i) => `${r.session(e, s, i)}/restart-preview`,
22
+ fork: (e, s, i) => `${r.session(e, s, i)}/fork`,
23
+ flushEvents: (e, s, i) => `${r.session(e, s, i)}/events/flush`,
24
+ revertTurn: (e, s, i) => `${r.session(e, s, i)}/turns/revert`,
25
+ unrevertTurn: (e, s, i) => `${r.session(e, s, i)}/turns/unrevert`,
26
+ releases: (e, s) => `${o(e, s)}/releases`,
27
+ /** Internal-admin only. Extracts a new restaurant style out of a session's
28
+ * verified checkpoint and, once confirmed, opens a PR against this repo. */
29
+ publishAsTemplate: (e, s) => `${o(e, s)}/publish-as-template`,
30
+ publishRelease: (e, s, i) => `${r.releases(e, s)}/${i}/publish`,
31
+ releasePreviewUrl: (e, s, i) => `${r.releases(e, s)}/${i}/preview-url`,
32
+ rollbackToRelease: (e, s, i) => `${o(e, s)}/rollback-to-release/${i}`,
33
+ rollbackToV1: (e, s) => `${o(e, s)}/rollback-to-v1`,
34
+ start: (e, s, i) => {
35
+ const a = new URLSearchParams();
36
+ e && a.set("businessId", e), s && a.set("projectId", s), i && a.set("sessionId", i);
37
+ const t = a.toString();
38
+ return `/api/start${t ? `?${t}` : ""}`;
39
+ },
40
+ opencode: (e = "") => `/api/opencode${e ? `/${e.replace(/^\/+/, "")}` : ""}`,
41
+ /** The shared component library's catalog. Deliberately not under a
42
+ * business/project path: the library belongs to no business, and the
43
+ * module centre is not inside a workspace. */
44
+ componentLibraryCatalog: () => "/api/component-library/catalog",
45
+ /** The self-contained preview document the module centre frames. Fetched with
46
+ * the portal's bearer and assigned to an iframe's `srcdoc`, never used as an
47
+ * `<iframe src>` — a navigation request carries no Authorization header,
48
+ * which is what a signed URL would otherwise exist to work around. */
49
+ componentLibraryPreview: () => "/api/component-library/preview",
50
+ /** The application templates this environment can provision, for the portal's
51
+ * picker. Not under a business/project path: the answer is a property of
52
+ * the environment, and it is needed BEFORE a project exists. */
53
+ appTemplates: () => "/api/app-templates",
54
+ /** Whether the caller is an internal admin — for the portal to decide whether to
55
+ * show internal-only entry points such as the Template Center. The real
56
+ * enforcement is on every admin route itself; this is a UI convenience. */
57
+ adminWhoami: () => "/api/admin/whoami",
58
+ /** Template Center: the FULL choice catalog (active + archived), internal-admin only. */
59
+ appTemplateChoices: () => "/api/admin/app-template-choices",
60
+ appTemplateChoice: (e) => `/api/admin/app-template-choices/${e}`,
61
+ appTemplateChoiceArchive: (e) => `${r.appTemplateChoice(e)}/archive`,
62
+ appTemplateChoiceRestore: (e) => `${r.appTemplateChoice(e)}/restore`
63
+ };
64
+ export {
65
+ r as a
66
+ };