@webstudio-is/sdk 0.95.0 → 0.97.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 CHANGED
@@ -1,13 +1,390 @@
1
- "use strict";
2
- export * from "./schema/assets";
3
- export * from "./schema/pages";
4
- export * from "./schema/instances";
5
- export * from "./schema/data-sources";
6
- export * from "./schema/props";
7
- export * from "./schema/breakpoints";
8
- export * from "./schema/style-sources";
9
- export * from "./schema/style-source-selections";
10
- export * from "./schema/styles";
11
- export * from "./schema/deployment";
12
- export * from "./instances-utils";
13
- export * from "./scope";
1
+ // src/schema/assets.ts
2
+ import { z } from "zod";
3
+ import { FontFormat, FontMeta } from "@webstudio-is/fonts";
4
+ var AssetId = z.string();
5
+ var baseAsset = {
6
+ id: AssetId,
7
+ projectId: z.string(),
8
+ size: z.number(),
9
+ name: z.string(),
10
+ description: z.union([z.string(), z.null()]),
11
+ createdAt: z.string()
12
+ };
13
+ var FontAsset = z.object({
14
+ ...baseAsset,
15
+ format: FontFormat,
16
+ meta: FontMeta,
17
+ type: z.literal("font")
18
+ });
19
+ var ImageMeta = z.object({
20
+ width: z.number(),
21
+ height: z.number()
22
+ });
23
+ var ImageAsset = z.object({
24
+ ...baseAsset,
25
+ format: z.string(),
26
+ meta: ImageMeta,
27
+ type: z.literal("image")
28
+ });
29
+ var Asset = z.union([FontAsset, ImageAsset]);
30
+ var Assets = z.map(AssetId, Asset);
31
+
32
+ // src/schema/pages.ts
33
+ import { z as z2 } from "zod";
34
+ var MIN_TITLE_LENGTH = 2;
35
+ var PageName = z2.string().refine((value) => value.trim() !== "", "Can't be empty");
36
+ var PageTitle = z2.string().refine(
37
+ (val) => val.length >= MIN_TITLE_LENGTH,
38
+ `Minimum ${MIN_TITLE_LENGTH} characters required`
39
+ );
40
+ var commonPageFields = {
41
+ id: z2.string(),
42
+ name: PageName,
43
+ title: PageTitle,
44
+ meta: z2.record(z2.string(), z2.string()),
45
+ rootInstanceId: z2.string()
46
+ };
47
+ var HomePagePath = z2.string().refine((path) => path === "", "Home page path must be empty");
48
+ var HomePage = z2.object({
49
+ ...commonPageFields,
50
+ path: HomePagePath
51
+ });
52
+ var pathValidators = (baseValidator) => baseValidator.refine((path) => path !== "", "Can't be empty").refine((path) => path !== "/", "Can't be just a /").refine(
53
+ (path) => path === "" || path.startsWith("/"),
54
+ "Must start with a /"
55
+ ).refine((path) => path.endsWith("/") === false, "Can't end with a /").refine(
56
+ (path) => path.includes("//") === false,
57
+ "Can't contain repeating /"
58
+ ).refine(
59
+ (path) => /^[-_a-z0-9\\/]*$/.test(path),
60
+ "Only a-z, 0-9, -, _ and / are allowed"
61
+ ).refine(
62
+ // We use /s for our system stuff like /s/css or /s/uploads
63
+ (path) => path !== "/s" && path.startsWith("/s/") === false,
64
+ "/s prefix is reserved for the system"
65
+ ).refine(
66
+ // Remix serves build artefacts like JS bundles from /build
67
+ // And we cannot customize it due to bug in Remix: https://github.com/remix-run/remix/issues/2933
68
+ (path) => path !== "/build" && path.startsWith("/build/") === false,
69
+ "/build prefix is reserved for the system"
70
+ );
71
+ var PagePath = pathValidators(z2.string());
72
+ var Page = z2.object({
73
+ ...commonPageFields,
74
+ path: PagePath
75
+ });
76
+ var Pages = z2.object({
77
+ homePage: HomePage,
78
+ pages: z2.array(Page).refine(
79
+ (array) => new Set(array.map((page) => page.path)).size === array.length,
80
+ "All paths must be unique"
81
+ )
82
+ });
83
+
84
+ // src/schema/instances.ts
85
+ import { z as z3 } from "zod";
86
+ var Text = z3.object({
87
+ type: z3.literal("text"),
88
+ value: z3.string()
89
+ });
90
+ var InstanceId = z3.string();
91
+ var Id = z3.object({
92
+ type: z3.literal("id"),
93
+ value: InstanceId
94
+ });
95
+ var Instance = z3.object({
96
+ type: z3.literal("instance"),
97
+ id: InstanceId,
98
+ component: z3.string(),
99
+ label: z3.string().optional(),
100
+ children: z3.array(z3.union([Id, Text]))
101
+ });
102
+ var Instances = z3.map(InstanceId, Instance);
103
+
104
+ // src/schema/data-sources.ts
105
+ import { z as z4 } from "zod";
106
+ var DataSourceId = z4.string();
107
+ var DataSourceVariableValue = z4.union([
108
+ z4.object({
109
+ type: z4.literal("number"),
110
+ // initial value of variable store
111
+ value: z4.number()
112
+ }),
113
+ z4.object({
114
+ type: z4.literal("string"),
115
+ value: z4.string()
116
+ }),
117
+ z4.object({
118
+ type: z4.literal("boolean"),
119
+ value: z4.boolean()
120
+ }),
121
+ z4.object({
122
+ type: z4.literal("string[]"),
123
+ value: z4.array(z4.string())
124
+ })
125
+ ]);
126
+ var DataSource = z4.union([
127
+ z4.object({
128
+ type: z4.literal("variable"),
129
+ id: DataSourceId,
130
+ scopeInstanceId: z4.optional(z4.string()),
131
+ name: z4.string(),
132
+ value: DataSourceVariableValue
133
+ }),
134
+ z4.object({
135
+ type: z4.literal("expression"),
136
+ id: DataSourceId,
137
+ scopeInstanceId: z4.optional(z4.string()),
138
+ name: z4.string(),
139
+ code: z4.string()
140
+ })
141
+ ]);
142
+ var DataSources = z4.map(DataSourceId, DataSource);
143
+
144
+ // src/schema/props.ts
145
+ import { z as z5 } from "zod";
146
+ var PropId = z5.string();
147
+ var baseProp = {
148
+ id: PropId,
149
+ instanceId: z5.string(),
150
+ name: z5.string(),
151
+ required: z5.optional(z5.boolean())
152
+ };
153
+ var Prop = z5.union([
154
+ z5.object({
155
+ ...baseProp,
156
+ type: z5.literal("number"),
157
+ value: z5.number()
158
+ }),
159
+ z5.object({
160
+ ...baseProp,
161
+ type: z5.literal("string"),
162
+ value: z5.string()
163
+ }),
164
+ z5.object({
165
+ ...baseProp,
166
+ type: z5.literal("boolean"),
167
+ value: z5.boolean()
168
+ }),
169
+ z5.object({
170
+ ...baseProp,
171
+ type: z5.literal("asset"),
172
+ value: z5.string()
173
+ // asset id
174
+ }),
175
+ z5.object({
176
+ ...baseProp,
177
+ type: z5.literal("page"),
178
+ value: z5.union([
179
+ z5.string(),
180
+ // page id
181
+ z5.object({
182
+ pageId: z5.string(),
183
+ instanceId: z5.string()
184
+ })
185
+ ])
186
+ }),
187
+ z5.object({
188
+ ...baseProp,
189
+ type: z5.literal("string[]"),
190
+ value: z5.array(z5.string())
191
+ }),
192
+ z5.object({
193
+ ...baseProp,
194
+ type: z5.literal("dataSource"),
195
+ // data source id
196
+ value: z5.string()
197
+ }),
198
+ z5.object({
199
+ ...baseProp,
200
+ type: z5.literal("action"),
201
+ value: z5.array(
202
+ z5.object({
203
+ type: z5.literal("execute"),
204
+ args: z5.array(z5.string()),
205
+ code: z5.string()
206
+ })
207
+ )
208
+ })
209
+ ]);
210
+ var Props = z5.map(PropId, Prop);
211
+
212
+ // src/schema/breakpoints.ts
213
+ import { z as z6 } from "zod";
214
+ var BreakpointId = z6.string();
215
+ var Breakpoint = z6.object({
216
+ id: BreakpointId,
217
+ label: z6.string(),
218
+ minWidth: z6.number().optional(),
219
+ maxWidth: z6.number().optional()
220
+ }).refine(({ minWidth, maxWidth }) => {
221
+ return (
222
+ // Either min or max width have to be defined
223
+ minWidth !== void 0 && maxWidth === void 0 || minWidth === void 0 && maxWidth !== void 0 || // This is a base breakpoint
224
+ minWidth === void 0 && maxWidth === void 0
225
+ );
226
+ }, "Either minWidth or maxWidth should be defined");
227
+ var Breakpoints = z6.map(BreakpointId, Breakpoint);
228
+ var initialBreakpoints = [
229
+ { id: "placeholder", label: "Base" },
230
+ { id: "placeholder", label: "Tablet", maxWidth: 991 },
231
+ { id: "placeholder", label: "Mobile landscape", maxWidth: 767 },
232
+ { id: "placeholder", label: "Mobile portrait", maxWidth: 479 }
233
+ ];
234
+
235
+ // src/schema/style-sources.ts
236
+ import { z as z7 } from "zod";
237
+ var StyleSourceId = z7.string();
238
+ var StyleSourceToken = z7.object({
239
+ type: z7.literal("token"),
240
+ id: StyleSourceId,
241
+ name: z7.string()
242
+ });
243
+ var StyleSourceLocal = z7.object({
244
+ type: z7.literal("local"),
245
+ id: StyleSourceId
246
+ });
247
+ var StyleSource = z7.union([StyleSourceToken, StyleSourceLocal]);
248
+ var StyleSources = z7.map(StyleSourceId, StyleSource);
249
+
250
+ // src/schema/style-source-selections.ts
251
+ import { z as z8 } from "zod";
252
+ var InstanceId2 = z8.string();
253
+ var StyleSourceId2 = z8.string();
254
+ var StyleSourceSelection = z8.object({
255
+ instanceId: InstanceId2,
256
+ values: z8.array(StyleSourceId2)
257
+ });
258
+ var StyleSourceSelections = z8.map(InstanceId2, StyleSourceSelection);
259
+
260
+ // src/schema/styles.ts
261
+ import { z as z9 } from "zod";
262
+ import { StyleValue } from "@webstudio-is/css-engine";
263
+ var StyleDeclRaw = z9.object({
264
+ styleSourceId: z9.string(),
265
+ breakpointId: z9.string(),
266
+ state: z9.optional(z9.string()),
267
+ // @todo can't figure out how to make property to be enum
268
+ property: z9.string(),
269
+ value: StyleValue
270
+ });
271
+ var StyleDecl = StyleDeclRaw;
272
+ var getStyleDeclKey = (styleDecl) => {
273
+ return `${styleDecl.styleSourceId}:${styleDecl.breakpointId}:${styleDecl.property}:${styleDecl.state ?? ""}`;
274
+ };
275
+ var Styles = z9.map(z9.string(), StyleDecl);
276
+
277
+ // src/schema/deployment.ts
278
+ import { z as z10 } from "zod";
279
+ var Deployment = z10.object({
280
+ domains: z10.array(z10.string()),
281
+ projectDomain: z10.string()
282
+ });
283
+
284
+ // src/instances-utils.ts
285
+ var traverseInstances = (instances, instanceId, callback) => {
286
+ const instance = instances.get(instanceId);
287
+ if (instance === void 0) {
288
+ return;
289
+ }
290
+ const skipTraversingChildren = callback(instance);
291
+ if (skipTraversingChildren === false) {
292
+ return;
293
+ }
294
+ for (const child of instance.children) {
295
+ if (child.type === "id") {
296
+ traverseInstances(instances, child.value, callback);
297
+ }
298
+ }
299
+ };
300
+ var findTreeInstanceIds = (instances, rootInstanceId) => {
301
+ const ids = /* @__PURE__ */ new Set();
302
+ traverseInstances(instances, rootInstanceId, (instance) => {
303
+ ids.add(instance.id);
304
+ });
305
+ return ids;
306
+ };
307
+ var findTreeInstanceIdsExcludingSlotDescendants = (instances, rootInstanceId) => {
308
+ const ids = /* @__PURE__ */ new Set();
309
+ traverseInstances(instances, rootInstanceId, (instance) => {
310
+ ids.add(instance.id);
311
+ if (instance.component === "Slot") {
312
+ return false;
313
+ }
314
+ });
315
+ return ids;
316
+ };
317
+ var parseComponentName = (componentName) => {
318
+ const parts = componentName.split(":");
319
+ let namespace;
320
+ let name;
321
+ if (parts.length === 1) {
322
+ [name] = parts;
323
+ } else {
324
+ [namespace, name] = parts;
325
+ }
326
+ return [namespace, name];
327
+ };
328
+
329
+ // src/scope.ts
330
+ var createScope = (occupiedIdentifiers = []) => {
331
+ const freeIndexByPreferredName = /* @__PURE__ */ new Map();
332
+ const scopedNameByIdMap = /* @__PURE__ */ new Map();
333
+ for (const identifier of occupiedIdentifiers) {
334
+ freeIndexByPreferredName.set(identifier, 1);
335
+ }
336
+ const getName = (id, preferredName) => {
337
+ const cachedName = scopedNameByIdMap.get(id);
338
+ if (cachedName !== void 0) {
339
+ return cachedName;
340
+ }
341
+ const index = freeIndexByPreferredName.get(preferredName);
342
+ freeIndexByPreferredName.set(preferredName, (index ?? 0) + 1);
343
+ let scopedName = preferredName;
344
+ if (index !== void 0) {
345
+ scopedName = `${preferredName}_${index}`;
346
+ }
347
+ scopedNameByIdMap.set(id, scopedName);
348
+ return scopedName;
349
+ };
350
+ return {
351
+ getName
352
+ };
353
+ };
354
+ export {
355
+ Asset,
356
+ Assets,
357
+ Breakpoint,
358
+ Breakpoints,
359
+ DataSource,
360
+ DataSourceVariableValue,
361
+ DataSources,
362
+ Deployment,
363
+ FontAsset,
364
+ HomePagePath,
365
+ Id,
366
+ ImageAsset,
367
+ ImageMeta,
368
+ Instance,
369
+ Instances,
370
+ PageName,
371
+ PagePath,
372
+ PageTitle,
373
+ Pages,
374
+ Prop,
375
+ Props,
376
+ StyleDecl,
377
+ StyleSource,
378
+ StyleSourceSelection,
379
+ StyleSourceSelections,
380
+ StyleSources,
381
+ Styles,
382
+ Text,
383
+ createScope,
384
+ findTreeInstanceIds,
385
+ findTreeInstanceIdsExcludingSlotDescendants,
386
+ getStyleDeclKey,
387
+ initialBreakpoints,
388
+ parseComponentName,
389
+ pathValidators
390
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webstudio-is/sdk",
3
- "version": "0.95.0",
3
+ "version": "0.97.0",
4
4
  "description": "Webstudio site data schema",
5
5
  "author": "Webstudio <github@webstudio.is>",
6
6
  "homepage": "https://webstudio.is",
@@ -19,8 +19,8 @@
19
19
  "sideEffects": false,
20
20
  "dependencies": {
21
21
  "zod": "^3.21.4",
22
- "@webstudio-is/fonts": "^0.95.0",
23
- "@webstudio-is/css-engine": "^0.95.0"
22
+ "@webstudio-is/fonts": "^0.97.0",
23
+ "@webstudio-is/css-engine": "^0.97.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@jest/globals": "^29.6.4",
@@ -32,8 +32,8 @@
32
32
  "typecheck": "tsc",
33
33
  "test": "NODE_OPTIONS=--experimental-vm-modules jest",
34
34
  "checks": "pnpm typecheck && pnpm test",
35
- "dev": "pnpm build --watch",
36
- "build": "rm -rf lib && esbuild 'src/**/*.ts' 'src/**/*.tsx' --outdir=lib",
35
+ "dev": "rm -rf lib && esbuild 'src/**/*.ts' 'src/**/*.tsx' --outdir=lib --watch",
36
+ "build": "rm -rf lib && esbuild src/index.ts --outdir=lib --bundle --format=esm --packages=external",
37
37
  "dts": "tsc --project tsconfig.dts.json"
38
38
  }
39
39
  }
