From 1c79d9b7457fb842212744e2c6695e30ae66cf48 Mon Sep 17 00:00:00 2001 From: YRM Date: Tue, 2 Jan 2024 23:41:53 +0800 Subject: [PATCH] feat: support create-svelte --- README.md | 2 + package.json | 61 +++++++++++++++++++++++- pnpm-lock.yaml | 78 +++++++++++++++++++++++++++++++ resources/svelte.svg | 1 + src/commands/starter.ts | 101 ++++++++++++++++++++++++++++++++++++++++ src/config.ts | 16 +++++++ tsup.config.ts | 6 ++- 7 files changed, 263 insertions(+), 2 deletions(-) create mode 100644 resources/svelte.svg diff --git a/README.md b/README.md index 6546d07..21dec13 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ Kickstart your project with a Starter Template in VSCode

Preview 1 + Preview 2

@@ -41,6 +42,7 @@ Kickstart your project with a Starter Template in VSCode - [Vitesse](https://github.com/antfu/vitesse) - Opinionated starter template. - [Vitesse Lite](https://github.com/antfu/vitesse-lite) - Lightweight version of Vitesse. - [Create Next App](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) - The easiest way to get started with Next.js. +- [Create Svelte](https://github.com/sveltejs/kit/tree/main/packages/create-svelte) - Create new SvelteKit projects. - [Starter TS](https://github.com/antfu/starter-ts) - Starter template for TypeScript library. - [Starter VSCode](https://github.com/antfu/starter-vscode) - Starter template for VS Code Extension. - [Vitesse WebExt](https://github.com/antfu/vitesse-webext) - WebExtension Vite Starter Template. diff --git a/package.json b/package.json index 4b36efe..6bdd0c3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "publisher": "YRM", "name": "starter-templates", "displayName": "Starter Templates", - "version": "0.7.0", + "version": "0.8.0", "description": "Kickstart your project with a Starter Template in VSCode", "license": "MIT", "repository": { @@ -162,6 +162,62 @@ "scope": "window" } } + }, + { + "title": "Create Svelte(Official)", + "order": 4, + "properties": { + "starterTemplates.createSvelte.whichAppTemplate": { + "enum": [ + "default", + "skeleton", + "skeletonlib" + ], + "default": "default", + "description": "Which Svelte app template?", + "scope": "window" + }, + "starterTemplates.createSvelte.addTypeCheckingWith": { + "enum": [ + "checkjs", + "typescript", + "no" + ], + "default": "typescript", + "markdownDescription": "Add type checking with TypeScript?", + "scope": "window" + }, + "starterTemplates.createSvelte.needsEslint": { + "type": "boolean", + "default": true, + "markdownDescription": "Add ESLint for code linting?", + "scope": "window" + }, + "starterTemplates.createSvelte.needsPrettier": { + "type": "boolean", + "default": true, + "markdownDescription": "Add Prettier for code formatting?", + "scope": "window" + }, + "starterTemplates.createSvelte.needsPlaywright": { + "type": "boolean", + "default": true, + "markdownDescription": "Add Playwright for browser testing?", + "scope": "window" + }, + "starterTemplates.createSvelte.needsVitest": { + "type": "boolean", + "default": true, + "markdownDescription": "Add Vitest for unit testing?", + "scope": "window" + }, + "starterTemplates.createSvelte.trySvelte5Preview": { + "type": "boolean", + "default": true, + "markdownDescription": "Try the Svelte 5 preview (unstable!)?", + "scope": "window" + } + } } ] }, @@ -178,6 +234,7 @@ "devDependencies": { "@antfu/eslint-config": "^2.4.6", "@types/degit": "^2.8.6", + "@types/fs-extra": "^11.0.4", "@types/mocha": "^10.0.6", "@types/node": "18.x", "@types/vscode": "^1.85.0", @@ -185,9 +242,11 @@ "@typescript-eslint/parser": "^6.13.1", "@vscode/test-cli": "^0.0.4", "@vscode/test-electron": "^2.3.8", + "create-svelte": "^6.0.5", "degit": "^2.8.4", "eslint": "^8.54.0", "execa": "^8.0.1", + "fs-extra": "^11.2.0", "nypm": "^0.3.3", "tsup": "^8.0.1", "typescript": "^5.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c2b490a..f0f6977 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ devDependencies: '@types/degit': specifier: ^2.8.6 version: 2.8.6 + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 '@types/mocha': specifier: ^10.0.6 version: 10.0.6 @@ -32,6 +35,9 @@ devDependencies: '@vscode/test-electron': specifier: ^2.3.8 version: 2.3.8 + create-svelte: + specifier: ^6.0.5 + version: 6.0.5 degit: specifier: ^2.8.4 version: 2.8.4 @@ -41,6 +47,9 @@ devDependencies: execa: specifier: ^8.0.1 version: 8.0.1 + fs-extra: + specifier: ^11.2.0 + version: 11.2.0 nypm: specifier: ^0.3.3 version: 0.3.3 @@ -192,6 +201,23 @@ packages: to-fast-properties: 2.0.0 dev: true + /@clack/core@0.3.3: + resolution: {integrity: sha512-5ZGyb75BUBjlll6eOa1m/IZBxwk91dooBWhPSL67sWcLS0zt9SnswRL0l26TVdBhb0wnWORRxUn//uH6n4z7+A==} + dependencies: + picocolors: 1.0.0 + sisteransi: 1.0.5 + dev: true + + /@clack/prompts@0.7.0: + resolution: {integrity: sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==} + dependencies: + '@clack/core': 0.3.3 + picocolors: 1.0.0 + sisteransi: 1.0.5 + dev: true + bundledDependencies: + - is-unicode-supported + /@es-joy/jsdoccomment@0.41.0: resolution: {integrity: sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==} engines: {node: '>=16'} @@ -726,10 +752,23 @@ packages: resolution: {integrity: sha512-y0M7sqzsnHB6cvAeTCBPrCQNQiZe8U4qdzf8uBVmOWYap5MMTN/gB2iEqrIqFiYcsyvP74GnGD5tgsHttielFw==} dev: true + /@types/fs-extra@11.0.4: + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 18.19.3 + dev: true + /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true + /@types/jsonfile@6.1.4: + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + dependencies: + '@types/node': 18.19.3 + dev: true + /@types/mdast@3.0.15: resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} dependencies: @@ -1284,6 +1323,14 @@ packages: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true + /create-svelte@6.0.5: + resolution: {integrity: sha512-BnACeq5tHhL7cbMlVQMVCFNocVTpRSbiXqYJnPhK3CVWPz3+hodu08TqozEu+RNdVCoARsci50pTv7axetGLlg==} + hasBin: true + dependencies: + '@clack/prompts': 0.7.0 + kleur: 4.1.5 + dev: true + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1978,6 +2025,15 @@ packages: signal-exit: 4.1.0 dev: true + /fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: true + /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true @@ -2082,6 +2138,10 @@ packages: slash: 3.0.0 dev: true + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: true @@ -2350,6 +2410,14 @@ packages: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} dev: true + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + /jszip@3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} dependencies: @@ -2370,6 +2438,11 @@ packages: engines: {node: '>=6'} dev: true + /kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: true + /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -3368,6 +3441,11 @@ packages: '@types/unist': 2.0.10 dev: true + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + dev: true + /update-browserslist-db@1.0.13(browserslist@4.22.2): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true diff --git a/resources/svelte.svg b/resources/svelte.svg new file mode 100644 index 0000000..bb9e1fc --- /dev/null +++ b/resources/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/commands/starter.ts b/src/commands/starter.ts index 2378acf..41dc66b 100644 --- a/src/commands/starter.ts +++ b/src/commands/starter.ts @@ -3,6 +3,7 @@ import * as path from 'node:path' import { chdir, cwd } from 'node:process' import type { InputBoxValidationMessage, QuickPickItem } from 'vscode' import { ProgressLocation, QuickPickItemKind, Uri, commands, window } from 'vscode' +import { create } from 'create-svelte' import degit from 'degit' import { $ } from 'execa' import { installDependencies } from 'nypm' @@ -62,6 +63,9 @@ export class StarterCommands extends BaseCommands { case 'create-next-app': await this.handleCreateNextApp(projectName) break + case 'create-svelte': + await this.handleCreateSvelte(projectName, projectPath!) + break case 'starter-ts': await degit('antfu/starter-ts').clone(`${projectPath}`) break @@ -82,6 +86,7 @@ export class StarterCommands extends BaseCommands { return 0 } catch (error) { + console.log(error) window.showErrorMessage('Failed to create prpject!') return -1 } @@ -118,6 +123,19 @@ export class StarterCommands extends BaseCommands { } } + private async handleCreateSvelte(projectName: string, projectPath: string) { + await create(projectPath, { + name: projectName, + template: config.createSvelteWhichAppTemplate, + types: config.createSvelteAddTypeCheckingWith === 'no' ? null : config.createSvelteAddTypeCheckingWith, + eslint: config.createSvelteNeedsEslint, + prettier: config.createSvelteNeedsPrettier, + playwright: config.createSvelteNeedsPlaywright, + vitest: config.createSvelteNeedsVitest, + svelte5: config.createSvelteTrySvelte5Preview, + }) + } + private async handleCreateNextApp(projectName: string) { const args = [] if (config.createNextAppNeedsTypeScript) @@ -272,6 +290,19 @@ export class StarterCommands extends BaseCommands { detail: 'The easiest way to get started with Next.js', template: { id: 'create-next-app', defaultProjectName: 'next-project' }, }, + { + kind: QuickPickItemKind.Separator, + label: 'Svelte', + }, + { + label: 'Create Svelte(Official)', + iconPath: { + dark: Uri.file(this.context.asAbsolutePath('resources/svelte.svg')), + light: Uri.file(this.context.asAbsolutePath('resources/svelte.svg')), + }, + detail: 'Create new SvelteKit projects', + template: { id: 'create-svelte', defaultProjectName: 'svelte-project' }, + }, { kind: QuickPickItemKind.Separator, label: 'TypeScript Library', @@ -391,6 +422,8 @@ export class StarterCommands extends BaseCommands { return [...this.getCurrentCreateSettingsOfCreateVue(), ...this.getGlobalSettings()] case 'create-next-app': return this.getCurrentCreateSettingsOfCreateNextApp() + case 'create-svelte': + return [...this.getCurrentCreateSettingsOfCreateSvelte(), ...this.getGlobalSettings()] default: return this.getGlobalSettings() } @@ -569,6 +602,74 @@ export class StarterCommands extends BaseCommands { return createNextAppSettings } + private getCurrentCreateSettingsOfCreateSvelte() { + const createSvelteSettings: PickableSetting[] = [ + { + kind: QuickPickItemKind.Separator, + label: 'Create Svelte', + }, + { + currentValue: config.createSvelteWhichAppTemplate || 'default', + description: config.createSvelteWhichAppTemplate || 'default', + detail: '', + enumValues: ['default', 'skeleton', 'skeletonlib'], + label: 'Which Svelte app template?', + setValue: (newValue: 'default' | 'skeleton' | 'skeletonlib') => config.setCreateSvelteWhichAppTemplate(newValue), + settingKind: 'ENUM', + }, + { + currentValue: config.createSvelteAddTypeCheckingWith || 'typescript', + description: config.createSvelteAddTypeCheckingWith || 'typescript', + detail: '', + enumValues: ['checkjs', 'typescript', 'no'], + label: 'Add type checking with TypeScript?', + setValue: (newValue: 'checkjs' | 'typescript' | 'no') => config.setCreateSvelteAddTypeCheckingWith(newValue), + settingKind: 'ENUM', + }, + { + currentValue: config.createSvelteNeedsEslint ? 'Yes' : 'No', + description: config.createSvelteNeedsEslint ? 'Yes' : 'No', + detail: '', + label: 'Add ESLint for code linting?', + setValue: (newValue: boolean) => config.setCreateSvelteNeedsEslint(newValue), + settingKind: 'BOOL', + }, + { + currentValue: config.createSvelteNeedsPrettier ? 'Yes' : 'No', + description: config.createSvelteNeedsPrettier ? 'Yes' : 'No', + detail: '', + label: 'Add Prettier for code formatting?', + setValue: (newValue: boolean) => config.setCreateSvelteNeedsPrettier(newValue), + settingKind: 'BOOL', + }, + { + currentValue: config.createSvelteNeedsPlaywright ? 'Yes' : 'No', + description: config.createSvelteNeedsPlaywright ? 'Yes' : 'No', + detail: '', + label: 'Add Playwright for browser testing?', + setValue: (newValue: boolean) => config.setCreateSvelteNeedsPlaywright(newValue), + settingKind: 'BOOL', + }, + { + currentValue: config.createSvelteNeedsVitest ? 'Yes' : 'No', + description: config.createSvelteNeedsVitest ? 'Yes' : 'No', + detail: '', + label: 'Add Vitest for unit testing?', + setValue: (newValue: boolean) => config.setCreateSvelteNeedsVitest(newValue), + settingKind: 'BOOL', + }, + { + currentValue: config.createSvelteTrySvelte5Preview ? 'Yes' : 'No', + description: config.createSvelteTrySvelte5Preview ? 'Yes' : 'No', + detail: '', + label: 'Try the Svelte 5 preview (unstable!)?', + setValue: (newValue: boolean) => config.setCreateSvelteTrySvelte5Preview(newValue), + settingKind: 'BOOL', + } + ] + return createSvelteSettings + } + private validateCreateNextAppImportAlias(input: string): string | InputBoxValidationMessage | undefined | null | Thenable { if (!/^.+\/\*$/.test(input)) diff --git a/src/config.ts b/src/config.ts index db581a6..aca5499 100644 --- a/src/config.ts +++ b/src/config.ts @@ -54,6 +54,14 @@ class Config { get createNextAppNeedsSrcDirectory(): boolean { return this.getConfig('createNextApp.needsSrcDirectory', true) } get createNextAppNeedsAppRouter(): boolean { return this.getConfig('createNextApp.needsAppRouter', true) } get createNextAppCustomizeTheDefaultImportAlias(): string { return this.getConfig('createNextApp.customizeTheDefaultImportAlias', '@/*') } + // create svelte + get createSvelteWhichAppTemplate(): 'default' | 'skeleton' | 'skeletonlib' { return this.getConfig<'default' | 'skeleton' | 'skeletonlib'>('createSvelte.whichAppTemplate', 'default') } + get createSvelteAddTypeCheckingWith(): 'checkjs' | 'typescript' | 'no' { return this.getConfig<'checkjs' | 'typescript' | 'no'>('createSvelte.addTypeCheckingWith', 'typescript') } + get createSvelteNeedsEslint(): boolean { return this.getConfig('createSvelte.needsEslint', true) } + get createSvelteNeedsPrettier(): boolean { return this.getConfig('createSvelte.needsPrettier', true) } + get createSvelteNeedsPlaywright(): boolean { return this.getConfig('createSvelte.needsPlaywright', true) } + get createSvelteNeedsVitest(): boolean { return this.getConfig('createSvelte.needsVitest', true) } + get createSvelteTrySvelte5Preview(): boolean { return this.getConfig('createSvelte.trySvelte5Preview', true) } // global settings get globalNeedsGitInit(): boolean { return this.getConfig('globalSettings.needsGitInit', true) } get globalNeedsInstall(): boolean { return this.getConfig('globalSettings.needsInstall', true) } @@ -75,6 +83,14 @@ class Config { public setCreateNextAppNeedsSrcDirectory(value: boolean): Promise { return this.setConfig('createNextApp.needsSrcDirectory', value, ConfigurationTarget.Global) } public setCreateNextAppNeedsAppRouter(value: boolean): Promise { return this.setConfig('createNextApp.needsAppRouter', value, ConfigurationTarget.Global) } public setCreateNextAppCustomizeTheDefaultImportAlias(value: string): Promise { return this.setConfig('createNextApp.customizeTheDefaultImportAlias', value, ConfigurationTarget.Global) } + // create svelte + public setCreateSvelteWhichAppTemplate(value: 'default' | 'skeleton' | 'skeletonlib'): Promise { return this.setConfig('createSvelte.whichAppTemplate', value, ConfigurationTarget.Global) } + public setCreateSvelteAddTypeCheckingWith(value: 'checkjs' | 'typescript' | 'no'): Promise { return this.setConfig('createSvelte.addTypeCheckingWith', value, ConfigurationTarget.Global) } + public setCreateSvelteNeedsEslint(value: boolean): Promise { return this.setConfig('createSvelte.needsEslint', value, ConfigurationTarget.Global) } + public setCreateSvelteNeedsPrettier(value: boolean): Promise { return this.setConfig('createSvelte.needsPrettier', value, ConfigurationTarget.Global) } + public setCreateSvelteNeedsPlaywright(value: boolean): Promise { return this.setConfig('createSvelte.needsPlaywright', value, ConfigurationTarget.Global) } + public setCreateSvelteNeedsVitest(value: boolean): Promise { return this.setConfig('createSvelte.needsVitest', value, ConfigurationTarget.Global) } + public setCreateSvelteTrySvelte5Preview(value: boolean): Promise { return this.setConfig('createSvelte.trySvelte5Preview', value, ConfigurationTarget.Global) } // global settings public setGlobalNeedsGitInit(value: boolean): Promise { return this.setConfig('globalSettings.needsGitInit', value, ConfigurationTarget.Global) } public setGlobalNeedsInstall(value: boolean): Promise { return this.setConfig('globalSettings.needsInstall', value, ConfigurationTarget.Global) } diff --git a/tsup.config.ts b/tsup.config.ts index 747332d..a8123da 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -1,3 +1,4 @@ +import fs from 'fs-extra' import { defineConfig } from 'tsup' export default defineConfig({ @@ -5,9 +6,12 @@ export default defineConfig({ 'src/index.ts', ], format: ['cjs'], - shims: false, + shims: true, dts: false, external: [ 'vscode', ], + async onSuccess() { + fs.copySync('./node_modules/create-svelte/dist', './dist/dist', { overwrite: true }); + }, })