Skip to content

Commit 1d4cfa1

Browse files
committed
feat: provide a description for every property.
1 parent 0cea9af commit 1d4cfa1

File tree

7 files changed

+133
-55
lines changed

7 files changed

+133
-55
lines changed

extensions/vscode/src/language-server/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ const server = createServer(connection);
1010
connection.listen();
1111

1212
connection.onInitialize((params) => {
13-
connection.console.debug('CONNECTED' + params.capabilities);
14-
1513
const yamlService = createYamlService({
1614
getLanguageSettings(_context) {
1715
const schema = readSchema();
@@ -25,7 +23,7 @@ connection.onInitialize((params) => {
2523
isKubernetes: false,
2624
schemas: [
2725
{
28-
uri: 'https://tutorialkit.dev/schema.json',
26+
uri: 'https://tutorialkit.dev/reference/configuration/',
2927
schema,
3028
fileMatch: [
3129
'**/*',

packages/types/src/schemas/chapter.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import { baseSchema } from './common.js';
33

44
export const chapterSchema = baseSchema.extend({
55
type: z.literal('chapter'),
6-
lessons: z.array(z.string()).optional(),
6+
lessons: z
7+
.array(z.string())
8+
.optional()
9+
.describe(
10+
'The list of lessons in this chapter. The order in this array defines the order of the lessons. If not specified a folder-based numbering system is used instead.',
11+
),
712
});
813

914
export type ChapterSchema = z.infer<typeof chapterSchema>;

packages/types/src/schemas/common.ts

Lines changed: 93 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,21 @@ export const commandSchema = z.union([
99
z.tuple([z.string(), z.string()]),
1010

1111
z.strictObject({
12-
command: z.string(),
13-
title: z.string(),
12+
command: z.string().describe('Command to execute in WebContainer.'),
13+
title: z.string().describe('Title to show for this step in the Prepare Environment section.'),
1414
}),
1515
]);
1616

1717
export type CommandSchema = z.infer<typeof commandSchema>;
1818

1919
export const commandsSchema = z.object({
20-
mainCommand: commandSchema.optional(),
21-
prepareCommands: commandSchema.array().optional(),
20+
mainCommand: commandSchema.optional().describe('The last command to be executed. Typically a dev server.'),
21+
prepareCommands: commandSchema
22+
.array()
23+
.optional()
24+
.describe(
25+
'List of commands to be executed to prepare the environment in WebContainer. Each command executed and its status will be shown in the Prepare Environment section.',
26+
),
2227
});
2328

2429
export type CommandsSchema = z.infer<typeof commandsSchema>;
@@ -36,16 +41,28 @@ export const previewSchema = z.union([
3641
z.tuple([z.number(), z.string()]),
3742

3843
z.strictObject({
39-
port: z.number(),
40-
title: z.string(),
44+
port: z.number().describe('Port number of the preview.'),
45+
title: z.string().describe('Title of the preview.'),
4146
}),
4247
])
4348
.array(),
4449
]);
4550

4651
export type PreviewSchema = z.infer<typeof previewSchema>;
4752

48-
const panelType = z.union([z.literal('output'), z.literal('terminal')]);
53+
const panelTypeSchema = z
54+
.union([z.literal('output'), z.literal('terminal')])
55+
.describe(`The type of the terminal which can either be 'output' or 'terminal'.`);
56+
57+
const allowRedirectsSchema = z
58+
.boolean()
59+
.optional()
60+
.describe('`true` if you want to enable output redirects in the terminal, disabled by default.');
61+
62+
const allowCommandsSchema = z
63+
.array(z.string())
64+
.optional()
65+
.describe('List of command that are allowed in the terminal, if not provided, all commands are allowed.');
4966

5067
export const terminalSchema = z.union([
5168
// `false` if you want to disable the terminal entirely
@@ -67,12 +84,12 @@ export const terminalSchema = z.union([
6784
.array(
6885
z.union([
6986
// the type of the panel
70-
panelType,
87+
panelTypeSchema,
7188

7289
// or a tuple with the type and the title of the panel
7390
z.tuple([
7491
// the type of the panel
75-
panelType,
92+
panelTypeSchema,
7693

7794
// the title of the panel which is shown in the tab
7895
z.string(),
@@ -81,19 +98,24 @@ export const terminalSchema = z.union([
8198
// or an object defining the panel
8299
z.strictObject({
83100
// the type of the panel
84-
type: panelType,
101+
type: panelTypeSchema,
85102

86103
// an id linking the terminal of multiple lessons together
87-
id: z.string().optional(),
104+
id: z
105+
.string()
106+
.optional()
107+
.describe(
108+
'An id linking the terminal of multiple lessons together so that its state is preserved between lessons.',
109+
),
88110

89111
// the title of the panel which is shown in the tab
90-
title: z.string().optional(),
112+
title: z.string().optional().describe('The title of the panel which is shown in the tab.'),
91113

92114
// `true` if you want to enable output redirects in the terminal, disabled by default
93-
allowRedirects: z.boolean().optional(),
115+
allowRedirects: allowRedirectsSchema,
94116

95117
// list of command that are allowed in the terminal, if not provided, all commands are allowed
96-
allowCommands: z.array(z.string()).optional(),
118+
allowCommands: allowCommandsSchema,
97119
}),
98120
]),
99121
)
@@ -122,35 +144,62 @@ export const terminalSchema = z.union([
122144
},
123145
),
124146
]),
125-
activePanel: z.number().gte(0).optional(),
147+
activePanel: z.number().gte(0).optional().describe('Defines which panel should be visible by default.'),
126148

127149
// `true` if you want to enable output redirects in the terminal, disabled by default
128-
allowRedirects: z.boolean().optional(),
150+
allowRedirects: allowRedirectsSchema,
129151

130152
// list of command that are allowed in the terminal, if not provided, all commands are allowed
131-
allowCommands: z.array(z.string()).optional(),
153+
allowCommands: allowCommandsSchema,
132154
}),
133155
]);
134156

135-
export type TerminalPanelType = z.infer<typeof panelType>;
157+
export type TerminalPanelType = z.infer<typeof panelTypeSchema>;
136158
export type TerminalSchema = z.infer<typeof terminalSchema>;
137159

138160
export const webcontainerSchema = commandsSchema.extend({
139-
previews: previewSchema.optional(),
140-
autoReload: z.boolean().optional(),
141-
template: z.string().optional(),
142-
terminal: terminalSchema.optional(),
143-
focus: z.string().optional(),
144-
editor: z.union([
145-
// can either be completely removed by setting it to `false`
146-
z.boolean().optional(),
147-
148-
// or you can only remove the file tree
149-
z.strictObject({
150-
fileTree: z.boolean().optional(),
151-
}),
152-
]),
153-
i18n: i18nSchema.optional(),
161+
previews: previewSchema
162+
.optional()
163+
.describe(
164+
'Configure which ports should be used for the previews allowing you to align the behavior with your demo application’s dev server setup. If not specified, the lowest port will be used.',
165+
),
166+
autoReload: z
167+
.boolean()
168+
.optional()
169+
.describe(
170+
'Navigating to a lesson that specifies autoReload will always reload the preview. This is typically only needed if your server does not support HMR.',
171+
),
172+
template: z
173+
.string()
174+
.optional()
175+
.describe(
176+
'Specified which folder from the src/templates/ directory should be used as the basis for the code. See the “Code templates” guide for a detailed explainer.',
177+
),
178+
terminal: terminalSchema
179+
.optional()
180+
.describe(
181+
'Configures one or more terminals. TutorialKit provides two types of terminals: read-only, called output, and interactive, called terminal.',
182+
),
183+
focus: z
184+
.string()
185+
.optional()
186+
.describe('Defines which file should be opened in the code editor by default when lesson loads.'),
187+
editor: z
188+
.union([
189+
// can either be completely removed by setting it to `false`
190+
z.boolean().optional(),
191+
192+
// or you can only remove the file tree
193+
z.strictObject({
194+
fileTree: z.boolean().optional(),
195+
}),
196+
])
197+
.describe(
198+
'Configure whether or not the editor should be rendered. If an object is provided with fileTree: false, only the file tree is hidden.',
199+
),
200+
i18n: i18nSchema
201+
.optional()
202+
.describe('Lets you define alternative texts used in the UI. This is useful for localization.'),
154203
editPageLink: z
155204
.union([
156205
// pattern for creating the URL
@@ -159,12 +208,20 @@ export const webcontainerSchema = commandsSchema.extend({
159208
// `false` for disabling the edit link
160209
z.boolean(),
161210
])
162-
.optional(),
211+
.optional()
212+
.describe(
213+
'Display a link in lesson for editing the page content. The value is a URL pattern where ${path} is replaced with the lesson’s location relative to src/content/tutorial.',
214+
),
163215
});
164216

165217
export const baseSchema = webcontainerSchema.extend({
166-
title: z.string(),
167-
slug: z.string().optional(),
218+
title: z.string().describe('The title of the part, chapter, or lesson.'),
219+
slug: z
220+
.string()
221+
.optional()
222+
.describe(
223+
'Customize the URL segment of this part / chapter or lesson. The full URL path is /:partSlug/:chapterSlug/:lessonSlug.',
224+
),
168225
});
169226

170227
export type BaseSchema = z.infer<typeof baseSchema>;

packages/types/src/schemas/i18n.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,64 +6,69 @@ export const i18nSchema = z.object({
66
*
77
* @default 'Part ${index}: ${title}'
88
*/
9-
partTemplate: z.string().optional(),
9+
partTemplate: z.string().optional().describe('Template on how to format a part. Variables: ${index} and ${title}.'),
1010

1111
/**
1212
* Text of the edit page link.
1313
*
1414
* @default 'Edit this page'
1515
*/
16-
editPageText: z.string().optional(),
16+
editPageText: z.string().optional().describe('Text of the edit page link.'),
1717

1818
/**
1919
* Text shown when there are no previews or steps to show in the prepare environment section.
2020
*
2121
* @default 'Start WebContainer'
2222
*/
23-
startWebContainerText: z.string().optional(),
23+
startWebContainerText: z
24+
.string()
25+
.optional()
26+
.describe('Text shown when there are no previews or steps to show in the prepare environment section.'),
2427

2528
/**
26-
* Text shown on the call to action button to start webcontainer when boot was blocked
27-
* due to memory restrictions.
29+
* Text shown in the preview section when there are no steps to run and no preview to show.
2830
*
2931
* @default 'No preview to run nor steps to show'
3032
*/
31-
noPreviewNorStepsText: z.string().optional(),
33+
noPreviewNorStepsText: z
34+
.string()
35+
.optional()
36+
.describe('Text shown in the preview section when there are no steps to run and no preview to show.'),
3237

3338
/**
3439
* Text shown on top of the file tree.
3540
*
3641
* @default 'Files'
3742
*/
38-
filesTitleText: z.string().optional(),
43+
filesTitleText: z.string().optional().describe('Text shown on top of the file tree.'),
3944

4045
/**
4146
* Text shown on top of the steps section.
4247
*
4348
* @default 'Preparing Environment'
4449
*/
45-
prepareEnvironmentTitleText: z.string().optional(),
50+
prepareEnvironmentTitleText: z.string().optional().describe('Text shown on top of the steps section.'),
4651

4752
/**
4853
* Text shown for the toggle terminal button.
4954
*
5055
* @default 'Toggle Terminal'
5156
*/
52-
toggleTerminalButtonText: z.string().optional(),
57+
toggleTerminalButtonText: z.string().optional().describe('Text shown for the toggle terminal button.'),
5358

5459
/**
5560
* Text shown for the solve button.
5661
*
5762
* @default 'Solve'
5863
*/
59-
solveButtonText: z.string().optional(),
64+
solveButtonText: z.string().optional().describe('Text shown for the solve button.'),
6065

6166
/**
6267
* Text shown for the reset button.
6368
*
6469
* @default 'Reset'
6570
*/
66-
resetButtonText: z.string().optional(),
71+
resetButtonText: z.string().optional().describe('Text shown for the reset button.'),
6772
});
6873

6974
export type I18nSchema = z.infer<typeof i18nSchema>;

packages/types/src/schemas/lesson.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ import { baseSchema } from './common.js';
33

44
export const lessonSchema = baseSchema.extend({
55
type: z.literal('lesson'),
6-
scope: z.string().optional(),
7-
hideRoot: z.boolean().optional(),
6+
scope: z.string().optional().describe('A prefix that all file paths must match to be visible in the file tree.'),
7+
hideRoot: z
8+
.boolean()
9+
.optional()
10+
.describe('If set to false, `/` is shown at the top of the file tree. Defaults to true.'),
811
});
912

1013
export type LessonSchema = z.infer<typeof lessonSchema>;

packages/types/src/schemas/part.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import { baseSchema } from './common.js';
33

44
export const partSchema = baseSchema.extend({
55
type: z.literal('part'),
6-
chapters: z.array(z.string()).optional(),
6+
chapters: z
7+
.array(z.string())
8+
.optional()
9+
.describe(
10+
'The list of chapters in this part. The order in this array defines the order of the chapters. If not specified a folder-based numbering system is used instead.',
11+
),
712
});
813

914
export type PartSchema = z.infer<typeof partSchema>;

packages/types/src/schemas/tutorial.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ import { webcontainerSchema } from './common.js';
44
export const tutorialSchema = webcontainerSchema.extend({
55
type: z.literal('tutorial'),
66
logoLink: z.string().optional(),
7-
parts: z.array(z.string()).optional(),
7+
parts: z
8+
.array(z.string())
9+
.optional()
10+
.describe(
11+
'The list of parts in this tutorial. The order in this array defines the order of the parts. If not specified a folder-based numbering system is used instead.',
12+
),
813
});
914

1015
export type TutorialSchema = z.infer<typeof tutorialSchema>;

0 commit comments

Comments
 (0)