webstudio 0.267.0 → 0.269.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 +628 -50
- package/package.json +15 -14
- package/templates/cloudflare/package.json +1 -0
- package/templates/defaults/app/redirect-url.ts +21 -0
- package/templates/defaults/app/root.tsx +9 -0
- package/templates/defaults/app/route-templates/html.tsx +56 -12
- package/templates/defaults/app/route-templates/redirect.tsx +4 -3
- package/templates/defaults/app/route-templates/text.tsx +107 -0
- package/templates/defaults/app/route-templates/xml.tsx +28 -2
- package/templates/defaults/package.json +8 -7
- package/templates/internal/package.json +2 -1
- package/templates/react-router/app/redirect-url.ts +21 -0
- package/templates/react-router/app/root.tsx +15 -1
- package/templates/react-router/app/route-templates/html.tsx +56 -12
- package/templates/react-router/app/route-templates/redirect.tsx +4 -3
- package/templates/react-router/app/route-templates/text.tsx +107 -0
- package/templates/react-router/app/route-templates/xml.tsx +28 -2
- package/templates/react-router/package.json +8 -7
- package/templates/react-router-cloudflare/package.json +1 -0
- package/templates/ssg/app/route-templates/html/+Page.tsx +34 -11
- package/templates/ssg/package.json +6 -6
- package/templates/ssg/renderer/+onRenderClient.tsx +3 -2
- package/templates/ssg/public/favicon.ico +0 -0
package/lib/cli.js
CHANGED
|
@@ -374,7 +374,7 @@ const getApiCompatibilityPayload = (value) => {
|
|
|
374
374
|
return findPayload(value, /* @__PURE__ */ new WeakSet());
|
|
375
375
|
};
|
|
376
376
|
const name = "webstudio";
|
|
377
|
-
const version = "0.
|
|
377
|
+
const version = "0.269.0";
|
|
378
378
|
const description = "Webstudio CLI";
|
|
379
379
|
const author = "Webstudio <github@webstudio.is>";
|
|
380
380
|
const homepage = "https://webstudio.is";
|
|
@@ -386,7 +386,7 @@ const scripts = { "typecheck": "tsgo --noEmit", "build": "rm -rf lib && vite bui
|
|
|
386
386
|
const license = "AGPL-3.0-or-later";
|
|
387
387
|
const engines = { "node": ">=22" };
|
|
388
388
|
const dependencies = { "@clack/prompts": "^0.10.0", "@emotion/hash": "^0.9.2", "@trpc/client": "^10.45.2", "@webstudio-is/project-migrations": "workspace:*", "@webstudio-is/trpc-interface": "workspace:*", "acorn": "^8.14.1", "acorn-walk": "^8.3.4", "change-case": "^5.4.4", "deepmerge": "^4.3.1", "env-paths": "^3.0.0", "nanoid": "^5.1.5", "p-limit": "^6.2.0", "parse5": "7.3.0", "picocolors": "^1.1.1", "reserved-identifiers": "^1.0.0", "tinyexec": "^0.3.2", "warn-once": "^0.1.1", "yargs": "^17.7.2", "zod": "^3.24.2" };
|
|
389
|
-
const devDependencies = { "@cloudflare/vite-plugin": "^1.1.0", "@netlify/vite-plugin-react-router": "^1.0.1", "@react-router/dev": "^7.5.3", "@react-router/fs-routes": "^7.5.3", "@remix-run/cloudflare": "^2.16.5", "@remix-run/cloudflare-pages": "^2.16.5", "@remix-run/dev": "^2.16.5", "@remix-run/node": "^2.16.5", "@remix-run/react": "^2.16.5", "@remix-run/server-runtime": "^2.16.5", "@types/react": "^18.2.70", "@types/react-dom": "^18.2.25", "@types/yargs": "^17.0.33", "@vercel/react-router": "^1.1.0", "@vitejs/plugin-react": "^4.4.1", "@webstudio-is/css-engine": "workspace:*", "@webstudio-is/http-client": "workspace:*", "@webstudio-is/image": "workspace:*", "@webstudio-is/react-sdk": "workspace:*", "@webstudio-is/sdk": "workspace:*", "@webstudio-is/sdk-components-animation": "workspace:*", "@webstudio-is/sdk-components-react": "workspace:*", "@webstudio-is/sdk-components-react-radix": "workspace:*", "@webstudio-is/sdk-components-react-remix": "workspace:*", "@webstudio-is/sdk-components-react-router": "workspace:*", "@webstudio-is/tsconfig": "workspace:*", "h3": "^1.15.1", "ipx": "^3.0.3", "isbot": "^5.1.25", "prettier": "3.5.3", "react": "18.3.0-canary-14898b6a9-20240318", "react-dom": "18.3.0-canary-14898b6a9-20240318", "react-router": "^7.5.3", "ts-expect": "^1.3.0", "vike": "^0.4.229", "vite": "^6.3.4", "vitest": "^3.1.2", "wrangler": "^3.63.2" };
|
|
389
|
+
const devDependencies = { "@cloudflare/vite-plugin": "^1.1.0", "@netlify/vite-plugin-react-router": "^1.0.1", "@react-router/dev": "^7.5.3", "@react-router/fs-routes": "^7.5.3", "@remix-run/cloudflare": "^2.16.5", "@remix-run/cloudflare-pages": "^2.16.5", "@remix-run/dev": "^2.16.5", "@remix-run/node": "^2.16.5", "@remix-run/react": "^2.16.5", "@remix-run/server-runtime": "^2.16.5", "@types/react": "^18.2.70", "@types/react-dom": "^18.2.25", "@types/yargs": "^17.0.33", "@vercel/react-router": "^1.1.0", "@vitejs/plugin-react": "^4.4.1", "@webstudio-is/css-engine": "workspace:*", "@webstudio-is/http-client": "workspace:*", "@webstudio-is/image": "workspace:*", "@webstudio-is/react-sdk": "workspace:*", "@webstudio-is/sdk": "workspace:*", "@webstudio-is/sdk-components-animation": "workspace:*", "@webstudio-is/sdk-components-react": "workspace:*", "@webstudio-is/sdk-components-react-radix": "workspace:*", "@webstudio-is/sdk-components-react-remix": "workspace:*", "@webstudio-is/sdk-components-react-router": "workspace:*", "@webstudio-is/tsconfig": "workspace:*", "@webstudio-is/wsauth": "workspace:*", "h3": "^1.15.1", "ipx": "^3.0.3", "isbot": "^5.1.25", "prettier": "3.5.3", "react": "18.3.0-canary-14898b6a9-20240318", "react-dom": "18.3.0-canary-14898b6a9-20240318", "react-router": "^7.5.3", "ts-expect": "^1.3.0", "vike": "^0.4.229", "vite": "^6.3.4", "vitest": "^3.1.2", "wrangler": "^3.63.2" };
|
|
390
390
|
const packageJson = {
|
|
391
391
|
name,
|
|
392
392
|
version,
|
|
@@ -892,6 +892,293 @@ new Map(
|
|
|
892
892
|
return weightData.names.map((name2) => [name2, weight]);
|
|
893
893
|
}).flat()
|
|
894
894
|
);
|
|
895
|
+
var basicLoginErrors = (login) => {
|
|
896
|
+
const issues = [];
|
|
897
|
+
if (login.length === 0) {
|
|
898
|
+
issues.push({ path: ["login"], message: "Login is required" });
|
|
899
|
+
}
|
|
900
|
+
if (login.includes(":")) {
|
|
901
|
+
issues.push({ path: ["login"], message: "Login can't contain a colon" });
|
|
902
|
+
}
|
|
903
|
+
if (/\s/.test(login)) {
|
|
904
|
+
issues.push({
|
|
905
|
+
path: ["login"],
|
|
906
|
+
message: "Login can't contain whitespace"
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
return issues;
|
|
910
|
+
};
|
|
911
|
+
var basicPasswordErrors = (password) => {
|
|
912
|
+
const issues = [];
|
|
913
|
+
if (password.length === 0) {
|
|
914
|
+
issues.push({ path: ["password"], message: "Password is required" });
|
|
915
|
+
}
|
|
916
|
+
if (/\s/.test(password)) {
|
|
917
|
+
issues.push({
|
|
918
|
+
path: ["password"],
|
|
919
|
+
message: "Password can't contain whitespace"
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
return issues;
|
|
923
|
+
};
|
|
924
|
+
var validateBasicAuth = ({
|
|
925
|
+
login,
|
|
926
|
+
password
|
|
927
|
+
}) => {
|
|
928
|
+
const issues = [...basicLoginErrors(login), ...basicPasswordErrors(password)];
|
|
929
|
+
if (issues.length > 0) {
|
|
930
|
+
const loginErrors = issues.filter((issue) => issue.path[0] === "login").map((issue) => issue.message);
|
|
931
|
+
const passwordErrors = issues.filter((issue) => issue.path[0] === "password").map((issue) => issue.message);
|
|
932
|
+
return {
|
|
933
|
+
issues,
|
|
934
|
+
errors: {
|
|
935
|
+
login: loginErrors.length > 0 ? loginErrors : void 0,
|
|
936
|
+
password: passwordErrors.length > 0 ? passwordErrors : void 0
|
|
937
|
+
}
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
return {
|
|
941
|
+
auth: {
|
|
942
|
+
method: "basic",
|
|
943
|
+
login,
|
|
944
|
+
password,
|
|
945
|
+
credentials: `${login}:${password}`
|
|
946
|
+
}
|
|
947
|
+
};
|
|
948
|
+
};
|
|
949
|
+
var createBasicAuthRoute = ({
|
|
950
|
+
route,
|
|
951
|
+
login,
|
|
952
|
+
password
|
|
953
|
+
}) => {
|
|
954
|
+
const routeError = validateWsAuthRoute(route);
|
|
955
|
+
if (routeError) {
|
|
956
|
+
throw new Error(routeError);
|
|
957
|
+
}
|
|
958
|
+
const auth = validateBasicAuth({ login, password }).auth;
|
|
959
|
+
if (auth === void 0) {
|
|
960
|
+
throw new Error(
|
|
961
|
+
'Basic auth requires non-empty login and password; login cannot contain ":" and neither field can contain whitespace'
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
return { route, auth };
|
|
965
|
+
};
|
|
966
|
+
var createWsAuthRouteFromPage = ({
|
|
967
|
+
route,
|
|
968
|
+
auth
|
|
969
|
+
}) => {
|
|
970
|
+
if (auth === void 0) {
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
973
|
+
if ("method" in auth && auth.method !== "basic" || "type" in auth && auth.type !== "basic") {
|
|
974
|
+
throw new Error(`Unsupported auth method for route "${route}"`);
|
|
975
|
+
}
|
|
976
|
+
return createBasicAuthRoute({
|
|
977
|
+
route,
|
|
978
|
+
login: auth.login,
|
|
979
|
+
password: auth.password
|
|
980
|
+
});
|
|
981
|
+
};
|
|
982
|
+
var isRecord = (value) => {
|
|
983
|
+
return typeof value === "object" && value !== null && Array.isArray(value) === false;
|
|
984
|
+
};
|
|
985
|
+
var parameterSegment = /^:\w+[?*]?$/;
|
|
986
|
+
var validateWsAuthRoute = (route) => {
|
|
987
|
+
if (route.startsWith("/") === false) {
|
|
988
|
+
return 'Route must start with "/"';
|
|
989
|
+
}
|
|
990
|
+
if (route === "/") {
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
993
|
+
if (route !== "/" && route.endsWith("/")) {
|
|
994
|
+
return 'Route must not end with "/"';
|
|
995
|
+
}
|
|
996
|
+
if (route.includes("//")) {
|
|
997
|
+
return 'Route must not contain repeating "/"';
|
|
998
|
+
}
|
|
999
|
+
const segments = route.slice(1).split("/");
|
|
1000
|
+
for (let index = 0; index < segments.length; index += 1) {
|
|
1001
|
+
const segment = segments[index];
|
|
1002
|
+
if (segment === void 0 || segment === "") {
|
|
1003
|
+
return "Route contains an empty segment";
|
|
1004
|
+
}
|
|
1005
|
+
if (segment === "*" || /^:\w+\*$/.test(segment)) {
|
|
1006
|
+
if (index !== segments.length - 1) {
|
|
1007
|
+
return "Wildcard route segment must be the last segment";
|
|
1008
|
+
}
|
|
1009
|
+
continue;
|
|
1010
|
+
}
|
|
1011
|
+
if (segment.startsWith(":") && parameterSegment.test(segment) === false) {
|
|
1012
|
+
return `Invalid route parameter "${segment}"`;
|
|
1013
|
+
}
|
|
1014
|
+
if (segment.includes("*")) {
|
|
1015
|
+
return "Wildcard can only be used as * or :name*";
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
};
|
|
1019
|
+
var parseJson = (content, errors) => {
|
|
1020
|
+
if (content.trim() === "") {
|
|
1021
|
+
return { version: 1, routes: {} };
|
|
1022
|
+
}
|
|
1023
|
+
try {
|
|
1024
|
+
return JSON.parse(content);
|
|
1025
|
+
} catch (error) {
|
|
1026
|
+
errors.push({
|
|
1027
|
+
path: "$",
|
|
1028
|
+
message: error instanceof Error ? error.message : "Invalid JSON"
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1032
|
+
var parseWsAuth = (content) => {
|
|
1033
|
+
const routes = [];
|
|
1034
|
+
const errors = [];
|
|
1035
|
+
const json = parseJson(content, errors);
|
|
1036
|
+
if (json === void 0) {
|
|
1037
|
+
return { routes, errors };
|
|
1038
|
+
}
|
|
1039
|
+
if (isRecord(json) === false) {
|
|
1040
|
+
errors.push({ path: "$", message: "Auth config must be an object" });
|
|
1041
|
+
return { routes, errors };
|
|
1042
|
+
}
|
|
1043
|
+
if (json.version !== 1) {
|
|
1044
|
+
errors.push({ path: "version", message: "Version must be 1" });
|
|
1045
|
+
}
|
|
1046
|
+
if (isRecord(json.routes) === false) {
|
|
1047
|
+
errors.push({ path: "routes", message: "Routes must be an object" });
|
|
1048
|
+
return { routes, errors };
|
|
1049
|
+
}
|
|
1050
|
+
for (const [route, authInput] of Object.entries(json.routes)) {
|
|
1051
|
+
const routeError = validateWsAuthRoute(route);
|
|
1052
|
+
if (routeError) {
|
|
1053
|
+
errors.push({
|
|
1054
|
+
path: `routes.${JSON.stringify(route)}`,
|
|
1055
|
+
message: routeError
|
|
1056
|
+
});
|
|
1057
|
+
continue;
|
|
1058
|
+
}
|
|
1059
|
+
if (isRecord(authInput) === false) {
|
|
1060
|
+
errors.push({
|
|
1061
|
+
path: `routes.${JSON.stringify(route)}`,
|
|
1062
|
+
message: "Auth rule must be an object"
|
|
1063
|
+
});
|
|
1064
|
+
continue;
|
|
1065
|
+
}
|
|
1066
|
+
if (authInput.method !== "basic") {
|
|
1067
|
+
errors.push({
|
|
1068
|
+
path: `routes.${JSON.stringify(route)}.method`,
|
|
1069
|
+
message: 'Auth method must be "basic"'
|
|
1070
|
+
});
|
|
1071
|
+
continue;
|
|
1072
|
+
}
|
|
1073
|
+
const login = authInput.login;
|
|
1074
|
+
const password = authInput.password;
|
|
1075
|
+
if (typeof login !== "string") {
|
|
1076
|
+
errors.push({
|
|
1077
|
+
path: `routes.${JSON.stringify(route)}.login`,
|
|
1078
|
+
message: "Login must be a string"
|
|
1079
|
+
});
|
|
1080
|
+
continue;
|
|
1081
|
+
}
|
|
1082
|
+
if (typeof password !== "string") {
|
|
1083
|
+
errors.push({
|
|
1084
|
+
path: `routes.${JSON.stringify(route)}.password`,
|
|
1085
|
+
message: "Password must be a string"
|
|
1086
|
+
});
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1089
|
+
const validation = validateBasicAuth({ login, password });
|
|
1090
|
+
if (validation.auth === void 0) {
|
|
1091
|
+
for (const issue of validation.issues ?? []) {
|
|
1092
|
+
errors.push({
|
|
1093
|
+
path: `routes.${JSON.stringify(route)}.${issue.path[0]}`,
|
|
1094
|
+
message: issue.message
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
continue;
|
|
1098
|
+
}
|
|
1099
|
+
const auth = validation.auth;
|
|
1100
|
+
routes.push({ route, auth });
|
|
1101
|
+
}
|
|
1102
|
+
return { routes, errors };
|
|
1103
|
+
};
|
|
1104
|
+
var parseWsAuthOrThrow = (content, sourceName) => {
|
|
1105
|
+
const result = parseWsAuth(content);
|
|
1106
|
+
if (result.errors.length > 0) {
|
|
1107
|
+
const message = result.errors.map((error) => `${sourceName}:${error.path} ${error.message}`).join("\n");
|
|
1108
|
+
throw new Error(message);
|
|
1109
|
+
}
|
|
1110
|
+
return result.routes;
|
|
1111
|
+
};
|
|
1112
|
+
var serializeWsAuth = (routes) => {
|
|
1113
|
+
const config = { version: 1, routes: {} };
|
|
1114
|
+
for (const { route, auth } of routes) {
|
|
1115
|
+
switch (auth.method) {
|
|
1116
|
+
case "basic":
|
|
1117
|
+
config.routes[route] = {
|
|
1118
|
+
method: "basic",
|
|
1119
|
+
login: auth.login,
|
|
1120
|
+
password: auth.password
|
|
1121
|
+
};
|
|
1122
|
+
break;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
return `${JSON.stringify(config, null, 2)}
|
|
1126
|
+
`;
|
|
1127
|
+
};
|
|
1128
|
+
var collectWsAuthRoutes = (sources) => {
|
|
1129
|
+
return sources.flatMap((source) => {
|
|
1130
|
+
if ("content" in source) {
|
|
1131
|
+
return parseWsAuthOrThrow(source.content, source.name);
|
|
1132
|
+
}
|
|
1133
|
+
return source.routes;
|
|
1134
|
+
});
|
|
1135
|
+
};
|
|
1136
|
+
var buildWsAuth = (sources) => {
|
|
1137
|
+
const content = serializeWsAuth(collectWsAuthRoutes(sources));
|
|
1138
|
+
const routes = parseWsAuthOrThrow(content, "Serialized auth config");
|
|
1139
|
+
return {
|
|
1140
|
+
routes,
|
|
1141
|
+
content
|
|
1142
|
+
};
|
|
1143
|
+
};
|
|
1144
|
+
var createWsAuthResources = ({
|
|
1145
|
+
projectContent = "",
|
|
1146
|
+
pages,
|
|
1147
|
+
projectSourceName = "Auth",
|
|
1148
|
+
generatedSourceName = "Generated page auth"
|
|
1149
|
+
}) => {
|
|
1150
|
+
const generatedRoutes = pages.flatMap((page) => {
|
|
1151
|
+
const route = createWsAuthRouteFromPage(page);
|
|
1152
|
+
return route === void 0 ? [] : [route];
|
|
1153
|
+
});
|
|
1154
|
+
const result = buildWsAuth([
|
|
1155
|
+
{ name: projectSourceName, content: projectContent },
|
|
1156
|
+
{ name: generatedSourceName, routes: generatedRoutes }
|
|
1157
|
+
]);
|
|
1158
|
+
console.info("[wsauth] create resources", {
|
|
1159
|
+
projectContentLength: projectContent.length,
|
|
1160
|
+
projectContent,
|
|
1161
|
+
pageCount: pages.length,
|
|
1162
|
+
pages,
|
|
1163
|
+
generatedRouteCount: generatedRoutes.length,
|
|
1164
|
+
generatedRoutes,
|
|
1165
|
+
routeCount: result.routes.length,
|
|
1166
|
+
routes: result.routes
|
|
1167
|
+
});
|
|
1168
|
+
return {
|
|
1169
|
+
...result,
|
|
1170
|
+
module: [
|
|
1171
|
+
`import type { WsAuthRoute } from "@webstudio-is/wsauth";`,
|
|
1172
|
+
"",
|
|
1173
|
+
`export const authRoutes: WsAuthRoute[] = ${JSON.stringify(
|
|
1174
|
+
result.routes,
|
|
1175
|
+
null,
|
|
1176
|
+
2
|
|
1177
|
+
)};`,
|
|
1178
|
+
""
|
|
1179
|
+
].join("\n")
|
|
1180
|
+
};
|
|
1181
|
+
};
|
|
895
1182
|
function dot3(a2, b2) {
|
|
896
1183
|
return a2[0] * b2[0] + a2[1] * b2[1] + a2[2] * b2[2];
|
|
897
1184
|
}
|
|
@@ -2687,8 +2974,19 @@ const oklch = new ColorSpace({
|
|
|
2687
2974
|
}
|
|
2688
2975
|
}
|
|
2689
2976
|
});
|
|
2977
|
+
var isKeyword = (value, keyword) => {
|
|
2978
|
+
if (value.type === "keyword") {
|
|
2979
|
+
return value.value === keyword;
|
|
2980
|
+
}
|
|
2981
|
+
if (value.type === "layers") {
|
|
2982
|
+
return value.value.some((layer) => isKeyword(layer, keyword));
|
|
2983
|
+
}
|
|
2984
|
+
return false;
|
|
2985
|
+
};
|
|
2690
2986
|
var prefixStyles = (styleMap) => {
|
|
2691
2987
|
const newStyleMap = /* @__PURE__ */ new Map();
|
|
2988
|
+
const backgroundClip = styleMap.get("background-clip");
|
|
2989
|
+
const hasTextBackgroundClip = backgroundClip !== void 0 && isKeyword(backgroundClip, "text");
|
|
2692
2990
|
for (const [property, value] of styleMap) {
|
|
2693
2991
|
if (property === "background-clip") {
|
|
2694
2992
|
newStyleMap.set("-webkit-background-clip", value);
|
|
@@ -2702,6 +3000,9 @@ var prefixStyles = (styleMap) => {
|
|
|
2702
3000
|
if (property === "backdrop-filter") {
|
|
2703
3001
|
newStyleMap.set("-webkit-backdrop-filter", value);
|
|
2704
3002
|
}
|
|
3003
|
+
if (property === "color" && hasTextBackgroundClip && isKeyword(value, "transparent")) {
|
|
3004
|
+
newStyleMap.set("-webkit-text-fill-color", value);
|
|
3005
|
+
}
|
|
2705
3006
|
if (property === "view-timeline-name" || property === "scroll-timeline-name" || property === "view-timeline-inset") {
|
|
2706
3007
|
newStyleMap.set(`--${property}`, value);
|
|
2707
3008
|
}
|
|
@@ -3807,7 +4108,36 @@ var PageTitle = z.string().refine(
|
|
|
3807
4108
|
(val) => val.length >= MIN_TITLE_LENGTH,
|
|
3808
4109
|
`Minimum ${MIN_TITLE_LENGTH} characters required`
|
|
3809
4110
|
);
|
|
3810
|
-
var documentTypes = ["html", "xml"];
|
|
4111
|
+
var documentTypes = ["html", "xml", "text"];
|
|
4112
|
+
var BasicAuthFields = {
|
|
4113
|
+
login: z.string(),
|
|
4114
|
+
password: z.string()
|
|
4115
|
+
};
|
|
4116
|
+
var validateBasicAuthFields = ({
|
|
4117
|
+
login,
|
|
4118
|
+
password
|
|
4119
|
+
}, context) => {
|
|
4120
|
+
for (const issue of validateBasicAuth({ login, password }).issues ?? []) {
|
|
4121
|
+
context.addIssue({
|
|
4122
|
+
code: z.ZodIssueCode.custom,
|
|
4123
|
+
path: issue.path,
|
|
4124
|
+
message: issue.message
|
|
4125
|
+
});
|
|
4126
|
+
}
|
|
4127
|
+
};
|
|
4128
|
+
var PageBasicAuth = z.object({
|
|
4129
|
+
method: z.literal("basic"),
|
|
4130
|
+
...BasicAuthFields
|
|
4131
|
+
}).superRefine(validateBasicAuthFields);
|
|
4132
|
+
var LegacyPageBasicAuth = z.object({
|
|
4133
|
+
type: z.literal("basic"),
|
|
4134
|
+
...BasicAuthFields
|
|
4135
|
+
}).superRefine(validateBasicAuthFields).transform(({ login, password }) => ({
|
|
4136
|
+
method: "basic",
|
|
4137
|
+
login,
|
|
4138
|
+
password
|
|
4139
|
+
}));
|
|
4140
|
+
var PageAuth = z.union([PageBasicAuth, LegacyPageBasicAuth]);
|
|
3811
4141
|
var commonPageFields = {
|
|
3812
4142
|
id: PageId,
|
|
3813
4143
|
name: PageName,
|
|
@@ -3825,6 +4155,8 @@ var commonPageFields = {
|
|
|
3825
4155
|
status: z.string().optional(),
|
|
3826
4156
|
redirect: z.string().optional(),
|
|
3827
4157
|
documentType: z.optional(z.enum(documentTypes)),
|
|
4158
|
+
content: z.string().optional(),
|
|
4159
|
+
auth: PageAuth.optional(),
|
|
3828
4160
|
custom: z.array(
|
|
3829
4161
|
z.object({
|
|
3830
4162
|
property: z.string(),
|
|
@@ -3875,12 +4207,21 @@ var Page = z.object({
|
|
|
3875
4207
|
...commonPageFields,
|
|
3876
4208
|
path: z.union([HomePagePath, PagePath])
|
|
3877
4209
|
});
|
|
4210
|
+
var PageTemplate = z.object({
|
|
4211
|
+
id: PageId,
|
|
4212
|
+
name: PageName,
|
|
4213
|
+
title: PageTitle,
|
|
4214
|
+
rootInstanceId: z.string(),
|
|
4215
|
+
systemDataSourceId: z.string().optional(),
|
|
4216
|
+
meta: commonPageFields.meta
|
|
4217
|
+
});
|
|
3878
4218
|
var ProjectMeta = z.object({
|
|
3879
4219
|
// All fields are optional to ensure consistency and allow for the addition of new fields without requiring migration
|
|
3880
4220
|
siteName: z.string().optional(),
|
|
3881
4221
|
contactEmail: z.string().optional(),
|
|
3882
4222
|
faviconAssetId: z.string().optional(),
|
|
3883
|
-
code: z.string().optional()
|
|
4223
|
+
code: z.string().optional(),
|
|
4224
|
+
auth: z.string().optional()
|
|
3884
4225
|
});
|
|
3885
4226
|
var ProjectNewRedirectPath = z.string().min(1, "Path is required").refine((data) => {
|
|
3886
4227
|
try {
|
|
@@ -3906,6 +4247,7 @@ var Pages = z.object({
|
|
|
3906
4247
|
homePageId: PageId,
|
|
3907
4248
|
rootFolderId: FolderId,
|
|
3908
4249
|
pages: z.map(PageId, Page),
|
|
4250
|
+
pageTemplates: z.map(PageId, PageTemplate).optional(),
|
|
3909
4251
|
folders: z.map(FolderId, Folder).refine((folders) => folders.size > 0, "Folders can't be empty")
|
|
3910
4252
|
}).superRefine((pages, context) => {
|
|
3911
4253
|
const homePage = pages.pages.get(pages.homePageId);
|
|
@@ -3947,6 +4289,22 @@ var Pages = z.object({
|
|
|
3947
4289
|
});
|
|
3948
4290
|
}
|
|
3949
4291
|
}
|
|
4292
|
+
for (const [templateId, template] of pages.pageTemplates ?? []) {
|
|
4293
|
+
if (template.id !== templateId) {
|
|
4294
|
+
context.addIssue({
|
|
4295
|
+
code: z.ZodIssueCode.custom,
|
|
4296
|
+
path: ["pageTemplates", templateId, "id"],
|
|
4297
|
+
message: "Page template id must match its record key"
|
|
4298
|
+
});
|
|
4299
|
+
}
|
|
4300
|
+
if (pages.pages.has(templateId)) {
|
|
4301
|
+
context.addIssue({
|
|
4302
|
+
code: z.ZodIssueCode.custom,
|
|
4303
|
+
path: ["pageTemplates", templateId, "id"],
|
|
4304
|
+
message: "Page template id must not match an existing page id"
|
|
4305
|
+
});
|
|
4306
|
+
}
|
|
4307
|
+
}
|
|
3950
4308
|
for (const [folderId, folder] of pages.folders) {
|
|
3951
4309
|
if (folder.id !== folderId) {
|
|
3952
4310
|
context.addIssue({
|
|
@@ -4590,6 +4948,13 @@ var Select = z.object({
|
|
|
4590
4948
|
defaultValue: z.string().optional(),
|
|
4591
4949
|
options: z.array(z.string())
|
|
4592
4950
|
});
|
|
4951
|
+
var TimeZone = z.object({
|
|
4952
|
+
...common,
|
|
4953
|
+
control: z.literal("timeZone"),
|
|
4954
|
+
type: z.literal("string"),
|
|
4955
|
+
defaultValue: z.string().optional(),
|
|
4956
|
+
options: z.array(z.string())
|
|
4957
|
+
});
|
|
4593
4958
|
var Check = z.object({
|
|
4594
4959
|
...common,
|
|
4595
4960
|
control: z.literal("check"),
|
|
@@ -4670,6 +5035,7 @@ var PropMeta = z.union([
|
|
|
4670
5035
|
Radio,
|
|
4671
5036
|
InlineRadio,
|
|
4672
5037
|
Select,
|
|
5038
|
+
TimeZone,
|
|
4673
5039
|
MultiSelect,
|
|
4674
5040
|
Check,
|
|
4675
5041
|
InlineCheck,
|
|
@@ -4697,6 +5063,7 @@ var componentCategories = [
|
|
|
4697
5063
|
"localization",
|
|
4698
5064
|
"radix",
|
|
4699
5065
|
"xml",
|
|
5066
|
+
"text",
|
|
4700
5067
|
"other",
|
|
4701
5068
|
"hidden",
|
|
4702
5069
|
"internal"
|
|
@@ -5572,6 +5939,29 @@ var parseComponentName = (componentName) => {
|
|
|
5572
5939
|
}
|
|
5573
5940
|
return [namespace, name2];
|
|
5574
5941
|
};
|
|
5942
|
+
var getHtmlTagsFromProps = (props) => {
|
|
5943
|
+
const tags2 = /* @__PURE__ */ new Map();
|
|
5944
|
+
for (const prop of props.values()) {
|
|
5945
|
+
if (prop.type === "string" && prop.name === "tag") {
|
|
5946
|
+
tags2.set(prop.instanceId, prop.value);
|
|
5947
|
+
}
|
|
5948
|
+
}
|
|
5949
|
+
return tags2;
|
|
5950
|
+
};
|
|
5951
|
+
var getHtmlTagFromInstance = ({
|
|
5952
|
+
instance: instance2,
|
|
5953
|
+
metas,
|
|
5954
|
+
props,
|
|
5955
|
+
htmlTagsByInstanceId
|
|
5956
|
+
}) => {
|
|
5957
|
+
if (instance2.component === "XmlNode") {
|
|
5958
|
+
return;
|
|
5959
|
+
}
|
|
5960
|
+
const meta = metas.get(instance2.component);
|
|
5961
|
+
const metaTag = Object.keys((meta == null ? void 0 : meta.presetStyle) ?? {}).at(0);
|
|
5962
|
+
const propTag = (htmlTagsByInstanceId == null ? void 0 : htmlTagsByInstanceId.get(instance2.id)) ?? getHtmlTagsFromProps(props).get(instance2.id);
|
|
5963
|
+
return instance2.tag ?? propTag ?? metaTag;
|
|
5964
|
+
};
|
|
5575
5965
|
var getIndexesWithinAncestors = (metas, instances, rootIds) => {
|
|
5576
5966
|
const ancestors = /* @__PURE__ */ new Set();
|
|
5577
5967
|
for (const meta of metas.values()) {
|
|
@@ -5624,6 +6014,49 @@ var systemParameter = {
|
|
|
5624
6014
|
type: "parameter",
|
|
5625
6015
|
name: "system"
|
|
5626
6016
|
};
|
|
6017
|
+
var walkAssignmentTarget = (node, visitor) => {
|
|
6018
|
+
var _a2, _b2, _c2, _d2;
|
|
6019
|
+
if (node.type === "Identifier") {
|
|
6020
|
+
(_a2 = visitor.Identifier) == null ? void 0 : _a2.call(visitor, node, "binding");
|
|
6021
|
+
return;
|
|
6022
|
+
}
|
|
6023
|
+
if (node.type === "MemberExpression") {
|
|
6024
|
+
(_b2 = visitor.MemberExpression) == null ? void 0 : _b2.call(visitor, node);
|
|
6025
|
+
const { object } = node;
|
|
6026
|
+
if (object.type === "Identifier") {
|
|
6027
|
+
(_c2 = visitor.Identifier) == null ? void 0 : _c2.call(visitor, object, "memberObject");
|
|
6028
|
+
} else if (object.type === "MemberExpression") {
|
|
6029
|
+
walkAssignmentTarget(object, visitor);
|
|
6030
|
+
}
|
|
6031
|
+
return;
|
|
6032
|
+
}
|
|
6033
|
+
(_d2 = visitor.UnsupportedPattern) == null ? void 0 : _d2.call(visitor, node);
|
|
6034
|
+
};
|
|
6035
|
+
var stringMethodReturnKindByName = /* @__PURE__ */ new Map([
|
|
6036
|
+
["toLowerCase", "string"],
|
|
6037
|
+
["replace", "string"],
|
|
6038
|
+
["split", "array"],
|
|
6039
|
+
["slice", "string"],
|
|
6040
|
+
["at", "unknown"],
|
|
6041
|
+
["endsWith", "boolean"],
|
|
6042
|
+
["includes", "boolean"],
|
|
6043
|
+
["startsWith", "boolean"],
|
|
6044
|
+
["toString", "string"],
|
|
6045
|
+
["toUpperCase", "string"],
|
|
6046
|
+
["toLocaleLowerCase", "string"],
|
|
6047
|
+
["toLocaleUpperCase", "string"]
|
|
6048
|
+
]);
|
|
6049
|
+
var arrayMethodReturnKindByName = /* @__PURE__ */ new Map([
|
|
6050
|
+
["at", "unknown"],
|
|
6051
|
+
["includes", "boolean"],
|
|
6052
|
+
["join", "string"],
|
|
6053
|
+
["slice", "array"],
|
|
6054
|
+
["toString", "string"]
|
|
6055
|
+
]);
|
|
6056
|
+
new Set(
|
|
6057
|
+
stringMethodReturnKindByName.keys()
|
|
6058
|
+
);
|
|
6059
|
+
new Set(arrayMethodReturnKindByName.keys());
|
|
5627
6060
|
var transpileExpression = ({
|
|
5628
6061
|
expression,
|
|
5629
6062
|
executable = false,
|
|
@@ -5636,17 +6069,44 @@ var transpileExpression = ({
|
|
|
5636
6069
|
const message = error.message;
|
|
5637
6070
|
throw Error(`${message} in ${JSON.stringify(expression)}`);
|
|
5638
6071
|
}
|
|
6072
|
+
const assignmentTargetMemberRanges = [];
|
|
6073
|
+
if (executable) {
|
|
6074
|
+
simple(root, {
|
|
6075
|
+
AssignmentExpression(node) {
|
|
6076
|
+
walkAssignmentTarget(node.left, {
|
|
6077
|
+
MemberExpression(node2) {
|
|
6078
|
+
assignmentTargetMemberRanges.push([node2.start, node2.end]);
|
|
6079
|
+
}
|
|
6080
|
+
});
|
|
6081
|
+
}
|
|
6082
|
+
});
|
|
6083
|
+
}
|
|
5639
6084
|
const replacements = [];
|
|
6085
|
+
const replacementIndexByRange = /* @__PURE__ */ new Map();
|
|
6086
|
+
const addReplacement = (start, end, fragment, { replaceExisting = false } = {}) => {
|
|
6087
|
+
const range = `${start}:${end}`;
|
|
6088
|
+
const existingIndex = replacementIndexByRange.get(range);
|
|
6089
|
+
if (existingIndex !== void 0) {
|
|
6090
|
+
if (replaceExisting) {
|
|
6091
|
+
replacements[existingIndex] = [start, end, fragment];
|
|
6092
|
+
}
|
|
6093
|
+
return;
|
|
6094
|
+
}
|
|
6095
|
+
replacementIndexByRange.set(range, replacements.length);
|
|
6096
|
+
replacements.push([start, end, fragment]);
|
|
6097
|
+
};
|
|
5640
6098
|
const replaceIdentifier = (node, assignee) => {
|
|
5641
6099
|
const newName = replaceVariable == null ? void 0 : replaceVariable(node.name, assignee);
|
|
5642
6100
|
if (newName) {
|
|
5643
|
-
|
|
6101
|
+
addReplacement(node.start, node.end, newName, {
|
|
6102
|
+
replaceExisting: assignee
|
|
6103
|
+
});
|
|
5644
6104
|
}
|
|
5645
6105
|
};
|
|
5646
6106
|
simple(root, {
|
|
5647
6107
|
Identifier: (node) => replaceIdentifier(node, false),
|
|
5648
6108
|
AssignmentExpression(node) {
|
|
5649
|
-
|
|
6109
|
+
walkAssignmentTarget(node.left, {
|
|
5650
6110
|
Identifier: (node2) => replaceIdentifier(node2, true)
|
|
5651
6111
|
});
|
|
5652
6112
|
},
|
|
@@ -5654,13 +6114,18 @@ var transpileExpression = ({
|
|
|
5654
6114
|
if (executable === false || node.optional) {
|
|
5655
6115
|
return;
|
|
5656
6116
|
}
|
|
6117
|
+
if (assignmentTargetMemberRanges.some(
|
|
6118
|
+
([start, end]) => start === node.start && end === node.end
|
|
6119
|
+
)) {
|
|
6120
|
+
return;
|
|
6121
|
+
}
|
|
5657
6122
|
if (node.computed === false) {
|
|
5658
6123
|
const dotIndex = expression.indexOf(".", node.object.end);
|
|
5659
|
-
|
|
6124
|
+
addReplacement(dotIndex, dotIndex, "?");
|
|
5660
6125
|
}
|
|
5661
6126
|
if (node.computed === true) {
|
|
5662
6127
|
const dotIndex = expression.indexOf("[", node.object.end);
|
|
5663
|
-
|
|
6128
|
+
addReplacement(dotIndex, dotIndex, "?.");
|
|
5664
6129
|
}
|
|
5665
6130
|
},
|
|
5666
6131
|
CallExpression(node) {
|
|
@@ -5670,7 +6135,7 @@ var transpileExpression = ({
|
|
|
5670
6135
|
if (node.callee.type === "MemberExpression") {
|
|
5671
6136
|
const openParenIndex = expression.indexOf("(", node.callee.end);
|
|
5672
6137
|
if (openParenIndex !== -1) {
|
|
5673
|
-
|
|
6138
|
+
addReplacement(openParenIndex, openParenIndex, "?.");
|
|
5674
6139
|
}
|
|
5675
6140
|
}
|
|
5676
6141
|
}
|
|
@@ -5744,14 +6209,21 @@ var getHomePage = (pages) => {
|
|
|
5744
6209
|
}
|
|
5745
6210
|
return homePage;
|
|
5746
6211
|
};
|
|
5747
|
-
|
|
6212
|
+
function findPageByIdOrPath(idOrPath, pages, options = {}) {
|
|
6213
|
+
var _a2;
|
|
5748
6214
|
if (idOrPath === "" || idOrPath === "/" || idOrPath === pages.homePageId) {
|
|
5749
6215
|
return getHomePage(pages);
|
|
5750
6216
|
}
|
|
5751
|
-
|
|
6217
|
+
const found = getAllPages(pages).find(
|
|
5752
6218
|
(page) => page.id === idOrPath || getPagePath(page.id, pages) === idOrPath
|
|
5753
6219
|
);
|
|
5754
|
-
|
|
6220
|
+
if (found) {
|
|
6221
|
+
return found;
|
|
6222
|
+
}
|
|
6223
|
+
if (options.includeTemplates) {
|
|
6224
|
+
return (_a2 = pages.pageTemplates) == null ? void 0 : _a2.get(idOrPath);
|
|
6225
|
+
}
|
|
6226
|
+
}
|
|
5755
6227
|
var getPagePath = (id, pages) => {
|
|
5756
6228
|
const foldersMap = /* @__PURE__ */ new Map();
|
|
5757
6229
|
const childParentMap = /* @__PURE__ */ new Map();
|
|
@@ -6063,6 +6535,12 @@ var generatePageMeta = ({
|
|
|
6063
6535
|
usedDataSources,
|
|
6064
6536
|
scope: localScope
|
|
6065
6537
|
});
|
|
6538
|
+
const contentExpression = generateExpression({
|
|
6539
|
+
expression: page.meta.content ?? "undefined",
|
|
6540
|
+
dataSources,
|
|
6541
|
+
usedDataSources,
|
|
6542
|
+
scope: localScope
|
|
6543
|
+
});
|
|
6066
6544
|
let customExpression = "";
|
|
6067
6545
|
customExpression += `[
|
|
6068
6546
|
`;
|
|
@@ -6071,7 +6549,7 @@ var generatePageMeta = ({
|
|
|
6071
6549
|
continue;
|
|
6072
6550
|
}
|
|
6073
6551
|
const propertyExpression = JSON.stringify(customMeta.property);
|
|
6074
|
-
const
|
|
6552
|
+
const contentExpression2 = generateExpression({
|
|
6075
6553
|
expression: customMeta.content,
|
|
6076
6554
|
dataSources,
|
|
6077
6555
|
usedDataSources,
|
|
@@ -6081,7 +6559,7 @@ var generatePageMeta = ({
|
|
|
6081
6559
|
`;
|
|
6082
6560
|
customExpression += ` property: ${propertyExpression},
|
|
6083
6561
|
`;
|
|
6084
|
-
customExpression += ` content: ${
|
|
6562
|
+
customExpression += ` content: ${contentExpression2},
|
|
6085
6563
|
`;
|
|
6086
6564
|
customExpression += ` },
|
|
6087
6565
|
`;
|
|
@@ -6146,6 +6624,8 @@ var generatePageMeta = ({
|
|
|
6146
6624
|
generated += ` status: ${statusExpression},
|
|
6147
6625
|
`;
|
|
6148
6626
|
generated += ` redirect: ${redirectExpression},
|
|
6627
|
+
`;
|
|
6628
|
+
generated += ` content: ${contentExpression},
|
|
6149
6629
|
`;
|
|
6150
6630
|
generated += ` custom: ${customExpression},
|
|
6151
6631
|
`;
|
|
@@ -6209,22 +6689,19 @@ var generateCss = ({
|
|
|
6209
6689
|
const scope = createScope([], normalizeClassName, "-");
|
|
6210
6690
|
const tagsByComponent = /* @__PURE__ */ new Map();
|
|
6211
6691
|
tagsByComponent.set(rootComponent, /* @__PURE__ */ new Set(["html"]));
|
|
6212
|
-
const
|
|
6213
|
-
for (const prop of props.values()) {
|
|
6214
|
-
if (prop.type === "string" && prop.name === "tag") {
|
|
6215
|
-
tagByInstanceId.set(prop.instanceId, prop.value);
|
|
6216
|
-
}
|
|
6217
|
-
}
|
|
6692
|
+
const htmlTagsByInstanceId = getHtmlTagsFromProps(props);
|
|
6218
6693
|
for (const instance2 of instances.values()) {
|
|
6219
|
-
const propTag = tagByInstanceId.get(instance2.id);
|
|
6220
|
-
const meta = componentMetas.get(instance2.component);
|
|
6221
|
-
const metaTag = Object.keys((meta == null ? void 0 : meta.presetStyle) ?? {}).at(0);
|
|
6222
6694
|
let componentTags = tagsByComponent.get(instance2.component);
|
|
6223
6695
|
if (componentTags === void 0) {
|
|
6224
6696
|
componentTags = /* @__PURE__ */ new Set();
|
|
6225
6697
|
tagsByComponent.set(instance2.component, componentTags);
|
|
6226
6698
|
}
|
|
6227
|
-
const tag =
|
|
6699
|
+
const tag = getHtmlTagFromInstance({
|
|
6700
|
+
instance: instance2,
|
|
6701
|
+
metas: componentMetas,
|
|
6702
|
+
props,
|
|
6703
|
+
htmlTagsByInstanceId
|
|
6704
|
+
});
|
|
6228
6705
|
if (tag) {
|
|
6229
6706
|
componentTags.add(tag);
|
|
6230
6707
|
}
|
|
@@ -6926,7 +7403,7 @@ var generateJsxChildren = ({
|
|
|
6926
7403
|
usedDataSources,
|
|
6927
7404
|
scope
|
|
6928
7405
|
});
|
|
6929
|
-
generatedChildren = `{${expression}}
|
|
7406
|
+
generatedChildren = `{renderText(${expression})}
|
|
6930
7407
|
`;
|
|
6931
7408
|
continue;
|
|
6932
7409
|
}
|
|
@@ -7107,11 +7584,12 @@ var migratePages = (pages) => {
|
|
|
7107
7584
|
if (isSerializedPages(pages) && pages.pages instanceof Map && pages.folders instanceof Map) {
|
|
7108
7585
|
const currentPages = pages;
|
|
7109
7586
|
const result = Pages.safeParse(currentPages);
|
|
7110
|
-
if (result.success) {
|
|
7587
|
+
if (result.success && currentPages.pageTemplates !== void 0) {
|
|
7111
7588
|
return currentPages;
|
|
7112
7589
|
}
|
|
7113
7590
|
return {
|
|
7114
7591
|
...currentPages,
|
|
7592
|
+
pageTemplates: currentPages.pageTemplates ?? /* @__PURE__ */ new Map(),
|
|
7115
7593
|
folders: removeOrphanFolderChildren(
|
|
7116
7594
|
currentPages.pages,
|
|
7117
7595
|
currentPages.folders
|
|
@@ -7128,6 +7606,7 @@ var migratePages = (pages) => {
|
|
|
7128
7606
|
homePageId: pages.homePageId,
|
|
7129
7607
|
rootFolderId: pages.rootFolderId,
|
|
7130
7608
|
pages: nextPages2,
|
|
7609
|
+
pageTemplates: pages.pageTemplates === void 0 ? /* @__PURE__ */ new Map() : toMap(pages.pageTemplates),
|
|
7131
7610
|
folders: removeOrphanFolderChildren(nextPages2, nextFolders2)
|
|
7132
7611
|
};
|
|
7133
7612
|
}
|
|
@@ -7184,6 +7663,7 @@ var migratePages = (pages) => {
|
|
|
7184
7663
|
homePageId: homePage.id,
|
|
7185
7664
|
rootFolderId: rootFolder.id,
|
|
7186
7665
|
pages: nextPages,
|
|
7666
|
+
pageTemplates: /* @__PURE__ */ new Map(),
|
|
7187
7667
|
folders: nextFolders
|
|
7188
7668
|
};
|
|
7189
7669
|
};
|
|
@@ -7645,7 +8125,7 @@ const g$3 = {
|
|
|
7645
8125
|
const t$f = {
|
|
7646
8126
|
tag: { required: false, control: "text", type: "string" }
|
|
7647
8127
|
};
|
|
7648
|
-
const n$
|
|
8128
|
+
const n$7 = {
|
|
7649
8129
|
icon: TextIcon,
|
|
7650
8130
|
presetStyle: {
|
|
7651
8131
|
div: [
|
|
@@ -7841,14 +8321,14 @@ const c$4 = {
|
|
|
7841
8321
|
}
|
|
7842
8322
|
};
|
|
7843
8323
|
const o$v = {};
|
|
7844
|
-
const r$
|
|
8324
|
+
const r$c = {
|
|
7845
8325
|
form: [
|
|
7846
8326
|
...form,
|
|
7847
8327
|
{ property: "min-height", value: { type: "unit", unit: "px", value: 20 } }
|
|
7848
8328
|
]
|
|
7849
8329
|
}, p$4 = {
|
|
7850
8330
|
label: "Form",
|
|
7851
|
-
presetStyle: r$
|
|
8331
|
+
presetStyle: r$c,
|
|
7852
8332
|
initialProps: ["id", "class", "action"],
|
|
7853
8333
|
props: o$v
|
|
7854
8334
|
};
|
|
@@ -7862,7 +8342,7 @@ const e$o = {
|
|
|
7862
8342
|
},
|
|
7863
8343
|
quality: { required: false, control: "number", type: "number" }
|
|
7864
8344
|
};
|
|
7865
|
-
const r$
|
|
8345
|
+
const r$b = {
|
|
7866
8346
|
img: [
|
|
7867
8347
|
...img,
|
|
7868
8348
|
// Otherwise on new image insert onto canvas it can overfit screen size multiple times
|
|
@@ -7887,7 +8367,7 @@ const r$c = {
|
|
|
7887
8367
|
}, i$7 = {
|
|
7888
8368
|
category: "media",
|
|
7889
8369
|
description: "Add an image asset to the page. Webstudio automatically converts images to WebP or AVIF format and makes them responsive for best performance.",
|
|
7890
|
-
presetStyle: r$
|
|
8370
|
+
presetStyle: r$b,
|
|
7891
8371
|
order: 0,
|
|
7892
8372
|
initialProps: [
|
|
7893
8373
|
"id",
|
|
@@ -7978,7 +8458,7 @@ const e$n = {
|
|
|
7978
8458
|
value: { type: "rgb", r: 226, g: 226, b: 226, alpha: 1 }
|
|
7979
8459
|
}
|
|
7980
8460
|
]
|
|
7981
|
-
}, r$
|
|
8461
|
+
}, r$a = {
|
|
7982
8462
|
presetStyle: e$n,
|
|
7983
8463
|
initialProps: ["id", "class", "cite"],
|
|
7984
8464
|
props: o$u
|
|
@@ -8165,7 +8645,7 @@ const e$k = {
|
|
|
8165
8645
|
description: "Value of the form control"
|
|
8166
8646
|
}
|
|
8167
8647
|
};
|
|
8168
|
-
const r$
|
|
8648
|
+
const r$9 = {
|
|
8169
8649
|
input: [
|
|
8170
8650
|
...radio,
|
|
8171
8651
|
{
|
|
@@ -8176,7 +8656,7 @@ const r$a = {
|
|
|
8176
8656
|
}, m$7 = {
|
|
8177
8657
|
label: "Radio",
|
|
8178
8658
|
icon: RadioCheckedIcon,
|
|
8179
|
-
presetStyle: r$
|
|
8659
|
+
presetStyle: r$9,
|
|
8180
8660
|
initialProps: ["id", "class", "name", "value", "required", "checked"],
|
|
8181
8661
|
props: e$k
|
|
8182
8662
|
};
|
|
@@ -8940,15 +9420,22 @@ const e$d = {
|
|
|
8940
9420
|
defaultValue: "medium",
|
|
8941
9421
|
options: ["full", "long", "medium", "short", "none"]
|
|
8942
9422
|
},
|
|
9423
|
+
datetime: {
|
|
9424
|
+
required: false,
|
|
9425
|
+
control: "text",
|
|
9426
|
+
type: "string",
|
|
9427
|
+
defaultValue: "dateTime attribute is not set",
|
|
9428
|
+
description: "Machine-readable value"
|
|
9429
|
+
},
|
|
8943
9430
|
format: {
|
|
8944
9431
|
description: `Custom format template. Overrides Date Style and Time Style.
|
|
8945
9432
|
|
|
8946
9433
|
Tokens: YYYY/YY (year), MMMM/MMM/MM/M (month), DDDD/DDD/DD/D (day), HH/H (hours), mm/m (minutes), ss/s (seconds)
|
|
8947
9434
|
|
|
8948
9435
|
Examples:
|
|
8949
|
-
"YYYY-MM-DD" → 2025-11-03
|
|
8950
|
-
"DDDD, MMMM D" → Monday, November 3
|
|
8951
|
-
"DDD, D. MMM YYYY" → Mon, 3. Nov 2025
|
|
9436
|
+
- "YYYY-MM-DD" → 2025-11-03
|
|
9437
|
+
- "DDDD, MMMM D" → Monday, November 3
|
|
9438
|
+
- "DDD, D. MMM YYYY" → Mon, 3. Nov 2025
|
|
8952
9439
|
|
|
8953
9440
|
Day and month names use the selected language.`,
|
|
8954
9441
|
required: false,
|
|
@@ -9040,9 +9527,19 @@ Day and month names use the selected language.`,
|
|
|
9040
9527
|
type: "string",
|
|
9041
9528
|
defaultValue: "none",
|
|
9042
9529
|
options: ["full", "long", "medium", "short", "none"]
|
|
9530
|
+
},
|
|
9531
|
+
timeZone: {
|
|
9532
|
+
description: `Time zone used to format the date.
|
|
9533
|
+
|
|
9534
|
+
Use "UTC" for deterministic UTC output, "visitor" to use the browser time
|
|
9535
|
+
zone after hydration, or an IANA time zone like "Europe/Berlin".`,
|
|
9536
|
+
required: false,
|
|
9537
|
+
control: "text",
|
|
9538
|
+
type: "string",
|
|
9539
|
+
defaultValue: "UTC"
|
|
9043
9540
|
}
|
|
9044
9541
|
};
|
|
9045
|
-
const
|
|
9542
|
+
const n$6 = {
|
|
9046
9543
|
category: "localization",
|
|
9047
9544
|
description: "Converts machine-readable date and time to a human-readable format.",
|
|
9048
9545
|
contentModel: {
|
|
@@ -9058,6 +9555,7 @@ const r$9 = {
|
|
|
9058
9555
|
"country",
|
|
9059
9556
|
"dateStyle",
|
|
9060
9557
|
"timeStyle",
|
|
9558
|
+
"timeZone",
|
|
9061
9559
|
"format"
|
|
9062
9560
|
],
|
|
9063
9561
|
props: {
|
|
@@ -9084,6 +9582,15 @@ const r$9 = {
|
|
|
9084
9582
|
...e$d.timeStyle,
|
|
9085
9583
|
contentMode: true
|
|
9086
9584
|
},
|
|
9585
|
+
timeZone: {
|
|
9586
|
+
required: false,
|
|
9587
|
+
control: "timeZone",
|
|
9588
|
+
type: "string",
|
|
9589
|
+
defaultValue: "UTC",
|
|
9590
|
+
options: ["UTC", "visitor"],
|
|
9591
|
+
description: 'Timezone used to display the date. Use "visitor" to display each visitor’s browser timezone after the page loads, or select/type an IANA timezone like "Europe/Berlin".',
|
|
9592
|
+
contentMode: true
|
|
9593
|
+
},
|
|
9087
9594
|
format: {
|
|
9088
9595
|
...e$d.format,
|
|
9089
9596
|
contentMode: true
|
|
@@ -9238,7 +9745,7 @@ const n$5 = {
|
|
|
9238
9745
|
};
|
|
9239
9746
|
const baseComponentMetas = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
9240
9747
|
__proto__: null,
|
|
9241
|
-
Blockquote: r$
|
|
9748
|
+
Blockquote: r$a,
|
|
9242
9749
|
Body: i$9,
|
|
9243
9750
|
Bold: p$6,
|
|
9244
9751
|
Box: g$3,
|
|
@@ -9272,9 +9779,9 @@ const baseComponentMetas = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
|
|
|
9272
9779
|
Span: e$s,
|
|
9273
9780
|
Subscript: s$3,
|
|
9274
9781
|
Superscript: o$z,
|
|
9275
|
-
Text: n$
|
|
9782
|
+
Text: n$7,
|
|
9276
9783
|
Textarea: l$4,
|
|
9277
|
-
Time:
|
|
9784
|
+
Time: n$6,
|
|
9278
9785
|
Video: n$5,
|
|
9279
9786
|
Vimeo: s$2,
|
|
9280
9787
|
VimeoPlayButton: c$2,
|
|
@@ -9879,7 +10386,15 @@ const e$5 = {
|
|
|
9879
10386
|
type: "string",
|
|
9880
10387
|
description: "Current value of the element"
|
|
9881
10388
|
}
|
|
9882
|
-
}, t$2 = {},
|
|
10389
|
+
}, t$2 = {}, n$2 = {}, r$3 = {
|
|
10390
|
+
forceMount: {
|
|
10391
|
+
description: "Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries or keeping content available in the DOM.",
|
|
10392
|
+
required: false,
|
|
10393
|
+
control: "boolean",
|
|
10394
|
+
type: "boolean",
|
|
10395
|
+
defaultValue: true
|
|
10396
|
+
}
|
|
10397
|
+
};
|
|
9883
10398
|
const C$1 = {
|
|
9884
10399
|
icon: AccordionIcon,
|
|
9885
10400
|
contentModel: {
|
|
@@ -9946,7 +10461,7 @@ const C$1 = {
|
|
|
9946
10461
|
presetStyle: {
|
|
9947
10462
|
button: [button, b$2].flat()
|
|
9948
10463
|
},
|
|
9949
|
-
props:
|
|
10464
|
+
props: n$2
|
|
9950
10465
|
}, H = {
|
|
9951
10466
|
label: "Item Content",
|
|
9952
10467
|
icon: ContentIcon,
|
|
@@ -9961,7 +10476,7 @@ const C$1 = {
|
|
|
9961
10476
|
presetStyle: {
|
|
9962
10477
|
div
|
|
9963
10478
|
},
|
|
9964
|
-
props:
|
|
10479
|
+
props: r$3
|
|
9965
10480
|
};
|
|
9966
10481
|
const e$4 = {
|
|
9967
10482
|
defaultValue: { required: false, control: "text", type: "string" },
|
|
@@ -10547,6 +11062,10 @@ const createFramework$2 = async () => {
|
|
|
10547
11062
|
join(routeTemplatesDir, "xml.tsx"),
|
|
10548
11063
|
"utf8"
|
|
10549
11064
|
);
|
|
11065
|
+
const textTemplate = await readFile(
|
|
11066
|
+
join(routeTemplatesDir, "text.tsx"),
|
|
11067
|
+
"utf8"
|
|
11068
|
+
);
|
|
10550
11069
|
const defaultSitemapTemplate = await readFile(
|
|
10551
11070
|
join(routeTemplatesDir, "default-sitemap.tsx"),
|
|
10552
11071
|
"utf8"
|
|
@@ -10556,7 +11075,7 @@ const createFramework$2 = async () => {
|
|
|
10556
11075
|
"utf8"
|
|
10557
11076
|
);
|
|
10558
11077
|
await rm(routeTemplatesDir, { recursive: true, force: true });
|
|
10559
|
-
const base = "@webstudio-is/sdk-components-react";
|
|
11078
|
+
const base = "@webstudio-is/sdk-components-react/components";
|
|
10560
11079
|
const remix = "@webstudio-is/sdk-components-react-remix";
|
|
10561
11080
|
const reactRadix = "@webstudio-is/sdk-components-react-radix";
|
|
10562
11081
|
const animation = "@webstudio-is/sdk-components-animation";
|
|
@@ -10600,6 +11119,12 @@ const createFramework$2 = async () => {
|
|
|
10600
11119
|
template: xmlTemplate
|
|
10601
11120
|
}
|
|
10602
11121
|
],
|
|
11122
|
+
text: ({ pagePath }) => [
|
|
11123
|
+
{
|
|
11124
|
+
file: join("app", "routes", `${generateRemixRoute(pagePath)}.tsx`),
|
|
11125
|
+
template: textTemplate
|
|
11126
|
+
}
|
|
11127
|
+
],
|
|
10603
11128
|
redirect: ({ pagePath }) => [
|
|
10604
11129
|
{
|
|
10605
11130
|
file: join("app", "routes", `${generateRemixRoute(pagePath)}.ts`),
|
|
@@ -10628,6 +11153,10 @@ const createFramework$1 = async () => {
|
|
|
10628
11153
|
join(routeTemplatesDir, "xml.tsx"),
|
|
10629
11154
|
"utf8"
|
|
10630
11155
|
);
|
|
11156
|
+
const textTemplate = await readFile(
|
|
11157
|
+
join(routeTemplatesDir, "text.tsx"),
|
|
11158
|
+
"utf8"
|
|
11159
|
+
);
|
|
10631
11160
|
const defaultSitemapTemplate = await readFile(
|
|
10632
11161
|
join(routeTemplatesDir, "default-sitemap.tsx"),
|
|
10633
11162
|
"utf8"
|
|
@@ -10637,7 +11166,7 @@ const createFramework$1 = async () => {
|
|
|
10637
11166
|
"utf8"
|
|
10638
11167
|
);
|
|
10639
11168
|
await rm(routeTemplatesDir, { recursive: true, force: true });
|
|
10640
|
-
const base = "@webstudio-is/sdk-components-react";
|
|
11169
|
+
const base = "@webstudio-is/sdk-components-react/components";
|
|
10641
11170
|
const reactRouter = "@webstudio-is/sdk-components-react-router";
|
|
10642
11171
|
const reactRadix = "@webstudio-is/sdk-components-react-radix";
|
|
10643
11172
|
const animation = "@webstudio-is/sdk-components-animation";
|
|
@@ -10681,6 +11210,12 @@ const createFramework$1 = async () => {
|
|
|
10681
11210
|
template: xmlTemplate
|
|
10682
11211
|
}
|
|
10683
11212
|
],
|
|
11213
|
+
text: ({ pagePath }) => [
|
|
11214
|
+
{
|
|
11215
|
+
file: join("app", "routes", `${generateRemixRoute(pagePath)}.tsx`),
|
|
11216
|
+
template: textTemplate
|
|
11217
|
+
}
|
|
11218
|
+
],
|
|
10684
11219
|
redirect: ({ pagePath }) => [
|
|
10685
11220
|
{
|
|
10686
11221
|
file: join("app", "routes", `${generateRemixRoute(pagePath)}.ts`),
|
|
@@ -10720,7 +11255,7 @@ const createFramework = async () => {
|
|
|
10720
11255
|
"utf8"
|
|
10721
11256
|
);
|
|
10722
11257
|
await rm(routeTemplatesDir, { recursive: true, force: true });
|
|
10723
|
-
const base = "@webstudio-is/sdk-components-react";
|
|
11258
|
+
const base = "@webstudio-is/sdk-components-react/components";
|
|
10724
11259
|
const reactRadix = "@webstudio-is/sdk-components-react-radix";
|
|
10725
11260
|
const animation = "@webstudio-is/sdk-components-animation";
|
|
10726
11261
|
const components = {};
|
|
@@ -10743,7 +11278,8 @@ const createFramework = async () => {
|
|
|
10743
11278
|
tags: {
|
|
10744
11279
|
textarea: `${base}:Textarea`,
|
|
10745
11280
|
input: `${base}:Input`,
|
|
10746
|
-
select: `${base}:Select
|
|
11281
|
+
select: `${base}:Select`,
|
|
11282
|
+
a: `${base}:Link`
|
|
10747
11283
|
},
|
|
10748
11284
|
html: ({ pagePath }) => {
|
|
10749
11285
|
if (isPathnamePattern(pagePath)) {
|
|
@@ -10765,11 +11301,13 @@ const createFramework = async () => {
|
|
|
10765
11301
|
];
|
|
10766
11302
|
},
|
|
10767
11303
|
xml: () => [],
|
|
11304
|
+
text: () => [],
|
|
10768
11305
|
redirect: () => [],
|
|
10769
11306
|
defaultSitemap: () => []
|
|
10770
11307
|
};
|
|
10771
11308
|
};
|
|
10772
11309
|
const limit = pLimit(10);
|
|
11310
|
+
const wsAuthFile = ".webstudio/auth.json";
|
|
10773
11311
|
const downloadAsset = async (url, name2, assetBaseUrl) => {
|
|
10774
11312
|
const assetPath = join("public", assetBaseUrl, name2);
|
|
10775
11313
|
const tempAssetPath = `${assetPath}.tmp`;
|
|
@@ -10813,6 +11351,40 @@ const mergeJsonInto = async (sourcePath, destinationPath) => {
|
|
|
10813
11351
|
);
|
|
10814
11352
|
await writeFile(destinationPath, content, "utf8");
|
|
10815
11353
|
};
|
|
11354
|
+
const writeWsAuthResources = async (generatedDir, pages) => {
|
|
11355
|
+
var _a2, _b2, _c2, _d2;
|
|
11356
|
+
console.info("[wsauth] prebuild create auth config", {
|
|
11357
|
+
file: wsAuthFile,
|
|
11358
|
+
projectAuthContentLength: ((_b2 = (_a2 = pages.meta) == null ? void 0 : _a2.auth) == null ? void 0 : _b2.length) ?? 0,
|
|
11359
|
+
projectAuthContent: (_c2 = pages.meta) == null ? void 0 : _c2.auth,
|
|
11360
|
+
pages: getAllPages(pages).map((page) => ({
|
|
11361
|
+
id: page.id,
|
|
11362
|
+
name: page.name,
|
|
11363
|
+
route: getPagePath(page.id, pages),
|
|
11364
|
+
auth: page.meta.auth
|
|
11365
|
+
}))
|
|
11366
|
+
});
|
|
11367
|
+
const { content, module } = createWsAuthResources({
|
|
11368
|
+
projectContent: (_d2 = pages.meta) == null ? void 0 : _d2.auth,
|
|
11369
|
+
pages: getAllPages(pages).map((page) => ({
|
|
11370
|
+
route: getPagePath(page.id, pages),
|
|
11371
|
+
auth: page.meta.auth
|
|
11372
|
+
}))
|
|
11373
|
+
});
|
|
11374
|
+
console.info("[wsauth] prebuild write auth config", {
|
|
11375
|
+
file: wsAuthFile,
|
|
11376
|
+
contentLength: content.length,
|
|
11377
|
+
content,
|
|
11378
|
+
generatedModulePath: join(generatedDir, "$resources.wsauth.server.ts"),
|
|
11379
|
+
generatedModule: module
|
|
11380
|
+
});
|
|
11381
|
+
await createFolderIfNotExists(dirname(wsAuthFile));
|
|
11382
|
+
await writeFile(wsAuthFile, content);
|
|
11383
|
+
await createFileIfNotExists(
|
|
11384
|
+
join(generatedDir, "$resources.wsauth.server.ts"),
|
|
11385
|
+
module
|
|
11386
|
+
);
|
|
11387
|
+
};
|
|
10816
11388
|
const isCliTemplate = async (template) => {
|
|
10817
11389
|
const currentPath = fileURLToPath(new URL(import.meta.url));
|
|
10818
11390
|
const templatesPath = normalize(
|
|
@@ -10913,6 +11485,7 @@ Please check webstudio --help for more details`
|
|
|
10913
11485
|
);
|
|
10914
11486
|
const pages = migratePages(siteData.build.pages);
|
|
10915
11487
|
const allPages = getAllPages(pages);
|
|
11488
|
+
await writeWsAuthResources(generatedDir, pages);
|
|
10916
11489
|
const siteDataByPage = {};
|
|
10917
11490
|
const fontAssetsByPage = {};
|
|
10918
11491
|
const backgroundImageAssetsByPage = {};
|
|
@@ -11144,11 +11717,13 @@ Please check webstudio --help for more details`
|
|
|
11144
11717
|
|
|
11145
11718
|
|
|
11146
11719
|
import { Fragment, useState } from "react";
|
|
11147
|
-
import { useResource, useVariableState } from "@webstudio-is/react-sdk/runtime";
|
|
11720
|
+
import { renderText, useResource, useVariableState } from "@webstudio-is/react-sdk/runtime";
|
|
11148
11721
|
${importsString}
|
|
11149
11722
|
|
|
11150
11723
|
export const projectId = "${siteData.build.projectId}";
|
|
11151
11724
|
|
|
11725
|
+
export const projectDomain = ${JSON.stringify(siteData.projectDomain)};
|
|
11726
|
+
|
|
11152
11727
|
export const lastPublished = "${new Date(siteData.build.createdAt).toISOString()}";
|
|
11153
11728
|
|
|
11154
11729
|
export const siteName = ${JSON.stringify(projectMeta == null ? void 0 : projectMeta.siteName)};
|
|
@@ -11221,7 +11796,7 @@ Please check webstudio --help for more details`
|
|
|
11221
11796
|
await createFileIfNotExists(clientFile, pageExports);
|
|
11222
11797
|
const serverFile = join(generatedDir, `${generatedBasename}.server.tsx`);
|
|
11223
11798
|
await createFileIfNotExists(serverFile, serverExports);
|
|
11224
|
-
const getTemplates = documentType
|
|
11799
|
+
const getTemplates = framework[documentType];
|
|
11225
11800
|
for (const { file, template } of getTemplates({ pagePath })) {
|
|
11226
11801
|
const content = template.replaceAll("__CONSTANTS__", importFrom("./app/constants.mjs", file)).replaceAll(
|
|
11227
11802
|
"__SITEMAP__",
|
|
@@ -11229,6 +11804,9 @@ Please check webstudio --help for more details`
|
|
|
11229
11804
|
).replaceAll(
|
|
11230
11805
|
"__ASSETS__",
|
|
11231
11806
|
importFrom(`./app/__generated__/$resources.assets`, file)
|
|
11807
|
+
).replaceAll(
|
|
11808
|
+
"__AUTH__",
|
|
11809
|
+
importFrom(`./app/__generated__/$resources.wsauth.server`, file)
|
|
11232
11810
|
).replaceAll(
|
|
11233
11811
|
"__CLIENT__",
|
|
11234
11812
|
importFrom(`./app/__generated__/${generatedBasename}`, file)
|