From 1a77b3cbbd031c489c4a876969e59b233128c63b Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sun, 20 Oct 2024 10:28:21 +0200 Subject: [PATCH 001/126] mock api --- packages/core/adder/config.ts | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index f19cb146..c2f6625e 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -25,6 +25,22 @@ export type Scripts = { condition?: ConditionDefinition; }; +// todo: rename +export type FileApi = { + update: (name: string, content: (content: string) => string) => string; +}; + +// todo: rename +export type PackageApi = { + dependency: (pkg: string, version: string) => void; + devDependency: (pkg: string, version: string) => void; +}; + +// todo: rename +export type ScriptApi = { + run: (args: { description: string; args: string[]; stdio: 'inherit' | 'pipe' }) => void; +}; + export type Adder = { id: string; alias?: string; @@ -32,16 +48,23 @@ export type Adder = { homepage?: string; options: Args; dependsOn?: string[]; - packages: Array>; - scripts?: Array>; - files: Array>; - preInstall?: (workspace: Workspace) => MaybePromise; - postInstall?: (workspace: Workspace) => MaybePromise; nextSteps?: ( data: { highlighter: Highlighter; } & Workspace ) => string[]; + + run: ( + workspace: Workspace & { files: FileApi; packages: PackageApi; scripts: ScriptApi } + ) => MaybePromise; + + // todo: to remove (start) + files: Array>; + preInstall?: (workspace: Workspace) => MaybePromise; + postInstall?: (workspace: Workspace) => MaybePromise; + packages: Array>; + scripts?: Array>; + // todo: to remove (end) }; export type Highlighter = { From bd660a74efea03a4f1b2d444551f53efc6976b7a Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sun, 20 Oct 2024 10:29:22 +0200 Subject: [PATCH 002/126] mock paraglide adder --- packages/adders/common.ts | 5 +- packages/adders/paraglide/index.ts | 345 +++++++++++++---------------- 2 files changed, 161 insertions(+), 189 deletions(-) diff --git a/packages/adders/common.ts b/packages/adders/common.ts index a65ca1f9..a17c892d 100644 --- a/packages/adders/common.ts +++ b/packages/adders/common.ts @@ -65,10 +65,7 @@ export function addEslintConfigPrettier({ content }: FileEditor>, - path: string -): string { +export function addToDemoPage(content: string, path: string): string { const { template, generateCode } = parseSvelte(content); for (const node of template.ast.childNodes) { diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts index 459f0295..b80d56ae 100644 --- a/packages/adders/paraglide/index.ts +++ b/packages/adders/paraglide/index.ts @@ -10,28 +10,12 @@ import { object, variables, exports, - kit + kit as kitJs } from '@sveltejs/cli-core/js'; import * as html from '@sveltejs/cli-core/html'; import { parseHtml, parseJson, parseScript, parseSvelte } from '@sveltejs/cli-core/parsers'; import { addToDemoPage } from '../common.ts'; -const DEFAULT_INLANG_PROJECT = { - $schema: 'https://inlang.com/schema/project-settings', - modules: [ - 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@1/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-identical-pattern@1/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@1/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-without-source@1/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-valid-js-identifier@1/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@2/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@0/dist/index.js' - ], - 'plugin.inlang.messageFormat': { - pathPattern: './messages/{languageTag}.json' - } -}; - export const options = defineAdderOptions({ availableLanguageTags: { question: `Which languages would you like to support? ${colors.gray('(e.g. en,de-ch)')}`, @@ -66,21 +50,29 @@ export default defineAdder({ environments: { svelte: false, kit: true }, homepage: 'https://inlang.com', options, - packages: [ - { - name: '@inlang/paraglide-sveltekit', - version: '^0.11.1', - dev: false - } - ], - files: [ - { - // create an inlang project if it doesn't exist yet - name: () => 'project.inlang/settings.json', - condition: ({ cwd }) => !fs.existsSync(path.join(cwd, 'project.inlang/settings.json')), - content: ({ options, content }) => { + run: ({ files, cwd, options, typescript, kit, packages, dependencyVersion }) => { + packages.dependency('@inlang/paraglide-sveltekit', '^0.11.1'); + + if (!fs.existsSync(path.join(cwd, 'project.inlang/settings.json'))) { + files.update('project.inlang/settings.json', (content) => { const { data, generateCode } = parseJson(content); + const DEFAULT_INLANG_PROJECT = { + $schema: 'https://inlang.com/schema/project-settings', + modules: [ + 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@1/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-identical-pattern@1/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@1/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-without-source@1/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-valid-js-identifier@1/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@2/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@0/dist/index.js' + ], + 'plugin.inlang.messageFormat': { + pathPattern: './messages/{languageTag}.json' + } + }; + for (const key in DEFAULT_INLANG_PROJECT) { data[key] = DEFAULT_INLANG_PROJECT[key as keyof typeof DEFAULT_INLANG_PROJECT]; } @@ -91,158 +83,141 @@ export default defineAdder({ data.languageTags = validLanguageTags; return generateCode(); - } - }, - { - // add the vite plugin - name: ({ typescript }) => `vite.config.${typescript ? 'ts' : 'js'}`, - content: ({ content }) => { - const { ast, generateCode } = parseScript(content); - - const vitePluginName = 'paraglide'; - imports.addNamed(ast, '@inlang/paraglide-sveltekit/vite', { paraglide: vitePluginName }); - - const { value: rootObject } = exports.defaultExport( - ast, - functions.call('defineConfig', []) - ); - const param1 = functions.argumentByIndex(rootObject, 0, object.createEmpty()); + }); + } - const pluginsArray = object.property(param1, 'plugins', array.createEmpty()); - const pluginFunctionCall = functions.call(vitePluginName, []); - const pluginConfig = object.create({ - project: common.createLiteral('./project.inlang'), - outdir: common.createLiteral('./src/lib/paraglide') - }); - functions.argumentByIndex(pluginFunctionCall, 0, pluginConfig); - array.push(pluginsArray, pluginFunctionCall); + // add the vite plugin + files.update(`vite.config.${typescript ? 'ts' : 'js'}`, (content) => { + const { ast, generateCode } = parseScript(content); - return generateCode(); - } - }, - { - // src/lib/i18n file - name: ({ typescript }) => `src/lib/i18n.${typescript ? 'ts' : 'js'}`, - content({ content }) { - const { ast, generateCode } = parseScript(content); - - imports.addNamed(ast, '@inlang/paraglide-sveltekit', { createI18n: 'createI18n' }); - imports.addDefault(ast, '$lib/paraglide/runtime', '* as runtime'); - - const createI18nExpression = common.expressionFromString('createI18n(runtime)'); - const i18n = variables.declaration(ast, 'const', 'i18n', createI18nExpression); - - const existingExport = exports.namedExport(ast, 'i18n', i18n); - if (existingExport.declaration != i18n) { - log.warn('Setting up $lib/i18n failed because it already exports an i18n function'); - } + const vitePluginName = 'paraglide'; + imports.addNamed(ast, '@inlang/paraglide-sveltekit/vite', { paraglide: vitePluginName }); - return generateCode(); - } - }, - { - // reroute hook - name: ({ typescript }) => `src/hooks.${typescript ? 'ts' : 'js'}`, - content({ content }) { - const { ast, generateCode } = parseScript(content); - - imports.addNamed(ast, '$lib/i18n', { - i18n: 'i18n' - }); - - const expression = common.expressionFromString('i18n.reroute()'); - const rerouteIdentifier = variables.declaration(ast, 'const', 'reroute', expression); - - const existingExport = exports.namedExport(ast, 'reroute', rerouteIdentifier); - if (existingExport.declaration != rerouteIdentifier) { - log.warn('Adding the reroute hook automatically failed. Add it manually'); - } + const { value: rootObject } = exports.defaultExport(ast, functions.call('defineConfig', [])); + const param1 = functions.argumentByIndex(rootObject, 0, object.createEmpty()); - return generateCode(); + const pluginsArray = object.property(param1, 'plugins', array.createEmpty()); + const pluginFunctionCall = functions.call(vitePluginName, []); + const pluginConfig = object.create({ + project: common.createLiteral('./project.inlang'), + outdir: common.createLiteral('./src/lib/paraglide') + }); + functions.argumentByIndex(pluginFunctionCall, 0, pluginConfig); + array.push(pluginsArray, pluginFunctionCall); + + return generateCode(); + }); + + // src/lib/i18n file + files.update(`src/lib/i18n.${typescript ? 'ts' : 'js'}`, (content) => { + const { ast, generateCode } = parseScript(content); + + imports.addNamed(ast, '@inlang/paraglide-sveltekit', { createI18n: 'createI18n' }); + imports.addDefault(ast, '$lib/paraglide/runtime', '* as runtime'); + + const createI18nExpression = common.expressionFromString('createI18n(runtime)'); + const i18n = variables.declaration(ast, 'const', 'i18n', createI18nExpression); + + const existingExport = exports.namedExport(ast, 'i18n', i18n); + if (existingExport.declaration != i18n) { + log.warn('Setting up $lib/i18n failed because it already exports an i18n function'); } - }, - { - // handle hook - name: ({ typescript }) => `src/hooks.server.${typescript ? 'ts' : 'js'}`, - content({ content, typescript }) { - const { ast, generateCode } = parseScript(content); - imports.addNamed(ast, '$lib/i18n', { - i18n: 'i18n' - }); + return generateCode(); + }); - const hookHandleContent = 'i18n.handle()'; - kit.addHooksHandle(ast, typescript, 'handleParaglide', hookHandleContent); + // reroute hook + files.update(`src/hooks.${typescript ? 'ts' : 'js'}`, (content) => { + const { ast, generateCode } = parseScript(content); - return generateCode(); + imports.addNamed(ast, '$lib/i18n', { + i18n: 'i18n' + }); + + const expression = common.expressionFromString('i18n.reroute()'); + const rerouteIdentifier = variables.declaration(ast, 'const', 'reroute', expression); + + const existingExport = exports.namedExport(ast, 'reroute', rerouteIdentifier); + if (existingExport.declaration != rerouteIdentifier) { + log.warn('Adding the reroute hook automatically failed. Add it manually'); } - }, - { - // add the component to the layout - name: ({ kit }) => `${kit?.routesDirectory}/+layout.svelte`, - content: ({ content, dependencyVersion, typescript }) => { - const { script, template, generateCode } = parseSvelte(content, { typescript }); - const paraglideComponentName = 'ParaglideJS'; - imports.addNamed(script.ast, '@inlang/paraglide-sveltekit', { - [paraglideComponentName]: paraglideComponentName - }); - imports.addNamed(script.ast, '$lib/i18n', { - i18n: 'i18n' - }); + return generateCode(); + }); - if (template.source.length === 0) { - const svelteVersion = dependencyVersion('svelte'); - if (!svelteVersion) throw new Error('Failed to determine svelte version'); + // handle hook + files.update(`src/hooks.server.${typescript ? 'ts' : 'js'}`, (content) => { + const { ast, generateCode } = parseScript(content); - html.addSlot(script.ast, template.ast, svelteVersion); - } + imports.addNamed(ast, '$lib/i18n', { + i18n: 'i18n' + }); - const templateCode = new MagicString(template.generateCode()); - if (!templateCode.original.includes('\n'); - templateCode.append('\n'); - } + const hookHandleContent = 'i18n.handle()'; + kitJs.addHooksHandle(ast, typescript, 'handleParaglide', hookHandleContent); + + return generateCode(); + }); + + // add the component to the layout + files.update(`${kit?.routesDirectory}/+layout.svelte`, (content) => { + const { script, template, generateCode } = parseSvelte(content, { typescript }); - return generateCode({ script: script.generateCode(), template: templateCode.toString() }); + const paraglideComponentName = 'ParaglideJS'; + imports.addNamed(script.ast, '@inlang/paraglide-sveltekit', { + [paraglideComponentName]: paraglideComponentName + }); + imports.addNamed(script.ast, '$lib/i18n', { + i18n: 'i18n' + }); + + if (template.source.length === 0) { + const svelteVersion = dependencyVersion('svelte'); + if (!svelteVersion) throw new Error('Failed to determine svelte version'); + + html.addSlot(script.ast, template.ast, svelteVersion); } - }, - { - // add the text-direction and lang attribute placeholders to app.html - name: () => 'src/app.html', - content: ({ content }) => { - const { ast, generateCode } = parseHtml(content); - - const htmlNode = ast.children.find( - (child): child is html.HtmlElement => - child.type === html.HtmlElementType.Tag && child.name === 'html' - ); - if (!htmlNode) { - log.warn( - "Could not find node in app.html. You'll need to add the language placeholder manually" - ); - return generateCode(); - } - htmlNode.attribs = { - ...htmlNode.attribs, - lang: '%paraglide.lang%', - dir: '%paraglide.textDirection%' - }; + const templateCode = new MagicString(template.generateCode()); + if (!templateCode.original.includes('\n'); + templateCode.append('\n'); + } + + return generateCode({ script: script.generateCode(), template: templateCode.toString() }); + }); + + // add the text-direction and lang attribute placeholders to app.html + files.update('src/app.html', (content) => { + const { ast, generateCode } = parseHtml(content); + + const htmlNode = ast.children.find( + (child): child is html.HtmlElement => + child.type === html.HtmlElementType.Tag && child.name === 'html' + ); + if (!htmlNode) { + log.warn( + "Could not find node in app.html. You'll need to add the language placeholder manually" + ); return generateCode(); } - }, - { - name: ({ kit }) => `${kit?.routesDirectory}/demo/+page.svelte`, - condition: ({ options }) => options.demo, - content: (editor) => addToDemoPage(editor, 'paraglide') - }, - { + htmlNode.attribs = { + ...htmlNode.attribs, + lang: '%paraglide.lang%', + dir: '%paraglide.textDirection%' + }; + + return generateCode(); + }); + + if (options.demo) { + files.update(`${kit?.routesDirectory}/demo/+page.svelte`, (content) => { + return addToDemoPage(content, 'paraglide'); + }); + // add usage example - name: ({ kit }) => `${kit?.routesDirectory}/demo/paraglide/+page.svelte`, - condition: ({ options }) => options.demo, - content({ content, options, typescript }) { + files.update(`${kit?.routesDirectory}/demo/paraglide/+page.svelte`, (content) => { const { script, template, generateCode } = parseSvelte(content, { typescript }); imports.addDefault(script.ast, '$lib/paraglide/messages.js', '* as m'); @@ -265,15 +240,15 @@ export default defineAdder({ scriptCode.trim(); scriptCode.append('\n\n'); scriptCode.append(dedent` - ${ts('', '/**')} - ${ts('', '* @param import("$lib/paraglide/runtime").AvailableLanguageTag newLanguage')} - ${ts('', '*/')} - function switchToLanguage(newLanguage${ts(': AvailableLanguageTag')}) { - const canonicalPath = i18n.route($page.url.pathname); - const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage); - goto(localisedPath); - } - `); + ${ts('', '/**')} + ${ts('', '* @param import("$lib/paraglide/runtime").AvailableLanguageTag newLanguage')} + ${ts('', '*/')} + function switchToLanguage(newLanguage${ts(': AvailableLanguageTag')}) { + const canonicalPath = i18n.route($page.url.pathname); + const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage); + goto(localisedPath); + } + `); } const templateCode = new MagicString(template.source); @@ -293,26 +268,26 @@ export default defineAdder({ templateCode.append(`
\n${links}\n
`); return generateCode({ script: scriptCode.toString(), template: templateCode.toString() }); - } + }); } - ], - postInstall: ({ cwd, options }) => { - const jsonData: Record = {}; - jsonData['$schema'] = 'https://inlang.com/schema/inlang-message-format'; const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); for (const languageTag of validLanguageTags) { - jsonData.hello_world = `Hello, {name} from ${languageTag}!`; - - const filePath = `messages/${languageTag}.json`; - const directoryPath = path.dirname(filePath); - const fullDirectoryPath = path.join(cwd, directoryPath); - const fullFilePath = path.join(cwd, filePath); + files.update(`messages/${languageTag}.json`, (content) => { + const { data, generateCode } = parseJson(content); + data['$schema'] = 'https://inlang.com/schema/inlang-message-format'; + data.hello_world = `Hello, {name} from ${languageTag}!`; - fs.mkdirSync(fullDirectoryPath, { recursive: true }); - fs.writeFileSync(fullFilePath, JSON.stringify(jsonData, null, 2) + '\n'); + return generateCode(); + }); } }, + + // todo: to remove (start) + packages: [], + files: [], + // todo: to remove (end) + nextSteps: ({ highlighter }) => { const steps = [ `Edit your messages in ${highlighter.path('messages/en.json')}`, From f7fedd076e0318dbcd26825530ee40b7009e7c84 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sun, 20 Oct 2024 10:35:44 +0200 Subject: [PATCH 003/126] improve? api --- packages/adders/paraglide/index.ts | 24 ++++++++++++------------ packages/core/adder/config.ts | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts index b80d56ae..f4f546d0 100644 --- a/packages/adders/paraglide/index.ts +++ b/packages/adders/paraglide/index.ts @@ -50,11 +50,11 @@ export default defineAdder({ environments: { svelte: false, kit: true }, homepage: 'https://inlang.com', options, - run: ({ files, cwd, options, typescript, kit, packages, dependencyVersion }) => { - packages.dependency('@inlang/paraglide-sveltekit', '^0.11.1'); + run: ({ api, cwd, options, typescript, kit, dependencyVersion }) => { + api.dependency('@inlang/paraglide-sveltekit', '^0.11.1'); if (!fs.existsSync(path.join(cwd, 'project.inlang/settings.json'))) { - files.update('project.inlang/settings.json', (content) => { + api.updateFile('project.inlang/settings.json', (content) => { const { data, generateCode } = parseJson(content); const DEFAULT_INLANG_PROJECT = { @@ -87,7 +87,7 @@ export default defineAdder({ } // add the vite plugin - files.update(`vite.config.${typescript ? 'ts' : 'js'}`, (content) => { + api.updateFile(`vite.config.${typescript ? 'ts' : 'js'}`, (content) => { const { ast, generateCode } = parseScript(content); const vitePluginName = 'paraglide'; @@ -109,7 +109,7 @@ export default defineAdder({ }); // src/lib/i18n file - files.update(`src/lib/i18n.${typescript ? 'ts' : 'js'}`, (content) => { + api.updateFile(`src/lib/i18n.${typescript ? 'ts' : 'js'}`, (content) => { const { ast, generateCode } = parseScript(content); imports.addNamed(ast, '@inlang/paraglide-sveltekit', { createI18n: 'createI18n' }); @@ -127,7 +127,7 @@ export default defineAdder({ }); // reroute hook - files.update(`src/hooks.${typescript ? 'ts' : 'js'}`, (content) => { + api.updateFile(`src/hooks.${typescript ? 'ts' : 'js'}`, (content) => { const { ast, generateCode } = parseScript(content); imports.addNamed(ast, '$lib/i18n', { @@ -146,7 +146,7 @@ export default defineAdder({ }); // handle hook - files.update(`src/hooks.server.${typescript ? 'ts' : 'js'}`, (content) => { + api.updateFile(`src/hooks.server.${typescript ? 'ts' : 'js'}`, (content) => { const { ast, generateCode } = parseScript(content); imports.addNamed(ast, '$lib/i18n', { @@ -160,7 +160,7 @@ export default defineAdder({ }); // add the component to the layout - files.update(`${kit?.routesDirectory}/+layout.svelte`, (content) => { + api.updateFile(`${kit?.routesDirectory}/+layout.svelte`, (content) => { const { script, template, generateCode } = parseSvelte(content, { typescript }); const paraglideComponentName = 'ParaglideJS'; @@ -189,7 +189,7 @@ export default defineAdder({ }); // add the text-direction and lang attribute placeholders to app.html - files.update('src/app.html', (content) => { + api.updateFile('src/app.html', (content) => { const { ast, generateCode } = parseHtml(content); const htmlNode = ast.children.find( @@ -212,12 +212,12 @@ export default defineAdder({ }); if (options.demo) { - files.update(`${kit?.routesDirectory}/demo/+page.svelte`, (content) => { + api.updateFile(`${kit?.routesDirectory}/demo/+page.svelte`, (content) => { return addToDemoPage(content, 'paraglide'); }); // add usage example - files.update(`${kit?.routesDirectory}/demo/paraglide/+page.svelte`, (content) => { + api.updateFile(`${kit?.routesDirectory}/demo/paraglide/+page.svelte`, (content) => { const { script, template, generateCode } = parseSvelte(content, { typescript }); imports.addDefault(script.ast, '$lib/paraglide/messages.js', '* as m'); @@ -273,7 +273,7 @@ export default defineAdder({ const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); for (const languageTag of validLanguageTags) { - files.update(`messages/${languageTag}.json`, (content) => { + api.updateFile(`messages/${languageTag}.json`, (content) => { const { data, generateCode } = parseJson(content); data['$schema'] = 'https://inlang.com/schema/inlang-message-format'; data.hello_world = `Hello, {name} from ${languageTag}!`; diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index c2f6625e..e035cb95 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -27,7 +27,7 @@ export type Scripts = { // todo: rename export type FileApi = { - update: (name: string, content: (content: string) => string) => string; + updateFile: (name: string, content: (content: string) => string) => string; }; // todo: rename @@ -55,7 +55,7 @@ export type Adder = { ) => string[]; run: ( - workspace: Workspace & { files: FileApi; packages: PackageApi; scripts: ScriptApi } + workspace: Workspace & { api: FileApi & PackageApi & ScriptApi } ) => MaybePromise; // todo: to remove (start) From 390f6afc96bb574b8a6434f5f62a72f149df5915 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 20 Oct 2024 12:35:15 -0400 Subject: [PATCH 004/126] small tweaks --- packages/adders/paraglide/index.ts | 32 +++++++++++++++--------------- packages/core/adder/config.ts | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts index f4f546d0..25442173 100644 --- a/packages/adders/paraglide/index.ts +++ b/packages/adders/paraglide/index.ts @@ -45,6 +45,22 @@ export const options = defineAdderOptions({ } }); +const DEFAULT_INLANG_PROJECT = { + $schema: 'https://inlang.com/schema/project-settings', + modules: [ + 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@1/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-identical-pattern@1/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@1/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-without-source@1/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-valid-js-identifier@1/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@2/dist/index.js', + 'https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@0/dist/index.js' + ], + 'plugin.inlang.messageFormat': { + pathPattern: './messages/{languageTag}.json' + } +}; + export default defineAdder({ id: 'paraglide', environments: { svelte: false, kit: true }, @@ -57,22 +73,6 @@ export default defineAdder({ api.updateFile('project.inlang/settings.json', (content) => { const { data, generateCode } = parseJson(content); - const DEFAULT_INLANG_PROJECT = { - $schema: 'https://inlang.com/schema/project-settings', - modules: [ - 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@1/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-identical-pattern@1/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@1/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-without-source@1/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-valid-js-identifier@1/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@2/dist/index.js', - 'https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@0/dist/index.js' - ], - 'plugin.inlang.messageFormat': { - pathPattern: './messages/{languageTag}.json' - } - }; - for (const key in DEFAULT_INLANG_PROJECT) { data[key] = DEFAULT_INLANG_PROJECT[key as keyof typeof DEFAULT_INLANG_PROJECT]; } diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index e035cb95..3b747292 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -38,7 +38,7 @@ export type PackageApi = { // todo: rename export type ScriptApi = { - run: (args: { description: string; args: string[]; stdio: 'inherit' | 'pipe' }) => void; + execute: (args: { description: string; args: string[]; stdio: 'inherit' | 'pipe' }) => void; }; export type Adder = { From 6940e342e06d135ebb4eb7355ae775f8a1d1e07e Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 20 Oct 2024 18:54:17 -0400 Subject: [PATCH 005/126] more tweaks --- packages/adders/paraglide/index.ts | 38 +++++++++++++----------------- packages/core/adder/config.ts | 2 +- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts index 25442173..8312266c 100644 --- a/packages/adders/paraglide/index.ts +++ b/packages/adders/paraglide/index.ts @@ -21,7 +21,7 @@ export const options = defineAdderOptions({ question: `Which languages would you like to support? ${colors.gray('(e.g. en,de-ch)')}`, type: 'string', default: 'en', - validate(input: any) { + validate(input) { const { invalidLanguageTags, validLanguageTags } = parseLanguageTagInput(input); if (invalidLanguageTags.length > 0) { @@ -66,11 +66,11 @@ export default defineAdder({ environments: { svelte: false, kit: true }, homepage: 'https://inlang.com', options, - run: ({ api, cwd, options, typescript, kit, dependencyVersion }) => { - api.dependency('@inlang/paraglide-sveltekit', '^0.11.1'); + run: ({ sv, cwd, options, typescript, kit, dependencyVersion }) => { + sv.dependency('@inlang/paraglide-sveltekit', '^0.11.1'); if (!fs.existsSync(path.join(cwd, 'project.inlang/settings.json'))) { - api.updateFile('project.inlang/settings.json', (content) => { + sv.updateFile('project.inlang/settings.json', (content) => { const { data, generateCode } = parseJson(content); for (const key in DEFAULT_INLANG_PROJECT) { @@ -87,7 +87,7 @@ export default defineAdder({ } // add the vite plugin - api.updateFile(`vite.config.${typescript ? 'ts' : 'js'}`, (content) => { + sv.updateFile(`vite.config.${typescript ? 'ts' : 'js'}`, (content) => { const { ast, generateCode } = parseScript(content); const vitePluginName = 'paraglide'; @@ -109,7 +109,7 @@ export default defineAdder({ }); // src/lib/i18n file - api.updateFile(`src/lib/i18n.${typescript ? 'ts' : 'js'}`, (content) => { + sv.updateFile(`src/lib/i18n.${typescript ? 'ts' : 'js'}`, (content) => { const { ast, generateCode } = parseScript(content); imports.addNamed(ast, '@inlang/paraglide-sveltekit', { createI18n: 'createI18n' }); @@ -127,12 +127,10 @@ export default defineAdder({ }); // reroute hook - api.updateFile(`src/hooks.${typescript ? 'ts' : 'js'}`, (content) => { + sv.updateFile(`src/hooks.${typescript ? 'ts' : 'js'}`, (content) => { const { ast, generateCode } = parseScript(content); - imports.addNamed(ast, '$lib/i18n', { - i18n: 'i18n' - }); + imports.addNamed(ast, '$lib/i18n', { i18n: 'i18n' }); const expression = common.expressionFromString('i18n.reroute()'); const rerouteIdentifier = variables.declaration(ast, 'const', 'reroute', expression); @@ -146,12 +144,10 @@ export default defineAdder({ }); // handle hook - api.updateFile(`src/hooks.server.${typescript ? 'ts' : 'js'}`, (content) => { + sv.updateFile(`src/hooks.server.${typescript ? 'ts' : 'js'}`, (content) => { const { ast, generateCode } = parseScript(content); - imports.addNamed(ast, '$lib/i18n', { - i18n: 'i18n' - }); + imports.addNamed(ast, '$lib/i18n', { i18n: 'i18n' }); const hookHandleContent = 'i18n.handle()'; kitJs.addHooksHandle(ast, typescript, 'handleParaglide', hookHandleContent); @@ -160,16 +156,14 @@ export default defineAdder({ }); // add the component to the layout - api.updateFile(`${kit?.routesDirectory}/+layout.svelte`, (content) => { + sv.updateFile(`${kit?.routesDirectory}/+layout.svelte`, (content) => { const { script, template, generateCode } = parseSvelte(content, { typescript }); const paraglideComponentName = 'ParaglideJS'; imports.addNamed(script.ast, '@inlang/paraglide-sveltekit', { [paraglideComponentName]: paraglideComponentName }); - imports.addNamed(script.ast, '$lib/i18n', { - i18n: 'i18n' - }); + imports.addNamed(script.ast, '$lib/i18n', { i18n: 'i18n' }); if (template.source.length === 0) { const svelteVersion = dependencyVersion('svelte'); @@ -189,7 +183,7 @@ export default defineAdder({ }); // add the text-direction and lang attribute placeholders to app.html - api.updateFile('src/app.html', (content) => { + sv.updateFile('src/app.html', (content) => { const { ast, generateCode } = parseHtml(content); const htmlNode = ast.children.find( @@ -212,12 +206,12 @@ export default defineAdder({ }); if (options.demo) { - api.updateFile(`${kit?.routesDirectory}/demo/+page.svelte`, (content) => { + sv.updateFile(`${kit?.routesDirectory}/demo/+page.svelte`, (content) => { return addToDemoPage(content, 'paraglide'); }); // add usage example - api.updateFile(`${kit?.routesDirectory}/demo/paraglide/+page.svelte`, (content) => { + sv.updateFile(`${kit?.routesDirectory}/demo/paraglide/+page.svelte`, (content) => { const { script, template, generateCode } = parseSvelte(content, { typescript }); imports.addDefault(script.ast, '$lib/paraglide/messages.js', '* as m'); @@ -273,7 +267,7 @@ export default defineAdder({ const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); for (const languageTag of validLanguageTags) { - api.updateFile(`messages/${languageTag}.json`, (content) => { + sv.updateFile(`messages/${languageTag}.json`, (content) => { const { data, generateCode } = parseJson(content); data['$schema'] = 'https://inlang.com/schema/inlang-message-format'; data.hello_world = `Hello, {name} from ${languageTag}!`; diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index 3b747292..b8207117 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -55,7 +55,7 @@ export type Adder = { ) => string[]; run: ( - workspace: Workspace & { api: FileApi & PackageApi & ScriptApi } + workspace: Workspace & { sv: FileApi & PackageApi & ScriptApi } ) => MaybePromise; // todo: to remove (start) From ef89da7197b1b0eac399fe6a134c5971c06e8646 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 20 Oct 2024 19:17:55 -0400 Subject: [PATCH 006/126] more --- packages/adders/paraglide/index.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts index 8312266c..3210c9fe 100644 --- a/packages/adders/paraglide/index.ts +++ b/packages/adders/paraglide/index.ts @@ -67,6 +67,9 @@ export default defineAdder({ homepage: 'https://inlang.com', options, run: ({ sv, cwd, options, typescript, kit, dependencyVersion }) => { + const ext = typescript ? 'ts' : 'js'; + if (!kit) throw new Error('SvelteKit is required'); + sv.dependency('@inlang/paraglide-sveltekit', '^0.11.1'); if (!fs.existsSync(path.join(cwd, 'project.inlang/settings.json'))) { @@ -87,7 +90,7 @@ export default defineAdder({ } // add the vite plugin - sv.updateFile(`vite.config.${typescript ? 'ts' : 'js'}`, (content) => { + sv.updateFile(`vite.config.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); const vitePluginName = 'paraglide'; @@ -109,7 +112,7 @@ export default defineAdder({ }); // src/lib/i18n file - sv.updateFile(`src/lib/i18n.${typescript ? 'ts' : 'js'}`, (content) => { + sv.updateFile(`src/lib/i18n.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); imports.addNamed(ast, '@inlang/paraglide-sveltekit', { createI18n: 'createI18n' }); @@ -119,7 +122,7 @@ export default defineAdder({ const i18n = variables.declaration(ast, 'const', 'i18n', createI18nExpression); const existingExport = exports.namedExport(ast, 'i18n', i18n); - if (existingExport.declaration != i18n) { + if (existingExport.declaration !== i18n) { log.warn('Setting up $lib/i18n failed because it already exports an i18n function'); } @@ -127,7 +130,7 @@ export default defineAdder({ }); // reroute hook - sv.updateFile(`src/hooks.${typescript ? 'ts' : 'js'}`, (content) => { + sv.updateFile(`src/hooks.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); imports.addNamed(ast, '$lib/i18n', { i18n: 'i18n' }); @@ -136,7 +139,7 @@ export default defineAdder({ const rerouteIdentifier = variables.declaration(ast, 'const', 'reroute', expression); const existingExport = exports.namedExport(ast, 'reroute', rerouteIdentifier); - if (existingExport.declaration != rerouteIdentifier) { + if (existingExport.declaration !== rerouteIdentifier) { log.warn('Adding the reroute hook automatically failed. Add it manually'); } @@ -144,7 +147,7 @@ export default defineAdder({ }); // handle hook - sv.updateFile(`src/hooks.server.${typescript ? 'ts' : 'js'}`, (content) => { + sv.updateFile(`src/hooks.server.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); imports.addNamed(ast, '$lib/i18n', { i18n: 'i18n' }); @@ -156,7 +159,7 @@ export default defineAdder({ }); // add the component to the layout - sv.updateFile(`${kit?.routesDirectory}/+layout.svelte`, (content) => { + sv.updateFile(`${kit.routesDirectory}/+layout.svelte`, (content) => { const { script, template, generateCode } = parseSvelte(content, { typescript }); const paraglideComponentName = 'ParaglideJS'; @@ -206,12 +209,12 @@ export default defineAdder({ }); if (options.demo) { - sv.updateFile(`${kit?.routesDirectory}/demo/+page.svelte`, (content) => { + sv.updateFile(`${kit.routesDirectory}/demo/+page.svelte`, (content) => { return addToDemoPage(content, 'paraglide'); }); // add usage example - sv.updateFile(`${kit?.routesDirectory}/demo/paraglide/+page.svelte`, (content) => { + sv.updateFile(`${kit.routesDirectory}/demo/paraglide/+page.svelte`, (content) => { const { script, template, generateCode } = parseSvelte(content, { typescript }); imports.addDefault(script.ast, '$lib/paraglide/messages.js', '* as m'); From 750cc0cc15acf6d14ce17f1b9825f284b1cb6b8f Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Mon, 21 Oct 2024 19:05:30 +0200 Subject: [PATCH 007/126] start implementing new api (no clue if it works, requires cleanup) --- packages/adders/paraglide/index.ts | 5 -- packages/cli/commands/add/index.ts | 64 ++++++++++++++++---------- packages/cli/commands/add/processor.ts | 34 -------------- packages/cli/commands/add/utils.ts | 17 ++++--- packages/core/adder/config.ts | 25 ++-------- 5 files changed, 52 insertions(+), 93 deletions(-) delete mode 100644 packages/cli/commands/add/processor.ts diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts index 3210c9fe..c53378b0 100644 --- a/packages/adders/paraglide/index.ts +++ b/packages/adders/paraglide/index.ts @@ -280,11 +280,6 @@ export default defineAdder({ } }, - // todo: to remove (start) - packages: [], - files: [], - // todo: to remove (end) - nextSteps: ({ highlighter }) => { const steps = [ `Edit your messages in ${highlighter.path('messages/en.json')}`, diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index bd84b626..3c87ad2a 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -14,12 +14,11 @@ import { communityAdderIds, getCommunityAdder } from '@sveltejs/adders'; -import type { AdderWithoutExplicitArgs, OptionValues } from '@sveltejs/cli-core'; +import type { AdderWithoutExplicitArgs, OptionValues, SvApi } from '@sveltejs/cli-core'; import * as common from '../../common.ts'; import { Directive, downloadPackage, getPackageJSON } from '../../utils/fetch-packages.ts'; import { createWorkspace } from './workspace.ts'; -import { getHighlighter, installPackages } from './utils.ts'; -import { createOrUpdateFiles } from './processor.ts'; +import { fileExists, getHighlighter, installPackages, readFile, writeFile } from './utils.ts'; const AddersSchema = v.array(v.string()); const AdderOptionFlagsSchema = v.object({ @@ -307,11 +306,12 @@ export async function runAddCommand( if (!dependent) throw new Error(`Adder '${adder.id}' depends on an invalid '${depId}'`); // check if the dependent adder has already been installed - let installed = false; - installed = dependent.packages.every( - // we'll skip the conditions since we don't have any options to supply it - (p) => p.condition !== undefined || !!workspace.dependencyVersion(p.name) - ); + const installed = false; + // todo: see discussion, how to solve this + // installed = dependent.packages.every( + // // we'll skip the conditions since we don't have any options to supply it + // (p) => p.condition !== undefined || !!workspace.dependencyVersion(p.name) + // ); if (installed) continue; @@ -516,28 +516,33 @@ async function runAdders({ // apply adders const filesToFormat = new Set(); - for (const config of details) { - const adderId = config.id; + for (const adder of details) { + const adderId = adder.id; const workspace = createWorkspace({ cwd, packageManager }); workspace.options = official[adderId] ?? community[adderId]!; // execute adders - await config.preInstall?.(workspace); - const pkgPath = installPackages(config, workspace); - filesToFormat.add(pkgPath); - const changedFiles = createOrUpdateFiles(config.files, workspace); - changedFiles.forEach((file) => filesToFormat.add(file)); - await config.postInstall?.(workspace); - - if (config.scripts && config.scripts.length > 0) { - for (const script of config.scripts) { - if (script.condition?.(workspace) === false) continue; - + const dependencies: Array<{ pkg: string; version: string; dev: boolean }> = []; + const sv: SvApi = { + updateFile: (path, content) => { + const exists = fileExists(workspace.cwd, path); + let contentString = exists ? readFile(workspace.cwd, path) : ''; + // process file + // todo: rename + contentString = content(contentString); + + writeFile(workspace, path, contentString); + filesToFormat.add(path); + + return contentString; + }, + executeScript: async (script) => { const { command, args } = resolveCommand(workspace.packageManager, 'execute', script.args)!; - const adderPrefix = details.length > 1 ? `${config.id}: ` : ''; + const adderPrefix = details.length > 1 ? `${adder.id}: ` : ''; + const executedCommandDisplayName = `${command} ${args.join(' ')}`; p.log.step( - `${adderPrefix}Running external command ${pc.gray(`(${command} ${args.join(' ')})`)}` + `${adderPrefix}Running external command ${pc.gray(`(${executedCommandDisplayName})`)}` ); // adding --yes as the first parameter helps avoiding the "Need to install the following packages:" message @@ -548,11 +553,20 @@ async function runAdders({ } catch (error) { const typedError = error as Error; throw new Error( - `Failed to execute scripts '${script.description}': ` + typedError.message + `Failed to execute scripts '${executedCommandDisplayName}': ` + typedError.message ); } + }, + dependency: (pkg, version) => { + dependencies.push({ pkg, version, dev: false }); + }, + devDependency: (pkg, version) => { + dependencies.push({ pkg, version, dev: true }); } - } + }; + await adder.run({ ...workspace, sv }); + + installPackages(dependencies, workspace); } return Array.from(filesToFormat); diff --git a/packages/cli/commands/add/processor.ts b/packages/cli/commands/add/processor.ts deleted file mode 100644 index 8f635243..00000000 --- a/packages/cli/commands/add/processor.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { fileExists, readFile, writeFile } from './utils.ts'; -import type { Workspace, OptionDefinition, FileType } from '@sveltejs/cli-core'; - -/** - * @param files - * @param workspace - * @returns a list of paths of changed or created files - */ -export function createOrUpdateFiles( - files: Array>, - workspace: Workspace -): string[] { - const changedFiles: string[] = []; - for (const fileDetails of files) { - try { - if (fileDetails.condition && !fileDetails.condition(workspace)) { - continue; - } - - const exists = fileExists(workspace.cwd, fileDetails.name(workspace)); - let content = exists ? readFile(workspace.cwd, fileDetails.name(workspace)) : ''; - // process file - content = fileDetails.content({ content, ...workspace }); - - writeFile(workspace, fileDetails.name(workspace), content); - changedFiles.push(fileDetails.name(workspace)); - } catch (e) { - if (e instanceof Error) - throw new Error(`Unable to process '${fileDetails.name(workspace)}'. Reason: ${e.message}`); - throw e; - } - } - return changedFiles; -} diff --git a/packages/cli/commands/add/utils.ts b/packages/cli/commands/add/utils.ts index 0651fadf..4f3eb79b 100644 --- a/packages/cli/commands/add/utils.ts +++ b/packages/cli/commands/add/utils.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import pc from 'picocolors'; import { parseJson } from '@sveltejs/cli-core/parsers'; -import type { Adder, Highlighter, Workspace } from '@sveltejs/cli-core'; +import type { Highlighter, Workspace } from '@sveltejs/cli-core'; export type Package = { name: string; @@ -38,20 +38,19 @@ export function readFile(cwd: string, filePath: string): string { return text; } -export function installPackages(config: Adder, workspace: Workspace): string { +export function installPackages( + dependencies: Array<{ pkg: string; version: string; dev: boolean }>, + workspace: Workspace +): string { const { data, generateCode } = getPackageJson(workspace.cwd); - for (const dependency of config.packages) { - if (dependency.condition && !dependency.condition(workspace)) { - continue; - } - + for (const dependency of dependencies) { if (dependency.dev) { data.devDependencies ??= {}; - data.devDependencies[dependency.name] = dependency.version; + data.devDependencies[dependency.pkg] = dependency.version; } else { data.dependencies ??= {}; - data.dependencies[dependency.name] = dependency.version; + data.dependencies[dependency.pkg] = dependency.version; } } diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index b8207117..92ee947c 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -26,19 +26,14 @@ export type Scripts = { }; // todo: rename -export type FileApi = { - updateFile: (name: string, content: (content: string) => string) => string; -}; +export type SvApi = { + updateFile: (path: string, content: (content: string) => string) => string; -// todo: rename -export type PackageApi = { dependency: (pkg: string, version: string) => void; devDependency: (pkg: string, version: string) => void; -}; -// todo: rename -export type ScriptApi = { - execute: (args: { description: string; args: string[]; stdio: 'inherit' | 'pipe' }) => void; + // todo: why make this an object, and all other params? Unify! + executeScript: (options: { args: string[]; stdio: 'inherit' | 'pipe' }) => Promise; }; export type Adder = { @@ -54,17 +49,7 @@ export type Adder = { } & Workspace ) => string[]; - run: ( - workspace: Workspace & { sv: FileApi & PackageApi & ScriptApi } - ) => MaybePromise; - - // todo: to remove (start) - files: Array>; - preInstall?: (workspace: Workspace) => MaybePromise; - postInstall?: (workspace: Workspace) => MaybePromise; - packages: Array>; - scripts?: Array>; - // todo: to remove (end) + run: (workspace: Workspace & { sv: SvApi }) => MaybePromise; }; export type Highlighter = { From ba6a78a3db8d7dfe2062dc593ad6453f96dd5526 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Mon, 21 Oct 2024 19:13:25 +0200 Subject: [PATCH 008/126] rename --- packages/cli/commands/add/index.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 3c87ad2a..862eefc3 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -527,15 +527,14 @@ async function runAdders({ const sv: SvApi = { updateFile: (path, content) => { const exists = fileExists(workspace.cwd, path); - let contentString = exists ? readFile(workspace.cwd, path) : ''; + let fileContent = exists ? readFile(workspace.cwd, path) : ''; // process file - // todo: rename - contentString = content(contentString); + fileContent = content(fileContent); - writeFile(workspace, path, contentString); + writeFile(workspace, path, fileContent); filesToFormat.add(path); - return contentString; + return fileContent; }, executeScript: async (script) => { const { command, args } = resolveCommand(workspace.packageManager, 'execute', script.args)!; From d4dca57ca84f5ed57285b314748264b756ef1a6f Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Tue, 22 Oct 2024 19:38:30 +0200 Subject: [PATCH 009/126] rename some stuff --- packages/adders/paraglide/index.ts | 20 ++++++++++---------- packages/cli/commands/add/index.ts | 4 ++-- packages/core/adder/config.ts | 7 +++---- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts index c53378b0..ad3f4aba 100644 --- a/packages/adders/paraglide/index.ts +++ b/packages/adders/paraglide/index.ts @@ -73,7 +73,7 @@ export default defineAdder({ sv.dependency('@inlang/paraglide-sveltekit', '^0.11.1'); if (!fs.existsSync(path.join(cwd, 'project.inlang/settings.json'))) { - sv.updateFile('project.inlang/settings.json', (content) => { + sv.file('project.inlang/settings.json', (content) => { const { data, generateCode } = parseJson(content); for (const key in DEFAULT_INLANG_PROJECT) { @@ -90,7 +90,7 @@ export default defineAdder({ } // add the vite plugin - sv.updateFile(`vite.config.${ext}`, (content) => { + sv.file(`vite.config.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); const vitePluginName = 'paraglide'; @@ -112,7 +112,7 @@ export default defineAdder({ }); // src/lib/i18n file - sv.updateFile(`src/lib/i18n.${ext}`, (content) => { + sv.file(`src/lib/i18n.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); imports.addNamed(ast, '@inlang/paraglide-sveltekit', { createI18n: 'createI18n' }); @@ -130,7 +130,7 @@ export default defineAdder({ }); // reroute hook - sv.updateFile(`src/hooks.${ext}`, (content) => { + sv.file(`src/hooks.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); imports.addNamed(ast, '$lib/i18n', { i18n: 'i18n' }); @@ -147,7 +147,7 @@ export default defineAdder({ }); // handle hook - sv.updateFile(`src/hooks.server.${ext}`, (content) => { + sv.file(`src/hooks.server.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); imports.addNamed(ast, '$lib/i18n', { i18n: 'i18n' }); @@ -159,7 +159,7 @@ export default defineAdder({ }); // add the component to the layout - sv.updateFile(`${kit.routesDirectory}/+layout.svelte`, (content) => { + sv.file(`${kit.routesDirectory}/+layout.svelte`, (content) => { const { script, template, generateCode } = parseSvelte(content, { typescript }); const paraglideComponentName = 'ParaglideJS'; @@ -186,7 +186,7 @@ export default defineAdder({ }); // add the text-direction and lang attribute placeholders to app.html - sv.updateFile('src/app.html', (content) => { + sv.file('src/app.html', (content) => { const { ast, generateCode } = parseHtml(content); const htmlNode = ast.children.find( @@ -209,12 +209,12 @@ export default defineAdder({ }); if (options.demo) { - sv.updateFile(`${kit.routesDirectory}/demo/+page.svelte`, (content) => { + sv.file(`${kit.routesDirectory}/demo/+page.svelte`, (content) => { return addToDemoPage(content, 'paraglide'); }); // add usage example - sv.updateFile(`${kit.routesDirectory}/demo/paraglide/+page.svelte`, (content) => { + sv.file(`${kit.routesDirectory}/demo/paraglide/+page.svelte`, (content) => { const { script, template, generateCode } = parseSvelte(content, { typescript }); imports.addDefault(script.ast, '$lib/paraglide/messages.js', '* as m'); @@ -270,7 +270,7 @@ export default defineAdder({ const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); for (const languageTag of validLanguageTags) { - sv.updateFile(`messages/${languageTag}.json`, (content) => { + sv.file(`messages/${languageTag}.json`, (content) => { const { data, generateCode } = parseJson(content); data['$schema'] = 'https://inlang.com/schema/inlang-message-format'; data.hello_world = `Hello, {name} from ${languageTag}!`; diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 862eefc3..3206de3b 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -525,7 +525,7 @@ async function runAdders({ // execute adders const dependencies: Array<{ pkg: string; version: string; dev: boolean }> = []; const sv: SvApi = { - updateFile: (path, content) => { + file: (path, content) => { const exists = fileExists(workspace.cwd, path); let fileContent = exists ? readFile(workspace.cwd, path) : ''; // process file @@ -536,7 +536,7 @@ async function runAdders({ return fileContent; }, - executeScript: async (script) => { + execute: async (script) => { const { command, args } = resolveCommand(workspace.packageManager, 'execute', script.args)!; const adderPrefix = details.length > 1 ? `${adder.id}: ` : ''; const executedCommandDisplayName = `${command} ${args.join(' ')}`; diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index 92ee947c..a44df55c 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -27,13 +27,13 @@ export type Scripts = { // todo: rename export type SvApi = { - updateFile: (path: string, content: (content: string) => string) => string; - + file: (path: string, content: (content: string) => string) => string; dependency: (pkg: string, version: string) => void; devDependency: (pkg: string, version: string) => void; + dependsOn: (adder: string, options: Record) => Promise; // todo: why make this an object, and all other params? Unify! - executeScript: (options: { args: string[]; stdio: 'inherit' | 'pipe' }) => Promise; + execute: (options: { args: string[]; stdio: 'inherit' | 'pipe' }) => Promise; }; export type Adder = { @@ -42,7 +42,6 @@ export type Adder = { environments: Environments; homepage?: string; options: Args; - dependsOn?: string[]; nextSteps?: ( data: { highlighter: Highlighter; From 24da62ef3c63b3ec0dc3649227a1137d6a3d66ef Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Tue, 22 Oct 2024 19:50:37 +0200 Subject: [PATCH 010/126] migrate eslint --- packages/adders/common.ts | 3 +- packages/adders/eslint/index.ts | 210 +++++++++++++++----------------- 2 files changed, 98 insertions(+), 115 deletions(-) diff --git a/packages/adders/common.ts b/packages/adders/common.ts index a17c892d..7511bc2f 100644 --- a/packages/adders/common.ts +++ b/packages/adders/common.ts @@ -1,8 +1,7 @@ import { imports, exports, common } from '@sveltejs/cli-core/js'; -import { type Question, type FileEditor } from '@sveltejs/cli-core'; import { parseScript, parseSvelte } from '@sveltejs/cli-core/parsers'; -export function addEslintConfigPrettier({ content }: FileEditor>): string { +export function addEslintConfigPrettier(content: string): string { const { ast, generateCode } = parseScript(content); // if a default import for `eslint-plugin-svelte` already exists, then we'll use their specifier's name instead diff --git a/packages/adders/eslint/index.ts b/packages/adders/eslint/index.ts index 086b722f..2c5cf8f9 100644 --- a/packages/adders/eslint/index.ts +++ b/packages/adders/eslint/index.ts @@ -19,135 +19,119 @@ export default defineAdder({ environments: { svelte: true, kit: true }, homepage: 'https://eslint.org', options: {}, - packages: [ - { name: 'eslint', version: '^9.7.0', dev: true }, - { name: '@types/eslint', version: '^9.6.0', dev: true }, - { name: 'globals', version: '^15.0.0', dev: true }, - { - name: 'typescript-eslint', - version: '^8.0.0', - dev: true, - condition: ({ typescript }) => typescript - }, - { name: 'eslint-plugin-svelte', version: '^2.36.0', dev: true }, - { - name: 'eslint-config-prettier', - version: '^9.1.0', - dev: true, - condition: ({ dependencyVersion }) => Boolean(dependencyVersion('prettier')) - } - ], - files: [ - { - name: () => 'package.json', - content: ({ content }) => { - const { data, generateCode } = parseJson(content); - data.scripts ??= {}; - const scripts: Record = data.scripts; - const LINT_CMD = 'eslint .'; - scripts['lint'] ??= LINT_CMD; - if (!scripts['lint'].includes(LINT_CMD)) scripts['lint'] += ` && ${LINT_CMD}`; - return generateCode(); - } - }, - { - name: () => '.vscode/settings.json', - // we'll only want to run this step if the file exists - condition: ({ cwd }) => fs.existsSync(path.join(cwd, '.vscode', 'settings.json')), - content: ({ content }) => { + run: ({ sv, typescript, cwd, dependencyVersion }) => { + sv.devDependency('eslint', '^9.7.0'); + sv.devDependency('@types/eslint', '^9.6.0'); + sv.devDependency('globals', '^15.0.0'); + sv.devDependency('eslint-plugin-svelte', '^2.36.0'); + + if (typescript) sv.devDependency('typescript-eslint', '^8.0.0'); + + const prettierInstalled = Boolean(dependencyVersion('prettier')); + if (prettierInstalled) sv.devDependency('eslint-config-prettier', '^9.1.0'); + + sv.file('package.json', (content) => { + const { data, generateCode } = parseJson(content); + data.scripts ??= {}; + const scripts: Record = data.scripts; + const LINT_CMD = 'eslint .'; + scripts['lint'] ??= LINT_CMD; + if (!scripts['lint'].includes(LINT_CMD)) scripts['lint'] += ` && ${LINT_CMD}`; + return generateCode(); + }); + + if (fs.existsSync(path.join(cwd, '.vscode', 'settings.json'))) { + sv.file('.vscode/settings.json', (content) => { const { data, generateCode } = parseJson(content); const validate: string[] | undefined = data['eslint.validate']; if (validate && !validate.includes('svelte')) { validate.push('svelte'); } return generateCode(); + }); + } + + sv.file('eslint.config.js', (content) => { + const { ast, generateCode } = parseScript(content); + + const eslintConfigs: Array< + AstKinds.ExpressionKind | AstTypes.SpreadElement | AstTypes.ObjectExpression + > = []; + + const jsConfig = common.expressionFromString('js.configs.recommended'); + eslintConfigs.push(jsConfig); + + if (typescript) { + const tsConfig = common.expressionFromString('ts.configs.recommended'); + eslintConfigs.push(common.createSpreadElement(tsConfig)); } - }, - { - name: () => 'eslint.config.js', - content: ({ content, typescript }) => { - const { ast, generateCode } = parseScript(content); - - const eslintConfigs: Array< - AstKinds.ExpressionKind | AstTypes.SpreadElement | AstTypes.ObjectExpression - > = []; - - const jsConfig = common.expressionFromString('js.configs.recommended'); - eslintConfigs.push(jsConfig); - - if (typescript) { - const tsConfig = common.expressionFromString('ts.configs.recommended'); - eslintConfigs.push(common.createSpreadElement(tsConfig)); - } - const svelteConfig = common.expressionFromString('svelte.configs["flat/recommended"]'); - eslintConfigs.push(common.createSpreadElement(svelteConfig)); + const svelteConfig = common.expressionFromString('svelte.configs["flat/recommended"]'); + eslintConfigs.push(common.createSpreadElement(svelteConfig)); - const globalsBrowser = common.createSpreadElement( - common.expressionFromString('globals.browser') - ); - const globalsNode = common.createSpreadElement(common.expressionFromString('globals.node')); - const globalsObjLiteral = object.createEmpty(); - globalsObjLiteral.properties = [globalsBrowser, globalsNode]; - const globalsConfig = object.create({ + const globalsBrowser = common.createSpreadElement( + common.expressionFromString('globals.browser') + ); + const globalsNode = common.createSpreadElement(common.expressionFromString('globals.node')); + const globalsObjLiteral = object.createEmpty(); + globalsObjLiteral.properties = [globalsBrowser, globalsNode]; + const globalsConfig = object.create({ + languageOptions: object.create({ + globals: globalsObjLiteral + }) + }); + eslintConfigs.push(globalsConfig); + + if (typescript) { + const svelteTSParserConfig = object.create({ + files: common.expressionFromString('["**/*.svelte"]'), languageOptions: object.create({ - globals: globalsObjLiteral + parserOptions: object.create({ + parser: common.expressionFromString('ts.parser') + }) }) }); - eslintConfigs.push(globalsConfig); - - if (typescript) { - const svelteTSParserConfig = object.create({ - files: common.expressionFromString('["**/*.svelte"]'), - languageOptions: object.create({ - parserOptions: object.create({ - parser: common.expressionFromString('ts.parser') - }) - }) - }); - eslintConfigs.push(svelteTSParserConfig); - } + eslintConfigs.push(svelteTSParserConfig); + } - const ignoresConfig = object.create({ - ignores: common.expressionFromString('["build/", ".svelte-kit/", "dist/"]') - }); - eslintConfigs.push(ignoresConfig); - - let exportExpression: AstTypes.ArrayExpression | AstTypes.CallExpression; - if (typescript) { - const tsConfigCall = functions.call('ts.config', []); - tsConfigCall.arguments.push(...eslintConfigs); - exportExpression = tsConfigCall; - } else { - const eslintArray = array.createEmpty(); - eslintConfigs.map((x) => array.push(eslintArray, x)); - exportExpression = eslintArray; - } + const ignoresConfig = object.create({ + ignores: common.expressionFromString('["build/", ".svelte-kit/", "dist/"]') + }); + eslintConfigs.push(ignoresConfig); - const defaultExport = exports.defaultExport(ast, exportExpression); - // if it's not the config we created, then we'll leave it alone and exit out - if (defaultExport.value !== exportExpression) { - log.warn('An eslint config is already defined. Skipping initialization.'); - return content; - } + let exportExpression: AstTypes.ArrayExpression | AstTypes.CallExpression; + if (typescript) { + const tsConfigCall = functions.call('ts.config', []); + tsConfigCall.arguments.push(...eslintConfigs); + exportExpression = tsConfigCall; + } else { + const eslintArray = array.createEmpty(); + eslintConfigs.map((x) => array.push(eslintArray, x)); + exportExpression = eslintArray; + } - // type annotate config - if (!typescript) - common.addJsDocTypeComment(defaultExport.astNode, "import('eslint').Linter.Config[]"); + const defaultExport = exports.defaultExport(ast, exportExpression); + // if it's not the config we created, then we'll leave it alone and exit out + if (defaultExport.value !== exportExpression) { + log.warn('An eslint config is already defined. Skipping initialization.'); + return content; + } - // imports - if (typescript) imports.addDefault(ast, 'typescript-eslint', 'ts'); - imports.addDefault(ast, 'globals', 'globals'); - imports.addDefault(ast, 'eslint-plugin-svelte', 'svelte'); - imports.addDefault(ast, '@eslint/js', 'js'); + // type annotate config + if (!typescript) + common.addJsDocTypeComment(defaultExport.astNode, "import('eslint').Linter.Config[]"); - return generateCode(); - } - }, - { - name: () => 'eslint.config.js', - condition: ({ dependencyVersion }) => Boolean(dependencyVersion('prettier')), - content: addEslintConfigPrettier + // imports + if (typescript) imports.addDefault(ast, 'typescript-eslint', 'ts'); + imports.addDefault(ast, 'globals', 'globals'); + imports.addDefault(ast, 'eslint-plugin-svelte', 'svelte'); + imports.addDefault(ast, '@eslint/js', 'js'); + + return generateCode(); + }); + + if (prettierInstalled) { + sv.file('', addEslintConfigPrettier); } - ] + } }); From 2d4cceb2dc1cf851b3984922b1a90537d2c3f01b Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Tue, 22 Oct 2024 19:56:11 +0200 Subject: [PATCH 011/126] migrate mdsvex --- packages/adders/mdsvex/index.ts | 52 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/packages/adders/mdsvex/index.ts b/packages/adders/mdsvex/index.ts index 33316fe3..4cf9cd2f 100644 --- a/packages/adders/mdsvex/index.ts +++ b/packages/adders/mdsvex/index.ts @@ -7,38 +7,36 @@ export default defineAdder({ environments: { svelte: true, kit: true }, homepage: 'https://mdsvex.pngwn.io', options: {}, - packages: [{ name: 'mdsvex', version: '^0.11.2', dev: true }], - files: [ - { - name: () => 'svelte.config.js', - content: ({ content }) => { - const { ast, generateCode } = parseScript(content); + run: ({ sv }) => { + sv.devDependency('mdsvex', '^0.11.2'); - imports.addNamed(ast, 'mdsvex', { mdsvex: 'mdsvex' }); + sv.file('svelte.config.js', (content) => { + const { ast, generateCode } = parseScript(content); - const { value: exportDefault } = exports.defaultExport(ast, object.createEmpty()); + imports.addNamed(ast, 'mdsvex', { mdsvex: 'mdsvex' }); - // preprocess - let preprocessorArray = object.property(exportDefault, 'preprocess', array.createEmpty()); - const isArray = preprocessorArray.type === 'ArrayExpression'; + const { value: exportDefault } = exports.defaultExport(ast, object.createEmpty()); - if (!isArray) { - const previousElement = preprocessorArray; - preprocessorArray = array.createEmpty(); - array.push(preprocessorArray, previousElement); - object.overrideProperty(exportDefault, 'preprocess', preprocessorArray); - } + // preprocess + let preprocessorArray = object.property(exportDefault, 'preprocess', array.createEmpty()); + const isArray = preprocessorArray.type === 'ArrayExpression'; - const mdsvexCall = functions.call('mdsvex', []); - array.push(preprocessorArray, mdsvexCall); + if (!isArray) { + const previousElement = preprocessorArray; + preprocessorArray = array.createEmpty(); + array.push(preprocessorArray, previousElement); + object.overrideProperty(exportDefault, 'preprocess', preprocessorArray); + } - // extensions - const extensionsArray = object.property(exportDefault, 'extensions', array.createEmpty()); - array.push(extensionsArray, '.svelte'); - array.push(extensionsArray, '.svx'); + const mdsvexCall = functions.call('mdsvex', []); + array.push(preprocessorArray, mdsvexCall); - return generateCode(); - } - } - ] + // extensions + const extensionsArray = object.property(exportDefault, 'extensions', array.createEmpty()); + array.push(extensionsArray, '.svelte'); + array.push(extensionsArray, '.svx'); + + return generateCode(); + }); + } }); From 627a68d64de936dfa0dabe7ed154f3197dac8f49 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Tue, 22 Oct 2024 20:00:56 +0200 Subject: [PATCH 012/126] migrate playwright --- packages/adders/playwright/index.ts | 125 +++++++++++++--------------- 1 file changed, 60 insertions(+), 65 deletions(-) diff --git a/packages/adders/playwright/index.ts b/packages/adders/playwright/index.ts index e05251ed..be3feca1 100644 --- a/packages/adders/playwright/index.ts +++ b/packages/adders/playwright/index.ts @@ -9,76 +9,71 @@ export default defineAdder({ environments: { svelte: true, kit: true }, homepage: 'https://playwright.dev', options: {}, - packages: [{ name: '@playwright/test', version: '^1.45.3', dev: true }], - files: [ - { - name: () => 'package.json', - content: ({ content }) => { - const { data, generateCode } = parseJson(content); - data.scripts ??= {}; - const scripts: Record = data.scripts; - const TEST_CMD = 'playwright test'; - const RUN_TEST = 'npm run test:e2e'; - scripts['test:e2e'] ??= TEST_CMD; - scripts['test'] ??= RUN_TEST; - if (!scripts['test'].includes(RUN_TEST)) scripts['test'] += ` && ${RUN_TEST}`; - return generateCode(); - } - }, - { - name: () => '.gitignore', - condition: ({ cwd }) => fs.existsSync(join(cwd, '.gitignore')), - content: ({ content }) => { + run: ({ sv, cwd, typescript }) => { + const ext = typescript ? 'ts' : 'js'; + + sv.devDependency('@playwright/test', '^1.45.3'); + + sv.file('package.json', (content) => { + const { data, generateCode } = parseJson(content); + data.scripts ??= {}; + const scripts: Record = data.scripts; + const TEST_CMD = 'playwright test'; + const RUN_TEST = 'npm run test:e2e'; + scripts['test:e2e'] ??= TEST_CMD; + scripts['test'] ??= RUN_TEST; + if (!scripts['test'].includes(RUN_TEST)) scripts['test'] += ` && ${RUN_TEST}`; + return generateCode(); + }); + + if (fs.existsSync(join(cwd, '.gitignore'))) { + sv.file('.gitignore', (content) => { if (content.includes('test-results')) return content; return 'test-results\n' + content.trim(); - } - }, - { - name: ({ typescript }) => `e2e/demo.test.${typescript ? 'ts' : 'js'}`, - content: ({ content }) => { - if (content) return content; + }); + } - return dedent` - import { expect, test } from '@playwright/test'; + sv.file(`e2e/demo.test.${ext}`, (content) => { + if (content) return content; - test('home page has expected h1', async ({ page }) => { - await page.goto('/'); - await expect(page.locator('h1')).toBeVisible(); - }); - `; - } - }, - { - name: ({ typescript }) => `playwright.config.${typescript ? 'ts' : 'js'}`, - content: ({ content }) => { - const { ast, generateCode } = parseScript(content); - const defineConfig = common.expressionFromString('defineConfig({})'); - const defaultExport = exports.defaultExport(ast, defineConfig); + return dedent` + import { expect, test } from '@playwright/test'; + + test('home page has expected h1', async ({ page }) => { + await page.goto('/'); + await expect(page.locator('h1')).toBeVisible(); + }); + `; + }); - const config = { - webServer: object.create({ - command: common.createLiteral('npm run build && npm run preview'), - port: common.expressionFromString('4173') - }), - testDir: common.createLiteral('e2e') - }; + sv.file(`playwright.config.${ext}`, (content) => { + const { ast, generateCode } = parseScript(content); + const defineConfig = common.expressionFromString('defineConfig({})'); + const defaultExport = exports.defaultExport(ast, defineConfig); - if ( - defaultExport.value.type === 'CallExpression' && - defaultExport.value.arguments[0]?.type === 'ObjectExpression' - ) { - // uses the `defineConfig` helper - imports.addNamed(ast, '@playwright/test', { defineConfig: 'defineConfig' }); - object.properties(defaultExport.value.arguments[0], config); - } else if (defaultExport.value.type === 'ObjectExpression') { - // if the config is just an object expression, just add the property - object.properties(defaultExport.value, config); - } else { - // unexpected config shape - log.warn('Unexpected playwright config for playwright adder. Could not update.'); - } - return generateCode(); + const config = { + webServer: object.create({ + command: common.createLiteral('npm run build && npm run preview'), + port: common.expressionFromString('4173') + }), + testDir: common.createLiteral('e2e') + }; + + if ( + defaultExport.value.type === 'CallExpression' && + defaultExport.value.arguments[0]?.type === 'ObjectExpression' + ) { + // uses the `defineConfig` helper + imports.addNamed(ast, '@playwright/test', { defineConfig: 'defineConfig' }); + object.properties(defaultExport.value.arguments[0], config); + } else if (defaultExport.value.type === 'ObjectExpression') { + // if the config is just an object expression, just add the property + object.properties(defaultExport.value, config); + } else { + // unexpected config shape + log.warn('Unexpected playwright config for playwright adder. Could not update.'); } - } - ] + return generateCode(); + }); + } }); From 741b6e17af520d27e644968588cb2281eb2adbca Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Tue, 22 Oct 2024 20:10:31 +0200 Subject: [PATCH 013/126] migrate prettier --- packages/adders/eslint/index.ts | 3 +- packages/adders/prettier/index.ts | 141 +++++++++++++----------------- 2 files changed, 65 insertions(+), 79 deletions(-) diff --git a/packages/adders/eslint/index.ts b/packages/adders/eslint/index.ts index 2c5cf8f9..25f28e95 100644 --- a/packages/adders/eslint/index.ts +++ b/packages/adders/eslint/index.ts @@ -20,6 +20,8 @@ export default defineAdder({ homepage: 'https://eslint.org', options: {}, run: ({ sv, typescript, cwd, dependencyVersion }) => { + const prettierInstalled = Boolean(dependencyVersion('prettier')); + sv.devDependency('eslint', '^9.7.0'); sv.devDependency('@types/eslint', '^9.6.0'); sv.devDependency('globals', '^15.0.0'); @@ -27,7 +29,6 @@ export default defineAdder({ if (typescript) sv.devDependency('typescript-eslint', '^8.0.0'); - const prettierInstalled = Boolean(dependencyVersion('prettier')); if (prettierInstalled) sv.devDependency('eslint-config-prettier', '^9.1.0'); sv.file('package.json', (content) => { diff --git a/packages/adders/prettier/index.ts b/packages/adders/prettier/index.ts index 9be7b903..8477868c 100644 --- a/packages/adders/prettier/index.ts +++ b/packages/adders/prettier/index.ts @@ -7,94 +7,79 @@ export default defineAdder({ environments: { svelte: true, kit: true }, homepage: 'https://prettier.io', options: {}, - packages: [ - { name: 'prettier', version: '^3.3.2', dev: true }, - { name: 'prettier-plugin-svelte', version: '^3.2.6', dev: true }, - { - name: 'eslint-config-prettier', - version: '^9.1.0', - dev: true, - condition: ({ dependencyVersion }) => hasEslint(dependencyVersion) - } - ], - files: [ - { - name: () => '.prettierignore', - content: ({ content }) => { - if (content) return content; - return dedent` - # Package Managers - package-lock.json - pnpm-lock.yaml - yarn.lock - `; + run: ({ sv, dependencyVersion }) => { + const eslintInstalled = hasEslint(dependencyVersion); + + sv.devDependency('prettier', '^3.3.2'); + sv.devDependency('prettier-plugin-svelte', '^3.2.6'); + + if (eslintInstalled) sv.devDependency('eslint-config-prettier', '^9.1.0'); + + sv.file('.prettierignore', (content) => { + if (content) return content; + return dedent` + # Package Managers + package-lock.json + pnpm-lock.yaml + yarn.lock + `; + }); + + sv.file('.prettierrc', (content) => { + const { data, generateCode } = parseJson(content); + if (Object.keys(data).length === 0) { + // we'll only set these defaults if there is no pre-existing config + data.useTabs = true; + data.singleQuote = true; + data.trailingComma = 'none'; + data.printWidth = 100; } - }, - { - name: () => '.prettierrc', - content: ({ content }) => { - const { data, generateCode } = parseJson(content); - if (Object.keys(data).length === 0) { - // we'll only set these defaults if there is no pre-existing config - data.useTabs = true; - data.singleQuote = true; - data.trailingComma = 'none'; - data.printWidth = 100; - } - data.plugins ??= []; - data.overrides ??= []; + data.plugins ??= []; + data.overrides ??= []; - const plugins: string[] = data.plugins; - if (!plugins.includes('prettier-plugin-svelte')) { - data.plugins.unshift('prettier-plugin-svelte'); - } + const plugins: string[] = data.plugins; + if (!plugins.includes('prettier-plugin-svelte')) { + data.plugins.unshift('prettier-plugin-svelte'); + } - const overrides: Array<{ files: string | string[]; options?: { parser?: string } }> = - data.overrides; - const override = overrides.find((o) => o?.options?.parser === 'svelte'); - if (!override) { - overrides.push({ files: '*.svelte', options: { parser: 'svelte' } }); - } - return generateCode(); + const overrides: Array<{ files: string | string[]; options?: { parser?: string } }> = + data.overrides; + const override = overrides.find((o) => o?.options?.parser === 'svelte'); + if (!override) { + overrides.push({ files: '*.svelte', options: { parser: 'svelte' } }); } - }, - { - name: () => 'package.json', - content: ({ content, dependencyVersion }) => { - const { data, generateCode } = parseJson(content); + return generateCode(); + }); - data.scripts ??= {}; - const scripts: Record = data.scripts; - const CHECK_CMD = 'prettier --check .'; - scripts['format'] ??= 'prettier --write .'; + sv.file('package.json', (content) => { + const { data, generateCode } = parseJson(content); - if (hasEslint(dependencyVersion)) { - scripts['lint'] ??= `${CHECK_CMD} && eslint .`; - if (!scripts['lint'].includes(CHECK_CMD)) scripts['lint'] += ` && ${CHECK_CMD}`; - } else { - scripts['lint'] ??= CHECK_CMD; - } - return generateCode(); + data.scripts ??= {}; + const scripts: Record = data.scripts; + const CHECK_CMD = 'prettier --check .'; + scripts['format'] ??= 'prettier --write .'; + + if (hasEslint(dependencyVersion)) { + scripts['lint'] ??= `${CHECK_CMD} && eslint .`; + if (!scripts['lint'].includes(CHECK_CMD)) scripts['lint'] += ` && ${CHECK_CMD}`; + } else { + scripts['lint'] ??= CHECK_CMD; } - }, - { - name: () => 'eslint.config.js', - condition: ({ dependencyVersion }) => { - // We only want this to execute when it's `false`, not falsy + return generateCode(); + }); - if (dependencyVersion('eslint')?.startsWith(SUPPORTED_ESLINT_VERSION) === false) { - log.warn( - `An older major version of ${colors.yellow( - 'eslint' - )} was detected. Skipping ${colors.yellow('eslint-config-prettier')} installation.` - ); - } - return hasEslint(dependencyVersion); - }, - content: addEslintConfigPrettier + if (dependencyVersion('eslint')?.startsWith(SUPPORTED_ESLINT_VERSION) === false) { + log.warn( + `An older major version of ${colors.yellow( + 'eslint' + )} was detected. Skipping ${colors.yellow('eslint-config-prettier')} installation.` + ); + } + if (eslintInstalled) { + sv.file('eslint.config.js', addEslintConfigPrettier); } - ] + } }); const SUPPORTED_ESLINT_VERSION = '9'; From aca314d0e031a01643543d29f3e1f48a3b03d452 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Tue, 22 Oct 2024 20:13:55 +0200 Subject: [PATCH 014/126] delete routify --- packages/adders/_config/official.ts | 4 +- packages/adders/routify/index.ts | 85 ----------------------------- packages/adders/routify/logo.svg | 1 - packages/adders/routify/tests.ts | 22 -------- 4 files changed, 1 insertion(+), 111 deletions(-) delete mode 100644 packages/adders/routify/index.ts delete mode 100644 packages/adders/routify/logo.svg delete mode 100644 packages/adders/routify/tests.ts diff --git a/packages/adders/_config/official.ts b/packages/adders/_config/official.ts index 9fb704b4..2afb5764 100644 --- a/packages/adders/_config/official.ts +++ b/packages/adders/_config/official.ts @@ -7,7 +7,6 @@ import mdsvex from '../mdsvex/index.ts'; import paraglide from '../paraglide/index.ts'; import playwright from '../playwright/index.ts'; import prettier from '../prettier/index.ts'; -import routify from '../routify/index.ts'; import storybook from '../storybook/index.ts'; import tailwindcss from '../tailwindcss/index.ts'; import vitest from '../vitest/index.ts'; @@ -24,8 +23,7 @@ export const officialAdders = [ lucia, mdsvex, paraglide, - storybook, - routify + storybook ]; export function getAdderDetails(id: string): AdderWithoutExplicitArgs { diff --git a/packages/adders/routify/index.ts b/packages/adders/routify/index.ts deleted file mode 100644 index 4a30f254..00000000 --- a/packages/adders/routify/index.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { defineAdder } from '@sveltejs/cli-core'; -import { array, exports, functions, imports, object, variables } from '@sveltejs/cli-core/js'; -import * as html from '@sveltejs/cli-core/html'; -import { parseScript, parseSvelte } from '@sveltejs/cli-core/parsers'; - -export default defineAdder({ - id: 'routify', - environments: { svelte: true, kit: false }, - homepage: 'https://routify.dev', - options: {}, - packages: [{ name: '@roxi/routify', version: 'next', dev: true }], - files: [ - { - name: ({ typescript }) => `vite.config.${typescript ? 'ts' : 'js'}`, - content: ({ content }) => { - const { ast, generateCode } = parseScript(content); - const vitePluginName = 'routify'; - imports.addDefault(ast, '@roxi/routify/vite-plugin', vitePluginName); - - const { value: rootObject } = exports.defaultExport( - ast, - functions.call('defineConfig', []) - ); - const param1 = functions.argumentByIndex(rootObject, 0, object.createEmpty()); - - const pluginsArray = object.property(param1, 'plugins', array.createEmpty()); - const pluginFunctionCall = functions.call(vitePluginName, []); - const pluginConfig = object.createEmpty(); - functions.argumentByIndex(pluginFunctionCall, 0, pluginConfig); - - array.push(pluginsArray, pluginFunctionCall); - return generateCode(); - } - }, - { - name: () => 'src/App.svelte', - content: ({ content }) => { - const { script, template, generateCode } = parseSvelte(content); - imports.addNamed(script.ast, '@roxi/routify', { - Router: 'Router', - createRouter: 'createRouter' - }); - imports.addDefault(script.ast, '../.routify/routes.default.js', 'routes'); - - const routesObject = object.createEmpty(); - const routesIdentifier = variables.identifier('routes'); - object.property(routesObject, 'routes', routesIdentifier); - const createRouterFunction = functions.call('createRouter', []); - createRouterFunction.arguments.push(routesObject); - const routerVariableDeclaration = variables.declaration( - script.ast, - 'const', - 'router', - createRouterFunction - ); - exports.namedExport(script.ast, 'router', routerVariableDeclaration); - - const router = html.element('Router', { '{router}': '' }); - html.insertElement(template.ast.childNodes, router); - return generateCode({ script: script.generateCode(), template: template.generateCode() }); - } - }, - { - name: () => 'src/routes/index.svelte', - content: ({ content }) => { - const htmlString = `${routifyDemoHtml}

On index

`; - return content + htmlString; - } - }, - { - name: () => 'src/routes/demo.svelte', - content: ({ content }) => { - const htmlString = `${routifyDemoHtml}

On demo

`; - return content + htmlString; - } - } - ] -}); - -const routifyDemoHtml = ` -
- Index - Demo -
-`; diff --git a/packages/adders/routify/logo.svg b/packages/adders/routify/logo.svg deleted file mode 100644 index 9ed3bc46..00000000 --- a/packages/adders/routify/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/packages/adders/routify/tests.ts b/packages/adders/routify/tests.ts deleted file mode 100644 index 80cd4fe7..00000000 --- a/packages/adders/routify/tests.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { defineAdderTests } from '@sveltejs/cli-core'; - -export const tests = defineAdderTests({ - files: [], - options: {}, - optionValues: [], - tests: [ - { - name: 'check page switch', - run: async ({ elementExists, click, expectUrlPath }) => { - await elementExists('.routify-demo'); - expectUrlPath('/'); - - await click('.routify-demo .demo', '/demo'); - expectUrlPath('/demo'); - - await click('.routify-demo .index', '/'); - expectUrlPath('/'); - } - } - ] -}); From fd4a0a29c43ea79211a654ca6ee03cf8447441e3 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Tue, 22 Oct 2024 20:16:14 +0200 Subject: [PATCH 015/126] update storybook --- packages/adders/storybook/index.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/adders/storybook/index.ts b/packages/adders/storybook/index.ts index 9a76cbef..a1cd6e3a 100644 --- a/packages/adders/storybook/index.ts +++ b/packages/adders/storybook/index.ts @@ -5,13 +5,10 @@ export default defineAdder({ environments: { kit: true, svelte: true }, homepage: 'https://storybook.js.org', options: {}, - packages: [], - scripts: [ - { - description: 'applies storybook', + run: ({ sv }) => { + sv.execute({ args: ['storybook@latest', 'init', '--skip-install', '--no-dev'], stdio: 'inherit' - } - ], - files: [] + }); + } }); From dddde9614974d20bf9fe5f4b459c03b7fdf0514c Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Tue, 22 Oct 2024 20:27:11 +0200 Subject: [PATCH 016/126] update tailwindcss --- packages/adders/tailwindcss/index.ts | 198 ++++++++++++--------------- 1 file changed, 91 insertions(+), 107 deletions(-) diff --git a/packages/adders/tailwindcss/index.ts b/packages/adders/tailwindcss/index.ts index aded2740..3e61538a 100644 --- a/packages/adders/tailwindcss/index.ts +++ b/packages/adders/tailwindcss/index.ts @@ -1,4 +1,4 @@ -import { defineAdder, defineAdderOptions, type PackageDefinition } from '@sveltejs/cli-core'; +import { defineAdder, defineAdderOptions } from '@sveltejs/cli-core'; import { addImports } from '@sveltejs/cli-core/css'; import { array, common, exports, imports, object, type AstTypes } from '@sveltejs/cli-core/js'; import { parseCss, parseScript, parseJson, parseSvelte } from '@sveltejs/cli-core/parsers'; @@ -38,13 +38,6 @@ const plugins: Plugin[] = [ } ]; -const pluginPackages: Array> = plugins.map((x) => ({ - name: x.package, - version: x.version, - dev: true, - condition: ({ options }) => options.plugins.includes(x.id) -})); - export const options = defineAdderOptions({ plugins: { type: 'multiselect', @@ -60,112 +53,105 @@ export default defineAdder({ environments: { svelte: true, kit: true }, homepage: 'https://tailwindcss.com', options, - packages: [ - { name: 'tailwindcss', version: '^3.4.9', dev: true }, - { name: 'autoprefixer', version: '^10.4.20', dev: true }, - { - name: 'prettier-plugin-tailwindcss', - version: '^0.6.5', - dev: true, - condition: ({ dependencyVersion }) => Boolean(dependencyVersion('prettier')) - }, - ...pluginPackages - ], - files: [ - { - name: ({ typescript }) => `tailwind.config.${typescript ? 'ts' : 'js'}`, - content: ({ options, typescript, content }) => { - const { ast, generateCode } = parseScript(content); - let root; - const rootExport = object.createEmpty(); - if (typescript) { - imports.addNamed(ast, 'tailwindcss', { Config: 'Config' }, true); - root = common.typeAnnotateExpression(rootExport, 'Config'); - } + run: ({ sv, options, typescript, kit, dependencyVersion }) => { + const ext = typescript ? 'ts' : 'js'; + const prettierInstalled = Boolean(dependencyVersion('prettier')); - const { astNode: exportDeclaration, value: node } = exports.defaultExport( - ast, - root ?? rootExport - ); + sv.devDependency('tailwindcss', '^3.4.9'); + sv.devDependency('autoprefixer', '^10.4.20'); - const config = ( - node.type === 'TSAsExpression' ? node.expression : node - ) as AstTypes.ObjectExpression; + if (prettierInstalled) sv.devDependency('prettier-plugin-tailwindcss', '^0.6.5'); - if (!typescript) { - common.addJsDocTypeComment(exportDeclaration, "import('tailwindcss').Config"); - } + for (const plugin of plugins) { + if (!options.plugins.includes(plugin.id)) continue; - const contentArray = object.property(config, 'content', array.createEmpty()); - array.push(contentArray, './src/**/*.{html,js,svelte,ts}'); + sv.dependency(plugin.package, plugin.version); + } - const themeObject = object.property(config, 'theme', object.createEmpty()); - object.property(themeObject, 'extend', object.createEmpty()); + sv.file(`tailwind.config.${ext}`, (content) => { + const { ast, generateCode } = parseScript(content); + let root; + const rootExport = object.createEmpty(); + if (typescript) { + imports.addNamed(ast, 'tailwindcss', { Config: 'Config' }, true); + root = common.typeAnnotateExpression(rootExport, 'Config'); + } - const pluginsArray = object.property(config, 'plugins', array.createEmpty()); + const { astNode: exportDeclaration, value: node } = exports.defaultExport( + ast, + root ?? rootExport + ); - for (const plugin of plugins) { - if (!options.plugins.includes(plugin.id)) continue; - imports.addDefault(ast, plugin.package, plugin.identifier); - array.push(pluginsArray, { type: 'Identifier', name: plugin.identifier }); - } + const config = ( + node.type === 'TSAsExpression' ? node.expression : node + ) as AstTypes.ObjectExpression; - return generateCode(); - } - }, - { - name: () => 'postcss.config.js', - content: ({ content }) => { - const { ast, generateCode } = parseScript(content); - const { value: rootObject } = exports.defaultExport(ast, object.createEmpty()); - const pluginsObject = object.property(rootObject, 'plugins', object.createEmpty()); - - object.property(pluginsObject, 'tailwindcss', object.createEmpty()); - object.property(pluginsObject, 'autoprefixer', object.createEmpty()); - return generateCode(); + if (!typescript) { + common.addJsDocTypeComment(exportDeclaration, "import('tailwindcss').Config"); } - }, - { - name: () => 'src/app.css', - content: ({ content }) => { - const { ast, generateCode } = parseCss(content); - const layerImports = ['base', 'components', 'utilities'].map( - (layer) => `"tailwindcss/${layer}"` - ); - const originalFirst = ast.first; - - const nodes = addImports(ast, layerImports); - - if ( - originalFirst !== ast.first && - originalFirst?.type === 'atrule' && - originalFirst.name === 'import' - ) { - originalFirst.raws.before = '\n'; - } - // We remove the first node to avoid adding a newline at the top of the stylesheet - nodes.shift(); + const contentArray = object.property(config, 'content', array.createEmpty()); + array.push(contentArray, './src/**/*.{html,js,svelte,ts}'); - // Each node is prefixed with single newline, ensuring the imports will always be single spaced. - // Without this, the CSS printer will vary the spacing depending on the current state of the stylesheet - nodes.forEach((n) => (n.raws.before = '\n')); + const themeObject = object.property(config, 'theme', object.createEmpty()); + object.property(themeObject, 'extend', object.createEmpty()); - return generateCode(); + const pluginsArray = object.property(config, 'plugins', array.createEmpty()); + + for (const plugin of plugins) { + if (!options.plugins.includes(plugin.id)) continue; + imports.addDefault(ast, plugin.package, plugin.identifier); + array.push(pluginsArray, { type: 'Identifier', name: plugin.identifier }); + } + + return generateCode(); + }); + + sv.file('postcss.config.js', (content) => { + const { ast, generateCode } = parseScript(content); + const { value: rootObject } = exports.defaultExport(ast, object.createEmpty()); + const pluginsObject = object.property(rootObject, 'plugins', object.createEmpty()); + + object.property(pluginsObject, 'tailwindcss', object.createEmpty()); + object.property(pluginsObject, 'autoprefixer', object.createEmpty()); + return generateCode(); + }); + + sv.file('src/app.css', (content) => { + const { ast, generateCode } = parseCss(content); + const layerImports = ['base', 'components', 'utilities'].map( + (layer) => `"tailwindcss/${layer}"` + ); + const originalFirst = ast.first; + + const nodes = addImports(ast, layerImports); + + if ( + originalFirst !== ast.first && + originalFirst?.type === 'atrule' && + originalFirst.name === 'import' + ) { + originalFirst.raws.before = '\n'; } - }, - { - name: () => 'src/App.svelte', - content: ({ content, typescript }) => { + + // We remove the first node to avoid adding a newline at the top of the stylesheet + nodes.shift(); + + // Each node is prefixed with single newline, ensuring the imports will always be single spaced. + // Without this, the CSS printer will vary the spacing depending on the current state of the stylesheet + nodes.forEach((n) => (n.raws.before = '\n')); + + return generateCode(); + }); + + if (!kit) { + sv.file('src/App.svelte', (content) => { const { script, generateCode } = parseSvelte(content, { typescript }); imports.addEmpty(script.ast, './app.css'); return generateCode({ script: script.generateCode() }); - }, - condition: ({ kit }) => !kit - }, - { - name: ({ kit }) => `${kit?.routesDirectory}/+layout.svelte`, - content: ({ content, typescript, dependencyVersion }) => { + }); + } else { + sv.file(`${kit?.routesDirectory}/+layout.svelte`, (content) => { const { script, template, generateCode } = parseSvelte(content, { typescript }); imports.addEmpty(script.ast, '../app.css'); @@ -179,12 +165,11 @@ export default defineAdder({ script: script.generateCode(), template: content.length === 0 ? template.generateCode() : undefined }); - }, - condition: ({ kit }) => Boolean(kit) - }, - { - name: () => '.prettierrc', - content: ({ content }) => { + }); + } + + if (dependencyVersion('prettier')) { + sv.file('.prettierrc', (content) => { const { data, generateCode } = parseJson(content); const PLUGIN_NAME = 'prettier-plugin-tailwindcss'; @@ -194,8 +179,7 @@ export default defineAdder({ if (!plugins.includes(PLUGIN_NAME)) plugins.push(PLUGIN_NAME); return generateCode(); - }, - condition: ({ dependencyVersion }) => Boolean(dependencyVersion('prettier')) + }); } - ] + } }); From 3f66470439839d3f38af8714538574bea1c9d3ed Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Wed, 23 Oct 2024 19:28:11 +0200 Subject: [PATCH 017/126] migrate vitest --- packages/adders/vitest/index.ts | 164 ++++++++++++++++---------------- 1 file changed, 80 insertions(+), 84 deletions(-) diff --git a/packages/adders/vitest/index.ts b/packages/adders/vitest/index.ts index 47706ee2..d61fecc6 100644 --- a/packages/adders/vitest/index.ts +++ b/packages/adders/vitest/index.ts @@ -7,99 +7,95 @@ export default defineAdder({ environments: { svelte: true, kit: true }, homepage: 'https://vitest.dev', options: {}, - packages: [{ name: 'vitest', version: '^2.0.4', dev: true }], - files: [ - { - name: () => 'package.json', - content: ({ content }) => { - const { data, generateCode } = parseJson(content); - data.scripts ??= {}; - const scripts: Record = data.scripts; - const TEST_CMD = 'vitest'; - // we use `--run` so that vitest doesn't run in watch mode when running `npm run test` - const RUN_TEST = 'npm run test:unit -- --run'; - scripts['test:unit'] ??= TEST_CMD; - scripts['test'] ??= RUN_TEST; - if (!scripts['test'].includes(RUN_TEST)) scripts['test'] += ` && ${RUN_TEST}`; - return generateCode(); - } - }, - { - name: ({ typescript }) => `src/demo.spec.${typescript ? 'ts' : 'js'}`, - content: ({ content }) => { - if (content) return content; + run: ({ sv, typescript }) => { + const ext = typescript ? 'ts' : 'js'; + + sv.devDependency('vitest', '^2.0.4'); + + sv.file('package.json', (content) => { + const { data, generateCode } = parseJson(content); + data.scripts ??= {}; + const scripts: Record = data.scripts; + const TEST_CMD = 'vitest'; + // we use `--run` so that vitest doesn't run in watch mode when running `npm run test` + const RUN_TEST = 'npm run test:unit -- --run'; + scripts['test:unit'] ??= TEST_CMD; + scripts['test'] ??= RUN_TEST; + if (!scripts['test'].includes(RUN_TEST)) scripts['test'] += ` && ${RUN_TEST}`; + return generateCode(); + }); - return dedent` - import { describe, it, expect } from 'vitest'; + sv.file(`src/demo.spec.${ext}`, (content) => { + if (content) return content; - describe('sum test', () => { - it('adds 1 + 2 to equal 3', () => { - expect(1 + 2).toBe(3); - }); + return dedent` + import { describe, it, expect } from 'vitest'; + + describe('sum test', () => { + it('adds 1 + 2 to equal 3', () => { + expect(1 + 2).toBe(3); }); - `; - } - }, - { - name: ({ typescript }) => `vite.config.${typescript ? 'ts' : 'js'}`, - content: ({ content }) => { - const { ast, generateCode } = parseScript(content); + }); + `; + }); - // find `defineConfig` import declaration for "vite" - const importDecls = ast.body.filter((n) => n.type === 'ImportDeclaration'); - const defineConfigImportDecl = importDecls.find( - (importDecl) => - (importDecl.source.value === 'vite' || importDecl.source.value === 'vitest/config') && - importDecl.importKind === 'value' && - importDecl.specifiers?.some( - (specifier) => - specifier.type === 'ImportSpecifier' && specifier.imported.name === 'defineConfig' - ) - ); + sv.file(`vite.config.${ext}`, (content) => { + const { ast, generateCode } = parseScript(content); - // we'll need to replace the "vite" import for a "vitest/config" import. - // if `defineConfig` is the only specifier in that "vite" import, remove the entire import declaration - if (defineConfigImportDecl?.specifiers?.length === 1) { - const idxToRemove = ast.body.indexOf(defineConfigImportDecl); - ast.body.splice(idxToRemove, 1); - } else { - // otherwise, just remove the `defineConfig` specifier - const idxToRemove = defineConfigImportDecl?.specifiers?.findIndex( - (s) => s.type === 'ImportSpecifier' && s.imported.name === 'defineConfig' - ); - if (idxToRemove) defineConfigImportDecl?.specifiers?.splice(idxToRemove, 1); - } + // find `defineConfig` import declaration for "vite" + const importDecls = ast.body.filter((n) => n.type === 'ImportDeclaration'); + const defineConfigImportDecl = importDecls.find( + (importDecl) => + (importDecl.source.value === 'vite' || importDecl.source.value === 'vitest/config') && + importDecl.importKind === 'value' && + importDecl.specifiers?.some( + (specifier) => + specifier.type === 'ImportSpecifier' && specifier.imported.name === 'defineConfig' + ) + ); - const config = common.expressionFromString('defineConfig({})'); - const defaultExport = exports.defaultExport(ast, config); + // we'll need to replace the "vite" import for a "vitest/config" import. + // if `defineConfig` is the only specifier in that "vite" import, remove the entire import declaration + if (defineConfigImportDecl?.specifiers?.length === 1) { + const idxToRemove = ast.body.indexOf(defineConfigImportDecl); + ast.body.splice(idxToRemove, 1); + } else { + // otherwise, just remove the `defineConfig` specifier + const idxToRemove = defineConfigImportDecl?.specifiers?.findIndex( + (s) => s.type === 'ImportSpecifier' && s.imported.name === 'defineConfig' + ); + if (idxToRemove) defineConfigImportDecl?.specifiers?.splice(idxToRemove, 1); + } - const test = object.create({ - include: common.expressionFromString("['src/**/*.{test,spec}.{js,ts}']") - }); + const config = common.expressionFromString('defineConfig({})'); + const defaultExport = exports.defaultExport(ast, config); - // uses the `defineConfig` helper - if ( - defaultExport.value.type === 'CallExpression' && - defaultExport.value.arguments[0]?.type === 'ObjectExpression' - ) { - // if the previous `defineConfig` was aliased, reuse the alias for the "vitest/config" import - const importSpecifier = defineConfigImportDecl?.specifiers?.find( - (sp) => sp.type === 'ImportSpecifier' && sp.imported.name === 'defineConfig' - ); - const defineConfigAlias = importSpecifier?.local?.name ?? 'defineConfig'; - imports.addNamed(ast, 'vitest/config', { defineConfig: defineConfigAlias }); + const test = object.create({ + include: common.expressionFromString("['src/**/*.{test,spec}.{js,ts}']") + }); - object.properties(defaultExport.value.arguments[0], { test }); - } else if (defaultExport.value.type === 'ObjectExpression') { - // if the config is just an object expression, just add the property - object.properties(defaultExport.value, { test }); - } else { - // unexpected config shape - log.warn('Unexpected vite config for vitest adder. Could not update.'); - } + // uses the `defineConfig` helper + if ( + defaultExport.value.type === 'CallExpression' && + defaultExport.value.arguments[0]?.type === 'ObjectExpression' + ) { + // if the previous `defineConfig` was aliased, reuse the alias for the "vitest/config" import + const importSpecifier = defineConfigImportDecl?.specifiers?.find( + (sp) => sp.type === 'ImportSpecifier' && sp.imported.name === 'defineConfig' + ); + const defineConfigAlias = importSpecifier?.local?.name ?? 'defineConfig'; + imports.addNamed(ast, 'vitest/config', { defineConfig: defineConfigAlias }); - return generateCode(); + object.properties(defaultExport.value.arguments[0], { test }); + } else if (defaultExport.value.type === 'ObjectExpression') { + // if the config is just an object expression, just add the property + object.properties(defaultExport.value, { test }); + } else { + // unexpected config shape + log.warn('Unexpected vite config for vitest adder. Could not update.'); } - } - ] + + return generateCode(); + }); + } }); From 1feee6feccffbe529b4d2aa399d2288b8b367554 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Wed, 23 Oct 2024 19:51:34 +0200 Subject: [PATCH 018/126] migrate drizzle --- packages/adders/drizzle/index.ts | 442 ++++++++++++++----------------- 1 file changed, 197 insertions(+), 245 deletions(-) diff --git a/packages/adders/drizzle/index.ts b/packages/adders/drizzle/index.ts index f3174054..8214fb45 100644 --- a/packages/adders/drizzle/index.ts +++ b/packages/adders/drizzle/index.ts @@ -1,5 +1,5 @@ import { common, exports, functions, imports, object, variables } from '@sveltejs/cli-core/js'; -import { defineAdder, defineAdderOptions, dedent, type FileEditor } from '@sveltejs/cli-core'; +import { defineAdder, defineAdderOptions, dedent, type OptionValues } from '@sveltejs/cli-core'; import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; const PORTS = { @@ -68,69 +68,34 @@ export default defineAdder({ environments: { svelte: false, kit: true }, homepage: 'https://orm.drizzle.team', options, - packages: [ - { name: 'drizzle-orm', version: '^0.33.0', dev: false }, - { name: 'drizzle-kit', version: '^0.22.0', dev: true }, + run: ({ sv, typescript, options, kit }) => { + const ext = typescript ? 'ts' : 'js'; + + sv.dependency('drizzle-orm', '^0.33.0'); + sv.devDependency('drizzle-kit', '^0.22.0'); + // MySQL - { - name: 'mysql2', - version: '^3.11.0', - dev: false, - condition: ({ options }) => options.mysql === 'mysql2' - }, - { - name: '@planetscale/database', - version: '^1.18.0', - dev: false, - condition: ({ options }) => options.mysql === 'planetscale' - }, + if (options.mysql === 'mysql2') sv.dependency('mysql2', '^3.11.0'); + if (options.mysql === 'planetscale') sv.dependency('@planetscale/database', '^1.18.0'); + // PostgreSQL - { - name: '@neondatabase/serverless', - version: '^0.9.4', - dev: false, - condition: ({ options }) => options.postgresql === 'neon' - }, - { - name: 'postgres', - version: '^3.4.4', - dev: false, - condition: ({ options }) => options.postgresql === 'postgres.js' - }, + if (options.postgresql === 'neon') sv.dependency('@neondatabase/serverless', '^0.9.4'); + if (options.postgresql === 'postgres.js') sv.dependency('postgres', '^3.4.4'); + // SQLite - { - name: 'better-sqlite3', - version: '^11.1.2', - dev: false, - condition: ({ options }) => options.sqlite === 'better-sqlite3' - }, - { - name: '@types/better-sqlite3', - version: '^7.6.11', - dev: true, - condition: ({ options }) => options.sqlite === 'better-sqlite3' - }, - { - name: '@libsql/client', - version: '^0.9.0', - dev: false, - condition: ({ options }) => options.sqlite === 'libsql' || options.sqlite === 'turso' + if (options.sqlite === 'better-sqlite3') { + sv.dependency('better-sqlite3', '^11.1.2'); + sv.devDependency('@types/better-sqlite3', '^7.6.11'); } - ], - files: [ - { - name: () => '.env', - content: generateEnvFileContent - }, - { - name: () => '.env.example', - content: generateEnvFileContent - }, - { - name: () => 'docker-compose.yml', - condition: ({ options }) => - options.docker && (options.mysql === 'mysql2' || options.postgresql === 'postgres.js'), - content: ({ content, options }) => { + + if (options.sqlite === 'libsql' || options.sqlite === 'turso') + sv.dependency('@libsql/client', '^0.9.0'); + + sv.file('.env', (content) => generateEnvFileContent(content, options)); + sv.file('.env.example', (content) => generateEnvFileContent(content, options)); + + if (options.docker && (options.mysql === 'mysql2' || options.postgresql === 'postgres.js')) { + sv.file('docker-compose.yml', (content) => { // if the file already exists, don't modify it // (in the future, we could add some tooling for modifying yaml) if (content.length > 0) return content; @@ -168,218 +133,205 @@ export default defineAdder({ `; return content; - } - }, - { - name: () => 'package.json', - content: ({ content, options }) => { - const { data, generateCode } = parseJson(content); - data.scripts ??= {}; - const scripts: Record = data.scripts; - if (options.docker) scripts['db:start'] ??= 'docker compose up'; - scripts['db:push'] ??= 'drizzle-kit push'; - scripts['db:migrate'] ??= 'drizzle-kit migrate'; - scripts['db:studio'] ??= 'drizzle-kit studio'; - return generateCode(); - } - }, - { - // Adds the db file to the gitignore if an ignore is present - name: () => '.gitignore', - condition: ({ options }) => options.database === 'sqlite', - content: ({ content }) => { + }); + } + + sv.file('package.json', (content) => { + const { data, generateCode } = parseJson(content); + data.scripts ??= {}; + const scripts: Record = data.scripts; + if (options.docker) scripts['db:start'] ??= 'docker compose up'; + scripts['db:push'] ??= 'drizzle-kit push'; + scripts['db:migrate'] ??= 'drizzle-kit migrate'; + scripts['db:studio'] ??= 'drizzle-kit studio'; + return generateCode(); + }); + + if (options.database === 'sqlite') { + sv.file('.gitgnore', (content) => { + // Adds the db file to the gitignore if an ignore is present if (content.length === 0) return content; if (!content.includes('\n*.db')) { content = content.trimEnd() + '\n\n# SQLite\n*.db'; } return content; - } - }, - { - name: ({ typescript }) => `drizzle.config.${typescript ? 'ts' : 'js'}`, - content: ({ options, content, typescript }) => { - const { ast, generateCode } = parseScript(content); + }); + } - imports.addNamed(ast, 'drizzle-kit', { defineConfig: 'defineConfig' }); + sv.file(`drizzle.config.${ext}`, (content) => { + const { ast, generateCode } = parseScript(content); - const envCheckStatement = common.statementFromString( - `if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');` - ); - common.addStatement(ast, envCheckStatement); - - const fallback = common.expressionFromString('defineConfig({})'); - const { value: exportDefault } = exports.defaultExport(ast, fallback); - if (exportDefault.type !== 'CallExpression') return content; - - const objExpression = exportDefault.arguments?.[0]; - if (!objExpression || objExpression.type !== 'ObjectExpression') return content; - - const driver = options.sqlite === 'turso' ? common.createLiteral('turso') : undefined; - const authToken = - options.sqlite === 'turso' - ? common.expressionFromString('process.env.DATABASE_AUTH_TOKEN') - : undefined; - - object.properties(objExpression, { - schema: common.createLiteral(`./src/lib/server/db/schema.${typescript ? 'ts' : 'js'}`), - dbCredentials: object.create({ - url: common.expressionFromString('process.env.DATABASE_URL'), - authToken - }), - verbose: { type: 'BooleanLiteral', value: true }, - strict: { type: 'BooleanLiteral', value: true }, - driver + imports.addNamed(ast, 'drizzle-kit', { defineConfig: 'defineConfig' }); + + const envCheckStatement = common.statementFromString( + `if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');` + ); + common.addStatement(ast, envCheckStatement); + + const fallback = common.expressionFromString('defineConfig({})'); + const { value: exportDefault } = exports.defaultExport(ast, fallback); + if (exportDefault.type !== 'CallExpression') return content; + + const objExpression = exportDefault.arguments?.[0]; + if (!objExpression || objExpression.type !== 'ObjectExpression') return content; + + const driver = options.sqlite === 'turso' ? common.createLiteral('turso') : undefined; + const authToken = + options.sqlite === 'turso' + ? common.expressionFromString('process.env.DATABASE_AUTH_TOKEN') + : undefined; + + object.properties(objExpression, { + schema: common.createLiteral(`./src/lib/server/db/schema.${typescript ? 'ts' : 'js'}`), + dbCredentials: object.create({ + url: common.expressionFromString('process.env.DATABASE_URL'), + authToken + }), + verbose: { type: 'BooleanLiteral', value: true }, + strict: { type: 'BooleanLiteral', value: true }, + driver + }); + + object.overrideProperties(objExpression, { + dialect: common.createLiteral(options.database) + }); + + // The `driver` property is only required for _some_ sqlite DBs. + // We'll need to remove it if it's anything but sqlite + if (options.database !== 'sqlite') object.removeProperty(objExpression, 'driver'); + + return generateCode(); + }); + + sv.file(`${kit?.libDirectory}/server/db/schema.${ext}`, (content) => { + const { ast, generateCode } = parseScript(content); + + let userSchemaExpression; + if (options.database === 'sqlite') { + imports.addNamed(ast, 'drizzle-orm/sqlite-core', { + sqliteTable: 'sqliteTable', + text: 'text', + integer: 'integer' }); - object.overrideProperties(objExpression, { - dialect: common.createLiteral(options.database) + userSchemaExpression = common.expressionFromString(`sqliteTable('user', { + id: integer('id').primaryKey(), + age: integer('age') + })`); + } + if (options.database === 'mysql') { + imports.addNamed(ast, 'drizzle-orm/mysql-core', { + mysqlTable: 'mysqlTable', + serial: 'serial', + text: 'text', + int: 'int' }); - // The `driver` property is only required for _some_ sqlite DBs. - // We'll need to remove it if it's anything but sqlite - if (options.database !== 'sqlite') object.removeProperty(objExpression, 'driver'); + userSchemaExpression = common.expressionFromString(`mysqlTable('user', { + id: serial('id').primaryKey(), + age: int('age'), + })`); + } + if (options.database === 'postgresql') { + imports.addNamed(ast, 'drizzle-orm/pg-core', { + pgTable: 'pgTable', + serial: 'serial', + text: 'text', + integer: 'integer' + }); - return generateCode(); + userSchemaExpression = common.expressionFromString(`pgTable('user', { + id: serial('id').primaryKey(), + age: integer('age'), + })`); } - }, - { - name: ({ kit, typescript }) => - `${kit?.libDirectory}/server/db/schema.${typescript ? 'ts' : 'js'}`, - content: ({ content, options }) => { - const { ast, generateCode } = parseScript(content); - - let userSchemaExpression; - if (options.database === 'sqlite') { - imports.addNamed(ast, 'drizzle-orm/sqlite-core', { - sqliteTable: 'sqliteTable', - text: 'text', - integer: 'integer' - }); - - userSchemaExpression = common.expressionFromString(`sqliteTable('user', { - id: integer('id').primaryKey(), - age: integer('age') - })`); - } - if (options.database === 'mysql') { - imports.addNamed(ast, 'drizzle-orm/mysql-core', { - mysqlTable: 'mysqlTable', - serial: 'serial', - text: 'text', - int: 'int' - }); - - userSchemaExpression = common.expressionFromString(`mysqlTable('user', { - id: serial('id').primaryKey(), - age: int('age'), - })`); - } - if (options.database === 'postgresql') { - imports.addNamed(ast, 'drizzle-orm/pg-core', { - pgTable: 'pgTable', - serial: 'serial', - text: 'text', - integer: 'integer' - }); - - userSchemaExpression = common.expressionFromString(`pgTable('user', { - id: serial('id').primaryKey(), - age: integer('age'), - })`); - } - if (!userSchemaExpression) throw new Error('unreachable state...'); - const userIdentifier = variables.declaration(ast, 'const', 'user', userSchemaExpression); - exports.namedExport(ast, 'user', userIdentifier); + if (!userSchemaExpression) throw new Error('unreachable state...'); + const userIdentifier = variables.declaration(ast, 'const', 'user', userSchemaExpression); + exports.namedExport(ast, 'user', userIdentifier); - return generateCode(); - } - }, - { - name: ({ kit, typescript }) => - `${kit?.libDirectory}/server/db/index.${typescript ? 'ts' : 'js'}`, - content: ({ content, options }) => { - const { ast, generateCode } = parseScript(content); - - imports.addNamed(ast, '$env/dynamic/private', { env: 'env' }); - - // env var checks - const dbURLCheck = common.statementFromString( - `if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set');` - ); - common.addStatement(ast, dbURLCheck); + return generateCode(); + }); - let clientExpression; - // SQLite - if (options.sqlite === 'better-sqlite3') { - imports.addDefault(ast, 'better-sqlite3', 'Database'); - imports.addNamed(ast, 'drizzle-orm/better-sqlite3', { drizzle: 'drizzle' }); + sv.file(`${kit?.libDirectory}/server/db/index.${ext}`, (content) => { + const { ast, generateCode } = parseScript(content); - clientExpression = common.expressionFromString('new Database(env.DATABASE_URL)'); - } - if (options.sqlite === 'libsql' || options.sqlite === 'turso') { - imports.addNamed(ast, '@libsql/client', { createClient: 'createClient' }); - imports.addNamed(ast, 'drizzle-orm/libsql', { drizzle: 'drizzle' }); - - if (options.sqlite === 'turso') { - imports.addNamed(ast, '$app/environment', { dev: 'dev' }); - // auth token check in prod - const authTokenCheck = common.statementFromString( - `if (!dev && !env.DATABASE_AUTH_TOKEN) throw new Error('DATABASE_AUTH_TOKEN is not set');` - ); - common.addStatement(ast, authTokenCheck); - - clientExpression = common.expressionFromString( - 'createClient({ url: env.DATABASE_URL, authToken: env.DATABASE_AUTH_TOKEN })' - ); - } else { - clientExpression = common.expressionFromString( - 'createClient({ url: env.DATABASE_URL })' - ); - } - } - // MySQL - if (options.mysql === 'mysql2') { - imports.addDefault(ast, 'mysql2/promise', 'mysql'); - imports.addNamed(ast, 'drizzle-orm/mysql2', { drizzle: 'drizzle' }); + imports.addNamed(ast, '$env/dynamic/private', { env: 'env' }); + + // env var checks + const dbURLCheck = common.statementFromString( + `if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set');` + ); + common.addStatement(ast, dbURLCheck); + + let clientExpression; + // SQLite + if (options.sqlite === 'better-sqlite3') { + imports.addDefault(ast, 'better-sqlite3', 'Database'); + imports.addNamed(ast, 'drizzle-orm/better-sqlite3', { drizzle: 'drizzle' }); + + clientExpression = common.expressionFromString('new Database(env.DATABASE_URL)'); + } + if (options.sqlite === 'libsql' || options.sqlite === 'turso') { + imports.addNamed(ast, '@libsql/client', { createClient: 'createClient' }); + imports.addNamed(ast, 'drizzle-orm/libsql', { drizzle: 'drizzle' }); + + if (options.sqlite === 'turso') { + imports.addNamed(ast, '$app/environment', { dev: 'dev' }); + // auth token check in prod + const authTokenCheck = common.statementFromString( + `if (!dev && !env.DATABASE_AUTH_TOKEN) throw new Error('DATABASE_AUTH_TOKEN is not set');` + ); + common.addStatement(ast, authTokenCheck); clientExpression = common.expressionFromString( - 'await mysql.createConnection(env.DATABASE_URL)' + 'createClient({ url: env.DATABASE_URL, authToken: env.DATABASE_AUTH_TOKEN })' ); + } else { + clientExpression = common.expressionFromString('createClient({ url: env.DATABASE_URL })'); } - if (options.mysql === 'planetscale') { - imports.addNamed(ast, '@planetscale/database', { Client: 'Client' }); - imports.addNamed(ast, 'drizzle-orm/planetscale-serverless', { drizzle: 'drizzle' }); + } + // MySQL + if (options.mysql === 'mysql2') { + imports.addDefault(ast, 'mysql2/promise', 'mysql'); + imports.addNamed(ast, 'drizzle-orm/mysql2', { drizzle: 'drizzle' }); - clientExpression = common.expressionFromString('new Client({ url: env.DATABASE_URL })'); - } - // PostgreSQL - if (options.postgresql === 'neon') { - imports.addNamed(ast, '@neondatabase/serverless', { neon: 'neon' }); - imports.addNamed(ast, 'drizzle-orm/neon-http', { drizzle: 'drizzle' }); + clientExpression = common.expressionFromString( + 'await mysql.createConnection(env.DATABASE_URL)' + ); + } + if (options.mysql === 'planetscale') { + imports.addNamed(ast, '@planetscale/database', { Client: 'Client' }); + imports.addNamed(ast, 'drizzle-orm/planetscale-serverless', { drizzle: 'drizzle' }); - clientExpression = common.expressionFromString('neon(env.DATABASE_URL)'); - } - if (options.postgresql === 'postgres.js') { - imports.addDefault(ast, 'postgres', 'postgres'); - imports.addNamed(ast, 'drizzle-orm/postgres-js', { drizzle: 'drizzle' }); + clientExpression = common.expressionFromString('new Client({ url: env.DATABASE_URL })'); + } + // PostgreSQL + if (options.postgresql === 'neon') { + imports.addNamed(ast, '@neondatabase/serverless', { neon: 'neon' }); + imports.addNamed(ast, 'drizzle-orm/neon-http', { drizzle: 'drizzle' }); - clientExpression = common.expressionFromString('postgres(env.DATABASE_URL)'); - } + clientExpression = common.expressionFromString('neon(env.DATABASE_URL)'); + } + if (options.postgresql === 'postgres.js') { + imports.addDefault(ast, 'postgres', 'postgres'); + imports.addNamed(ast, 'drizzle-orm/postgres-js', { drizzle: 'drizzle' }); - if (!clientExpression) throw new Error('unreachable state...'); - const clientIdentifier = variables.declaration(ast, 'const', 'client', clientExpression); - common.addStatement(ast, clientIdentifier); + clientExpression = common.expressionFromString('postgres(env.DATABASE_URL)'); + } - const drizzleCall = functions.callByIdentifier('drizzle', ['client']); - const db = variables.declaration(ast, 'const', 'db', drizzleCall); - exports.namedExport(ast, 'db', db); + if (!clientExpression) throw new Error('unreachable state...'); + const clientIdentifier = variables.declaration(ast, 'const', 'client', clientExpression); + common.addStatement(ast, clientIdentifier); - return generateCode(); - } - } - ], + const drizzleCall = functions.callByIdentifier('drizzle', ['client']); + const db = variables.declaration(ast, 'const', 'db', drizzleCall); + exports.namedExport(ast, 'db', db); + + return generateCode(); + }); + }, nextSteps: ({ options, highlighter, packageManager }) => { const steps = [ `You will need to set ${highlighter.env('DATABASE_URL')} in your production environment` @@ -397,7 +349,7 @@ export default defineAdder({ } }); -function generateEnvFileContent({ content, options: opts }: FileEditor) { +function generateEnvFileContent(content: string, opts: OptionValues) { const DB_URL_KEY = 'DATABASE_URL'; if (opts.docker) { // we'll prefill with the default docker db credentials From 791d96c7161fba00602522387bcc1eaa3d3fbcd5 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Wed, 23 Oct 2024 20:06:03 +0200 Subject: [PATCH 019/126] migrate lucia --- packages/adders/lucia/index.ts | 577 ++++++++++++++++----------------- 1 file changed, 280 insertions(+), 297 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 8bc1ed7a..4ef47b60 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -8,7 +8,15 @@ import { utils, Walker } from '@sveltejs/cli-core'; -import { common, exports, imports, variables, object, functions, kit } from '@sveltejs/cli-core/js'; +import { + common, + exports, + imports, + variables, + object, + functions, + kit as kitJs +} from '@sveltejs/cli-core/js'; // eslint-disable-next-line no-duplicate-imports import type { AstTypes } from '@sveltejs/cli-core/js'; import { parseScript } from '@sveltejs/cli-core/parsers'; @@ -38,286 +46,279 @@ export default defineAdder({ environments: { svelte: false, kit: true }, homepage: 'https://lucia-next.pages.dev', options, - packages: [ - { name: '@oslojs/crypto', version: '^1.0.1', dev: false }, - { name: '@oslojs/encoding', version: '^1.1.0', dev: false }, - // password hashing for demo - { - name: '@node-rs/argon2', - version: '^1.1.0', - condition: ({ options }) => options.demo, - dev: false + run: ({ sv, typescript, options, kit, dependencyVersion }) => { + const ext = typescript ? 'ts' : 'js'; + + sv.dependency('@oslojs/crypto', '^1.0.1'); + sv.dependency('@oslojs/encoding', '^1.1.0'); + + if (options.demo) { + // password hashing for demo + sv.dependency('@node-rs/argon2', '^1.1.0'); } - ], - dependsOn: ['drizzle'], - files: [ - { - name: ({ typescript }) => `drizzle.config.${typescript ? 'ts' : 'js'}`, - content: ({ content }) => { - const { ast, generateCode } = parseScript(content); - const isProp = (name: string, node: AstTypes.ObjectProperty) => - node.key.type === 'Identifier' && node.key.name === name; - - // prettier-ignore - Walker.walk(ast as AstTypes.ASTNode, {}, { - ObjectProperty(node) { - if (isProp('dialect', node) && node.value.type === 'StringLiteral') { - drizzleDialect = node.value.value as Dialect; - } - if (isProp('schema', node) && node.value.type === 'StringLiteral') { - schemaPath = node.value.value; - } - } - }) - if (!drizzleDialect) { - throw new Error('Failed to detect DB dialect in your `drizzle.config.[js|ts]` file'); - } - if (!schemaPath) { - throw new Error('Failed to find schema path in your `drizzle.config.[js|ts]` file'); + // todo: depends on lucia. Is this the right way? + sv.dependsOn('drizzle', {}); + + sv.file(`drizzle.config.${ext}`, (content) => { + const { ast, generateCode } = parseScript(content); + const isProp = (name: string, node: AstTypes.ObjectProperty) => + node.key.type === 'Identifier' && node.key.name === name; + + // prettier-ignore + Walker.walk(ast as AstTypes.ASTNode, {}, { + ObjectProperty(node) { + if (isProp('dialect', node) && node.value.type === 'StringLiteral') { + drizzleDialect = node.value.value as Dialect; + } + if (isProp('schema', node) && node.value.type === 'StringLiteral') { + schemaPath = node.value.value; + } } - return generateCode(); + }) + + if (!drizzleDialect) { + throw new Error('Failed to detect DB dialect in your `drizzle.config.[js|ts]` file'); } - }, - { - name: () => schemaPath, - content: ({ content, options, typescript }) => { - const { ast, generateCode } = parseScript(content); - const createTable = (name: string) => functions.call(TABLE_TYPE[drizzleDialect], [name]); + if (!schemaPath) { + throw new Error('Failed to find schema path in your `drizzle.config.[js|ts]` file'); + } + return generateCode(); + }); - const userDecl = variables.declaration(ast, 'const', 'user', createTable('user')); - const sessionDecl = variables.declaration(ast, 'const', 'session', createTable('session')); + sv.file(schemaPath, (content) => { + const { ast, generateCode } = parseScript(content); + const createTable = (name: string) => functions.call(TABLE_TYPE[drizzleDialect], [name]); - const user = exports.namedExport(ast, 'user', userDecl); - const session = exports.namedExport(ast, 'session', sessionDecl); + const userDecl = variables.declaration(ast, 'const', 'user', createTable('user')); + const sessionDecl = variables.declaration(ast, 'const', 'session', createTable('session')); - const userTable = getCallExpression(user); - const sessionTable = getCallExpression(session); + const user = exports.namedExport(ast, 'user', userDecl); + const session = exports.namedExport(ast, 'session', sessionDecl); - if (!userTable || !sessionTable) { - throw new Error('failed to find call expression of `user` or `session`'); - } + const userTable = getCallExpression(user); + const sessionTable = getCallExpression(session); - if (userTable.arguments.length === 1) { - userTable.arguments.push(object.createEmpty()); - } - if (sessionTable.arguments.length === 1) { - sessionTable.arguments.push(object.createEmpty()); - } + if (!userTable || !sessionTable) { + throw new Error('failed to find call expression of `user` or `session`'); + } - const userAttributes = userTable.arguments[1]; - const sessionAttributes = sessionTable.arguments[1]; - if ( - userAttributes?.type !== 'ObjectExpression' || - sessionAttributes?.type !== 'ObjectExpression' - ) { - throw new Error('unexpected shape of `user` or `session` table definition'); - } + if (userTable.arguments.length === 1) { + userTable.arguments.push(object.createEmpty()); + } + if (sessionTable.arguments.length === 1) { + sessionTable.arguments.push(object.createEmpty()); + } - if (drizzleDialect === 'sqlite') { - imports.addNamed(ast, 'drizzle-orm/sqlite-core', { - sqliteTable: 'sqliteTable', - text: 'text', - integer: 'integer' - }); + const userAttributes = userTable.arguments[1]; + const sessionAttributes = sessionTable.arguments[1]; + if ( + userAttributes?.type !== 'ObjectExpression' || + sessionAttributes?.type !== 'ObjectExpression' + ) { + throw new Error('unexpected shape of `user` or `session` table definition'); + } + + if (drizzleDialect === 'sqlite') { + imports.addNamed(ast, 'drizzle-orm/sqlite-core', { + sqliteTable: 'sqliteTable', + text: 'text', + integer: 'integer' + }); + object.overrideProperties(userAttributes, { + id: common.expressionFromString(`text('id').primaryKey()`) + }); + if (options.demo) { object.overrideProperties(userAttributes, { - id: common.expressionFromString(`text('id').primaryKey()`) - }); - if (options.demo) { - object.overrideProperties(userAttributes, { - username: common.expressionFromString(`text('username').notNull().unique()`), - passwordHash: common.expressionFromString(`text('password_hash').notNull()`) - }); - } - object.overrideProperties(sessionAttributes, { - id: common.expressionFromString(`text('id').primaryKey()`), - userId: common.expressionFromString( - `text('user_id').notNull().references(() => user.id)` - ), - expiresAt: common.expressionFromString( - `integer('expires_at', { mode: 'timestamp' }).notNull()` - ) + username: common.expressionFromString(`text('username').notNull().unique()`), + passwordHash: common.expressionFromString(`text('password_hash').notNull()`) }); } - if (drizzleDialect === 'mysql') { - imports.addNamed(ast, 'drizzle-orm/mysql-core', { - mysqlTable: 'mysqlTable', - varchar: 'varchar', - datetime: 'datetime' - }); + object.overrideProperties(sessionAttributes, { + id: common.expressionFromString(`text('id').primaryKey()`), + userId: common.expressionFromString( + `text('user_id').notNull().references(() => user.id)` + ), + expiresAt: common.expressionFromString( + `integer('expires_at', { mode: 'timestamp' }).notNull()` + ) + }); + } + if (drizzleDialect === 'mysql') { + imports.addNamed(ast, 'drizzle-orm/mysql-core', { + mysqlTable: 'mysqlTable', + varchar: 'varchar', + datetime: 'datetime' + }); + object.overrideProperties(userAttributes, { + id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`) + }); + if (options.demo) { object.overrideProperties(userAttributes, { - id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`) - }); - if (options.demo) { - object.overrideProperties(userAttributes, { - username: common.expressionFromString( - `varchar('username', { length: 32 }).notNull().unique()` - ), - passwordHash: common.expressionFromString( - `varchar('password_hash', { length: 255 }).notNull()` - ) - }); - } - object.overrideProperties(sessionAttributes, { - id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`), - userId: common.expressionFromString( - `varchar('user_id', { length: 255 }).notNull().references(() => user.id)` + username: common.expressionFromString( + `varchar('username', { length: 32 }).notNull().unique()` ), - expiresAt: common.expressionFromString(`datetime('expires_at').notNull()`) + passwordHash: common.expressionFromString( + `varchar('password_hash', { length: 255 }).notNull()` + ) }); } - if (drizzleDialect === 'postgresql') { - imports.addNamed(ast, 'drizzle-orm/pg-core', { - pgTable: 'pgTable', - text: 'text', - timestamp: 'timestamp' - }); + object.overrideProperties(sessionAttributes, { + id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`), + userId: common.expressionFromString( + `varchar('user_id', { length: 255 }).notNull().references(() => user.id)` + ), + expiresAt: common.expressionFromString(`datetime('expires_at').notNull()`) + }); + } + if (drizzleDialect === 'postgresql') { + imports.addNamed(ast, 'drizzle-orm/pg-core', { + pgTable: 'pgTable', + text: 'text', + timestamp: 'timestamp' + }); + object.overrideProperties(userAttributes, { + id: common.expressionFromString(`text('id').primaryKey()`) + }); + if (options.demo) { object.overrideProperties(userAttributes, { - id: common.expressionFromString(`text('id').primaryKey()`) - }); - if (options.demo) { - object.overrideProperties(userAttributes, { - username: common.expressionFromString(`text('username').notNull().unique()`), - passwordHash: common.expressionFromString(`text('password_hash').notNull()`) - }); - } - object.overrideProperties(sessionAttributes, { - id: common.expressionFromString(`text('id').primaryKey()`), - userId: common.expressionFromString( - `text('user_id').notNull().references(() => user.id)` - ), - expiresAt: common.expressionFromString( - `timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()` - ) + username: common.expressionFromString(`text('username').notNull().unique()`), + passwordHash: common.expressionFromString(`text('password_hash').notNull()`) }); } + object.overrideProperties(sessionAttributes, { + id: common.expressionFromString(`text('id').primaryKey()`), + userId: common.expressionFromString( + `text('user_id').notNull().references(() => user.id)` + ), + expiresAt: common.expressionFromString( + `timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()` + ) + }); + } - let code = generateCode(); - if (typescript) { - if (!code.includes('export type Session =')) { - code += '\n\nexport type Session = typeof session.$inferSelect;'; - } - if (!code.includes('export type User =')) { - code += '\n\nexport type User = typeof user.$inferSelect;'; - } + let code = generateCode(); + if (typescript) { + if (!code.includes('export type Session =')) { + code += '\n\nexport type Session = typeof session.$inferSelect;'; + } + if (!code.includes('export type User =')) { + code += '\n\nexport type User = typeof user.$inferSelect;'; } - return code; } - }, - { - name: ({ kit, typescript }) => `${kit?.libDirectory}/server/auth.${typescript ? 'ts' : 'js'}`, - content: ({ content, typescript }) => { - const { ast, generateCode } = parseScript(content); - - imports.addNamespace(ast, '$lib/server/db/schema', 'table'); - imports.addNamed(ast, '$lib/server/db', { db: 'db' }); - imports.addNamed(ast, '@oslojs/encoding', { - encodeBase32LowerCaseNoPadding: 'encodeBase32LowerCaseNoPadding', - encodeHexLowerCase: 'encodeHexLowerCase' - }); - imports.addNamed(ast, '@oslojs/crypto/sha2', { sha256: 'sha256' }); - imports.addNamed(ast, 'drizzle-orm', { eq: 'eq' }); + return code; + }); + + sv.file(`${kit?.libDirectory}/server/auth.${ext}`, (content) => { + const { ast, generateCode } = parseScript(content); + + imports.addNamespace(ast, '$lib/server/db/schema', 'table'); + imports.addNamed(ast, '$lib/server/db', { db: 'db' }); + imports.addNamed(ast, '@oslojs/encoding', { + encodeBase32LowerCaseNoPadding: 'encodeBase32LowerCaseNoPadding', + encodeHexLowerCase: 'encodeHexLowerCase' + }); + imports.addNamed(ast, '@oslojs/crypto/sha2', { sha256: 'sha256' }); + imports.addNamed(ast, 'drizzle-orm', { eq: 'eq' }); + + const ms = new MagicString(generateCode().trim()); + const [ts] = utils.createPrinter(typescript); + + if (!ms.original.includes('const DAY_IN_MS')) { + ms.append('\n\nconst DAY_IN_MS = 1000 * 60 * 60 * 24;'); + } + if (!ms.original.includes('export const sessionCookieName')) { + ms.append("\n\nexport const sessionCookieName = 'auth-session';"); + } + if (!ms.original.includes('function generateSessionToken')) { + const generateSessionToken = dedent` + ${ts('', '/** @returns {string} */')} + function generateSessionToken()${ts(': string')} { + const bytes = crypto.getRandomValues(new Uint8Array(20)); + const token = encodeBase32LowerCaseNoPadding(bytes); + return token; + }`; + ms.append(`\n\n${generateSessionToken}`); + } + if (!ms.original.includes('async function createSession')) { + const createSession = dedent` + ${ts('', '/** @param {string} userId */')} + export async function createSession(userId${ts(': string')})${ts(': Promise')} { + const token = generateSessionToken(); + const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); + const session${ts(': table.Session')} = { + id: sessionId, + userId, + expiresAt: new Date(Date.now() + DAY_IN_MS * 30) + }; + await db.insert(table.session).values(session); + return session; + }`; + ms.append(`\n\n${createSession}`); + } + if (!ms.original.includes('async function invalidateSession')) { + const invalidateSession = dedent` + ${ts('', '/**')} + ${ts('', ' * @param {string} sessionId')} + ${ts('', ' * @returns {Promise}')} + ${ts('', ' */')} + export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} { + await db.delete(table.session).where(eq(table.session.id, sessionId)); + }`; + ms.append(`\n\n${invalidateSession}`); + } + if (!ms.original.includes('async function validateSession')) { + const validateSession = dedent` + ${ts('', '/** @param {string} sessionId */')} + export async function validateSession(sessionId${ts(': string')}) { + const [result] = await db + .select({ + // Adjust user table here to tweak returned data + user: { id: table.user.id, username: table.user.username }, + session: table.session + }) + .from(table.session) + .innerJoin(table.user, eq(table.session.userId, table.user.id)) + .where(eq(table.session.id, sessionId)); + + if (!result) { + return { session: null, user: null }; + } + const { session, user } = result; - const ms = new MagicString(generateCode().trim()); - const [ts] = utils.createPrinter(typescript); + const sessionExpired = Date.now() >= session.expiresAt.getTime(); + if (sessionExpired) { + await db.delete(table.session).where(eq(table.session.id, session.id)); + return { session: null, user: null }; + } - if (!ms.original.includes('const DAY_IN_MS')) { - ms.append('\n\nconst DAY_IN_MS = 1000 * 60 * 60 * 24;'); - } - if (!ms.original.includes('export const sessionCookieName')) { - ms.append("\n\nexport const sessionCookieName = 'auth-session';"); - } - if (!ms.original.includes('function generateSessionToken')) { - const generateSessionToken = dedent` - ${ts('', '/** @returns {string} */')} - function generateSessionToken()${ts(': string')} { - const bytes = crypto.getRandomValues(new Uint8Array(20)); - const token = encodeBase32LowerCaseNoPadding(bytes); - return token; - }`; - ms.append(`\n\n${generateSessionToken}`); - } - if (!ms.original.includes('async function createSession')) { - const createSession = dedent` - ${ts('', '/** @param {string} userId */')} - export async function createSession(userId${ts(': string')})${ts(': Promise')} { - const token = generateSessionToken(); - const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); - const session${ts(': table.Session')} = { - id: sessionId, - userId, - expiresAt: new Date(Date.now() + DAY_IN_MS * 30) - }; - await db.insert(table.session).values(session); - return session; - }`; - ms.append(`\n\n${createSession}`); - } - if (!ms.original.includes('async function invalidateSession')) { - const invalidateSession = dedent` - ${ts('', '/**')} - ${ts('', ' * @param {string} sessionId')} - ${ts('', ' * @returns {Promise}')} - ${ts('', ' */')} - export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} { - await db.delete(table.session).where(eq(table.session.id, sessionId)); - }`; - ms.append(`\n\n${invalidateSession}`); - } - if (!ms.original.includes('async function validateSession')) { - const validateSession = dedent` - ${ts('', '/** @param {string} sessionId */')} - export async function validateSession(sessionId${ts(': string')}) { - const [result] = await db - .select({ - // Adjust user table here to tweak returned data - user: { id: table.user.id, username: table.user.username }, - session: table.session - }) - .from(table.session) - .innerJoin(table.user, eq(table.session.userId, table.user.id)) - .where(eq(table.session.id, sessionId)); - - if (!result) { - return { session: null, user: null }; - } - const { session, user } = result; - - const sessionExpired = Date.now() >= session.expiresAt.getTime(); - if (sessionExpired) { - await db.delete(table.session).where(eq(table.session.id, session.id)); - return { session: null, user: null }; - } - - const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15; - if (renewSession) { - session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30); - await db - .update(table.session) - .set({ expiresAt: session.expiresAt }) - .where(eq(table.session.id, session.id)); - } - - return { session, user }; - }`; - ms.append(`\n\n${validateSession}`); - } - if (typescript && !ms.original.includes('export type SessionValidationResult')) { - const sessionType = - 'export type SessionValidationResult = Awaited>;'; - ms.append(`\n\n${sessionType}`); - } + const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15; + if (renewSession) { + session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30); + await db + .update(table.session) + .set({ expiresAt: session.expiresAt }) + .where(eq(table.session.id, session.id)); + } - return ms.toString(); + return { session, user }; + }`; + ms.append(`\n\n${validateSession}`); } - }, - { - name: () => 'src/app.d.ts', - condition: ({ typescript }) => typescript, - content: ({ content }) => { + if (typescript && !ms.original.includes('export type SessionValidationResult')) { + const sessionType = + 'export type SessionValidationResult = Awaited>;'; + ms.append(`\n\n${sessionType}`); + } + + return ms.toString(); + }); + + if (typescript) { + sv.file('src/app.d.ts', (content) => { const { ast, generateCode } = parseScript(content); - const locals = kit.addGlobalAppInterface(ast, 'Locals'); + const locals = kitJs.addGlobalAppInterface(ast, 'Locals'); if (!locals) { throw new Error('Failed detecting `locals` interface in `src/app.d.ts`'); } @@ -332,30 +333,23 @@ export default defineAdder({ locals.body.body.push(createLuciaType('session')); } return generateCode(); - } - }, - { - name: ({ typescript }) => `src/hooks.server.${typescript ? 'ts' : 'js'}`, - content: ({ content, typescript }) => { - const { ast, generateCode } = parseScript(content); - imports.addNamespace(ast, '$lib/server/auth.js', 'auth'); - imports.addNamed(ast, '$app/environment', { dev: 'dev' }); - kit.addHooksHandle(ast, typescript, 'handleAuth', getAuthHandleContent()); - return generateCode(); - } - }, - // DEMO - // login/register - { - name: ({ kit }) => `${kit?.routesDirectory}/demo/+page.svelte`, - condition: ({ options }) => options.demo, - content: (editor) => addToDemoPage(editor, 'lucia') - }, - { - name: ({ kit, typescript }) => - `${kit!.routesDirectory}/demo/lucia/login/+page.server.${typescript ? 'ts' : 'js'}`, - condition: ({ options }) => options.demo, - content({ content, typescript, kit }) { + }); + } + + sv.file(`src/hooks.server.${ext}`, (content) => { + const { ast, generateCode } = parseScript(content); + imports.addNamespace(ast, '$lib/server/auth.js', 'auth'); + imports.addNamed(ast, '$app/environment', { dev: 'dev' }); + kitJs.addHooksHandle(ast, typescript, 'handleAuth', getAuthHandleContent()); + return generateCode(); + }); + + if (options.demo) { + sv.file(`${kit?.routesDirectory}/demo/+page.svelte`, (content) => { + return addToDemoPage(content, 'lucia'); + }); + + sv.file(`${kit!.routesDirectory}/demo/lucia/login/+page.server.${ext}`, (content) => { if (content) { const filePath = `${kit!.routesDirectory}/demo/lucia/login/+page.server.${typescript ? 'ts' : 'js'}`; log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`); @@ -486,12 +480,9 @@ export default defineAdder({ ); } `; - } - }, - { - name: ({ kit }) => `${kit!.routesDirectory}/demo/lucia/login/+page.svelte`, - condition: ({ options }) => options.demo, - content({ content, dependencyVersion, typescript, kit }) { + }); + + sv.file(`${kit!.routesDirectory}/demo/lucia/login/+page.svelte`, (content) => { if (content) { const filePath = `${kit!.routesDirectory}/demo/lucia/login/+page.svelte`; log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`); @@ -522,14 +513,9 @@ export default defineAdder({

{form?.message ?? ''}

`; - } - }, - // logout - { - name: ({ kit, typescript }) => - `${kit!.routesDirectory}/demo/lucia/+page.server.${typescript ? 'ts' : 'js'}`, - condition: ({ options }) => options.demo, - content({ content, typescript, kit }) { + }); + + sv.file(`${kit!.routesDirectory}/demo/lucia/+page.server.${ext}`, (content) => { if (content) { const filePath = `${kit!.routesDirectory}/demo/lucia/+page.server.${typescript ? 'ts' : 'js'}`; log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`); @@ -560,12 +546,9 @@ export default defineAdder({ }, }; `; - } - }, - { - name: ({ kit }) => `${kit!.routesDirectory}/demo/lucia/+page.svelte`, - condition: ({ options }) => options.demo, - content({ content, dependencyVersion, typescript, kit }) { + }); + + sv.file(`${kit!.routesDirectory}/demo/lucia/+page.svelte`, (content) => { if (content) { const filePath = `${kit!.routesDirectory}/demo/lucia/+page.svelte`; log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`); @@ -587,9 +570,9 @@ export default defineAdder({ `; - } + }); } - ], + }, nextSteps: ({ highlighter, options, packageManager }) => { const steps = [ `Run ${highlighter.command(`${packageManager} run db:push`)} to update your database schema` From 046e62d11afd2812f029f12d0b00e2ddd77ba614 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Fri, 25 Oct 2024 18:05:16 +0200 Subject: [PATCH 020/126] exract `dependsOn` into seperate function --- packages/adders/lucia/index.ts | 7 ++++--- packages/cli/commands/add/index.ts | 31 ++++++++++++------------------ packages/core/adder/config.ts | 6 ++---- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index c02d9bbe..9c5fdba4 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -46,6 +46,10 @@ export default defineAdder({ environments: { svelte: false, kit: true }, homepage: 'https://lucia-auth.com', options, + dependsOn: ({ dependencyVersion }) => { + if (dependencyVersion('drizzle-orm')) return []; + return ['drizzle']; + }, run: ({ sv, typescript, options, kit, dependencyVersion }) => { const ext = typescript ? 'ts' : 'js'; @@ -57,9 +61,6 @@ export default defineAdder({ sv.dependency('@node-rs/argon2', '^1.1.0'); } - // todo: depends on lucia. Is this the right way? - sv.dependsOn('drizzle', {}); - sv.file(`drizzle.config.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); const isProp = (name: string, node: AstTypes.ObjectProperty) => diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 2aab9b48..16683cf2 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -297,25 +297,15 @@ export async function runAddCommand( // add inter-adder dependencies for (const { adder } of selectedAdders) { - const dependents = - adder.dependsOn?.filter((dep) => !selectedAdders.some((a) => a.adder.id === dep)) ?? []; - const workspace = createWorkspace({ cwd: options.cwd }); - for (const depId of dependents) { - const dependent = officialAdders.find((a) => a.id === depId) as AdderWithoutExplicitArgs; - if (!dependent) throw new Error(`Adder '${adder.id}' depends on an invalid '${depId}'`); - // check if the dependent adder has already been installed - const installed = false; - // todo: see discussion, how to solve this - // installed = dependent.packages.every( - // // we'll skip the conditions since we don't have any options to supply it - // (p) => p.condition !== undefined || !!workspace.dependencyVersion(p.name) - // ); + const dependents = adder.dependsOn?.(workspace) ?? []; + const filteredDependents = + dependents.filter((dep) => !selectedAdders.some((a) => a.adder.id === dep)) ?? []; - if (installed) continue; + for (const depId of filteredDependents) { + const dependent = officialAdders.find((a) => a.id === depId) as AdderWithoutExplicitArgs; - // prompt to install the dependent const install = await p.confirm({ message: `The ${pc.bold(pc.cyan(adder.id))} integration requires ${pc.bold(pc.cyan(depId))} to also be setup. ${pc.green('Include it?')}` }); @@ -507,12 +497,15 @@ async function runAdders({ // this orders the adders to (ideally) have adders without dependencies run first // and adders with dependencies runs later on, based on the adders they depend on. // based on https://stackoverflow.com/a/72030336/16075084 + const workspace = createWorkspace({ cwd, packageManager }); details.sort((a, b) => { - if (!a.dependsOn && !b.dependsOn) return 0; - if (!a.dependsOn) return -1; - if (!b.dependsOn) return 1; + const aDeps = a.dependsOn?.(workspace); + const bDeps = b.dependsOn?.(workspace); + if (!aDeps && !bDeps) return 0; + if (!aDeps) return -1; + if (!bDeps) return 1; - return a.dependsOn.includes(b.id) ? 1 : b.dependsOn.includes(a.id) ? -1 : 0; + return aDeps.includes(b.id) ? 1 : bDeps.includes(a.id) ? -1 : 0; }); // apply adders diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index a44df55c..33c655c0 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -30,8 +30,6 @@ export type SvApi = { file: (path: string, content: (content: string) => string) => string; dependency: (pkg: string, version: string) => void; devDependency: (pkg: string, version: string) => void; - dependsOn: (adder: string, options: Record) => Promise; - // todo: why make this an object, and all other params? Unify! execute: (options: { args: string[]; stdio: 'inherit' | 'pipe' }) => Promise; }; @@ -42,13 +40,13 @@ export type Adder = { environments: Environments; homepage?: string; options: Args; + dependsOn?: (workspace: Workspace) => string[]; + run: (workspace: Workspace & { sv: SvApi }) => MaybePromise; nextSteps?: ( data: { highlighter: Highlighter; } & Workspace ) => string[]; - - run: (workspace: Workspace & { sv: SvApi }) => MaybePromise; }; export type Highlighter = { From 82e723f19ec148e725917fb40d9a7ead033bdc0d Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Fri, 25 Oct 2024 18:15:17 +0200 Subject: [PATCH 021/126] cleanup --- packages/adders/storybook/index.ts | 5 +---- packages/cli/commands/add/index.ts | 6 +++--- packages/core/adder/config.ts | 4 +--- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/adders/storybook/index.ts b/packages/adders/storybook/index.ts index a1cd6e3a..091c0bd8 100644 --- a/packages/adders/storybook/index.ts +++ b/packages/adders/storybook/index.ts @@ -6,9 +6,6 @@ export default defineAdder({ homepage: 'https://storybook.js.org', options: {}, run: ({ sv }) => { - sv.execute({ - args: ['storybook@latest', 'init', '--skip-install', '--no-dev'], - stdio: 'inherit' - }); + sv.execute(['storybook@latest', 'init', '--skip-install', '--no-dev'], 'inherit'); } }); diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 16683cf2..d7c13fdb 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -530,8 +530,8 @@ async function runAdders({ return fileContent; }, - execute: async (script) => { - const { command, args } = resolveCommand(workspace.packageManager, 'execute', script.args)!; + execute: async (commandArgs, stdio) => { + const { command, args } = resolveCommand(workspace.packageManager, 'execute', commandArgs)!; const adderPrefix = details.length > 1 ? `${adder.id}: ` : ''; const executedCommandDisplayName = `${command} ${args.join(' ')}`; p.log.step( @@ -542,7 +542,7 @@ async function runAdders({ if (workspace.packageManager === 'npm') args.unshift('--yes'); try { - await exec(command, args, { nodeOptions: { cwd: workspace.cwd, stdio: script.stdio } }); + await exec(command, args, { nodeOptions: { cwd: workspace.cwd, stdio } }); } catch (error) { const typedError = error as Error; throw new Error( diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index 33c655c0..974c0a04 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -25,13 +25,11 @@ export type Scripts = { condition?: ConditionDefinition; }; -// todo: rename export type SvApi = { file: (path: string, content: (content: string) => string) => string; dependency: (pkg: string, version: string) => void; devDependency: (pkg: string, version: string) => void; - // todo: why make this an object, and all other params? Unify! - execute: (options: { args: string[]; stdio: 'inherit' | 'pipe' }) => Promise; + execute: (args: string[], stdio: 'inherit' | 'pipe') => Promise; }; export type Adder = { From 19ffb9ce42d0058960cfc2a4ae6af922ffb31670 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Fri, 25 Oct 2024 18:17:50 +0200 Subject: [PATCH 022/126] migrate community adder --- community-adder-template/src/index.js | 44 ++++++++++++--------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/community-adder-template/src/index.js b/community-adder-template/src/index.js index 9e4348aa..d31c5121 100644 --- a/community-adder-template/src/index.js +++ b/community-adder-template/src/index.js @@ -1,37 +1,31 @@ import { defineAdder, defineAdderOptions } from '@sveltejs/cli-core'; import { imports } from '@sveltejs/cli-core/js'; -import { parseScript } from '@sveltejs/cli-core/parsers'; +import { parseSvelte } from '@sveltejs/cli-core/parsers'; export const options = defineAdderOptions({ - demo: { - question: 'Do you want to use a demo?', - type: 'boolean', - default: false - } + demo: { + question: 'Do you want to use a demo?', + type: 'boolean', + default: false + } }); export const adder = defineAdder({ id: 'community-adder-template', environments: { kit: true, svelte: true }, options, - packages: [], - files: [ - { - name: () => 'adder-template-demo.txt', - content: ({ content, options }) => { - if (options.demo) { - return 'This is a text file made by the Community Adder Template demo!'; - } - return content; + run: ({ sv }) => { + sv.file('adder-template-demo.txt', (content) => { + if (options.demo) { + return 'This is a text file made by the Community Adder Template demo!'; } - }, - { - name: () => 'src/DemoComponent.svelte', - content: ({ content }) => { - const { ast, generateCode } = parseScript(content); - imports.addDefault(ast, '../adder-template-demo.txt?raw', 'Demo'); - return generateCode(); - } - } - ] + return content; + }); + + sv.file('src/DemoComponent.svelte', (content) => { + const { script, generateCode } = parseSvelte(content); + imports.addDefault(script.ast, '../adder-template-demo.txt?raw', 'Demo'); + return generateCode({ script: script.generateCode() }); + }); + } }); From ec831d223d2a5d51ff33863080c205d6df3df114 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Wed, 30 Oct 2024 20:12:52 +0100 Subject: [PATCH 023/126] try out `setup` api, without actually implementing it --- packages/adders/drizzle/index.ts | 4 +++- packages/adders/eslint/index.ts | 1 - packages/adders/lucia/index.ts | 7 +++---- packages/adders/mdsvex/index.ts | 1 - packages/adders/paraglide/index.ts | 4 +++- packages/adders/playwright/index.ts | 1 - packages/adders/prettier/index.ts | 1 - packages/adders/storybook/index.ts | 1 - packages/adders/tailwindcss/index.ts | 1 - packages/adders/vitest/index.ts | 1 - packages/core/adder/config.ts | 10 +++------- 11 files changed, 12 insertions(+), 20 deletions(-) diff --git a/packages/adders/drizzle/index.ts b/packages/adders/drizzle/index.ts index 8214fb45..0fe7ad4a 100644 --- a/packages/adders/drizzle/index.ts +++ b/packages/adders/drizzle/index.ts @@ -65,9 +65,11 @@ export const options = defineAdderOptions({ export default defineAdder({ id: 'drizzle', - environments: { svelte: false, kit: true }, homepage: 'https://orm.drizzle.team', options, + setup: ({ kit, unavailable }) => { + if (!kit) unavailable(); + }, run: ({ sv, typescript, options, kit }) => { const ext = typescript ? 'ts' : 'js'; diff --git a/packages/adders/eslint/index.ts b/packages/adders/eslint/index.ts index 25f28e95..b5a2257b 100644 --- a/packages/adders/eslint/index.ts +++ b/packages/adders/eslint/index.ts @@ -16,7 +16,6 @@ import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; export default defineAdder({ id: 'eslint', - environments: { svelte: true, kit: true }, homepage: 'https://eslint.org', options: {}, run: ({ sv, typescript, cwd, dependencyVersion }) => { diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 9c5fdba4..cdb29438 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -43,12 +43,11 @@ export const options = defineAdderOptions({ export default defineAdder({ id: 'lucia', - environments: { svelte: false, kit: true }, homepage: 'https://lucia-auth.com', options, - dependsOn: ({ dependencyVersion }) => { - if (dependencyVersion('drizzle-orm')) return []; - return ['drizzle']; + setup: ({ kit, dependencyVersion, unavailable, dependsOn }) => { + if (!kit) unavailable(); + if (!dependencyVersion('drizzle-orm')) dependsOn('drizzle'); }, run: ({ sv, typescript, options, kit, dependencyVersion }) => { const ext = typescript ? 'ts' : 'js'; diff --git a/packages/adders/mdsvex/index.ts b/packages/adders/mdsvex/index.ts index 4cf9cd2f..f132dbc6 100644 --- a/packages/adders/mdsvex/index.ts +++ b/packages/adders/mdsvex/index.ts @@ -4,7 +4,6 @@ import { parseScript } from '@sveltejs/cli-core/parsers'; export default defineAdder({ id: 'mdsvex', - environments: { svelte: true, kit: true }, homepage: 'https://mdsvex.pngwn.io', options: {}, run: ({ sv }) => { diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts index ad3f4aba..78097e90 100644 --- a/packages/adders/paraglide/index.ts +++ b/packages/adders/paraglide/index.ts @@ -63,9 +63,11 @@ const DEFAULT_INLANG_PROJECT = { export default defineAdder({ id: 'paraglide', - environments: { svelte: false, kit: true }, homepage: 'https://inlang.com', options, + setup: ({ kit, unavailable }) => { + if (!kit) unavailable(); + }, run: ({ sv, cwd, options, typescript, kit, dependencyVersion }) => { const ext = typescript ? 'ts' : 'js'; if (!kit) throw new Error('SvelteKit is required'); diff --git a/packages/adders/playwright/index.ts b/packages/adders/playwright/index.ts index be3feca1..f1903135 100644 --- a/packages/adders/playwright/index.ts +++ b/packages/adders/playwright/index.ts @@ -6,7 +6,6 @@ import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; export default defineAdder({ id: 'playwright', - environments: { svelte: true, kit: true }, homepage: 'https://playwright.dev', options: {}, run: ({ sv, cwd, typescript }) => { diff --git a/packages/adders/prettier/index.ts b/packages/adders/prettier/index.ts index 8477868c..d963e548 100644 --- a/packages/adders/prettier/index.ts +++ b/packages/adders/prettier/index.ts @@ -4,7 +4,6 @@ import { parseJson } from '@sveltejs/cli-core/parsers'; export default defineAdder({ id: 'prettier', - environments: { svelte: true, kit: true }, homepage: 'https://prettier.io', options: {}, run: ({ sv, dependencyVersion }) => { diff --git a/packages/adders/storybook/index.ts b/packages/adders/storybook/index.ts index 091c0bd8..1127bfaa 100644 --- a/packages/adders/storybook/index.ts +++ b/packages/adders/storybook/index.ts @@ -2,7 +2,6 @@ import { defineAdder } from '@sveltejs/cli-core'; export default defineAdder({ id: 'storybook', - environments: { kit: true, svelte: true }, homepage: 'https://storybook.js.org', options: {}, run: ({ sv }) => { diff --git a/packages/adders/tailwindcss/index.ts b/packages/adders/tailwindcss/index.ts index 5908ab96..65ff4e24 100644 --- a/packages/adders/tailwindcss/index.ts +++ b/packages/adders/tailwindcss/index.ts @@ -50,7 +50,6 @@ export const options = defineAdderOptions({ export default defineAdder({ id: 'tailwindcss', alias: 'tailwind', - environments: { svelte: true, kit: true }, homepage: 'https://tailwindcss.com', options, run: ({ sv, options, typescript, kit, dependencyVersion }) => { diff --git a/packages/adders/vitest/index.ts b/packages/adders/vitest/index.ts index df07cc1e..a008b99c 100644 --- a/packages/adders/vitest/index.ts +++ b/packages/adders/vitest/index.ts @@ -4,7 +4,6 @@ import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; export default defineAdder({ id: 'vitest', - environments: { svelte: true, kit: true }, homepage: 'https://vitest.dev', options: {}, run: ({ sv, typescript }) => { diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index 974c0a04..a64921a4 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -6,11 +6,6 @@ export type ConditionDefinition = ( Workspace: Workspace ) => boolean; -export type Environments = { - svelte: boolean; - kit: boolean; -}; - export type PackageDefinition = { name: string; version: string; @@ -35,10 +30,11 @@ export type SvApi = { export type Adder = { id: string; alias?: string; - environments: Environments; homepage?: string; options: Args; - dependsOn?: (workspace: Workspace) => string[]; + setup?: ( + workspace: Workspace & { dependsOn: (name: string) => void; unavailable: () => void } + ) => MaybePromise; run: (workspace: Workspace & { sv: SvApi }) => MaybePromise; nextSteps?: ( data: { From 5e22384b8ca325521ec12b81c1b273655cfa1127 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Mon, 4 Nov 2024 17:15:07 -0500 Subject: [PATCH 024/126] skip writing empty files --- packages/cli/commands/add/processor.ts | 4 +++- packages/cli/commands/add/utils.ts | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/cli/commands/add/processor.ts b/packages/cli/commands/add/processor.ts index 8f635243..46c3e7c8 100644 --- a/packages/cli/commands/add/processor.ts +++ b/packages/cli/commands/add/processor.ts @@ -21,12 +21,14 @@ export function createOrUpdateFiles( let content = exists ? readFile(workspace.cwd, fileDetails.name(workspace)) : ''; // process file content = fileDetails.content({ content, ...workspace }); + if (!content) continue; writeFile(workspace, fileDetails.name(workspace), content); changedFiles.push(fileDetails.name(workspace)); } catch (e) { - if (e instanceof Error) + if (e instanceof Error) { throw new Error(`Unable to process '${fileDetails.name(workspace)}'. Reason: ${e.message}`); + } throw e; } } diff --git a/packages/cli/commands/add/utils.ts b/packages/cli/commands/add/utils.ts index 0651fadf..d9a12bdd 100644 --- a/packages/cli/commands/add/utils.ts +++ b/packages/cli/commands/add/utils.ts @@ -15,7 +15,11 @@ export type Package = { workspaces?: string[]; }; -export function getPackageJson(cwd: string) { +export function getPackageJson(cwd: string): { + source: string; + data: Package; + generateCode: () => string; +} { const packageText = readFile(cwd, commonFilePaths.packageJson); if (!packageText) { const pkgPath = path.join(cwd, commonFilePaths.packageJson); From bd756444fbe826c823caa0f718ebe23cf2d0771a Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Tue, 5 Nov 2024 18:07:50 +0100 Subject: [PATCH 025/126] make `setup` function work --- community-adder-template/src/index.js | 4 +- packages/adders/_config/official.ts | 2 +- packages/cli/commands/add/index.ts | 69 ++++++++++++++++++++------- packages/cli/common.ts | 11 ++--- packages/core/adder/config.ts | 2 + 5 files changed, 63 insertions(+), 25 deletions(-) diff --git a/community-adder-template/src/index.js b/community-adder-template/src/index.js index d31c5121..0196f2c3 100644 --- a/community-adder-template/src/index.js +++ b/community-adder-template/src/index.js @@ -12,8 +12,10 @@ export const options = defineAdderOptions({ export const adder = defineAdder({ id: 'community-adder-template', - environments: { kit: true, svelte: true }, options, + setup: ({ kit, unavailable }) => { + if (!kit) unavailable(); + }, run: ({ sv }) => { sv.file('adder-template-demo.txt', (content) => { if (options.demo) { diff --git a/packages/adders/_config/official.ts b/packages/adders/_config/official.ts index 2afb5764..eb4ea38f 100644 --- a/packages/adders/_config/official.ts +++ b/packages/adders/_config/official.ts @@ -24,7 +24,7 @@ export const officialAdders = [ mdsvex, paraglide, storybook -]; +] as AdderWithoutExplicitArgs[]; export function getAdderDetails(id: string): AdderWithoutExplicitArgs { const details = officialAdders.find((a) => a.id === id); diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 8b6193cd..86bda920 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -14,7 +14,12 @@ import { communityAdderIds, getCommunityAdder } from '@sveltejs/adders'; -import type { AdderWithoutExplicitArgs, OptionValues, SvApi } from '@sveltejs/cli-core'; +import type { + AdderSetupResult, + AdderWithoutExplicitArgs, + OptionValues, + SvApi +} from '@sveltejs/cli-core'; import * as common from '../../common.ts'; import { Directive, downloadPackage, getPackageJSON } from '../../utils/fetch-packages.ts'; import { createWorkspace } from './workspace.ts'; @@ -90,7 +95,10 @@ for (const option of addersOptions) { add.addOption(option); } -type SelectedAdder = { type: 'official' | 'community'; adder: AdderWithoutExplicitArgs }; +type SelectedAdder = { + type: 'official' | 'community'; + adder: AdderWithoutExplicitArgs; +}; export async function runAddCommand( options: Options, selectedAdderIds: string[] @@ -264,15 +272,29 @@ export async function runAddCommand( } } + // prepare official adders + let workspace = createWorkspace({ cwd: options.cwd }); + const adderSetupResults: Record = {}; + for (const officialAdder of officialAdders) { + const setupResult: AdderSetupResult = { + available: true, + dependsOn: [] + }; + officialAdder.setup?.({ + ...workspace, + dependsOn: (name) => setupResult.dependsOn.push(name), + unavailable: () => (setupResult.available = false) + }); + adderSetupResults[officialAdder.id] = setupResult; + } + // prompt which adders to apply if (selectedAdders.length === 0) { - const workspace = createWorkspace({ cwd: options.cwd }); - const projectType = workspace.kit ? 'kit' : 'svelte'; const adderOptions = officialAdders .map((adder) => { // we'll only display adders within their respective project types - if (projectType === 'kit' && !adder.environments.kit) return; - if (projectType === 'svelte' && !adder.environments.svelte) return; + const adderSetupResult = adderSetupResults[adder.id]; + if (!adderSetupResult.available) return; return { label: adder.id, @@ -292,14 +314,17 @@ export async function runAddCommand( process.exit(1); } - selected.forEach((id) => selectedAdders.push({ type: 'official', adder: getAdderDetails(id) })); + selected.forEach((id) => + selectedAdders.push({ type: 'official', adder: officialAdders.find((x) => x.id == id)! }) + ); } // add inter-adder dependencies for (const { adder } of selectedAdders) { - const workspace = createWorkspace({ cwd: options.cwd }); + workspace = createWorkspace({ cwd: options.cwd }); + const adderSetupResult = adderSetupResults[adder.id]; - const dependents = adder.dependsOn?.(workspace) ?? []; + const dependents = adderSetupResult.dependsOn; const filteredDependents = dependents.filter((dep) => !selectedAdders.some((a) => a.adder.id === dep)) ?? []; @@ -323,7 +348,12 @@ export async function runAddCommand( const { kit } = createWorkspace({ cwd: options.cwd }); const projectType = kit ? 'kit' : 'svelte'; const adders = selectedAdders.map(({ adder }) => adder); - const { preconditions } = common.getGlobalPreconditions(options.cwd, projectType, adders); + const { preconditions } = common.getGlobalPreconditions( + options.cwd, + projectType, + adders, + adderSetupResults + ); const fails: Array<{ name: string; message?: string }> = []; for (const condition of preconditions) { @@ -419,7 +449,13 @@ export async function runAddCommand( } // apply adders - const filesToFormat = await runAdders({ cwd: options.cwd, packageManager, official, community }); + const filesToFormat = await runAdders({ + cwd: options.cwd, + packageManager, + official, + community, + adderSetupResults + }); p.log.success('Successfully setup add-ons'); // install dependencies @@ -428,7 +464,7 @@ export async function runAddCommand( } // format modified/created files with prettier (if available) - const workspace = createWorkspace({ cwd: options.cwd, packageManager }); + workspace = createWorkspace({ cwd: options.cwd, packageManager }); if (filesToFormat.length > 0 && packageManager && !!workspace.dependencyVersion('prettier')) { const { start, stop } = p.spinner(); start('Formatting modified files'); @@ -476,6 +512,7 @@ export type InstallAdderOptions = { packageManager?: AgentName; official?: AdderOption; community?: AdderOption; + adderSetupResults: Record; }; /** @@ -485,7 +522,8 @@ async function runAdders({ cwd, official = {}, community = {}, - packageManager + packageManager, + adderSetupResults = {} }: InstallAdderOptions): Promise { const adderDetails = Object.keys(official).map((id) => getAdderDetails(id)); const commDetails = Object.keys(community).map( @@ -497,10 +535,9 @@ async function runAdders({ // this orders the adders to (ideally) have adders without dependencies run first // and adders with dependencies runs later on, based on the adders they depend on. // based on https://stackoverflow.com/a/72030336/16075084 - const workspace = createWorkspace({ cwd, packageManager }); details.sort((a, b) => { - const aDeps = a.dependsOn?.(workspace); - const bDeps = b.dependsOn?.(workspace); + const aDeps = adderSetupResults[a.id].dependsOn; + const bDeps = adderSetupResults[b.id].dependsOn; if (!aDeps && !bDeps) return 0; if (!aDeps) return -1; if (!bDeps) return 1; diff --git a/packages/cli/common.ts b/packages/cli/common.ts index de39f0a2..81a28762 100644 --- a/packages/cli/common.ts +++ b/packages/cli/common.ts @@ -6,7 +6,7 @@ import * as p from '@sveltejs/clack-prompts'; import { AGENTS, type AgentName, detectSync } from 'package-manager-detector'; import { COMMANDS, constructCommand, resolveCommand } from 'package-manager-detector/commands'; import type { Argument, HelpConfiguration, Option } from 'commander'; -import type { AdderWithoutExplicitArgs, Precondition } from '@sveltejs/cli-core'; +import type { AdderSetupResult, AdderWithoutExplicitArgs, Precondition } from '@sveltejs/cli-core'; const NO_PREFIX = '--no-'; let options: readonly Option[] = []; @@ -142,7 +142,8 @@ type PreconditionCheck = { name: string; preconditions: Precondition[] }; export function getGlobalPreconditions( cwd: string, projectType: 'svelte' | 'kit', - adders: AdderWithoutExplicitArgs[] + adders: AdderWithoutExplicitArgs[], + adderSetupResults: Record ): PreconditionCheck { return { name: 'global checks', @@ -173,11 +174,7 @@ export function getGlobalPreconditions( name: 'supported environments', run: () => { const addersForInvalidEnvironment = adders.filter((a) => { - const supportedEnvironments = a.environments; - if (projectType === 'kit' && !supportedEnvironments.kit) return true; - if (projectType === 'svelte' && !supportedEnvironments.svelte) return true; - - return false; + return !adderSetupResults[a.id].available; }); if (addersForInvalidEnvironment.length === 0) { diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index a64921a4..1b878cd8 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -55,6 +55,8 @@ export function defineAdder(config: Adder): return config; } +export type AdderSetupResult = { dependsOn: string[]; available: boolean }; + export type AdderWithoutExplicitArgs = Adder>; export type AdderConfigWithoutExplicitArgs = Adder>; From 95ff3862d539a1eedd44a642b377cfe845d3a163 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:49:56 -0500 Subject: [PATCH 026/126] rename dir because vitest hates us --- packages/adders/{vitest => vitest-addon}/index.ts | 0 packages/adders/{vitest => vitest-addon}/logo.svg | 0 packages/adders/vitest/tests.ts | 8 -------- 3 files changed, 8 deletions(-) rename packages/adders/{vitest => vitest-addon}/index.ts (100%) rename packages/adders/{vitest => vitest-addon}/logo.svg (100%) delete mode 100644 packages/adders/vitest/tests.ts diff --git a/packages/adders/vitest/index.ts b/packages/adders/vitest-addon/index.ts similarity index 100% rename from packages/adders/vitest/index.ts rename to packages/adders/vitest-addon/index.ts diff --git a/packages/adders/vitest/logo.svg b/packages/adders/vitest-addon/logo.svg similarity index 100% rename from packages/adders/vitest/logo.svg rename to packages/adders/vitest-addon/logo.svg diff --git a/packages/adders/vitest/tests.ts b/packages/adders/vitest/tests.ts deleted file mode 100644 index 764975ed..00000000 --- a/packages/adders/vitest/tests.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineAdderTests } from '@sveltejs/cli-core'; - -export const tests = defineAdderTests({ - files: [], - options: {}, - optionValues: [], - tests: [] -}); From 71e47f273fa5d6120eba0af24d53023b4c710530 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:50:55 -0500 Subject: [PATCH 027/126] dont expose `options` --- packages/adders/drizzle/index.ts | 2 +- packages/adders/lucia/index.ts | 2 +- packages/adders/paraglide/index.ts | 2 +- packages/adders/tailwindcss/index.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/adders/drizzle/index.ts b/packages/adders/drizzle/index.ts index f3174054..31794408 100644 --- a/packages/adders/drizzle/index.ts +++ b/packages/adders/drizzle/index.ts @@ -8,7 +8,7 @@ const PORTS = { sqlite: '' } as const; -export const options = defineAdderOptions({ +const options = defineAdderOptions({ database: { question: 'Which database would you like to use?', type: 'select', diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 35b905bd..7a73e53a 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -25,7 +25,7 @@ type Dialect = 'mysql' | 'postgresql' | 'sqlite'; let drizzleDialect: Dialect; let schemaPath: string; -export const options = defineAdderOptions({ +const options = defineAdderOptions({ demo: { type: 'boolean', default: true, diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts index 459f0295..b2f1b49d 100644 --- a/packages/adders/paraglide/index.ts +++ b/packages/adders/paraglide/index.ts @@ -32,7 +32,7 @@ const DEFAULT_INLANG_PROJECT = { } }; -export const options = defineAdderOptions({ +const options = defineAdderOptions({ availableLanguageTags: { question: `Which languages would you like to support? ${colors.gray('(e.g. en,de-ch)')}`, type: 'string', diff --git a/packages/adders/tailwindcss/index.ts b/packages/adders/tailwindcss/index.ts index 4993f9fb..b0f30d33 100644 --- a/packages/adders/tailwindcss/index.ts +++ b/packages/adders/tailwindcss/index.ts @@ -45,7 +45,7 @@ const pluginPackages: Array> = plugins.map((x) condition: ({ options }) => options.plugins.includes(x.id) })); -export const options = defineAdderOptions({ +const options = defineAdderOptions({ plugins: { type: 'multiselect', question: 'Which plugins would you like to add?', From 7e0f15271a20d915073e21d8255e163f2b00ae49 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:51:16 -0500 Subject: [PATCH 028/126] simplify --- packages/adders/package.json | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/adders/package.json b/packages/adders/package.json index c580c405..39023993 100644 --- a/packages/adders/package.json +++ b/packages/adders/package.json @@ -6,14 +6,10 @@ "scripts": { "check": "tsc", "format": "pnpm lint --write", - "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore" - }, - "exports": { - ".": { - "types": "./index.ts", - "default": "./index.ts" - } + "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore", + "test": "vitest" }, + "exports": "./index.ts", "dependencies": { "@sveltejs/cli-core": "workspace:*" } From 974e5ade1e7e071c72f26e848b113902e75a467a Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:53:25 -0500 Subject: [PATCH 029/126] pm --- packages/core/adder/workspace.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/adder/workspace.ts b/packages/core/adder/workspace.ts index a03f2877..85bb4fcd 100644 --- a/packages/core/adder/workspace.ts +++ b/packages/core/adder/workspace.ts @@ -14,5 +14,7 @@ export type Workspace = { dependencyVersion: (pkg: string) => string | undefined; typescript: boolean; kit: { libDirectory: string; routesDirectory: string } | undefined; - packageManager: 'npm' | 'yarn' | 'pnpm' | 'bun'; + packageManager: PackageManager; }; + +export type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun'; From 857094054f6ecb07e3de9ebc8fe300a9317047cd Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:56:05 -0500 Subject: [PATCH 030/126] remove old tests --- packages/adders/_config/official.ts | 2 +- packages/adders/eslint/tests.ts | 8 ---- packages/adders/lucia/tests.ts | 9 ---- packages/adders/mdsvex/tests.ts | 70 ---------------------------- packages/adders/paraglide/tests.ts | 10 ---- packages/adders/playwright/tests.ts | 8 ---- packages/adders/prettier/tests.ts | 8 ---- packages/adders/tailwindcss/tests.ts | 63 ------------------------- 8 files changed, 1 insertion(+), 177 deletions(-) delete mode 100644 packages/adders/eslint/tests.ts delete mode 100644 packages/adders/lucia/tests.ts delete mode 100644 packages/adders/mdsvex/tests.ts delete mode 100644 packages/adders/paraglide/tests.ts delete mode 100644 packages/adders/playwright/tests.ts delete mode 100644 packages/adders/prettier/tests.ts delete mode 100644 packages/adders/tailwindcss/tests.ts diff --git a/packages/adders/_config/official.ts b/packages/adders/_config/official.ts index 2afb5764..6beba501 100644 --- a/packages/adders/_config/official.ts +++ b/packages/adders/_config/official.ts @@ -9,7 +9,7 @@ import playwright from '../playwright/index.ts'; import prettier from '../prettier/index.ts'; import storybook from '../storybook/index.ts'; import tailwindcss from '../tailwindcss/index.ts'; -import vitest from '../vitest/index.ts'; +import vitest from '../vitest-addon/index.ts'; // The order of adders here determines the order they are displayed inside the CLI // We generally try to order them by perceived popularity diff --git a/packages/adders/eslint/tests.ts b/packages/adders/eslint/tests.ts deleted file mode 100644 index 764975ed..00000000 --- a/packages/adders/eslint/tests.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineAdderTests } from '@sveltejs/cli-core'; - -export const tests = defineAdderTests({ - files: [], - options: {}, - optionValues: [], - tests: [] -}); diff --git a/packages/adders/lucia/tests.ts b/packages/adders/lucia/tests.ts deleted file mode 100644 index cf23fa33..00000000 --- a/packages/adders/lucia/tests.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { defineAdderTests } from '@sveltejs/cli-core'; -import { options } from './index.ts'; - -export const tests = defineAdderTests({ - files: [], - options, - optionValues: [], - tests: [] -}); diff --git a/packages/adders/mdsvex/tests.ts b/packages/adders/mdsvex/tests.ts deleted file mode 100644 index 503d2a1b..00000000 --- a/packages/adders/mdsvex/tests.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { defineAdderTests, type OptionDefinition, type FileEditor } from '@sveltejs/cli-core'; -import { imports } from '@sveltejs/cli-core/js'; -import * as html from '@sveltejs/cli-core/html'; -import { parseSvelte } from '@sveltejs/cli-core/parsers'; - -export const tests = defineAdderTests({ - files: [ - { - name: ({ kit }) => `${kit?.routesDirectory}/+page.svelte`, - content: useMarkdownFile, - condition: ({ kit }) => Boolean(kit) - }, - { - name: () => 'src/App.svelte', - content: useMarkdownFile, - condition: ({ kit }) => !kit - }, - { - name: ({ kit }) => `${kit?.routesDirectory}/Demo.svx`, - content: addMarkdownFile, - condition: ({ kit }) => Boolean(kit) - }, - { - name: () => 'src/Demo.svx', - content: addMarkdownFile, - condition: ({ kit }) => !kit - } - ], - options: {}, - optionValues: [], - tests: [ - { - name: 'elements exist', - run: async ({ elementExists }) => { - await elementExists('.mdsvex h1'); - await elementExists('.mdsvex h2'); - await elementExists('.mdsvex p'); - } - } - ] -}); - -function addMarkdownFile({ content }: FileEditor) { - // example taken from website: https://mdsvex.pngwn.io - return ( - content + - ` ---- -title: Svex up your markdown ---- - -# { title } - -## Good stuff in your markdown - -Markdown is pretty good but sometimes you just need more. -` - ); -} - -function useMarkdownFile({ content }: FileEditor) { - const { script, template, generateCode } = parseSvelte(content); - imports.addDefault(script.ast, './Demo.svx', 'Demo'); - - const div = html.div({ class: 'mdsvex' }); - html.appendElement(template.ast.childNodes, div); - const mdsvexNode = html.element('Demo'); - html.appendElement(div.childNodes, mdsvexNode); - return generateCode({ script: script.generateCode(), template: template.generateCode() }); -} diff --git a/packages/adders/paraglide/tests.ts b/packages/adders/paraglide/tests.ts deleted file mode 100644 index 8941a20b..00000000 --- a/packages/adders/paraglide/tests.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { defineAdderTests } from '@sveltejs/cli-core'; -import { options } from './index.ts'; -// e2e tests make no sense in this context - -export const tests = defineAdderTests({ - files: [], - options, - optionValues: [], - tests: [] -}); diff --git a/packages/adders/playwright/tests.ts b/packages/adders/playwright/tests.ts deleted file mode 100644 index 764975ed..00000000 --- a/packages/adders/playwright/tests.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineAdderTests } from '@sveltejs/cli-core'; - -export const tests = defineAdderTests({ - files: [], - options: {}, - optionValues: [], - tests: [] -}); diff --git a/packages/adders/prettier/tests.ts b/packages/adders/prettier/tests.ts deleted file mode 100644 index 764975ed..00000000 --- a/packages/adders/prettier/tests.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineAdderTests } from '@sveltejs/cli-core'; - -export const tests = defineAdderTests({ - files: [], - options: {}, - optionValues: [], - tests: [] -}); diff --git a/packages/adders/tailwindcss/tests.ts b/packages/adders/tailwindcss/tests.ts deleted file mode 100644 index ea28b2af..00000000 --- a/packages/adders/tailwindcss/tests.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { defineAdderTests } from '@sveltejs/cli-core'; -import { options } from './index.ts'; - -const divId = 'myDiv'; -const typographyDivId = 'myTypographyDiv'; - -export const tests = defineAdderTests({ - files: [ - { - name: ({ kit }) => `${kit?.routesDirectory}/+page.svelte`, - content: ({ content, options }) => { - content = prepareCoreTest(content); - if (options.plugins.includes('typography')) content = prepareTypographyTest(content); - return content; - }, - condition: ({ kit }) => Boolean(kit) - }, - { - name: () => 'src/App.svelte', - content: ({ content, options }) => { - content = prepareCoreTest(content); - if (options.plugins.includes('typography')) content = prepareTypographyTest(content); - return content; - }, - condition: ({ kit }) => !kit - } - ], - options, - optionValues: [{ plugins: [] }, { plugins: ['typography'] }], - tests: [ - { - name: 'core properties', - run: async ({ expectProperty }) => { - const selector = '#' + divId; - await expectProperty(selector, 'background-color', 'rgb(71, 85, 105)'); - await expectProperty(selector, 'border-color', 'rgb(249, 250, 251)'); - await expectProperty(selector, 'border-width', '4px'); - await expectProperty(selector, 'margin-top', '4px'); - } - }, - { - name: 'typography properties', - condition: ({ plugins }) => plugins.includes('typography'), - run: async ({ expectProperty }) => { - const selector = '#' + typographyDivId; - await expectProperty(selector, 'font-size', '18px'); - await expectProperty(selector, 'line-height', '28px'); - await expectProperty(selector, 'text-align', 'right'); - await expectProperty(selector, 'text-decoration-line', 'line-through'); - } - } - ] -}); - -function prepareCoreTest(content: string) { - const div = `
`; - return content + div; -} - -function prepareTypographyTest(content: string) { - const p = `

`; - return content + p; -} From 809a72f5a261299d3fb150f1894b693a34075a56 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 20:41:07 -0500 Subject: [PATCH 031/126] initial install helper impl --- packages/cli/env.ts | 2 +- packages/cli/index.ts | 6 +- packages/cli/lib/install.ts | 88 +++++++++++++++++++++++++++++ packages/cli/package.json | 7 +++ packages/cli/testing.ts | 110 ++++++++++++++++++++++++++++++++++++ packages/cli/tsconfig.json | 2 +- 6 files changed, 210 insertions(+), 5 deletions(-) create mode 100644 packages/cli/lib/install.ts create mode 100644 packages/cli/testing.ts diff --git a/packages/cli/env.ts b/packages/cli/env.ts index d482918b..4ab46826 100644 --- a/packages/cli/env.ts +++ b/packages/cli/env.ts @@ -1,3 +1,3 @@ import process from 'node:process'; -export const TESTING: boolean = process.env.CI?.toLowerCase() === 'true'; +export const TESTING: boolean = process.env.NODE_ENV?.toLowerCase() === 'test'; diff --git a/packages/cli/index.ts b/packages/cli/index.ts index 50f83ec1..31079a3c 100644 --- a/packages/cli/index.ts +++ b/packages/cli/index.ts @@ -1,3 +1,3 @@ -import { create } from '@sveltejs/create'; - -export { create }; +export { create } from '@sveltejs/create'; +export { installAddon } from './lib/install.ts'; +export type { AddonMap, InstallOptions, OptionMap } from './lib/install.ts'; diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts new file mode 100644 index 00000000..f1bd2a43 --- /dev/null +++ b/packages/cli/lib/install.ts @@ -0,0 +1,88 @@ +import { exec } from 'tinyexec'; +import { resolveCommand } from 'package-manager-detector'; +import type { Adder, Workspace, PackageManager, OptionValues, Question } from '@sveltejs/cli-core'; +import { createWorkspace } from '../commands/add/workspace.ts'; +import { createOrUpdateFiles } from '../commands/add/processor.ts'; +import { installPackages } from '../commands/add/utils.ts'; + +type Addon = Adder; +export type InstallOptions = { + cwd: string; + addons: Addons; + options: OptionMap; + packageManager: PackageManager; +}; + +export type AddonMap = Record; +export type OptionMap = { + [K in keyof Addons]: Partial>; +}; + +export async function installAddon({ + addons, + cwd, + options, + packageManager = 'npm' +}: InstallOptions): Promise { + const filesToFormat = new Set(); + + const mapped = Object.entries(addons).map(([, addon]) => addon); + const ordered = orderAddons(mapped); + + for (const addon of ordered) { + const workspace = createWorkspace({ cwd, packageManager }); + workspace.options = options[addon.id]; + + const files = await runAddon(workspace, addon); + files.forEach((f) => filesToFormat.add(f)); + } + + return Array.from(filesToFormat); +} + +async function runAddon(workspace: Workspace, addon: Addon): Promise { + const files = new Set(); + + // TODO: figure out why this is wrongly typed + // apply default adder options + for (const [, question] of Object.entries(addon.options as Record)) { + // we'll only apply defaults to options that don't explicitly fail their conditions + if (question.condition?.(workspace.options) !== false) { + workspace.options ??= question.default; + } + } + + const pkgPath = installPackages(addon, workspace); + files.add(pkgPath); + const changedFiles = createOrUpdateFiles(addon.files, workspace); + changedFiles.forEach((file) => files.add(file)); + + for (const script of addon.scripts ?? []) { + if (script.condition?.(workspace) === false) continue; + + try { + const { args, command } = resolveCommand(workspace.packageManager, 'execute', script.args)!; + if (workspace.packageManager === 'npm') args.unshift('--yes'); + await exec(command, script.args, { nodeOptions: { cwd: workspace.cwd, stdio: 'pipe' } }); + } catch (error) { + const typedError = error as Error; + throw new Error(`Failed to execute scripts '${script.description}': ` + typedError.message); + } + } + + return Array.from(files); +} + +// sorts them to their execution order +function orderAddons(addons: Addon[]) { + return Array.from(addons).sort((a, b) => { + if (!a.dependsOn && !b.dependsOn) return 0; + if (!a.dependsOn) return -1; + if (!b.dependsOn) return 1; + + if (a.dependsOn.includes(b.id)) return 1; + if (b.dependsOn.includes(a.id)) return -1; + + return 0; + }); +} diff --git a/packages/cli/package.json b/packages/cli/package.json index e5df83f8..2ec028e5 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -23,6 +23,10 @@ ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" + }, + "./test": { + "types": "./dist/testing.d.ts", + "default": "./dist/testing.js" } }, "devDependencies": { @@ -30,12 +34,15 @@ "@sveltejs/clack-prompts": "workspace:*", "@sveltejs/cli-core": "workspace:*", "@sveltejs/create": "workspace:*", + "@types/degit": "^2.8.6", "@types/tar-fs": "^2.0.4", "commander": "^12.1.0", + "degit": "^2.8.4", "empathic": "^1.0.0", "package-manager-detector": "^0.2.2", "picocolors": "^1.1.0", "tar-fs": "^3.0.6", + "terminate": "^2.8.0", "tinyexec": "^0.3.0", "valibot": "^0.41.0" }, diff --git a/packages/cli/testing.ts b/packages/cli/testing.ts new file mode 100644 index 00000000..764a9a1d --- /dev/null +++ b/packages/cli/testing.ts @@ -0,0 +1,110 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process'; +import degit from 'degit'; +import terminate from 'terminate'; +import { create } from '@sveltejs/create'; +import { resolveCommand } from 'package-manager-detector'; +import type { PackageManager } from '@sveltejs/cli-core'; + +export type ProjectVariant = (typeof variants)[number]; +export const variants = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts'] as const; + +const TEMPLATES_DIR = '.templates'; + +export type CreateProject = (options: { + testId: string; + variant: ProjectVariant; + /** @default true */ + clean?: boolean; +}) => string; + +type SetupOptions = { + cwd: string; + variants: readonly ProjectVariant[]; + /** @default false */ + clean?: boolean; +}; +export async function setup({ + cwd, + clean = false, + variants +}: SetupOptions): Promise<{ templatesDir: string }> { + const workingDir = path.resolve(cwd); + if (clean && fs.existsSync(workingDir)) { + fs.rmSync(workingDir, { force: true, recursive: true }); + } + + // fetch the project types + const templatesDir = path.resolve(workingDir, TEMPLATES_DIR); + fs.mkdirSync(templatesDir, { recursive: true }); + for (const variant of variants) { + const templatePath = path.resolve(templatesDir, variant); + if (fs.existsSync(templatePath)) continue; + + if (variant === 'kit-js') { + create(templatePath, { name: variant, template: 'minimal', types: 'checkjs' }); + } else if (variant === 'kit-ts') { + create(templatePath, { name: variant, template: 'minimal', types: 'typescript' }); + } else if (variant === 'vite-js' || variant === 'vite-ts') { + const name = `template-svelte${variant === 'vite-ts' ? '-ts' : ''}`; + // TODO: should probably point this to a specific commit hash (ex: `#1234abcd`) + const template = degit(`vitejs/vite/packages/create-vite/${name}`, { force: true }); + await template.clone(templatePath); + } else throw new Error(`Unknown project variant: ${variant}`); + } + + return { templatesDir }; +} + +type CreateOptions = { cwd: string; testName: string; templatesDir: string }; +export function createProject({ cwd, testName, templatesDir }: CreateOptions): CreateProject { + // create the reference dir + const testDir = path.resolve(cwd, testName); + fs.mkdirSync(testDir, { recursive: true }); + return ({ testId, variant, clean = true }) => { + const targetDir = path.resolve(testDir, testId); + if (clean && fs.existsSync(targetDir)) { + fs.rmSync(targetDir, { force: true, recursive: true }); + } + const templatePath = path.resolve(templatesDir, variant); + fs.cpSync(templatePath, targetDir, { recursive: true, force: true }); + return targetDir; + }; +} + +type PreviewOptions = { cwd: string; packageManager?: PackageManager }; +export async function startPreview({ cwd, packageManager = 'npm' }: PreviewOptions): Promise<{ + url: string; + server: ChildProcessWithoutNullStreams; + close: () => void; +}> { + const { command, args } = resolveCommand(packageManager, 'run', ['preview'])!; + + const process = spawn(command, args, { stdio: 'pipe', shell: true, cwd, timeout: 120_000 }); + const close = () => { + if (!process.pid) return; + terminate(process.pid); + }; + + return await new Promise((resolve) => { + process.stdout.on('data', (data: Buffer) => { + const value = data.toString(); + + // extract dev server url from console output + const regexUnicode = /[^\x20-\xaf]+/g; + const withoutUnicode = value.replace(regexUnicode, ''); + + const regexUnicodeDigits = /\[[0-9]{1,2}m/g; + const withoutColors = withoutUnicode.replace(regexUnicodeDigits, ''); + + const regexUrl = /http:\/\/[^:\s]+:[0-9]+\//g; + const urls = withoutColors.match(regexUrl); + + if (urls && urls.length > 0) { + const url = urls[0]; + resolve({ url, server: process, close }); + } + }); + }); +} diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json index 6f800349..9249a2e6 100644 --- a/packages/cli/tsconfig.json +++ b/packages/cli/tsconfig.json @@ -6,5 +6,5 @@ "declaration": true }, // we'll only want to enforce `isolatedDeclarations` on the library portion of the CLI - "include": ["index.ts"] + "include": ["index.ts", "testing.ts"] } From 3e6f6bdc4ab531c5f82ffb34b0b4c467a50871dc Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 20:41:26 -0500 Subject: [PATCH 032/126] ignores --- .gitignore | 1 + community-adder-template/.gitignore | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 486eb366..193b6ac1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ yarn.lock vite.config.js.timestamp-* /packages/create-svelte/template/CHANGELOG.md .test-tmp +.test-output diff --git a/community-adder-template/.gitignore b/community-adder-template/.gitignore index 33738ed9..4404a552 100644 --- a/community-adder-template/.gitignore +++ b/community-adder-template/.gitignore @@ -1,3 +1,4 @@ node_modules temp .outputs +.test-output \ No newline at end of file From 0c86f370fbb00a6c8ef05b449122eebfdc470b68 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 20:44:47 -0500 Subject: [PATCH 033/126] add initial tests --- packages/adders/_tests/_setup/global.ts | 29 ++++++ packages/adders/_tests/_setup/setup.ts | 92 +++++++++++++++++++ .../adders/_tests/drizzle/docker-compose.yml | 20 ++++ packages/adders/_tests/drizzle/fixtures.ts | 26 ++++++ packages/adders/_tests/drizzle/test.ts | 62 +++++++++++++ packages/adders/_tests/eslint/test.ts | 16 ++++ packages/adders/_tests/lucia/test.ts | 20 ++++ packages/adders/_tests/mdsvex/test.ts | 66 +++++++++++++ packages/adders/_tests/paraglide/test.ts | 17 ++++ packages/adders/_tests/playwright/test.ts | 15 +++ packages/adders/_tests/prettier/test.ts | 15 +++ packages/adders/_tests/tailwindcss/test.ts | 57 ++++++++++++ packages/adders/_tests/vitest/test.ts | 15 +++ packages/adders/package.json | 3 + packages/adders/vitest.config.ts | 16 ++++ 15 files changed, 469 insertions(+) create mode 100644 packages/adders/_tests/_setup/global.ts create mode 100644 packages/adders/_tests/_setup/setup.ts create mode 100644 packages/adders/_tests/drizzle/docker-compose.yml create mode 100644 packages/adders/_tests/drizzle/fixtures.ts create mode 100644 packages/adders/_tests/drizzle/test.ts create mode 100644 packages/adders/_tests/eslint/test.ts create mode 100644 packages/adders/_tests/lucia/test.ts create mode 100644 packages/adders/_tests/mdsvex/test.ts create mode 100644 packages/adders/_tests/paraglide/test.ts create mode 100644 packages/adders/_tests/playwright/test.ts create mode 100644 packages/adders/_tests/prettier/test.ts create mode 100644 packages/adders/_tests/tailwindcss/test.ts create mode 100644 packages/adders/_tests/vitest/test.ts create mode 100644 packages/adders/vitest.config.ts diff --git a/packages/adders/_tests/_setup/global.ts b/packages/adders/_tests/_setup/global.ts new file mode 100644 index 00000000..5387fb66 --- /dev/null +++ b/packages/adders/_tests/_setup/global.ts @@ -0,0 +1,29 @@ +import path from 'node:path'; +import { setup, type ProjectVariant } from 'sv/test'; +import type { GlobalSetupContext } from 'vitest/node'; + +const TEST_DIR = path.resolve('.test-output'); +const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; + +export default async function ({ provide }: GlobalSetupContext) { + // global setup (e.g. spin up docker containers) + + // downloads different project configurations (sveltekit, js/ts, vite-only, etc) + const { templatesDir } = await setup({ cwd: TEST_DIR, variants, clean: true }); + + provide('testDir', TEST_DIR); + provide('templatesDir', templatesDir); + provide('variants', variants); + + return async () => { + // tear down... (e.g. cleanup docker containers) + }; +} + +declare module 'vitest' { + export interface ProvidedContext { + testDir: string; + templatesDir: string; + variants: ProjectVariant[]; + } +} diff --git a/packages/adders/_tests/_setup/setup.ts b/packages/adders/_tests/_setup/setup.ts new file mode 100644 index 00000000..f39ee8af --- /dev/null +++ b/packages/adders/_tests/_setup/setup.ts @@ -0,0 +1,92 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import * as vi from 'vitest'; +import { exec } from 'tinyexec'; +import { installAddon, type AddonMap, type OptionMap } from 'sv'; +import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/test'; +import { chromium, type Browser, type Page } from '@playwright/test'; + +const cwd = vi.inject('testDir'); +const templatesDir = vi.inject('templatesDir'); +const variants = vi.inject('variants'); + +type Fixtures = { + page: Page; + run(variant: ProjectVariant, options: OptionMap): Promise; +}; + +export function setupTest(addons: Addons) { + const test = vi.test.extend>({} as any); + + let create: CreateProject; + let browser: Browser; + + vi.beforeAll(async () => { + browser = await chromium.launch(); + return async () => { + await browser.close(); + }; + }); + + vi.beforeAll(({ name }) => { + const testName = path.dirname(name).split(path.sep).at(-1)!; + + // constructs a builder for create test projects + create = createProject({ cwd, templatesDir, testName }); + + // creates a pnpm workspace in each addon dir + fs.writeFileSync( + path.resolve(cwd, testName, 'pnpm-workspace.yaml'), + `packages:\n - '**/*'`, + 'utf8' + ); + }); + + // runs before each test case + vi.beforeEach>(async (ctx) => { + const browserCtx = await browser.newContext(); + ctx.page = await browserCtx.newPage(); + ctx.run = async (variant, options) => { + const cwd = create({ testId: ctx.task.id, variant }); + + // test metadata + const metaPath = path.resolve(cwd, 'meta.json'); + fs.writeFileSync(metaPath, JSON.stringify({ variant, options }, null, '\t'), 'utf8'); + + // run adder + await installAddon({ cwd, addons, options, packageManager: 'pnpm' }); + + return cwd; + }; + + return async () => { + await browserCtx.close(); + // ...other tear downs + }; + }); + + return { test, variants, prepareServer }; +} + +// installs dependencies, builds the project, and spins up the preview server +async function prepareServer( + { cwd, page }: { cwd: string; page: Page }, + afterInstall?: () => Promise | any +) { + // install deps + await exec('pnpm', ['i'], { nodeOptions: { cwd } }); + + // ...do commands and any other extra stuff + await afterInstall?.(); + + // build project + await exec('npm', ['run', 'build'], { nodeOptions: { cwd } }); + + // start preview server `vite preview` + const { url, close } = await startPreview({ cwd }); + + // navigate to the page + await page.goto(url); + + return { url, close }; +} diff --git a/packages/adders/_tests/drizzle/docker-compose.yml b/packages/adders/_tests/drizzle/docker-compose.yml new file mode 100644 index 00000000..f6f5e0a7 --- /dev/null +++ b/packages/adders/_tests/drizzle/docker-compose.yml @@ -0,0 +1,20 @@ +services: + db-postgres: + image: postgres + restart: always + shm_size: 128mb + ports: + - 5432:5432 + environment: + POSTGRES_USER: root + POSTGRES_PASSWORD: mysecretpassword + POSTGRES_DB: local + db-mysql: + image: mysql + restart: always + shm_size: 128mb + ports: + - 3306:3306 + environment: + MYSQL_ROOT_PASSWORD: mysecretpassword + MYSQL_DATABASE: local diff --git a/packages/adders/_tests/drizzle/fixtures.ts b/packages/adders/_tests/drizzle/fixtures.ts new file mode 100644 index 00000000..a6e2f803 --- /dev/null +++ b/packages/adders/_tests/drizzle/fixtures.ts @@ -0,0 +1,26 @@ +export const pageServer = ` +import { db } from '$lib/server/db'; +import { user } from '$lib/server/db/schema.js'; + +export const load = async () => { + await insertUser({ name: 'Foobar', id: 0, age: 20 }).catch((err) => console.error(err)); + + const users = await db.select().from(user); + + return { users }; +}; + +function insertUser(value) { + return db.insert(user).values(value); +} +`; + +export const pageComp = ` + + +{#each data.users as user} + {user.id} {user.name} +{/each} +`; diff --git a/packages/adders/_tests/drizzle/test.ts b/packages/adders/_tests/drizzle/test.ts new file mode 100644 index 00000000..928116d0 --- /dev/null +++ b/packages/adders/_tests/drizzle/test.ts @@ -0,0 +1,62 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import * as vi from 'vitest'; +import { expect } from '@playwright/test'; +import { exec } from 'tinyexec'; +import { setupTest } from '../_setup/setup.ts'; +import drizzle from '../../drizzle/index.ts'; +import { pageServer, pageComp } from './fixtures.ts'; + +const { test, variants, prepareServer } = setupTest({ drizzle }); + +vi.beforeAll(async () => { + const cwd = path.dirname(fileURLToPath(import.meta.url)); + await exec('docker', ['compose', 'up', '--detach'], { + nodeOptions: { cwd, stdio: 'pipe' } + }); + + return async () => { + await exec('docker', ['compose', 'down', '--volumes'], { + nodeOptions: { cwd, stdio: 'pipe' } + }); + }; +}); + +const kitOnly = variants.filter((v) => v.includes('kit')); +const testCases = [ + { name: 'better-sqlite3', options: { database: 'sqlite', sqlite: 'better-sqlite3' } }, + { name: 'libsql', options: { database: 'sqlite', sqlite: 'libsql' } }, + { name: 'mysql2', options: { database: 'mysql', mysql: 'mysql2', docker: true } }, + { + name: 'postgres.js', + options: { database: 'postgresql', postgresql: 'postgres.js', docker: true } + } +].flatMap((opts) => kitOnly.map((variant) => ({ ...opts, variant }))); + +test.concurrent.for(testCases)( + 'queries database - $name - $variant', + async ({ options, variant }, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { drizzle: options as any }); + + const ts = variant === 'kit-ts'; + const drizzleConfig = path.resolve(cwd, `drizzle.config.${ts ? 'ts' : 'js'}`); + const content = fs.readFileSync(drizzleConfig, 'utf8').replace('strict: true,', ''); + fs.writeFileSync(drizzleConfig, content, 'utf8'); + + const routes = path.resolve(cwd, 'src', 'routes'); + const pagePath = path.resolve(routes, '+page.svelte'); + fs.writeFileSync(pagePath, pageComp, 'utf8'); + + const pageServerPath = path.resolve(routes, `+page.server.${ts ? 'ts' : 'js'}`); + fs.writeFileSync(pageServerPath, pageServer, 'utf8'); + + const { close } = await prepareServer({ cwd, page }, async () => { + await exec('npm', ['run', 'db:push'], { nodeOptions: { cwd, stdio: 'pipe' } }); + }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + expect(await page.$('[data-testid]')).toBeTruthy(); + } +); diff --git a/packages/adders/_tests/eslint/test.ts b/packages/adders/_tests/eslint/test.ts new file mode 100644 index 00000000..a24a7f96 --- /dev/null +++ b/packages/adders/_tests/eslint/test.ts @@ -0,0 +1,16 @@ +import { expect } from '@playwright/test'; +import { setupTest } from '../_setup/setup.ts'; +import eslint from '../../eslint/index.ts'; + +const { test, variants, prepareServer } = setupTest({ eslint }); + +const kitOnly = variants.filter((v) => v.includes('kit')); +test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { eslint: {} }); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + expect(true).toBe(true); +}); diff --git a/packages/adders/_tests/lucia/test.ts b/packages/adders/_tests/lucia/test.ts new file mode 100644 index 00000000..1dc81acc --- /dev/null +++ b/packages/adders/_tests/lucia/test.ts @@ -0,0 +1,20 @@ +import { expect } from '@playwright/test'; +import { setupTest } from '../_setup/setup.ts'; +import lucia from '../../lucia/index.ts'; +import drizzle from '../../drizzle/index.ts'; + +const { test, variants, prepareServer } = setupTest({ drizzle, lucia }); + +const kitOnly = variants.filter((v) => v.includes('kit')); +test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { + drizzle: { database: 'sqlite', sqlite: 'libsql' }, + lucia: { demo: true } + }); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + expect(true).toBe(true); +}); diff --git a/packages/adders/_tests/mdsvex/test.ts b/packages/adders/_tests/mdsvex/test.ts new file mode 100644 index 00000000..e2d599f8 --- /dev/null +++ b/packages/adders/_tests/mdsvex/test.ts @@ -0,0 +1,66 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { expect } from '@playwright/test'; +import { parseSvelte } from '@sveltejs/cli-core/parsers'; +import { imports } from '@sveltejs/cli-core/js'; +import * as html from '@sveltejs/cli-core/html'; +import { setupTest } from '../_setup/setup.ts'; +import mdsvex from '../../mdsvex/index.ts'; + +const { test, variants, prepareServer } = setupTest({ mdsvex }); + +test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { mdsvex: {} }); + + // ...add test files + addFixture(cwd, variant); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + expect(await page.$('.mdsvex h1')).toBeTruthy(); + expect(await page.$('.mdsvex h2')).toBeTruthy(); + expect(await page.$('.mdsvex p')).toBeTruthy(); +}); + +const fixture = ` +--- +title: Svex up your markdown +--- + +# { title } + +## Good stuff in your markdown + +Markdown is pretty good but sometimes you just need more. +`; + +function addFixture(cwd: string, variant: string) { + let page; + let svx; + if (variant.startsWith('kit')) { + page = path.resolve(cwd, 'src', 'routes', '+page.svelte'); + svx = path.resolve(cwd, 'src', 'routes', 'Demo.svx'); + } else { + page = path.resolve(cwd, 'src', 'App.svelte'); + svx = path.resolve(cwd, 'src', 'Demo.svx'); + } + + const src = fs.readFileSync(page, 'utf8'); + const { script, template, generateCode } = parseSvelte(src); + imports.addDefault(script.ast, './Demo.svx', 'Demo'); + + const div = html.div({ class: 'mdsvex' }); + html.appendElement(template.ast.childNodes, div); + const mdsvexNode = html.element('Demo'); + html.appendElement(div.childNodes, mdsvexNode); + + const content = generateCode({ + script: script.generateCode(), + template: template.generateCode() + }); + + fs.writeFileSync(page, content, 'utf8'); + fs.writeFileSync(svx, fixture, 'utf8'); +} diff --git a/packages/adders/_tests/paraglide/test.ts b/packages/adders/_tests/paraglide/test.ts new file mode 100644 index 00000000..99c84d16 --- /dev/null +++ b/packages/adders/_tests/paraglide/test.ts @@ -0,0 +1,17 @@ +import { expect } from '@playwright/test'; +import { setupTest } from '../_setup/setup.ts'; +import paraglide from '../../paraglide/index.ts'; + +const { test, variants, prepareServer } = setupTest({ paraglide }); + +const kitOnly = variants.filter((v) => v.includes('kit')); +// TODO: figure out why this is failing +test.todo.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { paraglide: { demo: true, availableLanguageTags: 'en' } }); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + expect(true).toBe(true); +}); diff --git a/packages/adders/_tests/playwright/test.ts b/packages/adders/_tests/playwright/test.ts new file mode 100644 index 00000000..e0cde822 --- /dev/null +++ b/packages/adders/_tests/playwright/test.ts @@ -0,0 +1,15 @@ +import { expect } from '@playwright/test'; +import { setupTest } from '../_setup/setup.ts'; +import playwright from '../../playwright/index.ts'; + +const { test, variants, prepareServer } = setupTest({ playwright }); + +test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { playwright: {} }); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + expect(true).toBe(true); +}); diff --git a/packages/adders/_tests/prettier/test.ts b/packages/adders/_tests/prettier/test.ts new file mode 100644 index 00000000..e33ce87d --- /dev/null +++ b/packages/adders/_tests/prettier/test.ts @@ -0,0 +1,15 @@ +import { expect } from '@playwright/test'; +import { setupTest } from '../_setup/setup.ts'; +import prettier from '../../prettier/index.ts'; + +const { test, variants, prepareServer } = setupTest({ prettier }); + +test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { prettier: {} }); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + expect(true).toBe(true); +}); diff --git a/packages/adders/_tests/tailwindcss/test.ts b/packages/adders/_tests/tailwindcss/test.ts new file mode 100644 index 00000000..a0f9e730 --- /dev/null +++ b/packages/adders/_tests/tailwindcss/test.ts @@ -0,0 +1,57 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { expect } from '@playwright/test'; +import { setupTest } from '../_setup/setup.ts'; +import tailwindcss from '../../tailwindcss/index.ts'; + +const { test, variants, prepareServer } = setupTest({ tailwindcss }); + +const fixture = ` +
+

+
`; + +test.concurrent.for(variants)('none - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { tailwindcss: { plugins: [] } }); + + // ...add test files + addFixture(cwd, variant); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + const el = page.getByTestId('base'); + await expect(el).toHaveCSS('background-color', 'rgb(71, 85, 105)'); + await expect(el).toHaveCSS('border-color', 'rgb(249, 250, 251)'); + await expect(el).toHaveCSS('border-width', '4px'); + await expect(el).toHaveCSS('margin-top', '4px'); +}); + +test.concurrent.for(variants)('typography - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { tailwindcss: { plugins: ['typography'] } }); + + // ...add files + addFixture(cwd, variant); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + const el = page.getByTestId('typography'); + await expect(el).toHaveCSS('font-size', '18px'); + await expect(el).toHaveCSS('line-height', '28px'); + await expect(el).toHaveCSS('text-align', 'right'); + await expect(el).toHaveCSS('text-decoration-line', 'line-through'); +}); + +function addFixture(cwd: string, variant: string) { + let page; + if (variant.startsWith('kit')) { + page = path.resolve(cwd, 'src', 'routes', '+page.svelte'); + } else { + page = path.resolve(cwd, 'src', 'App.svelte'); + } + const content = fs.readFileSync(page, 'utf8') + fixture; + fs.writeFileSync(page, content, 'utf8'); +} diff --git a/packages/adders/_tests/vitest/test.ts b/packages/adders/_tests/vitest/test.ts new file mode 100644 index 00000000..d0b1ed56 --- /dev/null +++ b/packages/adders/_tests/vitest/test.ts @@ -0,0 +1,15 @@ +import { expect } from '@playwright/test'; +import { setupTest } from '../_setup/setup.ts'; +import vitest from '../../vitest-addon/index.ts'; + +const { test, variants, prepareServer } = setupTest({ vitest }); + +test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { vitest: {} }); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + expect(true).toBe(true); +}); diff --git a/packages/adders/package.json b/packages/adders/package.json index 39023993..d366fd1e 100644 --- a/packages/adders/package.json +++ b/packages/adders/package.json @@ -12,5 +12,8 @@ "exports": "./index.ts", "dependencies": { "@sveltejs/cli-core": "workspace:*" + }, + "devDependencies": { + "tinyexec": "^0.3.0" } } diff --git a/packages/adders/vitest.config.ts b/packages/adders/vitest.config.ts new file mode 100644 index 00000000..63ac177c --- /dev/null +++ b/packages/adders/vitest.config.ts @@ -0,0 +1,16 @@ +import { cpus } from 'node:os'; +import { defineConfig } from 'vitest/config'; + +const ONE_MINUTE = 1000 * 60; + +export default defineConfig({ + test: { + include: ['_tests/**/test.{js,ts}'], + exclude: ['_tests/{_setups,_fixtures}/**/*'], + testTimeout: ONE_MINUTE * 2, + hookTimeout: ONE_MINUTE * 3, + maxConcurrency: cpus().length, + pool: 'forks', + globalSetup: ['_tests/_setup/global.ts'] + } +}); From 665ead0b6e39e255f98c85d16c68c659af51821a Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:13:06 -0500 Subject: [PATCH 034/126] ..pin storybook --- packages/adders/storybook/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adders/storybook/index.ts b/packages/adders/storybook/index.ts index 9a76cbef..65de68a2 100644 --- a/packages/adders/storybook/index.ts +++ b/packages/adders/storybook/index.ts @@ -9,7 +9,7 @@ export default defineAdder({ scripts: [ { description: 'applies storybook', - args: ['storybook@latest', 'init', '--skip-install', '--no-dev'], + args: ['storybook@8.3', 'init', '--skip-install', '--no-dev'], stdio: 'inherit' } ], From 6446e597b6fccb501f76095038ba8da117e1d396 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:17:35 -0500 Subject: [PATCH 035/126] fix scripts --- packages/adders/_tests/_setup/global.ts | 2 +- packages/adders/_tests/_setup/setup.ts | 23 +++++++++++++++++++---- packages/cli/lib/install.ts | 2 +- packages/cli/testing.ts | 11 ++++------- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/packages/adders/_tests/_setup/global.ts b/packages/adders/_tests/_setup/global.ts index 5387fb66..42b646d7 100644 --- a/packages/adders/_tests/_setup/global.ts +++ b/packages/adders/_tests/_setup/global.ts @@ -9,7 +9,7 @@ export default async function ({ provide }: GlobalSetupContext) { // global setup (e.g. spin up docker containers) // downloads different project configurations (sveltekit, js/ts, vite-only, etc) - const { templatesDir } = await setup({ cwd: TEST_DIR, variants, clean: true }); + const { templatesDir } = await setup({ cwd: TEST_DIR, variants }); provide('testDir', TEST_DIR); provide('templatesDir', templatesDir); diff --git a/packages/adders/_tests/_setup/setup.ts b/packages/adders/_tests/_setup/setup.ts index f39ee8af..29017363 100644 --- a/packages/adders/_tests/_setup/setup.ts +++ b/packages/adders/_tests/_setup/setup.ts @@ -68,22 +68,37 @@ export function setupTest(addons: Addons) { return { test, variants, prepareServer }; } +type PrepareServerOptions = { + cwd: string; + page: Page; + previewCommand?: string; + buildCommand?: string; + installCommand?: string; +}; // installs dependencies, builds the project, and spins up the preview server async function prepareServer( - { cwd, page }: { cwd: string; page: Page }, + { + cwd, + page, + previewCommand = 'npm run preview', + buildCommand = 'npm run build', + installCommand = 'pnpm install' + }: PrepareServerOptions, afterInstall?: () => Promise | any ) { // install deps - await exec('pnpm', ['i'], { nodeOptions: { cwd } }); + const [installCmd, ...installArgs] = installCommand.split(' '); + await exec(installCmd, installArgs, { nodeOptions: { cwd } }); // ...do commands and any other extra stuff await afterInstall?.(); // build project - await exec('npm', ['run', 'build'], { nodeOptions: { cwd } }); + const [buildCmd, ...buildArgs] = buildCommand.split(' '); + await exec(buildCmd, buildArgs, { nodeOptions: { cwd } }); // start preview server `vite preview` - const { url, close } = await startPreview({ cwd }); + const { url, close } = await startPreview({ cwd, command: previewCommand }); // navigate to the page await page.goto(url); diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index f1bd2a43..7c6e14b8 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -63,7 +63,7 @@ async function runAddon(workspace: Workspace, addon: Addon): Promise void; }> { - const { command, args } = resolveCommand(packageManager, 'run', ['preview'])!; - - const process = spawn(command, args, { stdio: 'pipe', shell: true, cwd, timeout: 120_000 }); + const [cmd, ...args] = command.split(' '); + const process = spawn(cmd, args, { stdio: 'pipe', shell: true, cwd, timeout: 120_000 }); const close = () => { if (!process.pid) return; terminate(process.pid); From 53934db71b18dd159e3f1cbfdfc473d46baf8805 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:18:18 -0500 Subject: [PATCH 036/126] add storybook test --- packages/adders/_tests/storybook/test.ts | 25 +++++++ packages/adders/drizzle/tests.ts | 86 ------------------------ packages/adders/storybook/tests.ts | 21 ------ 3 files changed, 25 insertions(+), 107 deletions(-) create mode 100644 packages/adders/_tests/storybook/test.ts delete mode 100644 packages/adders/drizzle/tests.ts delete mode 100644 packages/adders/storybook/tests.ts diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts new file mode 100644 index 00000000..5fcc6b30 --- /dev/null +++ b/packages/adders/_tests/storybook/test.ts @@ -0,0 +1,25 @@ +import { expect } from '@playwright/test'; +import { setupTest } from '../_setup/setup.ts'; +import storybook from '../../storybook/index.ts'; + +const { test, variants, prepareServer } = setupTest({ storybook }); + +let port = 6006; +test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { storybook: {} }); + + const p = port++; + const { close } = await prepareServer({ + cwd, + page, + previewCommand: `pnpm storybook -p ${p} --ci`, + buildCommand: 'echo' + }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + await page.goto(`http://localhost:${p}`); + + expect(await page.$('main .sb-bar')).toBeTruthy(); + expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); +}); diff --git a/packages/adders/drizzle/tests.ts b/packages/adders/drizzle/tests.ts deleted file mode 100644 index 3257b575..00000000 --- a/packages/adders/drizzle/tests.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { options } from './index.ts'; -import { defineAdderTests } from '@sveltejs/cli-core'; -import { parseSvelte, parseJson } from '@sveltejs/cli-core/parsers'; - -const defaultOptionValues = { - sqlite: options.sqlite.default, - mysql: options.mysql.default, - postgresql: options.postgresql.default, - docker: options.docker.default -}; - -export const tests = defineAdderTests({ - options, - optionValues: [ - { ...defaultOptionValues, database: 'sqlite', sqlite: 'better-sqlite3' }, - { ...defaultOptionValues, database: 'sqlite', sqlite: 'libsql' }, - { ...defaultOptionValues, database: 'mysql', mysql: 'mysql2', docker: true }, - { ...defaultOptionValues, database: 'postgresql', postgresql: 'postgres.js', docker: true } - ], - files: [ - { - name: ({ kit }) => `${kit?.routesDirectory}/+page.svelte`, - condition: ({ kit }) => Boolean(kit), - content: ({ content }) => { - const { script, template, generateCode } = parseSvelte(content); - const dataProp = '\nexport let data;'; - const eachBlock = ` - {#each data.users as user} - {user.id} {user.name} - {/each}`; - return generateCode({ - script: script.source + dataProp, - template: template.source + eachBlock - }); - } - }, - { - name: ({ kit, typescript }) => - `${kit?.routesDirectory}/+page.server.${typescript ? 'ts' : 'js'}`, - condition: ({ kit }) => Boolean(kit), - content: ({ typescript }) => { - return ` - import { db } from '$lib/server/db'; - import { user } from '$lib/server/db/schema.js'; - - export const load = async () => { - await insertUser({ name: 'Foobar', id: 0, age: 20 }).catch((err) => console.error(err)); - - const users = await db.select().from(user); - - return { users }; - }; - - function insertUser(${typescript ? 'value: typeof user.$inferInsert' : 'value'}) { - return db.insert(user).values(value); - } - `; - } - }, - { - // override the config so we can remove strict mode - name: ({ typescript }) => `drizzle.config.${typescript ? 'ts' : 'js'}`, - condition: ({ kit }) => Boolean(kit), - content: ({ content }) => { - return content.replace('strict: true,', ''); - } - }, - { - name: () => 'package.json', - content: ({ content }) => { - const { data, generateCode } = parseJson(content); - // executes after pnpm install - data.scripts['postinstall'] ??= 'pnpm run db:push'; - return generateCode(); - } - } - ], - tests: [ - { - name: 'queries database', - run: async ({ elementExists }) => { - await elementExists('[data-test-id]'); - } - } - ] -}); diff --git a/packages/adders/storybook/tests.ts b/packages/adders/storybook/tests.ts deleted file mode 100644 index 5fb56a32..00000000 --- a/packages/adders/storybook/tests.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { defineAdderTests } from '@sveltejs/cli-core'; - -let port = 6006; - -export const tests = defineAdderTests({ - options: {}, - optionValues: [], - get command() { - return `storybook -p ${port++} --ci`; - }, - files: [], - tests: [ - { - name: 'storybook loaded', - run: async ({ elementExists }) => { - await elementExists('main .sb-bar'); - await elementExists('#storybook-preview-wrapper'); - } - } - ] -}); From d3ef73776911d567d18ea452a34e2b255e439d02 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:19:16 -0500 Subject: [PATCH 037/126] simplify --- packages/adders/_tests/storybook/test.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index 5fcc6b30..819956af 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -8,17 +8,16 @@ let port = 6006; test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { storybook: {} }); - const p = port++; const { close } = await prepareServer({ cwd, page, - previewCommand: `pnpm storybook -p ${p} --ci`, + previewCommand: `pnpm storybook -p ${++port} --ci`, buildCommand: 'echo' }); // kill server process when we're done ctx.onTestFinished(() => close()); - await page.goto(`http://localhost:${p}`); + await page.goto(`http://localhost:${port}`); expect(await page.$('main .sb-bar')).toBeTruthy(); expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); From e398dc20d1ed5163737b89d4153507a43bc974cc Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:20:05 -0500 Subject: [PATCH 038/126] deps --- .gitignore | 2 + package.json | 1 + pnpm-lock.yaml | 152 +++++++++++++++++++++++++++++++++++++++++++++-- rollup.config.js | 7 ++- 4 files changed, 154 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 193b6ac1..7d6f6845 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ vite.config.js.timestamp-* /packages/create-svelte/template/CHANGELOG.md .test-tmp .test-output + +*storybook.log \ No newline at end of file diff --git a/package.json b/package.json index 3678c39b..20fec6d2 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ }, "devDependencies": { "@changesets/cli": "^2.27.9", + "@playwright/test": "^1.48.2", "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-dynamic-import-vars": "^2.1.2", "@rollup/plugin-json": "^6.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1a7619e0..89b9b088 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@changesets/cli': specifier: ^2.27.9 version: 2.27.9 + '@playwright/test': + specifier: ^1.48.2 + version: 1.48.2 '@rollup/plugin-commonjs': specifier: ^26.0.1 version: 26.0.1(rollup@4.21.2) @@ -87,15 +90,25 @@ importers: specifier: workspace:* version: link:../packages/core devDependencies: + '@playwright/test': + specifier: ^1.48.2 + version: 1.48.2 sv: specifier: workspace:* version: link:../packages/cli + vitest: + specifier: ^2.0.5 + version: 2.0.5(@types/node@22.5.4)(@vitest/ui@2.0.5) packages/adders: dependencies: '@sveltejs/cli-core': specifier: workspace:* version: link:../core + devDependencies: + tinyexec: + specifier: ^0.3.0 + version: 0.3.0 packages/ast-tooling: devDependencies: @@ -171,12 +184,18 @@ importers: '@sveltejs/create': specifier: workspace:* version: link:../create + '@types/degit': + specifier: ^2.8.6 + version: 2.8.6 '@types/tar-fs': specifier: ^2.0.4 version: 2.0.4 commander: specifier: ^12.1.0 version: 12.1.0 + degit: + specifier: ^2.8.4 + version: 2.8.4 empathic: specifier: ^1.0.0 version: 1.0.0 @@ -189,6 +208,9 @@ importers: tar-fs: specifier: ^3.0.6 version: 3.0.6 + terminate: + specifier: ^2.8.0 + version: 2.8.0 tinyexec: specifier: ^0.3.0 version: 0.3.0 @@ -582,6 +604,11 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@playwright/test@1.48.2': + resolution: {integrity: sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==} + engines: {node: '>=18'} + hasBin: true + '@polka/url@1.0.0-next.25': resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} @@ -731,6 +758,9 @@ packages: resolution: {integrity: sha512-qhUGGDHcpbY2zpjW3SwqchuW8J/5EzlPFud7xNntHKA7f3a/mx5+g+ruJKFHSAiVZYo30PALt+AyhmPUNKH/Og==} engines: {node: ^14.13.1 || ^16.0.0 || >=18} + '@types/degit@2.8.6': + resolution: {integrity: sha512-y0M7sqzsnHB6cvAeTCBPrCQNQiZe8U4qdzf8uBVmOWYap5MMTN/gB2iEqrIqFiYcsyvP74GnGD5tgsHttielFw==} + '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -988,7 +1018,7 @@ packages: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} concat-map@0.0.1: - resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} @@ -1037,6 +1067,11 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + degit@2.8.4: + resolution: {integrity: sha512-vqYuzmSA5I50J882jd+AbAhQtgK6bdKUJIex1JNfEUPENCgYsxugzKVZlFyMwV4i06MmnV47/Iqi5Io86zf3Ng==} + engines: {node: '>=8.0.0'} + hasBin: true + detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -1070,6 +1105,9 @@ packages: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -1211,6 +1249,9 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + event-stream@3.3.4: + resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -1271,6 +1312,9 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} + from@0.1.7: + resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -1279,6 +1323,11 @@ packages: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1514,6 +1563,9 @@ packages: magic-string@0.30.12: resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + map-stream@0.1.0: + resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -1668,6 +1720,9 @@ packages: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} + pause-stream@0.0.11: + resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + picocolors@1.1.0: resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} @@ -1683,6 +1738,16 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} + playwright-core@1.48.2: + resolution: {integrity: sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.48.2: + resolution: {integrity: sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==} + engines: {node: '>=18'} + hasBin: true + postcss-load-config@3.1.4: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} @@ -1743,6 +1808,11 @@ packages: engines: {node: '>=14'} hasBin: true + ps-tree@1.2.0: + resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} + engines: {node: '>= 0.10'} + hasBin: true + pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} @@ -1883,6 +1953,9 @@ packages: spawndamnit@2.0.0: resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + split@0.3.3: + resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -1892,6 +1965,9 @@ packages: std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + stream-combiner@0.0.4: + resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} + streamx@2.20.1: resolution: {integrity: sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==} @@ -1967,6 +2043,10 @@ packages: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} + terminate@2.8.0: + resolution: {integrity: sha512-bcbjJEg0wY5nuJXvGxxHfmoEPkyHLCctUKO6suwtxy7jVSgGcgPeGwpbLDLELFhIaxCGRr3dPvyNg1yuz2V0eg==} + engines: {node: '>=12'} + text-decoder@1.2.0: resolution: {integrity: sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==} @@ -1980,6 +2060,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + tiny-glob@0.2.9: resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} @@ -2103,8 +2186,8 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite@5.4.3: - resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==} + vite@5.4.10: + resolution: {integrity: sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -2582,6 +2665,10 @@ snapshots: '@pkgr/core@0.1.1': {} + '@playwright/test@1.48.2': + dependencies: + playwright: 1.48.2 + '@polka/url@1.0.0-next.25': {} '@rollup/plugin-commonjs@26.0.1(rollup@4.21.2)': @@ -2702,6 +2789,8 @@ snapshots: transitivePeerDependencies: - encoding + '@types/degit@2.8.6': {} + '@types/estree@1.0.5': {} '@types/gitignore-parser@0.0.3': {} @@ -3013,6 +3102,8 @@ snapshots: deepmerge@4.3.1: {} + degit@2.8.4: {} + detect-indent@6.1.0: {} detect-indent@7.0.1: {} @@ -3043,6 +3134,8 @@ snapshots: dotenv@16.4.5: {} + duplexer@0.1.2: {} + eastasianwidth@0.2.0: {} emoji-regex@8.0.0: {} @@ -3236,6 +3329,16 @@ snapshots: esutils@2.0.3: {} + event-stream@3.3.4: + dependencies: + duplexer: 0.1.2 + from: 0.1.7 + map-stream: 0.1.0 + pause-stream: 0.0.11 + split: 0.3.3 + stream-combiner: 0.0.4 + through: 2.3.8 + execa@8.0.1: dependencies: cross-spawn: 7.0.3 @@ -3308,6 +3411,8 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 + from@0.1.7: {} + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -3320,6 +3425,9 @@ snapshots: jsonfile: 4.0.0 universalify: 0.1.2 + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -3532,6 +3640,8 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + map-stream@0.1.0: {} + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -3662,6 +3772,10 @@ snapshots: pathval@2.0.0: {} + pause-stream@0.0.11: + dependencies: + through: 2.3.8 + picocolors@1.1.0: {} picomatch@2.3.1: {} @@ -3670,6 +3784,14 @@ snapshots: pirates@4.0.6: {} + playwright-core@1.48.2: {} + + playwright@1.48.2: + dependencies: + playwright-core: 1.48.2 + optionalDependencies: + fsevents: 2.3.2 + postcss-load-config@3.1.4(postcss@8.4.45): dependencies: lilconfig: 2.1.0 @@ -3714,6 +3836,10 @@ snapshots: prettier@3.3.3: {} + ps-tree@1.2.0: + dependencies: + event-stream: 3.3.4 + pseudomap@1.0.2: {} pump@3.0.2: @@ -3860,12 +3986,20 @@ snapshots: cross-spawn: 5.1.0 signal-exit: 3.0.7 + split@0.3.3: + dependencies: + through: 2.3.8 + sprintf-js@1.0.3: {} stackback@0.0.2: {} std-env@3.7.0: {} + stream-combiner@0.0.4: + dependencies: + duplexer: 0.1.2 + streamx@2.20.1: dependencies: fast-fifo: 1.3.2 @@ -3965,6 +4099,10 @@ snapshots: term-size@2.2.1: {} + terminate@2.8.0: + dependencies: + ps-tree: 1.2.0 + text-decoder@1.2.0: dependencies: b4a: 1.6.6 @@ -3979,6 +4117,8 @@ snapshots: dependencies: any-promise: 1.3.0 + through@2.3.8: {} + tiny-glob@0.2.9: dependencies: globalyzer: 0.1.0 @@ -4074,7 +4214,7 @@ snapshots: debug: 4.3.7 pathe: 1.1.2 tinyrainbow: 1.2.0 - vite: 5.4.3(@types/node@22.5.4) + vite: 5.4.10(@types/node@22.5.4) transitivePeerDependencies: - '@types/node' - less @@ -4086,7 +4226,7 @@ snapshots: - supports-color - terser - vite@5.4.3(@types/node@22.5.4): + vite@5.4.10(@types/node@22.5.4): dependencies: esbuild: 0.21.5 postcss: 8.4.45 @@ -4113,7 +4253,7 @@ snapshots: tinybench: 2.9.0 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.3(@types/node@22.5.4) + vite: 5.4.10(@types/node@22.5.4) vite-node: 2.0.5(@types/node@22.5.4) why-is-node-running: 2.3.0 optionalDependencies: diff --git a/rollup.config.js b/rollup.config.js index f66a0e6c..74c8158c 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -35,7 +35,7 @@ function getConfig(project) { parsers: `${projectRoot}/tooling/parsers.ts` }; } else if (project === 'cli') { - inputs = [`${projectRoot}/index.ts`, `${projectRoot}/bin.ts`]; + inputs = [`${projectRoot}/index.ts`, `${projectRoot}/testing.ts`, `${projectRoot}/bin.ts`]; } else { inputs = [`${projectRoot}/index.ts`]; } @@ -107,7 +107,10 @@ function getConfig(project) { external, plugins: [ preserveShebangs(), - 'exports' in pkg && dts({ include: project === 'cli' ? [inputs[0]] : undefined }), + 'exports' in pkg && + dts({ + include: project === 'cli' ? [inputs[0], inputs[1], `${projectRoot}/lib/*`] : undefined + }), esbuild(), nodeResolve({ preferBuiltins: true, rootDir: projectRoot }), commonjs(), From 8068dfc922365cca8251daae8124d72cb1afb046 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:19:46 -0500 Subject: [PATCH 039/126] add retries --- packages/adders/_tests/_setup/setup.ts | 8 +++----- packages/adders/vitest.config.ts | 4 +++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/adders/_tests/_setup/setup.ts b/packages/adders/_tests/_setup/setup.ts index 29017363..dc782c5a 100644 --- a/packages/adders/_tests/_setup/setup.ts +++ b/packages/adders/_tests/_setup/setup.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; +import { execSync } from 'node:child_process'; import * as vi from 'vitest'; -import { exec } from 'tinyexec'; import { installAddon, type AddonMap, type OptionMap } from 'sv'; import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/test'; import { chromium, type Browser, type Page } from '@playwright/test'; @@ -87,15 +87,13 @@ async function prepareServer( afterInstall?: () => Promise | any ) { // install deps - const [installCmd, ...installArgs] = installCommand.split(' '); - await exec(installCmd, installArgs, { nodeOptions: { cwd } }); + execSync(installCommand, { cwd, stdio: 'pipe' }); // ...do commands and any other extra stuff await afterInstall?.(); // build project - const [buildCmd, ...buildArgs] = buildCommand.split(' '); - await exec(buildCmd, buildArgs, { nodeOptions: { cwd } }); + execSync(buildCommand, { cwd, stdio: 'pipe' }); // start preview server `vite preview` const { url, close } = await startPreview({ cwd, command: previewCommand }); diff --git a/packages/adders/vitest.config.ts b/packages/adders/vitest.config.ts index 63ac177c..05270bc3 100644 --- a/packages/adders/vitest.config.ts +++ b/packages/adders/vitest.config.ts @@ -1,4 +1,5 @@ import { cpus } from 'node:os'; +import { env } from 'node:process'; import { defineConfig } from 'vitest/config'; const ONE_MINUTE = 1000 * 60; @@ -11,6 +12,7 @@ export default defineConfig({ hookTimeout: ONE_MINUTE * 3, maxConcurrency: cpus().length, pool: 'forks', - globalSetup: ['_tests/_setup/global.ts'] + globalSetup: ['_tests/_setup/global.ts'], + retry: env.CI ? 3 : 0 } }); From 4b2f0369bdb0dab7e5ce459a829f8cb214c26bd9 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 12:10:59 -0500 Subject: [PATCH 040/126] not needed --- packages/adders/_tests/storybook/test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index 819956af..36a733e9 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -17,8 +17,6 @@ test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, . // kill server process when we're done ctx.onTestFinished(() => close()); - await page.goto(`http://localhost:${port}`); - expect(await page.$('main .sb-bar')).toBeTruthy(); expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); }); From 0a0ba1acb6ed6da00672b4b2fb09585269c23481 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 12:18:35 -0500 Subject: [PATCH 041/126] tweak community template --- community-adder-template/src/index.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/community-adder-template/src/index.js b/community-adder-template/src/index.js index 9e4348aa..c063124b 100644 --- a/community-adder-template/src/index.js +++ b/community-adder-template/src/index.js @@ -1,17 +1,17 @@ import { defineAdder, defineAdderOptions } from '@sveltejs/cli-core'; import { imports } from '@sveltejs/cli-core/js'; -import { parseScript } from '@sveltejs/cli-core/parsers'; +import { parseSvelte } from '@sveltejs/cli-core/parsers'; export const options = defineAdderOptions({ - demo: { - question: 'Do you want to use a demo?', - type: 'boolean', - default: false - } + demo: { + question: 'Do you want to use a demo?', + type: 'boolean', + default: false + } }); -export const adder = defineAdder({ - id: 'community-adder-template', +export default defineAdder({ + id: 'community-addon', environments: { kit: true, svelte: true }, options, packages: [], @@ -27,10 +27,11 @@ export const adder = defineAdder({ }, { name: () => 'src/DemoComponent.svelte', - content: ({ content }) => { - const { ast, generateCode } = parseScript(content); - imports.addDefault(ast, '../adder-template-demo.txt?raw', 'Demo'); - return generateCode(); + content: ({ content, options, typescript }) => { + if (!options.demo) return content; + const { script, generateCode } = parseSvelte(content, { typescript }); + imports.addDefault(script.ast, '../adder-template-demo.txt?raw', 'demo'); + return generateCode({ script: script.generateCode(), template: '{demo}' }); } } ] From cd1a56d81769d361e20d32d83b4d81e55486f5f6 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 12:18:43 -0500 Subject: [PATCH 042/126] add fixtures --- community-adder-template/tests/fixtures/+page.svelte | 5 +++++ community-adder-template/tests/fixtures/App.svelte | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 community-adder-template/tests/fixtures/+page.svelte create mode 100644 community-adder-template/tests/fixtures/App.svelte diff --git a/community-adder-template/tests/fixtures/+page.svelte b/community-adder-template/tests/fixtures/+page.svelte new file mode 100644 index 00000000..bd5a70ff --- /dev/null +++ b/community-adder-template/tests/fixtures/+page.svelte @@ -0,0 +1,5 @@ + + +{demo} diff --git a/community-adder-template/tests/fixtures/App.svelte b/community-adder-template/tests/fixtures/App.svelte new file mode 100644 index 00000000..8694a285 --- /dev/null +++ b/community-adder-template/tests/fixtures/App.svelte @@ -0,0 +1,5 @@ + + +{demo} From ed32699a8e9f040dec2d21f412aa0e789b5d1827 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 13:19:30 -0500 Subject: [PATCH 043/126] community template tests --- community-adder-template/package.json | 25 ++-- .../tests/custom-addon.test.ts | 28 +++++ .../tests/setup/global.ts | 29 +++++ community-adder-template/tests/setup/index.ts | 108 ++++++++++++++++++ community-adder-template/tests/tests.js | 16 --- community-adder-template/vitest.config.js | 16 +++ 6 files changed, 195 insertions(+), 27 deletions(-) create mode 100644 community-adder-template/tests/custom-addon.test.ts create mode 100644 community-adder-template/tests/setup/global.ts create mode 100644 community-adder-template/tests/setup/index.ts delete mode 100644 community-adder-template/tests/tests.js create mode 100644 community-adder-template/vitest.config.js diff --git a/community-adder-template/package.json b/community-adder-template/package.json index 557b1e55..f53952ad 100644 --- a/community-adder-template/package.json +++ b/community-adder-template/package.json @@ -2,25 +2,28 @@ "name": "community-adder-template", "private": true, "version": "0.0.0", - "license": "MIT", "type": "module", - "exports": "./src/index.js", - "keywords": [ - "svelte-add-on", - "sv" - ], + "license": "MIT", "scripts": { + "create-temp": "sv create temp --types ts --template minimal --no-add-ons --no-install", "start": "sv add -C temp --community file:../", - "create-temp": "sv create temp --check-types typescript --template skeleton --no-adders --no-install" + "test": "vitest" }, + "files": [ + "src", + "!src/**/*.test.*" + ], + "exports": "./src/index.js", "dependencies": { "@sveltejs/cli-core": "workspace:*" }, "devDependencies": { - "sv": "workspace:*" + "@playwright/test": "^1.48.2", + "sv": "workspace:*", + "vitest": "^2.0.5" }, - "files": [ - "src", - "!src/**/*.test.*" + "keywords": [ + "svelte-add-on", + "sv" ] } diff --git a/community-adder-template/tests/custom-addon.test.ts b/community-adder-template/tests/custom-addon.test.ts new file mode 100644 index 00000000..f18986a6 --- /dev/null +++ b/community-adder-template/tests/custom-addon.test.ts @@ -0,0 +1,28 @@ +import path from 'node:path'; +import { expect } from '@playwright/test'; +import { fixture, setupTest } from './setup/index.js'; +import addon from '../src/index.js'; + +const id = addon.id; +const { test, variants, prepareServer } = setupTest({ [id]: addon }); + +test.concurrent.for(variants)('demo - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { [id]: { demo: true } }); + + // ...add files + if (variant.startsWith('kit')) { + const target = path.resolve(cwd, 'src', 'routes', '+page.svelte'); + fixture({ name: '+page.svelte', target }); + } else { + const target = path.resolve(cwd, 'src', 'App.svelte'); + fixture({ name: 'App.svelte', target }); + } + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(() => close()); + + // expectations + const textContent = await page.getByTestId('demo').textContent(); + expect(textContent).toContain('This is a text file made by the Community Adder Template demo!'); +}); diff --git a/community-adder-template/tests/setup/global.ts b/community-adder-template/tests/setup/global.ts new file mode 100644 index 00000000..0dab6571 --- /dev/null +++ b/community-adder-template/tests/setup/global.ts @@ -0,0 +1,29 @@ +import path from 'node:path'; +import { setup, type ProjectVariant } from 'sv/test'; +import type { GlobalSetupContext } from 'vitest/node'; + +const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; +const TEST_DIR = path.resolve('.test-output'); + +export default async function ({ provide }: GlobalSetupContext) { + // global setup (e.g. spin up docker containers) + + // downloads different project configurations (sveltekit, js/ts, vite-only, etc) + const { templatesDir } = await setup({ cwd: TEST_DIR, variants, clean: true }); + + provide('testDir', TEST_DIR); + provide('templatesDir', templatesDir); + provide('variants', variants); + + return async () => { + // tear down... (e.g. cleanup docker containers) + }; +} + +declare module 'vitest' { + export interface ProvidedContext { + testDir: string; + templatesDir: string; + variants: ProjectVariant[]; + } +} diff --git a/community-adder-template/tests/setup/index.ts b/community-adder-template/tests/setup/index.ts new file mode 100644 index 00000000..ba798198 --- /dev/null +++ b/community-adder-template/tests/setup/index.ts @@ -0,0 +1,108 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { execSync } from 'node:child_process'; +import * as vi from 'vitest'; +import { installAddon, type AddonMap, type OptionMap } from 'sv'; +import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/test'; +import { chromium, type Browser, type Page } from '@playwright/test'; +import { fileURLToPath } from 'node:url'; + +const cwd = vi.inject('testDir'); +const templatesDir = vi.inject('templatesDir'); +const variants = vi.inject('variants'); + +const SETUP_DIR = path.dirname(fileURLToPath(import.meta.url)); + +type Fixtures = { + page: Page; + run(variant: ProjectVariant, options: OptionMap): Promise; +}; + +export function setupTest(addons: Addons) { + let create: CreateProject; + let browser: Browser; + + const test = vi.test.extend>({} as any); + + vi.beforeAll(async () => { + browser = await chromium.launch(); + return async () => { + await browser.close(); + }; + }); + + vi.beforeAll(({ name }) => { + const testName = path.parse(name).name.replace('.test', ''); + + // constructs a builder for create test projects + create = createProject({ cwd, templatesDir, testName }); + + // creates a pnpm workspace in each addon dir + fs.writeFileSync( + path.resolve(cwd, testName, 'pnpm-workspace.yaml'), + `packages:\n - '**/*'`, + 'utf8' + ); + }); + + // runs before each test case + vi.beforeEach>(async (ctx) => { + const browserCtx = await browser.newContext(); + ctx.page = await browserCtx.newPage(); + ctx.run = async (variant, options) => { + const cwd = create({ testId: ctx.task.id, variant }); + + // test metadata + const metaPath = path.resolve(cwd, 'meta.json'); + fs.writeFileSync(metaPath, JSON.stringify({ variant, options }, null, '\t'), 'utf8'); + + // run addon + await installAddon({ cwd, addons, options, packageManager: 'pnpm' }); + + return cwd; + }; + + return async () => { + await browserCtx.close(); + // ...other tear downs + }; + }); + + return { + test, + variants, + prepareServer + }; +} + +/** + * Installs dependencies, builds the project, and spins up the preview server + */ +async function prepareServer({ cwd, page }: { cwd: string; page: Page }) { + // install deps + execSync('pnpm install', { cwd, stdio: 'pipe' }); + + // ...do commands and any other extra stuff + + // build project + execSync('npm run build', { cwd, stdio: 'pipe' }); + + // start preview server `vite preview` + const { url, close } = await startPreview({ cwd }); + + // navigate to the page + await page.goto(url); + + return { url, close }; +} + +/** + * Applies a fixture to the target path + */ +export function fixture({ name, target }: { name: string; target: string }) { + const fixturePath = path.resolve(SETUP_DIR, '..', 'fixtures', name); + if (!fs.existsSync(fixturePath)) { + throw new Error(`Fixture does not exist at: ${fixturePath}`); + } + fs.copyFileSync(fixturePath, target); +} diff --git a/community-adder-template/tests/tests.js b/community-adder-template/tests/tests.js deleted file mode 100644 index 373c556b..00000000 --- a/community-adder-template/tests/tests.js +++ /dev/null @@ -1,16 +0,0 @@ -import { defineAdderTests } from '@sveltejs/cli-core'; -import { options } from '../src/index.js'; - -export const tests = defineAdderTests({ - files: [], - options, - optionValues: [{ demo: true }], - tests: [ - { - name: 'demo test', - run: async ({ elementExists }) => { - await elementExists('.test'); - } - } - ] -}); diff --git a/community-adder-template/vitest.config.js b/community-adder-template/vitest.config.js new file mode 100644 index 00000000..a117d1ca --- /dev/null +++ b/community-adder-template/vitest.config.js @@ -0,0 +1,16 @@ +import { cpus } from 'node:os'; +import { defineConfig } from 'vitest/config'; + +const ONE_MINUTE = 1000 * 60; + +export default defineConfig({ + test: { + include: ['tests/**/*.test.{js,ts}'], + exclude: ['tests/setup/*'], + testTimeout: ONE_MINUTE * 2, + hookTimeout: ONE_MINUTE * 3, + maxConcurrency: cpus().length, + pool: 'forks', + globalSetup: ['tests/setup/global.ts'] + } +}); From d40929afc510d3857d9dbadd9aea88ef50656131 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 13:20:59 -0500 Subject: [PATCH 044/126] naming --- community-adder-template/tests/custom-addon.test.ts | 2 +- community-adder-template/tests/setup/{index.ts => suite.ts} | 0 packages/adders/_tests/_setup/{setup.ts => suite.ts} | 0 packages/adders/_tests/drizzle/test.ts | 2 +- packages/adders/_tests/eslint/test.ts | 2 +- packages/adders/_tests/lucia/test.ts | 2 +- packages/adders/_tests/mdsvex/test.ts | 2 +- packages/adders/_tests/paraglide/test.ts | 2 +- packages/adders/_tests/playwright/test.ts | 2 +- packages/adders/_tests/prettier/test.ts | 2 +- packages/adders/_tests/storybook/test.ts | 2 +- packages/adders/_tests/tailwindcss/test.ts | 2 +- packages/adders/_tests/vitest/test.ts | 2 +- 13 files changed, 11 insertions(+), 11 deletions(-) rename community-adder-template/tests/setup/{index.ts => suite.ts} (100%) rename packages/adders/_tests/_setup/{setup.ts => suite.ts} (100%) diff --git a/community-adder-template/tests/custom-addon.test.ts b/community-adder-template/tests/custom-addon.test.ts index f18986a6..f3c01b74 100644 --- a/community-adder-template/tests/custom-addon.test.ts +++ b/community-adder-template/tests/custom-addon.test.ts @@ -1,6 +1,6 @@ import path from 'node:path'; import { expect } from '@playwright/test'; -import { fixture, setupTest } from './setup/index.js'; +import { fixture, setupTest } from './setup/suite.js'; import addon from '../src/index.js'; const id = addon.id; diff --git a/community-adder-template/tests/setup/index.ts b/community-adder-template/tests/setup/suite.ts similarity index 100% rename from community-adder-template/tests/setup/index.ts rename to community-adder-template/tests/setup/suite.ts diff --git a/packages/adders/_tests/_setup/setup.ts b/packages/adders/_tests/_setup/suite.ts similarity index 100% rename from packages/adders/_tests/_setup/setup.ts rename to packages/adders/_tests/_setup/suite.ts diff --git a/packages/adders/_tests/drizzle/test.ts b/packages/adders/_tests/drizzle/test.ts index 928116d0..48644f7e 100644 --- a/packages/adders/_tests/drizzle/test.ts +++ b/packages/adders/_tests/drizzle/test.ts @@ -4,7 +4,7 @@ import { fileURLToPath } from 'node:url'; import * as vi from 'vitest'; import { expect } from '@playwright/test'; import { exec } from 'tinyexec'; -import { setupTest } from '../_setup/setup.ts'; +import { setupTest } from '../_setup/suite.ts'; import drizzle from '../../drizzle/index.ts'; import { pageServer, pageComp } from './fixtures.ts'; diff --git a/packages/adders/_tests/eslint/test.ts b/packages/adders/_tests/eslint/test.ts index a24a7f96..b4bacd0b 100644 --- a/packages/adders/_tests/eslint/test.ts +++ b/packages/adders/_tests/eslint/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import { setupTest } from '../_setup/setup.ts'; +import { setupTest } from '../_setup/suite.ts'; import eslint from '../../eslint/index.ts'; const { test, variants, prepareServer } = setupTest({ eslint }); diff --git a/packages/adders/_tests/lucia/test.ts b/packages/adders/_tests/lucia/test.ts index 1dc81acc..5b16d12d 100644 --- a/packages/adders/_tests/lucia/test.ts +++ b/packages/adders/_tests/lucia/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import { setupTest } from '../_setup/setup.ts'; +import { setupTest } from '../_setup/suite.ts'; import lucia from '../../lucia/index.ts'; import drizzle from '../../drizzle/index.ts'; diff --git a/packages/adders/_tests/mdsvex/test.ts b/packages/adders/_tests/mdsvex/test.ts index e2d599f8..b4e42d7b 100644 --- a/packages/adders/_tests/mdsvex/test.ts +++ b/packages/adders/_tests/mdsvex/test.ts @@ -4,7 +4,7 @@ import { expect } from '@playwright/test'; import { parseSvelte } from '@sveltejs/cli-core/parsers'; import { imports } from '@sveltejs/cli-core/js'; import * as html from '@sveltejs/cli-core/html'; -import { setupTest } from '../_setup/setup.ts'; +import { setupTest } from '../_setup/suite.ts'; import mdsvex from '../../mdsvex/index.ts'; const { test, variants, prepareServer } = setupTest({ mdsvex }); diff --git a/packages/adders/_tests/paraglide/test.ts b/packages/adders/_tests/paraglide/test.ts index 99c84d16..e5053e7c 100644 --- a/packages/adders/_tests/paraglide/test.ts +++ b/packages/adders/_tests/paraglide/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import { setupTest } from '../_setup/setup.ts'; +import { setupTest } from '../_setup/suite.ts'; import paraglide from '../../paraglide/index.ts'; const { test, variants, prepareServer } = setupTest({ paraglide }); diff --git a/packages/adders/_tests/playwright/test.ts b/packages/adders/_tests/playwright/test.ts index e0cde822..11a0f340 100644 --- a/packages/adders/_tests/playwright/test.ts +++ b/packages/adders/_tests/playwright/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import { setupTest } from '../_setup/setup.ts'; +import { setupTest } from '../_setup/suite.ts'; import playwright from '../../playwright/index.ts'; const { test, variants, prepareServer } = setupTest({ playwright }); diff --git a/packages/adders/_tests/prettier/test.ts b/packages/adders/_tests/prettier/test.ts index e33ce87d..7dde97d2 100644 --- a/packages/adders/_tests/prettier/test.ts +++ b/packages/adders/_tests/prettier/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import { setupTest } from '../_setup/setup.ts'; +import { setupTest } from '../_setup/suite.ts'; import prettier from '../../prettier/index.ts'; const { test, variants, prepareServer } = setupTest({ prettier }); diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index 36a733e9..a2c0bb54 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import { setupTest } from '../_setup/setup.ts'; +import { setupTest } from '../_setup/suite.ts'; import storybook from '../../storybook/index.ts'; const { test, variants, prepareServer } = setupTest({ storybook }); diff --git a/packages/adders/_tests/tailwindcss/test.ts b/packages/adders/_tests/tailwindcss/test.ts index a0f9e730..da0f7717 100644 --- a/packages/adders/_tests/tailwindcss/test.ts +++ b/packages/adders/_tests/tailwindcss/test.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { expect } from '@playwright/test'; -import { setupTest } from '../_setup/setup.ts'; +import { setupTest } from '../_setup/suite.ts'; import tailwindcss from '../../tailwindcss/index.ts'; const { test, variants, prepareServer } = setupTest({ tailwindcss }); diff --git a/packages/adders/_tests/vitest/test.ts b/packages/adders/_tests/vitest/test.ts index d0b1ed56..7707a39d 100644 --- a/packages/adders/_tests/vitest/test.ts +++ b/packages/adders/_tests/vitest/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import { setupTest } from '../_setup/setup.ts'; +import { setupTest } from '../_setup/suite.ts'; import vitest from '../../vitest-addon/index.ts'; const { test, variants, prepareServer } = setupTest({ vitest }); From 36939bb385a8d4d3955b63b58c46bc353aaa6706 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 13:33:13 -0500 Subject: [PATCH 045/126] tweaks --- packages/adders/_tests/mdsvex/fixtures.ts | 11 +++++++++++ packages/adders/_tests/mdsvex/test.ts | 15 ++------------- .../adders/_tests/tailwindcss/fixtures.ts | 19 +++++++++++++++++++ packages/adders/_tests/tailwindcss/test.ts | 19 +------------------ 4 files changed, 33 insertions(+), 31 deletions(-) create mode 100644 packages/adders/_tests/mdsvex/fixtures.ts create mode 100644 packages/adders/_tests/tailwindcss/fixtures.ts diff --git a/packages/adders/_tests/mdsvex/fixtures.ts b/packages/adders/_tests/mdsvex/fixtures.ts new file mode 100644 index 00000000..909f8173 --- /dev/null +++ b/packages/adders/_tests/mdsvex/fixtures.ts @@ -0,0 +1,11 @@ +export const svxFile = ` +--- +title: Svex up your markdown +--- + +# { title } + +## Good stuff in your markdown + +Markdown is pretty good but sometimes you just need more. +`; diff --git a/packages/adders/_tests/mdsvex/test.ts b/packages/adders/_tests/mdsvex/test.ts index b4e42d7b..1d2731f3 100644 --- a/packages/adders/_tests/mdsvex/test.ts +++ b/packages/adders/_tests/mdsvex/test.ts @@ -5,6 +5,7 @@ import { parseSvelte } from '@sveltejs/cli-core/parsers'; import { imports } from '@sveltejs/cli-core/js'; import * as html from '@sveltejs/cli-core/html'; import { setupTest } from '../_setup/suite.ts'; +import { svxFile } from './fixtures.ts'; import mdsvex from '../../mdsvex/index.ts'; const { test, variants, prepareServer } = setupTest({ mdsvex }); @@ -24,18 +25,6 @@ test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => expect(await page.$('.mdsvex p')).toBeTruthy(); }); -const fixture = ` ---- -title: Svex up your markdown ---- - -# { title } - -## Good stuff in your markdown - -Markdown is pretty good but sometimes you just need more. -`; - function addFixture(cwd: string, variant: string) { let page; let svx; @@ -62,5 +51,5 @@ function addFixture(cwd: string, variant: string) { }); fs.writeFileSync(page, content, 'utf8'); - fs.writeFileSync(svx, fixture, 'utf8'); + fs.writeFileSync(svx, svxFile, 'utf8'); } diff --git a/packages/adders/_tests/tailwindcss/fixtures.ts b/packages/adders/_tests/tailwindcss/fixtures.ts new file mode 100644 index 00000000..737a10fc --- /dev/null +++ b/packages/adders/_tests/tailwindcss/fixtures.ts @@ -0,0 +1,19 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +const markup = ` +
+

+
+`; + +export function addFixture(cwd: string, variant: string) { + let page; + if (variant.startsWith('kit')) { + page = path.resolve(cwd, 'src', 'routes', '+page.svelte'); + } else { + page = path.resolve(cwd, 'src', 'App.svelte'); + } + const content = fs.readFileSync(page, 'utf8') + markup; + fs.writeFileSync(page, content, 'utf8'); +} diff --git a/packages/adders/_tests/tailwindcss/test.ts b/packages/adders/_tests/tailwindcss/test.ts index da0f7717..fd90fa0e 100644 --- a/packages/adders/_tests/tailwindcss/test.ts +++ b/packages/adders/_tests/tailwindcss/test.ts @@ -1,16 +1,10 @@ -import fs from 'node:fs'; -import path from 'node:path'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; +import { addFixture } from './fixtures.ts'; import tailwindcss from '../../tailwindcss/index.ts'; const { test, variants, prepareServer } = setupTest({ tailwindcss }); -const fixture = ` -
-

-
`; - test.concurrent.for(variants)('none - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { tailwindcss: { plugins: [] } }); @@ -44,14 +38,3 @@ test.concurrent.for(variants)('typography - %s', async (variant, { page, ...ctx await expect(el).toHaveCSS('text-align', 'right'); await expect(el).toHaveCSS('text-decoration-line', 'line-through'); }); - -function addFixture(cwd: string, variant: string) { - let page; - if (variant.startsWith('kit')) { - page = path.resolve(cwd, 'src', 'routes', '+page.svelte'); - } else { - page = path.resolve(cwd, 'src', 'App.svelte'); - } - const content = fs.readFileSync(page, 'utf8') + fixture; - fs.writeFileSync(page, content, 'utf8'); -} From c1b61be0e8378c42338dcaab3b929e2fc7285f69 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 13:38:36 -0500 Subject: [PATCH 046/126] unneeded --- packages/adders/vitest.config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/adders/vitest.config.ts b/packages/adders/vitest.config.ts index 05270bc3..e48762e7 100644 --- a/packages/adders/vitest.config.ts +++ b/packages/adders/vitest.config.ts @@ -7,7 +7,6 @@ const ONE_MINUTE = 1000 * 60; export default defineConfig({ test: { include: ['_tests/**/test.{js,ts}'], - exclude: ['_tests/{_setups,_fixtures}/**/*'], testTimeout: ONE_MINUTE * 2, hookTimeout: ONE_MINUTE * 3, maxConcurrency: cpus().length, From 7ae9ad9020faaa033be6cc1a0be697025d2c7ed6 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 14:23:09 -0500 Subject: [PATCH 047/126] clean --- packages/adders/_tests/_setup/global.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adders/_tests/_setup/global.ts b/packages/adders/_tests/_setup/global.ts index 42b646d7..5387fb66 100644 --- a/packages/adders/_tests/_setup/global.ts +++ b/packages/adders/_tests/_setup/global.ts @@ -9,7 +9,7 @@ export default async function ({ provide }: GlobalSetupContext) { // global setup (e.g. spin up docker containers) // downloads different project configurations (sveltekit, js/ts, vite-only, etc) - const { templatesDir } = await setup({ cwd: TEST_DIR, variants }); + const { templatesDir } = await setup({ cwd: TEST_DIR, variants, clean: true }); provide('testDir', TEST_DIR); provide('templatesDir', templatesDir); From 6adea4d4cc898f3b2dfbfd1f82947fb8c165ac8f Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:19:52 -0500 Subject: [PATCH 048/126] lockfile trickery --- community-adder-template/tests/setup/suite.ts | 2 +- package.json | 22 +++++++++---------- packages/adders/_tests/_setup/suite.ts | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/community-adder-template/tests/setup/suite.ts b/community-adder-template/tests/setup/suite.ts index ba798198..890ab229 100644 --- a/community-adder-template/tests/setup/suite.ts +++ b/community-adder-template/tests/setup/suite.ts @@ -80,7 +80,7 @@ export function setupTest(addons: Addons) { */ async function prepareServer({ cwd, page }: { cwd: string; page: Page }) { // install deps - execSync('pnpm install', { cwd, stdio: 'pipe' }); + execSync('pnpm install --no-frozen-lockfile', { cwd, stdio: 'pipe' }); // ...do commands and any other extra stuff diff --git a/package.json b/package.json index 20fec6d2..3865e4ee 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,20 @@ { "name": "sv-monorepo", - "version": "0.0.1", - "description": "monorepo for sv and friends", "private": true, + "version": "0.0.1", "type": "module", + "description": "monorepo for sv and friends", + "engines": { + "pnpm": "^9.0.0" + }, "scripts": { + "build": "rollup -c", + "changeset:publish": "changeset publish", "check": "pnpm --parallel check", - "lint": "pnpm --parallel lint && eslint --cache --cache-location node_modules/.eslintcache", - "format": "pnpm --parallel format", "dev": "rollup --config --watch", - "build": "rollup -c", - "test": "pnpm --parallel test", - "changeset:publish": "changeset publish" + "format": "pnpm --parallel format", + "lint": "pnpm --parallel lint && eslint --cache --cache-location node_modules/.eslintcache", + "test": "pnpm --parallel test" }, "devDependencies": { "@changesets/cli": "^2.27.9", @@ -40,8 +43,5 @@ "unplugin-isolated-decl": "^0.6.5", "vitest": "^2.0.5" }, - "packageManager": "pnpm@9.7.0", - "engines": { - "pnpm": "^9.0.0" - } + "packageManager": "pnpm@9.7.0" } diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index dc782c5a..71b2a2a8 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -82,7 +82,7 @@ async function prepareServer( page, previewCommand = 'npm run preview', buildCommand = 'npm run build', - installCommand = 'pnpm install' + installCommand = 'pnpm install --no-frozen-lockfile' }: PrepareServerOptions, afterInstall?: () => Promise | any ) { From 266fea45df31215f0b23c7eef86ffce5f5d5508f Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:25:21 -0500 Subject: [PATCH 049/126] fix eslint test --- packages/adders/_tests/eslint/test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/adders/_tests/eslint/test.ts b/packages/adders/_tests/eslint/test.ts index b4bacd0b..6de35cc6 100644 --- a/packages/adders/_tests/eslint/test.ts +++ b/packages/adders/_tests/eslint/test.ts @@ -4,8 +4,7 @@ import eslint from '../../eslint/index.ts'; const { test, variants, prepareServer } = setupTest({ eslint }); -const kitOnly = variants.filter((v) => v.includes('kit')); -test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { +test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { eslint: {} }); const { close } = await prepareServer({ cwd, page }); From 6a139e257605a6cc8ec68e5bfcde978c122f74d0 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:45:12 -0500 Subject: [PATCH 050/126] fix paraglide --- packages/adders/_tests/paraglide/test.ts | 3 +-- packages/cli/lib/install.ts | 10 +++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/adders/_tests/paraglide/test.ts b/packages/adders/_tests/paraglide/test.ts index e5053e7c..2b72898c 100644 --- a/packages/adders/_tests/paraglide/test.ts +++ b/packages/adders/_tests/paraglide/test.ts @@ -5,8 +5,7 @@ import paraglide from '../../paraglide/index.ts'; const { test, variants, prepareServer } = setupTest({ paraglide }); const kitOnly = variants.filter((v) => v.includes('kit')); -// TODO: figure out why this is failing -test.todo.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { +test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { paraglide: { demo: true, availableLanguageTags: 'en' } }); const { close } = await prepareServer({ cwd, page }); diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 7c6e14b8..d234b364 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -40,22 +40,26 @@ export async function installAddon({ return Array.from(filesToFormat); } -async function runAddon(workspace: Workspace, addon: Addon): Promise { +async function runAddon( + workspace: Workspace, + addon: Adder> +): Promise { const files = new Set(); - // TODO: figure out why this is wrongly typed // apply default adder options - for (const [, question] of Object.entries(addon.options as Record)) { + for (const [, question] of Object.entries(addon.options)) { // we'll only apply defaults to options that don't explicitly fail their conditions if (question.condition?.(workspace.options) !== false) { workspace.options ??= question.default; } } + await addon.preInstall?.(workspace); const pkgPath = installPackages(addon, workspace); files.add(pkgPath); const changedFiles = createOrUpdateFiles(addon.files, workspace); changedFiles.forEach((file) => files.add(file)); + await addon.postInstall?.(workspace); for (const script of addon.scripts ?? []) { if (script.condition?.(workspace) === false) continue; From 0fa007f0e6a51861fe0d6ba425b158c820142676 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:57:30 -0500 Subject: [PATCH 051/126] tweak workflow --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e1fe314d..9c78aee5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,5 +48,6 @@ jobs: node-version: 18 cache: pnpm - run: pnpm install --frozen-lockfile + - run: pnpm exec playwright install chrome - run: pnpm build - run: pnpm test From d417939143ee3f013876faa9032103a4de1caf76 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:01:59 -0500 Subject: [PATCH 052/126] ... --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c78aee5..ec94521b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,6 @@ jobs: node-version: 18 cache: pnpm - run: pnpm install --frozen-lockfile - - run: pnpm exec playwright install chrome + - run: pnpm exec playwright install - run: pnpm build - run: pnpm test From 19e80da876481cedaf1d38ccbec09de0e413f0b6 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:11:21 -0500 Subject: [PATCH 053/126] fix lint --- .github/workflows/ci.yml | 2 +- eslint.config.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec94521b..328d0750 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,6 @@ jobs: node-version: 18 cache: pnpm - run: pnpm install --frozen-lockfile - - run: pnpm exec playwright install + - run: pnpm exec playwright install chromium - run: pnpm build - run: pnpm test diff --git a/eslint.config.js b/eslint.config.js index c6f1bbf0..b3835abe 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -28,10 +28,12 @@ export default [ 'packages/create/scripts/**/*', 'packages/create/templates/**/*', '**/temp/*', - '.test-tmp/**/*', + '.test-tmp/*', + '**/.test-output/*', '**/dist/*', 'packages/**/tests/**/{output,input}.ts', - 'rollup.config.js' + 'rollup.config.js', + 'community-adder-template/*' ] } ]; From b2af1bb78b3ea00fd25ee384eddbebb193fd21d8 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:14:12 -0500 Subject: [PATCH 054/126] fix check --- packages/cli/common.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/common.ts b/packages/cli/common.ts index de39f0a2..3010961b 100644 --- a/packages/cli/common.ts +++ b/packages/cli/common.ts @@ -69,7 +69,7 @@ function formatDescription(arg: Option | Argument): string { type MaybePromise = () => Promise | void; -export async function runCommand(action: MaybePromise) { +export async function runCommand(action: MaybePromise): Promise { try { p.intro(`Welcome to the Svelte CLI! ${pc.gray(`(v${pkg.version})`)}`); await action(); @@ -114,7 +114,7 @@ export async function packageManagerPrompt(cwd: string): Promise { const spinner = p.spinner(); spinner.start('Installing dependencies...'); try { From fa0a992a9f298554327c1d8a30a80af9288c71c8 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 18:59:50 -0500 Subject: [PATCH 055/126] simplify --- community-adder-template/tests/setup/suite.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community-adder-template/tests/setup/suite.ts b/community-adder-template/tests/setup/suite.ts index 890ab229..d8607ec0 100644 --- a/community-adder-template/tests/setup/suite.ts +++ b/community-adder-template/tests/setup/suite.ts @@ -11,7 +11,7 @@ const cwd = vi.inject('testDir'); const templatesDir = vi.inject('templatesDir'); const variants = vi.inject('variants'); -const SETUP_DIR = path.dirname(fileURLToPath(import.meta.url)); +const SETUP_DIR = fileURLToPath(new URL('.', import.meta.url)); type Fixtures = { page: Page; From a9bbe4fe8a92cef8fbc08851451a82d9d80ecae1 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 19:16:45 -0500 Subject: [PATCH 056/126] simplify --- community-adder-template/vitest.config.js | 6 ++---- packages/adders/vitest.config.ts | 6 ++---- packages/core/tsconfig.json | 3 ++- packages/core/vitest.config.ts | 9 ++++++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/community-adder-template/vitest.config.js b/community-adder-template/vitest.config.js index a117d1ca..0dee885f 100644 --- a/community-adder-template/vitest.config.js +++ b/community-adder-template/vitest.config.js @@ -1,4 +1,3 @@ -import { cpus } from 'node:os'; import { defineConfig } from 'vitest/config'; const ONE_MINUTE = 1000 * 60; @@ -7,10 +6,9 @@ export default defineConfig({ test: { include: ['tests/**/*.test.{js,ts}'], exclude: ['tests/setup/*'], - testTimeout: ONE_MINUTE * 2, + testTimeout: ONE_MINUTE * 3, hookTimeout: ONE_MINUTE * 3, - maxConcurrency: cpus().length, - pool: 'forks', + maxConcurrency: 10, globalSetup: ['tests/setup/global.ts'] } }); diff --git a/packages/adders/vitest.config.ts b/packages/adders/vitest.config.ts index e48762e7..8924a20d 100644 --- a/packages/adders/vitest.config.ts +++ b/packages/adders/vitest.config.ts @@ -1,4 +1,3 @@ -import { cpus } from 'node:os'; import { env } from 'node:process'; import { defineConfig } from 'vitest/config'; @@ -7,10 +6,9 @@ const ONE_MINUTE = 1000 * 60; export default defineConfig({ test: { include: ['_tests/**/test.{js,ts}'], - testTimeout: ONE_MINUTE * 2, + testTimeout: ONE_MINUTE * 3, hookTimeout: ONE_MINUTE * 3, - maxConcurrency: cpus().length, - pool: 'forks', + maxConcurrency: 10, globalSetup: ['_tests/_setup/global.ts'], retry: env.CI ? 3 : 0 } diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index a1fcf6c9..9f06a6bc 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -4,5 +4,6 @@ "checkJs": false, "isolatedDeclarations": true, "declaration": true - } + }, + "include": ["index.ts"] } diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts index 5387a327..669f2a8e 100644 --- a/packages/core/vitest.config.ts +++ b/packages/core/vitest.config.ts @@ -1,5 +1,8 @@ -import { defineConfig, type UserConfig } from 'vitest/config'; +import { defineConfig } from 'vitest/config'; export default defineConfig({ - test: { dir: './tests', include: ['./**/index.ts'] } -}) as UserConfig; + test: { + dir: './tests', + include: ['./**/index.ts'] + } +}); From a76f89b891080c53f6dd18e977d3f3cacc8cf9f7 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 19:42:37 -0500 Subject: [PATCH 057/126] upgrade vitest --- community-adder-template/package.json | 2 +- package.json | 4 +- packages/adders/package.json | 2 +- packages/cli/package.json | 2 +- packages/migrate/package.json | 3 +- pnpm-lock.yaml | 887 +++++++++++++++----------- 6 files changed, 514 insertions(+), 386 deletions(-) diff --git a/community-adder-template/package.json b/community-adder-template/package.json index f53952ad..428d0913 100644 --- a/community-adder-template/package.json +++ b/community-adder-template/package.json @@ -20,7 +20,7 @@ "devDependencies": { "@playwright/test": "^1.48.2", "sv": "workspace:*", - "vitest": "^2.0.5" + "vitest": "^2.1.4" }, "keywords": [ "svelte-add-on", diff --git a/package.json b/package.json index 3865e4ee..58bd13dd 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@sveltejs/eslint-config": "^8.1.0", "@svitejs/changesets-changelog-github-compact": "^1.1.0", "@types/node": "^22.3.0", - "@vitest/ui": "^2.0.5", + "@vitest/ui": "^2.1.4", "eslint": "^9.10.0", "magic-string": "^0.30.11", "prettier": "^3.3.3", @@ -41,7 +41,7 @@ "typescript": "^5.6.2", "typescript-eslint": "^8.5.0", "unplugin-isolated-decl": "^0.6.5", - "vitest": "^2.0.5" + "vitest": "^2.1.4" }, "packageManager": "pnpm@9.7.0" } diff --git a/packages/adders/package.json b/packages/adders/package.json index d366fd1e..42394993 100644 --- a/packages/adders/package.json +++ b/packages/adders/package.json @@ -14,6 +14,6 @@ "@sveltejs/cli-core": "workspace:*" }, "devDependencies": { - "tinyexec": "^0.3.0" + "tinyexec": "^0.3.1" } } diff --git a/packages/cli/package.json b/packages/cli/package.json index fbb69af5..32d36dcf 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -43,7 +43,7 @@ "picocolors": "^1.1.0", "tar-fs": "^3.0.6", "terminate": "^2.8.0", - "tinyexec": "^0.3.0", + "tinyexec": "^0.3.1", "valibot": "^0.41.0" }, "keywords": [ diff --git a/packages/migrate/package.json b/packages/migrate/package.json index 83253197..e56d96c9 100644 --- a/packages/migrate/package.json +++ b/packages/migrate/package.json @@ -41,8 +41,7 @@ "@types/node": "^18.19.48", "@types/prompts": "^2.4.9", "@types/semver": "^7.5.6", - "svelte": "^4.2.10", - "vitest": "^2.0.1" + "svelte": "^4.2.10" }, "keywords": [ "migration", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62dc5763..f1a43bd9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,16 +31,16 @@ importers: version: link:packages/create '@sveltejs/eslint-config': specifier: ^8.1.0 - version: 8.1.0(@stylistic/eslint-plugin-js@2.8.0(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.10.2(eslint@9.10.0))(eslint-plugin-svelte@2.43.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.2))(typescript@5.6.2) + version: 8.1.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.13.1(eslint@9.10.0))(eslint-plugin-svelte@2.46.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.3))(typescript@5.6.3) '@svitejs/changesets-changelog-github-compact': specifier: ^1.1.0 version: 1.1.0 '@types/node': specifier: ^22.3.0 - version: 22.5.4 + version: 22.9.0 '@vitest/ui': - specifier: ^2.0.5 - version: 2.0.5(vitest@2.0.5) + specifier: ^2.1.4 + version: 2.1.4(vitest@2.1.4) eslint: specifier: ^9.10.0 version: 9.10.0 @@ -61,7 +61,7 @@ importers: version: 4.21.2 rollup-plugin-esbuild: specifier: ^6.1.1 - version: 6.1.1(esbuild@0.21.5)(rollup@4.21.2) + version: 6.1.1(esbuild@0.24.0)(rollup@4.21.2) rollup-plugin-preserve-shebangs: specifier: ^0.2.0 version: 0.2.0(rollup@4.21.2) @@ -73,16 +73,16 @@ importers: version: 5.0.0 typescript: specifier: ^5.6.2 - version: 5.6.2 + version: 5.6.3 typescript-eslint: specifier: ^8.5.0 - version: 8.5.0(eslint@9.10.0)(typescript@5.6.2) + version: 8.5.0(eslint@9.10.0)(typescript@5.6.3) unplugin-isolated-decl: specifier: ^0.6.5 - version: 0.6.5(rollup@4.21.2)(typescript@5.6.2)(webpack-sources@3.2.3) + version: 0.6.5(rollup@4.21.2)(typescript@5.6.3)(webpack-sources@3.2.3) vitest: - specifier: ^2.0.5 - version: 2.0.5(@types/node@22.5.4)(@vitest/ui@2.0.5) + specifier: ^2.1.4 + version: 2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4) community-adder-template: dependencies: @@ -97,8 +97,8 @@ importers: specifier: workspace:* version: link:../packages/cli vitest: - specifier: ^2.0.5 - version: 2.0.5(@types/node@22.5.4)(@vitest/ui@2.0.5) + specifier: ^2.1.4 + version: 2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4) packages/adders: dependencies: @@ -107,8 +107,8 @@ importers: version: link:../core devDependencies: tinyexec: - specifier: ^0.3.0 - version: 0.3.0 + specifier: ^0.3.1 + version: 0.3.1 packages/ast-tooling: devDependencies: @@ -132,7 +132,7 @@ importers: version: 9.1.0 postcss: specifier: ^8.4.38 - version: 8.4.45 + version: 8.4.47 recast: specifier: ^0.23.7 version: 0.23.9 @@ -147,7 +147,7 @@ importers: devDependencies: picocolors: specifier: ^1.1.0 - version: 1.1.0 + version: 1.1.1 sisteransi: specifier: ^1.0.5 version: 1.0.5 @@ -165,7 +165,7 @@ importers: version: 1.3.0 picocolors: specifier: ^1.1.0 - version: 1.1.0 + version: 1.1.1 sisteransi: specifier: ^1.0.5 version: 1.0.5 @@ -204,7 +204,7 @@ importers: version: 0.2.2 picocolors: specifier: ^1.1.0 - version: 1.1.0 + version: 1.1.1 tar-fs: specifier: ^3.0.6 version: 3.0.6 @@ -212,11 +212,11 @@ importers: specifier: ^2.8.0 version: 2.8.0 tinyexec: - specifier: ^0.3.0 - version: 0.3.0 + specifier: ^0.3.1 + version: 0.3.1 valibot: specifier: ^0.41.0 - version: 0.41.0(typescript@5.6.2) + version: 0.41.0(typescript@5.6.3) packages/core: dependencies: @@ -238,7 +238,7 @@ importers: version: 0.30.12 picocolors: specifier: ^1.1.0 - version: 1.1.0 + version: 1.1.1 packages/create: devDependencies: @@ -280,7 +280,7 @@ importers: version: 24.0.0 typescript: specifier: ^5.3.3 - version: 5.6.2 + version: 5.6.3 zimmerframe: specifier: ^1.1.2 version: 1.1.2 @@ -297,9 +297,6 @@ importers: svelte: specifier: ^4.2.10 version: 4.2.19 - vitest: - specifier: ^2.0.1 - version: 2.0.5(@types/node@18.19.64)(@vitest/ui@2.0.5) packages: @@ -392,146 +389,290 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.24.0': + resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.24.0': + resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.21.5': resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.24.0': + resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.21.5': resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.24.0': + resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.24.0': + resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.21.5': resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.24.0': + resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.24.0': + resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.24.0': + resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.24.0': + resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.21.5': resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.24.0': + resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.21.5': resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.24.0': + resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.21.5': resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.24.0': + resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.21.5': resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.24.0': + resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.21.5': resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.24.0': + resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.21.5': resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.24.0': + resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.21.5': resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.24.0': + resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.21.5': resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.24.0': + resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-x64@0.21.5': resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.24.0': + resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.24.0': + resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.24.0': + resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.24.0': + resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.24.0': + resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.21.5': resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.24.0': + resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.21.5': resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + '@esbuild/win32-x64@0.24.0': + resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.11.0': - resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/config-array@0.18.0': @@ -783,8 +924,8 @@ packages: cpu: [x64] os: [win32] - '@stylistic/eslint-plugin-js@2.8.0': - resolution: {integrity: sha512-/e7pSzVMrwBd6yzSDsKHwax3TS96+pd/xSKzELaTkOuYqUhYfj/becWdfDbFSBGQD7BBBCiiE4L8L2cUfu5h+A==} + '@stylistic/eslint-plugin-js@2.10.1': + resolution: {integrity: sha512-IikL/RKy9Sk2UMDUUpqrEcwDeYzUEt6SaL2/UVCFuVQxKACHSgStT0NxXkxZmBOUforaU52FPf2Su07FYH5s5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.40.0' @@ -822,8 +963,8 @@ packages: '@types/node@18.19.64': resolution: {integrity: sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==} - '@types/node@22.5.4': - resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==} + '@types/node@22.9.0': + resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==} '@types/prompts@2.4.9': resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} @@ -897,28 +1038,39 @@ packages: resolution: {integrity: sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitest/expect@2.0.5': - resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} + '@vitest/expect@2.1.4': + resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} + + '@vitest/mocker@2.1.4': + resolution: {integrity: sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true - '@vitest/pretty-format@2.0.5': - resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} + '@vitest/pretty-format@2.1.4': + resolution: {integrity: sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==} - '@vitest/runner@2.0.5': - resolution: {integrity: sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==} + '@vitest/runner@2.1.4': + resolution: {integrity: sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==} - '@vitest/snapshot@2.0.5': - resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==} + '@vitest/snapshot@2.1.4': + resolution: {integrity: sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==} - '@vitest/spy@2.0.5': - resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} + '@vitest/spy@2.1.4': + resolution: {integrity: sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==} - '@vitest/ui@2.0.5': - resolution: {integrity: sha512-m+ZpVt/PVi/nbeRKEjdiYeoh0aOfI9zr3Ria9LO7V2PlMETtAXJS3uETEZkc8Be2oOl8mhd7Ew+5SRBXRYncNw==} + '@vitest/ui@2.1.4': + resolution: {integrity: sha512-Zd9e5oU063c+j9N9XzGJagCLNvG71x/2tOme3Js4JEZKX55zsgxhJwUgLI8hkN6NjMLpdJO8d7nVUUuPGAA58Q==} peerDependencies: - vitest: 2.0.5 + vitest: 2.1.4 - '@vitest/utils@2.0.5': - resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} + '@vitest/utils@2.1.4': + resolution: {integrity: sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -930,8 +1082,8 @@ packages: peerDependencies: acorn: '>=8.9.0' - acorn@8.12.1: - resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} engines: {node: '>=0.4.0'} hasBin: true @@ -1038,8 +1190,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - chai@5.1.1: - resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} engines: {node: '>=12'} chalk@4.1.2: @@ -1212,6 +1364,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.24.0: + resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} + engines: {node: '>=18'} + hasBin: true + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -1234,18 +1391,18 @@ packages: peerDependencies: eslint: '>=8' - eslint-plugin-n@17.10.2: - resolution: {integrity: sha512-e+s4eAf5NtJaxPhTNu3qMO0Iz40WANS93w9LQgYcvuljgvDmWi/a3rh+OrNyMHeng6aOWGJO0rCg5lH4zi8yTw==} + eslint-plugin-n@17.13.1: + resolution: {integrity: sha512-97qzhk1z3DdSJNCqT45EslwCu5+LB9GDadSyBItgKUfGsXAmN/aa7LRQ0ZxHffUxUzvgbTPJL27/pE9ZQWHy7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.23.0' - eslint-plugin-svelte@2.43.0: - resolution: {integrity: sha512-REkxQWvg2pp7QVLxQNa+dJ97xUqRe7Y2JJbSWkHSuszu0VcblZtXkPBPckkivk99y5CdLw4slqfPylL2d/X4jQ==} + eslint-plugin-svelte@2.46.0: + resolution: {integrity: sha512-1A7iEMkzmCZ9/Iz+EAfOGYL8IoIG6zeKEq1SmpxGeM5SXmoQq+ZNnCpXFVJpsxPWYx8jIVGMerQMzX20cqUl0g==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0-0 || ^9.0.0-0 - svelte: ^3.37.0 || ^4.0.0 || ^5.0.0-next.191 + svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: svelte: optional: true @@ -1262,8 +1419,8 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-visitor-keys@4.0.0: - resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint@9.10.0: @@ -1279,8 +1436,8 @@ packages: esm-env@1.0.0: resolution: {integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==} - espree@10.1.0: - resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} espree@9.6.1: @@ -1320,9 +1477,9 @@ packages: event-stream@3.3.4: resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} @@ -1412,19 +1569,12 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - get-stdin@9.0.0: resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} engines: {node: '>=12'} - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - - get-tsconfig@4.8.0: - resolution: {integrity: sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==} + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} git-hooks-list@3.1.0: resolution: {integrity: sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==} @@ -1449,8 +1599,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.9.0: - resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==} + globals@15.12.0: + resolution: {integrity: sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==} engines: {node: '>=18'} globalyzer@0.1.0: @@ -1487,10 +1637,6 @@ packages: human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -1551,10 +1697,6 @@ packages: is-reference@3.0.2: resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-subdir@1.2.0: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} @@ -1604,8 +1746,8 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} - known-css-properties@0.34.0: - resolution: {integrity: sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==} + known-css-properties@0.35.0: + resolution: {integrity: sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==} levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} @@ -1635,8 +1777,8 @@ packages: lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - loupe@3.1.1: - resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -1656,9 +1798,6 @@ packages: mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1667,10 +1806,6 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -1713,10 +1848,6 @@ packages: encoding: optional: true - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -1724,10 +1855,6 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -1791,10 +1918,6 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -1819,8 +1942,8 @@ packages: periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} - picocolors@1.1.0: - resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -1876,8 +1999,8 @@ packages: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} - postcss@8.4.45: - resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==} + postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -2020,9 +2143,9 @@ packages: silver-fleece@1.2.1: resolution: {integrity: sha512-GwiBh7LzX4aKWb3LH1tPu8et2zZqe1cwXn+/uwIUK+H1Y2k119qpvPelVdRKG/6+RQvtUdRep4mBOOVf80VYDA==} - sirv@2.0.4: - resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} - engines: {node: '>= 10'} + sirv@3.0.0: + resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==} + engines: {node: '>=18'} sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -2095,10 +2218,6 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -2116,11 +2235,11 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte-eslint-parser@0.41.0: - resolution: {integrity: sha512-L6f4hOL+AbgfBIB52Z310pg1d2QjRqm7wy3kI1W6hhdhX5bvu7+f0R6w4ykp5HoDdzq+vGhIJmsisaiJDGmVfA==} + svelte-eslint-parser@0.43.0: + resolution: {integrity: sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: - svelte: ^3.37.0 || ^4.0.0 || ^5.0.0-next.191 + svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: svelte: optional: true @@ -2180,8 +2299,8 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@0.3.0: - resolution: {integrity: sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==} + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} tinyglobby@0.2.10: resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} @@ -2246,8 +2365,8 @@ packages: typescript: optional: true - typescript@5.6.2: - resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==} + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true @@ -2299,8 +2418,8 @@ packages: typescript: optional: true - vite-node@2.0.5: - resolution: {integrity: sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==} + vite-node@2.1.4: + resolution: {integrity: sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -2335,15 +2454,15 @@ packages: terser: optional: true - vitest@2.0.5: - resolution: {integrity: sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==} + vitest@2.1.4: + resolution: {integrity: sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.0.5 - '@vitest/ui': 2.0.5 + '@vitest/browser': 2.1.4 + '@vitest/ui': 2.1.4 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -2495,7 +2614,7 @@ snapshots: mri: 1.2.0 p-limit: 2.3.0 package-manager-detector: 0.2.2 - picocolors: 1.1.0 + picocolors: 1.1.1 resolve-from: 5.0.0 semver: 7.6.3 spawndamnit: 2.0.0 @@ -2519,7 +2638,7 @@ snapshots: dependencies: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 - picocolors: 1.1.0 + picocolors: 1.1.1 semver: 7.6.3 '@changesets/get-github-info@0.5.2': @@ -2550,7 +2669,7 @@ snapshots: '@changesets/logger@0.1.1': dependencies: - picocolors: 1.1.0 + picocolors: 1.1.1 '@changesets/parse@0.4.0': dependencies: @@ -2572,7 +2691,7 @@ snapshots: '@changesets/types': 6.0.0 fs-extra: 7.0.1 p-filter: 2.1.0 - picocolors: 1.1.0 + picocolors: 1.1.1 '@changesets/should-skip-package@0.1.1': dependencies: @@ -2593,78 +2712,150 @@ snapshots: '@esbuild/aix-ppc64@0.21.5': optional: true + '@esbuild/aix-ppc64@0.24.0': + optional: true + '@esbuild/android-arm64@0.21.5': optional: true + '@esbuild/android-arm64@0.24.0': + optional: true + '@esbuild/android-arm@0.21.5': optional: true + '@esbuild/android-arm@0.24.0': + optional: true + '@esbuild/android-x64@0.21.5': optional: true + '@esbuild/android-x64@0.24.0': + optional: true + '@esbuild/darwin-arm64@0.21.5': optional: true + '@esbuild/darwin-arm64@0.24.0': + optional: true + '@esbuild/darwin-x64@0.21.5': optional: true + '@esbuild/darwin-x64@0.24.0': + optional: true + '@esbuild/freebsd-arm64@0.21.5': optional: true + '@esbuild/freebsd-arm64@0.24.0': + optional: true + '@esbuild/freebsd-x64@0.21.5': optional: true + '@esbuild/freebsd-x64@0.24.0': + optional: true + '@esbuild/linux-arm64@0.21.5': optional: true + '@esbuild/linux-arm64@0.24.0': + optional: true + '@esbuild/linux-arm@0.21.5': optional: true + '@esbuild/linux-arm@0.24.0': + optional: true + '@esbuild/linux-ia32@0.21.5': optional: true + '@esbuild/linux-ia32@0.24.0': + optional: true + '@esbuild/linux-loong64@0.21.5': optional: true + '@esbuild/linux-loong64@0.24.0': + optional: true + '@esbuild/linux-mips64el@0.21.5': optional: true + '@esbuild/linux-mips64el@0.24.0': + optional: true + '@esbuild/linux-ppc64@0.21.5': optional: true + '@esbuild/linux-ppc64@0.24.0': + optional: true + '@esbuild/linux-riscv64@0.21.5': optional: true + '@esbuild/linux-riscv64@0.24.0': + optional: true + '@esbuild/linux-s390x@0.21.5': optional: true + '@esbuild/linux-s390x@0.24.0': + optional: true + '@esbuild/linux-x64@0.21.5': optional: true + '@esbuild/linux-x64@0.24.0': + optional: true + '@esbuild/netbsd-x64@0.21.5': optional: true + '@esbuild/netbsd-x64@0.24.0': + optional: true + + '@esbuild/openbsd-arm64@0.24.0': + optional: true + '@esbuild/openbsd-x64@0.21.5': optional: true + '@esbuild/openbsd-x64@0.24.0': + optional: true + '@esbuild/sunos-x64@0.21.5': optional: true + '@esbuild/sunos-x64@0.24.0': + optional: true + '@esbuild/win32-arm64@0.21.5': optional: true + '@esbuild/win32-arm64@0.24.0': + optional: true + '@esbuild/win32-ia32@0.21.5': optional: true + '@esbuild/win32-ia32@0.24.0': + optional: true + '@esbuild/win32-x64@0.21.5': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.10.0)': + '@esbuild/win32-x64@0.24.0': + optional: true + + '@eslint-community/eslint-utils@4.4.1(eslint@9.10.0)': dependencies: eslint: 9.10.0 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.11.0': {} + '@eslint-community/regexpp@4.12.1': {} '@eslint/config-array@0.18.0': dependencies: @@ -2678,7 +2869,7 @@ snapshots: dependencies: ajv: 6.12.6 debug: 4.3.7 - espree: 10.1.0 + espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.0 @@ -2883,22 +3074,22 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.21.2': optional: true - '@stylistic/eslint-plugin-js@2.8.0(eslint@9.10.0)': + '@stylistic/eslint-plugin-js@2.10.1(eslint@9.10.0)': dependencies: eslint: 9.10.0 - eslint-visitor-keys: 4.0.0 - espree: 10.1.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 - '@sveltejs/eslint-config@8.1.0(@stylistic/eslint-plugin-js@2.8.0(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.10.2(eslint@9.10.0))(eslint-plugin-svelte@2.43.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.2))(typescript@5.6.2)': + '@sveltejs/eslint-config@8.1.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.13.1(eslint@9.10.0))(eslint-plugin-svelte@2.46.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.3))(typescript@5.6.3)': dependencies: - '@stylistic/eslint-plugin-js': 2.8.0(eslint@9.10.0) + '@stylistic/eslint-plugin-js': 2.10.1(eslint@9.10.0) eslint: 9.10.0 eslint-config-prettier: 9.1.0(eslint@9.10.0) - eslint-plugin-n: 17.10.2(eslint@9.10.0) - eslint-plugin-svelte: 2.43.0(eslint@9.10.0)(svelte@5.0.0) - globals: 15.9.0 - typescript: 5.6.2 - typescript-eslint: 8.5.0(eslint@9.10.0)(typescript@5.6.2) + eslint-plugin-n: 17.13.1(eslint@9.10.0) + eslint-plugin-svelte: 2.46.0(eslint@9.10.0)(svelte@5.0.0) + globals: 15.12.0 + typescript: 5.6.3 + typescript-eslint: 8.5.0(eslint@9.10.0)(typescript@5.6.3) '@svitejs/changesets-changelog-github-compact@1.1.0': dependencies: @@ -2925,13 +3116,13 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/node@22.5.4': + '@types/node@22.9.0': dependencies: undici-types: 6.19.8 '@types/prompts@2.4.9': dependencies: - '@types/node': 22.5.4 + '@types/node': 22.9.0 kleur: 3.0.3 '@types/resolve@1.20.2': {} @@ -2940,41 +3131,41 @@ snapshots: '@types/tar-fs@2.0.4': dependencies: - '@types/node': 22.5.4 + '@types/node': 22.9.0 '@types/tar-stream': 3.1.3 '@types/tar-stream@3.1.3': dependencies: - '@types/node': 22.5.4 + '@types/node': 22.9.0 - '@typescript-eslint/eslint-plugin@8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.2))(eslint@9.10.0)(typescript@5.6.2)': + '@typescript-eslint/eslint-plugin@8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.3))(eslint@9.10.0)(typescript@5.6.3)': dependencies: - '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.2) + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.3) '@typescript-eslint/scope-manager': 8.5.0 - '@typescript-eslint/type-utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2) - '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/type-utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3) '@typescript-eslint/visitor-keys': 8.5.0 eslint: 9.10.0 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.6.2) + ts-api-utils: 1.3.0(typescript@5.6.3) optionalDependencies: - typescript: 5.6.2 + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.2)': + '@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.3)': dependencies: '@typescript-eslint/scope-manager': 8.5.0 '@typescript-eslint/types': 8.5.0 - '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2) + '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.3) '@typescript-eslint/visitor-keys': 8.5.0 debug: 4.3.7 eslint: 9.10.0 optionalDependencies: - typescript: 5.6.2 + typescript: 5.6.3 transitivePeerDependencies: - supports-color @@ -2983,21 +3174,21 @@ snapshots: '@typescript-eslint/types': 8.5.0 '@typescript-eslint/visitor-keys': 8.5.0 - '@typescript-eslint/type-utils@8.5.0(eslint@9.10.0)(typescript@5.6.2)': + '@typescript-eslint/type-utils@8.5.0(eslint@9.10.0)(typescript@5.6.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2) - '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.3) + '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3) debug: 4.3.7 - ts-api-utils: 1.3.0(typescript@5.6.2) + ts-api-utils: 1.3.0(typescript@5.6.3) optionalDependencies: - typescript: 5.6.2 + typescript: 5.6.3 transitivePeerDependencies: - eslint - supports-color '@typescript-eslint/types@8.5.0': {} - '@typescript-eslint/typescript-estree@8.5.0(typescript@5.6.2)': + '@typescript-eslint/typescript-estree@8.5.0(typescript@5.6.3)': dependencies: '@typescript-eslint/types': 8.5.0 '@typescript-eslint/visitor-keys': 8.5.0 @@ -3006,18 +3197,18 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.6.2) + ts-api-utils: 1.3.0(typescript@5.6.3) optionalDependencies: - typescript: 5.6.2 + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.5.0(eslint@9.10.0)(typescript@5.6.2)': + '@typescript-eslint/utils@8.5.0(eslint@9.10.0)(typescript@5.6.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0) '@typescript-eslint/scope-manager': 8.5.0 '@typescript-eslint/types': 8.5.0 - '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2) + '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.3) eslint: 9.10.0 transitivePeerDependencies: - supports-color @@ -3028,59 +3219,66 @@ snapshots: '@typescript-eslint/types': 8.5.0 eslint-visitor-keys: 3.4.3 - '@vitest/expect@2.0.5': + '@vitest/expect@2.1.4': dependencies: - '@vitest/spy': 2.0.5 - '@vitest/utils': 2.0.5 - chai: 5.1.1 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/pretty-format@2.0.5': + '@vitest/mocker@2.1.4(vite@5.4.10(@types/node@22.9.0))': + dependencies: + '@vitest/spy': 2.1.4 + estree-walker: 3.0.3 + magic-string: 0.30.12 + optionalDependencies: + vite: 5.4.10(@types/node@22.9.0) + + '@vitest/pretty-format@2.1.4': dependencies: tinyrainbow: 1.2.0 - '@vitest/runner@2.0.5': + '@vitest/runner@2.1.4': dependencies: - '@vitest/utils': 2.0.5 + '@vitest/utils': 2.1.4 pathe: 1.1.2 - '@vitest/snapshot@2.0.5': + '@vitest/snapshot@2.1.4': dependencies: - '@vitest/pretty-format': 2.0.5 + '@vitest/pretty-format': 2.1.4 magic-string: 0.30.12 pathe: 1.1.2 - '@vitest/spy@2.0.5': + '@vitest/spy@2.1.4': dependencies: tinyspy: 3.0.2 - '@vitest/ui@2.0.5(vitest@2.0.5)': + '@vitest/ui@2.1.4(vitest@2.1.4)': dependencies: - '@vitest/utils': 2.0.5 - fast-glob: 3.3.2 + '@vitest/utils': 2.1.4 fflate: 0.8.2 flatted: 3.3.1 pathe: 1.1.2 - sirv: 2.0.4 + sirv: 3.0.0 + tinyglobby: 0.2.10 tinyrainbow: 1.2.0 - vitest: 2.0.5(@types/node@22.5.4)(@vitest/ui@2.0.5) + vitest: 2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4) - '@vitest/utils@2.0.5': + '@vitest/utils@2.1.4': dependencies: - '@vitest/pretty-format': 2.0.5 - estree-walker: 3.0.3 - loupe: 3.1.1 + '@vitest/pretty-format': 2.1.4 + loupe: 3.1.2 tinyrainbow: 1.2.0 - acorn-jsx@5.3.2(acorn@8.12.1): + acorn-jsx@5.3.2(acorn@8.14.0): dependencies: - acorn: 8.12.1 + acorn: 8.14.0 - acorn-typescript@1.4.13(acorn@8.12.1): + acorn-typescript@1.4.13(acorn@8.14.0): dependencies: - acorn: 8.12.1 + acorn: 8.14.0 - acorn@8.12.1: {} + acorn@8.14.0: {} ajv@6.12.6: dependencies: @@ -3174,12 +3372,12 @@ snapshots: callsites@3.1.0: {} - chai@5.1.1: + chai@5.1.2: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.1 + loupe: 3.1.2 pathval: 2.0.0 chalk@4.1.2: @@ -3199,7 +3397,7 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 '@types/estree': 1.0.5 - acorn: 8.12.1 + acorn: 8.14.0 estree-walker: 3.0.3 periscopic: 3.1.0 @@ -3338,6 +3536,33 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 + esbuild@0.24.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.0 + '@esbuild/android-arm': 0.24.0 + '@esbuild/android-arm64': 0.24.0 + '@esbuild/android-x64': 0.24.0 + '@esbuild/darwin-arm64': 0.24.0 + '@esbuild/darwin-x64': 0.24.0 + '@esbuild/freebsd-arm64': 0.24.0 + '@esbuild/freebsd-x64': 0.24.0 + '@esbuild/linux-arm': 0.24.0 + '@esbuild/linux-arm64': 0.24.0 + '@esbuild/linux-ia32': 0.24.0 + '@esbuild/linux-loong64': 0.24.0 + '@esbuild/linux-mips64el': 0.24.0 + '@esbuild/linux-ppc64': 0.24.0 + '@esbuild/linux-riscv64': 0.24.0 + '@esbuild/linux-s390x': 0.24.0 + '@esbuild/linux-x64': 0.24.0 + '@esbuild/netbsd-x64': 0.24.0 + '@esbuild/openbsd-arm64': 0.24.0 + '@esbuild/openbsd-x64': 0.24.0 + '@esbuild/sunos-x64': 0.24.0 + '@esbuild/win32-arm64': 0.24.0 + '@esbuild/win32-ia32': 0.24.0 + '@esbuild/win32-x64': 0.24.0 + escape-string-regexp@4.0.0: {} eslint-compat-utils@0.5.1(eslint@9.10.0): @@ -3351,37 +3576,37 @@ snapshots: eslint-plugin-es-x@7.8.0(eslint@9.10.0): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) - '@eslint-community/regexpp': 4.11.0 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0) + '@eslint-community/regexpp': 4.12.1 eslint: 9.10.0 eslint-compat-utils: 0.5.1(eslint@9.10.0) - eslint-plugin-n@17.10.2(eslint@9.10.0): + eslint-plugin-n@17.13.1(eslint@9.10.0): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0) enhanced-resolve: 5.17.1 eslint: 9.10.0 eslint-plugin-es-x: 7.8.0(eslint@9.10.0) - get-tsconfig: 4.8.0 - globals: 15.9.0 + get-tsconfig: 4.8.1 + globals: 15.12.0 ignore: 5.3.2 minimatch: 9.0.5 semver: 7.6.3 - eslint-plugin-svelte@2.43.0(eslint@9.10.0)(svelte@5.0.0): + eslint-plugin-svelte@2.46.0(eslint@9.10.0)(svelte@5.0.0): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0) '@jridgewell/sourcemap-codec': 1.5.0 eslint: 9.10.0 eslint-compat-utils: 0.5.1(eslint@9.10.0) esutils: 2.0.3 - known-css-properties: 0.34.0 - postcss: 8.4.45 - postcss-load-config: 3.1.4(postcss@8.4.45) - postcss-safe-parser: 6.0.0(postcss@8.4.45) + known-css-properties: 0.35.0 + postcss: 8.4.47 + postcss-load-config: 3.1.4(postcss@8.4.47) + postcss-safe-parser: 6.0.0(postcss@8.4.47) postcss-selector-parser: 6.1.2 semver: 7.6.3 - svelte-eslint-parser: 0.41.0(svelte@5.0.0) + svelte-eslint-parser: 0.43.0(svelte@5.0.0) optionalDependencies: svelte: 5.0.0 transitivePeerDependencies: @@ -3399,12 +3624,12 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint-visitor-keys@4.0.0: {} + eslint-visitor-keys@4.2.0: {} eslint@9.10.0: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) - '@eslint-community/regexpp': 4.11.0 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0) + '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.18.0 '@eslint/eslintrc': 3.1.0 '@eslint/js': 9.10.0 @@ -3418,8 +3643,8 @@ snapshots: debug: 4.3.7 escape-string-regexp: 4.0.0 eslint-scope: 8.0.2 - eslint-visitor-keys: 4.0.0 - espree: 10.1.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -3442,16 +3667,16 @@ snapshots: esm-env@1.0.0: {} - espree@10.1.0: + espree@10.3.0: dependencies: - acorn: 8.12.1 - acorn-jsx: 5.3.2(acorn@8.12.1) - eslint-visitor-keys: 4.0.0 + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 espree@9.6.1: dependencies: - acorn: 8.12.1 - acorn-jsx: 5.3.2(acorn@8.12.1) + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} @@ -3489,17 +3714,7 @@ snapshots: stream-combiner: 0.0.4 through: 2.3.8 - execa@8.0.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 + expect-type@1.1.0: {} extendable-error@0.1.7: {} @@ -3587,13 +3802,9 @@ snapshots: function-bind@1.1.2: {} - get-func-name@2.0.2: {} - get-stdin@9.0.0: {} - get-stream@8.0.1: {} - - get-tsconfig@4.8.0: + get-tsconfig@4.8.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -3620,7 +3831,7 @@ snapshots: globals@14.0.0: {} - globals@15.9.0: {} + globals@15.12.0: {} globalyzer@0.1.0: {} @@ -3662,8 +3873,6 @@ snapshots: human-id@1.0.2: {} - human-signals@5.0.0: {} - iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -3711,8 +3920,6 @@ snapshots: dependencies: '@types/estree': 1.0.5 - is-stream@3.0.0: {} - is-subdir@1.2.0: dependencies: better-path-resolve: 1.0.0 @@ -3756,7 +3963,7 @@ snapshots: kleur@4.1.5: {} - known-css-properties@0.34.0: {} + known-css-properties@0.35.0: {} levn@0.4.1: dependencies: @@ -3781,9 +3988,7 @@ snapshots: lodash.startcase@4.4.0: {} - loupe@3.1.1: - dependencies: - get-func-name: 2.0.2 + loupe@3.1.2: {} lru-cache@10.4.3: {} @@ -3804,8 +4009,6 @@ snapshots: mdn-data@2.0.30: {} - merge-stream@2.0.0: {} - merge2@1.4.1: {} micromatch@4.0.8: @@ -3813,8 +4016,6 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 - mimic-fn@4.0.0: {} - minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -3845,20 +4046,12 @@ snapshots: dependencies: whatwg-url: 5.0.0 - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - object-assign@4.1.1: {} once@1.4.0: dependencies: wrappy: 1.0.2 - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -3921,8 +4114,6 @@ snapshots: path-key@3.1.1: {} - path-key@4.0.0: {} - path-parse@1.0.7: {} path-scurry@1.11.1: @@ -3946,7 +4137,7 @@ snapshots: estree-walker: 3.0.3 is-reference: 3.0.2 - picocolors@1.1.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -3964,30 +4155,30 @@ snapshots: optionalDependencies: fsevents: 2.3.2 - postcss-load-config@3.1.4(postcss@8.4.45): + postcss-load-config@3.1.4(postcss@8.4.47): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: - postcss: 8.4.45 + postcss: 8.4.47 - postcss-safe-parser@6.0.0(postcss@8.4.45): + postcss-safe-parser@6.0.0(postcss@8.4.47): dependencies: - postcss: 8.4.45 + postcss: 8.4.47 - postcss-scss@4.0.9(postcss@8.4.45): + postcss-scss@4.0.9(postcss@8.4.47): dependencies: - postcss: 8.4.45 + postcss: 8.4.47 postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss@8.4.45: + postcss@8.4.47: dependencies: nanoid: 3.3.7 - picocolors: 1.1.0 + picocolors: 1.1.1 source-map-js: 1.2.1 prelude-ls@1.2.1: {} @@ -4061,13 +4252,13 @@ snapshots: reusify@1.0.4: {} - rollup-plugin-esbuild@6.1.1(esbuild@0.21.5)(rollup@4.21.2): + rollup-plugin-esbuild@6.1.1(esbuild@0.24.0)(rollup@4.21.2): dependencies: '@rollup/pluginutils': 5.1.2(rollup@4.21.2) debug: 4.3.7 es-module-lexer: 1.5.4 - esbuild: 0.21.5 - get-tsconfig: 4.8.0 + esbuild: 0.24.0 + get-tsconfig: 4.8.1 rollup: 4.21.2 transitivePeerDependencies: - supports-color @@ -4127,7 +4318,7 @@ snapshots: silver-fleece@1.2.1: {} - sirv@2.0.4: + sirv@3.0.0: dependencies: '@polka/url': 1.0.0-next.25 mrmime: 2.0.0 @@ -4207,8 +4398,6 @@ snapshots: strip-bom@3.0.0: {} - strip-final-newline@3.0.0: {} - strip-json-comments@3.1.1: {} sucrase@3.35.0: @@ -4227,13 +4416,13 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-eslint-parser@0.41.0(svelte@5.0.0): + svelte-eslint-parser@0.43.0(svelte@5.0.0): dependencies: eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - postcss: 8.4.45 - postcss-scss: 4.0.9(postcss@8.4.45) + postcss: 8.4.47 + postcss-scss: 4.0.9(postcss@8.4.47) optionalDependencies: svelte: 5.0.0 @@ -4243,7 +4432,7 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 '@types/estree': 1.0.5 - acorn: 8.12.1 + acorn: 8.14.0 aria-query: 5.3.2 axobject-query: 4.1.0 code-red: 1.0.4 @@ -4259,8 +4448,8 @@ snapshots: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 '@types/estree': 1.0.5 - acorn: 8.12.1 - acorn-typescript: 1.4.13(acorn@8.12.1) + acorn: 8.14.0 + acorn-typescript: 1.4.13(acorn@8.14.0) aria-query: 5.3.2 axobject-query: 4.1.0 esm-env: 1.0.0 @@ -4322,7 +4511,7 @@ snapshots: tinybench@2.9.0: {} - tinyexec@0.3.0: {} + tinyexec@0.3.1: {} tinyglobby@0.2.10: dependencies: @@ -4349,9 +4538,9 @@ snapshots: tr46@0.0.3: {} - ts-api-utils@1.3.0(typescript@5.6.2): + ts-api-utils@1.3.0(typescript@5.6.3): dependencies: - typescript: 5.6.2 + typescript: 5.6.3 ts-interface-checker@0.1.13: {} @@ -4366,18 +4555,18 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.2): + typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.2))(eslint@9.10.0)(typescript@5.6.2) - '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.2) - '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/eslint-plugin': 8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.3))(eslint@9.10.0)(typescript@5.6.3) + '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3) optionalDependencies: - typescript: 5.6.2 + typescript: 5.6.3 transitivePeerDependencies: - eslint - supports-color - typescript@5.6.2: {} + typescript@5.6.3: {} undici-types@5.26.5: {} @@ -4385,21 +4574,21 @@ snapshots: universalify@0.1.2: {} - unplugin-isolated-decl@0.6.5(rollup@4.21.2)(typescript@5.6.2)(webpack-sources@3.2.3): + unplugin-isolated-decl@0.6.5(rollup@4.21.2)(typescript@5.6.3)(webpack-sources@3.2.3): dependencies: '@rollup/pluginutils': 5.1.2(rollup@4.21.2) magic-string: 0.30.12 oxc-parser: 0.30.3 unplugin: 1.14.1(webpack-sources@3.2.3) optionalDependencies: - typescript: 5.6.2 + typescript: 5.6.3 transitivePeerDependencies: - rollup - webpack-sources unplugin@1.14.1(webpack-sources@3.2.3): dependencies: - acorn: 8.12.1 + acorn: 8.14.0 webpack-virtual-modules: 0.6.2 optionalDependencies: webpack-sources: 3.2.3 @@ -4410,35 +4599,16 @@ snapshots: util-deprecate@1.0.2: {} - valibot@0.41.0(typescript@5.6.2): + valibot@0.41.0(typescript@5.6.3): optionalDependencies: - typescript: 5.6.2 - - vite-node@2.0.5(@types/node@18.19.64): - dependencies: - cac: 6.7.14 - debug: 4.3.7 - pathe: 1.1.2 - tinyrainbow: 1.2.0 - vite: 5.4.10(@types/node@18.19.64) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser + typescript: 5.6.3 - vite-node@2.0.5(@types/node@22.5.4): + vite-node@2.1.4(@types/node@22.9.0): dependencies: cac: 6.7.14 debug: 4.3.7 pathe: 1.1.2 - tinyrainbow: 1.2.0 - vite: 5.4.10(@types/node@22.5.4) + vite: 5.4.10(@types/node@22.9.0) transitivePeerDependencies: - '@types/node' - less @@ -4450,85 +4620,44 @@ snapshots: - supports-color - terser - vite@5.4.10(@types/node@18.19.64): - dependencies: - esbuild: 0.21.5 - postcss: 8.4.45 - rollup: 4.21.2 - optionalDependencies: - '@types/node': 18.19.64 - fsevents: 2.3.3 - - vite@5.4.10(@types/node@22.5.4): + vite@5.4.10(@types/node@22.9.0): dependencies: esbuild: 0.21.5 - postcss: 8.4.45 + postcss: 8.4.47 rollup: 4.21.2 optionalDependencies: - '@types/node': 22.5.4 + '@types/node': 22.9.0 fsevents: 2.3.3 - vitest@2.0.5(@types/node@18.19.64)(@vitest/ui@2.0.5): + vitest@2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4): dependencies: - '@ampproject/remapping': 2.3.0 - '@vitest/expect': 2.0.5 - '@vitest/pretty-format': 2.0.5 - '@vitest/runner': 2.0.5 - '@vitest/snapshot': 2.0.5 - '@vitest/spy': 2.0.5 - '@vitest/utils': 2.0.5 - chai: 5.1.1 - debug: 4.3.7 - execa: 8.0.1 - magic-string: 0.30.12 - pathe: 1.1.2 - std-env: 3.7.0 - tinybench: 2.9.0 - tinypool: 1.0.1 - tinyrainbow: 1.2.0 - vite: 5.4.10(@types/node@18.19.64) - vite-node: 2.0.5(@types/node@18.19.64) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 18.19.64 - '@vitest/ui': 2.0.5(vitest@2.0.5) - transitivePeerDependencies: - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - vitest@2.0.5(@types/node@22.5.4)(@vitest/ui@2.0.5): - dependencies: - '@ampproject/remapping': 2.3.0 - '@vitest/expect': 2.0.5 - '@vitest/pretty-format': 2.0.5 - '@vitest/runner': 2.0.5 - '@vitest/snapshot': 2.0.5 - '@vitest/spy': 2.0.5 - '@vitest/utils': 2.0.5 - chai: 5.1.1 + '@vitest/expect': 2.1.4 + '@vitest/mocker': 2.1.4(vite@5.4.10(@types/node@22.9.0)) + '@vitest/pretty-format': 2.1.4 + '@vitest/runner': 2.1.4 + '@vitest/snapshot': 2.1.4 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 debug: 4.3.7 - execa: 8.0.1 + expect-type: 1.1.0 magic-string: 0.30.12 pathe: 1.1.2 std-env: 3.7.0 tinybench: 2.9.0 + tinyexec: 0.3.1 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.10(@types/node@22.5.4) - vite-node: 2.0.5(@types/node@22.5.4) + vite: 5.4.10(@types/node@22.9.0) + vite-node: 2.1.4(@types/node@22.9.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.5.4 - '@vitest/ui': 2.0.5(vitest@2.0.5) + '@types/node': 22.9.0 + '@vitest/ui': 2.1.4(vitest@2.1.4) transitivePeerDependencies: - less - lightningcss + - msw - sass - sass-embedded - stylus From 55afcbecc9a870e89bc3cc3b9181f13e0a3e84c5 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 19:43:04 -0500 Subject: [PATCH 058/126] fix nit --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 7d6f6845..b87fdf1f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,4 @@ vite.config.js.timestamp-* /packages/create-svelte/template/CHANGELOG.md .test-tmp .test-output - -*storybook.log \ No newline at end of file +*storybook.log From e6386a706b3c9067ce3a186f6a755be950dc8b78 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 19:54:12 -0500 Subject: [PATCH 059/126] fix lint --- packages/adders/_tests/_setup/suite.ts | 2 +- packages/adders/drizzle/index.ts | 6 ++-- packages/adders/lucia/index.ts | 48 +++++++++++++------------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index 71b2a2a8..e5bb4c91 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -37,7 +37,7 @@ export function setupTest(addons: Addons) { // creates a pnpm workspace in each addon dir fs.writeFileSync( path.resolve(cwd, testName, 'pnpm-workspace.yaml'), - `packages:\n - '**/*'`, + "packages:\n - '**/*'", 'utf8' ); }); diff --git a/packages/adders/drizzle/index.ts b/packages/adders/drizzle/index.ts index 31794408..69a15b9c 100644 --- a/packages/adders/drizzle/index.ts +++ b/packages/adders/drizzle/index.ts @@ -204,7 +204,7 @@ export default defineAdder({ imports.addNamed(ast, 'drizzle-kit', { defineConfig: 'defineConfig' }); const envCheckStatement = common.statementFromString( - `if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');` + "if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');" ); common.addStatement(ast, envCheckStatement); @@ -306,7 +306,7 @@ export default defineAdder({ // env var checks const dbURLCheck = common.statementFromString( - `if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set');` + "if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set');" ); common.addStatement(ast, dbURLCheck); @@ -326,7 +326,7 @@ export default defineAdder({ imports.addNamed(ast, '$app/environment', { dev: 'dev' }); // auth token check in prod const authTokenCheck = common.statementFromString( - `if (!dev && !env.DATABASE_AUTH_TOKEN) throw new Error('DATABASE_AUTH_TOKEN is not set');` + "if (!dev && !env.DATABASE_AUTH_TOKEN) throw new Error('DATABASE_AUTH_TOKEN is not set');" ); common.addStatement(ast, authTokenCheck); diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 5a498e4b..18e9aaa7 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -121,21 +121,21 @@ export default defineAdder({ integer: 'integer' }); object.overrideProperties(userAttributes, { - id: common.expressionFromString(`text('id').primaryKey()`) + id: common.expressionFromString("text('id').primaryKey()") }); if (options.demo) { object.overrideProperties(userAttributes, { - username: common.expressionFromString(`text('username').notNull().unique()`), - passwordHash: common.expressionFromString(`text('password_hash').notNull()`) + username: common.expressionFromString("text('username').notNull().unique()"), + passwordHash: common.expressionFromString("text('password_hash').notNull()") }); } object.overrideProperties(sessionAttributes, { - id: common.expressionFromString(`text('id').primaryKey()`), + id: common.expressionFromString("text('id').primaryKey()"), userId: common.expressionFromString( - `text('user_id').notNull().references(() => user.id)` + "text('user_id').notNull().references(() => user.id)" ), expiresAt: common.expressionFromString( - `integer('expires_at', { mode: 'timestamp' }).notNull()` + "integer('expires_at', { mode: 'timestamp' }).notNull()" ) }); } @@ -146,24 +146,24 @@ export default defineAdder({ datetime: 'datetime' }); object.overrideProperties(userAttributes, { - id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`) + id: common.expressionFromString("varchar('id', { length: 255 }).primaryKey()") }); if (options.demo) { object.overrideProperties(userAttributes, { username: common.expressionFromString( - `varchar('username', { length: 32 }).notNull().unique()` + "varchar('username', { length: 32 }).notNull().unique()" ), passwordHash: common.expressionFromString( - `varchar('password_hash', { length: 255 }).notNull()` + "varchar('password_hash', { length: 255 }).notNull()" ) }); } object.overrideProperties(sessionAttributes, { - id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`), + id: common.expressionFromString("varchar('id', { length: 255 }).primaryKey()"), userId: common.expressionFromString( - `varchar('user_id', { length: 255 }).notNull().references(() => user.id)` + "varchar('user_id', { length: 255 }).notNull().references(() => user.id)" ), - expiresAt: common.expressionFromString(`datetime('expires_at').notNull()`) + expiresAt: common.expressionFromString("datetime('expires_at').notNull()") }); } if (drizzleDialect === 'postgresql') { @@ -173,21 +173,21 @@ export default defineAdder({ timestamp: 'timestamp' }); object.overrideProperties(userAttributes, { - id: common.expressionFromString(`text('id').primaryKey()`) + id: common.expressionFromString("text('id').primaryKey()") }); if (options.demo) { object.overrideProperties(userAttributes, { - username: common.expressionFromString(`text('username').notNull().unique()`), - passwordHash: common.expressionFromString(`text('password_hash').notNull()`) + username: common.expressionFromString("text('username').notNull().unique()"), + passwordHash: common.expressionFromString("text('password_hash').notNull()") }); } object.overrideProperties(sessionAttributes, { - id: common.expressionFromString(`text('id').primaryKey()`), + id: common.expressionFromString("text('id').primaryKey()"), userId: common.expressionFromString( - `text('user_id').notNull().references(() => user.id)` + "text('user_id').notNull().references(() => user.id)" ), expiresAt: common.expressionFromString( - `timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()` + "timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()" ) }); } @@ -396,7 +396,7 @@ export default defineAdder({ import * as auth from '$lib/server/auth'; import { db } from '$lib/server/db'; import * as table from '$lib/server/db/schema'; - ${ts(`import type { Actions, PageServerLoad } from './$types';\n`)} + ${ts("import type { Actions, PageServerLoad } from './$types';\n")} export const load${ts(': PageServerLoad')} = async (event) => { if (event.locals.user) { return redirect(302, '/demo/lucia'); @@ -516,9 +516,9 @@ export default defineAdder({ const svelte5 = !!dependencyVersion('svelte')?.startsWith('5'); const [ts, s5] = utils.createPrinter(typescript, svelte5); return dedent` - @@ -555,7 +555,7 @@ export default defineAdder({ return dedent` import * as auth from '$lib/server/auth'; import { fail, redirect } from '@sveltejs/kit'; - ${ts(`import type { Actions, PageServerLoad } from './$types';\n`)} + ${ts("import type { Actions, PageServerLoad } from './$types';\n")} export const load${ts(': PageServerLoad')} = async (event) => { if (!event.locals.user) { return redirect(302, '/demo/lucia/login'); @@ -590,9 +590,9 @@ export default defineAdder({ const svelte5 = !!dependencyVersion('svelte')?.startsWith('5'); const [ts, s5] = utils.createPrinter(typescript, svelte5); return dedent` - From 6a1d29f06ba613d73f9340c4f3249b693f213408 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 7 Nov 2024 20:16:54 -0500 Subject: [PATCH 060/126] simplify --- packages/adders/_tests/drizzle/test.ts | 18 +++++++----------- packages/adders/package.json | 3 --- pnpm-lock.yaml | 4 ---- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/packages/adders/_tests/drizzle/test.ts b/packages/adders/_tests/drizzle/test.ts index 48644f7e..3b067c1a 100644 --- a/packages/adders/_tests/drizzle/test.ts +++ b/packages/adders/_tests/drizzle/test.ts @@ -1,25 +1,21 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { execSync } from 'node:child_process'; import * as vi from 'vitest'; import { expect } from '@playwright/test'; -import { exec } from 'tinyexec'; import { setupTest } from '../_setup/suite.ts'; import drizzle from '../../drizzle/index.ts'; import { pageServer, pageComp } from './fixtures.ts'; const { test, variants, prepareServer } = setupTest({ drizzle }); -vi.beforeAll(async () => { +vi.beforeAll(() => { const cwd = path.dirname(fileURLToPath(import.meta.url)); - await exec('docker', ['compose', 'up', '--detach'], { - nodeOptions: { cwd, stdio: 'pipe' } - }); + execSync('docker compose up --detach', { cwd, stdio: 'pipe' }); - return async () => { - await exec('docker', ['compose', 'down', '--volumes'], { - nodeOptions: { cwd, stdio: 'pipe' } - }); + return () => { + execSync('docker compose down --volumes', { cwd, stdio: 'pipe' }); }; }); @@ -51,8 +47,8 @@ test.concurrent.for(testCases)( const pageServerPath = path.resolve(routes, `+page.server.${ts ? 'ts' : 'js'}`); fs.writeFileSync(pageServerPath, pageServer, 'utf8'); - const { close } = await prepareServer({ cwd, page }, async () => { - await exec('npm', ['run', 'db:push'], { nodeOptions: { cwd, stdio: 'pipe' } }); + const { close } = await prepareServer({ cwd, page }, () => { + execSync('npm run db:push', { cwd, stdio: 'pipe' }); }); // kill server process when we're done ctx.onTestFinished(() => close()); diff --git a/packages/adders/package.json b/packages/adders/package.json index 42394993..39023993 100644 --- a/packages/adders/package.json +++ b/packages/adders/package.json @@ -12,8 +12,5 @@ "exports": "./index.ts", "dependencies": { "@sveltejs/cli-core": "workspace:*" - }, - "devDependencies": { - "tinyexec": "^0.3.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f1a43bd9..0a4ff418 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -105,10 +105,6 @@ importers: '@sveltejs/cli-core': specifier: workspace:* version: link:../core - devDependencies: - tinyexec: - specifier: ^0.3.1 - version: 0.3.1 packages/ast-tooling: devDependencies: From 1e5be34e48df87835883947df29db6b01085a393 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:38:50 -0500 Subject: [PATCH 061/126] cleanup --- eslint.config.js | 2 +- packages/adders/_tests/_setup/global.ts | 6 ------ packages/adders/_tests/_setup/suite.ts | 2 +- packages/cli/testing.ts | 3 +-- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index b3835abe..d0cb3344 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -33,7 +33,7 @@ export default [ '**/dist/*', 'packages/**/tests/**/{output,input}.ts', 'rollup.config.js', - 'community-adder-template/*' + 'community-adder-template/tests/*' ] } ]; diff --git a/packages/adders/_tests/_setup/global.ts b/packages/adders/_tests/_setup/global.ts index 5387fb66..aaab43f5 100644 --- a/packages/adders/_tests/_setup/global.ts +++ b/packages/adders/_tests/_setup/global.ts @@ -6,18 +6,12 @@ const TEST_DIR = path.resolve('.test-output'); const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; export default async function ({ provide }: GlobalSetupContext) { - // global setup (e.g. spin up docker containers) - // downloads different project configurations (sveltekit, js/ts, vite-only, etc) const { templatesDir } = await setup({ cwd: TEST_DIR, variants, clean: true }); provide('testDir', TEST_DIR); provide('templatesDir', templatesDir); provide('variants', variants); - - return async () => { - // tear down... (e.g. cleanup docker containers) - }; } declare module 'vitest' { diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index e5bb4c91..1b9bf72b 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -95,7 +95,7 @@ async function prepareServer( // build project execSync(buildCommand, { cwd, stdio: 'pipe' }); - // start preview server `vite preview` + // start preview server const { url, close } = await startPreview({ cwd, command: previewCommand }); // navigate to the page diff --git a/packages/cli/testing.ts b/packages/cli/testing.ts index f6efe58c..032bc35e 100644 --- a/packages/cli/testing.ts +++ b/packages/cli/testing.ts @@ -5,8 +5,7 @@ import degit from 'degit'; import terminate from 'terminate'; import { create } from '@sveltejs/create'; -export type ProjectVariant = (typeof variants)[number]; -export const variants = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts'] as const; +export type ProjectVariant = 'kit-js' | 'kit-ts' | 'vite-js' | 'vite-ts'; const TEMPLATES_DIR = '.templates'; From 1e676fef6123eeee550f1a81475f39e3424eac67 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:41:46 -0500 Subject: [PATCH 062/126] rename `vi` to `vitest` --- community-adder-template/tests/setup/suite.ts | 16 ++++++++-------- packages/adders/_tests/_setup/suite.ts | 16 ++++++++-------- packages/adders/_tests/drizzle/test.ts | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/community-adder-template/tests/setup/suite.ts b/community-adder-template/tests/setup/suite.ts index d8607ec0..f9b39256 100644 --- a/community-adder-template/tests/setup/suite.ts +++ b/community-adder-template/tests/setup/suite.ts @@ -1,15 +1,15 @@ import fs from 'node:fs'; import path from 'node:path'; import { execSync } from 'node:child_process'; -import * as vi from 'vitest'; +import * as vitest from 'vitest'; import { installAddon, type AddonMap, type OptionMap } from 'sv'; import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/test'; import { chromium, type Browser, type Page } from '@playwright/test'; import { fileURLToPath } from 'node:url'; -const cwd = vi.inject('testDir'); -const templatesDir = vi.inject('templatesDir'); -const variants = vi.inject('variants'); +const cwd = vitest.inject('testDir'); +const templatesDir = vitest.inject('templatesDir'); +const variants = vitest.inject('variants'); const SETUP_DIR = fileURLToPath(new URL('.', import.meta.url)); @@ -22,16 +22,16 @@ export function setupTest(addons: Addons) { let create: CreateProject; let browser: Browser; - const test = vi.test.extend>({} as any); + const test = vitest.test.extend>({} as any); - vi.beforeAll(async () => { + vitest.beforeAll(async () => { browser = await chromium.launch(); return async () => { await browser.close(); }; }); - vi.beforeAll(({ name }) => { + vitest.beforeAll(({ name }) => { const testName = path.parse(name).name.replace('.test', ''); // constructs a builder for create test projects @@ -46,7 +46,7 @@ export function setupTest(addons: Addons) { }); // runs before each test case - vi.beforeEach>(async (ctx) => { + vitest.beforeEach>(async (ctx) => { const browserCtx = await browser.newContext(); ctx.page = await browserCtx.newPage(); ctx.run = async (variant, options) => { diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index 1b9bf72b..2bb78f00 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -1,14 +1,14 @@ import fs from 'node:fs'; import path from 'node:path'; import { execSync } from 'node:child_process'; -import * as vi from 'vitest'; +import * as vitest from 'vitest'; import { installAddon, type AddonMap, type OptionMap } from 'sv'; import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/test'; import { chromium, type Browser, type Page } from '@playwright/test'; -const cwd = vi.inject('testDir'); -const templatesDir = vi.inject('templatesDir'); -const variants = vi.inject('variants'); +const cwd = vitest.inject('testDir'); +const templatesDir = vitest.inject('templatesDir'); +const variants = vitest.inject('variants'); type Fixtures = { page: Page; @@ -16,19 +16,19 @@ type Fixtures = { }; export function setupTest(addons: Addons) { - const test = vi.test.extend>({} as any); + const test = vitest.test.extend>({} as any); let create: CreateProject; let browser: Browser; - vi.beforeAll(async () => { + vitest.beforeAll(async () => { browser = await chromium.launch(); return async () => { await browser.close(); }; }); - vi.beforeAll(({ name }) => { + vitest.beforeAll(({ name }) => { const testName = path.dirname(name).split(path.sep).at(-1)!; // constructs a builder for create test projects @@ -43,7 +43,7 @@ export function setupTest(addons: Addons) { }); // runs before each test case - vi.beforeEach>(async (ctx) => { + vitest.beforeEach>(async (ctx) => { const browserCtx = await browser.newContext(); ctx.page = await browserCtx.newPage(); ctx.run = async (variant, options) => { diff --git a/packages/adders/_tests/drizzle/test.ts b/packages/adders/_tests/drizzle/test.ts index 3b067c1a..4995980d 100644 --- a/packages/adders/_tests/drizzle/test.ts +++ b/packages/adders/_tests/drizzle/test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { execSync } from 'node:child_process'; -import * as vi from 'vitest'; +import * as vitest from 'vitest'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import drizzle from '../../drizzle/index.ts'; @@ -10,7 +10,7 @@ import { pageServer, pageComp } from './fixtures.ts'; const { test, variants, prepareServer } = setupTest({ drizzle }); -vi.beforeAll(() => { +vitest.beforeAll(() => { const cwd = path.dirname(fileURLToPath(import.meta.url)); execSync('docker compose up --detach', { cwd, stdio: 'pipe' }); From 0a56d2693d6694007ddf55784327938634e61cd9 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:45:05 -0500 Subject: [PATCH 063/126] windows fixes --- packages/adders/_tests/_setup/suite.ts | 2 +- packages/cli/lib/install.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index 2bb78f00..fe489c9c 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -29,7 +29,7 @@ export function setupTest(addons: Addons) { }); vitest.beforeAll(({ name }) => { - const testName = path.dirname(name).split(path.sep).at(-1)!; + const testName = path.dirname(name).split('/').at(-1)!; // constructs a builder for create test projects create = createProject({ cwd, templatesDir, testName }); diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index d234b364..a36ef024 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -67,7 +67,10 @@ async function runAddon( try { const { args, command } = resolveCommand(workspace.packageManager, 'execute', script.args)!; if (workspace.packageManager === 'npm') args.unshift('--yes'); - await exec(command, args, { nodeOptions: { cwd: workspace.cwd, stdio: 'pipe' } }); + await exec(command, args, { + nodeOptions: { cwd: workspace.cwd, stdio: 'pipe' }, + throwOnError: true + }); } catch (error) { const typedError = error as Error; throw new Error(`Failed to execute scripts '${script.description}': ` + typedError.message); From f6523d4fa6555133f3c28fc105eefcd10f15ffbf Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:01:40 -0500 Subject: [PATCH 064/126] more windows annoyances --- packages/adders/_tests/_setup/global.ts | 7 ++++++- packages/adders/_tests/_setup/suite.ts | 3 ++- packages/adders/storybook/index.ts | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/adders/_tests/_setup/global.ts b/packages/adders/_tests/_setup/global.ts index aaab43f5..2bef0d42 100644 --- a/packages/adders/_tests/_setup/global.ts +++ b/packages/adders/_tests/_setup/global.ts @@ -1,4 +1,5 @@ import path from 'node:path'; +import process from 'node:process'; import { setup, type ProjectVariant } from 'sv/test'; import type { GlobalSetupContext } from 'vitest/node'; @@ -7,7 +8,11 @@ const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; export default async function ({ provide }: GlobalSetupContext) { // downloads different project configurations (sveltekit, js/ts, vite-only, etc) - const { templatesDir } = await setup({ cwd: TEST_DIR, variants, clean: true }); + const { templatesDir } = await setup({ + cwd: TEST_DIR, + variants, + clean: process.platform !== 'win32' + }); provide('testDir', TEST_DIR); provide('templatesDir', templatesDir); diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index fe489c9c..0072802d 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -1,5 +1,6 @@ import fs from 'node:fs'; import path from 'node:path'; +import process from 'node:process'; import { execSync } from 'node:child_process'; import * as vitest from 'vitest'; import { installAddon, type AddonMap, type OptionMap } from 'sv'; @@ -47,7 +48,7 @@ export function setupTest(addons: Addons) { const browserCtx = await browser.newContext(); ctx.page = await browserCtx.newPage(); ctx.run = async (variant, options) => { - const cwd = create({ testId: ctx.task.id, variant }); + const cwd = create({ testId: ctx.task.id, variant, clean: process.platform !== 'win32' }); // test metadata const metaPath = path.resolve(cwd, 'meta.json'); diff --git a/packages/adders/storybook/index.ts b/packages/adders/storybook/index.ts index 65de68a2..20fdc5e8 100644 --- a/packages/adders/storybook/index.ts +++ b/packages/adders/storybook/index.ts @@ -9,7 +9,7 @@ export default defineAdder({ scripts: [ { description: 'applies storybook', - args: ['storybook@8.3', 'init', '--skip-install', '--no-dev'], + args: ['storybook@8.3.6', 'init', '--skip-install', '--no-dev'], stdio: 'inherit' } ], From 58700366cb0d2bdd258c9aad8a20909bfa2cf430 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:32:25 -0500 Subject: [PATCH 065/126] tweaks --- packages/adders/_tests/_setup/suite.ts | 4 ++-- packages/adders/_tests/storybook/test.ts | 2 +- packages/create/tsconfig.json | 2 +- packages/create/vitest.config.ts | 6 ++---- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index 0072802d..8afbd374 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -88,13 +88,13 @@ async function prepareServer( afterInstall?: () => Promise | any ) { // install deps - execSync(installCommand, { cwd, stdio: 'pipe' }); + if (installCommand) execSync(installCommand, { cwd, stdio: 'pipe' }); // ...do commands and any other extra stuff await afterInstall?.(); // build project - execSync(buildCommand, { cwd, stdio: 'pipe' }); + if (buildCommand) execSync(buildCommand, { cwd, stdio: 'pipe' }); // start preview server const { url, close } = await startPreview({ cwd, command: previewCommand }); diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index a2c0bb54..494d4242 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -12,7 +12,7 @@ test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, . cwd, page, previewCommand: `pnpm storybook -p ${++port} --ci`, - buildCommand: 'echo' + buildCommand: '' }); // kill server process when we're done ctx.onTestFinished(() => close()); diff --git a/packages/create/tsconfig.json b/packages/create/tsconfig.json index 770dd836..c7f6b862 100644 --- a/packages/create/tsconfig.json +++ b/packages/create/tsconfig.json @@ -6,5 +6,5 @@ "declaration": true }, // overrides the root tsconfig `exclude` field so we're not ignoring the `test` dir - "exclude": ["templates/**", "shared/**", "dist/**"] + "exclude": ["templates/**", "shared/**", "dist/**", "vitest.config.ts"] } diff --git a/packages/create/vitest.config.ts b/packages/create/vitest.config.ts index 78e3ca4a..33cdc9c7 100644 --- a/packages/create/vitest.config.ts +++ b/packages/create/vitest.config.ts @@ -1,7 +1,5 @@ -import { defineConfig, type UserConfig } from 'vitest/config'; +import { defineConfig } from 'vitest/config'; -const config: UserConfig = defineConfig({ +export default defineConfig({ test: { dir: './test', include: ['*.ts'] } }); - -export default config; From 677fbb0e047fc32e06a611f8cfb6c87de053910e Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Fri, 8 Nov 2024 19:35:06 +0100 Subject: [PATCH 066/126] add `test:ui` script --- packages/adders/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/adders/package.json b/packages/adders/package.json index 39023993..cff17db4 100644 --- a/packages/adders/package.json +++ b/packages/adders/package.json @@ -7,7 +7,8 @@ "check": "tsc", "format": "pnpm lint --write", "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore", - "test": "vitest" + "test": "vitest", + "test:ui": "vitest --ui" }, "exports": "./index.ts", "dependencies": { From 6e9360ccbce01f6684c41a628b0ace0e16d82feb Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Fri, 8 Nov 2024 20:02:28 +0100 Subject: [PATCH 067/126] `tinyexec` `throwOnError: true` --- packages/cli/commands/add/index.ts | 5 ++++- packages/cli/common.ts | 12 +++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index a91ea35c..14e0ec05 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -545,7 +545,10 @@ async function runAdders({ if (workspace.packageManager === 'npm') args.unshift('--yes'); try { - await exec(command, args, { nodeOptions: { cwd: workspace.cwd, stdio: script.stdio } }); + await exec(command, args, { + nodeOptions: { cwd: workspace.cwd, stdio: script.stdio }, + throwOnError: true + }); } catch (error) { const typedError = error as Error; throw new Error( diff --git a/packages/cli/common.ts b/packages/cli/common.ts index 3010961b..13035fd3 100644 --- a/packages/cli/common.ts +++ b/packages/cli/common.ts @@ -89,7 +89,10 @@ export async function formatFiles(options: { }): Promise { const args = ['prettier', '--write', '--ignore-unknown', ...options.paths]; const cmd = resolveCommand(options.packageManager, 'execute-local', args)!; - await exec(cmd.command, cmd.args, { nodeOptions: { cwd: options.cwd, stdio: 'pipe' } }); + await exec(cmd.command, cmd.args, { + nodeOptions: { cwd: options.cwd, stdio: 'pipe' }, + throwOnError: true + }); } const agents = AGENTS.filter((agent): agent is AgentName => !agent.includes('@')); @@ -119,7 +122,7 @@ export async function installDependencies(agent: AgentName, cwd: string): Promis spinner.start('Installing dependencies...'); try { const { command, args } = constructCommand(COMMANDS[agent].install, [])!; - await exec(command, args, { nodeOptions: { cwd } }); + await exec(command, args, { nodeOptions: { cwd }, throwOnError: true }); spinner.stop('Successfully installed dependencies'); } catch (error) { @@ -157,7 +160,10 @@ export function getGlobalPreconditions( // there are no pending changes. If the below command is run outside of a git repository, // git will exit with a failing exit code, which will trigger the catch statement. // also see https://remarkablemark.org/blog/2017/10/12/check-git-dirty/#git-status - const { stdout } = await exec('git', ['status', '--short'], { nodeOptions: { cwd } }); + const { stdout } = await exec('git', ['status', '--short'], { + nodeOptions: { cwd }, + throwOnError: true + }); if (stdout) { return { success: false, message: 'Found modified files' }; From 7181351307964ca886999c04e62d7167b1f42f9e Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:52:52 -0500 Subject: [PATCH 068/126] revert --- packages/adders/_tests/_setup/global.ts | 7 +------ packages/adders/_tests/_setup/suite.ts | 3 +-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/adders/_tests/_setup/global.ts b/packages/adders/_tests/_setup/global.ts index 2bef0d42..c65844cc 100644 --- a/packages/adders/_tests/_setup/global.ts +++ b/packages/adders/_tests/_setup/global.ts @@ -1,5 +1,4 @@ import path from 'node:path'; -import process from 'node:process'; import { setup, type ProjectVariant } from 'sv/test'; import type { GlobalSetupContext } from 'vitest/node'; @@ -8,11 +7,7 @@ const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; export default async function ({ provide }: GlobalSetupContext) { // downloads different project configurations (sveltekit, js/ts, vite-only, etc) - const { templatesDir } = await setup({ - cwd: TEST_DIR, - variants, - clean: process.platform !== 'win32' - }); + const { templatesDir } = await setup({ cwd: TEST_DIR, variants }); provide('testDir', TEST_DIR); provide('templatesDir', templatesDir); diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index 8afbd374..1eca82e0 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -1,6 +1,5 @@ import fs from 'node:fs'; import path from 'node:path'; -import process from 'node:process'; import { execSync } from 'node:child_process'; import * as vitest from 'vitest'; import { installAddon, type AddonMap, type OptionMap } from 'sv'; @@ -48,7 +47,7 @@ export function setupTest(addons: Addons) { const browserCtx = await browser.newContext(); ctx.page = await browserCtx.newPage(); ctx.run = async (variant, options) => { - const cwd = create({ testId: ctx.task.id, variant, clean: process.platform !== 'win32' }); + const cwd = create({ testId: ctx.task.id, variant }); // test metadata const metaPath = path.resolve(cwd, 'meta.json'); From d98c630b49c093f176b950db413246b87b90b35c Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 19:18:18 -0500 Subject: [PATCH 069/126] properly terminate child processes --- .../tests/custom-addon.test.ts | 2 +- packages/adders/_tests/drizzle/test.ts | 2 +- packages/adders/_tests/eslint/test.ts | 2 +- packages/adders/_tests/lucia/test.ts | 2 +- packages/adders/_tests/mdsvex/test.ts | 2 +- packages/adders/_tests/paraglide/test.ts | 2 +- packages/adders/_tests/playwright/test.ts | 2 +- packages/adders/_tests/prettier/test.ts | 2 +- packages/adders/_tests/storybook/test.ts | 4 +- packages/adders/_tests/tailwindcss/test.ts | 4 +- packages/adders/_tests/vitest/test.ts | 2 +- packages/cli/package.json | 4 +- packages/cli/testing.ts | 56 ++++++++++++++----- pnpm-lock.yaml | 25 +++++---- 14 files changed, 72 insertions(+), 39 deletions(-) diff --git a/community-adder-template/tests/custom-addon.test.ts b/community-adder-template/tests/custom-addon.test.ts index f3c01b74..20a970e3 100644 --- a/community-adder-template/tests/custom-addon.test.ts +++ b/community-adder-template/tests/custom-addon.test.ts @@ -20,7 +20,7 @@ test.concurrent.for(variants)('demo - %s', async (variant, { page, ...ctx }) => const { close } = await prepareServer({ cwd, page }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); // expectations const textContent = await page.getByTestId('demo').textContent(); diff --git a/packages/adders/_tests/drizzle/test.ts b/packages/adders/_tests/drizzle/test.ts index 4995980d..b8efb11b 100644 --- a/packages/adders/_tests/drizzle/test.ts +++ b/packages/adders/_tests/drizzle/test.ts @@ -51,7 +51,7 @@ test.concurrent.for(testCases)( execSync('npm run db:push', { cwd, stdio: 'pipe' }); }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); expect(await page.$('[data-testid]')).toBeTruthy(); } diff --git a/packages/adders/_tests/eslint/test.ts b/packages/adders/_tests/eslint/test.ts index 6de35cc6..6a8d3e20 100644 --- a/packages/adders/_tests/eslint/test.ts +++ b/packages/adders/_tests/eslint/test.ts @@ -9,7 +9,7 @@ test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => const { close } = await prepareServer({ cwd, page }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); expect(true).toBe(true); }); diff --git a/packages/adders/_tests/lucia/test.ts b/packages/adders/_tests/lucia/test.ts index 5b16d12d..c95ac959 100644 --- a/packages/adders/_tests/lucia/test.ts +++ b/packages/adders/_tests/lucia/test.ts @@ -14,7 +14,7 @@ test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { const { close } = await prepareServer({ cwd, page }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); expect(true).toBe(true); }); diff --git a/packages/adders/_tests/mdsvex/test.ts b/packages/adders/_tests/mdsvex/test.ts index 1d2731f3..13f71ab6 100644 --- a/packages/adders/_tests/mdsvex/test.ts +++ b/packages/adders/_tests/mdsvex/test.ts @@ -18,7 +18,7 @@ test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => const { close } = await prepareServer({ cwd, page }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); expect(await page.$('.mdsvex h1')).toBeTruthy(); expect(await page.$('.mdsvex h2')).toBeTruthy(); diff --git a/packages/adders/_tests/paraglide/test.ts b/packages/adders/_tests/paraglide/test.ts index 2b72898c..e2d2ac01 100644 --- a/packages/adders/_tests/paraglide/test.ts +++ b/packages/adders/_tests/paraglide/test.ts @@ -10,7 +10,7 @@ test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { const { close } = await prepareServer({ cwd, page }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); expect(true).toBe(true); }); diff --git a/packages/adders/_tests/playwright/test.ts b/packages/adders/_tests/playwright/test.ts index 11a0f340..e8d735f7 100644 --- a/packages/adders/_tests/playwright/test.ts +++ b/packages/adders/_tests/playwright/test.ts @@ -9,7 +9,7 @@ test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => const { close } = await prepareServer({ cwd, page }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); expect(true).toBe(true); }); diff --git a/packages/adders/_tests/prettier/test.ts b/packages/adders/_tests/prettier/test.ts index 7dde97d2..1b3f2992 100644 --- a/packages/adders/_tests/prettier/test.ts +++ b/packages/adders/_tests/prettier/test.ts @@ -9,7 +9,7 @@ test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => const { close } = await prepareServer({ cwd, page }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); expect(true).toBe(true); }); diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index 494d4242..eb128dd1 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -5,7 +5,7 @@ import storybook from '../../storybook/index.ts'; const { test, variants, prepareServer } = setupTest({ storybook }); let port = 6006; -test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { +test.concurrent.skip.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { storybook: {} }); const { close } = await prepareServer({ @@ -15,7 +15,7 @@ test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, . buildCommand: '' }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); expect(await page.$('main .sb-bar')).toBeTruthy(); expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); diff --git a/packages/adders/_tests/tailwindcss/test.ts b/packages/adders/_tests/tailwindcss/test.ts index fd90fa0e..1ede1055 100644 --- a/packages/adders/_tests/tailwindcss/test.ts +++ b/packages/adders/_tests/tailwindcss/test.ts @@ -13,7 +13,7 @@ test.concurrent.for(variants)('none - %s', async (variant, { page, ...ctx }) => const { close } = await prepareServer({ cwd, page }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); const el = page.getByTestId('base'); await expect(el).toHaveCSS('background-color', 'rgb(71, 85, 105)'); @@ -30,7 +30,7 @@ test.concurrent.for(variants)('typography - %s', async (variant, { page, ...ctx const { close } = await prepareServer({ cwd, page }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); const el = page.getByTestId('typography'); await expect(el).toHaveCSS('font-size', '18px'); diff --git a/packages/adders/_tests/vitest/test.ts b/packages/adders/_tests/vitest/test.ts index 7707a39d..ed451996 100644 --- a/packages/adders/_tests/vitest/test.ts +++ b/packages/adders/_tests/vitest/test.ts @@ -9,7 +9,7 @@ test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => const { close } = await prepareServer({ cwd, page }); // kill server process when we're done - ctx.onTestFinished(() => close()); + ctx.onTestFinished(async () => await close()); expect(true).toBe(true); }); diff --git a/packages/cli/package.json b/packages/cli/package.json index 32d36dcf..d2e845d8 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -35,15 +35,17 @@ "@sveltejs/cli-core": "workspace:*", "@sveltejs/create": "workspace:*", "@types/degit": "^2.8.6", + "@types/ps-tree": "^1.1.6", "@types/tar-fs": "^2.0.4", "commander": "^12.1.0", "degit": "^2.8.4", "empathic": "^1.0.0", "package-manager-detector": "^0.2.2", "picocolors": "^1.1.0", + "ps-tree": "^1.2.0", "tar-fs": "^3.0.6", - "terminate": "^2.8.0", "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", "valibot": "^0.41.0" }, "keywords": [ diff --git a/packages/cli/testing.ts b/packages/cli/testing.ts index 032bc35e..84b3f5f7 100644 --- a/packages/cli/testing.ts +++ b/packages/cli/testing.ts @@ -1,9 +1,10 @@ import fs from 'node:fs'; +import process from 'node:process'; import path from 'node:path'; -import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process'; import degit from 'degit'; -import terminate from 'terminate'; +import { exec } from 'tinyexec'; import { create } from '@sveltejs/create'; +import pstree, { type PS } from 'ps-tree'; export type ProjectVariant = 'kit-js' | 'kit-ts' | 'vite-js' | 'vite-ts'; @@ -71,20 +72,26 @@ export function createProject({ cwd, testName, templatesDir }: CreateOptions): C } type PreviewOptions = { cwd: string; command?: string }; -export async function startPreview({ cwd, command = 'npm run preview' }: PreviewOptions): Promise<{ - url: string; - server: ChildProcessWithoutNullStreams; - close: () => void; -}> { +export async function startPreview({ + cwd, + command = 'npm run preview' +}: PreviewOptions): Promise<{ url: string; close: () => Promise }> { const [cmd, ...args] = command.split(' '); - const process = spawn(cmd, args, { stdio: 'pipe', shell: true, cwd, timeout: 120_000 }); - const close = () => { - if (!process.pid) return; - terminate(process.pid); + const proc = exec(cmd, args, { + nodeOptions: { cwd, stdio: 'pipe' }, + throwOnError: true, + timeout: 60_000 + }); + + const close = async () => { + if (!proc.pid) return; + await terminate(proc.pid); }; - return await new Promise((resolve) => { - process.stdout.on('data', (data: Buffer) => { + return await new Promise((resolve, reject) => { + if (!proc.process?.stdout) return reject('impossible state'); + + proc.process.stdout.on('data', (data: Buffer) => { const value = data.toString(); // extract dev server url from console output @@ -99,8 +106,29 @@ export async function startPreview({ cwd, command = 'npm run preview' }: Preview if (urls && urls.length > 0) { const url = urls[0]; - resolve({ url, server: process, close }); + resolve({ url, close }); } }); }); } + +async function getProcessTree(pid: number) { + return new Promise((res, rej) => { + pstree(pid, (err, children) => { + if (err) rej(err); + res(children); + }); + }); +} + +async function terminate(pid: number) { + const children = await getProcessTree(pid); + // the process tree is ordered from parents -> children, + // so we'll iterate in the reverse order to terminate the children first + for (let i = children.length - 1; i >= 0; i--) { + const child = children[i]; + const pid = Number(child.PID); + process.kill(pid); + } + process.kill(pid); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0a4ff418..0dbffa69 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -183,6 +183,9 @@ importers: '@types/degit': specifier: ^2.8.6 version: 2.8.6 + '@types/ps-tree': + specifier: ^1.1.6 + version: 1.1.6 '@types/tar-fs': specifier: ^2.0.4 version: 2.0.4 @@ -201,15 +204,18 @@ importers: picocolors: specifier: ^1.1.0 version: 1.1.1 + ps-tree: + specifier: ^1.2.0 + version: 1.2.0 tar-fs: specifier: ^3.0.6 version: 3.0.6 - terminate: - specifier: ^2.8.0 - version: 2.8.0 tinyexec: specifier: ^0.3.1 version: 0.3.1 + tinypool: + specifier: ^1.0.1 + version: 1.0.1 valibot: specifier: ^0.41.0 version: 0.41.0(typescript@5.6.3) @@ -965,6 +971,9 @@ packages: '@types/prompts@2.4.9': resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} + '@types/ps-tree@1.1.6': + resolution: {integrity: sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==} + '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -2266,10 +2275,6 @@ packages: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} - terminate@2.8.0: - resolution: {integrity: sha512-bcbjJEg0wY5nuJXvGxxHfmoEPkyHLCctUKO6suwtxy7jVSgGcgPeGwpbLDLELFhIaxCGRr3dPvyNg1yuz2V0eg==} - engines: {node: '>=12'} - text-decoder@1.2.0: resolution: {integrity: sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==} @@ -3121,6 +3126,8 @@ snapshots: '@types/node': 22.9.0 kleur: 3.0.3 + '@types/ps-tree@1.1.6': {} + '@types/resolve@1.20.2': {} '@types/semver@7.5.8': {} @@ -4478,10 +4485,6 @@ snapshots: term-size@2.2.1: {} - terminate@2.8.0: - dependencies: - ps-tree: 1.2.0 - text-decoder@1.2.0: dependencies: b4a: 1.6.6 From 9aa59cfee9184ae9df6344602e1e0b2d0a16048f Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 19:39:19 -0500 Subject: [PATCH 070/126] dont skip storybook --- packages/adders/_tests/storybook/test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index eb128dd1..6093fc53 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -5,7 +5,7 @@ import storybook from '../../storybook/index.ts'; const { test, variants, prepareServer } = setupTest({ storybook }); let port = 6006; -test.concurrent.skip.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { +test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { storybook: {} }); const { close } = await prepareServer({ From dd141e78025f85888e6d5b088d3c48b043f03def Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 19:40:11 -0500 Subject: [PATCH 071/126] cleanup on failure to load the page --- packages/adders/_tests/_setup/suite.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index 1eca82e0..eebad34e 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -98,8 +98,14 @@ async function prepareServer( // start preview server const { url, close } = await startPreview({ cwd, command: previewCommand }); - // navigate to the page - await page.goto(url); + try { + // navigate to the page + await page.goto(url); + } catch (e) { + // cleanup in the instance of a timeout + await close(); + throw e; + } return { url, close }; } From d4794f0b1b46d81c4f6f8a949525f7a85ae90622 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 20:29:21 -0500 Subject: [PATCH 072/126] unused --- packages/cli/package.json | 1 - pnpm-lock.yaml | 3 --- 2 files changed, 4 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index d2e845d8..4f80ef88 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -45,7 +45,6 @@ "ps-tree": "^1.2.0", "tar-fs": "^3.0.6", "tinyexec": "^0.3.1", - "tinypool": "^1.0.1", "valibot": "^0.41.0" }, "keywords": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0dbffa69..bb9ceae1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -213,9 +213,6 @@ importers: tinyexec: specifier: ^0.3.1 version: 0.3.1 - tinypool: - specifier: ^1.0.1 - version: 1.0.1 valibot: specifier: ^0.41.0 version: 0.41.0(typescript@5.6.3) From 50fde5cc5ba8ff503e0b1edeb8b9d52afca02771 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 20:31:25 -0500 Subject: [PATCH 073/126] newline --- community-adder-template/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community-adder-template/.gitignore b/community-adder-template/.gitignore index 4404a552..a9e1699a 100644 --- a/community-adder-template/.gitignore +++ b/community-adder-template/.gitignore @@ -1,4 +1,4 @@ node_modules temp .outputs -.test-output \ No newline at end of file +.test-output From 2b98217ebcb591cb24e168638060e7424acb2573 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 8 Nov 2024 22:01:54 -0500 Subject: [PATCH 074/126] use vitest workspaces --- community-adder-template/package.json | 2 +- .../tests/setup/global.ts | 4 +- package.json | 3 +- packages/adders/_tests/_setup/global.ts | 4 +- packages/adders/package.json | 2 +- packages/adders/vitest.config.ts | 1 + packages/core/vitest.config.ts | 4 +- packages/create/.gitignore | 1 - packages/create/package.json | 2 +- packages/create/test/check.ts | 79 +++---------------- packages/create/vitest.config.ts | 5 +- packages/migrate/package.json | 2 +- packages/migrate/vitest.config.ts | 7 ++ rollup.config.js | 1 + vitest.workspace.ts | 3 + 15 files changed, 38 insertions(+), 82 deletions(-) create mode 100644 packages/migrate/vitest.config.ts create mode 100644 vitest.workspace.ts diff --git a/community-adder-template/package.json b/community-adder-template/package.json index 428d0913..fedd5d42 100644 --- a/community-adder-template/package.json +++ b/community-adder-template/package.json @@ -7,7 +7,7 @@ "scripts": { "create-temp": "sv create temp --types ts --template minimal --no-add-ons --no-install", "start": "sv add -C temp --community file:../", - "test": "vitest" + "test": "vitest run" }, "files": [ "src", diff --git a/community-adder-template/tests/setup/global.ts b/community-adder-template/tests/setup/global.ts index 0dab6571..95cc7c8d 100644 --- a/community-adder-template/tests/setup/global.ts +++ b/community-adder-template/tests/setup/global.ts @@ -1,9 +1,9 @@ -import path from 'node:path'; +import { fileURLToPath } from 'node:url'; import { setup, type ProjectVariant } from 'sv/test'; import type { GlobalSetupContext } from 'vitest/node'; const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; -const TEST_DIR = path.resolve('.test-output'); +const TEST_DIR = fileURLToPath(new URL('./.test-output/', import.meta.url)); export default async function ({ provide }: GlobalSetupContext) { // global setup (e.g. spin up docker containers) diff --git a/package.json b/package.json index 58bd13dd..a7a9881a 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "dev": "rollup --config --watch", "format": "pnpm --parallel format", "lint": "pnpm --parallel lint && eslint --cache --cache-location node_modules/.eslintcache", - "test": "pnpm --parallel test" + "test": "pnpm vitest run --silent", + "test:ui": "pnpm vitest --ui" }, "devDependencies": { "@changesets/cli": "^2.27.9", diff --git a/packages/adders/_tests/_setup/global.ts b/packages/adders/_tests/_setup/global.ts index c65844cc..3777b671 100644 --- a/packages/adders/_tests/_setup/global.ts +++ b/packages/adders/_tests/_setup/global.ts @@ -1,8 +1,8 @@ -import path from 'node:path'; +import { fileURLToPath } from 'node:url'; import { setup, type ProjectVariant } from 'sv/test'; import type { GlobalSetupContext } from 'vitest/node'; -const TEST_DIR = path.resolve('.test-output'); +const TEST_DIR = fileURLToPath(new URL('../../../../.test-output/adders/', import.meta.url)); const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; export default async function ({ provide }: GlobalSetupContext) { diff --git a/packages/adders/package.json b/packages/adders/package.json index cff17db4..05a0f370 100644 --- a/packages/adders/package.json +++ b/packages/adders/package.json @@ -7,7 +7,7 @@ "check": "tsc", "format": "pnpm lint --write", "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore", - "test": "vitest", + "test": "vitest run", "test:ui": "vitest --ui" }, "exports": "./index.ts", diff --git a/packages/adders/vitest.config.ts b/packages/adders/vitest.config.ts index 8924a20d..d0b04f60 100644 --- a/packages/adders/vitest.config.ts +++ b/packages/adders/vitest.config.ts @@ -5,6 +5,7 @@ const ONE_MINUTE = 1000 * 60; export default defineConfig({ test: { + name: 'adders', include: ['_tests/**/test.{js,ts}'], testTimeout: ONE_MINUTE * 3, hookTimeout: ONE_MINUTE * 3, diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts index 669f2a8e..5940c172 100644 --- a/packages/core/vitest.config.ts +++ b/packages/core/vitest.config.ts @@ -2,7 +2,7 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { - dir: './tests', - include: ['./**/index.ts'] + name: 'core', + include: ['./tests/**/index.ts'] } }); diff --git a/packages/create/.gitignore b/packages/create/.gitignore index 14b63618..e7e5bfa8 100644 --- a/packages/create/.gitignore +++ b/packages/create/.gitignore @@ -1,5 +1,4 @@ /dist -/.test-tmp # re-enable this once we're out of prerelease /cli/versions.js diff --git a/packages/create/package.json b/packages/create/package.json index c0560933..762372ba 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -16,7 +16,7 @@ "check": "tsc", "format": "pnpm lint --write", "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore", - "test": "pnpm build:dist && vitest run", + "test": "vitest run", "update-template-repo": "pnpm build:dist && echo \"Updating template repo\" && bash ./scripts/update-template-repo.sh" }, "files": [ diff --git a/packages/create/test/check.ts b/packages/create/test/check.ts index 8beb3dba..998359f4 100644 --- a/packages/create/test/check.ts +++ b/packages/create/test/check.ts @@ -1,9 +1,8 @@ -import { exec } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; -import { fileURLToPath } from 'node:url'; import { promisify } from 'node:util'; -import glob from 'tiny-glob/sync.js'; +import { fileURLToPath } from 'node:url'; +import { exec, type PromiseWithChild } from 'node:child_process'; import { beforeAll, describe, test } from 'vitest'; import { create, type LanguageType, type TemplateType } from '../index.ts'; @@ -11,38 +10,11 @@ import { create, type LanguageType, type TemplateType } from '../index.ts'; const resolve_path = (path: string) => fileURLToPath(new URL(path, import.meta.url)); // use a directory outside of packages to ensure it isn't added to the pnpm workspace -const test_workspace_dir = resolve_path('../../../.test-tmp/create-svelte/'); - -const existing_workspace_overrides = JSON.parse( - fs.readFileSync(resolve_path('../../../package.json'), 'utf-8') -).pnpm?.overrides; - -const overrides = { ...existing_workspace_overrides }; - -for (const pkg_path of glob(resolve_path('../../../packages/*/package.json'))) { - const name = JSON.parse(fs.readFileSync(pkg_path, 'utf-8')).name; - // use `file:` protocol for opting into stricter resolve logic which catches more bugs - overrides[name] = `file:${path.dirname(path.resolve(pkg_path))}`; -} +const test_workspace_dir = resolve_path('../../../.test-output/create/'); // prepare test pnpm workspace fs.rmSync(test_workspace_dir, { recursive: true, force: true }); fs.mkdirSync(test_workspace_dir, { recursive: true }); -const workspace = { - name: 'svelte-check-test-fake-pnpm-workspace', - private: true, - version: '0.0.0', - pnpm: { overrides }, - // convert override query "@foo/bar@>x [query.replace(/(@?[^@]+)@.*$/, '$1'), range]) - ) -}; - -fs.writeFileSync( - path.join(test_workspace_dir, 'package.json'), - JSON.stringify(workspace, null, '\t') -); fs.writeFileSync(path.join(test_workspace_dir, 'pnpm-workspace.yaml'), 'packages:\n - ./*\n'); @@ -54,37 +26,13 @@ beforeAll(async () => { }); }, 60000); -function patch_package_json(pkg: any) { - Object.entries(overrides).forEach(([key, value]) => { - if (pkg.devDependencies?.[key]) { - pkg.devDependencies[key] = value; - } - - if (pkg.dependencies?.[key]) { - pkg.dependencies[key] = value; - } - - if (!pkg.pnpm) { - pkg.pnpm = {}; - } - - if (!pkg.pnpm.overrides) { - pkg.pnpm.overrides = {}; - } - - pkg.pnpm.overrides = { ...pkg.pnpm.overrides, ...overrides }; - }); - pkg.private = true; -} - /** * Tests in different templates can be run concurrently for a nice speedup locally, but tests within a template must be run sequentially. * It'd be better to group tests by template, but vitest doesn't support that yet. - * @type {Map import('node:child_process').PromiseWithChild][]>} */ -const script_test_map = new Map(); +const script_test_map = new Map PromiseWithChild]>>(); -const templates = fs.readdirSync('templates') as TemplateType[]; +const templates = fs.readdirSync(resolve_path('../templates/')) as TemplateType[]; for (const template of templates) { if (template[0] === '.') continue; @@ -100,9 +48,6 @@ for (const template of templates) { }); const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8')); - patch_package_json(pkg); - - fs.writeFileSync(path.join(cwd, 'package.json'), JSON.stringify(pkg, null, '\t') + '\n'); // run provided scripts that are non-blocking. All of them should exit with 0 // package script requires lib dir @@ -120,13 +65,9 @@ for (const template of templates) { } for (const [script, tests] of script_test_map) { - describe.concurrent( - script, - () => { - for (const [name, task] of tests) { - test(name, task); - } - }, - { timeout: 60000 } - ); + describe.concurrent(script, { timeout: 60000 }, () => { + for (const [name, task] of tests) { + test(name, task); + } + }); } diff --git a/packages/create/vitest.config.ts b/packages/create/vitest.config.ts index 33cdc9c7..132b334f 100644 --- a/packages/create/vitest.config.ts +++ b/packages/create/vitest.config.ts @@ -1,5 +1,8 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ - test: { dir: './test', include: ['*.ts'] } + test: { + name: 'create', + include: ['test/*.ts'] + } }); diff --git a/packages/migrate/package.json b/packages/migrate/package.json index e56d96c9..0fe2bffe 100644 --- a/packages/migrate/package.json +++ b/packages/migrate/package.json @@ -14,7 +14,7 @@ "check": "tsc", "format": "pnpm lint --write", "lint": "prettier --check .", - "test": "vitest run --silent" + "test": "vitest run" }, "files": [ "bin.js", diff --git a/packages/migrate/vitest.config.ts b/packages/migrate/vitest.config.ts new file mode 100644 index 00000000..22afa1cf --- /dev/null +++ b/packages/migrate/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + name: 'migrate' + } +}); diff --git a/rollup.config.js b/rollup.config.js index 74c8158c..c11e3d9d 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -68,6 +68,7 @@ function getConfig(project) { console.log('building templates'); const start = performance.now(); await buildTemplates(path.resolve('packages', 'cli', 'dist')); + await buildTemplates(path.resolve('packages', 'create', 'dist')); const end = performance.now(); console.log(`finished building templates: ${Math.round(end - start)}ms`); } diff --git a/vitest.workspace.ts b/vitest.workspace.ts new file mode 100644 index 00000000..2a7e8f5f --- /dev/null +++ b/vitest.workspace.ts @@ -0,0 +1,3 @@ +import { defineWorkspace } from 'vitest/config'; + +export default defineWorkspace(['packages/*', 'community-adder-template']); From 8e006722f4d60794202713a3894c6f3fb6da03e4 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sat, 9 Nov 2024 08:30:52 +0100 Subject: [PATCH 075/126] add `try-catch` while killing processes --- packages/cli/testing.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/cli/testing.ts b/packages/cli/testing.ts index 84b3f5f7..1d90e97a 100644 --- a/packages/cli/testing.ts +++ b/packages/cli/testing.ts @@ -128,7 +128,16 @@ async function terminate(pid: number) { for (let i = children.length - 1; i >= 0; i--) { const child = children[i]; const pid = Number(child.PID); + try { + process.kill(pid); + } catch { + // this can happen if a process has been automatically terminated. + } + } + + try { process.kill(pid); + } catch { + // this can happen if a process has been automatically terminated. } - process.kill(pid); } From 9526feeefe18d5e35f1010eb194ae13545c8d8e4 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sat, 9 Nov 2024 17:51:29 +0100 Subject: [PATCH 076/126] increase navigation timeout --- packages/adders/_tests/_setup/suite.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index eebad34e..4820c621 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -98,6 +98,10 @@ async function prepareServer( // start preview server const { url, close } = await startPreview({ cwd, command: previewCommand }); + // default navigation timeout is 30 seconds. When running many tests at once as we are doing + // this is not always enough. Increase it to 60 seconds. + page.setDefaultNavigationTimeout(60_0000); + try { // navigate to the page await page.goto(url); From 479da37f511539c73cc8f1c3c151723a818c5cd0 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sat, 9 Nov 2024 19:03:56 +0100 Subject: [PATCH 077/126] apply merge changes --- packages/cli/commands/add/index.ts | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 3088b6f8..f39484b4 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -557,15 +557,23 @@ async function runAdders({ const dependencies: Array<{ pkg: string; version: string; dev: boolean }> = []; const sv: SvApi = { file: (path, content) => { - const exists = fileExists(workspace.cwd, path); - let fileContent = exists ? readFile(workspace.cwd, path) : ''; - // process file - fileContent = content(fileContent); - - writeFile(workspace, path, fileContent); - filesToFormat.add(path); - - return fileContent; + try { + const exists = fileExists(workspace.cwd, path); + let fileContent = exists ? readFile(workspace.cwd, path) : ''; + // process file + fileContent = content(fileContent); + if (!fileContent) return fileContent; + + writeFile(workspace, path, fileContent); + filesToFormat.add(path); + + return fileContent; + } catch (e) { + if (e instanceof Error) { + throw new Error(`Unable to process '${path}'. Reason: ${e.message}`); + } + throw e; + } }, execute: async (commandArgs, stdio) => { const { command, args } = resolveCommand(workspace.packageManager, 'execute', commandArgs)!; @@ -580,7 +588,7 @@ async function runAdders({ try { await exec(command, args, { - nodeOptions: { cwd: workspace.cwd, stdio: script.stdio }, + nodeOptions: { cwd: workspace.cwd, stdio }, throwOnError: true }); } catch (error) { From ebe7812b1f91c62073289816e9e1571c06c62e67 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 9 Nov 2024 14:01:11 -0500 Subject: [PATCH 078/126] fix timeout --- packages/adders/_tests/_setup/suite.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index 4820c621..3e6f3ef9 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -98,9 +98,8 @@ async function prepareServer( // start preview server const { url, close } = await startPreview({ cwd, command: previewCommand }); - // default navigation timeout is 30 seconds. When running many tests at once as we are doing - // this is not always enough. Increase it to 60 seconds. - page.setDefaultNavigationTimeout(60_0000); + // increases timeout as 30s is not always enough when running the full suite + page.setDefaultNavigationTimeout(60_000); try { // navigate to the page From ed81a57df6e2ad727be604793089e1cfdca3f150 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 9 Nov 2024 14:31:31 -0500 Subject: [PATCH 079/126] add retries --- packages/adders/vitest.config.ts | 6 +++--- packages/create/test/check.ts | 6 +----- packages/create/vitest.config.ts | 4 +++- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/adders/vitest.config.ts b/packages/adders/vitest.config.ts index d0b04f60..0d571dee 100644 --- a/packages/adders/vitest.config.ts +++ b/packages/adders/vitest.config.ts @@ -7,10 +7,10 @@ export default defineConfig({ test: { name: 'adders', include: ['_tests/**/test.{js,ts}'], + globalSetup: ['_tests/_setup/global.ts'], testTimeout: ONE_MINUTE * 3, hookTimeout: ONE_MINUTE * 3, - maxConcurrency: 10, - globalSetup: ['_tests/_setup/global.ts'], - retry: env.CI ? 3 : 0 + retry: env.CI ? 3 : 0, + pool: 'threads' } }); diff --git a/packages/create/test/check.ts b/packages/create/test/check.ts index 998359f4..ba807aa3 100644 --- a/packages/create/test/check.ts +++ b/packages/create/test/check.ts @@ -41,11 +41,7 @@ for (const template of templates) { const cwd = path.join(test_workspace_dir, `${template}-${types}`); fs.rmSync(cwd, { recursive: true, force: true }); - create(cwd, { - name: `create-svelte-test-${template}-${types}`, - template, - types - }); + create(cwd, { name: `create-svelte-test-${template}-${types}`, template, types }); const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8')); diff --git a/packages/create/vitest.config.ts b/packages/create/vitest.config.ts index 132b334f..f29b5427 100644 --- a/packages/create/vitest.config.ts +++ b/packages/create/vitest.config.ts @@ -1,8 +1,10 @@ +import { env } from 'node:process'; import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { name: 'create', - include: ['test/*.ts'] + include: ['test/*.ts'], + retry: env.CI ? 3 : 0 } }); From a3baf83ac705cfda800394d57de1f2fb44f5850d Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 9 Nov 2024 18:35:00 -0500 Subject: [PATCH 080/126] remove storybook log --- .gitignore | 1 - packages/cli/testing.ts | 11 ++++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index b87fdf1f..193b6ac1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,3 @@ vite.config.js.timestamp-* /packages/create-svelte/template/CHANGELOG.md .test-tmp .test-output -*storybook.log diff --git a/packages/cli/testing.ts b/packages/cli/testing.ts index 1d90e97a..907319a1 100644 --- a/packages/cli/testing.ts +++ b/packages/cli/testing.ts @@ -49,7 +49,16 @@ export async function setup({ // TODO: should probably point this to a specific commit hash (ex: `#1234abcd`) const template = degit(`vitejs/vite/packages/create-vite/${name}`, { force: true }); await template.clone(templatePath); - } else throw new Error(`Unknown project variant: ${variant}`); + + // vite templates have their gitignore file named as `_gitignore` + const gitignorePath = path.resolve(templatePath, '_gitignore'); + if (fs.existsSync(gitignorePath)) { + const fixedPath = path.resolve(templatePath, '.gitignore'); + fs.renameSync(gitignorePath, fixedPath); + } + } else { + throw new Error(`Unknown project variant: ${variant}`); + } } return { templatesDir }; From 987b1e8110b04ba02243a0a59d68fba914537e4d Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 9 Nov 2024 19:22:30 -0500 Subject: [PATCH 081/126] cleanup cli package --- .../tests/setup/global.ts | 2 +- community-adder-template/tests/setup/suite.ts | 2 +- packages/adders/_tests/_setup/global.ts | 2 +- packages/adders/_tests/_setup/suite.ts | 2 +- packages/cli/bin.ts | 2 +- .../{utils => commands/add}/fetch-packages.ts | 2 +- packages/cli/commands/add/index.ts | 16 +- packages/cli/commands/add/preconditions.ts | 66 ++++++ packages/cli/commands/add/utils.ts | 25 ++- packages/cli/commands/add/workspace.ts | 6 +- packages/cli/commands/check.ts | 6 +- packages/cli/commands/create.ts | 13 +- packages/cli/commands/migrate.ts | 2 +- packages/cli/common.ts | 206 ------------------ packages/cli/index.ts | 3 - packages/cli/lib/index.ts | 3 + packages/cli/lib/install.ts | 2 +- packages/cli/{ => lib}/testing.ts | 11 +- packages/cli/package.json | 6 +- packages/cli/tsconfig.json | 2 +- packages/cli/utils/common.ts | 78 +++++++ packages/cli/{ => utils}/env.ts | 0 packages/cli/utils/package-manager.ts | 56 +++++ rollup.config.js | 12 +- 24 files changed, 269 insertions(+), 256 deletions(-) rename packages/cli/{utils => commands/add}/fetch-packages.ts (98%) create mode 100644 packages/cli/commands/add/preconditions.ts delete mode 100644 packages/cli/common.ts delete mode 100644 packages/cli/index.ts create mode 100644 packages/cli/lib/index.ts rename packages/cli/{ => lib}/testing.ts (97%) create mode 100644 packages/cli/utils/common.ts rename packages/cli/{ => utils}/env.ts (100%) create mode 100644 packages/cli/utils/package-manager.ts diff --git a/community-adder-template/tests/setup/global.ts b/community-adder-template/tests/setup/global.ts index 95cc7c8d..9b38192b 100644 --- a/community-adder-template/tests/setup/global.ts +++ b/community-adder-template/tests/setup/global.ts @@ -1,5 +1,5 @@ import { fileURLToPath } from 'node:url'; -import { setup, type ProjectVariant } from 'sv/test'; +import { setup, type ProjectVariant } from 'sv/testing'; import type { GlobalSetupContext } from 'vitest/node'; const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; diff --git a/community-adder-template/tests/setup/suite.ts b/community-adder-template/tests/setup/suite.ts index f9b39256..46f3f8c8 100644 --- a/community-adder-template/tests/setup/suite.ts +++ b/community-adder-template/tests/setup/suite.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import { execSync } from 'node:child_process'; import * as vitest from 'vitest'; import { installAddon, type AddonMap, type OptionMap } from 'sv'; -import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/test'; +import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/testing'; import { chromium, type Browser, type Page } from '@playwright/test'; import { fileURLToPath } from 'node:url'; diff --git a/packages/adders/_tests/_setup/global.ts b/packages/adders/_tests/_setup/global.ts index 3777b671..93b6b955 100644 --- a/packages/adders/_tests/_setup/global.ts +++ b/packages/adders/_tests/_setup/global.ts @@ -1,5 +1,5 @@ import { fileURLToPath } from 'node:url'; -import { setup, type ProjectVariant } from 'sv/test'; +import { setup, type ProjectVariant } from 'sv/testing'; import type { GlobalSetupContext } from 'vitest/node'; const TEST_DIR = fileURLToPath(new URL('../../../../.test-output/adders/', import.meta.url)); diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts index 3e6f3ef9..df151f87 100644 --- a/packages/adders/_tests/_setup/suite.ts +++ b/packages/adders/_tests/_setup/suite.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import { execSync } from 'node:child_process'; import * as vitest from 'vitest'; import { installAddon, type AddonMap, type OptionMap } from 'sv'; -import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/test'; +import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/testing'; import { chromium, type Browser, type Page } from '@playwright/test'; const cwd = vitest.inject('testDir'); diff --git a/packages/cli/bin.ts b/packages/cli/bin.ts index 4a4c8924..838dda5d 100644 --- a/packages/cli/bin.ts +++ b/packages/cli/bin.ts @@ -6,7 +6,7 @@ import { add } from './commands/add/index.ts'; import { create } from './commands/create.ts'; import { migrate } from './commands/migrate.ts'; import { check } from './commands/check.ts'; -import { helpConfig } from './common.ts'; +import { helpConfig } from './utils/common.ts'; program.name(pkg.name).version(pkg.version, '-v, --version').configureHelp(helpConfig); program.addCommand(create).addCommand(add).addCommand(migrate).addCommand(check); diff --git a/packages/cli/utils/fetch-packages.ts b/packages/cli/commands/add/fetch-packages.ts similarity index 98% rename from packages/cli/utils/fetch-packages.ts rename to packages/cli/commands/add/fetch-packages.ts index 9bb3e8ff..588e84a8 100644 --- a/packages/cli/utils/fetch-packages.ts +++ b/packages/cli/commands/add/fetch-packages.ts @@ -7,7 +7,7 @@ import { fileURLToPath } from 'node:url'; import type { AdderWithoutExplicitArgs } from '@sveltejs/cli-core'; // path to the `node_modules` directory of `sv` -const NODE_MODULES = path.join(fileURLToPath(import.meta.url), '..', '..', 'node_modules'); +const NODE_MODULES = fileURLToPath(new URL('../../../node_modules', import.meta.url)); const REGISTRY = 'https://registry.npmjs.org'; export const Directive = { file: 'file:', npm: 'npm:' }; diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 14e0ec05..de05a29b 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -15,11 +15,13 @@ import { getCommunityAdder } from '@sveltejs/adders'; import type { AdderWithoutExplicitArgs, OptionValues } from '@sveltejs/cli-core'; -import * as common from '../../common.ts'; -import { Directive, downloadPackage, getPackageJSON } from '../../utils/fetch-packages.ts'; +import * as common from '../../utils/common.ts'; import { createWorkspace } from './workspace.ts'; -import { getHighlighter, installPackages } from './utils.ts'; import { createOrUpdateFiles } from './processor.ts'; +import { getGlobalPreconditions } from './preconditions.ts'; +import { formatFiles, getHighlighter, installPackages } from './utils.ts'; +import { Directive, downloadPackage, getPackageJSON } from './fetch-packages.ts'; +import { installDependencies, packageManagerPrompt } from '../../utils/package-manager.ts'; const AddersSchema = v.array(v.string()); const AdderOptionFlagsSchema = v.object({ @@ -333,7 +335,7 @@ export async function runAddCommand( const { kit } = createWorkspace({ cwd: options.cwd }); const projectType = kit ? 'kit' : 'svelte'; const adders = selectedAdders.map(({ adder }) => adder); - const { preconditions } = common.getGlobalPreconditions(options.cwd, projectType, adders); + const { preconditions } = getGlobalPreconditions(options.cwd, projectType, adders); const fails: Array<{ name: string; message?: string }> = []; for (const condition of preconditions) { @@ -425,7 +427,7 @@ export async function runAddCommand( // prompt for package manager let packageManager: AgentName | undefined; if (options.install) { - packageManager = await common.packageManagerPrompt(options.cwd); + packageManager = await packageManagerPrompt(options.cwd); } // apply adders @@ -434,7 +436,7 @@ export async function runAddCommand( // install dependencies if (packageManager && options.install) { - await common.installDependencies(packageManager, options.cwd); + await installDependencies(packageManager, options.cwd); } // format modified/created files with prettier (if available) @@ -443,7 +445,7 @@ export async function runAddCommand( const { start, stop } = p.spinner(); start('Formatting modified files'); try { - await common.formatFiles({ packageManager, cwd: options.cwd, paths: filesToFormat }); + await formatFiles({ packageManager, cwd: options.cwd, paths: filesToFormat }); stop('Successfully formatted modified files'); } catch (e) { stop('Failed to format files'); diff --git a/packages/cli/commands/add/preconditions.ts b/packages/cli/commands/add/preconditions.ts new file mode 100644 index 00000000..50f90098 --- /dev/null +++ b/packages/cli/commands/add/preconditions.ts @@ -0,0 +1,66 @@ +import { exec } from 'tinyexec'; +import type { AdderWithoutExplicitArgs, Precondition } from '@sveltejs/cli-core'; + +type PreconditionCheck = { name: string; preconditions: Precondition[] }; +export function getGlobalPreconditions( + cwd: string, + projectType: 'svelte' | 'kit', + adders: AdderWithoutExplicitArgs[] +): PreconditionCheck { + return { + name: 'global checks', + preconditions: [ + { + name: 'clean working directory', + run: async () => { + try { + // If a user has pending git changes the output of the following command will list + // all files that have been added/modified/deleted and thus the output will not be empty. + // In case the output of the command below is an empty text, we can safely assume + // there are no pending changes. If the below command is run outside of a git repository, + // git will exit with a failing exit code, which will trigger the catch statement. + // also see https://remarkablemark.org/blog/2017/10/12/check-git-dirty/#git-status + const { stdout } = await exec('git', ['status', '--short'], { + nodeOptions: { cwd }, + throwOnError: true + }); + + if (stdout) { + return { success: false, message: 'Found modified files' }; + } + + return { success: true, message: undefined }; + } catch { + return { success: true, message: 'Not a git repository' }; + } + } + }, + { + name: 'supported environments', + run: () => { + const addersForInvalidEnvironment = adders.filter((a) => { + const supportedEnvironments = a.environments; + if (projectType === 'kit' && !supportedEnvironments.kit) return true; + if (projectType === 'svelte' && !supportedEnvironments.svelte) return true; + + return false; + }); + + if (addersForInvalidEnvironment.length === 0) { + return { success: true, message: undefined }; + } + + const messages = addersForInvalidEnvironment.map((a) => { + if (projectType === 'kit') { + return `'${a.id}' does not support SvelteKit`; + } else { + return `'${a.id}' requires SvelteKit`; + } + }); + + throw new Error(messages.join('\n')); + } + } + ] + }; +} diff --git a/packages/cli/commands/add/utils.ts b/packages/cli/commands/add/utils.ts index d9a12bdd..55051644 100644 --- a/packages/cli/commands/add/utils.ts +++ b/packages/cli/commands/add/utils.ts @@ -1,8 +1,10 @@ import fs from 'node:fs'; import path from 'node:path'; import pc from 'picocolors'; +import { exec } from 'tinyexec'; import { parseJson } from '@sveltejs/cli-core/parsers'; import type { Adder, Highlighter, Workspace } from '@sveltejs/cli-core'; +import { resolveCommand, type AgentName } from 'package-manager-detector'; export type Package = { name: string; @@ -30,8 +32,21 @@ export function getPackageJson(cwd: string): { return { source: packageText, data: data as Package, generateCode }; } +export async function formatFiles(options: { + packageManager: AgentName; + cwd: string; + paths: string[]; +}): Promise { + const args = ['prettier', '--write', '--ignore-unknown', ...options.paths]; + const cmd = resolveCommand(options.packageManager, 'execute-local', args)!; + await exec(cmd.command, cmd.args, { + nodeOptions: { cwd: options.cwd, stdio: 'pipe' }, + throwOnError: true + }); +} + export function readFile(cwd: string, filePath: string): string { - const fullFilePath = getFilePath(cwd, filePath); + const fullFilePath = path.resolve(cwd, filePath); if (!fileExists(cwd, filePath)) { return ''; @@ -76,7 +91,7 @@ function alphabetizeProperties(obj: Record) { } export function writeFile(workspace: Workspace, filePath: string, content: string): void { - const fullFilePath = getFilePath(workspace.cwd, filePath); + const fullFilePath = path.resolve(workspace.cwd, filePath); const fullDirectoryPath = path.dirname(fullFilePath); if (content && !content.endsWith('\n')) content += '\n'; @@ -89,14 +104,10 @@ export function writeFile(workspace: Workspace, filePath: string, content: } export function fileExists(cwd: string, filePath: string): boolean { - const fullFilePath = getFilePath(cwd, filePath); + const fullFilePath = path.resolve(cwd, filePath); return fs.existsSync(fullFilePath); } -export function getFilePath(cwd: string, fileName: string): string { - return path.join(cwd, fileName); -} - export const commonFilePaths = { packageJson: 'package.json', svelteConfig: 'svelte.config.js', diff --git a/packages/cli/commands/add/workspace.ts b/packages/cli/commands/add/workspace.ts index 6e93d7e5..ac4d396f 100644 --- a/packages/cli/commands/add/workspace.ts +++ b/packages/cli/commands/add/workspace.ts @@ -3,11 +3,11 @@ import path from 'node:path'; import * as find from 'empathic/find'; import { common, object, type AstTypes } from '@sveltejs/cli-core/js'; import { parseScript } from '@sveltejs/cli-core/parsers'; -import { TESTING } from '../../env.ts'; -import { getUserAgent } from '../../common.ts'; -import { commonFilePaths, getPackageJson, readFile } from './utils.ts'; import type { Workspace } from '@sveltejs/cli-core'; import type { AgentName } from 'package-manager-detector'; +import { TESTING } from '../../utils/env.ts'; +import { commonFilePaths, getPackageJson, readFile } from './utils.ts'; +import { getUserAgent } from '../../utils/package-manager.ts'; type CreateWorkspaceOptions = { cwd: string; packageManager?: AgentName }; export function createWorkspace({ cwd, packageManager }: CreateWorkspaceOptions): Workspace { diff --git a/packages/cli/commands/check.ts b/packages/cli/commands/check.ts index eb925103..23797d20 100644 --- a/packages/cli/commands/check.ts +++ b/packages/cli/commands/check.ts @@ -1,10 +1,10 @@ -import { execSync } from 'node:child_process'; import process from 'node:process'; +import { execSync } from 'node:child_process'; import pc from 'picocolors'; -import * as resolve from 'empathic/resolve'; import { Command } from 'commander'; +import * as resolve from 'empathic/resolve'; import { resolveCommand } from 'package-manager-detector/commands'; -import { getUserAgent } from '../common.ts'; +import { getUserAgent } from '../utils/package-manager.ts'; export const check = new Command('check') .description('a CLI for checking your Svelte code') diff --git a/packages/cli/commands/create.ts b/packages/cli/commands/create.ts index 37a5267d..ac3463e1 100644 --- a/packages/cli/commands/create.ts +++ b/packages/cli/commands/create.ts @@ -11,9 +11,14 @@ import { type LanguageType, type TemplateType } from '@sveltejs/create'; -import * as common from '../common.js'; +import * as common from '../utils/common.ts'; import { runAddCommand } from './add/index.ts'; import { detectSync, type AgentName } from 'package-manager-detector'; +import { + getUserAgent, + installDependencies, + packageManagerPrompt +} from '../utils/package-manager.ts'; const langs = ['ts', 'jsdoc'] as const; const langMap: Record = { @@ -58,7 +63,7 @@ export const create = new Command('create') let i = 1; const initialSteps: string[] = []; const relative = path.relative(process.cwd(), directory); - const pm = packageManager ?? detectSync({ cwd })?.name ?? common.getUserAgent() ?? 'npm'; + const pm = packageManager ?? detectSync({ cwd })?.name ?? getUserAgent() ?? 'npm'; if (relative !== '') { const pathHasSpaces = relative.includes(' '); initialSteps.push( @@ -154,8 +159,8 @@ async function createProject(cwd: string, options: Options) { let packageManager: AgentName | undefined | null; let addOnNextSteps: string | undefined; const installDeps = async () => { - packageManager = await common.packageManagerPrompt(projectPath); - if (packageManager) await common.installDependencies(packageManager, projectPath); + packageManager = await packageManagerPrompt(projectPath); + if (packageManager) await installDependencies(packageManager, projectPath); }; if (options.addOns) { diff --git a/packages/cli/commands/migrate.ts b/packages/cli/commands/migrate.ts index 88a5dd7c..b3fecb36 100644 --- a/packages/cli/commands/migrate.ts +++ b/packages/cli/commands/migrate.ts @@ -2,7 +2,7 @@ import { execSync } from 'node:child_process'; import process from 'node:process'; import { Command } from 'commander'; import { resolveCommand } from 'package-manager-detector'; -import { getUserAgent } from '../common.ts'; +import { getUserAgent } from '../utils/package-manager.ts'; export const migrate = new Command('migrate') .description('a CLI for migrating Svelte(Kit) codebases') diff --git a/packages/cli/common.ts b/packages/cli/common.ts deleted file mode 100644 index 13035fd3..00000000 --- a/packages/cli/common.ts +++ /dev/null @@ -1,206 +0,0 @@ -import process from 'node:process'; -import pc from 'picocolors'; -import pkg from './package.json'; -import { exec } from 'tinyexec'; -import * as p from '@sveltejs/clack-prompts'; -import { AGENTS, type AgentName, detectSync } from 'package-manager-detector'; -import { COMMANDS, constructCommand, resolveCommand } from 'package-manager-detector/commands'; -import type { Argument, HelpConfiguration, Option } from 'commander'; -import type { AdderWithoutExplicitArgs, Precondition } from '@sveltejs/cli-core'; - -const NO_PREFIX = '--no-'; -let options: readonly Option[] = []; - -function getLongFlag(flags: string) { - return flags - .split(',') - .map((f) => f.trim()) - .find((f) => f.startsWith('--')); -} - -export const helpConfig: HelpConfiguration = { - argumentDescription: formatDescription, - optionDescription: formatDescription, - visibleOptions(cmd) { - // hack so that we can access existing options in `optionTerm` - options = cmd.options; - - const visible = cmd.options.filter((o) => !o.hidden); - const show: Option[] = []; - // hide any `--no-` flag variants if there's an existing flag of a similar name - // e.g. `--types` and `--no-types` will combine into a single `--[no-]types` flag - for (const option of visible) { - const flag = getLongFlag(option.flags); - if (flag?.startsWith(NO_PREFIX)) { - const stripped = flag.slice(NO_PREFIX.length); - const isNoVariant = visible.some((o) => getLongFlag(o.flags)?.startsWith(`--${stripped}`)); - if (isNoVariant) continue; - } - show.push(option); - } - return show; - }, - optionTerm(option) { - const longFlag = getLongFlag(option.flags); - const flag = longFlag?.split(' ').at(0); - if (!flag || !longFlag) return option.flags; - - // check if there's a `--no-{flag}` variant - const noVariant = `--no-${flag.slice(2)}`; - const hasVariant = options.some((o) => getLongFlag(o.flags) === noVariant); - if (hasVariant) { - return `--[no-]${longFlag.slice(2)}`; - } - - return option.flags; - } -}; - -function formatDescription(arg: Option | Argument): string { - let output = arg.description; - if (arg.defaultValue !== undefined && String(arg.defaultValue)) { - output += pc.dim(` (default: ${JSON.stringify(arg.defaultValue)})`); - } - if (arg.argChoices !== undefined && String(arg.argChoices)) { - output += pc.dim(` (choices: ${arg.argChoices.join(', ')})`); - } - return output; -} - -type MaybePromise = () => Promise | void; - -export async function runCommand(action: MaybePromise): Promise { - try { - p.intro(`Welcome to the Svelte CLI! ${pc.gray(`(v${pkg.version})`)}`); - await action(); - p.outro("You're all set!"); - } catch (e) { - p.cancel('Operation failed.'); - if (e instanceof Error) { - console.error(e.stack ?? e); - } - } -} - -export async function formatFiles(options: { - packageManager: AgentName; - cwd: string; - paths: string[]; -}): Promise { - const args = ['prettier', '--write', '--ignore-unknown', ...options.paths]; - const cmd = resolveCommand(options.packageManager, 'execute-local', args)!; - await exec(cmd.command, cmd.args, { - nodeOptions: { cwd: options.cwd, stdio: 'pipe' }, - throwOnError: true - }); -} - -const agents = AGENTS.filter((agent): agent is AgentName => !agent.includes('@')); -const agentOptions: PackageManagerOptions = agents.map((pm) => ({ value: pm, label: pm })); -agentOptions.unshift({ label: 'None', value: undefined }); - -type PackageManagerOptions = Array<{ value: AgentName | undefined; label: AgentName | 'None' }>; -export async function packageManagerPrompt(cwd: string): Promise { - const detected = detectSync({ cwd }); - const agent = detected?.name ?? getUserAgent(); - - const pm = await p.select({ - message: 'Which package manager do you want to install dependencies with?', - options: agentOptions, - initialValue: agent - }); - if (p.isCancel(pm)) { - p.cancel('Operation cancelled.'); - process.exit(1); - } - - return pm; -} - -export async function installDependencies(agent: AgentName, cwd: string): Promise { - const spinner = p.spinner(); - spinner.start('Installing dependencies...'); - try { - const { command, args } = constructCommand(COMMANDS[agent].install, [])!; - await exec(command, args, { nodeOptions: { cwd }, throwOnError: true }); - - spinner.stop('Successfully installed dependencies'); - } catch (error) { - spinner.stop('Failed to install dependencies', 2); - throw error; - } -} - -export function getUserAgent(): AgentName | undefined { - const userAgent = process.env.npm_config_user_agent; - if (!userAgent) return undefined; - - const pmSpec = userAgent.split(' ')[0]!; - const separatorPos = pmSpec.lastIndexOf('/'); - const name = pmSpec.substring(0, separatorPos) as AgentName; - return AGENTS.includes(name) ? name : undefined; -} - -type PreconditionCheck = { name: string; preconditions: Precondition[] }; -export function getGlobalPreconditions( - cwd: string, - projectType: 'svelte' | 'kit', - adders: AdderWithoutExplicitArgs[] -): PreconditionCheck { - return { - name: 'global checks', - preconditions: [ - { - name: 'clean working directory', - run: async () => { - try { - // If a user has pending git changes the output of the following command will list - // all files that have been added/modified/deleted and thus the output will not be empty. - // In case the output of the command below is an empty text, we can safely assume - // there are no pending changes. If the below command is run outside of a git repository, - // git will exit with a failing exit code, which will trigger the catch statement. - // also see https://remarkablemark.org/blog/2017/10/12/check-git-dirty/#git-status - const { stdout } = await exec('git', ['status', '--short'], { - nodeOptions: { cwd }, - throwOnError: true - }); - - if (stdout) { - return { success: false, message: 'Found modified files' }; - } - - return { success: true, message: undefined }; - } catch { - return { success: true, message: 'Not a git repository' }; - } - } - }, - { - name: 'supported environments', - run: () => { - const addersForInvalidEnvironment = adders.filter((a) => { - const supportedEnvironments = a.environments; - if (projectType === 'kit' && !supportedEnvironments.kit) return true; - if (projectType === 'svelte' && !supportedEnvironments.svelte) return true; - - return false; - }); - - if (addersForInvalidEnvironment.length === 0) { - return { success: true, message: undefined }; - } - - const messages = addersForInvalidEnvironment.map((a) => { - if (projectType === 'kit') { - return `'${a.id}' does not support SvelteKit`; - } else { - return `'${a.id}' requires SvelteKit`; - } - }); - - throw new Error(messages.join('\n')); - } - } - ] - }; -} diff --git a/packages/cli/index.ts b/packages/cli/index.ts deleted file mode 100644 index 31079a3c..00000000 --- a/packages/cli/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { create } from '@sveltejs/create'; -export { installAddon } from './lib/install.ts'; -export type { AddonMap, InstallOptions, OptionMap } from './lib/install.ts'; diff --git a/packages/cli/lib/index.ts b/packages/cli/lib/index.ts new file mode 100644 index 00000000..13aa9292 --- /dev/null +++ b/packages/cli/lib/index.ts @@ -0,0 +1,3 @@ +export { create } from '@sveltejs/create'; +export { installAddon } from './install.ts'; +export type { AddonMap, InstallOptions, OptionMap } from './install.ts'; diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index a36ef024..555da7e8 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -1,9 +1,9 @@ import { exec } from 'tinyexec'; import { resolveCommand } from 'package-manager-detector'; import type { Adder, Workspace, PackageManager, OptionValues, Question } from '@sveltejs/cli-core'; +import { installPackages } from '../commands/add/utils.ts'; import { createWorkspace } from '../commands/add/workspace.ts'; import { createOrUpdateFiles } from '../commands/add/processor.ts'; -import { installPackages } from '../commands/add/utils.ts'; type Addon = Adder; export type InstallOptions = { diff --git a/packages/cli/testing.ts b/packages/cli/lib/testing.ts similarity index 97% rename from packages/cli/testing.ts rename to packages/cli/lib/testing.ts index 907319a1..62857525 100644 --- a/packages/cli/testing.ts +++ b/packages/cli/lib/testing.ts @@ -1,6 +1,6 @@ import fs from 'node:fs'; -import process from 'node:process'; import path from 'node:path'; +import process from 'node:process'; import degit from 'degit'; import { exec } from 'tinyexec'; import { create } from '@sveltejs/create'; @@ -137,13 +137,12 @@ async function terminate(pid: number) { for (let i = children.length - 1; i >= 0; i--) { const child = children[i]; const pid = Number(child.PID); - try { - process.kill(pid); - } catch { - // this can happen if a process has been automatically terminated. - } + kill(pid); } + kill(pid); +} +function kill(pid: number) { try { process.kill(pid); } catch { diff --git a/packages/cli/package.json b/packages/cli/package.json index 4f80ef88..291f8afc 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -21,11 +21,11 @@ "bin": "./dist/bin.js", "exports": { ".": { - "types": "./dist/index.d.ts", + "types": "./dist/lib/index.d.ts", "default": "./dist/index.js" }, - "./test": { - "types": "./dist/testing.d.ts", + "./testing": { + "types": "./dist/lib/testing.d.ts", "default": "./dist/testing.js" } }, diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json index 9249a2e6..54c4c150 100644 --- a/packages/cli/tsconfig.json +++ b/packages/cli/tsconfig.json @@ -6,5 +6,5 @@ "declaration": true }, // we'll only want to enforce `isolatedDeclarations` on the library portion of the CLI - "include": ["index.ts", "testing.ts"] + "include": ["lib/index.ts", "lib/testing.ts"] } diff --git a/packages/cli/utils/common.ts b/packages/cli/utils/common.ts new file mode 100644 index 00000000..bfcbfd16 --- /dev/null +++ b/packages/cli/utils/common.ts @@ -0,0 +1,78 @@ +import pc from 'picocolors'; +import pkg from '../package.json'; +import * as p from '@sveltejs/clack-prompts'; +import type { Argument, HelpConfiguration, Option } from 'commander'; + +const NO_PREFIX = '--no-'; +let options: readonly Option[] = []; + +function getLongFlag(flags: string) { + return flags + .split(',') + .map((f) => f.trim()) + .find((f) => f.startsWith('--')); +} + +export const helpConfig: HelpConfiguration = { + argumentDescription: formatDescription, + optionDescription: formatDescription, + visibleOptions(cmd) { + // hack so that we can access existing options in `optionTerm` + options = cmd.options; + + const visible = cmd.options.filter((o) => !o.hidden); + const show: Option[] = []; + // hide any `--no-` flag variants if there's an existing flag of a similar name + // e.g. `--types` and `--no-types` will combine into a single `--[no-]types` flag + for (const option of visible) { + const flag = getLongFlag(option.flags); + if (flag?.startsWith(NO_PREFIX)) { + const stripped = flag.slice(NO_PREFIX.length); + const isNoVariant = visible.some((o) => getLongFlag(o.flags)?.startsWith(`--${stripped}`)); + if (isNoVariant) continue; + } + show.push(option); + } + return show; + }, + optionTerm(option) { + const longFlag = getLongFlag(option.flags); + const flag = longFlag?.split(' ').at(0); + if (!flag || !longFlag) return option.flags; + + // check if there's a `--no-{flag}` variant + const noVariant = `--no-${flag.slice(2)}`; + const hasVariant = options.some((o) => getLongFlag(o.flags) === noVariant); + if (hasVariant) { + return `--[no-]${longFlag.slice(2)}`; + } + + return option.flags; + } +}; + +function formatDescription(arg: Option | Argument): string { + let output = arg.description; + if (arg.defaultValue !== undefined && String(arg.defaultValue)) { + output += pc.dim(` (default: ${JSON.stringify(arg.defaultValue)})`); + } + if (arg.argChoices !== undefined && String(arg.argChoices)) { + output += pc.dim(` (choices: ${arg.argChoices.join(', ')})`); + } + return output; +} + +type MaybePromise = () => Promise | void; + +export async function runCommand(action: MaybePromise): Promise { + try { + p.intro(`Welcome to the Svelte CLI! ${pc.gray(`(v${pkg.version})`)}`); + await action(); + p.outro("You're all set!"); + } catch (e) { + p.cancel('Operation failed.'); + if (e instanceof Error) { + console.error(e.stack ?? e); + } + } +} diff --git a/packages/cli/env.ts b/packages/cli/utils/env.ts similarity index 100% rename from packages/cli/env.ts rename to packages/cli/utils/env.ts diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts new file mode 100644 index 00000000..c0226505 --- /dev/null +++ b/packages/cli/utils/package-manager.ts @@ -0,0 +1,56 @@ +import process from 'node:process'; +import { exec } from 'tinyexec'; +import * as p from '@sveltejs/clack-prompts'; +import { + AGENTS, + COMMANDS, + constructCommand, + detectSync, + type AgentName +} from 'package-manager-detector'; + +const agents = AGENTS.filter((agent): agent is AgentName => !agent.includes('@')); +const agentOptions: PackageManagerOptions = agents.map((pm) => ({ value: pm, label: pm })); +agentOptions.unshift({ label: 'None', value: undefined }); + +type PackageManagerOptions = Array<{ value: AgentName | undefined; label: AgentName | 'None' }>; +export async function packageManagerPrompt(cwd: string): Promise { + const detected = detectSync({ cwd }); + const agent = detected?.name ?? getUserAgent(); + + const pm = await p.select({ + message: 'Which package manager do you want to install dependencies with?', + options: agentOptions, + initialValue: agent + }); + if (p.isCancel(pm)) { + p.cancel('Operation cancelled.'); + process.exit(1); + } + + return pm; +} + +export async function installDependencies(agent: AgentName, cwd: string): Promise { + const spinner = p.spinner(); + spinner.start('Installing dependencies...'); + try { + const { command, args } = constructCommand(COMMANDS[agent].install, [])!; + await exec(command, args, { nodeOptions: { cwd }, throwOnError: true }); + + spinner.stop('Successfully installed dependencies'); + } catch (error) { + spinner.stop('Failed to install dependencies', 2); + throw error; + } +} + +export function getUserAgent(): AgentName | undefined { + const userAgent = process.env.npm_config_user_agent; + if (!userAgent) return undefined; + + const pmSpec = userAgent.split(' ')[0]!; + const separatorPos = pmSpec.lastIndexOf('/'); + const name = pmSpec.substring(0, separatorPos) as AgentName; + return AGENTS.includes(name) ? name : undefined; +} diff --git a/rollup.config.js b/rollup.config.js index c11e3d9d..6ec4e049 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -35,7 +35,11 @@ function getConfig(project) { parsers: `${projectRoot}/tooling/parsers.ts` }; } else if (project === 'cli') { - inputs = [`${projectRoot}/index.ts`, `${projectRoot}/testing.ts`, `${projectRoot}/bin.ts`]; + inputs = [ + `${projectRoot}/lib/index.ts`, + `${projectRoot}/lib/testing.ts`, + `${projectRoot}/bin.ts` + ]; } else { inputs = [`${projectRoot}/index.ts`]; } @@ -109,9 +113,7 @@ function getConfig(project) { plugins: [ preserveShebangs(), 'exports' in pkg && - dts({ - include: project === 'cli' ? [inputs[0], inputs[1], `${projectRoot}/lib/*`] : undefined - }), + dts({ include: project === 'cli' ? [`${projectRoot}/lib/*`] : undefined }), esbuild(), nodeResolve({ preferBuiltins: true, rootDir: projectRoot }), commonjs(), @@ -119,7 +121,7 @@ function getConfig(project) { dynamicImportVars({ // since we're relying on the usage of standard dynamic imports for community adders, we need to // prevent this plugin from transforming these cases - exclude: ['packages/cli/utils/fetch-packages.ts'] + exclude: ['packages/cli/commands/add/fetch-packages.ts'] }), buildCliTemplatesPlugin, communityAdderIdsPlugin From cc1e27d87eb99f272bbe148baa073aeef513ef05 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sun, 10 Nov 2024 08:38:29 +0100 Subject: [PATCH 082/126] simplify --- community-adder-template/src/index.js | 3 +- packages/cli/commands/add/index.ts | 151 ++++----------------- packages/cli/commands/add/preconditions.ts | 15 +- packages/cli/lib/install.ts | 141 ++++++++++++++----- 4 files changed, 139 insertions(+), 171 deletions(-) diff --git a/community-adder-template/src/index.js b/community-adder-template/src/index.js index ad6b9bc5..a629c68b 100644 --- a/community-adder-template/src/index.js +++ b/community-adder-template/src/index.js @@ -12,12 +12,11 @@ export const options = defineAdderOptions({ export default defineAdder({ id: 'community-addon', - environments: { kit: true, svelte: true }, options, setup: ({ kit, unavailable }) => { if (!kit) unavailable(); }, - run: ({ sv, options }) => { + run: ({ sv, options, typescript }) => { sv.file('adder-template-demo.txt', (content) => { if (options.demo) { return 'This is a text file made by the Community Adder Template demo!'; diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index bb3cb59a..82e8b2db 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -2,11 +2,10 @@ import fs from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import * as v from 'valibot'; -import { exec } from 'tinyexec'; import { Command, Option } from 'commander'; import * as p from '@sveltejs/clack-prompts'; import * as pkg from 'empathic/package'; -import { resolveCommand, type AgentName } from 'package-manager-detector'; +import { type AgentName } from 'package-manager-detector'; import pc from 'picocolors'; import { officialAdders, @@ -14,17 +13,14 @@ import { communityAdderIds, getCommunityAdder } from '@sveltejs/adders'; -import type { - AdderSetupResult, - AdderWithoutExplicitArgs, - OptionValues, - SvApi -} from '@sveltejs/cli-core'; +import type { AdderWithoutExplicitArgs, OptionValues } from '@sveltejs/cli-core'; import * as common from '../../utils/common.ts'; import { createWorkspace } from './workspace.ts'; -import { formatFiles, getHighlighter, installPackages } from './utils.ts'; +import { formatFiles, getHighlighter } from './utils.ts'; import { Directive, downloadPackage, getPackageJSON } from './fetch-packages.ts'; import { installDependencies, packageManagerPrompt } from '../../utils/package-manager.ts'; +import { getGlobalPreconditions } from './preconditions.ts'; +import { type AddonMap, installAddon, setupAddons } from '../../lib/install.ts'; const AddersSchema = v.array(v.string()); const AdderOptionFlagsSchema = v.object({ @@ -275,19 +271,7 @@ export async function runAddCommand( // prepare official adders let workspace = createWorkspace({ cwd: options.cwd }); - const adderSetupResults: Record = {}; - for (const officialAdder of officialAdders) { - const setupResult: AdderSetupResult = { - available: true, - dependsOn: [] - }; - officialAdder.setup?.({ - ...workspace, - dependsOn: (name) => setupResult.dependsOn.push(name), - unavailable: () => (setupResult.available = false) - }); - adderSetupResults[officialAdder.id] = setupResult; - } + const adderSetupResults = setupAddons(officialAdders, options.cwd); // prompt which adders to apply if (selectedAdders.length === 0) { @@ -349,7 +333,7 @@ export async function runAddCommand( const { kit } = createWorkspace({ cwd: options.cwd }); const projectType = kit ? 'kit' : 'svelte'; const adders = selectedAdders.map(({ adder }) => adder); - const { preconditions } = common.getGlobalPreconditions( + const { preconditions } = getGlobalPreconditions( options.cwd, projectType, adders, @@ -450,13 +434,25 @@ export async function runAddCommand( } // apply adders - const filesToFormat = await runAdders({ - cwd: options.cwd, - packageManager, - official, - community, + const adderDetails = Object.keys(official).map((id) => getAdderDetails(id)); + const commDetails = Object.keys(community).map( + (id) => communityDetails.find((a) => a.id === id)! + ); + const details = adderDetails.concat(commDetails); + + // todo simplify + const map: AddonMap = details.reduce((map, x) => { + map[x.id] = x; + return map; + }, {} as AddonMap); + const filesToFormat = await installAddon({ + cwd: workspace.cwd, + packageManager: workspace.packageManager, + addons: map, + options: official, adderSetupResults }); + p.log.success('Successfully setup add-ons'); // install dependencies @@ -513,107 +509,8 @@ export type InstallAdderOptions = { packageManager?: AgentName; official?: AdderOption; community?: AdderOption; - adderSetupResults: Record; }; -/** - * @returns a list of paths of modified files - */ -async function runAdders({ - cwd, - official = {}, - community = {}, - packageManager, - adderSetupResults = {} -}: InstallAdderOptions): Promise { - const adderDetails = Object.keys(official).map((id) => getAdderDetails(id)); - const commDetails = Object.keys(community).map( - (id) => communityDetails.find((a) => a.id === id)! - ); - const details = adderDetails.concat(commDetails); - - // adders might specify that they should be executed after another adder. - // this orders the adders to (ideally) have adders without dependencies run first - // and adders with dependencies runs later on, based on the adders they depend on. - // based on https://stackoverflow.com/a/72030336/16075084 - details.sort((a, b) => { - const aDeps = adderSetupResults[a.id].dependsOn; - const bDeps = adderSetupResults[b.id].dependsOn; - if (!aDeps && !bDeps) return 0; - if (!aDeps) return -1; - if (!bDeps) return 1; - - return aDeps.includes(b.id) ? 1 : bDeps.includes(a.id) ? -1 : 0; - }); - - // apply adders - const filesToFormat = new Set(); - for (const adder of details) { - const adderId = adder.id; - const workspace = createWorkspace({ cwd, packageManager }); - - workspace.options = official[adderId] ?? community[adderId]!; - - // execute adders - const dependencies: Array<{ pkg: string; version: string; dev: boolean }> = []; - const sv: SvApi = { - file: (path, content) => { - try { - const exists = fileExists(workspace.cwd, path); - let fileContent = exists ? readFile(workspace.cwd, path) : ''; - // process file - fileContent = content(fileContent); - if (!fileContent) return fileContent; - - writeFile(workspace, path, fileContent); - filesToFormat.add(path); - - return fileContent; - } catch (e) { - if (e instanceof Error) { - throw new Error(`Unable to process '${path}'. Reason: ${e.message}`); - } - throw e; - } - }, - execute: async (commandArgs, stdio) => { - const { command, args } = resolveCommand(workspace.packageManager, 'execute', commandArgs)!; - const adderPrefix = details.length > 1 ? `${adder.id}: ` : ''; - const executedCommandDisplayName = `${command} ${args.join(' ')}`; - p.log.step( - `${adderPrefix}Running external command ${pc.gray(`(${executedCommandDisplayName})`)}` - ); - - // adding --yes as the first parameter helps avoiding the "Need to install the following packages:" message - if (workspace.packageManager === 'npm') args.unshift('--yes'); - - try { - await exec(command, args, { - nodeOptions: { cwd: workspace.cwd, stdio }, - throwOnError: true - }); - } catch (error) { - const typedError = error as Error; - throw new Error( - `Failed to execute scripts '${executedCommandDisplayName}': ` + typedError.message - ); - } - }, - dependency: (pkg, version) => { - dependencies.push({ pkg, version, dev: false }); - }, - devDependency: (pkg, version) => { - dependencies.push({ pkg, version, dev: true }); - } - }; - await adder.run({ ...workspace, sv }); - - installPackages(dependencies, workspace); - } - - return Array.from(filesToFormat); -} - /** * Dedupes and transforms aliases into their respective adder id */ diff --git a/packages/cli/commands/add/preconditions.ts b/packages/cli/commands/add/preconditions.ts index 50f90098..ce751d32 100644 --- a/packages/cli/commands/add/preconditions.ts +++ b/packages/cli/commands/add/preconditions.ts @@ -1,11 +1,12 @@ import { exec } from 'tinyexec'; -import type { AdderWithoutExplicitArgs, Precondition } from '@sveltejs/cli-core'; +import type { AdderSetupResult, AdderWithoutExplicitArgs, Precondition } from '@sveltejs/cli-core'; type PreconditionCheck = { name: string; preconditions: Precondition[] }; export function getGlobalPreconditions( cwd: string, projectType: 'svelte' | 'kit', - adders: AdderWithoutExplicitArgs[] + adders: AdderWithoutExplicitArgs[], + adderSetupResult: Record ): PreconditionCheck { return { name: 'global checks', @@ -38,13 +39,9 @@ export function getGlobalPreconditions( { name: 'supported environments', run: () => { - const addersForInvalidEnvironment = adders.filter((a) => { - const supportedEnvironments = a.environments; - if (projectType === 'kit' && !supportedEnvironments.kit) return true; - if (projectType === 'svelte' && !supportedEnvironments.svelte) return true; - - return false; - }); + const addersForInvalidEnvironment = adders.filter( + (a) => !adderSetupResult[a.id].available + ); if (addersForInvalidEnvironment.length === 0) { return { success: true, message: undefined }; diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 555da7e8..cd634389 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -1,9 +1,19 @@ import { exec } from 'tinyexec'; import { resolveCommand } from 'package-manager-detector'; -import type { Adder, Workspace, PackageManager, OptionValues, Question } from '@sveltejs/cli-core'; -import { installPackages } from '../commands/add/utils.ts'; +import type { + Adder, + Workspace, + PackageManager, + OptionValues, + Question, + SvApi, + AdderSetupResult, + AdderWithoutExplicitArgs +} from '@sveltejs/cli-core'; +import { fileExists, installPackages, readFile, writeFile } from '../commands/add/utils.ts'; import { createWorkspace } from '../commands/add/workspace.ts'; -import { createOrUpdateFiles } from '../commands/add/processor.ts'; +import * as p from '@sveltejs/clack-prompts'; +import pc from 'picocolors'; type Addon = Adder; export type InstallOptions = { @@ -11,6 +21,7 @@ export type InstallOptions = { addons: Addons; options: OptionMap; packageManager: PackageManager; + adderSetupResults?: Record; }; export type AddonMap = Record; @@ -22,27 +33,55 @@ export async function installAddon({ addons, cwd, options, - packageManager = 'npm' + packageManager = 'npm', + adderSetupResults }: InstallOptions): Promise { const filesToFormat = new Set(); + adderSetupResults ??= setupAddons(Object.values(addons), cwd, packageManager); + const mapped = Object.entries(addons).map(([, addon]) => addon); - const ordered = orderAddons(mapped); + const ordered = orderAddons(mapped, adderSetupResults); for (const addon of ordered) { const workspace = createWorkspace({ cwd, packageManager }); workspace.options = options[addon.id]; - const files = await runAddon(workspace, addon); + const files = await runAddon(workspace, addon, ordered.length > 1); files.forEach((f) => filesToFormat.add(f)); } return Array.from(filesToFormat); } +export function setupAddons( + addons: AdderWithoutExplicitArgs[], + cwd: string, + packageManager?: PackageManager +): Record { + const adderSetupResults: Record = {}; + const workspace = createWorkspace({ cwd, packageManager }); + + for (const addon of addons) { + const setupResult: AdderSetupResult = { + available: true, + dependsOn: [] + }; + addon.setup?.({ + ...workspace, + dependsOn: (name) => setupResult.dependsOn.push(name), + unavailable: () => (setupResult.available = false) + }); + adderSetupResults[addon.id] = setupResult; + } + + return adderSetupResults; +} + async function runAddon( workspace: Workspace, - addon: Adder> + addon: Adder>, + applyMultipleAddons: boolean ): Promise { const files = new Set(); @@ -54,41 +93,77 @@ async function runAddon( } } - await addon.preInstall?.(workspace); - const pkgPath = installPackages(addon, workspace); - files.add(pkgPath); - const changedFiles = createOrUpdateFiles(addon.files, workspace); - changedFiles.forEach((file) => files.add(file)); - await addon.postInstall?.(workspace); - - for (const script of addon.scripts ?? []) { - if (script.condition?.(workspace) === false) continue; - - try { - const { args, command } = resolveCommand(workspace.packageManager, 'execute', script.args)!; + const dependencies: Array<{ pkg: string; version: string; dev: boolean }> = []; + const sv: SvApi = { + file: (path, content) => { + try { + const exists = fileExists(workspace.cwd, path); + let fileContent = exists ? readFile(workspace.cwd, path) : ''; + // process file + fileContent = content(fileContent); + if (!fileContent) return fileContent; + + writeFile(workspace, path, fileContent); + files.add(path); + + return fileContent; + } catch (e) { + if (e instanceof Error) { + throw new Error(`Unable to process '${path}'. Reason: ${e.message}`); + } + throw e; + } + }, + execute: async (commandArgs, stdio) => { + const { command, args } = resolveCommand(workspace.packageManager, 'execute', commandArgs)!; + const adderPrefix = applyMultipleAddons ? `${addon.id}: ` : ''; + const executedCommandDisplayName = `${command} ${args.join(' ')}`; + p.log.step( + `${adderPrefix}Running external command ${pc.gray(`(${executedCommandDisplayName})`)}` + ); + + // adding --yes as the first parameter helps avoiding the "Need to install the following packages:" message if (workspace.packageManager === 'npm') args.unshift('--yes'); - await exec(command, args, { - nodeOptions: { cwd: workspace.cwd, stdio: 'pipe' }, - throwOnError: true - }); - } catch (error) { - const typedError = error as Error; - throw new Error(`Failed to execute scripts '${script.description}': ` + typedError.message); + + try { + await exec(command, args, { + nodeOptions: { cwd: workspace.cwd, stdio }, + throwOnError: true + }); + } catch (error) { + const typedError = error as Error; + throw new Error( + `Failed to execute scripts '${executedCommandDisplayName}': ` + typedError.message + ); + } + }, + dependency: (pkg, version) => { + dependencies.push({ pkg, version, dev: false }); + }, + devDependency: (pkg, version) => { + dependencies.push({ pkg, version, dev: true }); } - } + }; + await addon.run({ ...workspace, sv }); + + const pkgPath = installPackages(dependencies, workspace); + files.add(pkgPath); return Array.from(files); } // sorts them to their execution order -function orderAddons(addons: Addon[]) { +function orderAddons(addons: Addon[], adderSetupResults: Record) { return Array.from(addons).sort((a, b) => { - if (!a.dependsOn && !b.dependsOn) return 0; - if (!a.dependsOn) return -1; - if (!b.dependsOn) return 1; + const aDeps = adderSetupResults[a.id].dependsOn; + const bDeps = adderSetupResults[b.id].dependsOn; + + if (!aDeps && !bDeps) return 0; + if (!aDeps) return -1; + if (!bDeps) return 1; - if (a.dependsOn.includes(b.id)) return 1; - if (b.dependsOn.includes(a.id)) return -1; + if (aDeps.includes(b.id)) return 1; + if (bDeps.includes(a.id)) return -1; return 0; }); From ba117c23efd47afc318edeefedb12fe5511894dc Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sun, 10 Nov 2024 10:32:41 +0100 Subject: [PATCH 083/126] fix lucia tests --- packages/adders/lucia/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 4a12277b..6642ef5a 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -249,7 +249,6 @@ export default defineAdder({ ${ts('', ' * @param {string} userId')} ${ts('', ' */')} export async function createSession(token${ts(': string')}, userId${ts(': string')}) { - const token = generateSessionToken(); const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); const session${ts(': table.Session')} = { id: sessionId, From 2f112780819510b5d92bf0871ea6e0374217bfb5 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sun, 10 Nov 2024 10:56:56 +0100 Subject: [PATCH 084/126] dont print external command output while testing --- packages/cli/lib/install.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index cd634389..6bda29f6 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -14,6 +14,7 @@ import { fileExists, installPackages, readFile, writeFile } from '../commands/ad import { createWorkspace } from '../commands/add/workspace.ts'; import * as p from '@sveltejs/clack-prompts'; import pc from 'picocolors'; +import { TESTING } from '../utils/env.ts'; type Addon = Adder; export type InstallOptions = { @@ -116,11 +117,14 @@ async function runAddon( }, execute: async (commandArgs, stdio) => { const { command, args } = resolveCommand(workspace.packageManager, 'execute', commandArgs)!; + const adderPrefix = applyMultipleAddons ? `${addon.id}: ` : ''; const executedCommandDisplayName = `${command} ${args.join(' ')}`; - p.log.step( - `${adderPrefix}Running external command ${pc.gray(`(${executedCommandDisplayName})`)}` - ); + if (!TESTING) { + p.log.step( + `${adderPrefix}Running external command ${pc.gray(`(${executedCommandDisplayName})`)}` + ); + } // adding --yes as the first parameter helps avoiding the "Need to install the following packages:" message if (workspace.packageManager === 'npm') args.unshift('--yes'); From 8a1a47a8c979e05ae230c9234004ce2b5d341945 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sun, 10 Nov 2024 10:57:07 +0100 Subject: [PATCH 085/126] fix storybook --- packages/adders/storybook/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/adders/storybook/index.ts b/packages/adders/storybook/index.ts index 6d2f9233..1e7600ea 100644 --- a/packages/adders/storybook/index.ts +++ b/packages/adders/storybook/index.ts @@ -4,7 +4,7 @@ export default defineAdder({ id: 'storybook', homepage: 'https://storybook.js.org', options: {}, - run: ({ sv }) => { - sv.execute(['storybook@8.3.6', 'init', '--skip-install', '--no-dev'], 'inherit'); + run: async ({ sv }) => { + await sv.execute(['storybook@8.3.6', 'init', '--skip-install', '--no-dev'], 'inherit'); } }); From 650ede77fc35bee00b4c828315c624a19f0a0c43 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 10 Nov 2024 12:20:25 -0500 Subject: [PATCH 086/126] fixes --- community-adder-template/tests/setup/global.ts | 2 +- packages/adders/vitest.config.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/community-adder-template/tests/setup/global.ts b/community-adder-template/tests/setup/global.ts index 9b38192b..872cd690 100644 --- a/community-adder-template/tests/setup/global.ts +++ b/community-adder-template/tests/setup/global.ts @@ -3,7 +3,7 @@ import { setup, type ProjectVariant } from 'sv/testing'; import type { GlobalSetupContext } from 'vitest/node'; const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; -const TEST_DIR = fileURLToPath(new URL('./.test-output/', import.meta.url)); +const TEST_DIR = fileURLToPath(new URL('../../.test-output/', import.meta.url)); export default async function ({ provide }: GlobalSetupContext) { // global setup (e.g. spin up docker containers) diff --git a/packages/adders/vitest.config.ts b/packages/adders/vitest.config.ts index 0d571dee..9f43ca88 100644 --- a/packages/adders/vitest.config.ts +++ b/packages/adders/vitest.config.ts @@ -10,7 +10,6 @@ export default defineConfig({ globalSetup: ['_tests/_setup/global.ts'], testTimeout: ONE_MINUTE * 3, hookTimeout: ONE_MINUTE * 3, - retry: env.CI ? 3 : 0, - pool: 'threads' + retry: env.CI ? 3 : 0 } }); From 047c549a9cf92834025e7211bdd5309346945c3e Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 10 Nov 2024 13:11:19 -0500 Subject: [PATCH 087/126] format before evaluating test --- .prettierignore | 2 -- .../core/tests/css/common/add-at-rule/input.css | 2 +- .../core/tests/css/common/add-at-rule/output.css | 4 ++-- .../core/tests/css/common/add-comment/input.css | 2 +- .../core/tests/css/common/add-comment/output.css | 2 +- .../core/tests/css/common/add-imports/input.css | 2 +- .../core/tests/css/common/add-imports/output.css | 2 +- packages/core/tests/css/common/add-rule/input.css | 2 +- packages/core/tests/css/common/add-rule/output.css | 7 ++++--- packages/core/tests/css/index.ts | 12 +++++++++--- .../core/tests/html/common/create-div/output.html | 3 ++- .../tests/html/common/create-element/output.html | 3 ++- packages/core/tests/html/index.ts | 12 +++++++++--- .../core/tests/js/arrays/object-array/output.ts | 13 ++++++++----- .../core/tests/js/arrays/string-array/output.ts | 2 +- .../core/tests/js/common/jsdoc-comment/input.ts | 6 +++--- .../core/tests/js/common/jsdoc-comment/output.ts | 6 +++--- .../exports/default-export-with-variable/output.ts | 4 ++-- .../core/tests/js/exports/default-export/output.ts | 4 ++-- .../js/exports/named-export-with-existing/output.ts | 6 +++--- .../core/tests/js/exports/named-export/output.ts | 6 +++--- .../tests/js/functions/arrow-function/output.ts | 6 +++--- .../core/tests/js/functions/function-call/output.ts | 2 +- .../core/tests/js/imports/default-import/output.ts | 2 +- .../core/tests/js/imports/empty-import/output.ts | 2 +- .../tests/js/imports/named-import-merging/input.ts | 2 +- .../tests/js/imports/named-import-merging/output.ts | 2 +- .../core/tests/js/imports/named-import/output.ts | 2 +- .../tests/js/imports/namespaced-import/output.ts | 2 +- packages/core/tests/js/index.ts | 12 +++++++++--- packages/core/tests/js/object/create/output.ts | 6 +++--- .../core/tests/js/object/override-property/input.ts | 8 ++++---- .../tests/js/object/override-property/output.ts | 8 ++++---- packages/core/tests/js/object/property/input.ts | 4 ++-- packages/core/tests/js/object/property/output.ts | 6 +++--- .../core/tests/js/object/remove-property/input.ts | 6 +++--- .../core/tests/js/object/remove-property/output.ts | 2 +- .../core/tests/js/variables/declaration/output.ts | 4 ++-- .../js/variables/type-annotate-declarator/input.ts | 2 +- .../js/variables/type-annotate-declarator/output.ts | 2 +- prettier.config.js | 9 ++++----- 41 files changed, 106 insertions(+), 85 deletions(-) delete mode 100644 .prettierignore diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index ea3293fe..00000000 --- a/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -packages/core/tests/**/input.* -packages/core/tests/**/output.* diff --git a/packages/core/tests/css/common/add-at-rule/input.css b/packages/core/tests/css/common/add-at-rule/input.css index faa4215a..cedf0a6d 100644 --- a/packages/core/tests/css/common/add-at-rule/input.css +++ b/packages/core/tests/css/common/add-at-rule/input.css @@ -1,3 +1,3 @@ .foo { - color: red; + color: red; } diff --git a/packages/core/tests/css/common/add-at-rule/output.css b/packages/core/tests/css/common/add-at-rule/output.css index ae662e2b..e2a2d26f 100644 --- a/packages/core/tests/css/common/add-at-rule/output.css +++ b/packages/core/tests/css/common/add-at-rule/output.css @@ -1,5 +1,5 @@ @tailwind 'lib/path/file.ext'; .foo { - color: red; + color: red; } -@tailwind 'lib/path/file1.ext' +@tailwind 'lib/path/file1.ext'; diff --git a/packages/core/tests/css/common/add-comment/input.css b/packages/core/tests/css/common/add-comment/input.css index faa4215a..cedf0a6d 100644 --- a/packages/core/tests/css/common/add-comment/input.css +++ b/packages/core/tests/css/common/add-comment/input.css @@ -1,3 +1,3 @@ .foo { - color: red; + color: red; } diff --git a/packages/core/tests/css/common/add-comment/output.css b/packages/core/tests/css/common/add-comment/output.css index cc8bc00f..fbb03f63 100644 --- a/packages/core/tests/css/common/add-comment/output.css +++ b/packages/core/tests/css/common/add-comment/output.css @@ -1,4 +1,4 @@ .foo { - color: red; + color: red; } /* foo comment */ diff --git a/packages/core/tests/css/common/add-imports/input.css b/packages/core/tests/css/common/add-imports/input.css index faa4215a..cedf0a6d 100644 --- a/packages/core/tests/css/common/add-imports/input.css +++ b/packages/core/tests/css/common/add-imports/input.css @@ -1,3 +1,3 @@ .foo { - color: red; + color: red; } diff --git a/packages/core/tests/css/common/add-imports/output.css b/packages/core/tests/css/common/add-imports/output.css index e5b67d82..4f96db19 100644 --- a/packages/core/tests/css/common/add-imports/output.css +++ b/packages/core/tests/css/common/add-imports/output.css @@ -1,4 +1,4 @@ @import 'lib/path/file.css'; .foo { - color: red; + color: red; } diff --git a/packages/core/tests/css/common/add-rule/input.css b/packages/core/tests/css/common/add-rule/input.css index faa4215a..cedf0a6d 100644 --- a/packages/core/tests/css/common/add-rule/input.css +++ b/packages/core/tests/css/common/add-rule/input.css @@ -1,3 +1,3 @@ .foo { - color: red; + color: red; } diff --git a/packages/core/tests/css/common/add-rule/output.css b/packages/core/tests/css/common/add-rule/output.css index 5c63305b..c99b655a 100644 --- a/packages/core/tests/css/common/add-rule/output.css +++ b/packages/core/tests/css/common/add-rule/output.css @@ -1,5 +1,6 @@ .foo { - color: red; -}.bar { - color: blue + color: red; +} +.bar { + color: blue; } diff --git a/packages/core/tests/css/index.ts b/packages/core/tests/css/index.ts index 738e1cb8..77a89d83 100644 --- a/packages/core/tests/css/index.ts +++ b/packages/core/tests/css/index.ts @@ -1,12 +1,17 @@ -import { describe, expect, test } from 'vitest'; -import { parseCss, serializeCss } from '@sveltejs/ast-tooling'; import fs from 'node:fs'; import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; +import prettier from 'prettier'; +import { describe, expect, test } from 'vitest'; +import { parseCss, serializeCss } from '@sveltejs/ast-tooling'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); +const prettierConfig = await prettier.resolveConfig(import.meta.url); +if (!prettierConfig) throw new Error('Failed to resolve prettier config'); +prettierConfig.filepath = 'output.css'; + for (const categoryDirectory of categoryDirectories) { describe(categoryDirectory, () => { const testNames = getDirectoryNames(join(baseDir, categoryDirectory)); @@ -23,7 +28,8 @@ for (const categoryDirectory of categoryDirectories) { module.run({ ast }); const output = serializeCss(ast); - await expect(output).toMatchFileSnapshot(`${testDirectoryPath}/output.css`); + const formattedOutput = await prettier.format(output, prettierConfig); + await expect(formattedOutput).toMatchFileSnapshot(`${testDirectoryPath}/output.css`); }); } }); diff --git a/packages/core/tests/html/common/create-div/output.html b/packages/core/tests/html/common/create-div/output.html index f9cce455..d68abe73 100644 --- a/packages/core/tests/html/common/create-div/output.html +++ b/packages/core/tests/html/common/create-div/output.html @@ -1,2 +1,3 @@ -
+
+
diff --git a/packages/core/tests/html/common/create-element/output.html b/packages/core/tests/html/common/create-element/output.html index 351470bd..6a6aa0de 100644 --- a/packages/core/tests/html/common/create-element/output.html +++ b/packages/core/tests/html/common/create-element/output.html @@ -1,2 +1,3 @@ -
+ +
diff --git a/packages/core/tests/html/index.ts b/packages/core/tests/html/index.ts index 6719acd4..dfad1d0d 100644 --- a/packages/core/tests/html/index.ts +++ b/packages/core/tests/html/index.ts @@ -1,12 +1,17 @@ -import { describe, expect, test } from 'vitest'; -import { parseHtml, serializeHtml } from '@sveltejs/ast-tooling'; import fs from 'node:fs'; import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; +import prettier from 'prettier'; +import { describe, expect, test } from 'vitest'; +import { parseHtml, serializeHtml } from '@sveltejs/ast-tooling'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); +const prettierConfig = await prettier.resolveConfig(import.meta.url); +if (!prettierConfig) throw new Error('Failed to resolve prettier config'); +prettierConfig.filepath = 'output.html'; + for (const categoryDirectory of categoryDirectories) { describe(categoryDirectory, () => { const testNames = getDirectoryNames(join(baseDir, categoryDirectory)); @@ -23,7 +28,8 @@ for (const categoryDirectory of categoryDirectories) { module.run({ ast }); const output = serializeHtml(ast); - await expect(output).toMatchFileSnapshot(`${testDirectoryPath}/output.html`); + const formattedOutput = await prettier.format(output, prettierConfig); + await expect(formattedOutput).toMatchFileSnapshot(`${testDirectoryPath}/output.html`); }); } }); diff --git a/packages/core/tests/js/arrays/object-array/output.ts b/packages/core/tests/js/arrays/object-array/output.ts index c47de750..1fa08802 100644 --- a/packages/core/tests/js/arrays/object-array/output.ts +++ b/packages/core/tests/js/arrays/object-array/output.ts @@ -1,5 +1,8 @@ -const array = [{ - test: true -}, { - test2: 'string' -}]; \ No newline at end of file +const array = [ + { + test: true + }, + { + test2: 'string' + } +]; diff --git a/packages/core/tests/js/arrays/string-array/output.ts b/packages/core/tests/js/arrays/string-array/output.ts index 7d00f941..e7618b3e 100644 --- a/packages/core/tests/js/arrays/string-array/output.ts +++ b/packages/core/tests/js/arrays/string-array/output.ts @@ -1 +1 @@ -const array = ['test', 'test2']; \ No newline at end of file +const array = ['test', 'test2']; diff --git a/packages/core/tests/js/common/jsdoc-comment/input.ts b/packages/core/tests/js/common/jsdoc-comment/input.ts index c4a1447a..a3423c81 100644 --- a/packages/core/tests/js/common/jsdoc-comment/input.ts +++ b/packages/core/tests/js/common/jsdoc-comment/input.ts @@ -1,5 +1,5 @@ function switchToLanguage(newLanguage) { - const canonicalPath = i18n.route($page.url.pathname); - const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage); - goto(localisedPath); + const canonicalPath = i18n.route($page.url.pathname); + const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage); + goto(localisedPath); } diff --git a/packages/core/tests/js/common/jsdoc-comment/output.ts b/packages/core/tests/js/common/jsdoc-comment/output.ts index d97338ba..2394044f 100644 --- a/packages/core/tests/js/common/jsdoc-comment/output.ts +++ b/packages/core/tests/js/common/jsdoc-comment/output.ts @@ -2,7 +2,7 @@ * @param {import("$lib/paraglide/runtime").AvailableLanguageTag} newLanguage */ function switchToLanguage(newLanguage) { - const canonicalPath = i18n.route($page.url.pathname); - const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage); - goto(localisedPath); + const canonicalPath = i18n.route($page.url.pathname); + const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage); + goto(localisedPath); } diff --git a/packages/core/tests/js/exports/default-export-with-variable/output.ts b/packages/core/tests/js/exports/default-export-with-variable/output.ts index e3eafc9d..920afac1 100644 --- a/packages/core/tests/js/exports/default-export-with-variable/output.ts +++ b/packages/core/tests/js/exports/default-export-with-variable/output.ts @@ -1,5 +1,5 @@ const object = { - test: 'string' + test: 'string' }; -export default object; \ No newline at end of file +export default object; diff --git a/packages/core/tests/js/exports/default-export/output.ts b/packages/core/tests/js/exports/default-export/output.ts index 76088cc4..d2516b3e 100644 --- a/packages/core/tests/js/exports/default-export/output.ts +++ b/packages/core/tests/js/exports/default-export/output.ts @@ -1,3 +1,3 @@ export default { - test: 'string' -}; \ No newline at end of file + test: 'string' +}; diff --git a/packages/core/tests/js/exports/named-export-with-existing/output.ts b/packages/core/tests/js/exports/named-export-with-existing/output.ts index 9bcf50f5..3cc72fee 100644 --- a/packages/core/tests/js/exports/named-export-with-existing/output.ts +++ b/packages/core/tests/js/exports/named-export-with-existing/output.ts @@ -1,4 +1,4 @@ export const named = { - test: 'string', - test2: "string2" -}; \ No newline at end of file + test: 'string', + test2: 'string2' +}; diff --git a/packages/core/tests/js/exports/named-export/output.ts b/packages/core/tests/js/exports/named-export/output.ts index c8a12a18..fec3056c 100644 --- a/packages/core/tests/js/exports/named-export/output.ts +++ b/packages/core/tests/js/exports/named-export/output.ts @@ -1,7 +1,7 @@ export const variable = { - test: 'string' + test: 'string' }; export const variable2 = { - test2: 'string2' -}; \ No newline at end of file + test2: 'string2' +}; diff --git a/packages/core/tests/js/functions/arrow-function/output.ts b/packages/core/tests/js/functions/arrow-function/output.ts index c74b611e..1dc5293f 100644 --- a/packages/core/tests/js/functions/arrow-function/output.ts +++ b/packages/core/tests/js/functions/arrow-function/output.ts @@ -1,6 +1,6 @@ () => console.log('foo'); () => { - console.log('foo'); - console.log('bar'); -}; \ No newline at end of file + console.log('foo'); + console.log('bar'); +}; diff --git a/packages/core/tests/js/functions/function-call/output.ts b/packages/core/tests/js/functions/function-call/output.ts index 6a886f44..69b852d5 100644 --- a/packages/core/tests/js/functions/function-call/output.ts +++ b/packages/core/tests/js/functions/function-call/output.ts @@ -1,4 +1,4 @@ function foo(bar: string) { console.log(bar); } -foo("bar"); \ No newline at end of file +foo('bar'); diff --git a/packages/core/tests/js/imports/default-import/output.ts b/packages/core/tests/js/imports/default-import/output.ts index 9203d582..0f58f59e 100644 --- a/packages/core/tests/js/imports/default-import/output.ts +++ b/packages/core/tests/js/imports/default-import/output.ts @@ -1 +1 @@ -import MyPackage from 'package'; \ No newline at end of file +import MyPackage from 'package'; diff --git a/packages/core/tests/js/imports/empty-import/output.ts b/packages/core/tests/js/imports/empty-import/output.ts index 47f21090..bf92fd96 100644 --- a/packages/core/tests/js/imports/empty-import/output.ts +++ b/packages/core/tests/js/imports/empty-import/output.ts @@ -1,2 +1,2 @@ import 'package/file.css'; -import './relativ/file.css'; \ No newline at end of file +import './relativ/file.css'; diff --git a/packages/core/tests/js/imports/named-import-merging/input.ts b/packages/core/tests/js/imports/named-import-merging/input.ts index 67f0c3d9..f4d71375 100644 --- a/packages/core/tests/js/imports/named-import-merging/input.ts +++ b/packages/core/tests/js/imports/named-import-merging/input.ts @@ -1 +1 @@ -import { namedOne } from "package"; +import { namedOne } from 'package'; diff --git a/packages/core/tests/js/imports/named-import-merging/output.ts b/packages/core/tests/js/imports/named-import-merging/output.ts index 772a0f86..7e5affa6 100644 --- a/packages/core/tests/js/imports/named-import-merging/output.ts +++ b/packages/core/tests/js/imports/named-import-merging/output.ts @@ -1 +1 @@ -import { namedOne, namedTwo } from "package"; \ No newline at end of file +import { namedOne, namedTwo } from 'package'; diff --git a/packages/core/tests/js/imports/named-import/output.ts b/packages/core/tests/js/imports/named-import/output.ts index 1a3abd90..640312d9 100644 --- a/packages/core/tests/js/imports/named-import/output.ts +++ b/packages/core/tests/js/imports/named-import/output.ts @@ -1,2 +1,2 @@ import { Handle } from '@sveltejs/kit'; -import { namedOne } from 'package'; \ No newline at end of file +import { namedOne } from 'package'; diff --git a/packages/core/tests/js/imports/namespaced-import/output.ts b/packages/core/tests/js/imports/namespaced-import/output.ts index 56eda1b3..89dc72a7 100644 --- a/packages/core/tests/js/imports/namespaced-import/output.ts +++ b/packages/core/tests/js/imports/namespaced-import/output.ts @@ -1,2 +1,2 @@ import * as bar from './some-file'; -import * as foo from 'package'; \ No newline at end of file +import * as foo from 'package'; diff --git a/packages/core/tests/js/index.ts b/packages/core/tests/js/index.ts index fc93e163..8cf489a4 100644 --- a/packages/core/tests/js/index.ts +++ b/packages/core/tests/js/index.ts @@ -1,12 +1,17 @@ -import { describe, expect, test } from 'vitest'; -import { parseScript, serializeScript } from '@sveltejs/ast-tooling'; import fs from 'node:fs'; import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; +import prettier from 'prettier'; +import { describe, expect, test } from 'vitest'; +import { parseScript, serializeScript } from '@sveltejs/ast-tooling'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); +const prettierConfig = await prettier.resolveConfig(import.meta.url); +if (!prettierConfig) throw new Error('Failed to resolve prettier config'); +prettierConfig.filepath = 'output.ts'; + for (const categoryDirectory of categoryDirectories) { describe(categoryDirectory, () => { const testNames = getDirectoryNames(join(baseDir, categoryDirectory)); @@ -23,7 +28,8 @@ for (const categoryDirectory of categoryDirectories) { module.run({ ast }); const output = serializeScript(ast, input); - await expect(output).toMatchFileSnapshot(`${testDirectoryPath}/output.ts`); + const formattedOutput = await prettier.format(output, prettierConfig); + await expect(formattedOutput).toMatchFileSnapshot(`${testDirectoryPath}/output.ts`); }); } }); diff --git a/packages/core/tests/js/object/create/output.ts b/packages/core/tests/js/object/create/output.ts index a31bc6cf..b8a403ca 100644 --- a/packages/core/tests/js/object/create/output.ts +++ b/packages/core/tests/js/object/create/output.ts @@ -1,6 +1,6 @@ const empty = {}; const created = { - foo: 1, - bar: 'string' -}; \ No newline at end of file + foo: 1, + bar: 'string' +}; diff --git a/packages/core/tests/js/object/override-property/input.ts b/packages/core/tests/js/object/override-property/input.ts index 42413f9b..72b9d208 100644 --- a/packages/core/tests/js/object/override-property/input.ts +++ b/packages/core/tests/js/object/override-property/input.ts @@ -1,5 +1,5 @@ const test = { - foo: 1, - bar: 'string', - lorem: true -} + foo: 1, + bar: 'string', + lorem: true +}; diff --git a/packages/core/tests/js/object/override-property/output.ts b/packages/core/tests/js/object/override-property/output.ts index d759f951..0069e775 100644 --- a/packages/core/tests/js/object/override-property/output.ts +++ b/packages/core/tests/js/object/override-property/output.ts @@ -1,5 +1,5 @@ const test = { - foo: 2, - bar: "string2", - lorem: false -} \ No newline at end of file + foo: 2, + bar: 'string2', + lorem: false +}; diff --git a/packages/core/tests/js/object/property/input.ts b/packages/core/tests/js/object/property/input.ts index 2e7612f4..8d0b560b 100644 --- a/packages/core/tests/js/object/property/input.ts +++ b/packages/core/tests/js/object/property/input.ts @@ -1,3 +1,3 @@ const test = { - foo: 1 -} + foo: 1 +}; diff --git a/packages/core/tests/js/object/property/output.ts b/packages/core/tests/js/object/property/output.ts index 022a2a8b..3967f063 100644 --- a/packages/core/tests/js/object/property/output.ts +++ b/packages/core/tests/js/object/property/output.ts @@ -1,4 +1,4 @@ const test = { - foo: 1, - bar: "string" -} \ No newline at end of file + foo: 1, + bar: 'string' +}; diff --git a/packages/core/tests/js/object/remove-property/input.ts b/packages/core/tests/js/object/remove-property/input.ts index 2ff5dd43..3967f063 100644 --- a/packages/core/tests/js/object/remove-property/input.ts +++ b/packages/core/tests/js/object/remove-property/input.ts @@ -1,4 +1,4 @@ const test = { - foo: 1, - bar: 'string' -} + foo: 1, + bar: 'string' +}; diff --git a/packages/core/tests/js/object/remove-property/output.ts b/packages/core/tests/js/object/remove-property/output.ts index e51fe4a1..f3129ed1 100644 --- a/packages/core/tests/js/object/remove-property/output.ts +++ b/packages/core/tests/js/object/remove-property/output.ts @@ -1 +1 @@ -const test = {} +const test = {}; diff --git a/packages/core/tests/js/variables/declaration/output.ts b/packages/core/tests/js/variables/declaration/output.ts index 2863841c..e96c602e 100644 --- a/packages/core/tests/js/variables/declaration/output.ts +++ b/packages/core/tests/js/variables/declaration/output.ts @@ -1,5 +1,5 @@ const testNumber = 2; const testObject = { - foo: 'bar' -}; \ No newline at end of file + foo: 'bar' +}; diff --git a/packages/core/tests/js/variables/type-annotate-declarator/input.ts b/packages/core/tests/js/variables/type-annotate-declarator/input.ts index c064160a..9726ffde 100644 --- a/packages/core/tests/js/variables/type-annotate-declarator/input.ts +++ b/packages/core/tests/js/variables/type-annotate-declarator/input.ts @@ -1 +1 @@ -const str = "123"; +const str = '123'; diff --git a/packages/core/tests/js/variables/type-annotate-declarator/output.ts b/packages/core/tests/js/variables/type-annotate-declarator/output.ts index 82e25885..99232ae3 100644 --- a/packages/core/tests/js/variables/type-annotate-declarator/output.ts +++ b/packages/core/tests/js/variables/type-annotate-declarator/output.ts @@ -1 +1 @@ -const str: string = "123"; +const str: string = '123'; diff --git a/prettier.config.js b/prettier.config.js index 1a3d9c70..e44ee21e 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -44,11 +44,13 @@ const packageSortOrder = [ 'keywords' ]; +/** @type {import("prettier").Config} */ export default { useTabs: true, singleQuote: true, trailingComma: 'none', printWidth: 100, + endOfLine: 'lf', plugins: ['prettier-plugin-packagejson', 'prettier-plugin-svelte'], overrides: [ { @@ -65,10 +67,7 @@ export default { } }, { - files: [ - '**/CHANGELOG.md', - 'packages/migrate/migrations/routes/*/samples.md' - ], + files: ['**/CHANGELOG.md', 'packages/migrate/migrations/routes/*/samples.md'], options: { requirePragma: true } @@ -80,4 +79,4 @@ export default { } } ] -} +}; From fe810a5a265bd8a018567f88aef303faff56d593 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 10 Nov 2024 13:20:25 -0500 Subject: [PATCH 088/126] fix dir path --- packages/cli/commands/add/fetch-packages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/commands/add/fetch-packages.ts b/packages/cli/commands/add/fetch-packages.ts index 588e84a8..d14be995 100644 --- a/packages/cli/commands/add/fetch-packages.ts +++ b/packages/cli/commands/add/fetch-packages.ts @@ -7,7 +7,7 @@ import { fileURLToPath } from 'node:url'; import type { AdderWithoutExplicitArgs } from '@sveltejs/cli-core'; // path to the `node_modules` directory of `sv` -const NODE_MODULES = fileURLToPath(new URL('../../../node_modules', import.meta.url)); +const NODE_MODULES = fileURLToPath(new URL('../node_modules', import.meta.url)); const REGISTRY = 'https://registry.npmjs.org'; export const Directive = { file: 'file:', npm: 'npm:' }; From 25cadb6520a3fdd17ffcfec2aee0c6d116fe163f Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 10 Nov 2024 18:24:16 -0500 Subject: [PATCH 089/126] setup matrix --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 328d0750..78e64e81 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,10 @@ jobs: - run: pnpm build - run: pnpm check test: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 From 88f94737d4119c341c28f8cd24030e40afb1ed04 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 10 Nov 2024 19:11:40 -0500 Subject: [PATCH 090/126] skip running docker containers outside of linux runners --- packages/adders/_tests/drizzle/test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/adders/_tests/drizzle/test.ts b/packages/adders/_tests/drizzle/test.ts index b8efb11b..2a6d7230 100644 --- a/packages/adders/_tests/drizzle/test.ts +++ b/packages/adders/_tests/drizzle/test.ts @@ -1,5 +1,6 @@ import fs from 'node:fs'; import path from 'node:path'; +import process from 'node:process'; import { fileURLToPath } from 'node:url'; import { execSync } from 'node:child_process'; import * as vitest from 'vitest'; @@ -10,7 +11,11 @@ import { pageServer, pageComp } from './fixtures.ts'; const { test, variants, prepareServer } = setupTest({ drizzle }); +// only linux is supported for running docker containers in github runners +const noDocker = process.env.CI && process.platform !== 'linux'; + vitest.beforeAll(() => { + if (noDocker) return; const cwd = path.dirname(fileURLToPath(import.meta.url)); execSync('docker compose up --detach', { cwd, stdio: 'pipe' }); @@ -33,6 +38,7 @@ const testCases = [ test.concurrent.for(testCases)( 'queries database - $name - $variant', async ({ options, variant }, { page, ...ctx }) => { + if (options.docker && noDocker) ctx.skip(); const cwd = await ctx.run(variant, { drizzle: options as any }); const ts = variant === 'kit-ts'; From 9d5b6b20bfdbfc31c23b4652bde24adb62b47a11 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Mon, 11 Nov 2024 16:59:15 +0100 Subject: [PATCH 091/126] print console output? --- packages/cli/lib/install.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 555da7e8..838e911e 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -68,7 +68,7 @@ async function runAddon( const { args, command } = resolveCommand(workspace.packageManager, 'execute', script.args)!; if (workspace.packageManager === 'npm') args.unshift('--yes'); await exec(command, args, { - nodeOptions: { cwd: workspace.cwd, stdio: 'pipe' }, + nodeOptions: { cwd: workspace.cwd, stdio: 'inherit' }, throwOnError: true }); } catch (error) { From 7c69d4e859bb2de2856ddbb72346047bbd02d2cd Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Mon, 11 Nov 2024 17:29:02 +0100 Subject: [PATCH 092/126] fix lint? --- pnpm-lock.yaml | 604 +++++++++++++++---------------------------------- 1 file changed, 184 insertions(+), 420 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bb9ceae1..2e164516 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,13 +31,13 @@ importers: version: link:packages/create '@sveltejs/eslint-config': specifier: ^8.1.0 - version: 8.1.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.13.1(eslint@9.10.0))(eslint-plugin-svelte@2.46.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.3))(typescript@5.6.3) + version: 8.1.0(@stylistic/eslint-plugin-js@2.8.0(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.10.2(eslint@9.10.0))(eslint-plugin-svelte@2.43.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.2))(typescript@5.6.2) '@svitejs/changesets-changelog-github-compact': specifier: ^1.1.0 version: 1.1.0 '@types/node': specifier: ^22.3.0 - version: 22.9.0 + version: 22.5.4 '@vitest/ui': specifier: ^2.1.4 version: 2.1.4(vitest@2.1.4) @@ -61,7 +61,7 @@ importers: version: 4.21.2 rollup-plugin-esbuild: specifier: ^6.1.1 - version: 6.1.1(esbuild@0.24.0)(rollup@4.21.2) + version: 6.1.1(esbuild@0.21.5)(rollup@4.21.2) rollup-plugin-preserve-shebangs: specifier: ^0.2.0 version: 0.2.0(rollup@4.21.2) @@ -73,16 +73,16 @@ importers: version: 5.0.0 typescript: specifier: ^5.6.2 - version: 5.6.3 + version: 5.6.2 typescript-eslint: specifier: ^8.5.0 - version: 8.5.0(eslint@9.10.0)(typescript@5.6.3) + version: 8.5.0(eslint@9.10.0)(typescript@5.6.2) unplugin-isolated-decl: specifier: ^0.6.5 - version: 0.6.5(rollup@4.21.2)(typescript@5.6.3)(webpack-sources@3.2.3) + version: 0.6.5(rollup@4.21.2)(typescript@5.6.2)(webpack-sources@3.2.3) vitest: specifier: ^2.1.4 - version: 2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4) + version: 2.1.4(@types/node@22.5.4)(@vitest/ui@2.1.4) community-adder-template: dependencies: @@ -98,7 +98,7 @@ importers: version: link:../packages/cli vitest: specifier: ^2.1.4 - version: 2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4) + version: 2.1.4(@types/node@22.5.4)(@vitest/ui@2.1.4) packages/adders: dependencies: @@ -128,7 +128,7 @@ importers: version: 9.1.0 postcss: specifier: ^8.4.38 - version: 8.4.47 + version: 8.4.45 recast: specifier: ^0.23.7 version: 0.23.9 @@ -143,7 +143,7 @@ importers: devDependencies: picocolors: specifier: ^1.1.0 - version: 1.1.1 + version: 1.1.0 sisteransi: specifier: ^1.0.5 version: 1.0.5 @@ -161,7 +161,7 @@ importers: version: 1.3.0 picocolors: specifier: ^1.1.0 - version: 1.1.1 + version: 1.1.0 sisteransi: specifier: ^1.0.5 version: 1.0.5 @@ -203,7 +203,7 @@ importers: version: 0.2.2 picocolors: specifier: ^1.1.0 - version: 1.1.1 + version: 1.1.0 ps-tree: specifier: ^1.2.0 version: 1.2.0 @@ -215,7 +215,7 @@ importers: version: 0.3.1 valibot: specifier: ^0.41.0 - version: 0.41.0(typescript@5.6.3) + version: 0.41.0(typescript@5.6.2) packages/core: dependencies: @@ -237,7 +237,7 @@ importers: version: 0.30.12 picocolors: specifier: ^1.1.0 - version: 1.1.1 + version: 1.1.0 packages/create: devDependencies: @@ -279,7 +279,7 @@ importers: version: 24.0.0 typescript: specifier: ^5.3.3 - version: 5.6.3 + version: 5.6.2 zimmerframe: specifier: ^1.1.2 version: 1.1.2 @@ -388,290 +388,146 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.24.0': - resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.24.0': - resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm@0.21.5': resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} cpu: [arm] os: [android] - '@esbuild/android-arm@0.24.0': - resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-x64@0.21.5': resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} cpu: [x64] os: [android] - '@esbuild/android-x64@0.24.0': - resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.24.0': - resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-x64@0.21.5': resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.24.0': - resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.24.0': - resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.24.0': - resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.24.0': - resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm@0.21.5': resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.24.0': - resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-ia32@0.21.5': resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.24.0': - resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-loong64@0.21.5': resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.24.0': - resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-mips64el@0.21.5': resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.24.0': - resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-ppc64@0.21.5': resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.24.0': - resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-riscv64@0.21.5': resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.24.0': - resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-s390x@0.21.5': resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.24.0': - resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-x64@0.21.5': resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.24.0': - resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/netbsd-x64@0.21.5': resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.24.0': - resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.24.0': - resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-x64@0.21.5': resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.24.0': - resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.24.0': - resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.24.0': - resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-ia32@0.21.5': resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.24.0': - resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-x64@0.21.5': resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.24.0': - resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.4.1': - resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + '@eslint-community/regexpp@4.11.0': + resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/config-array@0.18.0': @@ -923,8 +779,8 @@ packages: cpu: [x64] os: [win32] - '@stylistic/eslint-plugin-js@2.10.1': - resolution: {integrity: sha512-IikL/RKy9Sk2UMDUUpqrEcwDeYzUEt6SaL2/UVCFuVQxKACHSgStT0NxXkxZmBOUforaU52FPf2Su07FYH5s5g==} + '@stylistic/eslint-plugin-js@2.8.0': + resolution: {integrity: sha512-/e7pSzVMrwBd6yzSDsKHwax3TS96+pd/xSKzELaTkOuYqUhYfj/becWdfDbFSBGQD7BBBCiiE4L8L2cUfu5h+A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.40.0' @@ -962,8 +818,8 @@ packages: '@types/node@18.19.64': resolution: {integrity: sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==} - '@types/node@22.9.0': - resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==} + '@types/node@22.5.4': + resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==} '@types/prompts@2.4.9': resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} @@ -1084,8 +940,8 @@ packages: peerDependencies: acorn: '>=8.9.0' - acorn@8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} engines: {node: '>=0.4.0'} hasBin: true @@ -1236,7 +1092,7 @@ packages: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} @@ -1366,11 +1222,6 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.24.0: - resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} - engines: {node: '>=18'} - hasBin: true - escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -1393,18 +1244,18 @@ packages: peerDependencies: eslint: '>=8' - eslint-plugin-n@17.13.1: - resolution: {integrity: sha512-97qzhk1z3DdSJNCqT45EslwCu5+LB9GDadSyBItgKUfGsXAmN/aa7LRQ0ZxHffUxUzvgbTPJL27/pE9ZQWHy7A==} + eslint-plugin-n@17.10.2: + resolution: {integrity: sha512-e+s4eAf5NtJaxPhTNu3qMO0Iz40WANS93w9LQgYcvuljgvDmWi/a3rh+OrNyMHeng6aOWGJO0rCg5lH4zi8yTw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.23.0' - eslint-plugin-svelte@2.46.0: - resolution: {integrity: sha512-1A7iEMkzmCZ9/Iz+EAfOGYL8IoIG6zeKEq1SmpxGeM5SXmoQq+ZNnCpXFVJpsxPWYx8jIVGMerQMzX20cqUl0g==} + eslint-plugin-svelte@2.43.0: + resolution: {integrity: sha512-REkxQWvg2pp7QVLxQNa+dJ97xUqRe7Y2JJbSWkHSuszu0VcblZtXkPBPckkivk99y5CdLw4slqfPylL2d/X4jQ==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0-0 || ^9.0.0-0 - svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 + svelte: ^3.37.0 || ^4.0.0 || ^5.0.0-next.191 peerDependenciesMeta: svelte: optional: true @@ -1421,8 +1272,8 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-visitor-keys@4.2.0: - resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint@9.10.0: @@ -1438,8 +1289,8 @@ packages: esm-env@1.0.0: resolution: {integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==} - espree@10.3.0: - resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + espree@10.1.0: + resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} espree@9.6.1: @@ -1571,12 +1422,15 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + get-stdin@9.0.0: resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} engines: {node: '>=12'} - get-tsconfig@4.8.1: - resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + get-tsconfig@4.8.0: + resolution: {integrity: sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==} git-hooks-list@3.1.0: resolution: {integrity: sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==} @@ -1601,8 +1455,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.12.0: - resolution: {integrity: sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==} + globals@15.9.0: + resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==} engines: {node: '>=18'} globalyzer@0.1.0: @@ -1748,8 +1602,8 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} - known-css-properties@0.35.0: - resolution: {integrity: sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==} + known-css-properties@0.34.0: + resolution: {integrity: sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==} levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} @@ -1779,6 +1633,9 @@ packages: lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + loupe@3.1.1: + resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} + loupe@3.1.2: resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} @@ -1944,8 +1801,8 @@ packages: periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -2001,8 +1858,8 @@ packages: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} - postcss@8.4.47: - resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + postcss@8.4.45: + resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -2237,11 +2094,11 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte-eslint-parser@0.43.0: - resolution: {integrity: sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==} + svelte-eslint-parser@0.41.0: + resolution: {integrity: sha512-L6f4hOL+AbgfBIB52Z310pg1d2QjRqm7wy3kI1W6hhdhX5bvu7+f0R6w4ykp5HoDdzq+vGhIJmsisaiJDGmVfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: - svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 + svelte: ^3.37.0 || ^4.0.0 || ^5.0.0-next.191 peerDependenciesMeta: svelte: optional: true @@ -2363,8 +2220,8 @@ packages: typescript: optional: true - typescript@5.6.3: - resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + typescript@5.6.2: + resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==} engines: {node: '>=14.17'} hasBin: true @@ -2421,8 +2278,8 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite@5.4.10: - resolution: {integrity: sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==} + vite@5.4.3: + resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -2612,7 +2469,7 @@ snapshots: mri: 1.2.0 p-limit: 2.3.0 package-manager-detector: 0.2.2 - picocolors: 1.1.1 + picocolors: 1.1.0 resolve-from: 5.0.0 semver: 7.6.3 spawndamnit: 2.0.0 @@ -2636,7 +2493,7 @@ snapshots: dependencies: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 - picocolors: 1.1.1 + picocolors: 1.1.0 semver: 7.6.3 '@changesets/get-github-info@0.5.2': @@ -2667,7 +2524,7 @@ snapshots: '@changesets/logger@0.1.1': dependencies: - picocolors: 1.1.1 + picocolors: 1.1.0 '@changesets/parse@0.4.0': dependencies: @@ -2689,7 +2546,7 @@ snapshots: '@changesets/types': 6.0.0 fs-extra: 7.0.1 p-filter: 2.1.0 - picocolors: 1.1.1 + picocolors: 1.1.0 '@changesets/should-skip-package@0.1.1': dependencies: @@ -2710,150 +2567,78 @@ snapshots: '@esbuild/aix-ppc64@0.21.5': optional: true - '@esbuild/aix-ppc64@0.24.0': - optional: true - '@esbuild/android-arm64@0.21.5': optional: true - '@esbuild/android-arm64@0.24.0': - optional: true - '@esbuild/android-arm@0.21.5': optional: true - '@esbuild/android-arm@0.24.0': - optional: true - '@esbuild/android-x64@0.21.5': optional: true - '@esbuild/android-x64@0.24.0': - optional: true - '@esbuild/darwin-arm64@0.21.5': optional: true - '@esbuild/darwin-arm64@0.24.0': - optional: true - '@esbuild/darwin-x64@0.21.5': optional: true - '@esbuild/darwin-x64@0.24.0': - optional: true - '@esbuild/freebsd-arm64@0.21.5': optional: true - '@esbuild/freebsd-arm64@0.24.0': - optional: true - '@esbuild/freebsd-x64@0.21.5': optional: true - '@esbuild/freebsd-x64@0.24.0': - optional: true - '@esbuild/linux-arm64@0.21.5': optional: true - '@esbuild/linux-arm64@0.24.0': - optional: true - '@esbuild/linux-arm@0.21.5': optional: true - '@esbuild/linux-arm@0.24.0': - optional: true - '@esbuild/linux-ia32@0.21.5': optional: true - '@esbuild/linux-ia32@0.24.0': - optional: true - '@esbuild/linux-loong64@0.21.5': optional: true - '@esbuild/linux-loong64@0.24.0': - optional: true - '@esbuild/linux-mips64el@0.21.5': optional: true - '@esbuild/linux-mips64el@0.24.0': - optional: true - '@esbuild/linux-ppc64@0.21.5': optional: true - '@esbuild/linux-ppc64@0.24.0': - optional: true - '@esbuild/linux-riscv64@0.21.5': optional: true - '@esbuild/linux-riscv64@0.24.0': - optional: true - '@esbuild/linux-s390x@0.21.5': optional: true - '@esbuild/linux-s390x@0.24.0': - optional: true - '@esbuild/linux-x64@0.21.5': optional: true - '@esbuild/linux-x64@0.24.0': - optional: true - '@esbuild/netbsd-x64@0.21.5': optional: true - '@esbuild/netbsd-x64@0.24.0': - optional: true - - '@esbuild/openbsd-arm64@0.24.0': - optional: true - '@esbuild/openbsd-x64@0.21.5': optional: true - '@esbuild/openbsd-x64@0.24.0': - optional: true - '@esbuild/sunos-x64@0.21.5': optional: true - '@esbuild/sunos-x64@0.24.0': - optional: true - '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/win32-arm64@0.24.0': - optional: true - '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/win32-ia32@0.24.0': - optional: true - '@esbuild/win32-x64@0.21.5': optional: true - '@esbuild/win32-x64@0.24.0': - optional: true - - '@eslint-community/eslint-utils@4.4.1(eslint@9.10.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@9.10.0)': dependencies: eslint: 9.10.0 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.1': {} + '@eslint-community/regexpp@4.11.0': {} '@eslint/config-array@0.18.0': dependencies: @@ -2867,7 +2652,7 @@ snapshots: dependencies: ajv: 6.12.6 debug: 4.3.7 - espree: 10.3.0 + espree: 10.1.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.0 @@ -3072,22 +2857,22 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.21.2': optional: true - '@stylistic/eslint-plugin-js@2.10.1(eslint@9.10.0)': + '@stylistic/eslint-plugin-js@2.8.0(eslint@9.10.0)': dependencies: eslint: 9.10.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-visitor-keys: 4.0.0 + espree: 10.1.0 - '@sveltejs/eslint-config@8.1.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.13.1(eslint@9.10.0))(eslint-plugin-svelte@2.46.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.3))(typescript@5.6.3)': + '@sveltejs/eslint-config@8.1.0(@stylistic/eslint-plugin-js@2.8.0(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.10.2(eslint@9.10.0))(eslint-plugin-svelte@2.43.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.2))(typescript@5.6.2)': dependencies: - '@stylistic/eslint-plugin-js': 2.10.1(eslint@9.10.0) + '@stylistic/eslint-plugin-js': 2.8.0(eslint@9.10.0) eslint: 9.10.0 eslint-config-prettier: 9.1.0(eslint@9.10.0) - eslint-plugin-n: 17.13.1(eslint@9.10.0) - eslint-plugin-svelte: 2.46.0(eslint@9.10.0)(svelte@5.0.0) - globals: 15.12.0 - typescript: 5.6.3 - typescript-eslint: 8.5.0(eslint@9.10.0)(typescript@5.6.3) + eslint-plugin-n: 17.10.2(eslint@9.10.0) + eslint-plugin-svelte: 2.43.0(eslint@9.10.0)(svelte@5.0.0) + globals: 15.9.0 + typescript: 5.6.2 + typescript-eslint: 8.5.0(eslint@9.10.0)(typescript@5.6.2) '@svitejs/changesets-changelog-github-compact@1.1.0': dependencies: @@ -3114,13 +2899,13 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/node@22.9.0': + '@types/node@22.5.4': dependencies: undici-types: 6.19.8 '@types/prompts@2.4.9': dependencies: - '@types/node': 22.9.0 + '@types/node': 18.19.64 kleur: 3.0.3 '@types/ps-tree@1.1.6': {} @@ -3131,41 +2916,41 @@ snapshots: '@types/tar-fs@2.0.4': dependencies: - '@types/node': 22.9.0 + '@types/node': 22.5.4 '@types/tar-stream': 3.1.3 '@types/tar-stream@3.1.3': dependencies: - '@types/node': 22.9.0 + '@types/node': 22.5.4 - '@typescript-eslint/eslint-plugin@8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.3))(eslint@9.10.0)(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.2))(eslint@9.10.0)(typescript@5.6.2)': dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.3) + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.2) '@typescript-eslint/scope-manager': 8.5.0 - '@typescript-eslint/type-utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3) - '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3) + '@typescript-eslint/type-utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2) '@typescript-eslint/visitor-keys': 8.5.0 eslint: 9.10.0 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.3.0(typescript@5.6.2) optionalDependencies: - typescript: 5.6.3 + typescript: 5.6.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.3)': + '@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.2)': dependencies: '@typescript-eslint/scope-manager': 8.5.0 '@typescript-eslint/types': 8.5.0 - '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2) '@typescript-eslint/visitor-keys': 8.5.0 debug: 4.3.7 eslint: 9.10.0 optionalDependencies: - typescript: 5.6.3 + typescript: 5.6.2 transitivePeerDependencies: - supports-color @@ -3174,21 +2959,21 @@ snapshots: '@typescript-eslint/types': 8.5.0 '@typescript-eslint/visitor-keys': 8.5.0 - '@typescript-eslint/type-utils@8.5.0(eslint@9.10.0)(typescript@5.6.3)': + '@typescript-eslint/type-utils@8.5.0(eslint@9.10.0)(typescript@5.6.2)': dependencies: - '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.3) - '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2) + '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2) debug: 4.3.7 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.3.0(typescript@5.6.2) optionalDependencies: - typescript: 5.6.3 + typescript: 5.6.2 transitivePeerDependencies: - eslint - supports-color '@typescript-eslint/types@8.5.0': {} - '@typescript-eslint/typescript-estree@8.5.0(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@8.5.0(typescript@5.6.2)': dependencies: '@typescript-eslint/types': 8.5.0 '@typescript-eslint/visitor-keys': 8.5.0 @@ -3197,18 +2982,18 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.3.0(typescript@5.6.2) optionalDependencies: - typescript: 5.6.3 + typescript: 5.6.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.5.0(eslint@9.10.0)(typescript@5.6.3)': + '@typescript-eslint/utils@8.5.0(eslint@9.10.0)(typescript@5.6.2)': dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) '@typescript-eslint/scope-manager': 8.5.0 '@typescript-eslint/types': 8.5.0 - '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2) eslint: 9.10.0 transitivePeerDependencies: - supports-color @@ -3226,13 +3011,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.4(vite@5.4.10(@types/node@22.9.0))': + '@vitest/mocker@2.1.4(vite@5.4.3(@types/node@22.5.4))': dependencies: '@vitest/spy': 2.1.4 estree-walker: 3.0.3 magic-string: 0.30.12 optionalDependencies: - vite: 5.4.10(@types/node@22.9.0) + vite: 5.4.3(@types/node@22.5.4) '@vitest/pretty-format@2.1.4': dependencies: @@ -3262,7 +3047,7 @@ snapshots: sirv: 3.0.0 tinyglobby: 0.2.10 tinyrainbow: 1.2.0 - vitest: 2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4) + vitest: 2.1.4(@types/node@22.5.4)(@vitest/ui@2.1.4) '@vitest/utils@2.1.4': dependencies: @@ -3270,15 +3055,15 @@ snapshots: loupe: 3.1.2 tinyrainbow: 1.2.0 - acorn-jsx@5.3.2(acorn@8.14.0): + acorn-jsx@5.3.2(acorn@8.12.1): dependencies: - acorn: 8.14.0 + acorn: 8.12.1 - acorn-typescript@1.4.13(acorn@8.14.0): + acorn-typescript@1.4.13(acorn@8.12.1): dependencies: - acorn: 8.14.0 + acorn: 8.12.1 - acorn@8.14.0: {} + acorn@8.12.1: {} ajv@6.12.6: dependencies: @@ -3377,7 +3162,7 @@ snapshots: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.2 + loupe: 3.1.1 pathval: 2.0.0 chalk@4.1.2: @@ -3397,7 +3182,7 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 '@types/estree': 1.0.5 - acorn: 8.14.0 + acorn: 8.12.1 estree-walker: 3.0.3 periscopic: 3.1.0 @@ -3536,33 +3321,6 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 - esbuild@0.24.0: - optionalDependencies: - '@esbuild/aix-ppc64': 0.24.0 - '@esbuild/android-arm': 0.24.0 - '@esbuild/android-arm64': 0.24.0 - '@esbuild/android-x64': 0.24.0 - '@esbuild/darwin-arm64': 0.24.0 - '@esbuild/darwin-x64': 0.24.0 - '@esbuild/freebsd-arm64': 0.24.0 - '@esbuild/freebsd-x64': 0.24.0 - '@esbuild/linux-arm': 0.24.0 - '@esbuild/linux-arm64': 0.24.0 - '@esbuild/linux-ia32': 0.24.0 - '@esbuild/linux-loong64': 0.24.0 - '@esbuild/linux-mips64el': 0.24.0 - '@esbuild/linux-ppc64': 0.24.0 - '@esbuild/linux-riscv64': 0.24.0 - '@esbuild/linux-s390x': 0.24.0 - '@esbuild/linux-x64': 0.24.0 - '@esbuild/netbsd-x64': 0.24.0 - '@esbuild/openbsd-arm64': 0.24.0 - '@esbuild/openbsd-x64': 0.24.0 - '@esbuild/sunos-x64': 0.24.0 - '@esbuild/win32-arm64': 0.24.0 - '@esbuild/win32-ia32': 0.24.0 - '@esbuild/win32-x64': 0.24.0 - escape-string-regexp@4.0.0: {} eslint-compat-utils@0.5.1(eslint@9.10.0): @@ -3576,37 +3334,37 @@ snapshots: eslint-plugin-es-x@7.8.0(eslint@9.10.0): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0) - '@eslint-community/regexpp': 4.12.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) + '@eslint-community/regexpp': 4.11.0 eslint: 9.10.0 eslint-compat-utils: 0.5.1(eslint@9.10.0) - eslint-plugin-n@17.13.1(eslint@9.10.0): + eslint-plugin-n@17.10.2(eslint@9.10.0): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) enhanced-resolve: 5.17.1 eslint: 9.10.0 eslint-plugin-es-x: 7.8.0(eslint@9.10.0) - get-tsconfig: 4.8.1 - globals: 15.12.0 + get-tsconfig: 4.8.0 + globals: 15.9.0 ignore: 5.3.2 minimatch: 9.0.5 semver: 7.6.3 - eslint-plugin-svelte@2.46.0(eslint@9.10.0)(svelte@5.0.0): + eslint-plugin-svelte@2.43.0(eslint@9.10.0)(svelte@5.0.0): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) '@jridgewell/sourcemap-codec': 1.5.0 eslint: 9.10.0 eslint-compat-utils: 0.5.1(eslint@9.10.0) esutils: 2.0.3 - known-css-properties: 0.35.0 - postcss: 8.4.47 - postcss-load-config: 3.1.4(postcss@8.4.47) - postcss-safe-parser: 6.0.0(postcss@8.4.47) + known-css-properties: 0.34.0 + postcss: 8.4.45 + postcss-load-config: 3.1.4(postcss@8.4.45) + postcss-safe-parser: 6.0.0(postcss@8.4.45) postcss-selector-parser: 6.1.2 semver: 7.6.3 - svelte-eslint-parser: 0.43.0(svelte@5.0.0) + svelte-eslint-parser: 0.41.0(svelte@5.0.0) optionalDependencies: svelte: 5.0.0 transitivePeerDependencies: @@ -3624,12 +3382,12 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint-visitor-keys@4.2.0: {} + eslint-visitor-keys@4.0.0: {} eslint@9.10.0: dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0) - '@eslint-community/regexpp': 4.12.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) + '@eslint-community/regexpp': 4.11.0 '@eslint/config-array': 0.18.0 '@eslint/eslintrc': 3.1.0 '@eslint/js': 9.10.0 @@ -3643,8 +3401,8 @@ snapshots: debug: 4.3.7 escape-string-regexp: 4.0.0 eslint-scope: 8.0.2 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-visitor-keys: 4.0.0 + espree: 10.1.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -3667,16 +3425,16 @@ snapshots: esm-env@1.0.0: {} - espree@10.3.0: + espree@10.1.0: dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) - eslint-visitor-keys: 4.2.0 + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) + eslint-visitor-keys: 4.0.0 espree@9.6.1: dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} @@ -3802,9 +3560,11 @@ snapshots: function-bind@1.1.2: {} + get-func-name@2.0.2: {} + get-stdin@9.0.0: {} - get-tsconfig@4.8.1: + get-tsconfig@4.8.0: dependencies: resolve-pkg-maps: 1.0.0 @@ -3831,7 +3591,7 @@ snapshots: globals@14.0.0: {} - globals@15.12.0: {} + globals@15.9.0: {} globalyzer@0.1.0: {} @@ -3963,7 +3723,7 @@ snapshots: kleur@4.1.5: {} - known-css-properties@0.35.0: {} + known-css-properties@0.34.0: {} levn@0.4.1: dependencies: @@ -3988,6 +3748,10 @@ snapshots: lodash.startcase@4.4.0: {} + loupe@3.1.1: + dependencies: + get-func-name: 2.0.2 + loupe@3.1.2: {} lru-cache@10.4.3: {} @@ -4137,7 +3901,7 @@ snapshots: estree-walker: 3.0.3 is-reference: 3.0.2 - picocolors@1.1.1: {} + picocolors@1.1.0: {} picomatch@2.3.1: {} @@ -4155,30 +3919,30 @@ snapshots: optionalDependencies: fsevents: 2.3.2 - postcss-load-config@3.1.4(postcss@8.4.47): + postcss-load-config@3.1.4(postcss@8.4.45): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: - postcss: 8.4.47 + postcss: 8.4.45 - postcss-safe-parser@6.0.0(postcss@8.4.47): + postcss-safe-parser@6.0.0(postcss@8.4.45): dependencies: - postcss: 8.4.47 + postcss: 8.4.45 - postcss-scss@4.0.9(postcss@8.4.47): + postcss-scss@4.0.9(postcss@8.4.45): dependencies: - postcss: 8.4.47 + postcss: 8.4.45 postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss@8.4.47: + postcss@8.4.45: dependencies: nanoid: 3.3.7 - picocolors: 1.1.1 + picocolors: 1.1.0 source-map-js: 1.2.1 prelude-ls@1.2.1: {} @@ -4252,13 +4016,13 @@ snapshots: reusify@1.0.4: {} - rollup-plugin-esbuild@6.1.1(esbuild@0.24.0)(rollup@4.21.2): + rollup-plugin-esbuild@6.1.1(esbuild@0.21.5)(rollup@4.21.2): dependencies: '@rollup/pluginutils': 5.1.2(rollup@4.21.2) debug: 4.3.7 es-module-lexer: 1.5.4 - esbuild: 0.24.0 - get-tsconfig: 4.8.1 + esbuild: 0.21.5 + get-tsconfig: 4.8.0 rollup: 4.21.2 transitivePeerDependencies: - supports-color @@ -4416,13 +4180,13 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-eslint-parser@0.43.0(svelte@5.0.0): + svelte-eslint-parser@0.41.0(svelte@5.0.0): dependencies: eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - postcss: 8.4.47 - postcss-scss: 4.0.9(postcss@8.4.47) + postcss: 8.4.45 + postcss-scss: 4.0.9(postcss@8.4.45) optionalDependencies: svelte: 5.0.0 @@ -4432,7 +4196,7 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 '@types/estree': 1.0.5 - acorn: 8.14.0 + acorn: 8.12.1 aria-query: 5.3.2 axobject-query: 4.1.0 code-red: 1.0.4 @@ -4448,8 +4212,8 @@ snapshots: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 '@types/estree': 1.0.5 - acorn: 8.14.0 - acorn-typescript: 1.4.13(acorn@8.14.0) + acorn: 8.12.1 + acorn-typescript: 1.4.13(acorn@8.12.1) aria-query: 5.3.2 axobject-query: 4.1.0 esm-env: 1.0.0 @@ -4534,9 +4298,9 @@ snapshots: tr46@0.0.3: {} - ts-api-utils@1.3.0(typescript@5.6.3): + ts-api-utils@1.3.0(typescript@5.6.2): dependencies: - typescript: 5.6.3 + typescript: 5.6.2 ts-interface-checker@0.1.13: {} @@ -4551,18 +4315,18 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.3): + typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.3))(eslint@9.10.0)(typescript@5.6.3) - '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.3) - '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3) + '@typescript-eslint/eslint-plugin': 8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.2))(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2) optionalDependencies: - typescript: 5.6.3 + typescript: 5.6.2 transitivePeerDependencies: - eslint - supports-color - typescript@5.6.3: {} + typescript@5.6.2: {} undici-types@5.26.5: {} @@ -4570,21 +4334,21 @@ snapshots: universalify@0.1.2: {} - unplugin-isolated-decl@0.6.5(rollup@4.21.2)(typescript@5.6.3)(webpack-sources@3.2.3): + unplugin-isolated-decl@0.6.5(rollup@4.21.2)(typescript@5.6.2)(webpack-sources@3.2.3): dependencies: '@rollup/pluginutils': 5.1.2(rollup@4.21.2) magic-string: 0.30.12 oxc-parser: 0.30.3 unplugin: 1.14.1(webpack-sources@3.2.3) optionalDependencies: - typescript: 5.6.3 + typescript: 5.6.2 transitivePeerDependencies: - rollup - webpack-sources unplugin@1.14.1(webpack-sources@3.2.3): dependencies: - acorn: 8.14.0 + acorn: 8.12.1 webpack-virtual-modules: 0.6.2 optionalDependencies: webpack-sources: 3.2.3 @@ -4595,16 +4359,16 @@ snapshots: util-deprecate@1.0.2: {} - valibot@0.41.0(typescript@5.6.3): + valibot@0.41.0(typescript@5.6.2): optionalDependencies: - typescript: 5.6.3 + typescript: 5.6.2 - vite-node@2.1.4(@types/node@22.9.0): + vite-node@2.1.4(@types/node@22.5.4): dependencies: cac: 6.7.14 debug: 4.3.7 pathe: 1.1.2 - vite: 5.4.10(@types/node@22.9.0) + vite: 5.4.3(@types/node@22.5.4) transitivePeerDependencies: - '@types/node' - less @@ -4616,19 +4380,19 @@ snapshots: - supports-color - terser - vite@5.4.10(@types/node@22.9.0): + vite@5.4.3(@types/node@22.5.4): dependencies: esbuild: 0.21.5 - postcss: 8.4.47 + postcss: 8.4.45 rollup: 4.21.2 optionalDependencies: - '@types/node': 22.9.0 + '@types/node': 22.5.4 fsevents: 2.3.3 - vitest@2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4): + vitest@2.1.4(@types/node@22.5.4)(@vitest/ui@2.1.4): dependencies: '@vitest/expect': 2.1.4 - '@vitest/mocker': 2.1.4(vite@5.4.10(@types/node@22.9.0)) + '@vitest/mocker': 2.1.4(vite@5.4.3(@types/node@22.5.4)) '@vitest/pretty-format': 2.1.4 '@vitest/runner': 2.1.4 '@vitest/snapshot': 2.1.4 @@ -4644,11 +4408,11 @@ snapshots: tinyexec: 0.3.1 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.10(@types/node@22.9.0) - vite-node: 2.1.4(@types/node@22.9.0) + vite: 5.4.3(@types/node@22.5.4) + vite-node: 2.1.4(@types/node@22.5.4) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.9.0 + '@types/node': 22.5.4 '@vitest/ui': 2.1.4(vitest@2.1.4) transitivePeerDependencies: - less From ef2df6ec003f342814ac240053748b292a20968a Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Mon, 11 Nov 2024 17:45:22 +0100 Subject: [PATCH 093/126] force `npm` for storybook? --- packages/cli/lib/install.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 838e911e..7d970fce 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -65,7 +65,7 @@ async function runAddon( if (script.condition?.(workspace) === false) continue; try { - const { args, command } = resolveCommand(workspace.packageManager, 'execute', script.args)!; + const { args, command } = resolveCommand('npm', 'execute', script.args)!; if (workspace.packageManager === 'npm') args.unshift('--yes'); await exec(command, args, { nodeOptions: { cwd: workspace.cwd, stdio: 'inherit' }, From c3aa2fcebbe61e8b696a6126ab913ae4eeb74a4b Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Mon, 11 Nov 2024 17:53:43 +0100 Subject: [PATCH 094/126] Revert "force `npm` for storybook?" This reverts commit ef2df6ec003f342814ac240053748b292a20968a. --- packages/cli/lib/install.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 7d970fce..838e911e 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -65,7 +65,7 @@ async function runAddon( if (script.condition?.(workspace) === false) continue; try { - const { args, command } = resolveCommand('npm', 'execute', script.args)!; + const { args, command } = resolveCommand(workspace.packageManager, 'execute', script.args)!; if (workspace.packageManager === 'npm') args.unshift('--yes'); await exec(command, args, { nodeOptions: { cwd: workspace.cwd, stdio: 'inherit' }, From 1c095d614d0484710408a8605b54b1d0be145cc1 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Mon, 11 Nov 2024 18:03:13 +0100 Subject: [PATCH 095/126] try latest --- packages/adders/storybook/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adders/storybook/index.ts b/packages/adders/storybook/index.ts index 20fdc5e8..9a76cbef 100644 --- a/packages/adders/storybook/index.ts +++ b/packages/adders/storybook/index.ts @@ -9,7 +9,7 @@ export default defineAdder({ scripts: [ { description: 'applies storybook', - args: ['storybook@8.3.6', 'init', '--skip-install', '--no-dev'], + args: ['storybook@latest', 'init', '--skip-install', '--no-dev'], stdio: 'inherit' } ], From 57ab58efd12e386a23e796140c6ca1e7a15d13d4 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Mon, 11 Nov 2024 18:08:59 +0100 Subject: [PATCH 096/126] Revert "try latest" This reverts commit 1c095d614d0484710408a8605b54b1d0be145cc1. --- packages/adders/storybook/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adders/storybook/index.ts b/packages/adders/storybook/index.ts index 9a76cbef..20fdc5e8 100644 --- a/packages/adders/storybook/index.ts +++ b/packages/adders/storybook/index.ts @@ -9,7 +9,7 @@ export default defineAdder({ scripts: [ { description: 'applies storybook', - args: ['storybook@latest', 'init', '--skip-install', '--no-dev'], + args: ['storybook@8.3.6', 'init', '--skip-install', '--no-dev'], stdio: 'inherit' } ], From 88bf2ec9a0b81d502c1b19443b5eceb8f9c0c188 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Mon, 11 Nov 2024 18:09:06 +0100 Subject: [PATCH 097/126] Revert "print console output?" This reverts commit 9d5b6b20bfdbfc31c23b4652bde24adb62b47a11. --- packages/cli/lib/install.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 838e911e..555da7e8 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -68,7 +68,7 @@ async function runAddon( const { args, command } = resolveCommand(workspace.packageManager, 'execute', script.args)!; if (workspace.packageManager === 'npm') args.unshift('--yes'); await exec(command, args, { - nodeOptions: { cwd: workspace.cwd, stdio: 'inherit' }, + nodeOptions: { cwd: workspace.cwd, stdio: 'pipe' }, throwOnError: true }); } catch (error) { From fc72e9a0800b020bf0361520f9649b878bed63b0 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Mon, 11 Nov 2024 18:31:29 +0100 Subject: [PATCH 098/126] skip runnung storybook tests in ci on windows --- packages/adders/_tests/storybook/test.ts | 32 ++++++++++++++---------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index 6093fc53..4fdc82a4 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -1,3 +1,4 @@ +import process from 'node:process'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import storybook from '../../storybook/index.ts'; @@ -5,18 +6,23 @@ import storybook from '../../storybook/index.ts'; const { test, variants, prepareServer } = setupTest({ storybook }); let port = 6006; -test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { storybook: {} }); - const { close } = await prepareServer({ - cwd, - page, - previewCommand: `pnpm storybook -p ${++port} --ci`, - buildCommand: '' - }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); +const skip = process.env.CI && process.platform === 'win32'; +test.skipIf(skip).concurrent.for(variants)( + 'storybook loaded - %s', + async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { storybook: {} }); - expect(await page.$('main .sb-bar')).toBeTruthy(); - expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); -}); + const { close } = await prepareServer({ + cwd, + page, + previewCommand: `pnpm storybook -p ${++port} --ci`, + buildCommand: '' + }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); + + expect(await page.$('main .sb-bar')).toBeTruthy(); + expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); + } +); From 8fd78532a575e43970bd3016efb76f415c110761 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Tue, 12 Nov 2024 17:48:06 +0100 Subject: [PATCH 099/126] improve --- packages/cli/commands/add/index.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 82e8b2db..34708a9d 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -92,10 +92,7 @@ for (const option of addersOptions) { add.addOption(option); } -type SelectedAdder = { - type: 'official' | 'community'; - adder: AdderWithoutExplicitArgs; -}; +type SelectedAdder = { type: 'official' | 'community'; adder: AdderWithoutExplicitArgs }; export async function runAddCommand( options: Options, selectedAdderIds: string[] @@ -316,6 +313,7 @@ export async function runAddCommand( for (const depId of filteredDependents) { const dependent = officialAdders.find((a) => a.id === depId) as AdderWithoutExplicitArgs; + // prompt to install the dependent const install = await p.confirm({ message: `The ${pc.bold(pc.cyan(adder.id))} add-on requires ${pc.bold(pc.cyan(depId))} to also be setup. ${pc.green('Include it?')}` }); @@ -440,15 +438,14 @@ export async function runAddCommand( ); const details = adderDetails.concat(commDetails); - // todo simplify - const map: AddonMap = details.reduce((map, x) => { + const addonMap = details.reduce((map, x) => { map[x.id] = x; return map; }, {} as AddonMap); const filesToFormat = await installAddon({ cwd: workspace.cwd, packageManager: workspace.packageManager, - addons: map, + addons: addonMap, options: official, adderSetupResults }); From 3834a7a316383da813b4e06d50fa32c94730b333 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:20:45 -0500 Subject: [PATCH 100/126] missing filename --- packages/adders/eslint/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adders/eslint/index.ts b/packages/adders/eslint/index.ts index b5a2257b..7398b107 100644 --- a/packages/adders/eslint/index.ts +++ b/packages/adders/eslint/index.ts @@ -131,7 +131,7 @@ export default defineAdder({ }); if (prettierInstalled) { - sv.file('', addEslintConfigPrettier); + sv.file('eslint.config.js', addEslintConfigPrettier); } } }); From 8569b2741b651ee66a21303e916e61e6df135ab1 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:04:24 -0500 Subject: [PATCH 101/126] enhance tests --- packages/adders/_tests/all-addons/test.ts | 29 +++++++++++++++++++++++ packages/adders/_tests/eslint/test.ts | 12 +++++++++- packages/adders/_tests/prettier/test.ts | 12 +++++++++- 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 packages/adders/_tests/all-addons/test.ts diff --git a/packages/adders/_tests/all-addons/test.ts b/packages/adders/_tests/all-addons/test.ts new file mode 100644 index 00000000..99b76d26 --- /dev/null +++ b/packages/adders/_tests/all-addons/test.ts @@ -0,0 +1,29 @@ +import { expect } from '@playwright/test'; +import { setupTest } from '../_setup/suite.ts'; +import { officialAdders } from '../../index.ts'; + +const addons = officialAdders.reduce((addonMap, addon) => { + return (addonMap[addon.id] = addon); +}, {} as any); + +const defaultOptions = officialAdders.reduce((options, addon) => { + options[addon.id] = {}; + for (const [id, question] of Object.entries(addon.options)) { + if (question.condition?.(options[addon.id]) !== false) { + options[addon.id][id] ??= question.default; + } + } + return options; +}, {} as any); + +const { test, variants, prepareServer } = setupTest({ addons }); + +test.concurrent.for(variants)('run all addons - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, defaultOptions); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); + + expect(true).toBe(true); +}); diff --git a/packages/adders/_tests/eslint/test.ts b/packages/adders/_tests/eslint/test.ts index 6a8d3e20..9ca06c5c 100644 --- a/packages/adders/_tests/eslint/test.ts +++ b/packages/adders/_tests/eslint/test.ts @@ -1,3 +1,6 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { execSync } from 'node:child_process'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import eslint from '../../eslint/index.ts'; @@ -11,5 +14,12 @@ test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => // kill server process when we're done ctx.onTestFinished(async () => await close()); - expect(true).toBe(true); + const unlintedFile = 'let foo = "";\nif (Boolean(foo)) {\n//\n}'; + fs.writeFileSync(path.resolve(cwd, 'foo.js'), unlintedFile, 'utf8'); + + expect(() => execSync('pnpm lint', { cwd, stdio: 'pipe' })).toThrowError(); + + expect(() => execSync('pnpm eslint --fix .', { cwd, stdio: 'pipe' })).not.toThrowError(); + + expect(() => execSync('pnpm lint', { cwd, stdio: 'pipe' })).not.toThrowError(); }); diff --git a/packages/adders/_tests/prettier/test.ts b/packages/adders/_tests/prettier/test.ts index 1b3f2992..87f2552f 100644 --- a/packages/adders/_tests/prettier/test.ts +++ b/packages/adders/_tests/prettier/test.ts @@ -1,3 +1,6 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { execSync } from 'node:child_process'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import prettier from '../../prettier/index.ts'; @@ -11,5 +14,12 @@ test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => // kill server process when we're done ctx.onTestFinished(async () => await close()); - expect(true).toBe(true); + const unformattedFile = 'const foo = "bar"'; + fs.writeFileSync(path.resolve(cwd, 'foo.js'), unformattedFile, 'utf8'); + + expect(() => execSync('pnpm lint', { cwd, stdio: 'pipe' })).toThrowError(); + + expect(() => execSync('pnpm format', { cwd, stdio: 'pipe' })).not.toThrowError(); + + expect(() => execSync('pnpm lint', { cwd, stdio: 'pipe' })).not.toThrowError(); }); From 1c964fec767e70d531178d662198bdf1a6bf25d1 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:06:25 -0500 Subject: [PATCH 102/126] pipe stdio during tests --- packages/cli/lib/install.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 6bda29f6..5cd3b60b 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -131,7 +131,7 @@ async function runAddon( try { await exec(command, args, { - nodeOptions: { cwd: workspace.cwd, stdio }, + nodeOptions: { cwd: workspace.cwd, stdio: TESTING ? 'pipe' : stdio }, throwOnError: true }); } catch (error) { From 715eff0d9fe99c50ee0bea23bfeaa54dcba243cc Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:10:38 -0500 Subject: [PATCH 103/126] skip storybook --- packages/adders/_tests/all-addons/test.ts | 3 +++ packages/adders/_tests/storybook/test.ts | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/adders/_tests/all-addons/test.ts b/packages/adders/_tests/all-addons/test.ts index 99b76d26..f70928cf 100644 --- a/packages/adders/_tests/all-addons/test.ts +++ b/packages/adders/_tests/all-addons/test.ts @@ -1,8 +1,11 @@ +import process from 'node:process'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import { officialAdders } from '../../index.ts'; +const windowsCI = process.env.CI && process.platform === 'win32'; const addons = officialAdders.reduce((addonMap, addon) => { + if (addon.id === 'storybook' && windowsCI) return addonMap; return (addonMap[addon.id] = addon); }, {} as any); diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index 4fdc82a4..67afa255 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -7,8 +7,8 @@ const { test, variants, prepareServer } = setupTest({ storybook }); let port = 6006; -const skip = process.env.CI && process.platform === 'win32'; -test.skipIf(skip).concurrent.for(variants)( +const windowsCI = process.env.CI && process.platform === 'win32'; +test.skipIf(windowsCI).concurrent.for(variants)( 'storybook loaded - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { storybook: {} }); From 8a3ee4addafef33e6661199d73f22047b31b15cd Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:55:26 -0500 Subject: [PATCH 104/126] fixes --- packages/adders/_tests/all-addons/test.ts | 3 ++- packages/adders/drizzle/index.ts | 2 +- packages/cli/commands/add/index.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/adders/_tests/all-addons/test.ts b/packages/adders/_tests/all-addons/test.ts index f70928cf..b403a75c 100644 --- a/packages/adders/_tests/all-addons/test.ts +++ b/packages/adders/_tests/all-addons/test.ts @@ -6,7 +6,8 @@ import { officialAdders } from '../../index.ts'; const windowsCI = process.env.CI && process.platform === 'win32'; const addons = officialAdders.reduce((addonMap, addon) => { if (addon.id === 'storybook' && windowsCI) return addonMap; - return (addonMap[addon.id] = addon); + addonMap[addon.id] = addon; + return addonMap; }, {} as any); const defaultOptions = officialAdders.reduce((options, addon) => { diff --git a/packages/adders/drizzle/index.ts b/packages/adders/drizzle/index.ts index 229eaf9a..433545d7 100644 --- a/packages/adders/drizzle/index.ts +++ b/packages/adders/drizzle/index.ts @@ -8,7 +8,7 @@ const PORTS = { sqlite: '' } as const; -export const options = defineAdderOptions({ +const options = defineAdderOptions({ database: { question: 'Which database would you like to use?', type: 'select', diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 34708a9d..8635d15e 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -5,7 +5,7 @@ import * as v from 'valibot'; import { Command, Option } from 'commander'; import * as p from '@sveltejs/clack-prompts'; import * as pkg from 'empathic/package'; -import { type AgentName } from 'package-manager-detector'; +import type { AgentName } from 'package-manager-detector'; import pc from 'picocolors'; import { officialAdders, From a2e7b839782a7cffd1af6ccf56b3f0482f1930d6 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:12:24 -0500 Subject: [PATCH 105/126] fix test --- packages/adders/_tests/all-addons/test.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/adders/_tests/all-addons/test.ts b/packages/adders/_tests/all-addons/test.ts index b403a75c..8ed5cc83 100644 --- a/packages/adders/_tests/all-addons/test.ts +++ b/packages/adders/_tests/all-addons/test.ts @@ -2,27 +2,31 @@ import process from 'node:process'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import { officialAdders } from '../../index.ts'; +import type { AddonMap, OptionMap } from 'sv'; const windowsCI = process.env.CI && process.platform === 'win32'; -const addons = officialAdders.reduce((addonMap, addon) => { +const addons = officialAdders.reduce((addonMap, addon) => { if (addon.id === 'storybook' && windowsCI) return addonMap; addonMap[addon.id] = addon; return addonMap; -}, {} as any); +}, {}); -const defaultOptions = officialAdders.reduce((options, addon) => { +const defaultOptions = officialAdders.reduce>((options, addon) => { options[addon.id] = {}; + // TODO: we shouldn't have to apply defaults here + // applies defaults for (const [id, question] of Object.entries(addon.options)) { if (question.condition?.(options[addon.id]) !== false) { options[addon.id][id] ??= question.default; } } return options; -}, {} as any); +}, {}); -const { test, variants, prepareServer } = setupTest({ addons }); +const { test, variants, prepareServer } = setupTest(addons); -test.concurrent.for(variants)('run all addons - %s', async (variant, { page, ...ctx }) => { +const kitOnly = variants.filter((v) => v.startsWith('kit')); +test.concurrent.for(kitOnly)('run all addons - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, defaultOptions); const { close } = await prepareServer({ cwd, page }); From 2588ab283e183927b57a82fd0678a9fd28515df4 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:41:54 -0500 Subject: [PATCH 106/126] fix: apply defaults to unspecified options --- packages/adders/_tests/all-addons/test.ts | 7 ------- packages/cli/lib/install.ts | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/adders/_tests/all-addons/test.ts b/packages/adders/_tests/all-addons/test.ts index 8ed5cc83..934b3da1 100644 --- a/packages/adders/_tests/all-addons/test.ts +++ b/packages/adders/_tests/all-addons/test.ts @@ -13,13 +13,6 @@ const addons = officialAdders.reduce((addonMap, addon) => { const defaultOptions = officialAdders.reduce>((options, addon) => { options[addon.id] = {}; - // TODO: we shouldn't have to apply defaults here - // applies defaults - for (const [id, question] of Object.entries(addon.options)) { - if (question.condition?.(options[addon.id]) !== false) { - options[addon.id][id] ??= question.default; - } - } return options; }, {}); diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 5cd3b60b..4b31a67f 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -87,10 +87,10 @@ async function runAddon( const files = new Set(); // apply default adder options - for (const [, question] of Object.entries(addon.options)) { + for (const [id, question] of Object.entries(addon.options)) { // we'll only apply defaults to options that don't explicitly fail their conditions if (question.condition?.(workspace.options) !== false) { - workspace.options ??= question.default; + workspace.options[id] ??= question.default; } } From 184bbefa895570de2a476249d4dc1dfd69d5c8cc Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:31:57 -0500 Subject: [PATCH 107/126] unpin storybook and remove skipping windows ci --- packages/adders/_tests/storybook/test.ts | 12 ++++++------ packages/adders/storybook/index.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index 67afa255..ed35e18c 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -1,4 +1,3 @@ -import process from 'node:process'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import storybook from '../../storybook/index.ts'; @@ -7,10 +6,8 @@ const { test, variants, prepareServer } = setupTest({ storybook }); let port = 6006; -const windowsCI = process.env.CI && process.platform === 'win32'; -test.skipIf(windowsCI).concurrent.for(variants)( - 'storybook loaded - %s', - async (variant, { page, ...ctx }) => { +test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { + try { const cwd = await ctx.run(variant, { storybook: {} }); const { close } = await prepareServer({ @@ -24,5 +21,8 @@ test.skipIf(windowsCI).concurrent.for(variants)( expect(await page.$('main .sb-bar')).toBeTruthy(); expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); + } catch (e) { + console.error(e); + throw e; } -); +}); diff --git a/packages/adders/storybook/index.ts b/packages/adders/storybook/index.ts index 1e7600ea..8ab8ef54 100644 --- a/packages/adders/storybook/index.ts +++ b/packages/adders/storybook/index.ts @@ -5,6 +5,6 @@ export default defineAdder({ homepage: 'https://storybook.js.org', options: {}, run: async ({ sv }) => { - await sv.execute(['storybook@8.3.6', 'init', '--skip-install', '--no-dev'], 'inherit'); + await sv.execute(['storybook@8.4', 'init', '--skip-install', '--no-dev'], 'inherit'); } }); From 81810c7a6c6fed68e575fff76687b98fa884de36 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:39:24 -0500 Subject: [PATCH 108/126] use `defineProject` instead for better type safety in a workspace --- packages/adders/vitest.config.ts | 4 ++-- packages/core/vitest.config.ts | 4 ++-- packages/create/vitest.config.ts | 4 ++-- packages/migrate/vitest.config.ts | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/adders/vitest.config.ts b/packages/adders/vitest.config.ts index 9f43ca88..c1ac6663 100644 --- a/packages/adders/vitest.config.ts +++ b/packages/adders/vitest.config.ts @@ -1,9 +1,9 @@ import { env } from 'node:process'; -import { defineConfig } from 'vitest/config'; +import { defineProject } from 'vitest/config'; const ONE_MINUTE = 1000 * 60; -export default defineConfig({ +export default defineProject({ test: { name: 'adders', include: ['_tests/**/test.{js,ts}'], diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts index 5940c172..8b52c7a6 100644 --- a/packages/core/vitest.config.ts +++ b/packages/core/vitest.config.ts @@ -1,6 +1,6 @@ -import { defineConfig } from 'vitest/config'; +import { defineProject } from 'vitest/config'; -export default defineConfig({ +export default defineProject({ test: { name: 'core', include: ['./tests/**/index.ts'] diff --git a/packages/create/vitest.config.ts b/packages/create/vitest.config.ts index f29b5427..a3de89ca 100644 --- a/packages/create/vitest.config.ts +++ b/packages/create/vitest.config.ts @@ -1,7 +1,7 @@ import { env } from 'node:process'; -import { defineConfig } from 'vitest/config'; +import { defineProject } from 'vitest/config'; -export default defineConfig({ +export default defineProject({ test: { name: 'create', include: ['test/*.ts'], diff --git a/packages/migrate/vitest.config.ts b/packages/migrate/vitest.config.ts index 22afa1cf..13a0f18e 100644 --- a/packages/migrate/vitest.config.ts +++ b/packages/migrate/vitest.config.ts @@ -1,6 +1,6 @@ -import { defineConfig } from 'vitest/config'; +import { defineProject } from 'vitest/config'; -export default defineConfig({ +export default defineProject({ test: { name: 'migrate' } From adb2663b4c9ebd74f10441113bd4eff64ad057ce Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:41:06 -0500 Subject: [PATCH 109/126] remove silent flag --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index abe8d183..1fa940b8 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "dev": "rollup --config --watch", "format": "pnpm --parallel format", "lint": "pnpm --parallel lint && eslint --cache --cache-location node_modules/.eslintcache", - "test": "vitest run --silent", + "test": "vitest run", "test:ui": "vitest --ui" }, "devDependencies": { From 0e92311d0627f55687dabb71ddb8243214324f0f Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:41:23 -0500 Subject: [PATCH 110/126] use latest --- packages/adders/storybook/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adders/storybook/index.ts b/packages/adders/storybook/index.ts index 8ab8ef54..0869a62b 100644 --- a/packages/adders/storybook/index.ts +++ b/packages/adders/storybook/index.ts @@ -5,6 +5,6 @@ export default defineAdder({ homepage: 'https://storybook.js.org', options: {}, run: async ({ sv }) => { - await sv.execute(['storybook@8.4', 'init', '--skip-install', '--no-dev'], 'inherit'); + await sv.execute(['storybook@latest', 'init', '--skip-install', '--no-dev'], 'inherit'); } }); From 64afeb5b66eba67012a2a7eddf3defe3db1b5bee Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:57:27 -0500 Subject: [PATCH 111/126] temp log --- packages/cli/lib/install.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 4b31a67f..2f4a0707 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -1,4 +1,4 @@ -import { exec } from 'tinyexec'; +import { exec, NonZeroExitError } from 'tinyexec'; import { resolveCommand } from 'package-manager-detector'; import type { Adder, @@ -135,7 +135,8 @@ async function runAddon( throwOnError: true }); } catch (error) { - const typedError = error as Error; + const typedError = error as NonZeroExitError; + console.error(typedError); throw new Error( `Failed to execute scripts '${executedCommandDisplayName}': ` + typedError.message ); From 715d83e4344675b0b9dfc5d33ef5d4a15ca62446 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 17:33:02 -0500 Subject: [PATCH 112/126] unwrap --- packages/adders/_tests/storybook/test.ts | 27 ++++++++++-------------- packages/cli/lib/install.ts | 3 +-- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index ed35e18c..0aaeed5e 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -7,22 +7,17 @@ const { test, variants, prepareServer } = setupTest({ storybook }); let port = 6006; test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { - try { - const cwd = await ctx.run(variant, { storybook: {} }); + const cwd = await ctx.run(variant, { storybook: {} }); - const { close } = await prepareServer({ - cwd, - page, - previewCommand: `pnpm storybook -p ${++port} --ci`, - buildCommand: '' - }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ + cwd, + page, + previewCommand: `pnpm storybook -p ${++port} --ci`, + buildCommand: '' + }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - expect(await page.$('main .sb-bar')).toBeTruthy(); - expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); - } catch (e) { - console.error(e); - throw e; - } + expect(await page.$('main .sb-bar')).toBeTruthy(); + expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); }); diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 2f4a0707..8a2c60a8 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -136,9 +136,8 @@ async function runAddon( }); } catch (error) { const typedError = error as NonZeroExitError; - console.error(typedError); throw new Error( - `Failed to execute scripts '${executedCommandDisplayName}': ` + typedError.message + `Failed to execute scripts '${executedCommandDisplayName}': ${typedError.message}\n${typedError.output?.stderr}` ); } }, From 0fdf8be40ecbceb8c8f2758699da4681b7dd79f0 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 17:44:50 -0500 Subject: [PATCH 113/126] clear cache and log cause --- packages/cli/lib/install.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 8a2c60a8..6d287f02 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -137,7 +137,8 @@ async function runAddon( } catch (error) { const typedError = error as NonZeroExitError; throw new Error( - `Failed to execute scripts '${executedCommandDisplayName}': ${typedError.message}\n${typedError.output?.stderr}` + `Failed to execute scripts '${executedCommandDisplayName}': ${typedError.message}`, + { cause: typedError.output?.stderr || typedError.output?.stdout } ); } }, From 406a7c108ee5499f7459e1f7fdfab4611a61f307 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 17:53:11 -0500 Subject: [PATCH 114/126] move it along --- packages/adders/_tests/storybook/test.ts | 26 ++++++++++++++---------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index 0aaeed5e..6b4b0428 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -7,17 +7,21 @@ const { test, variants, prepareServer } = setupTest({ storybook }); let port = 6006; test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { storybook: {} }); + try { + const cwd = await ctx.run(variant, { storybook: {} }); - const { close } = await prepareServer({ - cwd, - page, - previewCommand: `pnpm storybook -p ${++port} --ci`, - buildCommand: '' - }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ + cwd, + page, + previewCommand: `pnpm storybook -p ${++port} --ci`, + buildCommand: '' + }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - expect(await page.$('main .sb-bar')).toBeTruthy(); - expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); + expect(await page.$('main .sb-bar')).toBeTruthy(); + expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); + } catch (e) { + console.error(e); + } }); From af23c2f5d0fe104f3461b7cf587d14c6b3034521 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:02:47 -0500 Subject: [PATCH 115/126] run sequentially --- packages/adders/_tests/storybook/test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index 6b4b0428..1aad2338 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -6,7 +6,7 @@ const { test, variants, prepareServer } = setupTest({ storybook }); let port = 6006; -test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { +test.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { try { const cwd = await ctx.run(variant, { storybook: {} }); @@ -22,6 +22,7 @@ test.concurrent.for(variants)('storybook loaded - %s', async (variant, { page, . expect(await page.$('main .sb-bar')).toBeTruthy(); expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); } catch (e) { - console.error(e); + console.error(e.message); + console.error(e.cause); } }); From 938381504b5a16eb6e860e7303f837c132885838 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:42:50 -0500 Subject: [PATCH 116/126] revert --- package.json | 2 +- packages/adders/_tests/storybook/test.ts | 27 ++++++++++-------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 1fa940b8..abe8d183 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "dev": "rollup --config --watch", "format": "pnpm --parallel format", "lint": "pnpm --parallel lint && eslint --cache --cache-location node_modules/.eslintcache", - "test": "vitest run", + "test": "vitest run --silent", "test:ui": "vitest --ui" }, "devDependencies": { diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index 1aad2338..903f41df 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -7,22 +7,17 @@ const { test, variants, prepareServer } = setupTest({ storybook }); let port = 6006; test.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { - try { - const cwd = await ctx.run(variant, { storybook: {} }); + const cwd = await ctx.run(variant, { storybook: {} }); - const { close } = await prepareServer({ - cwd, - page, - previewCommand: `pnpm storybook -p ${++port} --ci`, - buildCommand: '' - }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ + cwd, + page, + previewCommand: `pnpm storybook -p ${++port} --ci`, + buildCommand: '' + }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - expect(await page.$('main .sb-bar')).toBeTruthy(); - expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); - } catch (e) { - console.error(e.message); - console.error(e.cause); - } + expect(await page.$('main .sb-bar')).toBeTruthy(); + expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); }); From 804caa2d5c049652701e8b1ccf183d61e7e2da91 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:44:11 -0500 Subject: [PATCH 117/126] test --- packages/adders/_tests/all-addons/test.ts | 6 +++--- packages/cli/lib/install.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/adders/_tests/all-addons/test.ts b/packages/adders/_tests/all-addons/test.ts index 934b3da1..4d974f65 100644 --- a/packages/adders/_tests/all-addons/test.ts +++ b/packages/adders/_tests/all-addons/test.ts @@ -1,12 +1,12 @@ -import process from 'node:process'; +// import process from 'node:process'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import { officialAdders } from '../../index.ts'; import type { AddonMap, OptionMap } from 'sv'; -const windowsCI = process.env.CI && process.platform === 'win32'; +// const windowsCI = process.env.CI && process.platform === 'win32'; const addons = officialAdders.reduce((addonMap, addon) => { - if (addon.id === 'storybook' && windowsCI) return addonMap; + // if (addon.id === 'storybook' && windowsCI) return addonMap; addonMap[addon.id] = addon; return addonMap; }, {}); diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 6d287f02..aeaec8ba 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -138,7 +138,7 @@ async function runAddon( const typedError = error as NonZeroExitError; throw new Error( `Failed to execute scripts '${executedCommandDisplayName}': ${typedError.message}`, - { cause: typedError.output?.stderr || typedError.output?.stdout } + { cause: typedError.output } ); } }, From 489c692a68bcb25cef0e0e69ef7418714ab9387b Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:53:52 -0500 Subject: [PATCH 118/126] exclude windows from running concurrently --- packages/adders/_tests/all-addons/test.ts | 6 ++--- packages/adders/_tests/storybook/test.ts | 32 ++++++++++++++--------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/packages/adders/_tests/all-addons/test.ts b/packages/adders/_tests/all-addons/test.ts index 4d974f65..934b3da1 100644 --- a/packages/adders/_tests/all-addons/test.ts +++ b/packages/adders/_tests/all-addons/test.ts @@ -1,12 +1,12 @@ -// import process from 'node:process'; +import process from 'node:process'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import { officialAdders } from '../../index.ts'; import type { AddonMap, OptionMap } from 'sv'; -// const windowsCI = process.env.CI && process.platform === 'win32'; +const windowsCI = process.env.CI && process.platform === 'win32'; const addons = officialAdders.reduce((addonMap, addon) => { - // if (addon.id === 'storybook' && windowsCI) return addonMap; + if (addon.id === 'storybook' && windowsCI) return addonMap; addonMap[addon.id] = addon; return addonMap; }, {}); diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts index 903f41df..8a9e0258 100644 --- a/packages/adders/_tests/storybook/test.ts +++ b/packages/adders/_tests/storybook/test.ts @@ -1,3 +1,4 @@ +import process from 'node:process'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import storybook from '../../storybook/index.ts'; @@ -6,18 +7,23 @@ const { test, variants, prepareServer } = setupTest({ storybook }); let port = 6006; -test.for(variants)('storybook loaded - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { storybook: {} }); +const windowsCI = process.env.CI && process.platform === 'win32'; +test.for(variants)( + 'storybook loaded - %s', + { concurrent: !windowsCI }, + async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { storybook: {} }); - const { close } = await prepareServer({ - cwd, - page, - previewCommand: `pnpm storybook -p ${++port} --ci`, - buildCommand: '' - }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); + const { close } = await prepareServer({ + cwd, + page, + previewCommand: `pnpm storybook -p ${++port} --ci`, + buildCommand: '' + }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); - expect(await page.$('main .sb-bar')).toBeTruthy(); - expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); -}); + expect(await page.$('main .sb-bar')).toBeTruthy(); + expect(await page.$('#storybook-preview-wrapper')).toBeTruthy(); + } +); From 31c73c8c58dd441a47f11004a6d99fbfd20753c6 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 13 Nov 2024 00:28:50 -0500 Subject: [PATCH 119/126] tweaks --- packages/cli/commands/add/index.ts | 26 ++++++++++++++------------ packages/cli/commands/add/utils.ts | 2 +- packages/cli/lib/install.ts | 10 +++++----- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 8635d15e..17caa11b 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -1,18 +1,18 @@ import fs from 'node:fs'; import path from 'node:path'; import process from 'node:process'; +import pc from 'picocolors'; import * as v from 'valibot'; -import { Command, Option } from 'commander'; -import * as p from '@sveltejs/clack-prompts'; import * as pkg from 'empathic/package'; -import type { AgentName } from 'package-manager-detector'; -import pc from 'picocolors'; +import * as p from '@sveltejs/clack-prompts'; +import { Command, Option } from 'commander'; import { officialAdders, getAdderDetails, communityAdderIds, getCommunityAdder } from '@sveltejs/adders'; +import type { AgentName } from 'package-manager-detector'; import type { AdderWithoutExplicitArgs, OptionValues } from '@sveltejs/cli-core'; import * as common from '../../utils/common.ts'; import { createWorkspace } from './workspace.ts'; @@ -306,12 +306,14 @@ export async function runAddCommand( workspace = createWorkspace({ cwd: options.cwd }); const adderSetupResult = adderSetupResults[adder.id]; - const dependents = adderSetupResult.dependsOn; - const filteredDependents = - dependents.filter((dep) => !selectedAdders.some((a) => a.adder.id === dep)) ?? []; + const missingDependencies = adderSetupResult.dependsOn.filter( + (depId) => !selectedAdders.some((a) => a.adder.id === depId) + ); - for (const depId of filteredDependents) { - const dependent = officialAdders.find((a) => a.id === depId) as AdderWithoutExplicitArgs; + for (const depId of missingDependencies) { + // TODO: this will have to be adjusted when we work on community add-ons + const dependency = officialAdders.find((a) => a.id === depId); + if (!dependency) throw new Error(`'${adder.id}' depends on an invalid add-on: '${depId}'`); // prompt to install the dependent const install = await p.confirm({ @@ -321,7 +323,7 @@ export async function runAddCommand( p.cancel('Operation cancelled.'); process.exit(1); } - selectedAdders.push({ type: 'official', adder: dependent }); + selectedAdders.push({ type: 'official', adder: dependency }); } } @@ -438,10 +440,10 @@ export async function runAddCommand( ); const details = adderDetails.concat(commDetails); - const addonMap = details.reduce((map, x) => { + const addonMap = details.reduce((map, x) => { map[x.id] = x; return map; - }, {} as AddonMap); + }, {}); const filesToFormat = await installAddon({ cwd: workspace.cwd, packageManager: workspace.packageManager, diff --git a/packages/cli/commands/add/utils.ts b/packages/cli/commands/add/utils.ts index 6bd2dfc0..2c2900c5 100644 --- a/packages/cli/commands/add/utils.ts +++ b/packages/cli/commands/add/utils.ts @@ -3,8 +3,8 @@ import path from 'node:path'; import pc from 'picocolors'; import { exec } from 'tinyexec'; import { parseJson } from '@sveltejs/cli-core/parsers'; -import type { Highlighter, Workspace } from '@sveltejs/cli-core'; import { resolveCommand, type AgentName } from 'package-manager-detector'; +import type { Highlighter, Workspace } from '@sveltejs/cli-core'; export type Package = { name: string; diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index aeaec8ba..74eb5389 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -1,5 +1,3 @@ -import { exec, NonZeroExitError } from 'tinyexec'; -import { resolveCommand } from 'package-manager-detector'; import type { Adder, Workspace, @@ -10,11 +8,13 @@ import type { AdderSetupResult, AdderWithoutExplicitArgs } from '@sveltejs/cli-core'; -import { fileExists, installPackages, readFile, writeFile } from '../commands/add/utils.ts'; -import { createWorkspace } from '../commands/add/workspace.ts'; -import * as p from '@sveltejs/clack-prompts'; import pc from 'picocolors'; +import * as p from '@sveltejs/clack-prompts'; +import { exec, NonZeroExitError } from 'tinyexec'; +import { resolveCommand } from 'package-manager-detector'; import { TESTING } from '../utils/env.ts'; +import { createWorkspace } from '../commands/add/workspace.ts'; +import { fileExists, installPackages, readFile, writeFile } from '../commands/add/utils.ts'; type Addon = Adder; export type InstallOptions = { From 23b1912928f3f6efa077b16df4baf4c56fa80ca3 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Wed, 13 Nov 2024 17:09:37 +0100 Subject: [PATCH 120/126] dont return string from `file` function --- packages/cli/lib/install.ts | 2 -- packages/core/adder/config.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 74eb5389..3f52170b 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -106,8 +106,6 @@ async function runAddon( writeFile(workspace, path, fileContent); files.add(path); - - return fileContent; } catch (e) { if (e instanceof Error) { throw new Error(`Unable to process '${path}'. Reason: ${e.message}`); diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index 1b878cd8..dd9c356b 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -21,7 +21,7 @@ export type Scripts = { }; export type SvApi = { - file: (path: string, content: (content: string) => string) => string; + file: (path: string, edit: (content: string) => string) => void; dependency: (pkg: string, version: string) => void; devDependency: (pkg: string, version: string) => void; execute: (args: string[], stdio: 'inherit' | 'pipe') => Promise; From b9ed6a1c0595b8e778d0f37228a45f25ed20e21a Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Wed, 13 Nov 2024 17:44:27 +0100 Subject: [PATCH 121/126] improve `unsupported` --- community-adder-template/src/index.js | 4 ++-- packages/adders/drizzle/index.ts | 4 ++-- packages/adders/lucia/index.ts | 4 ++-- packages/adders/paraglide/index.ts | 4 ++-- packages/cli/commands/add/index.ts | 11 ++--------- packages/cli/commands/add/preconditions.ts | 17 ++++------------- packages/cli/lib/install.ts | 4 ++-- packages/core/adder/config.ts | 7 +++++-- 8 files changed, 21 insertions(+), 34 deletions(-) diff --git a/community-adder-template/src/index.js b/community-adder-template/src/index.js index a629c68b..11b34a15 100644 --- a/community-adder-template/src/index.js +++ b/community-adder-template/src/index.js @@ -13,8 +13,8 @@ export const options = defineAdderOptions({ export default defineAdder({ id: 'community-addon', options, - setup: ({ kit, unavailable }) => { - if (!kit) unavailable(); + setup: ({ kit, unsupported }) => { + if (!kit) unsupported('Requires SvelteKit'); }, run: ({ sv, options, typescript }) => { sv.file('adder-template-demo.txt', (content) => { diff --git a/packages/adders/drizzle/index.ts b/packages/adders/drizzle/index.ts index 433545d7..ec575f9c 100644 --- a/packages/adders/drizzle/index.ts +++ b/packages/adders/drizzle/index.ts @@ -67,8 +67,8 @@ export default defineAdder({ id: 'drizzle', homepage: 'https://orm.drizzle.team', options, - setup: ({ kit, unavailable }) => { - if (!kit) unavailable(); + setup: ({ kit, unsupported }) => { + if (!kit) unsupported('Requires SvelteKit'); }, run: ({ sv, typescript, options, kit }) => { const ext = typescript ? 'ts' : 'js'; diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 9fcb0dfa..3693e19f 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -45,8 +45,8 @@ export default defineAdder({ id: 'lucia', homepage: 'https://lucia-auth.com', options, - setup: ({ kit, dependencyVersion, unavailable, dependsOn }) => { - if (!kit) unavailable(); + setup: ({ kit, dependencyVersion, unsupported, dependsOn }) => { + if (!kit) unsupported('Requires SvelteKit'); if (!dependencyVersion('drizzle-orm')) dependsOn('drizzle'); }, run: ({ sv, typescript, options, kit, dependencyVersion }) => { diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts index 960a4db2..e2720e85 100644 --- a/packages/adders/paraglide/index.ts +++ b/packages/adders/paraglide/index.ts @@ -65,8 +65,8 @@ export default defineAdder({ id: 'paraglide', homepage: 'https://inlang.com', options, - setup: ({ kit, unavailable }) => { - if (!kit) unavailable(); + setup: ({ kit, unsupported }) => { + if (!kit) unsupported('Requires SvelteKit'); }, run: ({ sv, cwd, options, typescript, kit, dependencyVersion }) => { const ext = typescript ? 'ts' : 'js'; diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 17caa11b..76d3c5c6 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -276,7 +276,7 @@ export async function runAddCommand( .map((adder) => { // we'll only display adders within their respective project types const adderSetupResult = adderSetupResults[adder.id]; - if (!adderSetupResult.available) return; + if (adderSetupResult.unsupported.length > 0) return; return { label: adder.id, @@ -330,15 +330,8 @@ export async function runAddCommand( // run precondition checks if (options.preconditions && selectedAdders.length > 0) { // add global checks - const { kit } = createWorkspace({ cwd: options.cwd }); - const projectType = kit ? 'kit' : 'svelte'; const adders = selectedAdders.map(({ adder }) => adder); - const { preconditions } = getGlobalPreconditions( - options.cwd, - projectType, - adders, - adderSetupResults - ); + const { preconditions } = getGlobalPreconditions(options.cwd, adders, adderSetupResults); const fails: Array<{ name: string; message?: string }> = []; for (const condition of preconditions) { diff --git a/packages/cli/commands/add/preconditions.ts b/packages/cli/commands/add/preconditions.ts index ce751d32..9769b81a 100644 --- a/packages/cli/commands/add/preconditions.ts +++ b/packages/cli/commands/add/preconditions.ts @@ -4,7 +4,6 @@ import type { AdderSetupResult, AdderWithoutExplicitArgs, Precondition } from '@ type PreconditionCheck = { name: string; preconditions: Precondition[] }; export function getGlobalPreconditions( cwd: string, - projectType: 'svelte' | 'kit', adders: AdderWithoutExplicitArgs[], adderSetupResult: Record ): PreconditionCheck { @@ -37,24 +36,16 @@ export function getGlobalPreconditions( } }, { - name: 'supported environments', + name: 'unspported adders', run: () => { - const addersForInvalidEnvironment = adders.filter( - (a) => !adderSetupResult[a.id].available + const messages = adders.flatMap((a) => + adderSetupResult[a.id].unsupported.map((reason) => `${a.id}: ${reason}`) ); - if (addersForInvalidEnvironment.length === 0) { + if (messages.length === 0) { return { success: true, message: undefined }; } - const messages = addersForInvalidEnvironment.map((a) => { - if (projectType === 'kit') { - return `'${a.id}' does not support SvelteKit`; - } else { - return `'${a.id}' requires SvelteKit`; - } - }); - throw new Error(messages.join('\n')); } } diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 3f52170b..6a9b88df 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -65,13 +65,13 @@ export function setupAddons( for (const addon of addons) { const setupResult: AdderSetupResult = { - available: true, + unsupported: [], dependsOn: [] }; addon.setup?.({ ...workspace, dependsOn: (name) => setupResult.dependsOn.push(name), - unavailable: () => (setupResult.available = false) + unsupported: (reason) => setupResult.unsupported.push(reason) }); adderSetupResults[addon.id] = setupResult; } diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts index dd9c356b..ffc8abae 100644 --- a/packages/core/adder/config.ts +++ b/packages/core/adder/config.ts @@ -33,7 +33,10 @@ export type Adder = { homepage?: string; options: Args; setup?: ( - workspace: Workspace & { dependsOn: (name: string) => void; unavailable: () => void } + workspace: Workspace & { + dependsOn: (name: string) => void; + unsupported: (reason: string) => void; + } ) => MaybePromise; run: (workspace: Workspace & { sv: SvApi }) => MaybePromise; nextSteps?: ( @@ -55,7 +58,7 @@ export function defineAdder(config: Adder): return config; } -export type AdderSetupResult = { dependsOn: string[]; available: boolean }; +export type AdderSetupResult = { dependsOn: string[]; unsupported: string[] }; export type AdderWithoutExplicitArgs = Adder>; export type AdderConfigWithoutExplicitArgs = Adder>; From 53289dc77bcbd840eaeee24ff8b1db9246e076bf Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:58:57 -0500 Subject: [PATCH 122/126] log `stderr` on failed dep installs --- packages/cli/utils/package-manager.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index c0226505..ffb3ad1b 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -1,5 +1,5 @@ import process from 'node:process'; -import { exec } from 'tinyexec'; +import { exec, NonZeroExitError } from 'tinyexec'; import * as p from '@sveltejs/clack-prompts'; import { AGENTS, @@ -41,6 +41,12 @@ export async function installDependencies(agent: AgentName, cwd: string): Promis spinner.stop('Successfully installed dependencies'); } catch (error) { spinner.stop('Failed to install dependencies', 2); + + if (error instanceof NonZeroExitError) { + const stderr = error.output?.stderr; + if (stderr) p.log.error(stderr); + } + throw error; } } From 20ceb6607fae987b8a86df085cb0413b1273afba Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 13 Nov 2024 13:42:13 -0500 Subject: [PATCH 123/126] tweak error --- packages/cli/commands/add/index.ts | 9 ++------- packages/cli/commands/add/preconditions.ts | 11 ++++++----- packages/cli/utils/common.ts | 20 +++++++++++++++++--- packages/cli/utils/errors.ts | 9 +++++++++ 4 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 packages/cli/utils/errors.ts diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 76d3c5c6..5be67972 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -234,8 +234,8 @@ export async function runAddCommand( 'The Svelte maintainers have not reviewed community adders for malicious code. Use at your discretion.' ); - const paddingName = getPadding(pkgs.map(({ pkg }) => pkg.name)); - const paddingVersion = getPadding(pkgs.map(({ pkg }) => `(v${pkg.version})`)); + const paddingName = common.getPadding(pkgs.map(({ pkg }) => pkg.name)); + const paddingVersion = common.getPadding(pkgs.map(({ pkg }) => `(v${pkg.version})`)); const packageInfos = pkgs.map(({ pkg, repo: _repo }) => { const name = pc.yellowBright(pkg.name.padEnd(paddingName)); @@ -587,8 +587,3 @@ function getOptionChoices(details: AdderWithoutExplicitArgs) { } return { choices, defaults, groups }; } - -function getPadding(lines: string[]) { - const lengths = lines.map((s) => s.length); - return Math.max(...lengths); -} diff --git a/packages/cli/commands/add/preconditions.ts b/packages/cli/commands/add/preconditions.ts index 9769b81a..90694299 100644 --- a/packages/cli/commands/add/preconditions.ts +++ b/packages/cli/commands/add/preconditions.ts @@ -1,5 +1,6 @@ import { exec } from 'tinyexec'; import type { AdderSetupResult, AdderWithoutExplicitArgs, Precondition } from '@sveltejs/cli-core'; +import { UnsupportedError } from '../../utils/errors.ts'; type PreconditionCheck = { name: string; preconditions: Precondition[] }; export function getGlobalPreconditions( @@ -36,17 +37,17 @@ export function getGlobalPreconditions( } }, { - name: 'unspported adders', + name: 'unsupported adders', run: () => { - const messages = adders.flatMap((a) => - adderSetupResult[a.id].unsupported.map((reason) => `${a.id}: ${reason}`) + const reasons = adders.flatMap((a) => + adderSetupResult[a.id].unsupported.map((reason) => ({ id: a.id, reason })) ); - if (messages.length === 0) { + if (reasons.length === 0) { return { success: true, message: undefined }; } - throw new Error(messages.join('\n')); + throw new UnsupportedError(reasons); } } ] diff --git a/packages/cli/utils/common.ts b/packages/cli/utils/common.ts index bfcbfd16..68ef9593 100644 --- a/packages/cli/utils/common.ts +++ b/packages/cli/utils/common.ts @@ -2,6 +2,7 @@ import pc from 'picocolors'; import pkg from '../package.json'; import * as p from '@sveltejs/clack-prompts'; import type { Argument, HelpConfiguration, Option } from 'commander'; +import { UnsupportedError } from './errors.ts'; const NO_PREFIX = '--no-'; let options: readonly Option[] = []; @@ -70,9 +71,22 @@ export async function runCommand(action: MaybePromise): Promise { await action(); p.outro("You're all set!"); } catch (e) { - p.cancel('Operation failed.'); - if (e instanceof Error) { - console.error(e.stack ?? e); + if (e instanceof UnsupportedError) { + const padding = getPadding(e.reasons.map((r) => r.id)); + const message = e.reasons + .map((r) => ` ${r.id.padEnd(padding)} ${pc.red(r.reason)}`) + .join('\n'); + p.log.error(`${e.name}\n\n${message}`); + p.log.message(); + } else if (e instanceof Error) { + p.log.error(e.stack ?? String(e)); + p.log.message(); } + p.cancel('Operation failed.'); } } + +export function getPadding(lines: string[]) { + const lengths = lines.map((s) => s.length); + return Math.max(...lengths); +} diff --git a/packages/cli/utils/errors.ts b/packages/cli/utils/errors.ts new file mode 100644 index 00000000..1a33b141 --- /dev/null +++ b/packages/cli/utils/errors.ts @@ -0,0 +1,9 @@ +type Reason = { id: string; reason: string }; +export class UnsupportedError extends Error { + name = 'Unsupported Environment'; + reasons: Reason[] = []; + constructor(reasons: Reason[]) { + super(); + this.reasons = reasons; + } +} From 830fbd49b4b514e501d854979b6b7f0665ee5040 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 13 Nov 2024 20:27:24 -0500 Subject: [PATCH 124/126] simplify --- packages/cli/commands/add/index.ts | 75 ++++++++++---------------- packages/cli/commands/add/workspace.ts | 24 ++++++--- packages/cli/lib/install.ts | 57 +++++++++++--------- 3 files changed, 76 insertions(+), 80 deletions(-) diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 5be67972..97d12501 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -13,14 +13,14 @@ import { getCommunityAdder } from '@sveltejs/adders'; import type { AgentName } from 'package-manager-detector'; -import type { AdderWithoutExplicitArgs, OptionValues } from '@sveltejs/cli-core'; +import type { AdderWithoutExplicitArgs, OptionValues, PackageManager } from '@sveltejs/cli-core'; import * as common from '../../utils/common.ts'; import { createWorkspace } from './workspace.ts'; import { formatFiles, getHighlighter } from './utils.ts'; import { Directive, downloadPackage, getPackageJSON } from './fetch-packages.ts'; import { installDependencies, packageManagerPrompt } from '../../utils/package-manager.ts'; import { getGlobalPreconditions } from './preconditions.ts'; -import { type AddonMap, installAddon, setupAddons } from '../../lib/install.ts'; +import { type AddonMap, applyAddons, setupAddons } from '../../lib/install.ts'; const AddersSchema = v.array(v.string()); const AdderOptionFlagsSchema = v.object({ @@ -101,6 +101,11 @@ export async function runAddCommand( type: 'official', adder: getAdderDetails(id) })); + + type AdderId = string; + type QuestionValues = OptionValues; + type AdderOption = Record; + const official: AdderOption = {}; const community: AdderOption = {}; @@ -268,23 +273,14 @@ export async function runAddCommand( // prepare official adders let workspace = createWorkspace({ cwd: options.cwd }); - const adderSetupResults = setupAddons(officialAdders, options.cwd); + const adderSetupResults = setupAddons(officialAdders, workspace); // prompt which adders to apply if (selectedAdders.length === 0) { const adderOptions = officialAdders - .map((adder) => { - // we'll only display adders within their respective project types - const adderSetupResult = adderSetupResults[adder.id]; - if (adderSetupResult.unsupported.length > 0) return; - - return { - label: adder.id, - value: adder.id, - hint: adder.homepage - }; - }) - .filter((a) => !!a); + // only display supported adders relative to the current environment + .filter(({ id }) => adderSetupResults[id].unsupported.length === 0) + .map(({ id, homepage }) => ({ label: id, value: id, hint: homepage })); const selected = await p.multiselect({ message: `What would you like to add to your project? ${pc.dim('(use arrow keys / space bar)')}`, @@ -296,17 +292,18 @@ export async function runAddCommand( process.exit(1); } - selected.forEach((id) => - selectedAdders.push({ type: 'official', adder: officialAdders.find((x) => x.id == id)! }) - ); + for (const id of selected) { + const adder = officialAdders.find((adder) => adder.id === id)!; + selectedAdders.push({ type: 'official', adder }); + } } // add inter-adder dependencies for (const { adder } of selectedAdders) { - workspace = createWorkspace({ cwd: options.cwd }); - const adderSetupResult = adderSetupResults[adder.id]; + workspace = createWorkspace(workspace); - const missingDependencies = adderSetupResult.dependsOn.filter( + const setupResult = adderSetupResults[adder.id]; + const missingDependencies = setupResult.dependsOn.filter( (depId) => !selectedAdders.some((a) => a.adder.id === depId) ); @@ -421,28 +418,25 @@ export async function runAddCommand( if (selectedAdders.length === 0) return { packageManager: null }; // prompt for package manager - let packageManager: AgentName | undefined; + let packageManager: PackageManager | undefined; if (options.install) { packageManager = await packageManagerPrompt(options.cwd); + if (packageManager) workspace.packageManager = packageManager; } // apply adders - const adderDetails = Object.keys(official).map((id) => getAdderDetails(id)); + const officialDetails = Object.keys(official).map((id) => getAdderDetails(id)); const commDetails = Object.keys(community).map( (id) => communityDetails.find((a) => a.id === id)! ); - const details = adderDetails.concat(commDetails); - - const addonMap = details.reduce((map, x) => { - map[x.id] = x; - return map; - }, {}); - const filesToFormat = await installAddon({ - cwd: workspace.cwd, - packageManager: workspace.packageManager, + const details = officialDetails.concat(commDetails); + + const addonMap: AddonMap = Object.assign({}, ...details.map((a) => ({ [a.id]: a }))); + const filesToFormat = await applyAddons({ + workspace, + adderSetupResults, addons: addonMap, - options: official, - adderSetupResults + options: official }); p.log.success('Successfully setup add-ons'); @@ -453,7 +447,7 @@ export async function runAddCommand( } // format modified/created files with prettier (if available) - workspace = createWorkspace({ cwd: options.cwd, packageManager }); + workspace = createWorkspace(workspace); if (filesToFormat.length > 0 && packageManager && !!workspace.dependencyVersion('prettier')) { const { start, stop } = p.spinner(); start('Formatting modified files'); @@ -492,17 +486,6 @@ export async function runAddCommand( return { nextSteps, packageManager }; } -type AdderId = string; -type QuestionValues = OptionValues; -export type AdderOption = Record; - -export type InstallAdderOptions = { - cwd: string; - packageManager?: AgentName; - official?: AdderOption; - community?: AdderOption; -}; - /** * Dedupes and transforms aliases into their respective adder id */ diff --git a/packages/cli/commands/add/workspace.ts b/packages/cli/commands/add/workspace.ts index ac4d396f..a73b6358 100644 --- a/packages/cli/commands/add/workspace.ts +++ b/packages/cli/commands/add/workspace.ts @@ -3,14 +3,22 @@ import path from 'node:path'; import * as find from 'empathic/find'; import { common, object, type AstTypes } from '@sveltejs/cli-core/js'; import { parseScript } from '@sveltejs/cli-core/parsers'; -import type { Workspace } from '@sveltejs/cli-core'; -import type { AgentName } from 'package-manager-detector'; +import { detectSync } from 'package-manager-detector'; +import type { OptionValues, PackageManager, Workspace } from '@sveltejs/cli-core'; import { TESTING } from '../../utils/env.ts'; import { commonFilePaths, getPackageJson, readFile } from './utils.ts'; import { getUserAgent } from '../../utils/package-manager.ts'; -type CreateWorkspaceOptions = { cwd: string; packageManager?: AgentName }; -export function createWorkspace({ cwd, packageManager }: CreateWorkspaceOptions): Workspace { +type CreateWorkspaceOptions = { + cwd: string; + packageManager?: PackageManager; + options?: OptionValues; +}; +export function createWorkspace({ + cwd, + options = {}, + packageManager = detectSync({ cwd })?.name ?? getUserAgent() ?? 'npm' +}: CreateWorkspaceOptions): Workspace { const resolvedCwd = path.resolve(cwd); const viteConfigPath = path.join(resolvedCwd, commonFilePaths.viteConfigTS); let usesTypescript = fs.existsSync(viteConfigPath); @@ -43,12 +51,12 @@ export function createWorkspace({ cwd, packageManager }: CreateWorkspaceOptions) } return { - kit: dependencies['@sveltejs/kit'] ? parseKitOptions(resolvedCwd) : undefined, - packageManager: packageManager ?? getUserAgent() ?? 'npm', cwd: resolvedCwd, - dependencyVersion: (pkg) => dependencies[pkg], + options, + packageManager, typescript: usesTypescript, - options: {} + kit: dependencies['@sveltejs/kit'] ? parseKitOptions(resolvedCwd) : undefined, + dependencyVersion: (pkg) => dependencies[pkg] }; } diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 6a9b88df..154970da 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -21,8 +21,7 @@ export type InstallOptions = { cwd: string; addons: Addons; options: OptionMap; - packageManager: PackageManager; - adderSetupResults?: Record; + packageManager?: PackageManager; }; export type AddonMap = Record; @@ -34,19 +33,33 @@ export async function installAddon({ addons, cwd, options, - packageManager = 'npm', - adderSetupResults + packageManager = 'npm' }: InstallOptions): Promise { - const filesToFormat = new Set(); + const workspace = createWorkspace({ cwd, packageManager }); + const adderSetupResults = setupAddons(Object.values(addons), workspace); - adderSetupResults ??= setupAddons(Object.values(addons), cwd, packageManager); + return await applyAddons({ addons, workspace, options, adderSetupResults }); +} + +export type ApplyAddonOptions = { + addons: AddonMap; + options: OptionMap; + workspace: Workspace; + adderSetupResults: Record; +}; +export async function applyAddons({ + addons, + workspace, + adderSetupResults, + options +}: ApplyAddonOptions): Promise { + const filesToFormat = new Set(); const mapped = Object.entries(addons).map(([, addon]) => addon); const ordered = orderAddons(mapped, adderSetupResults); for (const addon of ordered) { - const workspace = createWorkspace({ cwd, packageManager }); - workspace.options = options[addon.id]; + workspace = createWorkspace({ ...workspace, options: options[addon.id] }); const files = await runAddon(workspace, addon, ordered.length > 1); files.forEach((f) => filesToFormat.add(f)); @@ -57,17 +70,12 @@ export async function installAddon({ export function setupAddons( addons: AdderWithoutExplicitArgs[], - cwd: string, - packageManager?: PackageManager + workspace: Workspace ): Record { const adderSetupResults: Record = {}; - const workspace = createWorkspace({ cwd, packageManager }); for (const addon of addons) { - const setupResult: AdderSetupResult = { - unsupported: [], - dependsOn: [] - }; + const setupResult: AdderSetupResult = { unsupported: [], dependsOn: [] }; addon.setup?.({ ...workspace, dependsOn: (name) => setupResult.dependsOn.push(name), @@ -117,11 +125,9 @@ async function runAddon( const { command, args } = resolveCommand(workspace.packageManager, 'execute', commandArgs)!; const adderPrefix = applyMultipleAddons ? `${addon.id}: ` : ''; - const executedCommandDisplayName = `${command} ${args.join(' ')}`; + const executedCommand = `${command} ${args.join(' ')}`; if (!TESTING) { - p.log.step( - `${adderPrefix}Running external command ${pc.gray(`(${executedCommandDisplayName})`)}` - ); + p.log.step(`${adderPrefix}Running external command ${pc.gray(`(${executedCommand})`)}`); } // adding --yes as the first parameter helps avoiding the "Need to install the following packages:" message @@ -134,10 +140,9 @@ async function runAddon( }); } catch (error) { const typedError = error as NonZeroExitError; - throw new Error( - `Failed to execute scripts '${executedCommandDisplayName}': ${typedError.message}`, - { cause: typedError.output } - ); + throw new Error(`Failed to execute scripts '${executedCommand}': ${typedError.message}`, { + cause: typedError.output + }); } }, dependency: (pkg, version) => { @@ -156,10 +161,10 @@ async function runAddon( } // sorts them to their execution order -function orderAddons(addons: Addon[], adderSetupResults: Record) { +function orderAddons(addons: Addon[], setupResults: Record) { return Array.from(addons).sort((a, b) => { - const aDeps = adderSetupResults[a.id].dependsOn; - const bDeps = adderSetupResults[b.id].dependsOn; + const aDeps = setupResults[a.id].dependsOn; + const bDeps = setupResults[b.id].dependsOn; if (!aDeps && !bDeps) return 0; if (!aDeps) return -1; From b78a6a38330fe91daf8ea36dd51e2d39784419bd Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 13 Nov 2024 20:59:30 -0500 Subject: [PATCH 125/126] fixes and tweaks --- packages/adders/drizzle/index.ts | 2 +- packages/adders/eslint/index.ts | 24 +++--- packages/adders/lucia/index.ts | 103 ++++++++++++-------------- packages/adders/paraglide/index.ts | 30 ++++---- packages/adders/playwright/index.ts | 15 ++-- packages/adders/prettier/index.ts | 16 ++-- packages/adders/tailwindcss/index.ts | 2 +- packages/adders/vitest-addon/index.ts | 2 +- packages/cli/lib/install.ts | 15 ++-- 9 files changed, 97 insertions(+), 112 deletions(-) diff --git a/packages/adders/drizzle/index.ts b/packages/adders/drizzle/index.ts index ec575f9c..c5821ffd 100644 --- a/packages/adders/drizzle/index.ts +++ b/packages/adders/drizzle/index.ts @@ -150,7 +150,7 @@ export default defineAdder({ }); if (options.database === 'sqlite') { - sv.file('.gitgnore', (content) => { + sv.file('.gitignore', (content) => { // Adds the db file to the gitignore if an ignore is present if (content.length === 0) return content; diff --git a/packages/adders/eslint/index.ts b/packages/adders/eslint/index.ts index 7398b107..b29b769e 100644 --- a/packages/adders/eslint/index.ts +++ b/packages/adders/eslint/index.ts @@ -1,5 +1,3 @@ -import fs from 'node:fs'; -import path from 'node:path'; import { addEslintConfigPrettier } from '../common.ts'; import { defineAdder, log } from '@sveltejs/cli-core'; import { @@ -18,7 +16,7 @@ export default defineAdder({ id: 'eslint', homepage: 'https://eslint.org', options: {}, - run: ({ sv, typescript, cwd, dependencyVersion }) => { + run: ({ sv, typescript, dependencyVersion }) => { const prettierInstalled = Boolean(dependencyVersion('prettier')); sv.devDependency('eslint', '^9.7.0'); @@ -40,16 +38,16 @@ export default defineAdder({ return generateCode(); }); - if (fs.existsSync(path.join(cwd, '.vscode', 'settings.json'))) { - sv.file('.vscode/settings.json', (content) => { - const { data, generateCode } = parseJson(content); - const validate: string[] | undefined = data['eslint.validate']; - if (validate && !validate.includes('svelte')) { - validate.push('svelte'); - } - return generateCode(); - }); - } + sv.file('.vscode/settings.json', (content) => { + if (!content) return content; + + const { data, generateCode } = parseJson(content); + const validate: string[] | undefined = data['eslint.validate']; + if (validate && !validate.includes('svelte')) { + validate.push('svelte'); + } + return generateCode(); + }); sv.file('eslint.config.js', (content) => { const { ast, generateCode } = parseScript(content); diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 3693e19f..ca4582a9 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -8,16 +8,7 @@ import { utils, Walker } from '@sveltejs/cli-core'; -import { - common, - exports, - imports, - variables, - object, - functions, - kit as kitJs -} from '@sveltejs/cli-core/js'; -// eslint-disable-next-line no-duplicate-imports +import * as js from '@sveltejs/cli-core/js'; import type { AstTypes } from '@sveltejs/cli-core/js'; import { parseScript } from '@sveltejs/cli-core/parsers'; import { addToDemoPage } from '../common.ts'; @@ -88,10 +79,10 @@ export default defineAdder({ sv.file(schemaPath, (content) => { const { ast, generateCode } = parseScript(content); - const createTable = (name: string) => functions.call(TABLE_TYPE[drizzleDialect], [name]); + const createTable = (name: string) => js.functions.call(TABLE_TYPE[drizzleDialect], [name]); - const userDecl = variables.declaration(ast, 'const', 'user', createTable('user')); - const sessionDecl = variables.declaration(ast, 'const', 'session', createTable('session')); + const userDecl = js.variables.declaration(ast, 'const', 'user', createTable('user')); + const sessionDecl = js.variables.declaration(ast, 'const', 'session', createTable('session')); const user = exports.namedExport(ast, 'user', userDecl); const session = exports.namedExport(ast, 'session', sessionDecl); @@ -104,10 +95,10 @@ export default defineAdder({ } if (userTable.arguments.length === 1) { - userTable.arguments.push(object.createEmpty()); + userTable.arguments.push(js.object.createEmpty()); } if (sessionTable.arguments.length === 1) { - sessionTable.arguments.push(object.createEmpty()); + sessionTable.arguments.push(js.object.createEmpty()); } const userAttributes = userTable.arguments[1]; @@ -120,78 +111,78 @@ export default defineAdder({ } if (drizzleDialect === 'sqlite') { - imports.addNamed(ast, 'drizzle-orm/sqlite-core', { + js.imports.addNamed(ast, 'drizzle-orm/sqlite-core', { sqliteTable: 'sqliteTable', text: 'text', integer: 'integer' }); - object.overrideProperties(userAttributes, { - id: common.expressionFromString("text('id').primaryKey()") + js.object.overrideProperties(userAttributes, { + id: js.common.expressionFromString("text('id').primaryKey()") }); if (options.demo) { - object.overrideProperties(userAttributes, { - username: common.expressionFromString("text('username').notNull().unique()"), - passwordHash: common.expressionFromString("text('password_hash').notNull()") + js.object.overrideProperties(userAttributes, { + username: js.common.expressionFromString("text('username').notNull().unique()"), + passwordHash: js.common.expressionFromString("text('password_hash').notNull()") }); } - object.overrideProperties(sessionAttributes, { - id: common.expressionFromString("text('id').primaryKey()"), - userId: common.expressionFromString( + js.object.overrideProperties(sessionAttributes, { + id: js.common.expressionFromString("text('id').primaryKey()"), + userId: js.common.expressionFromString( "text('user_id').notNull().references(() => user.id)" ), - expiresAt: common.expressionFromString( + expiresAt: js.common.expressionFromString( "integer('expires_at', { mode: 'timestamp' }).notNull()" ) }); } if (drizzleDialect === 'mysql') { - imports.addNamed(ast, 'drizzle-orm/mysql-core', { + js.imports.addNamed(ast, 'drizzle-orm/mysql-core', { mysqlTable: 'mysqlTable', varchar: 'varchar', datetime: 'datetime' }); - object.overrideProperties(userAttributes, { - id: common.expressionFromString("varchar('id', { length: 255 }).primaryKey()") + js.object.overrideProperties(userAttributes, { + id: js.common.expressionFromString("varchar('id', { length: 255 }).primaryKey()") }); if (options.demo) { - object.overrideProperties(userAttributes, { - username: common.expressionFromString( + js.object.overrideProperties(userAttributes, { + username: js.common.expressionFromString( "varchar('username', { length: 32 }).notNull().unique()" ), - passwordHash: common.expressionFromString( + passwordHash: js.common.expressionFromString( "varchar('password_hash', { length: 255 }).notNull()" ) }); } - object.overrideProperties(sessionAttributes, { - id: common.expressionFromString("varchar('id', { length: 255 }).primaryKey()"), - userId: common.expressionFromString( + js.object.overrideProperties(sessionAttributes, { + id: js.common.expressionFromString("varchar('id', { length: 255 }).primaryKey()"), + userId: js.common.expressionFromString( "varchar('user_id', { length: 255 }).notNull().references(() => user.id)" ), - expiresAt: common.expressionFromString("datetime('expires_at').notNull()") + expiresAt: js.common.expressionFromString("datetime('expires_at').notNull()") }); } if (drizzleDialect === 'postgresql') { - imports.addNamed(ast, 'drizzle-orm/pg-core', { + js.imports.addNamed(ast, 'drizzle-orm/pg-core', { pgTable: 'pgTable', text: 'text', timestamp: 'timestamp' }); - object.overrideProperties(userAttributes, { - id: common.expressionFromString("text('id').primaryKey()") + js.object.overrideProperties(userAttributes, { + id: js.common.expressionFromString("text('id').primaryKey()") }); if (options.demo) { - object.overrideProperties(userAttributes, { - username: common.expressionFromString("text('username').notNull().unique()"), - passwordHash: common.expressionFromString("text('password_hash').notNull()") + js.object.overrideProperties(userAttributes, { + username: js.common.expressionFromString("text('username').notNull().unique()"), + passwordHash: js.common.expressionFromString("text('password_hash').notNull()") }); } - object.overrideProperties(sessionAttributes, { - id: common.expressionFromString("text('id').primaryKey()"), - userId: common.expressionFromString( + js.object.overrideProperties(sessionAttributes, { + id: js.common.expressionFromString("text('id').primaryKey()"), + userId: js.common.expressionFromString( "text('user_id').notNull().references(() => user.id)" ), - expiresAt: common.expressionFromString( + expiresAt: js.common.expressionFromString( "timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()" ) }); @@ -212,16 +203,16 @@ export default defineAdder({ sv.file(`${kit?.libDirectory}/server/auth.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); - imports.addNamespace(ast, '$lib/server/db/schema', 'table'); - imports.addNamed(ast, '$lib/server/db', { db: 'db' }); - imports.addNamed(ast, '@oslojs/encoding', { + js.imports.addNamespace(ast, '$lib/server/db/schema', 'table'); + js.imports.addNamed(ast, '$lib/server/db', { db: 'db' }); + js.imports.addNamed(ast, '@oslojs/encoding', { encodeBase64url: 'encodeBase64url', encodeHexLowerCase: 'encodeHexLowerCase' }); - imports.addNamed(ast, '@oslojs/crypto/sha2', { sha256: 'sha256' }); - imports.addNamed(ast, 'drizzle-orm', { eq: 'eq' }); + js.imports.addNamed(ast, '@oslojs/crypto/sha2', { sha256: 'sha256' }); + js.imports.addNamed(ast, 'drizzle-orm', { eq: 'eq' }); if (typescript) { - imports.addNamed(ast, '@sveltejs/kit', { RequestEvent: 'RequestEvent' }, true); + js.imports.addNamed(ast, '@sveltejs/kit', { RequestEvent: 'RequestEvent' }, true); } const ms = new MagicString(generateCode().trim()); @@ -345,13 +336,13 @@ export default defineAdder({ sv.file('src/app.d.ts', (content) => { const { ast, generateCode } = parseScript(content); - const locals = kitJs.addGlobalAppInterface(ast, 'Locals'); + const locals = js.kit.addGlobalAppInterface(ast, 'Locals'); if (!locals) { throw new Error('Failed detecting `locals` interface in `src/app.d.ts`'); } - const user = locals.body.body.find((prop) => common.hasTypeProp('user', prop)); - const session = locals.body.body.find((prop) => common.hasTypeProp('session', prop)); + const user = locals.body.body.find((prop) => js.common.hasTypeProp('user', prop)); + const session = locals.body.body.find((prop) => js.common.hasTypeProp('session', prop)); if (!user) { locals.body.body.push(createLuciaType('user')); @@ -365,8 +356,8 @@ export default defineAdder({ sv.file(`src/hooks.server.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); - imports.addNamespace(ast, '$lib/server/auth.js', 'auth'); - kitJs.addHooksHandle(ast, typescript, 'handleAuth', getAuthHandleContent()); + js.imports.addNamespace(ast, '$lib/server/auth.js', 'auth'); + js.kit.addHooksHandle(ast, typescript, 'handleAuth', getAuthHandleContent()); return generateCode(); }); diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts index e2720e85..3a828834 100644 --- a/packages/adders/paraglide/index.ts +++ b/packages/adders/paraglide/index.ts @@ -1,5 +1,3 @@ -import fs from 'node:fs'; -import path from 'node:path'; import MagicString from 'magic-string'; import { colors, dedent, defineAdder, defineAdderOptions, log, utils } from '@sveltejs/cli-core'; import { @@ -68,28 +66,28 @@ export default defineAdder({ setup: ({ kit, unsupported }) => { if (!kit) unsupported('Requires SvelteKit'); }, - run: ({ sv, cwd, options, typescript, kit, dependencyVersion }) => { + run: ({ sv, options, typescript, kit, dependencyVersion }) => { const ext = typescript ? 'ts' : 'js'; if (!kit) throw new Error('SvelteKit is required'); sv.dependency('@inlang/paraglide-sveltekit', '^0.11.1'); - if (!fs.existsSync(path.join(cwd, 'project.inlang/settings.json'))) { - sv.file('project.inlang/settings.json', (content) => { - const { data, generateCode } = parseJson(content); + sv.file('project.inlang/settings.json', (content) => { + if (content) return content; - for (const key in DEFAULT_INLANG_PROJECT) { - data[key] = DEFAULT_INLANG_PROJECT[key as keyof typeof DEFAULT_INLANG_PROJECT]; - } - const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); - const sourceLanguageTag = validLanguageTags[0]; + const { data, generateCode } = parseJson(content); - data.sourceLanguageTag = sourceLanguageTag; - data.languageTags = validLanguageTags; + for (const key in DEFAULT_INLANG_PROJECT) { + data[key] = DEFAULT_INLANG_PROJECT[key as keyof typeof DEFAULT_INLANG_PROJECT]; + } + const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); + const sourceLanguageTag = validLanguageTags[0]; - return generateCode(); - }); - } + data.sourceLanguageTag = sourceLanguageTag; + data.languageTags = validLanguageTags; + + return generateCode(); + }); // add the vite plugin sv.file(`vite.config.${ext}`, (content) => { diff --git a/packages/adders/playwright/index.ts b/packages/adders/playwright/index.ts index f1903135..db3833f0 100644 --- a/packages/adders/playwright/index.ts +++ b/packages/adders/playwright/index.ts @@ -1,5 +1,3 @@ -import fs from 'node:fs'; -import { join } from 'node:path'; import { dedent, defineAdder, log } from '@sveltejs/cli-core'; import { common, exports, imports, object } from '@sveltejs/cli-core/js'; import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; @@ -8,7 +6,7 @@ export default defineAdder({ id: 'playwright', homepage: 'https://playwright.dev', options: {}, - run: ({ sv, cwd, typescript }) => { + run: ({ sv, typescript }) => { const ext = typescript ? 'ts' : 'js'; sv.devDependency('@playwright/test', '^1.45.3'); @@ -25,12 +23,11 @@ export default defineAdder({ return generateCode(); }); - if (fs.existsSync(join(cwd, '.gitignore'))) { - sv.file('.gitignore', (content) => { - if (content.includes('test-results')) return content; - return 'test-results\n' + content.trim(); - }); - } + sv.file('.gitignore', (content) => { + if (!content) return content; + if (content.includes('test-results')) return content; + return 'test-results\n' + content.trim(); + }); sv.file(`e2e/demo.test.${ext}`, (content) => { if (content) return content; diff --git a/packages/adders/prettier/index.ts b/packages/adders/prettier/index.ts index d963e548..2a5c21cf 100644 --- a/packages/adders/prettier/index.ts +++ b/packages/adders/prettier/index.ts @@ -7,13 +7,9 @@ export default defineAdder({ homepage: 'https://prettier.io', options: {}, run: ({ sv, dependencyVersion }) => { - const eslintInstalled = hasEslint(dependencyVersion); - sv.devDependency('prettier', '^3.3.2'); sv.devDependency('prettier-plugin-svelte', '^3.2.6'); - if (eslintInstalled) sv.devDependency('eslint-config-prettier', '^9.1.0'); - sv.file('.prettierignore', (content) => { if (content) return content; return dedent` @@ -51,6 +47,9 @@ export default defineAdder({ return generateCode(); }); + const eslintVersion = dependencyVersion('eslint'); + const eslintInstalled = hasEslint(eslintVersion); + sv.file('package.json', (content) => { const { data, generateCode } = parseJson(content); @@ -59,7 +58,7 @@ export default defineAdder({ const CHECK_CMD = 'prettier --check .'; scripts['format'] ??= 'prettier --write .'; - if (hasEslint(dependencyVersion)) { + if (eslintInstalled) { scripts['lint'] ??= `${CHECK_CMD} && eslint .`; if (!scripts['lint'].includes(CHECK_CMD)) scripts['lint'] += ` && ${CHECK_CMD}`; } else { @@ -68,14 +67,16 @@ export default defineAdder({ return generateCode(); }); - if (dependencyVersion('eslint')?.startsWith(SUPPORTED_ESLINT_VERSION) === false) { + if (eslintVersion?.startsWith(SUPPORTED_ESLINT_VERSION) === false) { log.warn( `An older major version of ${colors.yellow( 'eslint' )} was detected. Skipping ${colors.yellow('eslint-config-prettier')} installation.` ); } + if (eslintInstalled) { + sv.devDependency('eslint-config-prettier', '^9.1.0'); sv.file('eslint.config.js', addEslintConfigPrettier); } } @@ -83,7 +84,6 @@ export default defineAdder({ const SUPPORTED_ESLINT_VERSION = '9'; -function hasEslint(dependencyVersion: (pkg: string) => string | undefined): boolean { - const version = dependencyVersion('eslint'); +function hasEslint(version: string | undefined): boolean { return !!version && version.startsWith(SUPPORTED_ESLINT_VERSION); } diff --git a/packages/adders/tailwindcss/index.ts b/packages/adders/tailwindcss/index.ts index 65ff4e24..0560fa9f 100644 --- a/packages/adders/tailwindcss/index.ts +++ b/packages/adders/tailwindcss/index.ts @@ -38,7 +38,7 @@ const plugins: Plugin[] = [ } ]; -export const options = defineAdderOptions({ +const options = defineAdderOptions({ plugins: { type: 'multiselect', question: 'Which plugins would you like to add?', diff --git a/packages/adders/vitest-addon/index.ts b/packages/adders/vitest-addon/index.ts index a008b99c..ac72be43 100644 --- a/packages/adders/vitest-addon/index.ts +++ b/packages/adders/vitest-addon/index.ts @@ -35,7 +35,7 @@ export default defineAdder({ expect(1 + 2).toBe(3); }); }); - `; + `; }); sv.file(`vite.config.${ext}`, (content) => { diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 154970da..79c646d6 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -61,7 +61,7 @@ export async function applyAddons({ for (const addon of ordered) { workspace = createWorkspace({ ...workspace, options: options[addon.id] }); - const files = await runAddon(workspace, addon, ordered.length > 1); + const files = await runAddon({ workspace, addon, multiple: ordered.length > 1 }); files.forEach((f) => filesToFormat.add(f)); } @@ -87,11 +87,12 @@ export function setupAddons( return adderSetupResults; } -async function runAddon( - workspace: Workspace, - addon: Adder>, - applyMultipleAddons: boolean -): Promise { +type RunAddon = { + workspace: Workspace; + addon: Adder>; + multiple: boolean; +}; +async function runAddon({ addon, multiple, workspace }: RunAddon): Promise { const files = new Set(); // apply default adder options @@ -124,7 +125,7 @@ async function runAddon( execute: async (commandArgs, stdio) => { const { command, args } = resolveCommand(workspace.packageManager, 'execute', commandArgs)!; - const adderPrefix = applyMultipleAddons ? `${addon.id}: ` : ''; + const adderPrefix = multiple ? `${addon.id}: ` : ''; const executedCommand = `${command} ${args.join(' ')}`; if (!TESTING) { p.log.step(`${adderPrefix}Running external command ${pc.gray(`(${executedCommand})`)}`); From a3b6954ce9926bc914a975c357cae7666133ba2e Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Wed, 13 Nov 2024 21:01:37 -0500 Subject: [PATCH 126/126] fix --- packages/adders/lucia/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index ca4582a9..7a6c3b8c 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -84,8 +84,8 @@ export default defineAdder({ const userDecl = js.variables.declaration(ast, 'const', 'user', createTable('user')); const sessionDecl = js.variables.declaration(ast, 'const', 'session', createTable('session')); - const user = exports.namedExport(ast, 'user', userDecl); - const session = exports.namedExport(ast, 'session', sessionDecl); + const user = js.exports.namedExport(ast, 'user', userDecl); + const session = js.exports.namedExport(ast, 'session', sessionDecl); const userTable = getCallExpression(user); const sessionTable = getCallExpression(session);