Skip to content

Commit 2a0c8a0

Browse files
authored
feat: add xxxProps support to VS Code snippets (#2796)
fixes: #2782
1 parent 314ad4d commit 2a0c8a0

File tree

14 files changed

+1216
-147
lines changed

14 files changed

+1216
-147
lines changed

packages/svelte-vscode/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"build": "npm run build:ts && npm run build:grammar",
1010
"vscode:prepublish": "npm install && npm run build && npm prune --production",
1111
"watch": "npm run build:grammar && tsc -w -p ./",
12-
"test": "npm run build:grammar && node test/grammar/test.js"
12+
"test": "npm run build:grammar && node test/grammar/test.js && vitest --run"
1313
},
1414
"repository": {
1515
"type": "git",
@@ -745,6 +745,7 @@
745745
"js-yaml": "^3.14.0",
746746
"tslib": "^2.4.0",
747747
"typescript": "^5.8.2",
748+
"vitest": "^3.2.4",
748749
"vscode-tmgrammar-test": "^0.0.11"
749750
},
750751
"dependencies": {

packages/svelte-vscode/src/sveltekit/generateFiles/index.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { commands, ExtensionContext, ProgressLocation, Uri, window, workspace }
33
import { addResourceCommandMap } from './commands';
44
import { generateResources } from './generate';
55
import { resourcesMap } from './resources';
6-
import { FileType, ResourceType, GenerateConfig, CommandType, ProjectType } from './types';
7-
import { checkProjectType } from '../utils';
6+
import { FileType, ResourceType, GenerateConfig, CommandType } from './types';
7+
import { checkProjectKind } from '../utils';
88

99
class GenerateError extends Error {}
1010

@@ -38,7 +38,7 @@ async function handleSingle(uri: Uri | undefined, resourceType: ResourceType) {
3838
}
3939
const resources = [resource];
4040

41-
const { type, rootPath, scriptExtension } = await getCommonConfig(uri);
41+
const { kind, rootPath, scriptExtension } = await getCommonConfig(uri);
4242

4343
const itemPath = await promptResourcePath();
4444

@@ -48,15 +48,15 @@ async function handleSingle(uri: Uri | undefined, resourceType: ResourceType) {
4848

4949
await generate({
5050
path: path.join(rootPath, itemPath),
51-
type,
51+
kind,
5252
pageExtension: 'svelte',
5353
scriptExtension,
5454
resources
5555
});
5656
}
5757

5858
async function handleMultiple(uri: Uri | undefined) {
59-
const { type, rootPath, scriptExtension } = await getCommonConfig(uri);
59+
const { kind, rootPath, scriptExtension } = await getCommonConfig(uri);
6060
const itemPath = await promptResourcePath();
6161

6262
if (!itemPath) {
@@ -92,7 +92,7 @@ async function handleMultiple(uri: Uri | undefined) {
9292

9393
await generate({
9494
path: path.join(rootPath, itemPath),
95-
type,
95+
kind,
9696
pageExtension: 'svelte',
9797
scriptExtension,
9898
resources: result.map((res) => res.value)
@@ -125,17 +125,17 @@ async function getCommonConfig(uri: Uri | undefined) {
125125
);
126126
}
127127

128-
const type = await checkProjectType(rootPath);
129-
const scriptExtension = getScriptExtension(type);
128+
const kind = await checkProjectKind(rootPath);
129+
const scriptExtension = getScriptExtension(kind);
130130
return {
131-
type,
131+
kind,
132132
scriptExtension,
133133
rootPath
134134
} as const;
135135
}
136136

137-
function getScriptExtension(type: ProjectType) {
138-
return type === ProjectType.JS || type === ProjectType.JS_SV5 ? 'js' : 'ts';
137+
function getScriptExtension(kind: GenerateConfig['kind']) {
138+
return kind.withTs ? 'ts' : 'js';
139139
}
140140

141141
function getRootPath(uri: Uri | undefined) {
Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GenerateConfig, ProjectType, Resource } from '../types';
1+
import { GenerateConfig, Resource } from '../types';
22

33
const defaultScriptTemplate = `
44
<script>
@@ -16,15 +16,13 @@ const tsScriptTemplate = `
1616
<h1>{$page.status}: {$page.error?.message}</h1>
1717
`;
1818

19-
const scriptTemplate: ReadonlyMap<ProjectType, string> = new Map([
20-
[ProjectType.TS_SV5, tsScriptTemplate],
21-
[ProjectType.TS_SATISFIES_SV5, tsScriptTemplate],
22-
[ProjectType.JS_SV5, defaultScriptTemplate],
23-
[ProjectType.TS, tsScriptTemplate],
24-
[ProjectType.TS_SATISFIES, tsScriptTemplate],
25-
[ProjectType.JS, defaultScriptTemplate]
26-
]);
27-
2819
export default async function (config: GenerateConfig): ReturnType<Resource['generate']> {
29-
return (scriptTemplate.get(config.type) ?? defaultScriptTemplate).trim();
20+
const { withTs } = config.kind;
21+
let template = defaultScriptTemplate;
22+
23+
if (withTs) {
24+
template = tsScriptTemplate;
25+
}
26+
27+
return template.trim();
3028
}

packages/svelte-vscode/src/sveltekit/generateFiles/templates/layout-load.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GenerateConfig, ProjectType, Resource } from '../types';
1+
import { GenerateConfig, Resource } from '../types';
22

33
const defaultScriptTemplate = `
44
/** @type {import('./$types').LayoutLoad} */
@@ -23,15 +23,15 @@ export const load = (async () => {
2323
}) satisfies LayoutLoad;
2424
`;
2525

26-
const scriptTemplate: ReadonlyMap<ProjectType, string> = new Map([
27-
[ProjectType.TS_SV5, tsScriptTemplate],
28-
[ProjectType.TS_SATISFIES_SV5, tsSatisfiesScriptTemplate],
29-
[ProjectType.JS_SV5, defaultScriptTemplate],
30-
[ProjectType.TS, tsScriptTemplate],
31-
[ProjectType.TS_SATISFIES, tsSatisfiesScriptTemplate],
32-
[ProjectType.JS, defaultScriptTemplate]
33-
]);
34-
3526
export default async function (config: GenerateConfig): ReturnType<Resource['generate']> {
36-
return (scriptTemplate.get(config.type) ?? defaultScriptTemplate).trim();
27+
const { withTs, withSatisfies } = config.kind;
28+
let template = defaultScriptTemplate;
29+
30+
if (withTs && withSatisfies) {
31+
template = tsSatisfiesScriptTemplate;
32+
} else if (withTs && !withSatisfies) {
33+
template = tsScriptTemplate;
34+
}
35+
36+
return template.trim();
3737
}

packages/svelte-vscode/src/sveltekit/generateFiles/templates/layout-server.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GenerateConfig, ProjectType, Resource } from '../types';
1+
import { GenerateConfig, Resource } from '../types';
22

33
const defaultScriptTemplate = `
44
/** @type {import('./$types').LayoutServerLoad} */
@@ -23,15 +23,15 @@ export const load = (async () => {
2323
}) satisfies LayoutServerLoad;
2424
`;
2525

26-
const scriptTemplate: ReadonlyMap<ProjectType, string> = new Map([
27-
[ProjectType.TS_SV5, tsScriptTemplate],
28-
[ProjectType.TS_SATISFIES_SV5, tsSatisfiesScriptTemplate],
29-
[ProjectType.JS_SV5, defaultScriptTemplate],
30-
[ProjectType.TS, tsScriptTemplate],
31-
[ProjectType.TS_SATISFIES, tsSatisfiesScriptTemplate],
32-
[ProjectType.JS, defaultScriptTemplate]
33-
]);
34-
3526
export default async function (config: GenerateConfig): ReturnType<Resource['generate']> {
36-
return (scriptTemplate.get(config.type) ?? defaultScriptTemplate).trim();
27+
const { withTs, withSatisfies } = config.kind;
28+
let template = defaultScriptTemplate;
29+
30+
if (withTs && withSatisfies) {
31+
template = tsSatisfiesScriptTemplate;
32+
} else if (withTs && !withSatisfies) {
33+
template = tsScriptTemplate;
34+
}
35+
36+
return template.trim();
3737
}

packages/svelte-vscode/src/sveltekit/generateFiles/templates/layout.ts

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GenerateConfig, ProjectType, Resource } from '../types';
1+
import { GenerateConfig, Resource } from '../types';
22

33
const defaultScriptTemplate = `
44
<script>
@@ -20,6 +20,16 @@ const tsSv5ScriptTemplate = `
2020
{@render children()}
2121
`;
2222

23+
const tsSv5ScriptTemplateProps = `
24+
<script lang="ts">
25+
import type { LayoutProps } from './$types';
26+
27+
let { data, children }: LayoutProps = $props();
28+
</script>
29+
30+
{@render children()}
31+
`;
32+
2333
const tsScriptTemplate = `
2434
<script lang="ts">
2535
import type { LayoutData } from './$types';
@@ -39,15 +49,32 @@ const jsSv5ScriptTemplate = `
3949
{@render children()}
4050
`;
4151

42-
const scriptTemplate: ReadonlyMap<ProjectType, string> = new Map([
43-
[ProjectType.TS_SV5, tsSv5ScriptTemplate],
44-
[ProjectType.TS_SATISFIES_SV5, tsSv5ScriptTemplate],
45-
[ProjectType.JS_SV5, jsSv5ScriptTemplate],
46-
[ProjectType.TS, tsScriptTemplate],
47-
[ProjectType.TS_SATISFIES, tsScriptTemplate],
48-
[ProjectType.JS, defaultScriptTemplate]
49-
]);
52+
const jsSv5ScriptTemplateProps = `
53+
<script>
54+
/** @type {import('./$types').LayoutProps} */
55+
let { data, children } = $props();
56+
</script>
57+
58+
{@render children()}
59+
`;
5060

5161
export default async function (config: GenerateConfig): ReturnType<Resource['generate']> {
52-
return (scriptTemplate.get(config.type) ?? defaultScriptTemplate).trim();
62+
const { withRunes, withTs, withProps } = config.kind;
63+
let template = defaultScriptTemplate;
64+
65+
if (withRunes && withTs && withProps) {
66+
template = tsSv5ScriptTemplateProps;
67+
} else if (withRunes && withTs && !withProps) {
68+
template = tsSv5ScriptTemplate;
69+
} else if (withRunes && !withTs && withProps) {
70+
template = jsSv5ScriptTemplateProps;
71+
} else if (withRunes && !withTs && !withProps) {
72+
template = jsSv5ScriptTemplate;
73+
} else if (!withRunes && withTs) {
74+
template = tsScriptTemplate;
75+
} else if (!withRunes && !withTs) {
76+
template = defaultScriptTemplate;
77+
}
78+
79+
return template.trim();
5380
}

packages/svelte-vscode/src/sveltekit/generateFiles/templates/page-load.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GenerateConfig, ProjectType, Resource } from '../types';
1+
import { GenerateConfig, Resource } from '../types';
22

33
const defaultScriptTemplate = `
44
/** @type {import('./$types').PageLoad} */
@@ -23,15 +23,15 @@ export const load = (async () => {
2323
}) satisfies PageLoad;
2424
`;
2525

26-
const scriptTemplate: ReadonlyMap<ProjectType, string> = new Map([
27-
[ProjectType.TS_SV5, tsScriptTemplate],
28-
[ProjectType.TS_SATISFIES_SV5, tsSatisfiesScriptTemplate],
29-
[ProjectType.JS_SV5, defaultScriptTemplate],
30-
[ProjectType.TS, tsScriptTemplate],
31-
[ProjectType.TS_SATISFIES, tsSatisfiesScriptTemplate],
32-
[ProjectType.JS, defaultScriptTemplate]
33-
]);
34-
3526
export default async function (config: GenerateConfig): ReturnType<Resource['generate']> {
36-
return (scriptTemplate.get(config.type) ?? defaultScriptTemplate).trim();
27+
const { withTs, withSatisfies } = config.kind;
28+
let template = defaultScriptTemplate;
29+
30+
if (withTs && withSatisfies) {
31+
template = tsSatisfiesScriptTemplate;
32+
} else if (withTs && !withSatisfies) {
33+
template = tsScriptTemplate;
34+
}
35+
36+
return template.trim();
3737
}

packages/svelte-vscode/src/sveltekit/generateFiles/templates/page-server.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GenerateConfig, ProjectType, Resource } from '../types';
1+
import { GenerateConfig, Resource } from '../types';
22

33
const defaultScriptTemplate = `
44
/** @type {import('./$types').PageServerLoad} */
@@ -23,15 +23,15 @@ export const load = (async () => {
2323
}) satisfies PageServerLoad;
2424
`;
2525

26-
const scriptTemplate: ReadonlyMap<ProjectType, string> = new Map([
27-
[ProjectType.TS_SV5, tsScriptTemplate],
28-
[ProjectType.TS_SATISFIES_SV5, tsSatisfiesScriptTemplate],
29-
[ProjectType.JS_SV5, defaultScriptTemplate],
30-
[ProjectType.TS, tsScriptTemplate],
31-
[ProjectType.TS_SATISFIES, tsSatisfiesScriptTemplate],
32-
[ProjectType.JS, defaultScriptTemplate]
33-
]);
34-
3526
export default async function (config: GenerateConfig): ReturnType<Resource['generate']> {
36-
return (scriptTemplate.get(config.type) ?? defaultScriptTemplate).trim();
27+
const { withTs, withSatisfies } = config.kind;
28+
let template = defaultScriptTemplate;
29+
30+
if (withTs && withSatisfies) {
31+
template = tsSatisfiesScriptTemplate;
32+
} else if (withTs && !withSatisfies) {
33+
template = tsScriptTemplate;
34+
}
35+
36+
return template.trim();
3737
}
Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GenerateConfig, ProjectType, Resource } from '../types';
1+
import { GenerateConfig, Resource } from '../types';
22

33
const defaultScriptTemplate = `
44
<script>
@@ -7,11 +7,17 @@ const defaultScriptTemplate = `
77
</script>
88
`;
99

10-
const tsSv5ScriptTemplate = `
11-
<script lang="ts">
12-
import type { PageData } from './$types';
10+
const jsSv5ScriptTemplate = `
11+
<script>
12+
/** @type {{ data: import('./$types').PageData }} */
13+
let { data } = $props();
14+
</script>
15+
`;
1316

14-
let { data }: { data: PageData } = $props();
17+
const jsSv5ScriptTemplateProps = `
18+
<script>
19+
/** @type {import('./$types').PageProps} */
20+
let { data } = $props();
1521
</script>
1622
`;
1723

@@ -23,22 +29,39 @@ const tsScriptTemplate = `
2329
</script>
2430
`;
2531

26-
const jsSv5ScriptTemplate = `
27-
<script>
28-
/** @type {{ data: import('./$types').PageData }} */
29-
let { data } = $props();
32+
const tsSv5ScriptTemplate = `
33+
<script lang="ts">
34+
import type { PageData } from './$types';
35+
36+
let { data }: { data: PageData } = $props();
3037
</script>
3138
`;
3239

33-
const scriptTemplate: ReadonlyMap<ProjectType, string> = new Map([
34-
[ProjectType.TS_SV5, tsSv5ScriptTemplate],
35-
[ProjectType.TS_SATISFIES_SV5, tsSv5ScriptTemplate],
36-
[ProjectType.JS_SV5, jsSv5ScriptTemplate],
37-
[ProjectType.TS, tsScriptTemplate],
38-
[ProjectType.TS_SATISFIES, tsScriptTemplate],
39-
[ProjectType.JS, defaultScriptTemplate]
40-
]);
40+
const tsSv5ScriptTemplateProps = `
41+
<script lang="ts">
42+
import type { PageProps } from './$types';
43+
44+
let { data }: PageProps = $props();
45+
</script>
46+
`;
4147

4248
export default async function (config: GenerateConfig): ReturnType<Resource['generate']> {
43-
return (scriptTemplate.get(config.type) ?? defaultScriptTemplate).trim();
49+
const { withProps, withRunes, withTs } = config.kind;
50+
let template = defaultScriptTemplate;
51+
52+
if (withRunes && withTs && withProps) {
53+
template = tsSv5ScriptTemplateProps;
54+
} else if (withRunes && withTs && !withProps) {
55+
template = tsSv5ScriptTemplate;
56+
} else if (withRunes && !withTs && withProps) {
57+
template = jsSv5ScriptTemplateProps;
58+
} else if (withRunes && !withTs && !withProps) {
59+
template = jsSv5ScriptTemplate;
60+
} else if (!withRunes && withTs) {
61+
template = tsScriptTemplate;
62+
} else if (!withRunes && !withTs) {
63+
template = defaultScriptTemplate;
64+
}
65+
66+
return template.trim();
4467
}

0 commit comments

Comments
 (0)