@webstudio-is/sdk 0.275.0 → 0.276.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/core-templates.js +1 -1
- package/lib/index.js +304 -3
- package/lib/runtime.js +288 -1
- package/lib/schema-org.js +5703 -0
- package/lib/schema.js +1 -0
- package/lib/types/core-metas.d.ts +1 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/json-ld-utils.d.ts +3 -0
- package/lib/types/json-ld.d.ts +31 -0
- package/lib/types/runtime.d.ts +1 -0
- package/lib/types/schema/animation-schema.d.ts +41 -41
- package/lib/types/schema/assets.d.ts +54 -54
- package/lib/types/schema/component-meta.d.ts +43 -35
- package/lib/types/schema/data-sources.d.ts +3 -3
- package/lib/types/schema/deployment.d.ts +2 -2
- package/lib/types/schema/pages.d.ts +8 -6
- package/lib/types/schema/prop-meta.d.ts +34 -26
- package/lib/types/schema/props.d.ts +49 -49
- package/lib/types/schema/styles.d.ts +50 -50
- package/lib/types/schema/webstudio.d.ts +94 -94
- package/lib/types/scope.d.ts +3 -1
- package/package.json +18 -10
package/lib/runtime.js
CHANGED
|
@@ -149,6 +149,289 @@ var isBraveBrowser = () => {
|
|
|
149
149
|
return navigator.brave?.isBrave?.() === true || navigator.brave !== void 0;
|
|
150
150
|
};
|
|
151
151
|
|
|
152
|
+
// src/json-ld-utils.ts
|
|
153
|
+
var isJsonObject = (value) => typeof value === "object" && value !== null && Array.isArray(value) === false;
|
|
154
|
+
var appendJsonPath = (path, key) => typeof key === "number" ? `${path}[${key}]` : /^[A-Za-z_$][\w$]*$/.test(key) ? `${path}.${key}` : `${path}[${JSON.stringify(key)}]`;
|
|
155
|
+
var getJsonLdTypes = (value) => typeof value === "string" ? [value] : Array.isArray(value) && value.every((item) => typeof item === "string") ? value : [];
|
|
156
|
+
|
|
157
|
+
// src/json-ld.ts
|
|
158
|
+
var pushKeywordTypeError = (diagnostics, path, message) => {
|
|
159
|
+
diagnostics.push({
|
|
160
|
+
severity: "error",
|
|
161
|
+
code: "invalid-keyword-value",
|
|
162
|
+
path,
|
|
163
|
+
message
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
var escapeJsonLdScriptText = (value) => value.replace(/</g, "\\u003c");
|
|
167
|
+
var validateContextTermDefinition = (definition, path, diagnostics) => {
|
|
168
|
+
if (definition === null || typeof definition === "string" || isJsonObject(definition)) {
|
|
169
|
+
if (isJsonObject(definition) && definition["@context"] !== void 0) {
|
|
170
|
+
validateContext(
|
|
171
|
+
definition["@context"],
|
|
172
|
+
appendJsonPath(path, "@context"),
|
|
173
|
+
diagnostics
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
diagnostics.push({
|
|
179
|
+
severity: "error",
|
|
180
|
+
code: "invalid-context",
|
|
181
|
+
path,
|
|
182
|
+
message: "JSON-LD context terms must map to a string, object, or null."
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
var validateContext = (context, path, diagnostics) => {
|
|
186
|
+
if (context === null || typeof context === "string") {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (Array.isArray(context)) {
|
|
190
|
+
context.forEach(
|
|
191
|
+
(item, index) => validateContext(item, appendJsonPath(path, index), diagnostics)
|
|
192
|
+
);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (isJsonObject(context) === false) {
|
|
196
|
+
diagnostics.push({
|
|
197
|
+
severity: "error",
|
|
198
|
+
code: "invalid-context",
|
|
199
|
+
path,
|
|
200
|
+
message: "@context must be a string, object, array of contexts, or null."
|
|
201
|
+
});
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
for (const keyword of ["@base", "@vocab", "@language"]) {
|
|
205
|
+
if (context[keyword] !== void 0 && context[keyword] !== null && typeof context[keyword] !== "string") {
|
|
206
|
+
diagnostics.push({
|
|
207
|
+
severity: "error",
|
|
208
|
+
code: "invalid-context",
|
|
209
|
+
path: appendJsonPath(path, keyword),
|
|
210
|
+
message: `${keyword} must be a string or null.`
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (context["@direction"] !== void 0 && context["@direction"] !== null && context["@direction"] !== "ltr" && context["@direction"] !== "rtl") {
|
|
215
|
+
diagnostics.push({
|
|
216
|
+
severity: "error",
|
|
217
|
+
code: "invalid-context",
|
|
218
|
+
path: appendJsonPath(path, "@direction"),
|
|
219
|
+
message: '@direction must be "ltr", "rtl", or null.'
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (context["@propagate"] !== void 0 && typeof context["@propagate"] !== "boolean") {
|
|
223
|
+
diagnostics.push({
|
|
224
|
+
severity: "error",
|
|
225
|
+
code: "invalid-context",
|
|
226
|
+
path: appendJsonPath(path, "@propagate"),
|
|
227
|
+
message: "@propagate must be a boolean."
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
if (context["@version"] !== void 0 && context["@version"] !== 1.1) {
|
|
231
|
+
diagnostics.push({
|
|
232
|
+
severity: "error",
|
|
233
|
+
code: "invalid-context",
|
|
234
|
+
path: appendJsonPath(path, "@version"),
|
|
235
|
+
message: "@version must be 1.1."
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
for (const [term, definition] of Object.entries(context)) {
|
|
239
|
+
if (term.startsWith("@")) {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
validateContextTermDefinition(
|
|
243
|
+
definition,
|
|
244
|
+
appendJsonPath(path, term),
|
|
245
|
+
diagnostics
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
var validateNestedValues = (value, path, diagnostics) => {
|
|
250
|
+
if (isJsonObject(value)) {
|
|
251
|
+
validateNode(value, path, diagnostics);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
if (Array.isArray(value)) {
|
|
255
|
+
value.forEach((item, index) => {
|
|
256
|
+
if (isJsonObject(item) || Array.isArray(item)) {
|
|
257
|
+
validateNestedValues(item, appendJsonPath(path, index), diagnostics);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
var validateNode = (value, path, diagnostics) => {
|
|
263
|
+
if (Array.isArray(value)) {
|
|
264
|
+
value.forEach(
|
|
265
|
+
(item, index) => validateNode(item, appendJsonPath(path, index), diagnostics)
|
|
266
|
+
);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
if (isJsonObject(value) === false) {
|
|
270
|
+
diagnostics.push({
|
|
271
|
+
severity: "error",
|
|
272
|
+
code: "invalid-root",
|
|
273
|
+
path,
|
|
274
|
+
message: "JSON-LD nodes must be objects."
|
|
275
|
+
});
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (value["@context"] !== void 0) {
|
|
279
|
+
validateContext(
|
|
280
|
+
value["@context"],
|
|
281
|
+
appendJsonPath(path, "@context"),
|
|
282
|
+
diagnostics
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
const typeValue = value["@type"];
|
|
286
|
+
if (typeValue !== void 0 && (getJsonLdTypes(typeValue).length === 0 || Array.isArray(typeValue) && typeValue.length === 0)) {
|
|
287
|
+
pushKeywordTypeError(
|
|
288
|
+
diagnostics,
|
|
289
|
+
appendJsonPath(path, "@type"),
|
|
290
|
+
"@type must be a non-empty string or array of strings."
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
if (value["@id"] !== void 0 && typeof value["@id"] !== "string") {
|
|
294
|
+
pushKeywordTypeError(
|
|
295
|
+
diagnostics,
|
|
296
|
+
appendJsonPath(path, "@id"),
|
|
297
|
+
"@id must be a string."
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
if (value["@graph"] !== void 0 && isJsonObject(value["@graph"]) === false && Array.isArray(value["@graph"]) === false) {
|
|
301
|
+
pushKeywordTypeError(
|
|
302
|
+
diagnostics,
|
|
303
|
+
appendJsonPath(path, "@graph"),
|
|
304
|
+
"@graph must be an object or array of objects."
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
if (value["@language"] !== void 0 && value["@language"] !== null && typeof value["@language"] !== "string") {
|
|
308
|
+
pushKeywordTypeError(
|
|
309
|
+
diagnostics,
|
|
310
|
+
appendJsonPath(path, "@language"),
|
|
311
|
+
"@language must be a string or null."
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
if (value["@nest"] !== void 0 && isJsonObject(value["@nest"]) === false && (Array.isArray(value["@nest"]) === false || value["@nest"].every(isJsonObject) === false)) {
|
|
315
|
+
pushKeywordTypeError(
|
|
316
|
+
diagnostics,
|
|
317
|
+
appendJsonPath(path, "@nest"),
|
|
318
|
+
"@nest must be an object or array of objects."
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
if (value["@reverse"] !== void 0 && isJsonObject(value["@reverse"]) === false) {
|
|
322
|
+
pushKeywordTypeError(
|
|
323
|
+
diagnostics,
|
|
324
|
+
appendJsonPath(path, "@reverse"),
|
|
325
|
+
"@reverse must be an object."
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
for (const keyword of ["@index"]) {
|
|
329
|
+
if (value[keyword] !== void 0 && typeof value[keyword] !== "string") {
|
|
330
|
+
pushKeywordTypeError(
|
|
331
|
+
diagnostics,
|
|
332
|
+
appendJsonPath(path, keyword),
|
|
333
|
+
`${keyword} must be a string.`
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (value["@direction"] !== void 0 && value["@direction"] !== "ltr" && value["@direction"] !== "rtl" && value["@direction"] !== null) {
|
|
338
|
+
pushKeywordTypeError(
|
|
339
|
+
diagnostics,
|
|
340
|
+
appendJsonPath(path, "@direction"),
|
|
341
|
+
'@direction must be "ltr", "rtl", or null.'
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
if ("@value" in value) {
|
|
345
|
+
const invalidKeys = ["@id", "@graph", "@list", "@set", "@reverse"].filter(
|
|
346
|
+
(key) => key in value
|
|
347
|
+
);
|
|
348
|
+
const isJsonLiteral = value["@type"] === "@json";
|
|
349
|
+
const hasStructuredValue = typeof value["@value"] === "object" && value["@value"] !== null;
|
|
350
|
+
if (invalidKeys.length > 0 || hasStructuredValue && isJsonLiteral === false || "@type" in value && value["@type"] !== "@json" && ("@language" in value || "@direction" in value)) {
|
|
351
|
+
diagnostics.push({
|
|
352
|
+
severity: "error",
|
|
353
|
+
code: "invalid-value-object",
|
|
354
|
+
path,
|
|
355
|
+
message: "A JSON-LD value object has an incompatible keyword or @value shape."
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
for (const [property, propertyValue] of Object.entries(value)) {
|
|
360
|
+
const propertyPath = appendJsonPath(path, property);
|
|
361
|
+
if (property === "@context") {
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (["@graph", "@included", "@nest", "@reverse"].includes(property)) {
|
|
365
|
+
validateNode(propertyValue, propertyPath, diagnostics);
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (property.startsWith("@")) {
|
|
369
|
+
if (["@list", "@set"].includes(property)) {
|
|
370
|
+
validateNestedValues(propertyValue, propertyPath, diagnostics);
|
|
371
|
+
}
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
validateNestedValues(propertyValue, propertyPath, diagnostics);
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
var isJsonLdData = (value, ancestors) => {
|
|
378
|
+
if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
|
|
379
|
+
return true;
|
|
380
|
+
}
|
|
381
|
+
if (typeof value !== "object" || value === null || ancestors.has(value)) {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
const prototype = Object.getPrototypeOf(value);
|
|
385
|
+
if (Array.isArray(value) === false && prototype !== Object.prototype) {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
ancestors.add(value);
|
|
389
|
+
const isValid = Array.isArray(value) ? value.every((item) => isJsonLdData(item, ancestors)) : Object.values(value).every((item) => isJsonLdData(item, ancestors));
|
|
390
|
+
ancestors.delete(value);
|
|
391
|
+
return isValid;
|
|
392
|
+
};
|
|
393
|
+
var isJsonLdValue = (value) => (Array.isArray(value) || isJsonObject(value)) && isJsonLdData(value, /* @__PURE__ */ new Set());
|
|
394
|
+
var parseJsonLd = (input) => {
|
|
395
|
+
try {
|
|
396
|
+
const value = typeof input === "string" ? JSON.parse(input) : input;
|
|
397
|
+
if (isJsonLdValue(value)) {
|
|
398
|
+
return { success: true, value };
|
|
399
|
+
}
|
|
400
|
+
} catch {
|
|
401
|
+
}
|
|
402
|
+
return { success: false };
|
|
403
|
+
};
|
|
404
|
+
var validateJsonLd = (input) => {
|
|
405
|
+
const parsed = parseJsonLd(input);
|
|
406
|
+
if (parsed.success === false) {
|
|
407
|
+
return {
|
|
408
|
+
success: false,
|
|
409
|
+
diagnostics: [
|
|
410
|
+
{
|
|
411
|
+
severity: "error",
|
|
412
|
+
code: typeof input === "string" ? "invalid-json" : "invalid-root",
|
|
413
|
+
path: "$",
|
|
414
|
+
message: "JSON-LD must be a valid JSON object or array."
|
|
415
|
+
}
|
|
416
|
+
]
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
const diagnostics = [];
|
|
420
|
+
validateNode(parsed.value, "$", diagnostics);
|
|
421
|
+
if (diagnostics.length > 0) {
|
|
422
|
+
return { success: false, value: parsed.value, diagnostics };
|
|
423
|
+
}
|
|
424
|
+
return { success: true, value: parsed.value, diagnostics };
|
|
425
|
+
};
|
|
426
|
+
var hasTopLevelJsonLdContext = (value) => {
|
|
427
|
+
if (Array.isArray(value)) {
|
|
428
|
+
return value.some(
|
|
429
|
+
(item) => typeof item === "object" && item !== null && "@context" in item
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
return "@context" in value;
|
|
433
|
+
};
|
|
434
|
+
|
|
152
435
|
// src/runtime.ts
|
|
153
436
|
var tagProperty = "data-ws-tag";
|
|
154
437
|
var getTagFromProps = (props) => {
|
|
@@ -166,17 +449,21 @@ export {
|
|
|
166
449
|
cachedFetch,
|
|
167
450
|
createJsonStringifyProxy,
|
|
168
451
|
currentDateResourceUrl,
|
|
452
|
+
escapeJsonLdScriptText,
|
|
169
453
|
formBotFieldName,
|
|
170
454
|
formIdFieldName,
|
|
171
455
|
getIndexWithinAncestorFromProps,
|
|
172
456
|
getTagFromProps,
|
|
457
|
+
hasTopLevelJsonLdContext,
|
|
173
458
|
indexProperty,
|
|
174
459
|
isBraveBrowser,
|
|
175
460
|
isLocalResource,
|
|
176
461
|
isPlainObject,
|
|
177
462
|
loadResource,
|
|
178
463
|
loadResources,
|
|
464
|
+
parseJsonLd,
|
|
179
465
|
serializeValue,
|
|
180
466
|
sitemapResourceUrl,
|
|
181
|
-
tagProperty
|
|
467
|
+
tagProperty,
|
|
468
|
+
validateJsonLd
|
|
182
469
|
};
|