@@ -1,44 +0,0 @@
1
- "use strict";
2
- const traverseInstances = (instances, instanceId, callback) => {
3
- const instance = instances.get(instanceId);
4
- if (instance === void 0) {
5
- return;
6
- }
7
- const skipTraversingChildren = callback(instance);
8
- if (skipTraversingChildren === false) {
9
- return;
10
- }
11
- for (const child of instance.children) {
12
- if (child.type === "id") {
13
- traverseInstances(instances, child.value, callback);
14
- }
15
- }
16
- };
17
- export const findTreeInstanceIds = (instances, rootInstanceId) => {
18
- const ids = /* @__PURE__ */ new Set();
19
- traverseInstances(instances, rootInstanceId, (instance) => {
20
- ids.add(instance.id);
21
- });
22
- return ids;
23
- };
24
- export const findTreeInstanceIdsExcludingSlotDescendants = (instances, rootInstanceId) => {
25
- const ids = /* @__PURE__ */ new Set();
26
- traverseInstances(instances, rootInstanceId, (instance) => {
27
- ids.add(instance.id);
28
- if (instance.component === "Slot") {
29
- return false;
30
- }
31
- });
32
- return ids;
33
- };
34
- export const parseComponentName = (componentName) => {
35
- const parts = componentName.split(":");
36
- let namespace;
37
- let name;
38
- if (parts.length === 1) {
39
- [name] = parts;
40
- } else {
41
- [namespace, name] = parts;
42
- }
43
- return [namespace, name];
44
- };
@@ -1,63 +0,0 @@
1
- "use strict";
2
- import { expect, test } from "@jest/globals";
3
- import {
4
- findTreeInstanceIds,
5
- findTreeInstanceIdsExcludingSlotDescendants,
6
- parseComponentName
7
- } from "./instances-utils";
8
- const createInstance = (id, component, children) => {
9
- return {
10
- type: "instance",
11
- id,
12
- component,
13
- children
14
- };
15
- };
16
- const createInstancePair = (id, component, children) => {
17
- return [id, createInstance(id, component, children)];
18
- };
19
- test("find all tree instances", () => {
20
- const instances = new Map([
21
- createInstancePair("1", "Body", [{ type: "id", value: "3" }]),
22
- // this is outside of subtree
23
- createInstancePair("2", "Box", []),
24
- // these should be matched
25
- createInstancePair("3", "Box", [
26
- { type: "id", value: "4" },
27
- { type: "id", value: "5" }
28
- ]),
29
- createInstancePair("4", "Box", []),
30
- createInstancePair("5", "Box", []),
31
- // this one is from other tree
32
- createInstancePair("6", "Box", [])
33
- ]);
34
- expect(findTreeInstanceIds(instances, "3")).toEqual(/* @__PURE__ */ new Set(["3", "4", "5"]));
35
- });
36
- test("find all tree instances excluding slot descendants", () => {
37
- const instances = new Map([
38
- createInstancePair("root", "Body", [
39
- { type: "id", value: "box1" },
40
- { type: "id", value: "box2" }
41
- ]),
42
- // this is outside of subtree
43
- createInstancePair("outside", "Box", []),
44
- // these should be matched
45
- createInstancePair("box1", "Box", [
46
- { type: "id", value: "slot11" },
47
- { type: "id", value: "box12" }
48
- ]),
49
- createInstancePair("slot11", "Slot", [
50
- { type: "id", value: "box111" },
51
- { type: "id", value: "box112" }
52
- ]),
53
- createInstancePair("box12", "Box", []),
54
- createInstancePair("box2", "Box", [])
55
- ]);
56
- expect(
57
- findTreeInstanceIdsExcludingSlotDescendants(instances, "box1")
58
- ).toEqual(/* @__PURE__ */ new Set(["box1", "box12", "slot11"]));
59
- });
60
- test("extract short name and namespace from component name", () => {
61
- expect(parseComponentName("Box")).toEqual([void 0, "Box"]);
62
- expect(parseComponentName("radix:Box")).toEqual(["radix", "Box"]);
63
- });
@@ -1,30 +0,0 @@
1
- "use strict";
2
- import { z } from "zod";
3
- import { FontFormat, FontMeta } from "@webstudio-is/fonts";
4
- const AssetId = z.string();
5
- const baseAsset = {
6
- id: AssetId,
7
- projectId: z.string(),
8
- size: z.number(),
9
- name: z.string(),
10
- description: z.union([z.string(), z.null()]),
11
- createdAt: z.string()
12
- };
13
- export const FontAsset = z.object({
14
- ...baseAsset,
15
- format: FontFormat,
16
- meta: FontMeta,
17
- type: z.literal("font")
18
- });
19
- export const ImageMeta = z.object({
20
- width: z.number(),
21
- height: z.number()
22
- });
23
- export const ImageAsset = z.object({
24
- ...baseAsset,
25
- format: z.string(),
26
- meta: ImageMeta,
27
- type: z.literal("image")
28
- });
29
- export const Asset = z.union([FontAsset, ImageAsset]);
30
- export const Assets = z.map(AssetId, Asset);
@@ -1,22 +0,0 @@
1
- "use strict";
2
- import { z } from "zod";
3
- const BreakpointId = z.string();
4
- export const Breakpoint = z.object({
5
- id: BreakpointId,
6
- label: z.string(),
7
- minWidth: z.number().optional(),
8
- maxWidth: z.number().optional()
9
- }).refine(({ minWidth, maxWidth }) => {
10
- return (
11
- // Either min or max width have to be defined
12
- minWidth !== void 0 && maxWidth === void 0 || minWidth === void 0 && maxWidth !== void 0 || // This is a base breakpoint
13
- minWidth === void 0 && maxWidth === void 0
14
- );
15
- }, "Either minWidth or maxWidth should be defined");
16
- export const Breakpoints = z.map(BreakpointId, Breakpoint);
17
- export const initialBreakpoints = [
18
- { id: "placeholder", label: "Base" },
19
- { id: "placeholder", label: "Tablet", maxWidth: 991 },
20
- { id: "placeholder", label: "Mobile landscape", maxWidth: 767 },
21
- { id: "placeholder", label: "Mobile portrait", maxWidth: 479 }
22
- ];
@@ -1,39 +0,0 @@
1
- "use strict";
2
- import { z } from "zod";
3
- const DataSourceId = z.string();
4
- export const DataSourceVariableValue = z.union([
5
- z.object({
6
- type: z.literal("number"),
7
- // initial value of variable store
8
- value: z.number()
9
- }),
10
- z.object({
11
- type: z.literal("string"),
12
- value: z.string()
13
- }),
14
- z.object({
15
- type: z.literal("boolean"),
16
- value: z.boolean()
17
- }),
18
- z.object({
19
- type: z.literal("string[]"),
20
- value: z.array(z.string())
21
- })
22
- ]);
23
- export const DataSource = z.union([
24
- z.object({
25
- type: z.literal("variable"),
26
- id: DataSourceId,
27
- scopeInstanceId: z.optional(z.string()),
28
- name: z.string(),
29
- value: DataSourceVariableValue
30
- }),
31
- z.object({
32
- type: z.literal("expression"),
33
- id: DataSourceId,
34
- scopeInstanceId: z.optional(z.string()),
35
- name: z.string(),
36
- code: z.string()
37
- })
38
- ]);
39
- export const DataSources = z.map(DataSourceId, DataSource);
@@ -1,6 +0,0 @@
1
- "use strict";
2
- import { z } from "zod";
3
- export const Deployment = z.object({
4
- domains: z.array(z.string()),
5
- projectDomain: z.string()
6
- });
@@ -1,19 +0,0 @@
1
- "use strict";
2
- import { z } from "zod";
3
- export const Text = z.object({
4
- type: z.literal("text"),
5
- value: z.string()
6
- });
7
- const InstanceId = z.string();
8
- export const Id = z.object({
9
- type: z.literal("id"),
10
- value: InstanceId
11
- });
12
- export const Instance = z.object({
13
- type: z.literal("instance"),
14
- id: InstanceId,
15
- component: z.string(),
16
- label: z.string().optional(),
17
- children: z.array(z.union([Id, Text]))
18
- });
19
- export const Instances = z.map(InstanceId, Instance);
@@ -1,51 +0,0 @@
1
- "use strict";
2
- import { z } from "zod";
3
- const MIN_TITLE_LENGTH = 2;
4
- export const PageName = z.string().refine((value) => value.trim() !== "", "Can't be empty");
5
- export const PageTitle = z.string().refine(
6
- (val) => val.length >= MIN_TITLE_LENGTH,
7
- `Minimum ${MIN_TITLE_LENGTH} characters required`
8
- );
9
- const commonPageFields = {
10
- id: z.string(),
11
- name: PageName,
12
- title: PageTitle,
13
- meta: z.record(z.string(), z.string()),
14
- rootInstanceId: z.string()
15
- };
16
- export const HomePagePath = z.string().refine((path) => path === "", "Home page path must be empty");
17
- const HomePage = z.object({
18
- ...commonPageFields,
19
- path: HomePagePath
20
- });
21
- export const pathValidators = (baseValidator) => baseValidator.refine((path) => path !== "", "Can't be empty").refine((path) => path !== "/", "Can't be just a /").refine(
22
- (path) => path === "" || path.startsWith("/"),
23
- "Must start with a /"
24
- ).refine((path) => path.endsWith("/") === false, "Can't end with a /").refine(
25
- (path) => path.includes("//") === false,
26
- "Can't contain repeating /"
27
- ).refine(
28
- (path) => /^[-_a-z0-9\\/]*$/.test(path),
29
- "Only a-z, 0-9, -, _ and / are allowed"
30
- ).refine(
31
- // We use /s for our system stuff like /s/css or /s/uploads
32
- (path) => path !== "/s" && path.startsWith("/s/") === false,
33
- "/s prefix is reserved for the system"
34
- ).refine(
35
- // Remix serves build artefacts like JS bundles from /build
36
- // And we cannot customize it due to bug in Remix: https://github.com/remix-run/remix/issues/2933
37
- (path) => path !== "/build" && path.startsWith("/build/") === false,
38
- "/build prefix is reserved for the system"
39
- );
40
- export const PagePath = pathValidators(z.string());
41
- const Page = z.object({
42
- ...commonPageFields,
43
- path: PagePath
44
- });
45
- export const Pages = z.object({
46
- homePage: HomePage,
47
- pages: z.array(Page).refine(
48
- (array) => new Set(array.map((page) => page.path)).size === array.length,
49
- "All paths must be unique"
50
- )
51
- });
@@ -1,67 +0,0 @@
1
- "use strict";
2
- import { z } from "zod";
3
- const PropId = z.string();
4
- const baseProp = {
5
- id: PropId,
6
- instanceId: z.string(),
7
- name: z.string(),
8
- required: z.optional(z.boolean())
9
- };
10
- export const Prop = z.union([
11
- z.object({
12
- ...baseProp,
13
- type: z.literal("number"),
14
- value: z.number()
15
- }),
16
- z.object({
17
- ...baseProp,
18
- type: z.literal("string"),
19
- value: z.string()
20
- }),
21
- z.object({
22
- ...baseProp,
23
- type: z.literal("boolean"),
24
- value: z.boolean()
25
- }),
26
- z.object({
27
- ...baseProp,
28
- type: z.literal("asset"),
29
- value: z.string()
30
- // asset id
31
- }),
32
- z.object({
33
- ...baseProp,
34
- type: z.literal("page"),
35
- value: z.union([
36
- z.string(),
37
- // page id
38
- z.object({
39
- pageId: z.string(),
40
- instanceId: z.string()
41
- })
42
- ])
43
- }),
44
- z.object({
45
- ...baseProp,
46
- type: z.literal("string[]"),
47
- value: z.array(z.string())
48
- }),
49
- z.object({
50
- ...baseProp,
51
- type: z.literal("dataSource"),
52
- // data source id
53
- value: z.string()
54
- }),
55
- z.object({
56
- ...baseProp,
57
- type: z.literal("action"),
58
- value: z.array(
59
- z.object({
60
- type: z.literal("execute"),
61
- args: z.array(z.string()),
62
- code: z.string()
63
- })
64
- )
65
- })
66
- ]);
67
- export const Props = z.map(PropId, Prop);
@@ -1,9 +0,0 @@
1
- "use strict";
2
- import { z } from "zod";
3
- const InstanceId = z.string();
4
- const StyleSourceId = z.string();
5
- export const StyleSourceSelection = z.object({
6
- instanceId: InstanceId,
7
- values: z.array(StyleSourceId)
8
- });
9
- export const StyleSourceSelections = z.map(InstanceId, StyleSourceSelection);
@@ -1,14 +0,0 @@
1
- "use strict";
2
- import { z } from "zod";
3
- const StyleSourceId = z.string();
4
- const StyleSourceToken = z.object({
5
- type: z.literal("token"),
6
- id: StyleSourceId,
7
- name: z.string()
8
- });
9
- const StyleSourceLocal = z.object({
10
- type: z.literal("local"),
11
- id: StyleSourceId
12
- });
13
- export const StyleSource = z.union([StyleSourceToken, StyleSourceLocal]);
14
- export const StyleSources = z.map(StyleSourceId, StyleSource);
@@ -1,16 +0,0 @@
1
- "use strict";
2
- import { z } from "zod";
3
- import { StyleValue } from "@webstudio-is/css-engine";
4
- const StyleDeclRaw = z.object({
5
- styleSourceId: z.string(),
6
- breakpointId: z.string(),
7
- state: z.optional(z.string()),
8
- // @todo can't figure out how to make property to be enum
9
- property: z.string(),
10
- value: StyleValue
11
- });
12
- export const StyleDecl = StyleDeclRaw;
13
- export const getStyleDeclKey = (styleDecl) => {
14
- return `${styleDecl.styleSourceId}:${styleDecl.breakpointId}:${styleDecl.property}:${styleDecl.state ?? ""}`;
15
- };
16
- export const Styles = z.map(z.string(), StyleDecl);
package/lib/scope.js DELETED
@@ -1,25 +0,0 @@
1
- "use strict";
2
- export const createScope = (occupiedIdentifiers = []) => {
3
- const freeIndexByPreferredName = /* @__PURE__ */ new Map();
4
- const scopedNameByIdMap = /* @__PURE__ */ new Map();
5
- for (const identifier of occupiedIdentifiers) {
6
- freeIndexByPreferredName.set(identifier, 1);
7
- }
8
- const getName = (id, preferredName) => {
9
- const cachedName = scopedNameByIdMap.get(id);
10
- if (cachedName !== void 0) {
11
- return cachedName;
12
- }
13
- const index = freeIndexByPreferredName.get(preferredName);
14
- freeIndexByPreferredName.set(preferredName, (index ?? 0) + 1);
15
- let scopedName = preferredName;
16
- if (index !== void 0) {
17
- scopedName = `${preferredName}_${index}`;
18
- }
19
- scopedNameByIdMap.set(id, scopedName);
20
- return scopedName;
21
- };
22
- return {
23
- getName
24
- };
25
- };
package/lib/scope.test.js DELETED
@@ -1,15 +0,0 @@
1
- "use strict";
2
- import { expect, test } from "@jest/globals";
3
- import { createScope } from "./scope";
4
- test("use variable name for specific id and suffix on collision", () => {
5
- const scope = createScope();
6
- expect(scope.getName("1", "myName")).toEqual("myName");
7
- expect(scope.getName("2", "myName")).toEqual("myName_1");
8
- expect(scope.getName("1", "myName")).toEqual("myName");
9
- });
10
- test("allow to predefine already occupied identifiers", () => {
11
- const scope = createScope(["myName", "anotherName"]);
12
- expect(scope.getName("1", "myName")).toEqual("myName_1");
13
- expect(scope.getName("2", "anotherName")).toEqual("anotherName_1");
14
- expect(scope.getName("3", "newName")).toEqual("newName");
15
- });