@valbuild/shared 0.151.0 → 0.152.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/CHANGELOG.md +32 -0
- package/dist/declarations/src/internal/ApiRoutes.d.ts +17 -0
- package/dist/declarations/src/internal/aiTools/toolNames.d.ts +1 -1
- package/dist/declarations/src/internal/sketchpad/sketchFormat.d.ts +41 -6
- package/internal/dist/valbuild-shared-internal.cjs.dev.js +146 -15
- package/internal/dist/valbuild-shared-internal.cjs.prod.js +146 -15
- package/internal/dist/valbuild-shared-internal.esm.js +144 -16
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @valbuild/shared
|
|
2
2
|
|
|
3
|
+
## 0.152.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#1015](https://github.com/valbuild/val/pull/1015) [`08a3977`](https://github.com/valbuild/val/commit/08a39779dbe43702a72ae57cbf8cf29b14e64672) Thanks [@freekh](https://github.com/freekh)! - The Sketchpad covers several pages, builds what it shows, and can be linked to the content.
|
|
8
|
+
|
|
9
|
+
- **Route dividers.** A sketchpad is no longer about one page. A `--- /about` line starts the part about a page, so one sketch can cover a page and the pages it links to. Press a route to see that page beside the sketch, in the Studio's own live preview, which follows edits as they are made. A divider's menu changes its page, or adds a new one from a page type the site has (`/blog/[slug]`). A route the site has no page type for is allowed too, and is marked as needing code.
|
|
10
|
+
- **Start from a page.** An empty sketchpad offers to start from a page. The assistant writes that page into it, images and all, and changes nothing.
|
|
11
|
+
- **Build.** The button that sent the sketchpad to the assistant is now **Build**. It sends the sketchpad as a card in the chat (press it to open the sketchpad), with a request to change the pages to match the sketch. It is disabled while the sketch is empty.
|
|
12
|
+
- **Images that exist.** A box shows an image from a gallery, from the site's content, or one uploaded to the chat, and the picker offers exactly those, with search and Upload (which puts the file in the chat first). A box naming any other image says so. When the assistant writes a sketch with an image that is not in the project, the write is refused. Images are named by their content path (`/public/val/hero.webp`) and shown where the site serves them, including uploads that are not published yet.
|
|
13
|
+
- **Block types.** A box's kind is a combobox of the kinds of section the site's pages have, read from the schema. Any other word is allowed, and is marked as a new type that needs code.
|
|
14
|
+
- **Drag.** Blocks, rows, columns and images can be dragged to a new place. Columns share a row equally, so the width controls are gone.
|
|
15
|
+
- **Highlights.** The assistant can point at blocks, in a colour and with a note (for example, the ones that need code), with `highlight_sketchpad_blocks`. The highlights can be cleared, by the person or by the assistant.
|
|
16
|
+
- **Linked text (a try-out).** A heading or paragraph can be linked to a plain text field with `{field: <source path>}`. Typing in it then changes that field, as typing in the field would. The block shows what it is linked to and has an **Unlink** button. When the field was changed elsewhere, the block says so and offers the field's text. A sketchpad the assistant starts from a page links its text this way.
|
|
17
|
+
- **Converting images.** The assistant can convert an image in the chat to WebP, or scale it down, with `convert_session_image`, using the same encoder as the Studio's uploads.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#1013](https://github.com/valbuild/val/pull/1013) [`3bb76d7`](https://github.com/valbuild/val/commit/3bb76d74d82b499aa15023838d63018a70fd7ce7) Thanks [@freekh](https://github.com/freekh)! - A save that the content service fails to take no longer looks like a successful one.
|
|
22
|
+
|
|
23
|
+
Before, when the content service answered a save with a server error (or could not be reached), the Studio treated the edit as invalid and dropped it: the field went back to its old value, and the status bar kept saying "All changes saved". Now:
|
|
24
|
+
|
|
25
|
+
- **Your edit is kept.** The field keeps what you typed.
|
|
26
|
+
- **The Studio says the save failed.** The status bar shows "Could not save" (never "All changes saved" while a save has failed or is still pending), and a notice says which service failed, with the service's own message under **Details**.
|
|
27
|
+
- **Try again** sends the same save again. The Studio also retries by itself in the background, so if you leave the tab open your changes are saved once the service is back.
|
|
28
|
+
|
|
29
|
+
Pressing Publish while a save has failed now says what failed, in the service's words, with a **Save again** button, instead of "Check the connection and try again".
|
|
30
|
+
|
|
31
|
+
Saves that the service refuses because of your plan, and saves that conflict with someone else's change, work as before.
|
|
32
|
+
|
|
33
|
+
Error messages from the content service also stop blaming your network. "Could not get your changes. It is most likely due to a network issue. Check your network connection" was shown even when the service had answered with a 500. These messages now say what actually happened (the service answered with an error, refused the request, or could not be reached from your site's server) and name the service. The status code and the service's response are kept as details for whoever needs to look into it. Publish failures now also show the service's own message, where they used to say "Unknown error".
|
|
34
|
+
|
|
3
35
|
## 0.151.0
|
|
4
36
|
|
|
5
37
|
### Patch Changes
|
|
@@ -1265,6 +1265,22 @@ export declare const Api: {
|
|
|
1265
1265
|
}, z.core.$strip>]>;
|
|
1266
1266
|
headVersion: z.ZodOptional<z.ZodNumber>;
|
|
1267
1267
|
}, z.core.$strip>;
|
|
1268
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1269
|
+
status: z.ZodLiteral<502>;
|
|
1270
|
+
json: z.ZodObject<{
|
|
1271
|
+
type: z.ZodLiteral<"service-error">;
|
|
1272
|
+
message: z.ZodString;
|
|
1273
|
+
details: z.ZodOptional<z.ZodString>;
|
|
1274
|
+
newPatchIds: z.ZodArray<z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>>;
|
|
1275
|
+
parentRef: z.ZodUnion<readonly [z.ZodObject<{
|
|
1276
|
+
type: z.ZodLiteral<"head">;
|
|
1277
|
+
headBaseSha: z.ZodString;
|
|
1278
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1279
|
+
type: z.ZodLiteral<"patch">;
|
|
1280
|
+
patchId: z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>;
|
|
1281
|
+
}, z.core.$strip>]>;
|
|
1282
|
+
headVersion: z.ZodOptional<z.ZodNumber>;
|
|
1283
|
+
}, z.core.$strip>;
|
|
1268
1284
|
}, z.core.$strip>, z.ZodObject<{
|
|
1269
1285
|
status: z.ZodLiteral<200>;
|
|
1270
1286
|
json: z.ZodObject<{
|
|
@@ -1315,6 +1331,7 @@ export declare const Api: {
|
|
|
1315
1331
|
error: z.ZodObject<{
|
|
1316
1332
|
message: z.ZodString;
|
|
1317
1333
|
}, z.core.$strip>;
|
|
1334
|
+
details: z.ZodOptional<z.ZodString>;
|
|
1318
1335
|
}, z.core.$strip>;
|
|
1319
1336
|
}, z.core.$strip>, z.ZodObject<{
|
|
1320
1337
|
status: z.ZodLiteral<200>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const toolNames: readonly ["get_all_schema", "get_source", "search_content", "validate_content", "create_patch", "add_session_image_to_gallery", "remove_image_gallery_entry", "navigate_to", "get_current_context", "get_patches", "get_source_path_from_route", "set_session_name", "show_compare_view", "ask_user_question", "duplicate_source", "empty_at_path", "count_entries", "get_record_keys", "list_sketchpads", "create_sketchpad", "read_sketchpad", "write_sketchpad"];
|
|
1
|
+
export declare const toolNames: readonly ["get_all_schema", "get_source", "search_content", "validate_content", "create_patch", "add_session_image_to_gallery", "remove_image_gallery_entry", "convert_session_image", "navigate_to", "get_current_context", "get_patches", "get_source_path_from_route", "set_session_name", "show_compare_view", "ask_user_question", "duplicate_source", "empty_at_path", "count_entries", "get_record_keys", "list_sketchpads", "create_sketchpad", "read_sketchpad", "write_sketchpad", "highlight_sketchpad_blocks", "clear_sketchpad_highlights"];
|
|
2
2
|
export type ToolName = (typeof toolNames)[number];
|
|
@@ -2,18 +2,24 @@
|
|
|
2
2
|
* A page sketch: a page written as indented text, with four primitives.
|
|
3
3
|
*
|
|
4
4
|
* ```
|
|
5
|
+
* --- /about a route: what follows is the page at /about
|
|
5
6
|
* # Our people text (a heading: #, ## or ###)
|
|
6
7
|
* We are 40 people in Oslo. text (a paragraph)
|
|
8
|
+
* ## Hi {field: /x.val.ts?p="t"} text linked to a content field: typing
|
|
9
|
+
* in it writes the field
|
|
7
10
|
* [image: Team photo] placeholder: [kind] or [kind: label]
|
|
8
11
|
* [hero: Roof](image: /a.jpg) a placeholder with an image (or video) in it
|
|
9
12
|
* icon hero M3 5h18v14H3z how every [hero] box is drawn: SVG path data
|
|
10
13
|
* row its children side by side
|
|
11
|
-
* col
|
|
12
|
-
* ## Design
|
|
14
|
+
* col its children stacked; columns share a row
|
|
15
|
+
* ## Design equally
|
|
13
16
|
* col
|
|
14
17
|
* [button: Join us]
|
|
15
18
|
* ```
|
|
16
19
|
*
|
|
20
|
+
* A sketchpad is not one page's: a route divider starts the part about a
|
|
21
|
+
* page, so one sketch can cover a page and the two it links to.
|
|
22
|
+
*
|
|
17
23
|
* It is a scratch pad, not a layout language: it says WHAT is on a page and
|
|
18
24
|
* roughly WHERE, so an assistant and a person can agree on a page's content
|
|
19
25
|
* before anyone worries about how it looks. The person never sees this text,
|
|
@@ -31,17 +37,23 @@
|
|
|
31
37
|
* image. Media put in a box is written into the text too, so the assistant
|
|
32
38
|
* that builds the page reads it exactly as the person left it.
|
|
33
39
|
*/
|
|
34
|
-
export type SketchNode = SketchRow | SketchCol | SketchText | SketchPlaceholder;
|
|
40
|
+
export type SketchNode = SketchRoute | SketchRow | SketchCol | SketchText | SketchPlaceholder;
|
|
41
|
+
/** The start of the part about one page. Only at the top level. */
|
|
42
|
+
export type SketchRoute = {
|
|
43
|
+
type: "route";
|
|
44
|
+
line: number;
|
|
45
|
+
/** The page's route as the site serves it: `/about`, `/blog/[slug]`. */
|
|
46
|
+
route: string;
|
|
47
|
+
};
|
|
35
48
|
export type SketchRow = {
|
|
36
49
|
type: "row";
|
|
37
50
|
line: number;
|
|
38
51
|
children: SketchNode[];
|
|
39
52
|
};
|
|
53
|
+
/** Columns share their row equally: a sketch says what, not how wide. */
|
|
40
54
|
export type SketchCol = {
|
|
41
55
|
type: "col";
|
|
42
56
|
line: number;
|
|
43
|
-
/** Shares of the enclosing row this column takes. */
|
|
44
|
-
weight: number;
|
|
45
57
|
children: SketchNode[];
|
|
46
58
|
};
|
|
47
59
|
export type SketchText = {
|
|
@@ -50,6 +62,13 @@ export type SketchText = {
|
|
|
50
62
|
/** 0 is a paragraph; 1-3 are headings. */
|
|
51
63
|
level: 0 | 1 | 2 | 3;
|
|
52
64
|
text: string;
|
|
65
|
+
/**
|
|
66
|
+
* The content field this text is linked to, as a source path
|
|
67
|
+
* (`/content/home.val.ts?p="hero"."title"`): typing in the block writes
|
|
68
|
+
* the field. Written `{field: <source path>}` at the end of the line. One
|
|
69
|
+
* block per field: a second link to the same field is not one.
|
|
70
|
+
*/
|
|
71
|
+
field?: string;
|
|
53
72
|
};
|
|
54
73
|
export type SketchPlaceholder = {
|
|
55
74
|
type: "placeholder";
|
|
@@ -58,10 +77,18 @@ export type SketchPlaceholder = {
|
|
|
58
77
|
label: string | null;
|
|
59
78
|
media: SketchMedia | null;
|
|
60
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* `src` names a file the project has, never a guess: its `path` exactly as
|
|
82
|
+
* the content has it (`/public/val/hero.webp`, or its remote URL), or an
|
|
83
|
+
* image uploaded to the assistant's session, `session:<key>`. Which files
|
|
84
|
+
* those are is the Studio's to check; the text only holds the name.
|
|
85
|
+
*/
|
|
61
86
|
export type SketchMedia = {
|
|
62
87
|
type: "image" | "video";
|
|
63
88
|
src: string;
|
|
64
89
|
};
|
|
90
|
+
/** The prefix of a `src` that is an image in the assistant's session. */
|
|
91
|
+
export declare const SESSION_MEDIA_PREFIX = "session:";
|
|
65
92
|
export type SketchError = {
|
|
66
93
|
/** 1-based, like an editor's gutter. */
|
|
67
94
|
line: number;
|
|
@@ -82,7 +109,7 @@ export declare function parseSketch(source: string): ParsedSketch;
|
|
|
82
109
|
* The line a text block is written as. Line breaks become spaces, and a
|
|
83
110
|
* paragraph that would read as something else is kept as text with `\`.
|
|
84
111
|
*/
|
|
85
|
-
export declare function formatSketchText(level: SketchText["level"], text: string): string;
|
|
112
|
+
export declare function formatSketchText(level: SketchText["level"], text: string, field?: string): string;
|
|
86
113
|
/** The line a placeholder is written as. */
|
|
87
114
|
export declare function formatSketchBox(placeholder: Pick<SketchPlaceholder, "kind" | "label" | "media">): string;
|
|
88
115
|
/**
|
|
@@ -95,6 +122,14 @@ export declare function formatSketchBox(placeholder: Pick<SketchPlaceholder, "ki
|
|
|
95
122
|
* it is not on the page.
|
|
96
123
|
*/
|
|
97
124
|
export declare function formatSketch(blocks: SketchNode[], icons: Record<string, string>): string;
|
|
125
|
+
/**
|
|
126
|
+
* The text of every block linked to a field, by field: what the Studio
|
|
127
|
+
* writes to the content when a linked block changes. The first block wins,
|
|
128
|
+
* as `formatSketch` keeps only its link.
|
|
129
|
+
*/
|
|
130
|
+
export declare function sketchFieldTexts(blocks: SketchNode[]): Map<string, string>;
|
|
131
|
+
/** The pages a sketch is about, in the order it gives them. */
|
|
132
|
+
export declare function sketchRoutes(blocks: SketchNode[]): string[];
|
|
98
133
|
/**
|
|
99
134
|
* What a list names a sketch by: its first top-level heading, the biggest
|
|
100
135
|
* one first. Null for a sketch with no heading, which a list then names by
|
|
@@ -3086,6 +3086,26 @@ var Api = {
|
|
|
3086
3086
|
parentRef: ParentRef,
|
|
3087
3087
|
headVersion: zod.z.number().optional()
|
|
3088
3088
|
})
|
|
3089
|
+
}),
|
|
3090
|
+
/*
|
|
3091
|
+
* The content service failed to take a patch: it answered with a
|
|
3092
|
+
* server error, or could not be reached. Not the 400 above either,
|
|
3093
|
+
* because the patches are fine -- the Studio keeps them and offers
|
|
3094
|
+
* to send them again. `message` is for the editor and `details` (the
|
|
3095
|
+
* status line and the service's own words) for whoever they ask.
|
|
3096
|
+
*
|
|
3097
|
+
* As with the 403, the patches BEFORE the failed one were saved.
|
|
3098
|
+
*/
|
|
3099
|
+
zod.z.object({
|
|
3100
|
+
status: zod.z.literal(502),
|
|
3101
|
+
json: zod.z.object({
|
|
3102
|
+
type: zod.z.literal("service-error"),
|
|
3103
|
+
message: zod.z.string(),
|
|
3104
|
+
details: zod.z.string().optional(),
|
|
3105
|
+
newPatchIds: zod.z.array(PatchId),
|
|
3106
|
+
parentRef: ParentRef,
|
|
3107
|
+
headVersion: zod.z.number().optional()
|
|
3108
|
+
})
|
|
3089
3109
|
}), zod.z.object({
|
|
3090
3110
|
status: zod.z.literal(200),
|
|
3091
3111
|
json: zod.z.object({
|
|
@@ -3121,7 +3141,9 @@ var Api = {
|
|
|
3121
3141
|
status: zod.z.literal(500),
|
|
3122
3142
|
json: zod.z.object({
|
|
3123
3143
|
message: zod.z.string(),
|
|
3124
|
-
error: GenericError
|
|
3144
|
+
error: GenericError,
|
|
3145
|
+
/** What the content service said: its status line and words. */
|
|
3146
|
+
details: zod.z.string().optional()
|
|
3125
3147
|
})
|
|
3126
3148
|
}), zod.z.object({
|
|
3127
3149
|
status: zod.z.literal(200),
|
|
@@ -8239,24 +8261,30 @@ function emptyRecord(schema, context) {
|
|
|
8239
8261
|
}));
|
|
8240
8262
|
}
|
|
8241
8263
|
|
|
8242
|
-
var toolNames = ["get_all_schema", "get_source", "search_content", "validate_content", "create_patch", "add_session_image_to_gallery", "remove_image_gallery_entry", "navigate_to", "get_current_context", "get_patches", "get_source_path_from_route", "set_session_name", "show_compare_view", "ask_user_question", "duplicate_source", "empty_at_path", "count_entries", "get_record_keys", "list_sketchpads", "create_sketchpad", "read_sketchpad", "write_sketchpad"];
|
|
8264
|
+
var toolNames = ["get_all_schema", "get_source", "search_content", "validate_content", "create_patch", "add_session_image_to_gallery", "remove_image_gallery_entry", "convert_session_image", "navigate_to", "get_current_context", "get_patches", "get_source_path_from_route", "set_session_name", "show_compare_view", "ask_user_question", "duplicate_source", "empty_at_path", "count_entries", "get_record_keys", "list_sketchpads", "create_sketchpad", "read_sketchpad", "write_sketchpad", "highlight_sketchpad_blocks", "clear_sketchpad_highlights"];
|
|
8243
8265
|
|
|
8244
8266
|
/**
|
|
8245
8267
|
* A page sketch: a page written as indented text, with four primitives.
|
|
8246
8268
|
*
|
|
8247
8269
|
* ```
|
|
8270
|
+
* --- /about a route: what follows is the page at /about
|
|
8248
8271
|
* # Our people text (a heading: #, ## or ###)
|
|
8249
8272
|
* We are 40 people in Oslo. text (a paragraph)
|
|
8273
|
+
* ## Hi {field: /x.val.ts?p="t"} text linked to a content field: typing
|
|
8274
|
+
* in it writes the field
|
|
8250
8275
|
* [image: Team photo] placeholder: [kind] or [kind: label]
|
|
8251
8276
|
* [hero: Roof](image: /a.jpg) a placeholder with an image (or video) in it
|
|
8252
8277
|
* icon hero M3 5h18v14H3z how every [hero] box is drawn: SVG path data
|
|
8253
8278
|
* row its children side by side
|
|
8254
|
-
* col
|
|
8255
|
-
* ## Design
|
|
8279
|
+
* col its children stacked; columns share a row
|
|
8280
|
+
* ## Design equally
|
|
8256
8281
|
* col
|
|
8257
8282
|
* [button: Join us]
|
|
8258
8283
|
* ```
|
|
8259
8284
|
*
|
|
8285
|
+
* A sketchpad is not one page's: a route divider starts the part about a
|
|
8286
|
+
* page, so one sketch can cover a page and the two it links to.
|
|
8287
|
+
*
|
|
8260
8288
|
* It is a scratch pad, not a layout language: it says WHAT is on a page and
|
|
8261
8289
|
* roughly WHERE, so an assistant and a person can agree on a page's content
|
|
8262
8290
|
* before anyone worries about how it looks. The person never sees this text,
|
|
@@ -8275,7 +8303,21 @@ var toolNames = ["get_all_schema", "get_source", "search_content", "validate_con
|
|
|
8275
8303
|
* that builds the page reads it exactly as the person left it.
|
|
8276
8304
|
*/
|
|
8277
8305
|
|
|
8306
|
+
/** The start of the part about one page. Only at the top level. */
|
|
8307
|
+
|
|
8308
|
+
/** Columns share their row equally: a sketch says what, not how wide. */
|
|
8309
|
+
|
|
8310
|
+
/**
|
|
8311
|
+
* `src` names a file the project has, never a guess: its `path` exactly as
|
|
8312
|
+
* the content has it (`/public/val/hero.webp`, or its remote URL), or an
|
|
8313
|
+
* image uploaded to the assistant's session, `session:<key>`. Which files
|
|
8314
|
+
* those are is the Studio's to check; the text only holds the name.
|
|
8315
|
+
*/
|
|
8316
|
+
|
|
8317
|
+
/** The prefix of a `src` that is an image in the assistant's session. */
|
|
8318
|
+
var SESSION_MEDIA_PREFIX = "session:";
|
|
8278
8319
|
var CONTAINER = /^(row|col)(?:\s+(\d+))?$/;
|
|
8320
|
+
var ROUTE = /^---(?:\s+(.*))?$/;
|
|
8279
8321
|
var PLACEHOLDER = /^\[([^\]:]*)(?::([^\]]*))?\](?:\((image|video):\s*([^\s)]+)\s*\))?$/;
|
|
8280
8322
|
var HAS_MEDIA = /^\[[^\]]*\]\(/;
|
|
8281
8323
|
var ICON = /^icon\s+(\S+)\s+([Mm][\d\s.-].*)$/;
|
|
@@ -8318,6 +8360,32 @@ function parseSketch(source) {
|
|
|
8318
8360
|
while (stack.length > 1 && indent <= stack[stack.length - 1].indent) {
|
|
8319
8361
|
stack.pop();
|
|
8320
8362
|
}
|
|
8363
|
+
var route = ROUTE.exec(content);
|
|
8364
|
+
if (route) {
|
|
8365
|
+
var _route$;
|
|
8366
|
+
var _path = ((_route$ = route[1]) !== null && _route$ !== void 0 ? _route$ : "").trim();
|
|
8367
|
+
if (!_path.startsWith("/") || /\s/.test(_path)) {
|
|
8368
|
+
errors.push({
|
|
8369
|
+
line: line,
|
|
8370
|
+
message: 'A route divider names one page by its route, like "--- /about".'
|
|
8371
|
+
});
|
|
8372
|
+
}
|
|
8373
|
+
if (indent > 0) {
|
|
8374
|
+
errors.push({
|
|
8375
|
+
line: line,
|
|
8376
|
+
message: "A route divider starts a page, so it goes at the top level, not indented."
|
|
8377
|
+
});
|
|
8378
|
+
}
|
|
8379
|
+
// It closes everything open: what follows is another page.
|
|
8380
|
+
stack.length = 1;
|
|
8381
|
+
stack[0].lastIndent = 0;
|
|
8382
|
+
blocks.push({
|
|
8383
|
+
type: "route",
|
|
8384
|
+
line: line,
|
|
8385
|
+
route: _path
|
|
8386
|
+
});
|
|
8387
|
+
return;
|
|
8388
|
+
}
|
|
8321
8389
|
var parent = stack[stack.length - 1];
|
|
8322
8390
|
var node = parseContent(content, line, errors);
|
|
8323
8391
|
|
|
@@ -8359,7 +8427,27 @@ function parseSketch(source) {
|
|
|
8359
8427
|
errors: errors
|
|
8360
8428
|
};
|
|
8361
8429
|
}
|
|
8362
|
-
|
|
8430
|
+
|
|
8431
|
+
/** The link to a content field at the end of a text line. */
|
|
8432
|
+
var FIELD = / \{field: (\/[^{}]*)\}$/;
|
|
8433
|
+
function parseContent(whole, line, errors) {
|
|
8434
|
+
var link = FIELD.exec(whole);
|
|
8435
|
+
if (link) {
|
|
8436
|
+
var node = parseLine(whole.slice(0, link.index), line, errors);
|
|
8437
|
+
if (node.type !== "text") {
|
|
8438
|
+
errors.push({
|
|
8439
|
+
line: line,
|
|
8440
|
+
message: "Only a heading or a paragraph is linked to a field: put {field: ...} at the end of one."
|
|
8441
|
+
});
|
|
8442
|
+
return node;
|
|
8443
|
+
}
|
|
8444
|
+
return createForOfIteratorHelper._objectSpread2(createForOfIteratorHelper._objectSpread2({}, node), {}, {
|
|
8445
|
+
field: link[1].trim()
|
|
8446
|
+
});
|
|
8447
|
+
}
|
|
8448
|
+
return parseLine(whole, line, errors);
|
|
8449
|
+
}
|
|
8450
|
+
function parseLine(content, line, errors) {
|
|
8363
8451
|
// A leading backslash keeps a line that looks like a keyword as text.
|
|
8364
8452
|
if (content.startsWith("\\")) {
|
|
8365
8453
|
return {
|
|
@@ -8384,17 +8472,15 @@ function parseContent(content, line, errors) {
|
|
|
8384
8472
|
children: []
|
|
8385
8473
|
};
|
|
8386
8474
|
}
|
|
8387
|
-
|
|
8388
|
-
if (weight === 0) {
|
|
8475
|
+
if (container[2] !== undefined) {
|
|
8389
8476
|
errors.push({
|
|
8390
8477
|
line: line,
|
|
8391
|
-
message:
|
|
8478
|
+
message: 'Columns share a row equally, so a col takes no number: write "col".'
|
|
8392
8479
|
});
|
|
8393
8480
|
}
|
|
8394
8481
|
return {
|
|
8395
8482
|
type: "col",
|
|
8396
8483
|
line: line,
|
|
8397
|
-
weight: Math.max(weight, 1),
|
|
8398
8484
|
children: []
|
|
8399
8485
|
};
|
|
8400
8486
|
}
|
|
@@ -8468,13 +8554,19 @@ function parseContent(content, line, errors) {
|
|
|
8468
8554
|
* The line a text block is written as. Line breaks become spaces, and a
|
|
8469
8555
|
* paragraph that would read as something else is kept as text with `\`.
|
|
8470
8556
|
*/
|
|
8471
|
-
function formatSketchText(level, text) {
|
|
8557
|
+
function formatSketchText(level, text, field) {
|
|
8472
8558
|
var flat = text.replace(/\s+/g, " ").trim();
|
|
8559
|
+
var path = field === null || field === void 0 ? void 0 : field.replace(/\s+/g, " ").trim();
|
|
8560
|
+
// A source path, and one the line can be read back with: no braces.
|
|
8561
|
+
var link = path && /^\/[^{}]*$/.test(path) ? " {field: ".concat(path, "}") : "";
|
|
8473
8562
|
if (level > 0) {
|
|
8474
|
-
return "#".repeat(level) + " " + flat;
|
|
8563
|
+
return "#".repeat(level) + " " + flat + link;
|
|
8475
8564
|
}
|
|
8476
|
-
|
|
8477
|
-
|
|
8565
|
+
// Read as the whole line will be, link and all: `icon x M` is text, and
|
|
8566
|
+
// `icon x M {field: ...}` would be an icon.
|
|
8567
|
+
var whole = flat + link;
|
|
8568
|
+
var ambiguous = flat.startsWith("\\") || flat.startsWith("[") || CONTAINER.test(whole) || ROUTE.test(whole) || HEADING.test(whole) || ICON.test(whole);
|
|
8569
|
+
return (ambiguous ? "\\" + flat : flat) + link;
|
|
8478
8570
|
}
|
|
8479
8571
|
|
|
8480
8572
|
/** The line a placeholder is written as. */
|
|
@@ -8499,17 +8591,26 @@ function formatSketchBox(placeholder) {
|
|
|
8499
8591
|
*/
|
|
8500
8592
|
function formatSketch(blocks, icons) {
|
|
8501
8593
|
var lines = [];
|
|
8594
|
+
// One block per field: the first keeps the link.
|
|
8595
|
+
var linked = new Set();
|
|
8502
8596
|
var _walk = function walk(node, depth, inRow) {
|
|
8503
8597
|
var indent = " ".repeat(depth);
|
|
8504
8598
|
switch (node.type) {
|
|
8505
8599
|
case "text":
|
|
8506
8600
|
if (node.text) {
|
|
8507
|
-
|
|
8601
|
+
var field = node.field && !linked.has(node.field) ? node.field : undefined;
|
|
8602
|
+
if (field) {
|
|
8603
|
+
linked.add(field);
|
|
8604
|
+
}
|
|
8605
|
+
lines.push(indent + formatSketchText(node.level, node.text, field));
|
|
8508
8606
|
}
|
|
8509
8607
|
return;
|
|
8510
8608
|
case "placeholder":
|
|
8511
8609
|
lines.push(indent + formatSketchBox(node));
|
|
8512
8610
|
return;
|
|
8611
|
+
case "route":
|
|
8612
|
+
lines.push("--- ".concat(node.route));
|
|
8613
|
+
return;
|
|
8513
8614
|
case "row":
|
|
8514
8615
|
lines.push(indent + "row");
|
|
8515
8616
|
if (node.children.length === 0) {
|
|
@@ -8526,7 +8627,7 @@ function formatSketch(blocks, icons) {
|
|
|
8526
8627
|
});
|
|
8527
8628
|
return;
|
|
8528
8629
|
}
|
|
8529
|
-
lines.push(indent +
|
|
8630
|
+
lines.push(indent + "col");
|
|
8530
8631
|
node.children.forEach(function (child) {
|
|
8531
8632
|
return _walk(child, depth + 1, false);
|
|
8532
8633
|
});
|
|
@@ -8546,6 +8647,33 @@ function formatSketch(blocks, icons) {
|
|
|
8546
8647
|
return all.length > 0 ? all.join("\n") + "\n" : "";
|
|
8547
8648
|
}
|
|
8548
8649
|
|
|
8650
|
+
/**
|
|
8651
|
+
* The text of every block linked to a field, by field: what the Studio
|
|
8652
|
+
* writes to the content when a linked block changes. The first block wins,
|
|
8653
|
+
* as `formatSketch` keeps only its link.
|
|
8654
|
+
*/
|
|
8655
|
+
function sketchFieldTexts(blocks) {
|
|
8656
|
+
var texts = new Map();
|
|
8657
|
+
var _walk2 = function walk(node) {
|
|
8658
|
+
if (node.type === "text") {
|
|
8659
|
+
if (node.field && node.text && !texts.has(node.field)) {
|
|
8660
|
+
texts.set(node.field, node.text.replace(/\s+/g, " ").trim());
|
|
8661
|
+
}
|
|
8662
|
+
} else if (node.type === "row" || node.type === "col") {
|
|
8663
|
+
node.children.forEach(_walk2);
|
|
8664
|
+
}
|
|
8665
|
+
};
|
|
8666
|
+
blocks.forEach(_walk2);
|
|
8667
|
+
return texts;
|
|
8668
|
+
}
|
|
8669
|
+
|
|
8670
|
+
/** The pages a sketch is about, in the order it gives them. */
|
|
8671
|
+
function sketchRoutes(blocks) {
|
|
8672
|
+
return blocks.flatMap(function (block) {
|
|
8673
|
+
return block.type === "route" && block.route !== "" ? [block.route] : [];
|
|
8674
|
+
});
|
|
8675
|
+
}
|
|
8676
|
+
|
|
8549
8677
|
/**
|
|
8550
8678
|
* What a list names a sketch by: its first top-level heading, the biggest
|
|
8551
8679
|
* one first. Null for a sketch with no heading, which a list then names by
|
|
@@ -11829,6 +11957,7 @@ exports.RestoreVerdict = RestoreVerdict;
|
|
|
11829
11957
|
exports.RichTextOptions = RichTextOptions;
|
|
11830
11958
|
exports.SCHEMA_SOURCE_FIXES = SCHEMA_SOURCE_FIXES;
|
|
11831
11959
|
exports.SELF_CHECK_VERSION = SELF_CHECK_VERSION;
|
|
11960
|
+
exports.SESSION_MEDIA_PREFIX = SESSION_MEDIA_PREFIX;
|
|
11832
11961
|
exports.SKETCHPAD_MAX_TEXT_LENGTH = SKETCHPAD_MAX_TEXT_LENGTH;
|
|
11833
11962
|
exports.STAGED_SCHEMA_PREFIX = STAGED_SCHEMA_PREFIX;
|
|
11834
11963
|
exports.STUDIO_FIXES = STUDIO_FIXES;
|
|
@@ -11980,6 +12109,8 @@ exports.selfCheck = selfCheck;
|
|
|
11980
12109
|
exports.shouldEncodeWithWasm = shouldEncodeWithWasm;
|
|
11981
12110
|
exports.sideFiles = sideFiles;
|
|
11982
12111
|
exports.sideSource = sideSource;
|
|
12112
|
+
exports.sketchFieldTexts = sketchFieldTexts;
|
|
12113
|
+
exports.sketchRoutes = sketchRoutes;
|
|
11983
12114
|
exports.sketchTitle = sketchTitle;
|
|
11984
12115
|
exports.sourcePathOfChild = sourcePathOfChild;
|
|
11985
12116
|
exports.storeWork = storeWork;
|
|
@@ -3086,6 +3086,26 @@ var Api = {
|
|
|
3086
3086
|
parentRef: ParentRef,
|
|
3087
3087
|
headVersion: zod.z.number().optional()
|
|
3088
3088
|
})
|
|
3089
|
+
}),
|
|
3090
|
+
/*
|
|
3091
|
+
* The content service failed to take a patch: it answered with a
|
|
3092
|
+
* server error, or could not be reached. Not the 400 above either,
|
|
3093
|
+
* because the patches are fine -- the Studio keeps them and offers
|
|
3094
|
+
* to send them again. `message` is for the editor and `details` (the
|
|
3095
|
+
* status line and the service's own words) for whoever they ask.
|
|
3096
|
+
*
|
|
3097
|
+
* As with the 403, the patches BEFORE the failed one were saved.
|
|
3098
|
+
*/
|
|
3099
|
+
zod.z.object({
|
|
3100
|
+
status: zod.z.literal(502),
|
|
3101
|
+
json: zod.z.object({
|
|
3102
|
+
type: zod.z.literal("service-error"),
|
|
3103
|
+
message: zod.z.string(),
|
|
3104
|
+
details: zod.z.string().optional(),
|
|
3105
|
+
newPatchIds: zod.z.array(PatchId),
|
|
3106
|
+
parentRef: ParentRef,
|
|
3107
|
+
headVersion: zod.z.number().optional()
|
|
3108
|
+
})
|
|
3089
3109
|
}), zod.z.object({
|
|
3090
3110
|
status: zod.z.literal(200),
|
|
3091
3111
|
json: zod.z.object({
|
|
@@ -3121,7 +3141,9 @@ var Api = {
|
|
|
3121
3141
|
status: zod.z.literal(500),
|
|
3122
3142
|
json: zod.z.object({
|
|
3123
3143
|
message: zod.z.string(),
|
|
3124
|
-
error: GenericError
|
|
3144
|
+
error: GenericError,
|
|
3145
|
+
/** What the content service said: its status line and words. */
|
|
3146
|
+
details: zod.z.string().optional()
|
|
3125
3147
|
})
|
|
3126
3148
|
}), zod.z.object({
|
|
3127
3149
|
status: zod.z.literal(200),
|
|
@@ -8239,24 +8261,30 @@ function emptyRecord(schema, context) {
|
|
|
8239
8261
|
}));
|
|
8240
8262
|
}
|
|
8241
8263
|
|
|
8242
|
-
var toolNames = ["get_all_schema", "get_source", "search_content", "validate_content", "create_patch", "add_session_image_to_gallery", "remove_image_gallery_entry", "navigate_to", "get_current_context", "get_patches", "get_source_path_from_route", "set_session_name", "show_compare_view", "ask_user_question", "duplicate_source", "empty_at_path", "count_entries", "get_record_keys", "list_sketchpads", "create_sketchpad", "read_sketchpad", "write_sketchpad"];
|
|
8264
|
+
var toolNames = ["get_all_schema", "get_source", "search_content", "validate_content", "create_patch", "add_session_image_to_gallery", "remove_image_gallery_entry", "convert_session_image", "navigate_to", "get_current_context", "get_patches", "get_source_path_from_route", "set_session_name", "show_compare_view", "ask_user_question", "duplicate_source", "empty_at_path", "count_entries", "get_record_keys", "list_sketchpads", "create_sketchpad", "read_sketchpad", "write_sketchpad", "highlight_sketchpad_blocks", "clear_sketchpad_highlights"];
|
|
8243
8265
|
|
|
8244
8266
|
/**
|
|
8245
8267
|
* A page sketch: a page written as indented text, with four primitives.
|
|
8246
8268
|
*
|
|
8247
8269
|
* ```
|
|
8270
|
+
* --- /about a route: what follows is the page at /about
|
|
8248
8271
|
* # Our people text (a heading: #, ## or ###)
|
|
8249
8272
|
* We are 40 people in Oslo. text (a paragraph)
|
|
8273
|
+
* ## Hi {field: /x.val.ts?p="t"} text linked to a content field: typing
|
|
8274
|
+
* in it writes the field
|
|
8250
8275
|
* [image: Team photo] placeholder: [kind] or [kind: label]
|
|
8251
8276
|
* [hero: Roof](image: /a.jpg) a placeholder with an image (or video) in it
|
|
8252
8277
|
* icon hero M3 5h18v14H3z how every [hero] box is drawn: SVG path data
|
|
8253
8278
|
* row its children side by side
|
|
8254
|
-
* col
|
|
8255
|
-
* ## Design
|
|
8279
|
+
* col its children stacked; columns share a row
|
|
8280
|
+
* ## Design equally
|
|
8256
8281
|
* col
|
|
8257
8282
|
* [button: Join us]
|
|
8258
8283
|
* ```
|
|
8259
8284
|
*
|
|
8285
|
+
* A sketchpad is not one page's: a route divider starts the part about a
|
|
8286
|
+
* page, so one sketch can cover a page and the two it links to.
|
|
8287
|
+
*
|
|
8260
8288
|
* It is a scratch pad, not a layout language: it says WHAT is on a page and
|
|
8261
8289
|
* roughly WHERE, so an assistant and a person can agree on a page's content
|
|
8262
8290
|
* before anyone worries about how it looks. The person never sees this text,
|
|
@@ -8275,7 +8303,21 @@ var toolNames = ["get_all_schema", "get_source", "search_content", "validate_con
|
|
|
8275
8303
|
* that builds the page reads it exactly as the person left it.
|
|
8276
8304
|
*/
|
|
8277
8305
|
|
|
8306
|
+
/** The start of the part about one page. Only at the top level. */
|
|
8307
|
+
|
|
8308
|
+
/** Columns share their row equally: a sketch says what, not how wide. */
|
|
8309
|
+
|
|
8310
|
+
/**
|
|
8311
|
+
* `src` names a file the project has, never a guess: its `path` exactly as
|
|
8312
|
+
* the content has it (`/public/val/hero.webp`, or its remote URL), or an
|
|
8313
|
+
* image uploaded to the assistant's session, `session:<key>`. Which files
|
|
8314
|
+
* those are is the Studio's to check; the text only holds the name.
|
|
8315
|
+
*/
|
|
8316
|
+
|
|
8317
|
+
/** The prefix of a `src` that is an image in the assistant's session. */
|
|
8318
|
+
var SESSION_MEDIA_PREFIX = "session:";
|
|
8278
8319
|
var CONTAINER = /^(row|col)(?:\s+(\d+))?$/;
|
|
8320
|
+
var ROUTE = /^---(?:\s+(.*))?$/;
|
|
8279
8321
|
var PLACEHOLDER = /^\[([^\]:]*)(?::([^\]]*))?\](?:\((image|video):\s*([^\s)]+)\s*\))?$/;
|
|
8280
8322
|
var HAS_MEDIA = /^\[[^\]]*\]\(/;
|
|
8281
8323
|
var ICON = /^icon\s+(\S+)\s+([Mm][\d\s.-].*)$/;
|
|
@@ -8318,6 +8360,32 @@ function parseSketch(source) {
|
|
|
8318
8360
|
while (stack.length > 1 && indent <= stack[stack.length - 1].indent) {
|
|
8319
8361
|
stack.pop();
|
|
8320
8362
|
}
|
|
8363
|
+
var route = ROUTE.exec(content);
|
|
8364
|
+
if (route) {
|
|
8365
|
+
var _route$;
|
|
8366
|
+
var _path = ((_route$ = route[1]) !== null && _route$ !== void 0 ? _route$ : "").trim();
|
|
8367
|
+
if (!_path.startsWith("/") || /\s/.test(_path)) {
|
|
8368
|
+
errors.push({
|
|
8369
|
+
line: line,
|
|
8370
|
+
message: 'A route divider names one page by its route, like "--- /about".'
|
|
8371
|
+
});
|
|
8372
|
+
}
|
|
8373
|
+
if (indent > 0) {
|
|
8374
|
+
errors.push({
|
|
8375
|
+
line: line,
|
|
8376
|
+
message: "A route divider starts a page, so it goes at the top level, not indented."
|
|
8377
|
+
});
|
|
8378
|
+
}
|
|
8379
|
+
// It closes everything open: what follows is another page.
|
|
8380
|
+
stack.length = 1;
|
|
8381
|
+
stack[0].lastIndent = 0;
|
|
8382
|
+
blocks.push({
|
|
8383
|
+
type: "route",
|
|
8384
|
+
line: line,
|
|
8385
|
+
route: _path
|
|
8386
|
+
});
|
|
8387
|
+
return;
|
|
8388
|
+
}
|
|
8321
8389
|
var parent = stack[stack.length - 1];
|
|
8322
8390
|
var node = parseContent(content, line, errors);
|
|
8323
8391
|
|
|
@@ -8359,7 +8427,27 @@ function parseSketch(source) {
|
|
|
8359
8427
|
errors: errors
|
|
8360
8428
|
};
|
|
8361
8429
|
}
|
|
8362
|
-
|
|
8430
|
+
|
|
8431
|
+
/** The link to a content field at the end of a text line. */
|
|
8432
|
+
var FIELD = / \{field: (\/[^{}]*)\}$/;
|
|
8433
|
+
function parseContent(whole, line, errors) {
|
|
8434
|
+
var link = FIELD.exec(whole);
|
|
8435
|
+
if (link) {
|
|
8436
|
+
var node = parseLine(whole.slice(0, link.index), line, errors);
|
|
8437
|
+
if (node.type !== "text") {
|
|
8438
|
+
errors.push({
|
|
8439
|
+
line: line,
|
|
8440
|
+
message: "Only a heading or a paragraph is linked to a field: put {field: ...} at the end of one."
|
|
8441
|
+
});
|
|
8442
|
+
return node;
|
|
8443
|
+
}
|
|
8444
|
+
return createForOfIteratorHelper._objectSpread2(createForOfIteratorHelper._objectSpread2({}, node), {}, {
|
|
8445
|
+
field: link[1].trim()
|
|
8446
|
+
});
|
|
8447
|
+
}
|
|
8448
|
+
return parseLine(whole, line, errors);
|
|
8449
|
+
}
|
|
8450
|
+
function parseLine(content, line, errors) {
|
|
8363
8451
|
// A leading backslash keeps a line that looks like a keyword as text.
|
|
8364
8452
|
if (content.startsWith("\\")) {
|
|
8365
8453
|
return {
|
|
@@ -8384,17 +8472,15 @@ function parseContent(content, line, errors) {
|
|
|
8384
8472
|
children: []
|
|
8385
8473
|
};
|
|
8386
8474
|
}
|
|
8387
|
-
|
|
8388
|
-
if (weight === 0) {
|
|
8475
|
+
if (container[2] !== undefined) {
|
|
8389
8476
|
errors.push({
|
|
8390
8477
|
line: line,
|
|
8391
|
-
message:
|
|
8478
|
+
message: 'Columns share a row equally, so a col takes no number: write "col".'
|
|
8392
8479
|
});
|
|
8393
8480
|
}
|
|
8394
8481
|
return {
|
|
8395
8482
|
type: "col",
|
|
8396
8483
|
line: line,
|
|
8397
|
-
weight: Math.max(weight, 1),
|
|
8398
8484
|
children: []
|
|
8399
8485
|
};
|
|
8400
8486
|
}
|
|
@@ -8468,13 +8554,19 @@ function parseContent(content, line, errors) {
|
|
|
8468
8554
|
* The line a text block is written as. Line breaks become spaces, and a
|
|
8469
8555
|
* paragraph that would read as something else is kept as text with `\`.
|
|
8470
8556
|
*/
|
|
8471
|
-
function formatSketchText(level, text) {
|
|
8557
|
+
function formatSketchText(level, text, field) {
|
|
8472
8558
|
var flat = text.replace(/\s+/g, " ").trim();
|
|
8559
|
+
var path = field === null || field === void 0 ? void 0 : field.replace(/\s+/g, " ").trim();
|
|
8560
|
+
// A source path, and one the line can be read back with: no braces.
|
|
8561
|
+
var link = path && /^\/[^{}]*$/.test(path) ? " {field: ".concat(path, "}") : "";
|
|
8473
8562
|
if (level > 0) {
|
|
8474
|
-
return "#".repeat(level) + " " + flat;
|
|
8563
|
+
return "#".repeat(level) + " " + flat + link;
|
|
8475
8564
|
}
|
|
8476
|
-
|
|
8477
|
-
|
|
8565
|
+
// Read as the whole line will be, link and all: `icon x M` is text, and
|
|
8566
|
+
// `icon x M {field: ...}` would be an icon.
|
|
8567
|
+
var whole = flat + link;
|
|
8568
|
+
var ambiguous = flat.startsWith("\\") || flat.startsWith("[") || CONTAINER.test(whole) || ROUTE.test(whole) || HEADING.test(whole) || ICON.test(whole);
|
|
8569
|
+
return (ambiguous ? "\\" + flat : flat) + link;
|
|
8478
8570
|
}
|
|
8479
8571
|
|
|
8480
8572
|
/** The line a placeholder is written as. */
|
|
@@ -8499,17 +8591,26 @@ function formatSketchBox(placeholder) {
|
|
|
8499
8591
|
*/
|
|
8500
8592
|
function formatSketch(blocks, icons) {
|
|
8501
8593
|
var lines = [];
|
|
8594
|
+
// One block per field: the first keeps the link.
|
|
8595
|
+
var linked = new Set();
|
|
8502
8596
|
var _walk = function walk(node, depth, inRow) {
|
|
8503
8597
|
var indent = " ".repeat(depth);
|
|
8504
8598
|
switch (node.type) {
|
|
8505
8599
|
case "text":
|
|
8506
8600
|
if (node.text) {
|
|
8507
|
-
|
|
8601
|
+
var field = node.field && !linked.has(node.field) ? node.field : undefined;
|
|
8602
|
+
if (field) {
|
|
8603
|
+
linked.add(field);
|
|
8604
|
+
}
|
|
8605
|
+
lines.push(indent + formatSketchText(node.level, node.text, field));
|
|
8508
8606
|
}
|
|
8509
8607
|
return;
|
|
8510
8608
|
case "placeholder":
|
|
8511
8609
|
lines.push(indent + formatSketchBox(node));
|
|
8512
8610
|
return;
|
|
8611
|
+
case "route":
|
|
8612
|
+
lines.push("--- ".concat(node.route));
|
|
8613
|
+
return;
|
|
8513
8614
|
case "row":
|
|
8514
8615
|
lines.push(indent + "row");
|
|
8515
8616
|
if (node.children.length === 0) {
|
|
@@ -8526,7 +8627,7 @@ function formatSketch(blocks, icons) {
|
|
|
8526
8627
|
});
|
|
8527
8628
|
return;
|
|
8528
8629
|
}
|
|
8529
|
-
lines.push(indent +
|
|
8630
|
+
lines.push(indent + "col");
|
|
8530
8631
|
node.children.forEach(function (child) {
|
|
8531
8632
|
return _walk(child, depth + 1, false);
|
|
8532
8633
|
});
|
|
@@ -8546,6 +8647,33 @@ function formatSketch(blocks, icons) {
|
|
|
8546
8647
|
return all.length > 0 ? all.join("\n") + "\n" : "";
|
|
8547
8648
|
}
|
|
8548
8649
|
|
|
8650
|
+
/**
|
|
8651
|
+
* The text of every block linked to a field, by field: what the Studio
|
|
8652
|
+
* writes to the content when a linked block changes. The first block wins,
|
|
8653
|
+
* as `formatSketch` keeps only its link.
|
|
8654
|
+
*/
|
|
8655
|
+
function sketchFieldTexts(blocks) {
|
|
8656
|
+
var texts = new Map();
|
|
8657
|
+
var _walk2 = function walk(node) {
|
|
8658
|
+
if (node.type === "text") {
|
|
8659
|
+
if (node.field && node.text && !texts.has(node.field)) {
|
|
8660
|
+
texts.set(node.field, node.text.replace(/\s+/g, " ").trim());
|
|
8661
|
+
}
|
|
8662
|
+
} else if (node.type === "row" || node.type === "col") {
|
|
8663
|
+
node.children.forEach(_walk2);
|
|
8664
|
+
}
|
|
8665
|
+
};
|
|
8666
|
+
blocks.forEach(_walk2);
|
|
8667
|
+
return texts;
|
|
8668
|
+
}
|
|
8669
|
+
|
|
8670
|
+
/** The pages a sketch is about, in the order it gives them. */
|
|
8671
|
+
function sketchRoutes(blocks) {
|
|
8672
|
+
return blocks.flatMap(function (block) {
|
|
8673
|
+
return block.type === "route" && block.route !== "" ? [block.route] : [];
|
|
8674
|
+
});
|
|
8675
|
+
}
|
|
8676
|
+
|
|
8549
8677
|
/**
|
|
8550
8678
|
* What a list names a sketch by: its first top-level heading, the biggest
|
|
8551
8679
|
* one first. Null for a sketch with no heading, which a list then names by
|
|
@@ -11829,6 +11957,7 @@ exports.RestoreVerdict = RestoreVerdict;
|
|
|
11829
11957
|
exports.RichTextOptions = RichTextOptions;
|
|
11830
11958
|
exports.SCHEMA_SOURCE_FIXES = SCHEMA_SOURCE_FIXES;
|
|
11831
11959
|
exports.SELF_CHECK_VERSION = SELF_CHECK_VERSION;
|
|
11960
|
+
exports.SESSION_MEDIA_PREFIX = SESSION_MEDIA_PREFIX;
|
|
11832
11961
|
exports.SKETCHPAD_MAX_TEXT_LENGTH = SKETCHPAD_MAX_TEXT_LENGTH;
|
|
11833
11962
|
exports.STAGED_SCHEMA_PREFIX = STAGED_SCHEMA_PREFIX;
|
|
11834
11963
|
exports.STUDIO_FIXES = STUDIO_FIXES;
|
|
@@ -11980,6 +12109,8 @@ exports.selfCheck = selfCheck;
|
|
|
11980
12109
|
exports.shouldEncodeWithWasm = shouldEncodeWithWasm;
|
|
11981
12110
|
exports.sideFiles = sideFiles;
|
|
11982
12111
|
exports.sideSource = sideSource;
|
|
12112
|
+
exports.sketchFieldTexts = sketchFieldTexts;
|
|
12113
|
+
exports.sketchRoutes = sketchRoutes;
|
|
11983
12114
|
exports.sketchTitle = sketchTitle;
|
|
11984
12115
|
exports.sourcePathOfChild = sourcePathOfChild;
|
|
11985
12116
|
exports.storeWork = storeWork;
|
|
@@ -3079,6 +3079,26 @@ var Api = {
|
|
|
3079
3079
|
parentRef: ParentRef,
|
|
3080
3080
|
headVersion: z.number().optional()
|
|
3081
3081
|
})
|
|
3082
|
+
}),
|
|
3083
|
+
/*
|
|
3084
|
+
* The content service failed to take a patch: it answered with a
|
|
3085
|
+
* server error, or could not be reached. Not the 400 above either,
|
|
3086
|
+
* because the patches are fine -- the Studio keeps them and offers
|
|
3087
|
+
* to send them again. `message` is for the editor and `details` (the
|
|
3088
|
+
* status line and the service's own words) for whoever they ask.
|
|
3089
|
+
*
|
|
3090
|
+
* As with the 403, the patches BEFORE the failed one were saved.
|
|
3091
|
+
*/
|
|
3092
|
+
z.object({
|
|
3093
|
+
status: z.literal(502),
|
|
3094
|
+
json: z.object({
|
|
3095
|
+
type: z.literal("service-error"),
|
|
3096
|
+
message: z.string(),
|
|
3097
|
+
details: z.string().optional(),
|
|
3098
|
+
newPatchIds: z.array(PatchId),
|
|
3099
|
+
parentRef: ParentRef,
|
|
3100
|
+
headVersion: z.number().optional()
|
|
3101
|
+
})
|
|
3082
3102
|
}), z.object({
|
|
3083
3103
|
status: z.literal(200),
|
|
3084
3104
|
json: z.object({
|
|
@@ -3114,7 +3134,9 @@ var Api = {
|
|
|
3114
3134
|
status: z.literal(500),
|
|
3115
3135
|
json: z.object({
|
|
3116
3136
|
message: z.string(),
|
|
3117
|
-
error: GenericError
|
|
3137
|
+
error: GenericError,
|
|
3138
|
+
/** What the content service said: its status line and words. */
|
|
3139
|
+
details: z.string().optional()
|
|
3118
3140
|
})
|
|
3119
3141
|
}), z.object({
|
|
3120
3142
|
status: z.literal(200),
|
|
@@ -8232,24 +8254,30 @@ function emptyRecord(schema, context) {
|
|
|
8232
8254
|
}));
|
|
8233
8255
|
}
|
|
8234
8256
|
|
|
8235
|
-
var toolNames = ["get_all_schema", "get_source", "search_content", "validate_content", "create_patch", "add_session_image_to_gallery", "remove_image_gallery_entry", "navigate_to", "get_current_context", "get_patches", "get_source_path_from_route", "set_session_name", "show_compare_view", "ask_user_question", "duplicate_source", "empty_at_path", "count_entries", "get_record_keys", "list_sketchpads", "create_sketchpad", "read_sketchpad", "write_sketchpad"];
|
|
8257
|
+
var toolNames = ["get_all_schema", "get_source", "search_content", "validate_content", "create_patch", "add_session_image_to_gallery", "remove_image_gallery_entry", "convert_session_image", "navigate_to", "get_current_context", "get_patches", "get_source_path_from_route", "set_session_name", "show_compare_view", "ask_user_question", "duplicate_source", "empty_at_path", "count_entries", "get_record_keys", "list_sketchpads", "create_sketchpad", "read_sketchpad", "write_sketchpad", "highlight_sketchpad_blocks", "clear_sketchpad_highlights"];
|
|
8236
8258
|
|
|
8237
8259
|
/**
|
|
8238
8260
|
* A page sketch: a page written as indented text, with four primitives.
|
|
8239
8261
|
*
|
|
8240
8262
|
* ```
|
|
8263
|
+
* --- /about a route: what follows is the page at /about
|
|
8241
8264
|
* # Our people text (a heading: #, ## or ###)
|
|
8242
8265
|
* We are 40 people in Oslo. text (a paragraph)
|
|
8266
|
+
* ## Hi {field: /x.val.ts?p="t"} text linked to a content field: typing
|
|
8267
|
+
* in it writes the field
|
|
8243
8268
|
* [image: Team photo] placeholder: [kind] or [kind: label]
|
|
8244
8269
|
* [hero: Roof](image: /a.jpg) a placeholder with an image (or video) in it
|
|
8245
8270
|
* icon hero M3 5h18v14H3z how every [hero] box is drawn: SVG path data
|
|
8246
8271
|
* row its children side by side
|
|
8247
|
-
* col
|
|
8248
|
-
* ## Design
|
|
8272
|
+
* col its children stacked; columns share a row
|
|
8273
|
+
* ## Design equally
|
|
8249
8274
|
* col
|
|
8250
8275
|
* [button: Join us]
|
|
8251
8276
|
* ```
|
|
8252
8277
|
*
|
|
8278
|
+
* A sketchpad is not one page's: a route divider starts the part about a
|
|
8279
|
+
* page, so one sketch can cover a page and the two it links to.
|
|
8280
|
+
*
|
|
8253
8281
|
* It is a scratch pad, not a layout language: it says WHAT is on a page and
|
|
8254
8282
|
* roughly WHERE, so an assistant and a person can agree on a page's content
|
|
8255
8283
|
* before anyone worries about how it looks. The person never sees this text,
|
|
@@ -8268,7 +8296,21 @@ var toolNames = ["get_all_schema", "get_source", "search_content", "validate_con
|
|
|
8268
8296
|
* that builds the page reads it exactly as the person left it.
|
|
8269
8297
|
*/
|
|
8270
8298
|
|
|
8299
|
+
/** The start of the part about one page. Only at the top level. */
|
|
8300
|
+
|
|
8301
|
+
/** Columns share their row equally: a sketch says what, not how wide. */
|
|
8302
|
+
|
|
8303
|
+
/**
|
|
8304
|
+
* `src` names a file the project has, never a guess: its `path` exactly as
|
|
8305
|
+
* the content has it (`/public/val/hero.webp`, or its remote URL), or an
|
|
8306
|
+
* image uploaded to the assistant's session, `session:<key>`. Which files
|
|
8307
|
+
* those are is the Studio's to check; the text only holds the name.
|
|
8308
|
+
*/
|
|
8309
|
+
|
|
8310
|
+
/** The prefix of a `src` that is an image in the assistant's session. */
|
|
8311
|
+
var SESSION_MEDIA_PREFIX = "session:";
|
|
8271
8312
|
var CONTAINER = /^(row|col)(?:\s+(\d+))?$/;
|
|
8313
|
+
var ROUTE = /^---(?:\s+(.*))?$/;
|
|
8272
8314
|
var PLACEHOLDER = /^\[([^\]:]*)(?::([^\]]*))?\](?:\((image|video):\s*([^\s)]+)\s*\))?$/;
|
|
8273
8315
|
var HAS_MEDIA = /^\[[^\]]*\]\(/;
|
|
8274
8316
|
var ICON = /^icon\s+(\S+)\s+([Mm][\d\s.-].*)$/;
|
|
@@ -8311,6 +8353,32 @@ function parseSketch(source) {
|
|
|
8311
8353
|
while (stack.length > 1 && indent <= stack[stack.length - 1].indent) {
|
|
8312
8354
|
stack.pop();
|
|
8313
8355
|
}
|
|
8356
|
+
var route = ROUTE.exec(content);
|
|
8357
|
+
if (route) {
|
|
8358
|
+
var _route$;
|
|
8359
|
+
var _path = ((_route$ = route[1]) !== null && _route$ !== void 0 ? _route$ : "").trim();
|
|
8360
|
+
if (!_path.startsWith("/") || /\s/.test(_path)) {
|
|
8361
|
+
errors.push({
|
|
8362
|
+
line: line,
|
|
8363
|
+
message: 'A route divider names one page by its route, like "--- /about".'
|
|
8364
|
+
});
|
|
8365
|
+
}
|
|
8366
|
+
if (indent > 0) {
|
|
8367
|
+
errors.push({
|
|
8368
|
+
line: line,
|
|
8369
|
+
message: "A route divider starts a page, so it goes at the top level, not indented."
|
|
8370
|
+
});
|
|
8371
|
+
}
|
|
8372
|
+
// It closes everything open: what follows is another page.
|
|
8373
|
+
stack.length = 1;
|
|
8374
|
+
stack[0].lastIndent = 0;
|
|
8375
|
+
blocks.push({
|
|
8376
|
+
type: "route",
|
|
8377
|
+
line: line,
|
|
8378
|
+
route: _path
|
|
8379
|
+
});
|
|
8380
|
+
return;
|
|
8381
|
+
}
|
|
8314
8382
|
var parent = stack[stack.length - 1];
|
|
8315
8383
|
var node = parseContent(content, line, errors);
|
|
8316
8384
|
|
|
@@ -8352,7 +8420,27 @@ function parseSketch(source) {
|
|
|
8352
8420
|
errors: errors
|
|
8353
8421
|
};
|
|
8354
8422
|
}
|
|
8355
|
-
|
|
8423
|
+
|
|
8424
|
+
/** The link to a content field at the end of a text line. */
|
|
8425
|
+
var FIELD = / \{field: (\/[^{}]*)\}$/;
|
|
8426
|
+
function parseContent(whole, line, errors) {
|
|
8427
|
+
var link = FIELD.exec(whole);
|
|
8428
|
+
if (link) {
|
|
8429
|
+
var node = parseLine(whole.slice(0, link.index), line, errors);
|
|
8430
|
+
if (node.type !== "text") {
|
|
8431
|
+
errors.push({
|
|
8432
|
+
line: line,
|
|
8433
|
+
message: "Only a heading or a paragraph is linked to a field: put {field: ...} at the end of one."
|
|
8434
|
+
});
|
|
8435
|
+
return node;
|
|
8436
|
+
}
|
|
8437
|
+
return _objectSpread2(_objectSpread2({}, node), {}, {
|
|
8438
|
+
field: link[1].trim()
|
|
8439
|
+
});
|
|
8440
|
+
}
|
|
8441
|
+
return parseLine(whole, line, errors);
|
|
8442
|
+
}
|
|
8443
|
+
function parseLine(content, line, errors) {
|
|
8356
8444
|
// A leading backslash keeps a line that looks like a keyword as text.
|
|
8357
8445
|
if (content.startsWith("\\")) {
|
|
8358
8446
|
return {
|
|
@@ -8377,17 +8465,15 @@ function parseContent(content, line, errors) {
|
|
|
8377
8465
|
children: []
|
|
8378
8466
|
};
|
|
8379
8467
|
}
|
|
8380
|
-
|
|
8381
|
-
if (weight === 0) {
|
|
8468
|
+
if (container[2] !== undefined) {
|
|
8382
8469
|
errors.push({
|
|
8383
8470
|
line: line,
|
|
8384
|
-
message:
|
|
8471
|
+
message: 'Columns share a row equally, so a col takes no number: write "col".'
|
|
8385
8472
|
});
|
|
8386
8473
|
}
|
|
8387
8474
|
return {
|
|
8388
8475
|
type: "col",
|
|
8389
8476
|
line: line,
|
|
8390
|
-
weight: Math.max(weight, 1),
|
|
8391
8477
|
children: []
|
|
8392
8478
|
};
|
|
8393
8479
|
}
|
|
@@ -8461,13 +8547,19 @@ function parseContent(content, line, errors) {
|
|
|
8461
8547
|
* The line a text block is written as. Line breaks become spaces, and a
|
|
8462
8548
|
* paragraph that would read as something else is kept as text with `\`.
|
|
8463
8549
|
*/
|
|
8464
|
-
function formatSketchText(level, text) {
|
|
8550
|
+
function formatSketchText(level, text, field) {
|
|
8465
8551
|
var flat = text.replace(/\s+/g, " ").trim();
|
|
8552
|
+
var path = field === null || field === void 0 ? void 0 : field.replace(/\s+/g, " ").trim();
|
|
8553
|
+
// A source path, and one the line can be read back with: no braces.
|
|
8554
|
+
var link = path && /^\/[^{}]*$/.test(path) ? " {field: ".concat(path, "}") : "";
|
|
8466
8555
|
if (level > 0) {
|
|
8467
|
-
return "#".repeat(level) + " " + flat;
|
|
8556
|
+
return "#".repeat(level) + " " + flat + link;
|
|
8468
8557
|
}
|
|
8469
|
-
|
|
8470
|
-
|
|
8558
|
+
// Read as the whole line will be, link and all: `icon x M` is text, and
|
|
8559
|
+
// `icon x M {field: ...}` would be an icon.
|
|
8560
|
+
var whole = flat + link;
|
|
8561
|
+
var ambiguous = flat.startsWith("\\") || flat.startsWith("[") || CONTAINER.test(whole) || ROUTE.test(whole) || HEADING.test(whole) || ICON.test(whole);
|
|
8562
|
+
return (ambiguous ? "\\" + flat : flat) + link;
|
|
8471
8563
|
}
|
|
8472
8564
|
|
|
8473
8565
|
/** The line a placeholder is written as. */
|
|
@@ -8492,17 +8584,26 @@ function formatSketchBox(placeholder) {
|
|
|
8492
8584
|
*/
|
|
8493
8585
|
function formatSketch(blocks, icons) {
|
|
8494
8586
|
var lines = [];
|
|
8587
|
+
// One block per field: the first keeps the link.
|
|
8588
|
+
var linked = new Set();
|
|
8495
8589
|
var _walk = function walk(node, depth, inRow) {
|
|
8496
8590
|
var indent = " ".repeat(depth);
|
|
8497
8591
|
switch (node.type) {
|
|
8498
8592
|
case "text":
|
|
8499
8593
|
if (node.text) {
|
|
8500
|
-
|
|
8594
|
+
var field = node.field && !linked.has(node.field) ? node.field : undefined;
|
|
8595
|
+
if (field) {
|
|
8596
|
+
linked.add(field);
|
|
8597
|
+
}
|
|
8598
|
+
lines.push(indent + formatSketchText(node.level, node.text, field));
|
|
8501
8599
|
}
|
|
8502
8600
|
return;
|
|
8503
8601
|
case "placeholder":
|
|
8504
8602
|
lines.push(indent + formatSketchBox(node));
|
|
8505
8603
|
return;
|
|
8604
|
+
case "route":
|
|
8605
|
+
lines.push("--- ".concat(node.route));
|
|
8606
|
+
return;
|
|
8506
8607
|
case "row":
|
|
8507
8608
|
lines.push(indent + "row");
|
|
8508
8609
|
if (node.children.length === 0) {
|
|
@@ -8519,7 +8620,7 @@ function formatSketch(blocks, icons) {
|
|
|
8519
8620
|
});
|
|
8520
8621
|
return;
|
|
8521
8622
|
}
|
|
8522
|
-
lines.push(indent +
|
|
8623
|
+
lines.push(indent + "col");
|
|
8523
8624
|
node.children.forEach(function (child) {
|
|
8524
8625
|
return _walk(child, depth + 1, false);
|
|
8525
8626
|
});
|
|
@@ -8539,6 +8640,33 @@ function formatSketch(blocks, icons) {
|
|
|
8539
8640
|
return all.length > 0 ? all.join("\n") + "\n" : "";
|
|
8540
8641
|
}
|
|
8541
8642
|
|
|
8643
|
+
/**
|
|
8644
|
+
* The text of every block linked to a field, by field: what the Studio
|
|
8645
|
+
* writes to the content when a linked block changes. The first block wins,
|
|
8646
|
+
* as `formatSketch` keeps only its link.
|
|
8647
|
+
*/
|
|
8648
|
+
function sketchFieldTexts(blocks) {
|
|
8649
|
+
var texts = new Map();
|
|
8650
|
+
var _walk2 = function walk(node) {
|
|
8651
|
+
if (node.type === "text") {
|
|
8652
|
+
if (node.field && node.text && !texts.has(node.field)) {
|
|
8653
|
+
texts.set(node.field, node.text.replace(/\s+/g, " ").trim());
|
|
8654
|
+
}
|
|
8655
|
+
} else if (node.type === "row" || node.type === "col") {
|
|
8656
|
+
node.children.forEach(_walk2);
|
|
8657
|
+
}
|
|
8658
|
+
};
|
|
8659
|
+
blocks.forEach(_walk2);
|
|
8660
|
+
return texts;
|
|
8661
|
+
}
|
|
8662
|
+
|
|
8663
|
+
/** The pages a sketch is about, in the order it gives them. */
|
|
8664
|
+
function sketchRoutes(blocks) {
|
|
8665
|
+
return blocks.flatMap(function (block) {
|
|
8666
|
+
return block.type === "route" && block.route !== "" ? [block.route] : [];
|
|
8667
|
+
});
|
|
8668
|
+
}
|
|
8669
|
+
|
|
8542
8670
|
/**
|
|
8543
8671
|
* What a list names a sketch by: its first top-level heading, the biggest
|
|
8544
8672
|
* one first. Null for a sketch with no heading, which a list then names by
|
|
@@ -11707,4 +11835,4 @@ var messageOf = function messageOf(error) {
|
|
|
11707
11835
|
return error instanceof Error ? error.message : String(error);
|
|
11708
11836
|
};
|
|
11709
11837
|
|
|
11710
|
-
export { AA_LARGE, AA_TEXT, AIToolCallSummaries, AnalyticsBeacon, Api, BRAND_CONTRAST_PAIRS, BinaryFileRef, ChainFold, CodeOptions, ColorOptions, DEFAULT_ERROR_MESSAGE, DateOptions, EMPTY_CHAIN, ENCODE_DEFAULTS, ENCODE_MIME_TYPE_OF, ENGINE, FileOptions, HistoricalCommit, HistoricalModule, HistoricalPatchSet, HistoryError, ImageEncodeOption, ImageOptions, JSONValue, JSON_ENTRIES_BATCH_MAX, LOCAL_FILE_IN_REMOTE_PROJECT_HINT, LOCAL_FILE_IN_REMOTE_PROJECT_WARNING, ModuleComparison, ModuleVersionSchema, NEVER_ENCODED, ParentRef$1 as ParentRef, Patch, PatchBlock, PatchId, PatchJSON, PatchSets, PlanRefusalError, ProjectVersionSchema, RAMP_STEPS, RemirrorBr, RemirrorBulletList, RemirrorHeading, RemirrorImage, RemirrorJSON, RemirrorLinkMark, RemirrorListItem, RemirrorOrderedList, RemirrorParagraph, RemirrorText, RemirrorTextMark, RestoreVerdict, RichTextOptions, SCHEMA_SOURCE_FIXES, SELF_CHECK_VERSION, SKETCHPAD_MAX_TEXT_LENGTH, STAGED_SCHEMA_PREFIX, STUDIO_FIXES, SerializedArraySchema, SerializedBooleanSchema, SerializedCodeSchema, SerializedColorSchema, SerializedDateSchema, SerializedDateTimeSchema, SerializedDiscriminatedUnionSchema, SerializedEnumSchema, SerializedFileSchema, SerializedImageSchema, SerializedKeyOfSchema, SerializedLiteralSchema, SerializedLocaleSchema, SerializedNumberSchema, SerializedObjectSchema, SerializedRecordSchema, SerializedRichTextSchema, SerializedRouteSchema, SerializedSchema, SerializedSettingsSchema, SerializedStringSchema, SerializedValViewSchema, SerializedVideoSchema, SharedValConfig, Sketchpad, SketchpadSummary, VAL_CLIENT_HEADER, VAL_ENABLE_COOKIE_NAME, VAL_GREEN_RAMP, VAL_SESSION_COOKIE, VAL_STATE_COOKIE, VAL_STUDIO_HEADER, ValCommit, ValDeployment, VideoOptions, VideoStreamOption, WARNING_FIXES, WASM_ENCODED_MIME_TYPES, accentRamp, applyChain, applyPatchRecord, baseModuleContent, baseVersionOf, buildDuplicatePatch, buildEmptyAtPathPatch, buildFileRefValue, buildImageGalleryPatch, buildRemoveImageGalleryEntryPatch, buildSearchIndex, bundleTier, chainHeadOf, chainOf, checkCompatibility, checkSketch, childSource, chooseEncoded, classifyJsonValuesOp, concatModulePath, contrastRatio, createRegExpFromPattern, createSearchIndex, createValClient, declaredLocales, describeContainerAtPath, emptyOf, engineWork, entryAddress, entryState, enumLocaleTag, expandJsonValuesRootOp, expandJsonValuesRootOpForKey, explainIncompatible, extendChain, fallbackMimeType, filterBlockingValidationErrors, filterRoutesByPatterns, findSimilar, fitWithin, flattenRichText, forEachRichTextImage, formatSketch, formatSketchBox, formatSketchText, getErrorMessageFromUnknownJson, getFilenameFromRef, getInlineImgInfo, getKeyOfRecordAt, getRefParts, getRoutesOf, getRoutesWithModulePaths, getSourceAt, getValDemo, hasLocaleRouteParam, indexModule, isInsidePatchSetPath, isJsonObject, isJsonValuesRootOp, isLocaleSchema, isMimeTypeAccepted, isRemoteSchema, isRepairedOnSave, isSchemaSourceFixError, isSkippedSource, isStudioFix, isValidationWarning, isWarningFix, joinSharedChanges, keyOfRecordPath, levenshtein, localeAt, localeMeantBy, localeOfModuleRoot, localeOfRouteKey, localeParamOfRouteKey, localeScopeAt, memoryTier, moduleKey, newestCommitSha, parseModuleKey, parseSketch, partitionValidationErrors, pathOfModuleKey, performSearch, proposalCustomProperties, rebaseContentOp, relativeLuminance, relocateForLocale, remirrorToRichTextSource, removeModule, resolveEncodeSettings, resolveEntry, resolvePairGround, resolveSchemaSourceFixForError, resolveSchemaSourceFixes, resolveSerializedSchemaAtPath, richTextImageSchema, richTextToRemirror, safeParsePatch, sameEntryVersion, sameModuleVersion, schemaErrorsOf, schemaTypesOfPath, schemaVersionOf, selectionClosure, selfCheck, shouldEncodeWithWasm, sideFiles, sideSource, sketchTitle, sourcePathOfChild, storeWork, themeCustomProperties, tiered, toolNames, traverseSchemaSource, urlOf, valClientHeaders, valModulesEntryFile, valModulesEntryPath, validateRoutePatterns, versionHashCount, wholeEntryKey, withExtension };
|
|
11838
|
+
export { AA_LARGE, AA_TEXT, AIToolCallSummaries, AnalyticsBeacon, Api, BRAND_CONTRAST_PAIRS, BinaryFileRef, ChainFold, CodeOptions, ColorOptions, DEFAULT_ERROR_MESSAGE, DateOptions, EMPTY_CHAIN, ENCODE_DEFAULTS, ENCODE_MIME_TYPE_OF, ENGINE, FileOptions, HistoricalCommit, HistoricalModule, HistoricalPatchSet, HistoryError, ImageEncodeOption, ImageOptions, JSONValue, JSON_ENTRIES_BATCH_MAX, LOCAL_FILE_IN_REMOTE_PROJECT_HINT, LOCAL_FILE_IN_REMOTE_PROJECT_WARNING, ModuleComparison, ModuleVersionSchema, NEVER_ENCODED, ParentRef$1 as ParentRef, Patch, PatchBlock, PatchId, PatchJSON, PatchSets, PlanRefusalError, ProjectVersionSchema, RAMP_STEPS, RemirrorBr, RemirrorBulletList, RemirrorHeading, RemirrorImage, RemirrorJSON, RemirrorLinkMark, RemirrorListItem, RemirrorOrderedList, RemirrorParagraph, RemirrorText, RemirrorTextMark, RestoreVerdict, RichTextOptions, SCHEMA_SOURCE_FIXES, SELF_CHECK_VERSION, SESSION_MEDIA_PREFIX, SKETCHPAD_MAX_TEXT_LENGTH, STAGED_SCHEMA_PREFIX, STUDIO_FIXES, SerializedArraySchema, SerializedBooleanSchema, SerializedCodeSchema, SerializedColorSchema, SerializedDateSchema, SerializedDateTimeSchema, SerializedDiscriminatedUnionSchema, SerializedEnumSchema, SerializedFileSchema, SerializedImageSchema, SerializedKeyOfSchema, SerializedLiteralSchema, SerializedLocaleSchema, SerializedNumberSchema, SerializedObjectSchema, SerializedRecordSchema, SerializedRichTextSchema, SerializedRouteSchema, SerializedSchema, SerializedSettingsSchema, SerializedStringSchema, SerializedValViewSchema, SerializedVideoSchema, SharedValConfig, Sketchpad, SketchpadSummary, VAL_CLIENT_HEADER, VAL_ENABLE_COOKIE_NAME, VAL_GREEN_RAMP, VAL_SESSION_COOKIE, VAL_STATE_COOKIE, VAL_STUDIO_HEADER, ValCommit, ValDeployment, VideoOptions, VideoStreamOption, WARNING_FIXES, WASM_ENCODED_MIME_TYPES, accentRamp, applyChain, applyPatchRecord, baseModuleContent, baseVersionOf, buildDuplicatePatch, buildEmptyAtPathPatch, buildFileRefValue, buildImageGalleryPatch, buildRemoveImageGalleryEntryPatch, buildSearchIndex, bundleTier, chainHeadOf, chainOf, checkCompatibility, checkSketch, childSource, chooseEncoded, classifyJsonValuesOp, concatModulePath, contrastRatio, createRegExpFromPattern, createSearchIndex, createValClient, declaredLocales, describeContainerAtPath, emptyOf, engineWork, entryAddress, entryState, enumLocaleTag, expandJsonValuesRootOp, expandJsonValuesRootOpForKey, explainIncompatible, extendChain, fallbackMimeType, filterBlockingValidationErrors, filterRoutesByPatterns, findSimilar, fitWithin, flattenRichText, forEachRichTextImage, formatSketch, formatSketchBox, formatSketchText, getErrorMessageFromUnknownJson, getFilenameFromRef, getInlineImgInfo, getKeyOfRecordAt, getRefParts, getRoutesOf, getRoutesWithModulePaths, getSourceAt, getValDemo, hasLocaleRouteParam, indexModule, isInsidePatchSetPath, isJsonObject, isJsonValuesRootOp, isLocaleSchema, isMimeTypeAccepted, isRemoteSchema, isRepairedOnSave, isSchemaSourceFixError, isSkippedSource, isStudioFix, isValidationWarning, isWarningFix, joinSharedChanges, keyOfRecordPath, levenshtein, localeAt, localeMeantBy, localeOfModuleRoot, localeOfRouteKey, localeParamOfRouteKey, localeScopeAt, memoryTier, moduleKey, newestCommitSha, parseModuleKey, parseSketch, partitionValidationErrors, pathOfModuleKey, performSearch, proposalCustomProperties, rebaseContentOp, relativeLuminance, relocateForLocale, remirrorToRichTextSource, removeModule, resolveEncodeSettings, resolveEntry, resolvePairGround, resolveSchemaSourceFixForError, resolveSchemaSourceFixes, resolveSerializedSchemaAtPath, richTextImageSchema, richTextToRemirror, safeParsePatch, sameEntryVersion, sameModuleVersion, schemaErrorsOf, schemaTypesOfPath, schemaVersionOf, selectionClosure, selfCheck, shouldEncodeWithWasm, sideFiles, sideSource, sketchFieldTexts, sketchRoutes, sketchTitle, sourcePathOfChild, storeWork, themeCustomProperties, tiered, toolNames, traverseSchemaSource, urlOf, valClientHeaders, valModulesEntryFile, valModulesEntryPath, validateRoutePatterns, versionHashCount, wholeEntryKey, withExtension };
|