@frontify/frontify-cli 5.10.3 → 6.0.0-alpha.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.
package/dist/index.mjs CHANGED
@@ -1,966 +1,975 @@
1
1
  #!/usr/bin/env node
2
- import ue, { join as m, resolve as O } from "node:path";
3
- import { exit as W } from "node:process";
4
- import { cac as he } from "cac";
5
- import j from "prompts";
6
- import E from "fast-glob";
7
- import Q from "open";
8
- import b from "picocolors";
9
- import { readFileSync as N, writeFileSync as X, readdirSync as ee, mkdirSync as ye, statSync as ge, copyFileSync as we } from "node:fs";
10
- import ve from "conf";
11
- import be from "glob-to-regexp";
2
+ import e, { join as t, resolve as n } from "node:path";
3
+ import { exit as r } from "node:process";
4
+ import { cac as i } from "cac";
5
+ import a from "prompts";
6
+ import o from "fast-glob";
7
+ import s from "open";
8
+ import c from "picocolors";
9
+ import { copyFileSync as l, mkdirSync as u, readFileSync as d, readdirSync as f, statSync as p, writeFileSync as m } from "node:fs";
10
+ import h from "conf";
11
+ import g from "glob-to-regexp";
12
12
  import "node:crypto";
13
- import xe from "node-fetch";
14
- import { exec as Ee } from "node:child_process";
15
- import { URL as ke, fileURLToPath as $e } from "node:url";
13
+ import { exec as _ } from "node:child_process";
14
+ import { URL as ee, fileURLToPath as te } from "node:url";
16
15
  import "archiver";
