@webstudio-is/sdk 0.264.0 → 0.266.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/index.js +154 -16
- package/lib/types/page-utils.d.ts +6 -1
- package/lib/types/schema/component-meta.d.ts +110 -0
- package/lib/types/schema/pages.d.ts +77 -150
- package/lib/types/schema/prop-meta.d.ts +66 -0
- package/lib/types/schema/props.d.ts +8 -8
- package/lib/types/schema/webstudio.d.ts +6 -6
- package/package.json +7 -7
package/lib/index.js
CHANGED
|
@@ -97,10 +97,6 @@ var commonPageFields = {
|
|
|
97
97
|
)
|
|
98
98
|
};
|
|
99
99
|
var HomePagePath = z2.string().refine((path) => path === "", "Home page path must be empty");
|
|
100
|
-
var HomePage = z2.object({
|
|
101
|
-
...commonPageFields,
|
|
102
|
-
path: HomePagePath
|
|
103
|
-
});
|
|
104
100
|
var DefaultPagePage = z2.string().refine((path) => path !== "", "Can't be empty").refine((path) => path !== "/", "Can't be just a /").refine((path) => path.endsWith("/") === false, "Can't end with a /").refine((path) => path.includes("//") === false, "Can't contain repeating /").refine(
|
|
105
101
|
(path) => /^[-_a-z0-9*:?\\/.]*$/.test(path),
|
|
106
102
|
"Only a-z, 0-9, -, _, /, :, ?, . and * are allowed"
|
|
@@ -133,7 +129,7 @@ var PagePath = DefaultPagePage.refine(
|
|
|
133
129
|
);
|
|
134
130
|
var Page = z2.object({
|
|
135
131
|
...commonPageFields,
|
|
136
|
-
path: PagePath
|
|
132
|
+
path: z2.union([HomePagePath, PagePath])
|
|
137
133
|
});
|
|
138
134
|
var ProjectMeta = z2.object({
|
|
139
135
|
// All fields are optional to ensure consistency and allow for the addition of new fields without requiring migration
|
|
@@ -163,9 +159,123 @@ var Pages = z2.object({
|
|
|
163
159
|
meta: ProjectMeta.optional(),
|
|
164
160
|
compiler: CompilerSettings.optional(),
|
|
165
161
|
redirects: z2.array(PageRedirect).optional(),
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
162
|
+
homePageId: PageId,
|
|
163
|
+
rootFolderId: FolderId,
|
|
164
|
+
pages: z2.map(PageId, Page),
|
|
165
|
+
folders: z2.map(FolderId, Folder).refine((folders) => folders.size > 0, "Folders can't be empty")
|
|
166
|
+
}).superRefine((pages, context) => {
|
|
167
|
+
const homePage = pages.pages.get(pages.homePageId);
|
|
168
|
+
const rootFolder = pages.folders.get(pages.rootFolderId);
|
|
169
|
+
if (homePage === void 0) {
|
|
170
|
+
context.addIssue({
|
|
171
|
+
code: z2.ZodIssueCode.custom,
|
|
172
|
+
path: ["homePageId"],
|
|
173
|
+
message: "Home page must reference an existing page"
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
if (rootFolder === void 0) {
|
|
177
|
+
context.addIssue({
|
|
178
|
+
code: z2.ZodIssueCode.custom,
|
|
179
|
+
path: ["rootFolderId"],
|
|
180
|
+
message: "Root folder must reference an existing folder"
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
if (homePage !== void 0 && homePage.path !== "") {
|
|
184
|
+
context.addIssue({
|
|
185
|
+
code: z2.ZodIssueCode.custom,
|
|
186
|
+
path: ["pages", pages.homePageId, "path"],
|
|
187
|
+
message: "Home page path must be empty"
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
for (const [pageId, page] of pages.pages) {
|
|
191
|
+
if (page.id !== pageId) {
|
|
192
|
+
context.addIssue({
|
|
193
|
+
code: z2.ZodIssueCode.custom,
|
|
194
|
+
path: ["pages", pageId, "id"],
|
|
195
|
+
message: "Page id must match its record key"
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
if (pageId !== pages.homePageId && page.path === "") {
|
|
199
|
+
context.addIssue({
|
|
200
|
+
code: z2.ZodIssueCode.custom,
|
|
201
|
+
path: ["pages", pageId, "path"],
|
|
202
|
+
message: "Page path can't be empty"
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
for (const [folderId, folder] of pages.folders) {
|
|
207
|
+
if (folder.id !== folderId) {
|
|
208
|
+
context.addIssue({
|
|
209
|
+
code: z2.ZodIssueCode.custom,
|
|
210
|
+
path: ["folders", folderId, "id"],
|
|
211
|
+
message: "Folder id must match its record key"
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
for (const [index, childId] of folder.children.entries()) {
|
|
215
|
+
if (pages.pages.has(childId) === false && pages.folders.has(childId) === false) {
|
|
216
|
+
context.addIssue({
|
|
217
|
+
code: z2.ZodIssueCode.custom,
|
|
218
|
+
path: ["folders", folderId, "children", index],
|
|
219
|
+
message: "Folder child must reference an existing page or folder"
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (childId === pages.rootFolderId) {
|
|
223
|
+
context.addIssue({
|
|
224
|
+
code: z2.ZodIssueCode.custom,
|
|
225
|
+
path: ["folders", folderId, "children", index],
|
|
226
|
+
message: "Root folder can't be nested"
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
if (rootFolder !== void 0 && rootFolder.children[0] !== pages.homePageId) {
|
|
232
|
+
context.addIssue({
|
|
233
|
+
code: z2.ZodIssueCode.custom,
|
|
234
|
+
path: ["folders", pages.rootFolderId, "children"],
|
|
235
|
+
message: "Root folder must start with the home page"
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
const childParents = /* @__PURE__ */ new Map();
|
|
239
|
+
for (const [folderId, folder] of pages.folders) {
|
|
240
|
+
for (const [index, childId] of folder.children.entries()) {
|
|
241
|
+
const parentId = childParents.get(childId);
|
|
242
|
+
if (parentId !== void 0) {
|
|
243
|
+
context.addIssue({
|
|
244
|
+
code: z2.ZodIssueCode.custom,
|
|
245
|
+
path: ["folders", folderId, "children", index],
|
|
246
|
+
message: `Child is already registered in folder "${parentId}"`
|
|
247
|
+
});
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
childParents.set(childId, folderId);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const hasFolderCycle = (folderId, path = /* @__PURE__ */ new Set()) => {
|
|
254
|
+
if (path.has(folderId)) {
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
const folder = pages.folders.get(folderId);
|
|
258
|
+
if (folder === void 0) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
path.add(folderId);
|
|
262
|
+
for (const childId of folder.children) {
|
|
263
|
+
if (pages.folders.has(childId) && hasFolderCycle(childId, path)) {
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
path.delete(folderId);
|
|
268
|
+
return false;
|
|
269
|
+
};
|
|
270
|
+
for (const folderId of pages.folders.keys()) {
|
|
271
|
+
if (hasFolderCycle(folderId)) {
|
|
272
|
+
context.addIssue({
|
|
273
|
+
code: z2.ZodIssueCode.custom,
|
|
274
|
+
path: ["folders", folderId, "children"],
|
|
275
|
+
message: "Folders can't contain cycles"
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
169
279
|
});
|
|
170
280
|
|
|
171
281
|
// src/schema/instances.ts
|
|
@@ -700,7 +810,8 @@ import { z as z14 } from "zod";
|
|
|
700
810
|
var common = {
|
|
701
811
|
label: z14.string().optional(),
|
|
702
812
|
description: z14.string().optional(),
|
|
703
|
-
required: z14.boolean()
|
|
813
|
+
required: z14.boolean(),
|
|
814
|
+
contentMode: z14.boolean().optional()
|
|
704
815
|
};
|
|
705
816
|
var Tag = z14.object({
|
|
706
817
|
...common,
|
|
@@ -2364,16 +2475,36 @@ var isAbsoluteUrl = (href) => {
|
|
|
2364
2475
|
// src/page-utils.ts
|
|
2365
2476
|
var ROOT_FOLDER_ID = "root";
|
|
2366
2477
|
var isRootFolder = ({ id }) => id === ROOT_FOLDER_ID;
|
|
2478
|
+
var getPageById = (pages, pageId) => {
|
|
2479
|
+
return pages.pages.get(pageId);
|
|
2480
|
+
};
|
|
2481
|
+
var getFolderById = (pages, folderId) => {
|
|
2482
|
+
return pages.folders.get(folderId);
|
|
2483
|
+
};
|
|
2484
|
+
var getAllPages = (pages) => {
|
|
2485
|
+
return Array.from(pages.pages.values());
|
|
2486
|
+
};
|
|
2487
|
+
var getAllFolders = (pages) => {
|
|
2488
|
+
return Array.from(pages.folders.values());
|
|
2489
|
+
};
|
|
2490
|
+
var getHomePage = (pages) => {
|
|
2491
|
+
const homePage = getPageById(pages, pages.homePageId);
|
|
2492
|
+
if (homePage === void 0) {
|
|
2493
|
+
throw new Error(`Home page "${pages.homePageId}" was not found.`);
|
|
2494
|
+
}
|
|
2495
|
+
return homePage;
|
|
2496
|
+
};
|
|
2367
2497
|
var findPageByIdOrPath = (idOrPath, pages) => {
|
|
2368
|
-
if (idOrPath === "" || idOrPath === "/" || idOrPath === pages.
|
|
2369
|
-
return pages
|
|
2498
|
+
if (idOrPath === "" || idOrPath === "/" || idOrPath === pages.homePageId) {
|
|
2499
|
+
return getHomePage(pages);
|
|
2370
2500
|
}
|
|
2371
|
-
return pages.
|
|
2501
|
+
return getAllPages(pages).find(
|
|
2372
2502
|
(page) => page.id === idOrPath || getPagePath(page.id, pages) === idOrPath
|
|
2373
2503
|
);
|
|
2374
2504
|
};
|
|
2375
2505
|
var findParentFolderByChildId = (id, folders) => {
|
|
2376
|
-
|
|
2506
|
+
const folderList = folders instanceof Map ? folders.values() : folders;
|
|
2507
|
+
for (const folder of folderList) {
|
|
2377
2508
|
if (folder.children.includes(id)) {
|
|
2378
2509
|
return folder;
|
|
2379
2510
|
}
|
|
@@ -2382,7 +2513,7 @@ var findParentFolderByChildId = (id, folders) => {
|
|
|
2382
2513
|
var getPagePath = (id, pages) => {
|
|
2383
2514
|
const foldersMap = /* @__PURE__ */ new Map();
|
|
2384
2515
|
const childParentMap = /* @__PURE__ */ new Map();
|
|
2385
|
-
for (const folder of pages
|
|
2516
|
+
for (const folder of getAllFolders(pages)) {
|
|
2386
2517
|
foldersMap.set(folder.id, folder);
|
|
2387
2518
|
for (const childId of folder.children) {
|
|
2388
2519
|
childParentMap.set(childId, folder.id);
|
|
@@ -2390,7 +2521,7 @@ var getPagePath = (id, pages) => {
|
|
|
2390
2521
|
}
|
|
2391
2522
|
const paths = [];
|
|
2392
2523
|
let currentId = id;
|
|
2393
|
-
const allPages =
|
|
2524
|
+
const allPages = getAllPages(pages);
|
|
2394
2525
|
for (const page of allPages) {
|
|
2395
2526
|
if (page.id === id) {
|
|
2396
2527
|
paths.push(page.path);
|
|
@@ -2409,7 +2540,7 @@ var getPagePath = (id, pages) => {
|
|
|
2409
2540
|
return paths.reverse().join("/").replace(/\/+/g, "/");
|
|
2410
2541
|
};
|
|
2411
2542
|
var getStaticSiteMapXml = (pages, updatedAt) => {
|
|
2412
|
-
const allPages =
|
|
2543
|
+
const allPages = getAllPages(pages);
|
|
2413
2544
|
return allPages.filter((page) => (page.meta.documentType ?? "html") === "html").filter(
|
|
2414
2545
|
(page) => executeExpression(page.meta.excludePageFromSearch) !== true
|
|
2415
2546
|
).filter((page) => false === isPathnamePattern(page.path)).map((page) => ({
|
|
@@ -3008,6 +3139,7 @@ export {
|
|
|
3008
3139
|
FONT_EXTENSIONS,
|
|
3009
3140
|
FileAsset,
|
|
3010
3141
|
Folder,
|
|
3142
|
+
FolderId,
|
|
3011
3143
|
FolderName,
|
|
3012
3144
|
FontAsset,
|
|
3013
3145
|
HomePagePath,
|
|
@@ -3021,6 +3153,7 @@ export {
|
|
|
3021
3153
|
Instances,
|
|
3022
3154
|
MIME_CATEGORIES,
|
|
3023
3155
|
OldPagePath,
|
|
3156
|
+
PageId,
|
|
3024
3157
|
PageName,
|
|
3025
3158
|
PagePath,
|
|
3026
3159
|
PageRedirect,
|
|
@@ -3087,12 +3220,17 @@ export {
|
|
|
3087
3220
|
generateObjectExpression,
|
|
3088
3221
|
generatePageMeta,
|
|
3089
3222
|
generateResources,
|
|
3223
|
+
getAllFolders,
|
|
3224
|
+
getAllPages,
|
|
3090
3225
|
getAssetMime,
|
|
3091
3226
|
getAssetUrl,
|
|
3092
3227
|
getExpressionIdentifiers,
|
|
3228
|
+
getFolderById,
|
|
3229
|
+
getHomePage,
|
|
3093
3230
|
getIndexesWithinAncestors,
|
|
3094
3231
|
getMimeTypeByExtension,
|
|
3095
3232
|
getMimeTypeByFilename,
|
|
3233
|
+
getPageById,
|
|
3096
3234
|
getPagePath,
|
|
3097
3235
|
getStaticSiteMapXml,
|
|
3098
3236
|
getStyleDeclKey,
|
|
@@ -6,6 +6,11 @@ export declare const ROOT_FOLDER_ID = "root";
|
|
|
6
6
|
export declare const isRootFolder: ({ id }: {
|
|
7
7
|
id: Folder["id"];
|
|
8
8
|
}) => boolean;
|
|
9
|
+
export declare const getPageById: (pages: Pages, pageId: Page["id"]) => Page | undefined;
|
|
10
|
+
export declare const getFolderById: (pages: Pages, folderId: Folder["id"]) => Folder | undefined;
|
|
11
|
+
export declare const getAllPages: (pages: Pages) => Page[];
|
|
12
|
+
export declare const getAllFolders: (pages: Pages) => Folder[];
|
|
13
|
+
export declare const getHomePage: (pages: Pages) => Page;
|
|
9
14
|
/**
|
|
10
15
|
* Find a page by id or path.
|
|
11
16
|
*/
|
|
@@ -13,7 +18,7 @@ export declare const findPageByIdOrPath: (idOrPath: string, pages: Pages) => Pag
|
|
|
13
18
|
/**
|
|
14
19
|
* Find a folder that has has that id in the children.
|
|
15
20
|
*/
|
|
16
|
-
export declare const findParentFolderByChildId: (id: Folder["id"] | Page["id"], folders:
|
|
21
|
+
export declare const findParentFolderByChildId: (id: Folder["id"] | Page["id"], folders: Iterable<Folder> | Map<Folder["id"], Folder>) => Folder | undefined;
|
|
17
22
|
/**
|
|
18
23
|
* Get a path from all folder slugs from root to the current folder or page.
|
|
19
24
|
*/
|