webstudio 0.151.0 → 0.167.0
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/lib/cli.js +427 -245
- package/package.json +27 -25
- package/templates/cloudflare/functions/[[path]].ts +0 -1
- package/templates/cloudflare/package.json +3 -3
- package/templates/cloudflare/tsconfig.json +1 -1
- package/templates/defaults/app/root.tsx +20 -2
- package/templates/defaults/app/{routes/[sitemap.xml].tsx → route-templates/default-sitemap.tsx} +1 -1
- package/templates/defaults/app/{routes/template.tsx → route-templates/html.tsx} +75 -53
- package/templates/defaults/app/route-templates/xml.tsx +61 -0
- package/templates/defaults/package.json +13 -13
- package/templates/defaults/tsconfig.json +1 -1
- package/templates/internal/tsconfig.json +1 -1
- package/templates/netlify-edge-functions/package.json +2 -2
- package/templates/netlify-functions/package.json +2 -2
- package/templates/saas-helpers/tsconfig.json +1 -1
- package/templates/defaults/app/__generated__/[sitemap.xml].ts +0 -9
package/lib/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/cli.ts
|
|
2
|
-
import { exit, argv } from "node:process";
|
|
2
|
+
import { exit as exit4, argv } from "node:process";
|
|
3
3
|
import { hideBin } from "yargs/helpers";
|
|
4
4
|
|
|
5
5
|
// src/config.ts
|
|
@@ -68,16 +68,16 @@ var isFileExists = async (filePath) => {
|
|
|
68
68
|
return false;
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
|
-
var
|
|
71
|
+
var createFileIfNotExists = async (filePath, content) => {
|
|
72
72
|
const dir = dirname(filePath);
|
|
73
|
-
await
|
|
73
|
+
await createFolderIfNotExists(dir);
|
|
74
74
|
try {
|
|
75
75
|
await access(filePath, constants.F_OK);
|
|
76
76
|
} catch {
|
|
77
77
|
await writeFile(filePath, content || "", "utf8");
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
|
-
var
|
|
80
|
+
var createFolderIfNotExists = async (folderPath) => {
|
|
81
81
|
try {
|
|
82
82
|
await access(folderPath, constants.F_OK);
|
|
83
83
|
} catch {
|
|
@@ -94,10 +94,41 @@ var loadJSONFile = async (filePath) => {
|
|
|
94
94
|
};
|
|
95
95
|
|
|
96
96
|
// src/commands/link.ts
|
|
97
|
-
import {
|
|
97
|
+
import { cwd, exit } from "node:process";
|
|
98
98
|
import { join as join2 } from "node:path";
|
|
99
|
-
import * as readline from "node:readline/promises";
|
|
100
99
|
import { readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
100
|
+
import { cancel, isCancel, log, text } from "@clack/prompts";
|
|
101
|
+
var parseShareLink = (value) => {
|
|
102
|
+
const url = new URL(value);
|
|
103
|
+
const origin = url.origin;
|
|
104
|
+
const token = url.searchParams.get("authToken");
|
|
105
|
+
const segments = url.pathname.split("/").slice(1);
|
|
106
|
+
if (segments.length !== 2 || segments[0] !== "builder") {
|
|
107
|
+
throw Error("Segments not matching");
|
|
108
|
+
}
|
|
109
|
+
const [_builder, projectId] = segments;
|
|
110
|
+
if (token == null) {
|
|
111
|
+
throw Error("Token is missing");
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
origin,
|
|
115
|
+
projectId,
|
|
116
|
+
token
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
var validateShareLink = (value) => {
|
|
120
|
+
if (value.length === 0) {
|
|
121
|
+
return "Share link is required";
|
|
122
|
+
}
|
|
123
|
+
if (URL.canParse(value) === false) {
|
|
124
|
+
return "Share link is invalid";
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
parseShareLink(value);
|
|
128
|
+
} catch {
|
|
129
|
+
return "Share link is invalid";
|
|
130
|
+
}
|
|
131
|
+
};
|
|
101
132
|
var linkOptions = (yargs) => yargs.option("link", {
|
|
102
133
|
alias: "l",
|
|
103
134
|
type: "string",
|
|
@@ -108,62 +139,48 @@ var link = async (options) => {
|
|
|
108
139
|
if (options.link) {
|
|
109
140
|
shareLink = options.link;
|
|
110
141
|
} else {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const origin = shareLinkUrl.origin;
|
|
119
|
-
const token = shareLinkUrl.searchParams.get("authToken");
|
|
120
|
-
const paths = shareLinkUrl.pathname.split("/").slice(1);
|
|
121
|
-
if (paths[0] !== "builder" || paths.length !== 2) {
|
|
122
|
-
throw new Error("Invalid share link.");
|
|
123
|
-
}
|
|
124
|
-
const projectId = paths[1];
|
|
125
|
-
if (token == null) {
|
|
126
|
-
throw new Error("Invalid share link.");
|
|
127
|
-
}
|
|
128
|
-
try {
|
|
129
|
-
const currentConfig = await readFile2(GLOBAL_CONFIG_FILE, "utf-8");
|
|
130
|
-
const currentConfigJson = jsonToGlobalConfig(JSON.parse(currentConfig));
|
|
131
|
-
const newConfig = {
|
|
132
|
-
...currentConfigJson,
|
|
133
|
-
[projectId]: {
|
|
134
|
-
origin,
|
|
135
|
-
token
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
await writeFile2(GLOBAL_CONFIG_FILE, JSON.stringify(newConfig, null, 2));
|
|
139
|
-
console.info(`Saved credentials for project ${projectId}.
|
|
140
|
-
You can find your config at ${GLOBAL_CONFIG_FILE}
|
|
141
|
-
`);
|
|
142
|
-
const localConfig = {
|
|
143
|
-
projectId
|
|
144
|
-
};
|
|
145
|
-
await ensureFileInPath(
|
|
146
|
-
join2(cwd(), LOCAL_CONFIG_FILE),
|
|
147
|
-
JSON.stringify(localConfig, null, 2)
|
|
148
|
-
);
|
|
149
|
-
} catch (error) {
|
|
150
|
-
if (error instanceof Error && "code" in error && error.code === "ENONET") {
|
|
151
|
-
throw new Error(`Global config file is not found`);
|
|
142
|
+
shareLink = await text({
|
|
143
|
+
message: "Please paste a link from the Share Dialog in the builder",
|
|
144
|
+
validate: validateShareLink
|
|
145
|
+
});
|
|
146
|
+
if (isCancel(shareLink)) {
|
|
147
|
+
cancel("Project linking is cancelled");
|
|
148
|
+
exit(1);
|
|
152
149
|
}
|
|
153
|
-
throw error;
|
|
154
150
|
}
|
|
151
|
+
const { origin, projectId, token } = parseShareLink(shareLink);
|
|
152
|
+
const currentConfig = await readFile2(GLOBAL_CONFIG_FILE, "utf-8");
|
|
153
|
+
const currentConfigJson = jsonToGlobalConfig(JSON.parse(currentConfig));
|
|
154
|
+
const newConfig = {
|
|
155
|
+
...currentConfigJson,
|
|
156
|
+
[projectId]: {
|
|
157
|
+
origin,
|
|
158
|
+
token
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
await writeFile2(GLOBAL_CONFIG_FILE, JSON.stringify(newConfig, null, 2));
|
|
162
|
+
log.info(`Saved credentials for project ${projectId}.
|
|
163
|
+
You can find your config at ${GLOBAL_CONFIG_FILE}`);
|
|
164
|
+
const localConfig = {
|
|
165
|
+
projectId
|
|
166
|
+
};
|
|
167
|
+
await createFileIfNotExists(
|
|
168
|
+
join2(cwd(), LOCAL_CONFIG_FILE),
|
|
169
|
+
JSON.stringify(localConfig, null, 2)
|
|
170
|
+
);
|
|
171
|
+
log.step("The project is linked successfully");
|
|
155
172
|
};
|
|
156
173
|
|
|
157
174
|
// src/commands/sync.ts
|
|
158
175
|
import { readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
159
176
|
import { cwd as cwd2 } from "node:process";
|
|
160
177
|
import { join as join3 } from "node:path";
|
|
161
|
-
import
|
|
178
|
+
import pc from "picocolors";
|
|
179
|
+
import { spinner } from "@clack/prompts";
|
|
162
180
|
import {
|
|
163
181
|
loadProjectDataByBuildId,
|
|
164
182
|
loadProjectDataById
|
|
165
183
|
} from "@webstudio-is/http-client";
|
|
166
|
-
import pc from "picocolors";
|
|
167
184
|
var syncOptions = (yargs) => yargs.option("buildId", {
|
|
168
185
|
type: "string",
|
|
169
186
|
describe: "[Experimental] Project build id to sync"
|
|
@@ -175,15 +192,15 @@ var syncOptions = (yargs) => yargs.option("buildId", {
|
|
|
175
192
|
describe: "[Experimental] Service token"
|
|
176
193
|
});
|
|
177
194
|
var sync = async (options) => {
|
|
178
|
-
const
|
|
179
|
-
|
|
195
|
+
const syncing = spinner();
|
|
196
|
+
syncing.start("Synchronizing project data");
|
|
180
197
|
const definedOptionValues = [
|
|
181
198
|
options.buildId,
|
|
182
199
|
options.origin,
|
|
183
200
|
options.authToken
|
|
184
201
|
].filter(Boolean);
|
|
185
202
|
if (definedOptionValues.length > 0 && definedOptionValues.length < 3) {
|
|
186
|
-
|
|
203
|
+
syncing.stop(`Please provide buildId, origin and authToken`, 2);
|
|
187
204
|
return;
|
|
188
205
|
}
|
|
189
206
|
let project;
|
|
@@ -194,17 +211,12 @@ var sync = async (options) => {
|
|
|
194
211
|
origin: options.origin
|
|
195
212
|
});
|
|
196
213
|
} else {
|
|
197
|
-
if (await isFileExists(GLOBAL_CONFIG_FILE) === false) {
|
|
198
|
-
spinner.fail(
|
|
199
|
-
`Global config file at path ${GLOBAL_CONFIG_FILE} is not found. Please link your project using webstudio link command`
|
|
200
|
-
);
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
214
|
const globalConfigText = await readFile3(GLOBAL_CONFIG_FILE, "utf-8");
|
|
204
215
|
const globalConfig = jsonToGlobalConfig(JSON.parse(globalConfigText));
|
|
205
216
|
if (await isFileExists(LOCAL_CONFIG_FILE) === false) {
|
|
206
|
-
|
|
207
|
-
`Local config file is not found. Please make sure current directory is a webstudio project
|
|
217
|
+
syncing.stop(
|
|
218
|
+
`Local config file is not found. Please make sure current directory is a webstudio project`,
|
|
219
|
+
2
|
|
208
220
|
);
|
|
209
221
|
return;
|
|
210
222
|
}
|
|
@@ -215,29 +227,35 @@ var sync = async (options) => {
|
|
|
215
227
|
const localConfig = jsonToLocalConfig(JSON.parse(localConfigText));
|
|
216
228
|
const projectConfig = globalConfig[localConfig.projectId];
|
|
217
229
|
if (projectConfig === void 0) {
|
|
218
|
-
|
|
219
|
-
`Project config is not found, please run ${pc.dim("webstudio link")}
|
|
230
|
+
syncing.stop(
|
|
231
|
+
`Project config is not found, please run ${pc.dim("webstudio link")}`,
|
|
232
|
+
2
|
|
220
233
|
);
|
|
221
234
|
return;
|
|
222
235
|
}
|
|
223
236
|
const { origin, token } = projectConfig;
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
237
|
+
try {
|
|
238
|
+
project = await loadProjectDataById({
|
|
239
|
+
projectId: localConfig.projectId,
|
|
240
|
+
authToken: token,
|
|
241
|
+
origin
|
|
242
|
+
});
|
|
243
|
+
} catch (error) {
|
|
244
|
+
syncing.stop(error.message, 2);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
230
247
|
}
|
|
231
248
|
project;
|
|
232
|
-
spinner.text = "Saving project data to config file";
|
|
233
249
|
const localBuildFilePath = join3(cwd2(), LOCAL_DATA_FILE);
|
|
234
|
-
await
|
|
250
|
+
await createFileIfNotExists(localBuildFilePath);
|
|
235
251
|
await writeFile3(localBuildFilePath, JSON.stringify(project, null, 2), "utf8");
|
|
236
|
-
|
|
252
|
+
syncing.stop("Project data synchronized successfully");
|
|
237
253
|
};
|
|
238
254
|
|
|
239
255
|
// src/commands/build.ts
|
|
240
256
|
import { access as access3 } from "node:fs/promises";
|
|
257
|
+
import { exit as exit3 } from "node:process";
|
|
258
|
+
import { log as log3 } from "@clack/prompts";
|
|
241
259
|
|
|
242
260
|
// src/prebuild.ts
|
|
243
261
|
import { basename, dirname as dirname2, join as join4, normalize } from "node:path";
|
|
@@ -252,10 +270,10 @@ import {
|
|
|
252
270
|
readdir
|
|
253
271
|
} from "node:fs/promises";
|
|
254
272
|
import { pipeline } from "node:stream/promises";
|
|
255
|
-
import { cwd as cwd3 } from "node:process";
|
|
273
|
+
import { cwd as cwd3, exit as exit2 } from "node:process";
|
|
256
274
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
257
275
|
import pLimit from "p-limit";
|
|
258
|
-
import
|
|
276
|
+
import { log as log2, spinner as spinner2 } from "@clack/prompts";
|
|
259
277
|
import merge from "deepmerge";
|
|
260
278
|
import {
|
|
261
279
|
generateCss,
|
|
@@ -265,7 +283,7 @@ import {
|
|
|
265
283
|
normalizeProps,
|
|
266
284
|
generateRemixRoute,
|
|
267
285
|
generateRemixParams,
|
|
268
|
-
|
|
286
|
+
isCoreComponent
|
|
269
287
|
} from "@webstudio-is/react-sdk";
|
|
270
288
|
import {
|
|
271
289
|
createScope,
|
|
@@ -281,6 +299,122 @@ import { createImageLoader } from "@webstudio-is/image";
|
|
|
281
299
|
import * as baseComponentMetas from "@webstudio-is/sdk-components-react/metas";
|
|
282
300
|
import * as remixComponentMetas from "@webstudio-is/sdk-components-react-remix/metas";
|
|
283
301
|
import * as radixComponentMetas from "@webstudio-is/sdk-components-react-radix/metas";
|
|
302
|
+
|
|
303
|
+
// src/html-to-jsx.ts
|
|
304
|
+
import {
|
|
305
|
+
parseFragment,
|
|
306
|
+
defaultTreeAdapter
|
|
307
|
+
} from "parse5";
|
|
308
|
+
import { camelCase } from "change-case";
|
|
309
|
+
var BOOLEAN_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
310
|
+
"async",
|
|
311
|
+
"autofocus",
|
|
312
|
+
"autoplay",
|
|
313
|
+
"checked",
|
|
314
|
+
"contenteditable",
|
|
315
|
+
"controls",
|
|
316
|
+
"default",
|
|
317
|
+
"defer",
|
|
318
|
+
"disabled",
|
|
319
|
+
"formnovalidate",
|
|
320
|
+
"hidden",
|
|
321
|
+
"ismap",
|
|
322
|
+
"itemscope",
|
|
323
|
+
"loop",
|
|
324
|
+
"multiple",
|
|
325
|
+
"muted",
|
|
326
|
+
"nomodule",
|
|
327
|
+
"novalidate",
|
|
328
|
+
"open",
|
|
329
|
+
"playsinline",
|
|
330
|
+
"readonly",
|
|
331
|
+
"required",
|
|
332
|
+
"reversed",
|
|
333
|
+
"scoped",
|
|
334
|
+
"selected",
|
|
335
|
+
"truespeed"
|
|
336
|
+
]);
|
|
337
|
+
var isBooleanAttr = (name) => BOOLEAN_ATTRIBUTES.has(name.toLowerCase());
|
|
338
|
+
function* walkChildNodes(node) {
|
|
339
|
+
if (defaultTreeAdapter.isCommentNode(node) || defaultTreeAdapter.isTextNode(node) || defaultTreeAdapter.isDocumentTypeNode(node)) {
|
|
340
|
+
throw new Error("Unsupported node type");
|
|
341
|
+
}
|
|
342
|
+
for (const childNode of node.childNodes) {
|
|
343
|
+
if (defaultTreeAdapter.isCommentNode(childNode)) {
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
if (defaultTreeAdapter.isTextNode(childNode)) {
|
|
347
|
+
yield { type: "text", value: childNode.value };
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
if (false === defaultTreeAdapter.isElementNode(childNode)) {
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
const attributes = childNode.attrs.map((attr) => [
|
|
354
|
+
attr.name,
|
|
355
|
+
attr.value
|
|
356
|
+
]);
|
|
357
|
+
yield { type: "element-start", tagName: childNode.tagName, attributes };
|
|
358
|
+
yield* walkChildNodes(childNode);
|
|
359
|
+
yield { type: "element-end", tagName: childNode.tagName };
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
var convertStyleString = (style) => {
|
|
363
|
+
const styles = style.split(";").map((style2) => style2.trim()).map((style2) => style2.split(":").map((part) => part.trim()));
|
|
364
|
+
const res = {};
|
|
365
|
+
for (const [name, value] of styles) {
|
|
366
|
+
res[camelCase(name)] = value;
|
|
367
|
+
}
|
|
368
|
+
return JSON.stringify(res);
|
|
369
|
+
};
|
|
370
|
+
var toAttrString = (name, value) => {
|
|
371
|
+
const attName = name.toLowerCase();
|
|
372
|
+
const jsxName = attName === "class" ? "className" : attName;
|
|
373
|
+
if (value === "" && isBooleanAttr(attName)) {
|
|
374
|
+
return `${jsxName}`;
|
|
375
|
+
}
|
|
376
|
+
if (attName === "style") {
|
|
377
|
+
return `${jsxName}={${convertStyleString(value)}}`;
|
|
378
|
+
}
|
|
379
|
+
return `${jsxName}="${value}"`;
|
|
380
|
+
};
|
|
381
|
+
var attributesToString = (attributes) => attributes.map(([attName, value]) => ` ${toAttrString(attName, value)}`).join("");
|
|
382
|
+
var convertTagName = (tagName) => {
|
|
383
|
+
const tag = tagName.toLowerCase();
|
|
384
|
+
if (tag === "script") {
|
|
385
|
+
return "Script";
|
|
386
|
+
}
|
|
387
|
+
if (tag === "style") {
|
|
388
|
+
return "Style";
|
|
389
|
+
}
|
|
390
|
+
return tag;
|
|
391
|
+
};
|
|
392
|
+
var escapeValue = (value) => value.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$").replace(/\r/g, "\\r").replace(/\n/g, "\\n");
|
|
393
|
+
var htmlToJsx = (html) => {
|
|
394
|
+
const parsedHtml = parseFragment(html, { scriptingEnabled: false });
|
|
395
|
+
let result = "";
|
|
396
|
+
for (const walkNode of walkChildNodes(parsedHtml)) {
|
|
397
|
+
switch (walkNode.type) {
|
|
398
|
+
case "text": {
|
|
399
|
+
const escapedValue = escapeValue(walkNode.value);
|
|
400
|
+
result += escapedValue ? "{`" + escapedValue + "`}" : "";
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
case "element-start": {
|
|
404
|
+
const tag = convertTagName(walkNode.tagName);
|
|
405
|
+
result += `<${tag}${attributesToString(walkNode.attributes)}>`;
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
case "element-end": {
|
|
409
|
+
result += `</${convertTagName(walkNode.tagName)}>`;
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return result;
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
// src/prebuild.ts
|
|
284
418
|
var limit = pLimit(10);
|
|
285
419
|
var downloadAsset = async (url, name, assetBaseUrl) => {
|
|
286
420
|
const assetPath = join4("public", assetBaseUrl, name);
|
|
@@ -288,7 +422,7 @@ var downloadAsset = async (url, name, assetBaseUrl) => {
|
|
|
288
422
|
try {
|
|
289
423
|
await access2(assetPath);
|
|
290
424
|
} catch {
|
|
291
|
-
await
|
|
425
|
+
await createFolderIfNotExists(dirname2(assetPath));
|
|
292
426
|
try {
|
|
293
427
|
const response = await fetch(url);
|
|
294
428
|
if (!response.ok) {
|
|
@@ -357,12 +491,12 @@ var copyTemplates = async (template = "defaults") => {
|
|
|
357
491
|
}
|
|
358
492
|
};
|
|
359
493
|
var prebuild = async (options) => {
|
|
360
|
-
if (options.template ===
|
|
361
|
-
|
|
362
|
-
`
|
|
363
|
-
|
|
364
|
-
Please check webstudio --help for more details`
|
|
494
|
+
if (options.template.length === 0) {
|
|
495
|
+
log2.error(
|
|
496
|
+
`Template is not provided
|
|
497
|
+
Please check webstudio --help for more details`
|
|
365
498
|
);
|
|
499
|
+
exit2(1);
|
|
366
500
|
}
|
|
367
501
|
for (const template of options.template) {
|
|
368
502
|
if (template === "vanilla") {
|
|
@@ -372,16 +506,14 @@ var prebuild = async (options) => {
|
|
|
372
506
|
continue;
|
|
373
507
|
}
|
|
374
508
|
if (await isCliTemplate(template) === false) {
|
|
375
|
-
|
|
376
|
-
`
|
|
377
|
-
|
|
378
|
-
Please check webstudio --help for more details`
|
|
509
|
+
log2.error(
|
|
510
|
+
`Template ${options.template} is not available
|
|
511
|
+
Please check webstudio --help for more details`
|
|
379
512
|
);
|
|
513
|
+
exit2(1);
|
|
380
514
|
}
|
|
381
515
|
}
|
|
382
|
-
|
|
383
|
-
spinner.start();
|
|
384
|
-
spinner.text = "Generating files";
|
|
516
|
+
log2.step("Scaffolding the project files");
|
|
385
517
|
const appRoot = "app";
|
|
386
518
|
const generatedDir = join4(appRoot, "__generated__");
|
|
387
519
|
await rm(generatedDir, { recursive: true, force: true });
|
|
@@ -480,7 +612,7 @@ var prebuild = async (options) => {
|
|
|
480
612
|
};
|
|
481
613
|
componentsByPage[page.id] = /* @__PURE__ */ new Set();
|
|
482
614
|
for (const [_instanceId, instance] of instances) {
|
|
483
|
-
if (instance.component
|
|
615
|
+
if (isCoreComponent(instance.component)) {
|
|
484
616
|
continue;
|
|
485
617
|
}
|
|
486
618
|
componentsByPage[page.id].add(instance.component);
|
|
@@ -544,8 +676,9 @@ var prebuild = async (options) => {
|
|
|
544
676
|
}
|
|
545
677
|
}
|
|
546
678
|
const assets = new Map(siteData.assets.map((asset) => [asset.id, asset]));
|
|
547
|
-
spinner.text = "Generating css file";
|
|
548
679
|
const { cssText, classesMap } = generateCss({
|
|
680
|
+
instances: new Map(siteData.build.instances),
|
|
681
|
+
props: new Map(siteData.build.props),
|
|
549
682
|
assets,
|
|
550
683
|
breakpoints: new Map(siteData.build?.breakpoints),
|
|
551
684
|
styles: new Map(siteData.build?.styles),
|
|
@@ -555,11 +688,17 @@ var prebuild = async (options) => {
|
|
|
555
688
|
assetBaseUrl,
|
|
556
689
|
atomic: siteData.build.pages.compiler?.atomicStyles ?? true
|
|
557
690
|
});
|
|
558
|
-
await
|
|
559
|
-
|
|
560
|
-
const routeTemplatePath = normalize(join4(
|
|
691
|
+
await createFileIfNotExists(join4(generatedDir, "index.css"), cssText);
|
|
692
|
+
const routeTemplatesDir = join4(cwd3(), "app/route-templates");
|
|
693
|
+
const routeTemplatePath = normalize(join4(routeTemplatesDir, "html.tsx"));
|
|
694
|
+
const routeXmlTemplatePath = normalize(join4(routeTemplatesDir, "xml.tsx"));
|
|
695
|
+
const defaultSiteMapXmlPath = normalize(
|
|
696
|
+
join4(routeTemplatesDir, "default-sitemap.tsx")
|
|
697
|
+
);
|
|
561
698
|
const routeFileTemplate = await readFile4(routeTemplatePath, "utf8");
|
|
562
|
-
await
|
|
699
|
+
const routeXmlFileTemplate = await readFile4(routeXmlTemplatePath, "utf8");
|
|
700
|
+
const defaultSiteMapTemplate = await readFile4(defaultSiteMapXmlPath, "utf8");
|
|
701
|
+
await rm(routeTemplatesDir, { recursive: true, force: true });
|
|
563
702
|
for (const [pageId, pageComponents] of Object.entries(componentsByPage)) {
|
|
564
703
|
const scope = createScope([
|
|
565
704
|
// manually maintained list of occupied identifiers
|
|
@@ -592,14 +731,36 @@ var prebuild = async (options) => {
|
|
|
592
731
|
namespaces.get(namespace)?.add([shortName, component]);
|
|
593
732
|
}
|
|
594
733
|
let componentImports = "";
|
|
734
|
+
let xmlPresentationComponents = "";
|
|
735
|
+
const pageData = siteDataByPage[pageId];
|
|
736
|
+
const documentType = pageData.page.meta.documentType ?? "html";
|
|
595
737
|
for (const [namespace, componentsSet] of namespaces.entries()) {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
738
|
+
switch (documentType) {
|
|
739
|
+
case "html":
|
|
740
|
+
{
|
|
741
|
+
const specifiers = Array.from(componentsSet).map(
|
|
742
|
+
([shortName, component]) => `${shortName} as ${scope.getName(component, shortName)}`
|
|
743
|
+
).join(", ");
|
|
744
|
+
componentImports += `import { ${specifiers} } from "${namespace}";
|
|
600
745
|
`;
|
|
746
|
+
}
|
|
747
|
+
break;
|
|
748
|
+
case "xml":
|
|
749
|
+
{
|
|
750
|
+
componentImports = `import { XmlNode } from "@webstudio-is/sdk-components-react";
|
|
751
|
+
`;
|
|
752
|
+
xmlPresentationComponents += Array.from(componentsSet).map(
|
|
753
|
+
([shortName, component]) => scope.getName(component, shortName)
|
|
754
|
+
).filter((scopedName) => scopedName !== "XmlNode").map(
|
|
755
|
+
(scopedName) => scopedName === "Body" ? `const ${scopedName} = (props: any) => props.children;` : `const ${scopedName} = () => null;`
|
|
756
|
+
).join("\n");
|
|
757
|
+
}
|
|
758
|
+
break;
|
|
759
|
+
default: {
|
|
760
|
+
documentType;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
601
763
|
}
|
|
602
|
-
const pageData = siteDataByPage[pageId];
|
|
603
764
|
const pageFontAssets = fontAssetsByPage[pageId];
|
|
604
765
|
const pageBackgroundImageAssets = backgroundImageAssetsByPage[pageId];
|
|
605
766
|
const rootInstanceId = pageData.page.rootInstanceId;
|
|
@@ -638,83 +799,108 @@ var prebuild = async (options) => {
|
|
|
638
799
|
const pageMeta = pageData.page.meta;
|
|
639
800
|
const favIconAsset = assets.get(projectMeta?.faviconAssetId ?? "");
|
|
640
801
|
const socialImageAsset = assets.get(pageMeta.socialImageAssetId ?? "");
|
|
802
|
+
const pagePath = getPagePath(pageData.page.id, siteData.build.pages);
|
|
803
|
+
const remixRoute = generateRemixRoute(pagePath);
|
|
804
|
+
const fileName = `${remixRoute}.tsx`;
|
|
641
805
|
const pageExports = `/* eslint-disable */
|
|
642
|
-
/* This is a auto generated file for building the project */
|
|
806
|
+
/* This is a auto generated file for building the project */
|
|
643
807
|
|
|
644
808
|
|
|
645
|
-
import { Fragment, useState } from "react";
|
|
646
|
-
import type { FontAsset, ImageAsset } from "@webstudio-is/sdk";
|
|
647
|
-
import { useResource } from "@webstudio-is/react-sdk";
|
|
648
|
-
${componentImports}
|
|
809
|
+
import { Fragment, useState } from "react";
|
|
810
|
+
import type { FontAsset, ImageAsset } from "@webstudio-is/sdk";
|
|
811
|
+
import { useResource } from "@webstudio-is/react-sdk";
|
|
812
|
+
${componentImports}
|
|
649
813
|
|
|
650
|
-
export const siteName = ${JSON.stringify(projectMeta?.siteName)};
|
|
814
|
+
export const siteName = ${JSON.stringify(projectMeta?.siteName)};
|
|
651
815
|
|
|
652
|
-
export const favIconAsset: ImageAsset | undefined =
|
|
653
|
-
|
|
816
|
+
export const favIconAsset: ImageAsset | undefined =
|
|
817
|
+
${JSON.stringify(favIconAsset)};
|
|
654
818
|
|
|
655
|
-
export const socialImageAsset: ImageAsset | undefined =
|
|
656
|
-
|
|
819
|
+
export const socialImageAsset: ImageAsset | undefined =
|
|
820
|
+
${JSON.stringify(socialImageAsset)};
|
|
657
821
|
|
|
658
|
-
// Font assets on current page (can be preloaded)
|
|
659
|
-
export const pageFontAssets: FontAsset[] =
|
|
660
|
-
|
|
822
|
+
// Font assets on current page (can be preloaded)
|
|
823
|
+
export const pageFontAssets: FontAsset[] =
|
|
824
|
+
${JSON.stringify(pageFontAssets)}
|
|
661
825
|
|
|
662
|
-
export const pageBackgroundImageAssets: ImageAsset[] =
|
|
663
|
-
|
|
826
|
+
export const pageBackgroundImageAssets: ImageAsset[] =
|
|
827
|
+
${JSON.stringify(pageBackgroundImageAssets)}
|
|
664
828
|
|
|
829
|
+
${remixRoute === "_index" ? `
|
|
830
|
+
${projectMeta?.code ? `
|
|
831
|
+
const Script = ({children, ...props}: Record<string, string | boolean>) => {
|
|
832
|
+
if (children == null) {
|
|
833
|
+
return <script {...props} />;
|
|
834
|
+
}
|
|
665
835
|
|
|
836
|
+
return <script {...props} dangerouslySetInnerHTML={{__html: children}} />;
|
|
837
|
+
};
|
|
838
|
+
const Style = ({children, ...props}: Record<string, string | boolean>) => {
|
|
839
|
+
if (children == null) {
|
|
840
|
+
return <style {...props} />;
|
|
841
|
+
}
|
|
666
842
|
|
|
667
|
-
|
|
843
|
+
return <style {...props} dangerouslySetInnerHTML={{__html: children}} />;
|
|
844
|
+
};
|
|
845
|
+
` : ""}
|
|
668
846
|
|
|
669
|
-
export
|
|
670
|
-
|
|
847
|
+
export const CustomCode = () => {
|
|
848
|
+
return (<>${projectMeta?.code ? htmlToJsx(projectMeta.code) : ""}</>);
|
|
849
|
+
}
|
|
850
|
+
` : ""}
|
|
851
|
+
|
|
852
|
+
${xmlPresentationComponents}
|
|
853
|
+
|
|
854
|
+
${pageComponent}
|
|
855
|
+
|
|
856
|
+
export { Page }
|
|
857
|
+
`;
|
|
671
858
|
const serverExports = `/* eslint-disable */
|
|
672
|
-
/* This is a auto generated file for building the project */
|
|
859
|
+
/* This is a auto generated file for building the project */
|
|
673
860
|
|
|
674
861
|
|
|
675
|
-
import type { PageMeta } from "@webstudio-is/sdk";
|
|
676
|
-
${generateResourcesLoader({
|
|
862
|
+
import type { PageMeta } from "@webstudio-is/sdk";
|
|
863
|
+
${generateResourcesLoader({
|
|
677
864
|
scope,
|
|
678
865
|
page: pageData.page,
|
|
679
866
|
dataSources,
|
|
680
867
|
resources
|
|
681
868
|
})}
|
|
682
869
|
|
|
683
|
-
${generatePageMeta({
|
|
870
|
+
${generatePageMeta({
|
|
684
871
|
globalScope: scope,
|
|
685
872
|
page: pageData.page,
|
|
686
873
|
dataSources
|
|
687
874
|
})}
|
|
688
875
|
|
|
689
|
-
${generateFormsProperties(props)}
|
|
876
|
+
${generateFormsProperties(props)}
|
|
690
877
|
|
|
691
|
-
${generateRemixParams(pageData.page.path)}
|
|
878
|
+
${generateRemixParams(pageData.page.path)}
|
|
692
879
|
|
|
693
|
-
export const projectId = "${siteData.build.projectId}";
|
|
880
|
+
export const projectId = "${siteData.build.projectId}";
|
|
694
881
|
|
|
695
|
-
export const contactEmail = ${JSON.stringify(contactEmail)};
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
`;
|
|
699
|
-
const pagePath = getPagePath(pageData.page.id, siteData.build.pages);
|
|
700
|
-
const remixRoute = generateRemixRoute(pagePath);
|
|
701
|
-
const fileName = `${remixRoute}.tsx`;
|
|
702
|
-
const routeFileContent = routeFileTemplate.replace(
|
|
882
|
+
export const contactEmail = ${JSON.stringify(contactEmail)};
|
|
883
|
+
`;
|
|
884
|
+
const routeFileContent = (documentType === "html" ? routeFileTemplate : routeXmlFileTemplate).replace(
|
|
703
885
|
/".*\/__generated__\/_index"/,
|
|
704
886
|
`"../__generated__/${remixRoute}"`
|
|
705
887
|
).replace(
|
|
706
888
|
/".*\/__generated__\/_index.server"/,
|
|
707
889
|
`"../__generated__/${remixRoute}.server"`
|
|
708
890
|
);
|
|
709
|
-
await
|
|
710
|
-
await
|
|
711
|
-
await
|
|
891
|
+
await createFileIfNotExists(join4(routesDir, fileName), routeFileContent);
|
|
892
|
+
await createFileIfNotExists(join4(generatedDir, fileName), pageExports);
|
|
893
|
+
await createFileIfNotExists(
|
|
712
894
|
join4(generatedDir, `${remixRoute}.server.tsx`),
|
|
713
895
|
serverExports
|
|
714
896
|
);
|
|
715
897
|
}
|
|
716
|
-
await
|
|
717
|
-
join4(
|
|
898
|
+
await createFileIfNotExists(
|
|
899
|
+
join4(routesDir, "[sitemap.xml]._index.tsx"),
|
|
900
|
+
defaultSiteMapTemplate.replace(/".*\/__generated__\//, `"../__generated__/`)
|
|
901
|
+
);
|
|
902
|
+
await createFileIfNotExists(
|
|
903
|
+
join4(generatedDir, "$resources.sitemap.xml.ts"),
|
|
718
904
|
`
|
|
719
905
|
export const sitemap = ${JSON.stringify(
|
|
720
906
|
getStaticSiteMapXml(siteData.build.pages, siteData.build.updatedAt),
|
|
@@ -725,22 +911,25 @@ export const customCode = ${JSON.stringify(projectMeta?.code?.trim() ?? "")};
|
|
|
725
911
|
);
|
|
726
912
|
const redirects = siteData.build.pages?.redirects;
|
|
727
913
|
if (redirects !== void 0 && redirects.length > 0) {
|
|
728
|
-
spinner.text = "Generating redirects";
|
|
729
914
|
for (const redirect of redirects) {
|
|
730
915
|
const redirectPagePath = generateRemixRoute(redirect.old);
|
|
731
916
|
const redirectFileName = `${redirectPagePath}.ts`;
|
|
732
917
|
const content = `import { type LoaderFunctionArgs, redirect } from "@remix-run/server-runtime";
|
|
733
918
|
|
|
734
|
-
export const loader = (arg: LoaderFunctionArgs) => {
|
|
735
|
-
|
|
736
|
-
};
|
|
737
|
-
`;
|
|
738
|
-
await
|
|
919
|
+
export const loader = (arg: LoaderFunctionArgs) => {
|
|
920
|
+
return redirect("${redirect.new}", ${redirect.status ?? 301});
|
|
921
|
+
};
|
|
922
|
+
`;
|
|
923
|
+
await createFileIfNotExists(join4(routesDir, redirectFileName), content);
|
|
739
924
|
}
|
|
740
925
|
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
926
|
+
if (assetsToDownload.length > 0) {
|
|
927
|
+
const downloading = spinner2();
|
|
928
|
+
downloading.start("Downloading fonts and images");
|
|
929
|
+
await Promise.all(assetsToDownload);
|
|
930
|
+
downloading.stop("Downloaded fonts and images");
|
|
931
|
+
}
|
|
932
|
+
log2.step("Build finished");
|
|
744
933
|
};
|
|
745
934
|
|
|
746
935
|
// src/commands/build.ts
|
|
@@ -755,6 +944,7 @@ var buildOptions = (yargs) => yargs.option("assets", {
|
|
|
755
944
|
}).option("template", {
|
|
756
945
|
type: "array",
|
|
757
946
|
string: true,
|
|
947
|
+
default: [],
|
|
758
948
|
describe: `Template to use for the build [choices: ${PROJECT_TEMPALTES.join(
|
|
759
949
|
", "
|
|
760
950
|
)}]`
|
|
@@ -764,9 +954,10 @@ var build = async (options) => {
|
|
|
764
954
|
await access3(LOCAL_DATA_FILE);
|
|
765
955
|
} catch (error) {
|
|
766
956
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
767
|
-
|
|
957
|
+
log3.error(
|
|
768
958
|
`You need to link a webstudio project before building it. Run \`webstudio link\` to link a project.`
|
|
769
959
|
);
|
|
960
|
+
exit3(1);
|
|
770
961
|
}
|
|
771
962
|
throw error;
|
|
772
963
|
}
|
|
@@ -776,110 +967,99 @@ var build = async (options) => {
|
|
|
776
967
|
// src/commands/init-flow.ts
|
|
777
968
|
import { chdir, cwd as cwd4 } from "node:process";
|
|
778
969
|
import { join as join5 } from "node:path";
|
|
779
|
-
import ora3 from "ora";
|
|
780
|
-
|
|
781
|
-
// src/prompts.ts
|
|
782
|
-
import prompts from "prompts";
|
|
783
|
-
var prompt = (prompt2) => {
|
|
784
|
-
return prompts([
|
|
785
|
-
{
|
|
786
|
-
...prompt2,
|
|
787
|
-
onState: (state) => {
|
|
788
|
-
if (state.aborted) {
|
|
789
|
-
process.nextTick(() => {
|
|
790
|
-
process.exit(0);
|
|
791
|
-
});
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
]);
|
|
796
|
-
};
|
|
797
|
-
|
|
798
|
-
// src/commands/init-flow.ts
|
|
799
970
|
import pc2 from "picocolors";
|
|
971
|
+
import {
|
|
972
|
+
cancel as cancel2,
|
|
973
|
+
confirm,
|
|
974
|
+
isCancel as isCancel2,
|
|
975
|
+
log as log4,
|
|
976
|
+
select,
|
|
977
|
+
spinner as spinner3,
|
|
978
|
+
text as text2
|
|
979
|
+
} from "@clack/prompts";
|
|
800
980
|
import { $ } from "execa";
|
|
801
981
|
import { titleCase } from "title-case";
|
|
982
|
+
var exitIfCancelled = (value) => {
|
|
983
|
+
if (isCancel2(value)) {
|
|
984
|
+
cancel2("Project initialization is cancelled");
|
|
985
|
+
process.exit(0);
|
|
986
|
+
}
|
|
987
|
+
return value;
|
|
988
|
+
};
|
|
802
989
|
var initFlow = async (options) => {
|
|
803
990
|
const isProjectConfigured = await isFileExists(".webstudio/config.json");
|
|
804
991
|
let shouldInstallDeps = false;
|
|
805
992
|
let folderName;
|
|
806
993
|
let projectTemplate = void 0;
|
|
807
994
|
if (isProjectConfigured === false) {
|
|
808
|
-
const
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
995
|
+
const shouldCreateFolder = exitIfCancelled(
|
|
996
|
+
await confirm({
|
|
997
|
+
message: "Would you like to create a project folder? (no to use current folder)",
|
|
998
|
+
initialValue: true
|
|
999
|
+
})
|
|
1000
|
+
);
|
|
814
1001
|
if (shouldCreateFolder === true) {
|
|
815
|
-
folderName = (
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
1002
|
+
folderName = exitIfCancelled(
|
|
1003
|
+
await text2({
|
|
1004
|
+
message: "Please enter a project name",
|
|
1005
|
+
validate(value) {
|
|
1006
|
+
if (value.length === 0) {
|
|
1007
|
+
return "Folder name is required";
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
})
|
|
1011
|
+
);
|
|
1012
|
+
await createFolderIfNotExists(join5(cwd4(), folderName));
|
|
824
1013
|
chdir(join5(cwd4(), folderName));
|
|
825
1014
|
}
|
|
826
|
-
const
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
});
|
|
831
|
-
if (projectLink === void 0) {
|
|
832
|
-
throw new Error(`Project Link is required`);
|
|
833
|
-
}
|
|
834
|
-
await link({ link: projectLink });
|
|
835
|
-
const { deployTarget } = await prompt({
|
|
836
|
-
type: "select",
|
|
837
|
-
name: "deployTarget",
|
|
838
|
-
message: "Where would you like to deploy your project?",
|
|
839
|
-
choices: PROJECT_TEMPALTES.map((template) => {
|
|
840
|
-
return {
|
|
841
|
-
title: titleCase(template),
|
|
842
|
-
value: template
|
|
843
|
-
};
|
|
1015
|
+
const shareLink = exitIfCancelled(
|
|
1016
|
+
await text2({
|
|
1017
|
+
message: "Please paste a link from the Share Dialog in the builder",
|
|
1018
|
+
validate: validateShareLink
|
|
844
1019
|
})
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
1020
|
+
);
|
|
1021
|
+
await link({ link: shareLink });
|
|
1022
|
+
projectTemplate = exitIfCancelled(
|
|
1023
|
+
await select({
|
|
1024
|
+
message: "Where would you like to deploy your project?",
|
|
1025
|
+
options: PROJECT_TEMPALTES.map((template) => ({
|
|
1026
|
+
value: template,
|
|
1027
|
+
label: titleCase(template)
|
|
1028
|
+
}))
|
|
1029
|
+
})
|
|
1030
|
+
);
|
|
1031
|
+
shouldInstallDeps = exitIfCancelled(
|
|
1032
|
+
await confirm({
|
|
1033
|
+
message: "Would you like to install dependencies? (recommended)",
|
|
1034
|
+
initialValue: true
|
|
1035
|
+
})
|
|
1036
|
+
);
|
|
854
1037
|
}
|
|
855
|
-
await sync({ buildId: void 0, origin: void 0, authToken: void 0 });
|
|
856
1038
|
if (projectTemplate === void 0) {
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
value: template
|
|
865
|
-
};
|
|
1039
|
+
projectTemplate = exitIfCancelled(
|
|
1040
|
+
await select({
|
|
1041
|
+
message: "Where would you like to deploy your project?",
|
|
1042
|
+
options: PROJECT_TEMPALTES.map((template) => ({
|
|
1043
|
+
value: template,
|
|
1044
|
+
label: titleCase(template)
|
|
1045
|
+
}))
|
|
866
1046
|
})
|
|
867
|
-
|
|
868
|
-
projectTemplate = deployTarget;
|
|
1047
|
+
);
|
|
869
1048
|
}
|
|
1049
|
+
await sync({ buildId: void 0, origin: void 0, authToken: void 0 });
|
|
870
1050
|
await build({
|
|
871
1051
|
...options,
|
|
872
1052
|
...projectTemplate && { template: [projectTemplate] }
|
|
873
1053
|
});
|
|
874
1054
|
if (shouldInstallDeps === true) {
|
|
875
|
-
const
|
|
876
|
-
|
|
1055
|
+
const install = spinner3();
|
|
1056
|
+
install.start("Installing dependencies");
|
|
877
1057
|
await $`npm install`;
|
|
878
|
-
|
|
1058
|
+
install.stop("Installed dependencies");
|
|
879
1059
|
}
|
|
880
|
-
|
|
881
|
-
Your project was successfully synced \u{1F389}`)));
|
|
882
|
-
|
|
1060
|
+
log4.message();
|
|
1061
|
+
log4.message(pc2.green(pc2.bold(`Your project was successfully synced \u{1F389}`)));
|
|
1062
|
+
log4.message(
|
|
883
1063
|
[
|
|
884
1064
|
"Now you can:",
|
|
885
1065
|
folderName && `Go to your project: ${pc2.dim(`cd ${folderName}`)}`,
|
|
@@ -912,7 +1092,7 @@ import makeCLI from "yargs";
|
|
|
912
1092
|
// package.json
|
|
913
1093
|
var package_default = {
|
|
914
1094
|
name: "webstudio",
|
|
915
|
-
version: "0.
|
|
1095
|
+
version: "0.167.0",
|
|
916
1096
|
description: "Webstudio CLI",
|
|
917
1097
|
author: "Webstudio <github@webstudio.is>",
|
|
918
1098
|
homepage: "https://webstudio.is",
|
|
@@ -932,10 +1112,12 @@ var package_default = {
|
|
|
932
1112
|
checks: "pnpm typecheck",
|
|
933
1113
|
build: "rm -rf lib && esbuild src/cli.ts --outdir=lib --bundle --format=esm --packages=external",
|
|
934
1114
|
"local-run": "tsx --no-warnings ./src/bin.ts",
|
|
935
|
-
dev: "esbuild src/cli.ts --watch --bundle --format=esm --packages=external --outdir=./lib"
|
|
1115
|
+
dev: "esbuild src/cli.ts --watch --bundle --format=esm --packages=external --outdir=./lib",
|
|
1116
|
+
test: "NODE_OPTIONS=--experimental-vm-modules jest"
|
|
936
1117
|
},
|
|
937
1118
|
license: "AGPL-3.0-or-later",
|
|
938
1119
|
dependencies: {
|
|
1120
|
+
"@clack/prompts": "^0.7.0",
|
|
939
1121
|
"@webstudio-is/http-client": "workspace:*",
|
|
940
1122
|
"@webstudio-is/image": "workspace:*",
|
|
941
1123
|
"@webstudio-is/react-sdk": "workspace:*",
|
|
@@ -943,39 +1125,39 @@ var package_default = {
|
|
|
943
1125
|
"@webstudio-is/sdk-components-react": "workspace:*",
|
|
944
1126
|
"@webstudio-is/sdk-components-react-radix": "workspace:*",
|
|
945
1127
|
"@webstudio-is/sdk-components-react-remix": "workspace:*",
|
|
1128
|
+
"change-case": "^5.0.2",
|
|
946
1129
|
deepmerge: "^4.3.1",
|
|
947
1130
|
"env-paths": "^3.0.0",
|
|
948
1131
|
execa: "^7.2.0",
|
|
949
|
-
|
|
1132
|
+
parse5: "7.1.2",
|
|
950
1133
|
"p-limit": "^4.0.0",
|
|
951
|
-
picocolors: "^1.0.
|
|
952
|
-
prompts: "^2.4.2",
|
|
1134
|
+
picocolors: "^1.0.1",
|
|
953
1135
|
"strip-indent": "^4.0.0",
|
|
954
1136
|
"title-case": "^4.1.0",
|
|
955
1137
|
yargs: "^17.7.2",
|
|
956
1138
|
zod: "^3.22.4"
|
|
957
1139
|
},
|
|
958
1140
|
devDependencies: {
|
|
959
|
-
"@
|
|
960
|
-
"@netlify/remix-
|
|
961
|
-
"@remix-
|
|
962
|
-
"@remix-run/cloudflare
|
|
963
|
-
"@remix-run/
|
|
964
|
-
"@remix-run/
|
|
965
|
-
"@remix-run/
|
|
966
|
-
"@remix-run/
|
|
1141
|
+
"@jest/globals": "^29.7.0",
|
|
1142
|
+
"@netlify/remix-adapter": "^2.4.0",
|
|
1143
|
+
"@netlify/remix-edge-adapter": "3.3.0",
|
|
1144
|
+
"@remix-run/cloudflare": "^2.9.2",
|
|
1145
|
+
"@remix-run/cloudflare-pages": "^2.9.2",
|
|
1146
|
+
"@remix-run/dev": "^2.9.2",
|
|
1147
|
+
"@remix-run/node": "^2.9.2",
|
|
1148
|
+
"@remix-run/react": "^2.9.2",
|
|
1149
|
+
"@remix-run/server-runtime": "^2.9.2",
|
|
967
1150
|
"@types/node": "^20.12.7",
|
|
968
|
-
"@types/prompts": "^2.4.5",
|
|
969
1151
|
"@types/react": "^18.2.70",
|
|
970
1152
|
"@types/react-dom": "^18.2.25",
|
|
971
1153
|
"@types/yargs": "^17.0.32",
|
|
972
1154
|
"@webstudio-is/form-handlers": "workspace:*",
|
|
1155
|
+
"@webstudio-is/jest-config": "workspace:*",
|
|
973
1156
|
"@webstudio-is/tsconfig": "workspace:*",
|
|
974
1157
|
react: "18.3.0-canary-14898b6a9-20240318",
|
|
975
1158
|
"react-dom": "18.3.0-canary-14898b6a9-20240318",
|
|
976
|
-
tsx: "^4.7.2",
|
|
977
1159
|
typescript: "5.4.5",
|
|
978
|
-
vite: "^5.2.
|
|
1160
|
+
vite: "^5.2.12",
|
|
979
1161
|
wrangler: "^3.48.0"
|
|
980
1162
|
}
|
|
981
1163
|
};
|
|
@@ -983,7 +1165,7 @@ var package_default = {
|
|
|
983
1165
|
// src/cli.ts
|
|
984
1166
|
var main = async () => {
|
|
985
1167
|
try {
|
|
986
|
-
await
|
|
1168
|
+
await createFileIfNotExists(GLOBAL_CONFIG_FILE, "{}");
|
|
987
1169
|
const cmd = makeCLI(hideBin(argv)).strict().fail(function(msg, err, yargs) {
|
|
988
1170
|
if (err) {
|
|
989
1171
|
throw err;
|
|
@@ -1019,7 +1201,7 @@ var main = async () => {
|
|
|
1019
1201
|
await cmd.parse();
|
|
1020
1202
|
} catch (error) {
|
|
1021
1203
|
console.error(error);
|
|
1022
|
-
|
|
1204
|
+
exit4(1);
|
|
1023
1205
|
}
|
|
1024
1206
|
};
|
|
1025
1207
|
export {
|