17
- import x from "@vitejs/plugin-react";
18
- import { build as A, createServer as B } from "vite";
19
- import { viteExternalsPlugin as C } from "vite-plugin-externals";
20
- import { object as c, string as a, z as w, array as l, number as te, boolean as Se } from "zod";
21
- import Te from "@fastify/cors";
22
- import Pe from "fastify";
23
- import * as Ce from "esbuild";
24
- const De = "@frontify/frontify-cli", Oe = "module", Ae = "5.10.3", Fe = "Frontify Developers <developers@frontify.com>", Ue = { type: "git", url: "https://github.com/Frontify/brand-sdk", directory: "packages/cli" }, Re = { "frontify-cli": "dist/index.mjs" }, _e = ["dist", "templates"], Ie = { node: ">=18" }, je = { build: "vite build", dev: "vite build --watch", format: "prettier --write .", lint: "eslint .", "lint:fix": "eslint --fix .", start: "npm run build && node dist/index.mjs", test: "vitest run --silent", "test:watch": "vitest", "test:coverage": "vitest run --coverage", "test:ui": "vitest --ui", typecheck: "tsc --noEmit" }, Ne = { "@fastify/cors": "^11.2.0", "@vitejs/plugin-react": "^5.2.0", archiver: "^7.0.1", cac: "^6.7.14", conf: "^15.1.0", esbuild: "^0.27.4", "fast-glob": "^3.3.3", fastify: "^5.8.4", "glob-to-regexp": "^0.4.1", "node-fetch": "^3.3.2", open: "^11.0.0", picocolors: "^1.1.1", prompts: "^2.4.2", vite: "^7.3.1", "vite-plugin-externals": "^0.6.2", zod: "^3.25.76" }, Be = { "@frontify/eslint-config-basic": "^1.0.8", "@types/glob-to-regexp": "^0.4.4", "@types/mock-fs": "^4.13.4", "@types/node": "^20.19.25", "@types/prompts": "^2.4.9", "@types/ws": "8.18.1", "@vitest/coverage-v8": "4.1.2", "@vitest/ui": "^4.1.2", eslint: "^9.39.4", "eslint-plugin-notice": "^1.0.0", nock: "^13.5.6", prettier: "^3.7.4", "ts-node": "^10.9.2", typescript: "^5.9.3", vitest: "^4.1.2" }, F = {
25
- name: De,
26
- type: Oe,
27
- version: Ae,
28
- author: Fe,
29
- repository: Ue,
30
- bin: Re,
31
- files: _e,
32
- engines: Ie,
33
- scripts: je,
34
- dependencies: Ne,
35
- devDependencies: Be
36
- }, I = () => {
37
- const e = /* @__PURE__ */ new Date();
38
- return `${String(e.getHours()).padStart(2, "0")}:${String(e.getMinutes()).padStart(2, "0")}:${String(
39
- e.getSeconds()
40
- ).padStart(2, "0")}`;
41
- };
42
- class s {
43
- static defaultInfo(...t) {
44
- console.log(s.spacer(10), ...t);
45
- }
46
- static info(...t) {
47
- console.log(`[${I()}] ${t.join(" ")}`);
48
- }
49
- static success(...t) {
50
- console.log(`[${I()}] ${b.green(t.join(" "))}`);
51
- }
52
- static error(...t) {
53
- console.error(b.red(`[${I()}] ${t.join(" ")}`));
54
- }
55
- static spacer(t = 1) {
56
- return Array(t + 1).join(" ");
57
- }
58
- }
59
- class U extends Error {
60
- constructor(t) {
61
- super(), this.name = "FileNotFoundError", s.error(`The file at "${t}" was not found.`);
62
- }
63
- }
64
- class Le extends Error {
65
- constructor(t) {
66
- super(), this.name = "ParseJsonError", s.error(`The file at "${t}" could not be parsed.`);
67
- }
68
- }
69
- const $ = (e) => {
70
- try {
71
- const t = N(e, "utf8"), n = JSON.parse(t);
72
- return new Proxy(n, {
73
- set: (r, o, i) => {
74
- r[o] = i;
75
- const p = JSON.stringify(r, null, " ");
76
- return X(e, p), !0;
77
- }
78
- });
79
- } catch (t) {
80
- throw t instanceof SyntaxError ? new Le(e) : t.code === "ENOENT" ? new U(e) : new Error(t);
81
- }
82
- }, L = (e) => $(m(e, "package.json")).dependencies["@frontify/app-bridge"];
83
- class k {
84
- static {
85
- this.conf = new ve({
86
- projectName: "frontify-cli"
87
- });
88
- }
89
- static set(t, n) {
90
- this.conf.set(t, n);
91
- }
92
- static get(t) {
93
- return this.conf.get(t, void 0);
94
- }
95
- static delete(t) {
96
- return this.conf.delete(t);
97
- }
98
- }
99
- const Ve = (e) => {
100
- try {
101
- return ee(e).length === 0;
102
- } catch {
103
- return !0;
104
- }
105
- }, ne = (e, t, n) => {
106
- ye(t, { recursive: !0 });
107
- const r = n?.exclude.map((o) => be(o));
108
- for (const o of ee(e)) {
109
- if (r !== void 0 && r.some((u) => u.test(o)))
110
- continue;
111
- const i = O(e, o), p = O(t, o);
112
- Je(i, p);
113
- }
114
- }, Je = (e, t) => {
115
- ge(e).isDirectory() ? ne(e, t) : we(e, t);
116
- }, Me = (e) => {
117
- try {
118
- return N(e, "utf-8");
119
- } catch {
120
- throw new U(e);
121
- }
122
- }, ze = (e) => {
123
- try {
124
- return N(e, "base64");
125
- } catch {
126
- throw new U(e);
127
- }
128
- }, He = (e) => {
129
- try {
130
- return Me(e).split(/\r?\n/).filter((n) => n !== "");
131
- } catch {
132
- throw new U(e);
133
- }
134
- };
135
- class Ye extends Error {
136
- constructor(t, n) {
137
- super(`Status code ${t}`), this.code = 0, this.name = "HttpClientError", this.code = t, this.responseBody = n;
138
- }
139
- }
140
- class V {
141
- constructor(t) {
142
- this.baseUrl = t.replace(/^https?:\/\//, "");
143
- }
144
- async fetchExtended({ method: t, url: n, body: r, options: o }) {
145
- const i = await xe(this.getAbsoluteUrl(n), {
146
- method: t,
147
- ...r && {
148
- body: JSON.stringify(r)
149
- },
150
- ...o,
151
- headers: { "Content-Type": "application/json", ...o?.headers }
152
- });
153
- if (i.status === 200)
154
- if (i.headers.get("Content-Type") === "application/json") {
155
- const u = await i.json();
156
- return u || void 0;
157
- } else {
158
- const u = await i.text();
159
- return u || void 0;
160
- }
161
- else {
162
- const p = await i.json();
163
- throw new Ye(i.status, p);
164
- }
165
- }
166
- get(t, n) {
167
- return this.fetchExtended({ url: t, method: "GET", options: n });
168
- }
169
- post(t, n, r) {
170
- return this.fetchExtended({ url: t, method: "POST", body: n, options: r });
171
- }
172
- put(t, n, r) {
173
- return this.fetchExtended({ url: t, method: "PUT", body: n, options: r });
174
- }
175
- delete(t, n) {
176
- return this.fetchExtended({ url: t, method: "DELETE", options: n });
177
- }
178
- getAbsoluteUrl(t) {
179
- return `https://${this.baseUrl}${t}`;
180
- }
181
- }
182
- const qe = (e) => {
183
- const t = O(e, "package.json"), n = $(t);
184
- n.name = e;
185
- }, Ze = (e) => e ? /^[_a-z-]+$/.test(e) ? Ve(e) ? !0 : `The directory ./${e} already exist.` : 'The project name needs to be "a-z" separated by "-" or "_".' : "The content block name can not be empty.";
186
- class Ke extends Error {
187
- constructor(t) {
188
- super(), this.name = "CommandExecutionError", s.error(`The command execution failed: ${t}`);
189
- }
190
- }
191
- const M = (e, t = {}) => new Promise((n, r) => {
192
- Ee(e, t, (o, i) => o ? r(new Ke(o + i)) : n(i));
193
- });
194
- class Ge extends Error {
195
- constructor(t) {
196
- super(), this.name = "InvalidInstanceUrlError", t ? s.error(`The given URL "${t}" is invalid.`) : s.error("No instance URL was given.");
197
- }
198
- }
199
- const re = (e) => {
200
- try {
201
- const t = e.replace(/^https?:\/\//, "");
202
- return new ke(`https://${t}`).hostname;
203
- } catch {
204
- throw new Ge(e);
205
- }
206
- }, oe = async (e, t) => {
207
- const n = new V(e), r = t || k.get("tokens.access_token");
208
- try {
209
- return (await n.post(
210
- "/graphql",
211
- { query: "{ currentUser { email name } }" },
212
- { headers: { Authorization: `Bearer ${r}` } }
213
- )).data.currentUser;
214
- } catch {
215
- s.error(
216
- `You are currently not logged in. You can use the command ${b.bold("frontify-cli login")} to log in.`
217
- );
218
- return;
219
- }
220
- }, We = (e, t) => {
221
- const n = m(e, ".gitignore");
222
- X(n, Qe[t]);
223
- }, Qe = {
224
- "platform-app": `# Logs
225
- logs
226
- *.log
227
- npm-debug.log*
228
- yarn-debug.log*
229
- yarn-error.log*
230
- pnpm-debug.log*
231
- lerna-debug.log*
232
-
233
- node_modules
234
- dist
235
- dist-ssr
236
- *.localdist
237
- .idea
238
- .vscode
239
-
240
- # Editor directories and files
241
- .DS_Store
242
- *.suo
243
- *.ntvs*
244
- *.njsproj
245
- *.sln
246
- *.sw?
247
- .secret.json
248
- `,
249
- "content-block": `node_modules
250
- dist
251
- .idea
252
- .vscode
253
- `
254
- }, Xe = async ({ outputName: e, entryFile: t, projectPath: n = "" }) => {
255
- const r = L(n), o = await A({
256
- plugins: [
257
- x(),
258
- C({
259
- react: "React",
260
- "react-dom": "ReactDOM"
261
- })
262
- ],
263
- root: n,
264
- define: {
265
- "process.env.NODE_ENV": JSON.stringify("production")
266
- },
267
- build: {
268
- lib: {
269
- entry: t,
270
- name: e,
271
- formats: ["iife"],
272
- fileName: () => "index.js"
273
- },
274
- rollupOptions: {
275
- external: ["react", "react-dom"],
276
- output: {
277
- globals: {
278
- react: "React",
279
- "react-dom": "ReactDOM"
280
- },
281
- entryFileNames: "settings.js",
282
- footer: `
16
+ import v from "@vitejs/plugin-react";
17
+ import { build as y, createServer as b, esmExternalRequirePlugin as x } from "vite";
18
+ import { viteExternalsPlugin as ne } from "vite-plugin-externals";
19
+ import { array as S, boolean as re, number as ie, object as C, string as w, z as T } from "zod";
20
+ import ae from "@fastify/cors";
21
+ import oe from "fastify";
22
+ import * as se from "esbuild";
23
+ var E = {
24
+ name: "@frontify/frontify-cli",
25
+ type: "module",
26
+ version: "6.0.0-alpha.1",
27
+ author: "Frontify Developers <developers@frontify.com>",
28
+ repository: {
29
+ type: "git",
30
+ url: "https://github.com/Frontify/brand-sdk",
31
+ directory: "packages/cli"
32
+ },
33
+ bin: { "frontify-cli": "dist/index.mjs" },
34
+ files: ["dist", "templates"],
35
+ engines: { node: ">=22" },
36
+ scripts: {
37
+ build: "vite build",
38
+ dev: "vite build --watch",
39
+ format: "prettier --write .",
40
+ lint: "eslint .",
41
+ "lint:fix": "eslint --fix .",
42
+ start: "npm run build && node dist/index.mjs",
43
+ test: "vitest run --silent",
44
+ "test:watch": "vitest",
45
+ "test:coverage": "vitest run --coverage",
46
+ "test:ui": "vitest --ui",
47
+ typecheck: "tsc --noEmit"
48
+ },
49
+ dependencies: {
50
+ "@fastify/cors": "^11.2.0",
51
+ "@vitejs/plugin-react": "^6.0.1",
52
+ archiver: "^7.0.1",
53
+ cac: "^7.0.0",
54
+ conf: "^15.1.0",
55
+ esbuild: "^0.28.0",
56
+ "fast-glob": "^3.3.3",
57
+ fastify: "^5.8.4",
58
+ "glob-to-regexp": "^0.4.1",
59
+ open: "^11.0.0",
60
+ picocolors: "^1.1.1",
61
+ prompts: "^2.4.2",
62
+ vite: "^8.0.7",
63
+ "vite-plugin-externals": "^0.6.2",
64
+ zod: "^3.25.76"
65
+ },
66
+ devDependencies: {
67
+ "@frontify/eslint-config-basic": "^1.0.8",
68
+ "@types/glob-to-regexp": "^0.4.4",
69
+ "@types/mock-fs": "^4.13.4",
70
+ "@types/node": "^22.19.15",
71
+ "@types/prompts": "^2.4.9",
72
+ "@types/ws": "8.18.1",
73
+ "@vitest/coverage-v8": "4.1.2",
74
+ "@vitest/ui": "^4.1.2",
75
+ eslint: "^9.39.4",
76
+ "eslint-plugin-notice": "^1.0.0",
77
+ nock: "^14.0.11",
78
+ prettier: "^3.7.4",
79
+ "ts-node": "^10.9.2",
80
+ typescript: "^5.9.3",
81
+ vitest: "^4.1.2"
82
+ }
83
+ }, D = () => {
84
+ let e = /* @__PURE__ */ new Date();
85
+ return `${String(e.getHours()).padStart(2, "0")}:${String(e.getMinutes()).padStart(2, "0")}:${String(e.getSeconds()).padStart(2, "0")}`;
86
+ }, O = class e {
87
+ static defaultInfo(...t) {
88
+ console.log(e.spacer(10), ...t);
89
+ }
90
+ static info(...e) {
91
+ console.log(`[${D()}] ${e.join(" ")}`);
92
+ }
93
+ static success(...e) {
94
+ console.log(`[${D()}] ${c.green(e.join(" "))}`);
95
+ }
96
+ static error(...e) {
97
+ console.error(c.red(`[${D()}] ${e.join(" ")}`));
98
+ }
99
+ static spacer(e = 1) {
100
+ return " ".repeat(e);
101
+ }
102
+ }, k = class extends Error {
103
+ name = "FileNotFoundError";
104
+ constructor(e) {
105
+ super(), O.error(`The file at "${e}" was not found.`);
106
+ }
107
+ }, ce = class extends Error {
108
+ name = "ParseJsonError";
109
+ constructor(e) {
110
+ super(), O.error(`The file at "${e}" could not be parsed.`);
111
+ }
112
+ }, A = (e) => {
113
+ try {
114
+ let t = d(e, "utf8"), n = JSON.parse(t);
115
+ return new Proxy(n, { set: (t, n, r) => (t[n] = r, m(e, JSON.stringify(t, null, " ")), !0) });
116
+ } catch (t) {
117
+ throw t instanceof SyntaxError ? new ce(e) : t instanceof Error && "code" in t && t.code === "ENOENT" ? new k(e) : Error(String(t));
118
+ }
119
+ }, j = (e) => A(t(e, "package.json")).dependencies["@frontify/app-bridge"], le = (e) => A(t(e, "package.json")).dependencies["@frontify/app-bridge-theme"], M = (e) => A(t(e, "package.json")).dependencies.react, N = class {
120
+ static conf = new h({ projectName: "frontify-cli" });
121
+ static set(e, t) {
122
+ this.conf.set(e, t);
123
+ }
124
+ static get(e) {
125
+ return this.conf.get(e, void 0);
126
+ }
127
+ static delete(e) {
128
+ return this.conf.delete(e);
129
+ }
130
+ }, ue = (e) => {
131
+ try {
132
+ return f(e).length === 0;
133
+ } catch {
134
+ return !0;
135
+ }
136
+ }, P = (e, t, r) => {
137
+ u(t, { recursive: !0 });
138
+ let i = r?.exclude.map((e) => g(e));
139
+ for (let r of f(e)) i !== void 0 && i.some((e) => e.test(r)) || de(n(e, r), n(t, r));
140
+ }, de = (e, t) => {
141
+ p(e).isDirectory() ? P(e, t) : l(e, t);
142
+ }, fe = (e) => {
143
+ try {
144
+ return d(e, "utf-8");
145
+ } catch {
146
+ throw new k(e);
147
+ }
148
+ }, pe = (e) => {
149
+ try {
150
+ return d(e, "base64");
151
+ } catch {
152
+ throw new k(e);
153
+ }
154
+ }, me = (e) => {
155
+ try {
156
+ return fe(e).split(/\r?\n/).filter((e) => e !== "");
157
+ } catch {
158
+ throw new k(e);
159
+ }
160
+ }, he = class extends Error {
161
+ code = 0;
162
+ responseBody;
163
+ constructor(e, t) {
164
+ super(`Status code ${e}`), this.name = "HttpClientError", this.code = e, this.responseBody = t;
165
+ }
166
+ }, F = class {
167
+ baseUrl;
168
+ constructor(e) {
169
+ this.baseUrl = e.replace(/^https?:\/\//, "");
170
+ }
171
+ async fetchExtended({ method: e, url: t, body: n, options: r }) {
172
+ let i = await fetch(this.getAbsoluteUrl(t), {
173
+ method: e,
174
+ ...n && { body: JSON.stringify(n) },
175
+ ...r,
176
+ headers: {
177
+ "Content-Type": "application/json",
178
+ ...r?.headers
179
+ }
180
+ });
181
+ if (i.ok) switch (i.headers.get("Content-Type")) {
182
+ case "application/json": return await i.json() || void 0;
183
+ default: return await i.text() || void 0;
184
+ }
185
+ else {
186
+ let e = await i.json();
187
+ throw new he(i.status, e);
188
+ }
189
+ }
190
+ get(e, t) {
191
+ return this.fetchExtended({
192
+ url: e,
193
+ method: "GET",
194
+ options: t
195
+ });
196
+ }
197
+ post(e, t, n) {
198
+ return this.fetchExtended({
199
+ url: e,
200
+ method: "POST",
201
+ body: t,
202
+ options: n
203
+ });
204
+ }
205
+ put(e, t, n) {
206
+ return this.fetchExtended({
207
+ url: e,
208
+ method: "PUT",
209
+ body: t,
210
+ options: n
211
+ });
212
+ }
213
+ delete(e, t) {
214
+ return this.fetchExtended({
215
+ url: e,
216
+ method: "DELETE",
217
+ options: t
218
+ });
219
+ }
220
+ getAbsoluteUrl(e) {
221
+ return `https://${this.baseUrl}${e}`;
222
+ }
223
+ }, ge = (e) => {
224
+ let t = A(n(e, "package.json"));
225
+ t.name = e;
226
+ }, _e = (e) => e ? /^[_a-z-]+$/.test(e) ? ue(e) ? !0 : `The directory ./${e} already exist.` : "The project name needs to be \"a-z\" separated by \"-\" or \"_\"." : "The content block name can not be empty.", ve = class extends Error {
227
+ name = "CommandExecutionError";
228
+ constructor(e) {
229
+ super(), O.error(`The command execution failed: ${e}`);
230
+ }
231
+ }, I = (e, t = {}) => new Promise((n, r) => {
232
+ _(e, t, (e, t) => e ? r(new ve(`${e.message}${String(t)}`)) : n(String(t)));
233
+ }), ye = class extends Error {
234
+ name = "InvalidInstanceUrlError";
235
+ constructor(e) {
236
+ super(), e ? O.error(`The given URL "${e}" is invalid.`) : O.error("No instance URL was given.");
237
+ }
238
+ }, L = (e) => {
239
+ try {
240
+ return new ee(`https://${e.replace(/^https?:\/\//, "")}`).hostname;
241
+ } catch {
242
+ throw new ye(e);
243
+ }
244
+ }, R = async (e, t) => {
245
+ let n = new F(e), r = t || N.get("tokens.access_token");
246
+ try {
247
+ return (await n.post("/graphql", { query: "{ currentUser { email name } }" }, { headers: { Authorization: `Bearer ${r}` } })).data.currentUser;
248
+ } catch {
249
+ O.error(`You are currently not logged in. You can use the command ${c.bold("frontify-cli login")} to log in.`);
250
+ return;
251
+ }
252
+ }, be = (e, n) => {
253
+ m(t(e, ".gitignore"), xe[n]);
254
+ }, xe = {
255
+ "platform-app": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\ndist\ndist-ssr\n*.localdist\n.idea\n.vscode\n\n# Editor directories and files\n.DS_Store\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n.secret.json\n",
256
+ "content-block": "node_modules\ndist\n.idea\n.vscode\n"
257
+ }, Se = async ({ outputName: e, entryFile: t, projectPath: n = "" }) => {
258
+ let r = j(n), i = await y({
259
+ plugins: [v(), ne({
260
+ react: "React",
261
+ "react-dom": "ReactDOM"
262
+ })],
263
+ root: n,
264
+ mode: "production",
265
+ define: { "process.env.NODE_ENV": JSON.stringify("production") },
266
+ build: {
267
+ minify: "terser",
268
+ cssMinify: "esbuild",
269
+ lib: {
270
+ entry: t,
271
+ name: e,
272
+ formats: ["iife"],
273
+ fileName: () => "index.js",
274
+ cssFileName: "style"
275
+ },
276
+ rollupOptions: {
277
+ external: ["react", "react-dom"],
278
+ output: {
279
+ globals: {
280
+ react: "React",
281
+ "react-dom": "ReactDOM"
282
+ },
283
+ entryFileNames: "settings.js",
284
+ footer: `
283
285
  window.${e} = ${e};
284
286
  window.${e}.dependencies = window.${e}.packages || {};
285
- window.${e}.dependencies['@frontify/app-bridge'] = '${r}';
286
- `
287
- }
288
- }
289
- }
290
- });
291
- return { app: await A({
292
- plugins: [x()],
293
- root: n,
294
- define: {
295
- "process.env.NODE_ENV": JSON.stringify("production")
296
- },
297
- base: "/__DYNAMIC_SEGMENT__/",
298
- build: {
299
- emptyOutDir: !1
300
- }
301
- }), settings: o };
302
- }, se = async ({ projectPath: e, entryFile: t, outputName: n }) => {
303
- const r = L(e);
304
- return A({
305
- plugins: [
306
- x(),
307
- C({
308
- react: "React",
309
- "react-dom": "ReactDOM"
310
- })
311
- ],
312
- define: {
313
- "process.env.NODE_ENV": JSON.stringify("production")
314
- },
315
- root: e,
316
- build: {
317
- lib: {
318
- name: n,
319
- entry: t,
320
- formats: ["iife"],
321
- fileName: () => "index.js"
322
- },
323
- rollupOptions: {
324
- external: ["react", "react-dom"],
325
- output: {
326
- globals: {
327
- react: "React",
328
- "react-dom": "ReactDOM"
329
- },
330
- footer: `
331
- window.${n} = ${n};
332
- window.${n}.dependencies = window.${n}.packages || {};
333
- window.${n}.dependencies['@frontify/app-bridge'] = '${r}';
287
+ window.${e}.dependencies['@frontify/app-bridge-app'] = '${r}';
334
288
  `
335
- }
336
- }
337
- }
338
- });
339
- }, ae = (e) => $(m(e, "package.json")).dependencies["@frontify/app-bridge-theme"], ie = async ({ projectPath: e, entryFile: t, outputName: n }) => {
340
- const r = ae(e);
341
- return A({
342
- plugins: [
343
- x(),
344
- C({
345
- react: "React",
346
- "react-dom": "ReactDOM"
347
- })
348
- ],
349
- define: {
350
- "process.env.NODE_ENV": JSON.stringify("production")
351
- },
352
- root: e,
353
- build: {
354
- lib: {
355
- name: n,
356
- entry: t,
357
- formats: ["iife"],
358
- fileName: () => "index.js"
359
- },
360
- rollupOptions: {
361
- external: ["react", "react-dom"],
362
- output: {
363
- globals: {
364
- react: "React",
365
- "react-dom": "ReactDOM"
366
- },
367
- footer: `
368
- window.${n} = ${n};
369
- window.${n}.dependencies = window.${n}.packages || {};
370
- window.${n}.dependencies['@frontify/app-bridge-theme'] = '${r}';
371
- `
372
- }
373
- }
374
- }
375
- });
376
- }, g = ["exe", "dmg", "cmd", "sh", "bat"], v = (e) => `Invalid file extension, \`${e}.filenameExtension\` can not include: ${g.join(", ")}.`, T = c({
377
- title: a().min(1).max(40)
378
- }).optional(), P = w.enum(["audio", "document", "image", "video", "file", "embeddedContent"]), z = P.exclude(["audio", "document", "video", "file", "embeddedContent"]), H = w.enum(["svg"]), Y = w.enum(["svg", "jpg", "jpeg", "ai", "eps", "png", "tif", "tiff"]), et = w.enum(["content-block", "platform-app", "theme"]), q = /* @__PURE__ */ new Set(), tt = c({
379
- label: a(),
380
- key: a().min(1).max(80).refine(
381
- (e) => q.has(e) ? !1 : (q.add(e), /^\w+$/.test(e)),
382
- {
383
- message: "Secret Key must be unique and should only contain letters from a-z, A-Z, numbers from 0-9 and '_' without any spaces"
384
- }
385
- )
386
- }), nt = l(tt), rt = c({
387
- method: w.enum(["GET", "POST", "PUT", "DELETE"]),
388
- headers: w.record(a()).optional(),
389
- body: w.any().optional()
390
- }), Z = /* @__PURE__ */ new Set(), ot = c({
391
- name: a().refine(
392
- (e) => Z.has(e) ? !1 : (Z.add(e), /^[\w-]*$/.test(e)),
393
- {
394
- message: "Endpoint name must be unique"
395
- }
396
- ),
397
- resource: a(),
398
- options: rt
399
- }), st = /^(([\dA-Za-z]|[\dA-Za-z][\dA-Za-z-]*[\dA-Za-z])\.)*([\dA-Za-z]|[\dA-Za-z][\dA-Za-z-]*[\dA-Za-z])$/, at = w.enum(["basic:read", "basic:write", "account:read", "webhook:read", "webhook:write"]), it = c({
400
- permissions: c({
401
- scopes: l(at).min(1, "At least one scope is required").max(5, "No more than 5 scopes are allowed").refine((e) => e.includes("basic:read"), {
402
- message: "'basic:read' is required in scopes"
403
- })
404
- }).optional()
405
- }).optional(), K = c({
406
- key: a(),
407
- type: a(),
408
- label: a()
409
- }), ct = c({
410
- id: a(),
411
- title: a(),
412
- iconUrl: a(),
413
- returns: l(K),
414
- version: te().int().positive(),
415
- externalId: a(),
416
- parameters: l(K)
417
- }), lt = l(ct).optional(), pt = c({
418
- appId: a().length(25),
419
- appType: et,
420
- experimental: Se().optional(),
421
- secrets: nt.optional(),
422
- network: c({
423
- allowedHosts: l(
424
- a().refine((e) => st.test(e), {
425
- message: "Invalid host format"
426
- })
427
- ).optional(),
428
- endpoints: l(ot).optional()
429
- }).optional(),
430
- permissionsSchema: it,
431
- automation: c({
432
- actions: lt
433
- }).optional(),
434
- surfaces: c({
435
- guideline: c({
436
- pageAction: c({
437
- title: a().min(2).max(28)
438
- }).optional(),
439
- assetViewer: c({
440
- title: a().min(2).max(28),
441
- type: l(P),
442
- filenameExtension: l(
443
- a().refine((e) => !g.includes(e), {
444
- message: v("guideline")
445
- })
446
- )
447
- }).optional()
448
- }).optional(),
449
- mediaLibrary: c({
450
- assetBulkActions: c({
451
- title: a().min(2).max(28),
452
- filenameExtensions: l(
453
- a().refine((e) => !g.includes(e), {
454
- message: v("mediaLibrary")
455
- })
456
- )
457
- }).optional(),
458
- assetAction: c({
459
- title: a().min(2).max(28),
460
- type: l(P),
461
- filenameExtension: l(
462
- a().refine((e) => !g.includes(e), {
463
- message: v("mediaLibrary")
464
- })
465
- )
466
- }).optional(),
467
- assetCreation: T
468
- }).optional(),
469
- iconLibrary: c({
470
- assetBulkActions: c({
471
- title: a().min(2).max(28),
472
- filenameExtensions: l(H)
473
- }).optional(),
474
- assetAction: c({
475
- title: a().min(2).max(28),
476
- type: l(z),
477
- filenameExtension: l(H)
478
- }).optional(),
479
- assetCreation: T
480
- }).optional(),
481
- logoLibrary: c({
482
- assetBulkActions: c({
483
- title: a().min(2).max(28),
484
- filenameExtensions: l(Y)
485
- }).optional(),
486
- assetAction: c({
487
- title: a().min(2).max(28),
488
- type: l(z),
489
- filenameExtension: l(Y)
490
- }).optional(),
491
- assetCreation: T
492
- }).optional(),
493
- documentLibrary: c({
494
- assetBulkActions: c({
495
- title: a().min(2).max(28),
496
- filenameExtensions: l(
497
- a().refine((e) => !g.includes(e), {
498
- message: v("documentLibrary")
499
- })
500
- )
501
- }).optional(),
502
- assetAction: c({
503
- title: a().min(2).max(28),
504
- type: l(P),
505
- filenameExtension: l(
506
- a().refine((e) => !g.includes(e), {
507
- message: v("documentLibrary")
508
- })
509
- )
510
- }).optional(),
511
- assetCreation: T
512
- }).optional(),
513
- workspace: c({
514
- assetBulkActions: c({
515
- title: a().min(2).max(28),
516
- filenameExtensions: l(
517
- a().refine((e) => !g.includes(e), {
518
- message: v("workspaceProject")
519
- })
520
- )
521
- }).optional(),
522
- assetAction: c({
523
- title: a().min(2).max(28),
524
- type: l(P),
525
- filenameExtension: l(
526
- a().refine((e) => !g.includes(e), {
527
- message: v("workspaceProject")
528
- })
529
- )
530
- }).optional(),
531
- assetCreation: T
532
- }).optional()
533
- }).optional(),
534
- metadata: c({
535
- version: te().int()
536
- })
537
- }), dt = (e, t) => {
538
- const n = t.safeParse(e);
539
- if (!n.success)
540
- throw new Error(n.error.message);
541
- return n.data;
542
- }, G = async (e, t) => {
543
- const n = await E(`${E.convertPathToPattern(e)}/**`, { ignore: t, dot: !0 });
544
- return n.map((o) => o.replace(`${e}/`, "")).reduce((o, i, p) => (o[`/${i}`] = ze(n[p]), o), {});
545
- }, mt = ["**/*.*.map"], ft = [
546
- ".git",
547
- "node_modules",
548
- "dist",
549
- ".vscode",
550
- ".idea",
551
- ".eslintignore",
552
- ".prettierignore",
553
- "README.md",
554
- ".DS_Store",
555
- "**/*.graphql"
556
- ], D = async (e, t, { dryRun: n = !1, noVerify: r = !1, openInBrowser: o = !1, token: i, instance: p }, u) => {
557
- try {
558
- let h;
559
- const S = p || k.get("instanceUrl"), J = i || k.get("tokens.access_token");
560
- if ((!J || !S) && (s.error(
561
- `You are currently not logged in. You can use the command ${b.bold(
562
- "frontify-cli login"
563
- )} to log in, or pass --token=<token> --instance=<instance> to the deploy command.`
564
- ), process.exit(-1)), n || (h = await oe(S, i), h && s.info(`You are logged in as ${h.name} (${S}).`)), h || n) {
565
- n && s.info(b.blue("Dry run: enabled"));
566
- const y = process.cwd(), R = $(m(y, "manifest.json")), { appId: _ } = R.appType === "platform-app" ? dt(R, pt) : R;
567
- r || (s.info("Performing type checks..."), await M("npx tsc --noEmit"), s.info("Performing eslint checks..."), await M("npx eslint src"));
568
- try {
569
- await u({ projectPath: y, entryFile: e, outputName: _ });
570
- } catch (d) {
571
- s.error(d), process.exit(-1);
572
- }
573
- const pe = mt.map(
574
- (d) => E.convertPathToPattern(y + d)
575
- ), de = [...He(m(y, ".gitignore")).filter(
576
- (d) => d !== "manifest.json"
577
- ), ...ft].map((d) => d.includes("*") ? `${y}/${d}` : E.convertPathToPattern(`${y}/${d}`)), me = {
578
- build_files: await G(
579
- E.convertPathToPattern(`${y}/${t}`),
580
- pe
581
- ),
582
- source_files: await G(E.convertPathToPattern(y), de)
583
- };
584
- if (n)
585
- s.success("The command has been executed without any issue."), process.exit(0);
586
- else {
587
- s.info("Sending the files to Frontify Marketplace...");
588
- const d = new V(S);
589
- try {
590
- await d.put(`/api/marketplace/app/${_}`, me, {
591
- headers: { Authorization: `Bearer ${J}` }
592
- }), s.success("The new version has been pushed."), o && (s.info("Opening the Frontify Marketplace page..."), await Q(`https://${S}/marketplace/apps/${_}`));
593
- } catch (fe) {
594
- s.error("An error occured while deploying:", fe.responseBody.error), process.exit(-1);
595
- }
596
- }
597
- }
598
- } catch (h) {
599
- typeof h == "string" ? s.error("The deployment has failed and was aborted due to an error:", h) : h instanceof Error ? s.error("The deployment has failed and was aborted due to an error:", h.message) : s.error("The deployment has failed and was aborted due to an unknown error."), process.exit(-1);
600
- }
601
- };
602
- class ut {
603
- constructor(t, n = 5600) {
604
- this.fastifyServer = Pe(), this.instanceUrl = t, this.port = n, this.httpClient = new V(t);
605
- }
606
- serveCallbackServer() {
607
- this.registerPlugins(), this.registerRoutes(), this.fastifyServer.listen({ port: this.port });
608
- }
609
- registerRoutes() {
610
- this.fastifyServer.get("/oauth", async (t, n) => {
611
- s.info("Access granted, getting access token..."), n.send("You can close this window.");
612
- const r = await this.getOauthCredentialDetails(t.query.code);
613
- s.info("Tokens received, storing tokens..."), k.set("tokens", r), k.set("instanceUrl", this.instanceUrl);
614
- const o = await oe(this.instanceUrl);
615
- o && s.success(`Welcome back ${o.name} (${this.instanceUrl})!`), process.exit(0);
616
- });
617
- }
618
- registerPlugins() {
619
- this.fastifyServer.register(Te);
620
- }
621
- async storeRandomCodeChallenge() {
622
- try {
623
- const t = await this.httpClient.get(
624
- "/api/oauth/random"
625
- );
626
- this.randomChallenge = t.data;
627
- } catch (t) {
628
- const n = t instanceof Error ? t.message : String(t);
629
- throw new Error(`An error occurred while getting the random challenge: ${n}`);
630
- }
631
- }
632
- getLoginUrl() {
633
- if (!this.randomChallenge)
634
- throw new Error("Random challenge needs to be defined.");
635
- const t = [
636
- "response_type=code",
637
- "client_id=block-cli",
638
- "redirect_uri=http://localhost:5600/oauth",
639
- "scope=basic:read%2Bblocks:read%2Bblocks:write",
640
- `code_challenge=${this.randomChallenge.sha256}`,
641
- "code_challenge_method=S256"
642
- ].join("&");
643
- return `https://${this.instanceUrl}/api/oauth/authorize?${t}`;
644
- }
645
- async getOauthCredentialDetails(t) {
646
- if (!this.randomChallenge)
647
- throw new Error("Random challenge needs to be defined.");
648
- try {
649
- return await this.httpClient.post("/api/oauth/accesstoken", {
650
- grant_type: "authorization_code",
651
- client_id: "block-cli",
652
- redirect_uri: "http://localhost:5600/oauth",
653
- scope: "basic:read+blocks:read+blocks:write",
654
- code_verifier: this.randomChallenge.secret,
655
- code: t
656
- });
657
- } catch (n) {
658
- const r = n instanceof Error ? n.message : String(n);
659
- throw new Error(`An error occurred while getting tokens: ${r}`);
660
- }
661
- }
662
- }
663
- const ht = async (e, t) => {
664
- try {
665
- const n = re(e), r = new ut(n, t);
666
- r.serveCallbackServer(), await r.storeRandomCodeChallenge();
667
- const o = r.getLoginUrl();
668
- s.info("Attempting to open OAuth login page..."), s.info(
669
- `If a browser window doesn't automatically open, please open the following link manually: ${o}`
670
- ), await Q(o);
671
- } catch (n) {
672
- const r = n instanceof Error ? n.message : String(n);
673
- s.error(`You need to enter a valid Frontify instance URL: ${r}`), process.exit(-1);
674
- }
675
- }, yt = () => {
676
- k.delete("tokens"), s.info("You are now logged out.");
677
- };
678
- class gt {
679
- constructor(t, n, r) {
680
- this.entryFilePath = t, this.port = n, this.allowExternal = r;
681
- }
682
- async serve() {
683
- try {
684
- const t = await B({
685
- root: process.cwd(),
686
- plugins: [
687
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
688
- // @ts-ignore
689
- x(),
690
- C({
691
- react: "React",
692
- "react-dom": "ReactDOM"
693
- })
694
- ],
695
- define: {
696
- "process.env.NODE_ENV": JSON.stringify("development"),
697
- "DevCustomBlock.dependencies.appBridge": JSON.stringify(L(process.cwd()))
698
- },
699
- base: `http://localhost:${this.port}/`,
700
- appType: "custom",
701
- server: {
702
- port: this.port,
703
- host: this.allowExternal ? "0.0.0.0" : "localhost",
704
- cors: !0,
705
- hmr: {
706
- port: this.port,
707
- host: this.allowExternal ? "0.0.0.0" : "localhost",
708
- protocol: "ws"
709
- }
710
- }
711
- });
712
- t.middlewares.use("/", (r, o, i) => r.url !== "/" ? i() : (o.writeHead(200), o.end("OK"))), t.middlewares.use("/_entrypoint", (r, o, i) => r.url !== "/" ? i() : (o.setHeader("Content-Type", "application/json"), o.writeHead(200), o.end(
713
- JSON.stringify({
714
- url: `http://localhost:${this.port}/${this.entryFilePath}`,
715
- entryFilePath: this.entryFilePath,
716
- port: this.port,
717
- version: F.version
718
- })
719
- ))), (await t.listen(this.port, !0)).printUrls();
720
- } catch (t) {
721
- console.error(t), process.exit(1);
722
- }
723
- }
289
+ }
290
+ }
291
+ }
292
+ });
293
+ return {
294
+ app: await y({
295
+ plugins: [v()],
296
+ root: n,
297
+ mode: "production",
298
+ define: { "process.env.NODE_ENV": JSON.stringify("production") },
299
+ base: "/__DYNAMIC_SEGMENT__/",
300
+ build: {
301
+ minify: "terser",
302
+ cssMinify: "esbuild",
303
+ emptyOutDir: !1
304
+ }
305
+ }),
306
+ settings: i
307
+ };
308
+ }, z = [
309
+ "react",
310
+ "react/jsx-runtime",
311
+ "react/jsx-dev-runtime",
312
+ "react-dom",
313
+ "react-dom/client"
314
+ ];
315
+ function B() {
316
+ let e = /* @__PURE__ */ new Set(), t = [...z];
317
+ return {
318
+ name: "vite-plugin-react-bare-external",
319
+ enforce: "pre",
320
+ apply: "serve",
321
+ config(n) {
322
+ n.optimizeDeps ??= {}, n.optimizeDeps.exclude = [...n.optimizeDeps.exclude ?? [], ...t];
323
+ let r = n.optimizeDeps;
324
+ r.rolldownOptions ??= {};
325
+ let i = r.rolldownOptions;
326
+ return i.plugins ??= [], i.plugins.push({
327
+ name: "externalize-react",
328
+ resolveId(n) {
329
+ return t.includes(n) ? (e.add(n), {
330
+ id: n,
331
+ external: !0
332
+ }) : null;
333
+ }
334
+ }), i.plugins.push(x({ external: t })), null;
335
+ },
336
+ configResolved(t) {
337
+ let n = (t.base ?? "/").replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
338
+ t.plugins.push({
339
+ name: "vite-plugin-react-bare-restore",
340
+ transform(t) {
341
+ if (e.size === 0) return null;
342
+ let r = RegExp(`${n}@id\\/(${[...e].join("|")})`, "g");
343
+ return t.replace(r, (e, t) => t);
344
+ }
345
+ });
346
+ },
347
+ resolveId(n) {
348
+ return t.includes(n) ? (e.add(n), {
349
+ id: n,
350
+ external: !0
351
+ }) : null;
352
+ },
353
+ load(t) {
354
+ return e.has(t) ? "export default {};" : null;
355
+ }
356
+ };
724
357
  }
725
- class wt {
726
- constructor(t, n) {
727
- this.entryFilePath = t, this.port = n;
728
- }
729
- async serve() {
730
- try {
731
- const t = await Ce.context({
732
- entryPoints: [this.entryFilePath],
733
- outfile: "./dist/dev-settings.js",
734
- minify: !0,
735
- globalName: "devSettings",
736
- format: "iife",
737
- bundle: !0,
738
- loader: {
739
- ".css": "empty"
740
- }
741
- });
742
- (await (await B({
743
- root: process.cwd(),
744
- configFile: !1,
745
- define: {
746
- "process.env.NODE_ENV": JSON.stringify("development")
747
- },
748
- server: { cors: !0 },
749
- plugins: [
750
- x(),
751
- {
752
- name: "prebuild-commands",
753
- handleHotUpdate: ({ file: o, server: i }) => {
754
- const p = ue.relative(process.cwd(), o);
755
- (p === "src/settings.ts" || p === "src/index.ts") && (t.rebuild(), i.restart());
756
- },
757
- buildStart: () => {
758
- t.rebuild();
759
- }
760
- }
761
- ]
762
- })).listen(this.port, !0)).printUrls();
763
- } catch (t) {
764
- console.error(t), process.exit(1);
765
- }
766
- }
767
- }
768
- class vt {
769
- constructor(t, n, r) {
770
- this.entryFilePath = t, this.port = n, this.allowExternal = r;
771
- }
772
- async serve() {
773
- try {
774
- const t = await B({
775
- root: process.cwd(),
776
- plugins: [
777
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
778
- // @ts-ignore
779
- x(),
780
- C({
781
- react: "React",
782
- "react-dom": "ReactDOM"
783
- })
784
- ],
785
- define: {
786
- "process.env.NODE_ENV": JSON.stringify("development"),
787
- "DevCustomTheme.dependencies.appBridgeTheme": JSON.stringify(
788
- ae(process.cwd())
789
- )
790
- },
791
- base: `http://localhost:${this.port}/`,
792
- appType: "custom",
793
- server: {
794
- port: this.port,
795
- host: this.allowExternal ? "0.0.0.0" : "localhost",
796
- cors: !0,
797
- hmr: {
798
- port: this.port,
799
- host: this.allowExternal ? "0.0.0.0" : "localhost",
800
- protocol: "ws"
801
- }
802
- }
803
- });
804
- t.middlewares.use("/", (r, o, i) => r.url !== "/" ? i() : (o.writeHead(200), o.end("OK"))), t.middlewares.use("/_entrypoint", (r, o, i) => r.url !== "/" ? i() : (o.setHeader("Content-Type", "application/json"), o.writeHead(200), o.end(
805
- JSON.stringify({
806
- url: `http://localhost:${this.port}/${this.entryFilePath}`,
807
- entryFilePath: this.entryFilePath,
808
- port: this.port,
809
- version: F.version
810
- })
811
- ))), (await t.listen(this.port, !0)).printUrls();
812
- } catch (t) {
813
- console.error(t), process.exit(1);
814
- }
815
- }
816
- }
817
- const ce = async (e, t, n) => {
818
- s.info("Starting the development server..."), await new gt(e, t, n).serve();
819
- }, bt = async (e, t, n) => {
820
- s.info("Starting the development server for theme..."), await new vt(e, t, n).serve();
821
- }, xt = async (e, t) => {
822
- s.info("Starting the development server for Apps..."), await new wt(e, t).serve();
823
- }, le = (e, t, n) => {
824
- s.info(`Creating the ${n}...`);
825
- const r = b.blue(`./${e}`);
826
- s.info(`Scaffolding App in ${r}...`);
827
- const o = O($e(import.meta.url), `../../templates/${n}-${t}`);
828
- ne(o, e, { exclude: ["node_modules"] }), We(e, n), qe(e), s.defaultInfo(`
829
- ${s.spacer(11)}You can now access the project and install dependencies.`);
830
- const i = b.blue(`./${e}`);
831
- s.defaultInfo(`${s.spacer(4)}cd ${i}`), s.defaultInfo(`${s.spacer(4)}npm i`), s.defaultInfo(`${s.spacer(4)}npm run serve`), s.defaultInfo(`
832
- ${s.spacer(11)}Happy hacking!`);
833
- }, f = he(F.name.split("/")[1]);
834
- f.command("login [instanceUrl]", "log in to a Frontify instance").option("-i, --instance <instanceUrl>", "[string] url of the Frontify instance").option("-p, --port <port>", "[number] port for the oauth service", {
835
- default: process.env.PORT || 5600
836
- }).action(async (e, t) => {
837
- const n = e || t.instance || process.env.INSTANCE_URL;
838
- n && j.inject([n]);
839
- const { promptedInstanceUrl: r } = await j([
840
- {
841
- type: "text",
842
- name: "promptedInstanceUrl",
843
- message: "Enter a Frontify instance URL",
844
- initial: "instanceName.frontify.com",
845
- validate: (i) => i.trim() === "" ? "You need to enter a valid URL." : !0
846
- }
847
- ]);
848
- r || W(0);
849
- const o = re(r);
850
- await ht(o, t.port);
851
- });
852
- f.command("logout", "log out of an instance").action(yt);
853
- for (const e of ["block", "theme"])
854
- f.command(`${e} serve`, `[deprecated: use 'serve' instead] serve the ${e} locally`).alias(`${e} dev`).option("-e, --entryPath, --entry-path <entryPath>", `[string] path to the ${e} entry file`, {
855
- default: m("src", "index.tsx")
856
- }).option("--port <port>", "[number] specify port", {
857
- default: process.env.PORT || 5600
858
- }).option("--allowExternal, --allow-external", "[boolean] allow external IPs to access the server", {
859
- default: !1
860
- }).action(async (t) => {
861
- await ce(t.entryPath, t.port, t.allowExternal);
862
- });
863
- f.command("serve", "serve the app locally").alias("dev").option("-e, --entryPath, --entry-path <entryPath>", "[string] path to the entry file", {
864
- default: m("src", "index.ts")
865
- }).option("--port <port>", "[number] specify port", {
866
- default: process.env.PORT || 5600
867
- }).option("--allowExternal, --allow-external", "[boolean] allow external IPs to access the server", {
868
- default: !1
869
- }).option("--appType <appType>, --app-type", "[string] specify app type. Overrides manifest values").action(async (e) => {
870
- const t = $(m(process.cwd(), "manifest.json")), n = e.appType || t.appType;
871
- n === "platform-app" ? await xt(e.entryPath, e.port) : n === "theme" ? await bt(e.entryPath, e.port, e.allowExternal) : await ce(e.entryPath, e.port, e.allowExternal);
872
- });
873
- for (const e of ["block", "theme"])
874
- f.command(`${e} deploy`, `[deprecated: use 'deploy' instead] deploy the ${e} to the marketplace`).option("-e, --entryPath <entryPath>", "[string] path to the entry file", { default: m("src", "index.tsx") }).option("-o, --outDir <outDir>", "[string] path to the output directory", { default: "dist" }).option("--dryRun, --dry-run", "[boolean] enable the dry run mode", { default: !1 }).option("--noVerify, --no-verify", "[boolean] disable the linting and typechecking", { default: !1 }).option("--open", "[boolean] open the marketplace app page", { default: !1 }).action(async (t) => {
875
- await D(
876
- t.entryPath,
877
- t.outDir,
878
- {
879
- dryRun: t.dryRun,
880
- noVerify: t.noVerify,
881
- openInBrowser: t.open
882
- },
883
- e === "theme" ? ie : se
884
- );
885
- });
886
- f.command("deploy", "deploy the app to the marketplace").option("-e, --entryPath <entryPath>", "[string] path to the entry file", { default: m("src", "index.ts") }).option("-o, --outDir <outDir>", "[string] path to the output directory", { default: "dist" }).option("--dryRun, --dry-run", "[boolean] enable the dry run mode", { default: !1 }).option("--noVerify, --no-verify", "[boolean] disable the linting and typechecking", { default: !1 }).option("--open", "[boolean] open the marketplace app page", { default: !1 }).option("--appType [appType], --app-type", "[string] specify app type. Overrides manifest values").option("-i, --instance <instanceUrl>", "[string] url of the Frontify instance").option("-t, --token <accessToken>", "[string] the access token").action(async (e) => {
887
- const t = $(m(process.cwd(), "manifest.json")), n = e.appType || t.appType;
888
- n === "platform-app" ? await D(
889
- e.entryPath,
890
- e.outDir,
891
- {
892
- dryRun: e.dryRun,
893
- noVerify: e.noVerify,
894
- openInBrowser: e.open,
895
- instance: e.instance,
896
- token: e.token
897
- },
898
- Xe
899
- ) : n === "theme" ? await D(
900
- e.entryPath,
901
- e.outDir,
902
- {
903
- dryRun: e.dryRun,
904
- noVerify: e.noVerify,
905
- openInBrowser: e.open,
906
- instance: e.instance,
907
- token: e.token
908
- },
909
- ie
910
- ) : await D(
911
- e.entryPath,
912
- e.outDir,
913
- {
914
- dryRun: e.dryRun,
915
- noVerify: e.noVerify,
916
- openInBrowser: e.open,
917
- instance: e.instance,
918
- token: e.token
919
- },
920
- se
921
- );
922
- });
923
- f.command("create [appName]", "create a new marketplace app").action(async (e) => {
924
- const { promptedAppName: t, stylingFramework: n, appType: r } = await j([
925
- {
926
- type: "text",
927
- name: "promptedAppName",
928
- message: "Enter your app name",
929
- initial: e || "my-frontify-app",
930
- validate: (o) => o.trim() === "" ? "You need to enter an app name." : Ze(o)
931
- },
932
- {
933
- type: "select",
934
- name: "appType",
935
- message: "Select the type of your app",
936
- choices: [
937
- { title: "App", value: "platform-app" },
938
- { title: "Block", value: "content-block" }
939
- ]
940
- },
941
- {
942
- type: "select",
943
- name: "stylingFramework",
944
- message: "Choose a styling framework",
945
- choices: [
946
- { title: "Tailwind", value: "tailwind" },
947
- { title: "CSS Modules", value: "css-modules" },
948
- { title: "None", value: "css" }
949
- ]
950
- }
951
- ]);
952
- (!t || !n || !r) && W(0), le(t, n, r);
953
- });
954
- for (const e of ["block", "theme"])
955
- f.command(
956
- `${e} create [appName]`,
957
- `[deprecated: use 'create' instead] create a ${e} app locally`
958
- ).action((t) => le(t, "css-modules", "content-block"));
959
- f.help();
960
- f.version(F.version);
961
- const Et = (e) => {
962
- const t = e.findIndex((n) => n === "block" || n === "theme");
963
- return t !== -1 && (e[t + 1] === "serve" || e[t + 1] === "deploy" || e[t + 1] === "create") && (e[t] = `${e[t]} ${e[t + 1]}`, e.splice(t + 1, 1)), e;
964
- };
965
- f.parse(Et(process.argv));
966
- //# sourceMappingURL=index.mjs.map
358
+ //#endregion
359
+ //#region src/utils/compiler/compileBlock.ts
360
+ var Ce = async ({ projectPath: e, entryFile: t, outputName: n }) => y({
361
+ plugins: [v(), x({ external: z })],
362
+ define: { "process.env.NODE_ENV": JSON.stringify("production") },
363
+ root: e,
364
+ mode: "production",
365
+ build: {
366
+ minify: "terser",
367
+ cssMinify: "lightningcss",
368
+ lib: {
369
+ name: n,
370
+ entry: t,
371
+ formats: ["es"],
372
+ fileName: () => "index.js",
373
+ cssFileName: "style"
374
+ },
375
+ rolldownOptions: {
376
+ platform: "browser",
377
+ treeshake: { moduleSideEffects: [
378
+ {
379
+ test: /@frontify\/fondue-components/,
380
+ sideEffects: !1
381
+ },
382
+ {
383
+ test: /@frontify\/fondue-icons/,
384
+ sideEffects: !1
385
+ },
386
+ {
387
+ test: /@frontify\/fondue-tokens/,
388
+ sideEffects: !1
389
+ },
390
+ {
391
+ test: /@frontify\/fondue-charts/,
392
+ sideEffects: !1
393
+ },
394
+ {
395
+ test: /@frontify\/fondue-rte/,
396
+ sideEffects: !1
397
+ },
398
+ {
399
+ test: /\.css$/,
400
+ sideEffects: !0
401
+ }
402
+ ] }
403
+ }
404
+ }
405
+ }), we = async ({ projectPath: e, entryFile: t, outputName: n }) => y({
406
+ plugins: [v(), x({ external: z })],
407
+ define: { "process.env.NODE_ENV": JSON.stringify("production") },
408
+ root: e,
409
+ mode: "production",
410
+ build: {
411
+ minify: "terser",
412
+ cssMinify: "lightningcss",
413
+ lib: {
414
+ name: n,
415
+ entry: t,
416
+ formats: ["es"],
417
+ fileName: () => "index.js",
418
+ cssFileName: "style"
419
+ },
420
+ rolldownOptions: {
421
+ platform: "browser",
422
+ treeshake: { moduleSideEffects: [
423
+ {
424
+ test: /@frontify\/fondue-components/,
425
+ sideEffects: !1
426
+ },
427
+ {
428
+ test: /@frontify\/fondue-icons/,
429
+ sideEffects: !1
430
+ },
431
+ {
432
+ test: /@frontify\/fondue-tokens/,
433
+ sideEffects: !1
434
+ },
435
+ {
436
+ test: /@frontify\/fondue-charts/,
437
+ sideEffects: !1
438
+ },
439
+ {
440
+ test: /@frontify\/fondue-rte/,
441
+ sideEffects: !1
442
+ },
443
+ {
444
+ test: /\.css$/,
445
+ sideEffects: !0
446
+ }
447
+ ] }
448
+ }
449
+ }
450
+ }), V = [
451
+ "exe",
452
+ "dmg",
453
+ "cmd",
454
+ "sh",
455
+ "bat"
456
+ ], H = (e) => `Invalid file extension, \`${e}.filenameExtension\` can not include: ${V.join(", ")}.`, U = C({ title: w().min(1).max(40) }).optional(), W = T.enum([
457
+ "audio",
458
+ "document",
459
+ "image",
460
+ "video",
461
+ "file",
462
+ "embeddedContent"
463
+ ]), G = W.exclude([
464
+ "audio",
465
+ "document",
466
+ "video",
467
+ "file",
468
+ "embeddedContent"
469
+ ]), K = T.enum(["svg"]), q = T.enum([
470
+ "svg",
471
+ "jpg",
472
+ "jpeg",
473
+ "ai",
474
+ "eps",
475
+ "png",
476
+ "tif",
477
+ "tiff"
478
+ ]), Te = T.enum([
479
+ "content-block",
480
+ "platform-app",
481
+ "theme"
482
+ ]), J = /* @__PURE__ */ new Set(), Ee = S(C({
483
+ label: w(),
484
+ key: w().min(1).max(80).refine((e) => J.has(e) ? !1 : (J.add(e), /^\w+$/.test(e)), { message: "Secret Key must be unique and should only contain letters from a-z, A-Z, numbers from 0-9 and '_' without any spaces" })
485
+ })), De = C({
486
+ method: T.enum([
487
+ "GET",
488
+ "POST",
489
+ "PUT",
490
+ "DELETE"
491
+ ]),
492
+ headers: T.record(w()).optional(),
493
+ body: T.any().optional()
494
+ }), Y = /* @__PURE__ */ new Set(), Oe = C({
495
+ name: w().refine((e) => Y.has(e) ? !1 : (Y.add(e), /^[\w-]*$/.test(e)), { message: "Endpoint name must be unique" }),
496
+ resource: w(),
497
+ options: De
498
+ }), ke = /^(([\dA-Za-z]|[\dA-Za-z][\dA-Za-z-]*[\dA-Za-z])\.)*([\dA-Za-z]|[\dA-Za-z][\dA-Za-z-]*[\dA-Za-z])$/, Ae = C({ permissions: C({ scopes: S(T.enum([
499
+ "basic:read",
500
+ "basic:write",
501
+ "account:read",
502
+ "webhook:read",
503
+ "webhook:write"
504
+ ])).min(1, "At least one scope is required").max(5, "No more than 5 scopes are allowed").refine((e) => e.includes("basic:read"), { message: "'basic:read' is required in scopes" }) }).optional() }).optional(), X = C({
505
+ key: w(),
506
+ type: w(),
507
+ label: w()
508
+ }), je = S(C({
509
+ id: w(),
510
+ title: w(),
511
+ iconUrl: w(),
512
+ returns: S(X),
513
+ version: ie().int().positive(),
514
+ externalId: w(),
515
+ parameters: S(X)
516
+ })).optional(), Me = C({
517
+ appId: w().length(25),
518
+ appType: Te,
519
+ experimental: re().optional(),
520
+ secrets: Ee.optional(),
521
+ network: C({
522
+ allowedHosts: S(w().refine((e) => ke.test(e), { message: "Invalid host format" })).optional(),
523
+ endpoints: S(Oe).optional()
524
+ }).optional(),
525
+ permissionsSchema: Ae,
526
+ automation: C({ actions: je }).optional(),
527
+ surfaces: C({
528
+ guideline: C({
529
+ pageAction: C({ title: w().min(2).max(28) }).optional(),
530
+ assetViewer: C({
531
+ title: w().min(2).max(28),
532
+ type: S(W),
533
+ filenameExtension: S(w().refine((e) => !V.includes(e), { message: H("guideline") }))
534
+ }).optional()
535
+ }).optional(),
536
+ mediaLibrary: C({
537
+ assetBulkActions: C({
538
+ title: w().min(2).max(28),
539
+ filenameExtensions: S(w().refine((e) => !V.includes(e), { message: H("mediaLibrary") }))
540
+ }).optional(),
541
+ assetAction: C({
542
+ title: w().min(2).max(28),
543
+ type: S(W),
544
+ filenameExtension: S(w().refine((e) => !V.includes(e), { message: H("mediaLibrary") }))
545
+ }).optional(),
546
+ assetCreation: U
547
+ }).optional(),
548
+ iconLibrary: C({
549
+ assetBulkActions: C({
550
+ title: w().min(2).max(28),
551
+ filenameExtensions: S(K)
552
+ }).optional(),
553
+ assetAction: C({
554
+ title: w().min(2).max(28),
555
+ type: S(G),
556
+ filenameExtension: S(K)
557
+ }).optional(),
558
+ assetCreation: U
559
+ }).optional(),
560
+ logoLibrary: C({
561
+ assetBulkActions: C({
562
+ title: w().min(2).max(28),
563
+ filenameExtensions: S(q)
564
+ }).optional(),
565
+ assetAction: C({
566
+ title: w().min(2).max(28),
567
+ type: S(G),
568
+ filenameExtension: S(q)
569
+ }).optional(),
570
+ assetCreation: U
571
+ }).optional(),
572
+ documentLibrary: C({
573
+ assetBulkActions: C({
574
+ title: w().min(2).max(28),
575
+ filenameExtensions: S(w().refine((e) => !V.includes(e), { message: H("documentLibrary") }))
576
+ }).optional(),
577
+ assetAction: C({
578
+ title: w().min(2).max(28),
579
+ type: S(W),
580
+ filenameExtension: S(w().refine((e) => !V.includes(e), { message: H("documentLibrary") }))
581
+ }).optional(),
582
+ assetCreation: U
583
+ }).optional(),
584
+ workspace: C({
585
+ assetBulkActions: C({
586
+ title: w().min(2).max(28),
587
+ filenameExtensions: S(w().refine((e) => !V.includes(e), { message: H("workspaceProject") }))
588
+ }).optional(),
589
+ assetAction: C({
590
+ title: w().min(2).max(28),
591
+ type: S(W),
592
+ filenameExtension: S(w().refine((e) => !V.includes(e), { message: H("workspaceProject") }))
593
+ }).optional(),
594
+ assetCreation: U
595
+ }).optional()
596
+ }).optional(),
597
+ metadata: C({ version: ie().int() })
598
+ }), Ne = (e, t) => {
599
+ let n = t.safeParse(e);
600
+ if (!n.success) throw Error(n.error.message);
601
+ return n.data;
602
+ }, Z = async (e, t) => {
603
+ let n = await o(`${o.convertPathToPattern(e)}/**`, {
604
+ ignore: t,
605
+ dot: !0
606
+ });
607
+ return n.map((t) => t.replace(`${e}/`, "")).reduce((e, t, r) => (e[`/${t}`] = pe(n[r]), e), {});
608
+ }, Pe = ["**/*.*.map"], Fe = [
609
+ ".git",
610
+ "node_modules",
611
+ "dist",
612
+ ".vscode",
613
+ ".idea",
614
+ ".eslintignore",
615
+ ".prettierignore",
616
+ "README.md",
617
+ ".DS_Store",
618
+ "**/*.graphql"
619
+ ], Ie = (e, t) => {
620
+ let n = t || N.get("instanceUrl"), r = e || N.get("tokens.access_token");
621
+ return (!r || !n) && (O.error(`You are currently not logged in. You can use the command ${c.bold("frontify-cli login")} to log in, or pass --token=<token> --instance=<instance> to the deploy command.`), process.exit(-1)), {
622
+ instanceUrl: n,
623
+ accessToken: r
624
+ };
625
+ }, Le = async (e) => {
626
+ e || (O.info("Performing type checks..."), await I("npx tsc --noEmit"), O.info("Performing eslint checks..."), await I("npx eslint src"));
627
+ }, Re = async (e, n) => {
628
+ let r = Pe.map((t) => t.includes("*") ? `${o.convertPathToPattern(e)}/${t}` : o.convertPathToPattern(`${e}/${t}`)), i = [...me(t(e, ".gitignore")).filter((e) => e !== "manifest.json"), ...Fe].map((t) => t.includes("*") ? `${e}/${t}` : o.convertPathToPattern(`${e}/${t}`)), a = A(t(e, "package.json"));
629
+ return {
630
+ build_files: await Z(o.convertPathToPattern(`${e}/${n}`), r),
631
+ source_files: await Z(o.convertPathToPattern(e), i),
632
+ dependencies: a?.dependencies || {}
633
+ };
634
+ }, ze = (e) => {
635
+ typeof e == "string" ? O.error("The deployment has failed and was aborted due to an error:", e) : e instanceof Error ? O.error("The deployment has failed and was aborted due to an error:", e.message) : O.error("The deployment has failed and was aborted due to an unknown error."), process.exit(-1);
636
+ }, Be = async (e, n, { dryRun: r = !1, noVerify: i = !1, openInBrowser: a = !1, token: o, instance: l }, u) => {
637
+ try {
638
+ let { instanceUrl: d, accessToken: f } = Ie(o, l);
639
+ if (r) O.info(c.blue("Dry run: enabled"));
640
+ else {
641
+ let e = await R(d, o);
642
+ if (e) O.info(`You are logged in as ${e.name} (${d}).`);
643
+ else return;
644
+ }
645
+ let p = process.cwd(), m = A(t(p, "manifest.json")), { appId: h } = m.appType === "platform-app" ? Ne(m, Me) : m;
646
+ await Le(i);
647
+ try {
648
+ await u({
649
+ projectPath: p,
650
+ entryFile: e,
651
+ outputName: h
652
+ });
653
+ } catch (e) {
654
+ O.error(e), process.exit(-1);
655
+ }
656
+ let g = await Re(p, n);
657
+ r && (O.success("The command has been executed without any issue."), process.exit(0)), O.info("Sending the files to Frontify Marketplace...");
658
+ let _ = new F(d);
659
+ try {
660
+ await _.put(`/api/marketplace/app/${h}`, g, { headers: { Authorization: `Bearer ${f}` } }), O.success("The new version has been pushed."), a && (O.info("Opening the Frontify Marketplace page..."), await s(`https://${d}/marketplace/apps/${h}`));
661
+ } catch (e) {
662
+ O.error("An error occurred while deploying:", e.responseBody.error), process.exit(-1);
663
+ }
664
+ } catch (e) {
665
+ ze(e);
666
+ }
667
+ }, Ve = class {
668
+ instanceUrl;
669
+ port;
670
+ httpClient;
671
+ fastifyServer = oe();
672
+ randomChallenge;
673
+ constructor(e, t = 5600) {
674
+ this.instanceUrl = e, this.port = t, this.httpClient = new F(e);
675
+ }
676
+ serveCallbackServer() {
677
+ this.registerPlugins(), this.registerRoutes(), this.fastifyServer.listen({ port: this.port }).catch(() => {});
678
+ }
679
+ registerRoutes() {
680
+ this.fastifyServer.get("/oauth", async (e, t) => {
681
+ O.info("Access granted, getting access token..."), t.send("You can close this window.");
682
+ let n = await this.getOauthCredentialDetails(e.query.code);
683
+ O.info("Tokens received, storing tokens..."), N.set("tokens", n), N.set("instanceUrl", this.instanceUrl);
684
+ let r = await R(this.instanceUrl);
685
+ r && O.success(`Welcome back ${r.name} (${this.instanceUrl})!`), process.exit(0);
686
+ });
687
+ }
688
+ registerPlugins() {
689
+ this.fastifyServer.register(ae);
690
+ }
691
+ async storeRandomCodeChallenge() {
692
+ try {
693
+ this.randomChallenge = (await this.httpClient.get("/api/oauth/random")).data;
694
+ } catch (e) {
695
+ let t = e instanceof Error ? e.message : String(e);
696
+ throw Error(`An error occurred while getting the random challenge: ${t}`);
697
+ }
698
+ }
699
+ getLoginUrl() {
700
+ if (!this.randomChallenge) throw Error("Random challenge needs to be defined.");
701
+ let e = [
702
+ "response_type=code",
703
+ "client_id=block-cli",
704
+ `redirect_uri=http://localhost:${this.port}/oauth`,
705
+ "scope=basic:read%2Bblocks:read%2Bblocks:write",
706
+ `code_challenge=${this.randomChallenge.sha256}`,
707
+ "code_challenge_method=S256"
708
+ ].join("&");
709
+ return `https://${this.instanceUrl}/api/oauth/authorize?${e}`;
710
+ }
711
+ async getOauthCredentialDetails(e) {
712
+ if (!this.randomChallenge) throw Error("Random challenge needs to be defined.");
713
+ try {
714
+ return await this.httpClient.post("/api/oauth/accesstoken", {
715
+ grant_type: "authorization_code",
716
+ client_id: "block-cli",
717
+ redirect_uri: `http://localhost:${this.port}/oauth`,
718
+ scope: "basic:read+blocks:read+blocks:write",
719
+ code_verifier: this.randomChallenge.secret,
720
+ code: e
721
+ });
722
+ } catch (e) {
723
+ let t = e instanceof Error ? e.message : String(e);
724
+ throw Error(`An error occurred while getting tokens: ${t}`);
725
+ }
726
+ }
727
+ }, He = async (e, t) => {
728
+ try {
729
+ let n = new Ve(L(e), t);
730
+ n.serveCallbackServer(), await n.storeRandomCodeChallenge();
731
+ let r = n.getLoginUrl();
732
+ O.info("Attempting to open OAuth login page..."), O.info(`If a browser window doesn't automatically open, please open the following link manually: ${r}`), await s(r);
733
+ } catch (e) {
734
+ let t = e instanceof Error ? e.message : String(e);
735
+ O.error(`You need to enter a valid Frontify instance URL: ${t}`), process.exit(-1);
736
+ }
737
+ }, Ue = () => {
738
+ N.delete("tokens"), O.info("You are now logged out.");
739
+ }, We = class {
740
+ constructor(e, t, n) {
741
+ this.entryFilePath = e, this.port = t, this.allowExternal = n;
742
+ }
743
+ async serve() {
744
+ try {
745
+ let e = j(process.cwd()), t = M(process.cwd()), n = await b({
746
+ root: process.cwd(),
747
+ plugins: [v(), B()],
748
+ define: { "process.env.NODE_ENV": JSON.stringify("development") },
749
+ base: `http://localhost:${this.port}/`,
750
+ appType: "custom",
751
+ server: {
752
+ port: this.port,
753
+ host: this.allowExternal ? "0.0.0.0" : "localhost",
754
+ cors: !0,
755
+ hmr: {
756
+ port: this.port,
757
+ host: this.allowExternal ? "0.0.0.0" : "localhost",
758
+ protocol: "ws"
759
+ },
760
+ forwardConsole: !1
761
+ }
762
+ });
763
+ n.middlewares.use("/", (e, t, n) => e.url === "/" ? (t.setHeader("Access-Control-Allow-Origin", "*"), t.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS"), t.writeHead(200), t.end("OK")) : n()), n.middlewares.use("/_entrypoint", (n, r, i) => {
764
+ if (n.url !== "/") return i();
765
+ let a = n.headers.host || `localhost:${this.port}`, o = parseInt(a.split(":")[1] || String(this.port), 10);
766
+ return r.setHeader("Access-Control-Allow-Origin", "*"), r.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS"), r.setHeader("Content-Type", "application/json"), r.writeHead(200), r.end(JSON.stringify({
767
+ url: `http://${a}/${this.entryFilePath}`,
768
+ entryFilePath: this.entryFilePath,
769
+ port: o,
770
+ version: E.version,
771
+ dependencies: {
772
+ ...e ? { "@frontify/app-bridge": e } : {},
773
+ react: t
774
+ }
775
+ }));
776
+ }), (await n.listen(this.port, !0)).printUrls();
777
+ } catch (e) {
778
+ console.error(e), process.exit(1);
779
+ }
780
+ }
781
+ }, Ge = class {
782
+ constructor(e, t) {
783
+ this.entryFilePath = e, this.port = t;
784
+ }
785
+ async serve() {
786
+ try {
787
+ let t = await se.context({
788
+ entryPoints: [this.entryFilePath],
789
+ outfile: "./dist/dev-settings.js",
790
+ minify: !0,
791
+ globalName: "devSettings",
792
+ format: "iife",
793
+ bundle: !0,
794
+ loader: { ".css": "empty" }
795
+ });
796
+ (await (await b({
797
+ root: process.cwd(),
798
+ configFile: !1,
799
+ define: { "process.env.NODE_ENV": JSON.stringify("development") },
800
+ server: { cors: !0 },
801
+ plugins: [v(), {
802
+ name: "prebuild-commands",
803
+ handleHotUpdate: ({ file: n, server: r }) => {
804
+ let i = e.relative(process.cwd(), n);
805
+ (i === "src/settings.ts" || i === "src/index.ts") && (t.rebuild().catch(() => {}), r.restart().catch(() => {}));
806
+ },
807
+ buildStart: () => {
808
+ t.rebuild().catch(() => {});
809
+ }
810
+ }]
811
+ })).listen(this.port, !0)).printUrls();
812
+ } catch (e) {
813
+ console.error(e), process.exit(1);
814
+ }
815
+ }
816
+ }, Ke = class {
817
+ constructor(e, t, n) {
818
+ this.entryFilePath = e, this.port = t, this.allowExternal = n;
819
+ }
820
+ async serve() {
821
+ try {
822
+ let e = le(process.cwd()), t = M(process.cwd()), n = await b({
823
+ root: process.cwd(),
824
+ plugins: [v(), B()],
825
+ define: { "process.env.NODE_ENV": JSON.stringify("development") },
826
+ base: `http://localhost:${this.port}/`,
827
+ appType: "custom",
828
+ server: {
829
+ port: this.port,
830
+ host: this.allowExternal ? "0.0.0.0" : "localhost",
831
+ cors: !0,
832
+ hmr: {
833
+ port: this.port,
834
+ host: this.allowExternal ? "0.0.0.0" : "localhost",
835
+ protocol: "ws"
836
+ },
837
+ forwardConsole: !1
838
+ }
839
+ });
840
+ n.middlewares.use("/", (e, t, n) => e.url === "/" ? (t.setHeader("Access-Control-Allow-Origin", "*"), t.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS"), t.writeHead(200), t.end("OK")) : n()), n.middlewares.use("/_entrypoint", (n, r, i) => {
841
+ if (n.url !== "/") return i();
842
+ let a = n.headers.host || `localhost:${this.port}`, o = parseInt(a.split(":")[1] || String(this.port), 10);
843
+ return r.setHeader("Access-Control-Allow-Origin", "*"), r.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS"), r.setHeader("Content-Type", "application/json"), r.writeHead(200), r.end(JSON.stringify({
844
+ url: `http://${a}/${this.entryFilePath}`,
845
+ entryFilePath: this.entryFilePath,
846
+ port: o,
847
+ version: E.version,
848
+ dependencies: {
849
+ ...e ? { "@frontify/app-bridge-theme": e } : {},
850
+ react: t
851
+ }
852
+ }));
853
+ }), (await n.listen(this.port, !0)).printUrls();
854
+ } catch (e) {
855
+ console.error(e), process.exit(1);
856
+ }
857
+ }
858
+ }, qe = async (e, t, n) => {
859
+ O.info("Starting the development server..."), await new We(e, t, n).serve();
860
+ }, Je = async (e, t, n) => {
861
+ O.info("Starting the development server for theme..."), await new Ke(e, t, n).serve();
862
+ }, Ye = async (e, t) => {
863
+ O.info("Starting the development server for Apps..."), await new Ge(e, t).serve();
864
+ }, Xe = (e, t, r) => {
865
+ O.info(`Creating the ${r}...`);
866
+ let i = c.blue(`./${e}`);
867
+ O.info(`Scaffolding App in ${i}...`), P(n(te(import.meta.url), `../../templates/${r}-${t}`), e, { exclude: ["node_modules"] }), be(e, r), ge(e), O.defaultInfo(`\n${O.spacer(11)}You can now access the project and install dependencies.`);
868
+ let a = c.blue(`./${e}`);
869
+ O.defaultInfo(`${O.spacer(4)}cd ${a}`), O.defaultInfo(`${O.spacer(4)}npm i`), O.defaultInfo(`${O.spacer(4)}npm run serve`), O.defaultInfo(`\n${O.spacer(11)}Happy hacking!`);
870
+ }, Q = /* @__PURE__ */ function(e) {
871
+ return e.PRIVATE = "PRIVATE", e.COMMUNITY = "COMMUNITY", e;
872
+ }({}), Ze = async ({ releaseNotes: e, availability: n = Q.PRIVATE, token: r, instance: i }) => {
873
+ try {
874
+ let a = i || N.get("instanceUrl"), o = r || N.get("tokens.access_token");
875
+ (!o || !a) && (O.error(`You are currently not logged in. You can use the command ${c.bold("frontify-cli login")} to log in, or pass --token=<token> --instance=<instance> to the publish command.`), process.exit(-1));
876
+ let s = await R(a, r);
877
+ s || process.exit(-1), O.info(`You are logged in as ${s.name} (${a}).`);
878
+ let { appId: l } = A(t(process.cwd(), "manifest.json")), u = new F(a), d = `mutation PublishMarketplaceApp {
879
+ publishMarketplaceApp(
880
+ input: {appId: "${l}", releaseNotes: ${JSON.stringify(e)}, availability: ${n}}
881
+ ) {
882
+ id
883
+ }
884
+ }`;
885
+ O.info("Publishing the app to the Frontify Marketplace...");
886
+ try {
887
+ await u.post("/graphql", { query: d }, { headers: { Authorization: `Bearer ${o}` } }), O.success("The app has been published successfully.");
888
+ } catch (e) {
889
+ O.error("An error occurred while publishing:", e.responseBody.error), process.exit(-1);
890
+ }
891
+ } catch (e) {
892
+ typeof e == "string" ? O.error("The publishing has failed and was aborted due to an error:", e) : e instanceof Error ? O.error("The publishing has failed and was aborted due to an error:", e.message) : O.error("The publishing has failed and was aborted due to an unknown error."), process.exit(-1);
893
+ }
894
+ }, $ = i(E.name.split("/")[1]);
895
+ $.command("login [instanceUrl]", "log in to a Frontify instance").option("-i, --instance <instanceUrl>", "[string] url of the Frontify instance").option("-p, --port <port>", "[number] port for the oauth service", { default: process.env.PORT || 5600 }).action(async (e, t) => {
896
+ let n = e || t.instance || process.env.INSTANCE_URL;
897
+ n && a.inject([n]);
898
+ let { promptedInstanceUrl: i } = await a([{
899
+ type: "text",
900
+ name: "promptedInstanceUrl",
901
+ message: "Enter a Frontify instance URL",
902
+ initial: "instanceName.frontify.com",
903
+ validate: (e) => e.trim() === "" ? "You need to enter a valid URL." : !0
904
+ }]);
905
+ i || r(0), await He(L(i), t.port);
906
+ }), $.command("logout", "log out of an instance").action(Ue), $.command("serve", "serve the app locally").alias("dev").option("-e, --entryPath, --entry-path <entryPath>", "[string] path to the entry file", { default: t("src", "index.ts") }).option("--port <port>", "[number] specify port", { default: process.env.PORT || 5600 }).option("--allowExternal, --allow-external", "[boolean] allow external IPs to access the server", { default: !1 }).option("--appType <appType>, --app-type", "[string] specify app type. Overrides manifest values").action(async (e) => {
907
+ let n = A(t(process.cwd(), "manifest.json")), r = e.appType || n.appType;
908
+ r === "platform-app" ? await Ye(e.entryPath, e.port) : r === "theme" ? await Je(e.entryPath, e.port, e.allowExternal) : await qe(e.entryPath, e.port, e.allowExternal);
909
+ }), $.command("deploy", "deploy the app to the marketplace").option("-e, --entryPath <entryPath>", "[string] path to the entry file", { default: t("src", "index.ts") }).option("-o, --outDir <outDir>", "[string] path to the output directory", { default: "dist" }).option("--dryRun, --dry-run", "[boolean] enable the dry run mode", { default: !1 }).option("--noVerify, --no-verify", "[boolean] disable the linting and typechecking", { default: !1 }).option("--open", "[boolean] open the marketplace app page", { default: !1 }).option("--appType [appType], --app-type", "[string] specify app type. Overrides manifest values").option("-i, --instance <instanceUrl>", "[string] url of the Frontify instance").option("-t, --token <accessToken>", "[string] the access token").action(async (e) => {
910
+ let n = A(t(process.cwd(), "manifest.json")), r = e.appType || n.appType, i = {
911
+ "content-block": Ce,
912
+ "platform-app": Se,
913
+ theme: we
914
+ }, a = i[r ?? ""];
915
+ if (!a) throw Error(`Unknown app type "${r}". Expected one of: ${Object.keys(i).join(", ")}`);
916
+ await Be(e.entryPath, e.outDir, {
917
+ dryRun: e.dryRun,
918
+ noVerify: e.noVerify,
919
+ openInBrowser: e.open,
920
+ instance: e.instance,
921
+ token: e.token
922
+ }, a);
923
+ }), $.command("publish", "publish the app to the marketplace").option("--releaseNotes, --release-notes <releaseNotes>", "[string] release notes for the publish").option("--availability [availability]", `[string] availability of the app (${Object.values(Q).join(", ")})`, { default: Q.PRIVATE }).option("-i, --instance <instanceUrl>", "[string] url of the Frontify instance").option("-t, --token <accessToken>", "[string] the access token").action(async (e) => {
924
+ e.releaseNotes || (O.error("Release notes are required. Use --releaseNotes=\"Your release notes\"."), process.exit(-1)), await Ze({
925
+ releaseNotes: e.releaseNotes,
926
+ availability: e.availability,
927
+ token: e.token,
928
+ instance: e.instance
929
+ });
930
+ }), $.command("create [appName]", "create a new marketplace app").action(async (e) => {
931
+ let { promptedAppName: t, stylingFramework: n, appType: i } = await a([
932
+ {
933
+ type: "text",
934
+ name: "promptedAppName",
935
+ message: "Enter your app name",
936
+ initial: e || "my-frontify-app",
937
+ validate: (e) => e.trim() === "" ? "You need to enter an app name." : _e(e)
938
+ },
939
+ {
940
+ type: "select",
941
+ name: "appType",
942
+ message: "Select the type of your app",
943
+ choices: [{
944
+ title: "App",
945
+ value: "platform-app"
946
+ }, {
947
+ title: "Block",
948
+ value: "content-block"
949
+ }]
950
+ },
951
+ {
952
+ type: "select",
953
+ name: "stylingFramework",
954
+ message: "Choose a styling framework",
955
+ choices: [
956
+ {
957
+ title: "Tailwind",
958
+ value: "tailwind"
959
+ },
960
+ {
961
+ title: "CSS Modules",
962
+ value: "css-modules"
963
+ },
964
+ {
965
+ title: "None",
966
+ value: "css"
967
+ }
968
+ ]
969
+ }
970
+ ]);
971
+ (!t || !n || !i) && r(0), Xe(t, n, i);
972
+ }), $.help(), $.version(E.version), $.parse(process.argv);
973
+ //#endregion
974
+
975
+ //# sourceMappingURL=index.mjs.map