From 1a06cbedfca27fb4ddda0eb197db7160216318d6 Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 10:00:39 +0200 Subject: [PATCH 01/32] bring ensureNestedProperty --- .../js/object/ensure-nested-property/input.ts | 3 ++ .../object/ensure-nested-property/output.ts | 1 + .../js/object/ensure-nested-property/run.ts | 15 ++++++++ packages/core/tooling/js/object.ts | 38 +++++++++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 packages/core/tests/js/object/ensure-nested-property/input.ts create mode 100644 packages/core/tests/js/object/ensure-nested-property/output.ts create mode 100644 packages/core/tests/js/object/ensure-nested-property/run.ts diff --git a/packages/core/tests/js/object/ensure-nested-property/input.ts b/packages/core/tests/js/object/ensure-nested-property/input.ts new file mode 100644 index 000000000..90fd31b4e --- /dev/null +++ b/packages/core/tests/js/object/ensure-nested-property/input.ts @@ -0,0 +1,3 @@ +const test = { + a: { keep: 'me' } +}; diff --git a/packages/core/tests/js/object/ensure-nested-property/output.ts b/packages/core/tests/js/object/ensure-nested-property/output.ts new file mode 100644 index 000000000..fdf47f478 --- /dev/null +++ b/packages/core/tests/js/object/ensure-nested-property/output.ts @@ -0,0 +1 @@ +const test = { a: { keep: 'me', b: { c: '007' } } }; diff --git a/packages/core/tests/js/object/ensure-nested-property/run.ts b/packages/core/tests/js/object/ensure-nested-property/run.ts new file mode 100644 index 000000000..99d0391f5 --- /dev/null +++ b/packages/core/tests/js/object/ensure-nested-property/run.ts @@ -0,0 +1,15 @@ +import { variables, object, common, type AstTypes } from '@sveltejs/cli-core/js'; + +export function run(ast: AstTypes.Program): void { + const variable = variables.declaration(ast, { + kind: 'const', + name: 'test', + value: object.create({}) + }); + const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; + const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; + object.ensureNestedProperty(objectExpression, { + path: ['a', 'b', 'c'], + value: common.createLiteral('007') + }); +} diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index cd65a172d..ad4f63e3f 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -105,6 +105,44 @@ export function removeProperty( } } +export function ensureNestedProperty( + node: AstTypes.ObjectExpression, + options: { + path: string[]; + value: AstTypes.Expression; + } +): AstTypes.Expression { + let current = node; + + // Navigate/create the path, stopping at the last level + for (let i = 0; i < options.path.length - 1; i++) { + const pathSegment = options.path[i]; + + let nextNode = property(current, { + name: pathSegment, + fallback: create({}) + }); + + // Ensure the next level exists as an ObjectExpression + if (nextNode.type !== 'ObjectExpression') { + nextNode = create({}); + overrideProperty(current, { + name: pathSegment, + value: nextNode + }); + } + + current = nextNode; + } + + // Set the final property + const finalPropertyName = options.path[options.path.length - 1]; + return overrideProperty(current, { + name: finalPropertyName, + value: options.value + }); +} + type ObjectPrimitiveValues = string | number | boolean | undefined | null; type ObjectValues = ObjectPrimitiveValues | Record | ObjectValues[]; type ObjectMap = Record; From b820e8bb2211302c66725ff88a2786804c9017cd Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 10:03:01 +0200 Subject: [PATCH 02/32] rmv `addProperties` --- packages/addons/playwright/index.ts | 4 ++-- packages/addons/sveltekit-adapter/index.ts | 2 +- packages/core/tooling/js/object.ts | 15 --------------- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/packages/addons/playwright/index.ts b/packages/addons/playwright/index.ts index b422c53e7..c40dcf7eb 100644 --- a/packages/addons/playwright/index.ts +++ b/packages/addons/playwright/index.ts @@ -65,10 +65,10 @@ export default defineAddon({ from: '@playwright/test', imports: ['defineConfig'] }); - object.addProperties(defaultExport.arguments[0], { properties: config }); + object.overrideProperties(defaultExport.arguments[0], { properties: config }); } else if (defaultExport.type === 'ObjectExpression') { // if the config is just an object expression, just add the property - object.addProperties(defaultExport, { properties: config }); + object.overrideProperties(defaultExport, { properties: config }); } else { // unexpected config shape log.warn('Unexpected playwright config for playwright add-on. Could not update.'); diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index dab76511b..aa378201d 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -100,7 +100,7 @@ export default defineAddon({ }); } else { // creates the `kit` property when absent - object.addProperties(config, { + object.overrideProperties(config, { properties: { kit: object.create({ adapter: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index ad4f63e3f..90ac48ccf 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -76,21 +76,6 @@ export function overrideProperties( } } -export function addProperties( - node: AstTypes.ObjectExpression, - options: { - properties: Record; - } -): void { - for (const [prop, value] of Object.entries(options.properties)) { - if (value === undefined) continue; - property(node, { - name: prop, - fallback: value - }); - } -} - export function removeProperty( node: AstTypes.ObjectExpression, options: { From 64bdc83e858cd473285b0a535dfeef6589e08904 Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 10:24:47 +0200 Subject: [PATCH 03/32] expose less & align more --- .../js/object/ensure-nested-property/run.ts | 2 +- .../tests/js/object/override-property/run.ts | 10 ++-- packages/core/tooling/js/object.ts | 57 ++++++++++--------- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/packages/core/tests/js/object/ensure-nested-property/run.ts b/packages/core/tests/js/object/ensure-nested-property/run.ts index 99d0391f5..856942be1 100644 --- a/packages/core/tests/js/object/ensure-nested-property/run.ts +++ b/packages/core/tests/js/object/ensure-nested-property/run.ts @@ -8,7 +8,7 @@ export function run(ast: AstTypes.Program): void { }); const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; - object.ensureNestedProperty(objectExpression, { + object.overrideProperty(objectExpression, { path: ['a', 'b', 'c'], value: common.createLiteral('007') }); diff --git a/packages/core/tests/js/object/override-property/run.ts b/packages/core/tests/js/object/override-property/run.ts index 29f513e10..35debe5a2 100644 --- a/packages/core/tests/js/object/override-property/run.ts +++ b/packages/core/tests/js/object/override-property/run.ts @@ -12,10 +12,8 @@ export function run(ast: AstTypes.Program): void { name: 'foo', value: common.createLiteral(2) }); - object.overrideProperties(objectExpression, { - properties: { - bar: common.createLiteral('string2'), - lorem: common.createLiteral(false) - } - }); + object.overrideProperties(objectExpression, [ + { name: 'bar', value: common.createLiteral('string2') }, + { name: 'lorem', value: common.createLiteral(false) } + ]); } diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index 90ac48ccf..91e5ca3d2 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -42,13 +42,18 @@ export function property( return propertyValue; } +type OverridePropertyOptions = { value: T } & ( + | { name: string; path?: never } + | { name?: never; path: string[] } +); export function overrideProperty( node: AstTypes.ObjectExpression, - options: { - name: string; - value: T; - } + options: OverridePropertyOptions ): T { + if (options.path) { + return ensureNestedProperty(node, options); + } + const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); const prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); @@ -66,37 +71,21 @@ export function overrideProperty( export function overrideProperties( node: AstTypes.ObjectExpression, - options: { - properties: Record; - } + options: Array> ): void { - for (const [prop, value] of Object.entries(options.properties)) { - if (value === undefined) continue; - overrideProperty(node, { name: prop, value }); + for (const option of options) { + overrideProperty(node, option); } } -export function removeProperty( - node: AstTypes.ObjectExpression, - options: { - name: string; - } -): void { - const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); - const propIdx = properties.findIndex((x) => (x.key as AstTypes.Identifier).name === options.name); - - if (propIdx !== -1) { - node.properties.splice(propIdx, 1); - } -} - -export function ensureNestedProperty( +// internal helper function +function ensureNestedProperty( node: AstTypes.ObjectExpression, options: { path: string[]; - value: AstTypes.Expression; + value: T; } -): AstTypes.Expression { +): T { let current = node; // Navigate/create the path, stopping at the last level @@ -128,6 +117,20 @@ export function ensureNestedProperty( }); } +export function removeProperty( + node: AstTypes.ObjectExpression, + options: { + name: string; + } +): void { + const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); + const propIdx = properties.findIndex((x) => (x.key as AstTypes.Identifier).name === options.name); + + if (propIdx !== -1) { + node.properties.splice(propIdx, 1); + } +} + type ObjectPrimitiveValues = string | number | boolean | undefined | null; type ObjectValues = ObjectPrimitiveValues | Record | ObjectValues[]; type ObjectMap = Record; From 0d9962805527a319a7459f6e8c874f4b2817381a Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 10:36:02 +0200 Subject: [PATCH 04/32] update lucia --- packages/addons/lucia/index.ts | 126 +++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 53 deletions(-) diff --git a/packages/addons/lucia/index.ts b/packages/addons/lucia/index.ts index 739564ecb..1f56a1c1c 100644 --- a/packages/addons/lucia/index.ts +++ b/packages/addons/lucia/index.ts @@ -144,92 +144,112 @@ export default defineAddon({ from: 'drizzle-orm/sqlite-core', imports: ['sqliteTable', 'text', 'integer'] }); - js.object.overrideProperties(userAttributes, { - properties: { - id: js.common.parseExpression("text('id').primaryKey()") - } - }); + js.object.overrideProperties(userAttributes, [ + { name: 'id', value: js.common.parseExpression("text('id').primaryKey()") } + ]); if (options.demo) { - js.object.overrideProperties(userAttributes, { - properties: { - username: js.common.parseExpression("text('username').notNull().unique()"), - passwordHash: js.common.parseExpression("text('password_hash').notNull()") + js.object.overrideProperties(userAttributes, [ + { + name: 'username', + value: js.common.parseExpression("text('username').notNull().unique()") + }, + { + name: 'passwordHash', + value: js.common.parseExpression("text('password_hash').notNull()") } - }); + ]); } - js.object.overrideProperties(sessionAttributes, { - properties: { - id: js.common.parseExpression("text('id').primaryKey()"), - userId: js.common.parseExpression( - "text('user_id').notNull().references(() => user.id)" - ), - expiresAt: js.common.parseExpression( + js.object.overrideProperties(sessionAttributes, [ + { name: 'id', value: js.common.parseExpression("text('id').primaryKey()") }, + { + name: 'userId', + value: js.common.parseExpression("text('user_id').notNull().references(() => user.id)") + }, + { + name: 'expiresAt', + value: js.common.parseExpression( "integer('expires_at', { mode: 'timestamp' }).notNull()" ) } - }); + ]); } if (drizzleDialect === 'mysql') { js.imports.addNamed(ast, { from: 'drizzle-orm/mysql-core', imports: ['mysqlTable', 'varchar', 'datetime'] }); - js.object.overrideProperties(userAttributes, { - properties: { - id: js.common.parseExpression("varchar('id', { length: 255 }).primaryKey()") + js.object.overrideProperties(userAttributes, [ + { + name: 'id', + value: js.common.parseExpression("varchar('id', { length: 255 }).primaryKey()") } - }); + ]); if (options.demo) { - js.object.overrideProperties(userAttributes, { - properties: { - username: js.common.parseExpression( + js.object.overrideProperties(userAttributes, [ + { + name: 'username', + value: js.common.parseExpression( "varchar('username', { length: 32 }).notNull().unique()" - ), - passwordHash: js.common.parseExpression( + ) + }, + { + name: 'passwordHash', + value: js.common.parseExpression( "varchar('password_hash', { length: 255 }).notNull()" ) } - }); + ]); } - js.object.overrideProperties(sessionAttributes, { - properties: { - id: js.common.parseExpression("varchar('id', { length: 255 }).primaryKey()"), - userId: js.common.parseExpression( + js.object.overrideProperties(sessionAttributes, [ + { + name: 'id', + value: js.common.parseExpression("varchar('id', { length: 255 }).primaryKey()") + }, + { + name: 'userId', + value: js.common.parseExpression( "varchar('user_id', { length: 255 }).notNull().references(() => user.id)" - ), - expiresAt: js.common.parseExpression("datetime('expires_at').notNull()") + ) + }, + { + name: 'expiresAt', + value: js.common.parseExpression("datetime('expires_at').notNull()") } - }); + ]); } if (drizzleDialect === 'postgresql') { js.imports.addNamed(ast, { from: 'drizzle-orm/pg-core', imports: ['pgTable', 'text', 'timestamp'] }); - js.object.overrideProperties(userAttributes, { - properties: { - id: js.common.parseExpression("text('id').primaryKey()") - } - }); + js.object.overrideProperties(userAttributes, [ + { name: 'id', value: js.common.parseExpression("text('id').primaryKey()") } + ]); if (options.demo) { - js.object.overrideProperties(userAttributes, { - properties: { - username: js.common.parseExpression("text('username').notNull().unique()"), - passwordHash: js.common.parseExpression("text('password_hash').notNull()") + js.object.overrideProperties(userAttributes, [ + { + name: 'username', + value: js.common.parseExpression("text('username').notNull().unique()") + }, + { + name: 'passwordHash', + value: js.common.parseExpression("text('password_hash').notNull()") } - }); + ]); } - js.object.overrideProperties(sessionAttributes, { - properties: { - id: js.common.parseExpression("text('id').primaryKey()"), - userId: js.common.parseExpression( - "text('user_id').notNull().references(() => user.id)" - ), - expiresAt: js.common.parseExpression( + js.object.overrideProperties(sessionAttributes, [ + { name: 'id', value: js.common.parseExpression("text('id').primaryKey()") }, + { + name: 'userId', + value: js.common.parseExpression("text('user_id').notNull().references(() => user.id)") + }, + { + name: 'expiresAt', + value: js.common.parseExpression( "timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()" ) } - }); + ]); } let code = generateCode(); From 72578983b9bf5e3f337baca5941416c99dd2bbf7 Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 10:49:41 +0200 Subject: [PATCH 05/32] playwrite --- packages/addons/playwright/index.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/addons/playwright/index.ts b/packages/addons/playwright/index.ts index c40dcf7eb..43f0dd770 100644 --- a/packages/addons/playwright/index.ts +++ b/packages/addons/playwright/index.ts @@ -25,9 +25,9 @@ export default defineAddon({ }); sv.file('.gitignore', (content) => { - if (!content) return content; + if (!content) return 'test-results\n'; if (content.includes('test-results')) return content; - return 'test-results\n' + content.trim(); + return content.trim() + '\ntest-results\n'; }); sv.file(`e2e/demo.test.${ext}`, (content) => { @@ -48,27 +48,27 @@ export default defineAddon({ const defineConfig = common.parseExpression('defineConfig({})'); const { value: defaultExport } = exports.createDefault(ast, { fallback: defineConfig }); - const config = { - webServer: object.create({ + const webServerConfig = { + name: 'webServer', + value: object.create({ command: 'npm run build && npm run preview', port: 4173 - }), - testDir: common.createLiteral('e2e') + }) }; + const testDirConfig = { name: 'testDir', value: common.createLiteral('e2e') }; if ( defaultExport.type === 'CallExpression' && defaultExport.arguments[0]?.type === 'ObjectExpression' ) { // uses the `defineConfig` helper - imports.addNamed(ast, { - from: '@playwright/test', - imports: ['defineConfig'] - }); - object.overrideProperties(defaultExport.arguments[0], { properties: config }); + imports.addNamed(ast, { imports: ['defineConfig'], from: '@playwright/test' }); + object.overrideProperty(defaultExport.arguments[0], webServerConfig); + object.overrideProperty(defaultExport.arguments[0], testDirConfig); } else if (defaultExport.type === 'ObjectExpression') { - // if the config is just an object expression, just add the property - object.overrideProperties(defaultExport, { properties: config }); + // if the config is just an object expression, just add the properties + object.overrideProperty(defaultExport, webServerConfig); + object.overrideProperty(defaultExport, testDirConfig); } else { // unexpected config shape log.warn('Unexpected playwright config for playwright add-on. Could not update.'); From 788668777c00a00f85e04c56ee86e9fd86a77ab7 Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 10:51:06 +0200 Subject: [PATCH 06/32] adapter --- packages/addons/sveltekit-adapter/index.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index aa378201d..6b6d64b01 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -93,19 +93,17 @@ export default defineAddon({ } // only overrides the `adapter` property so we can reset it's args - object.overrideProperties(kitConfig.value, { - properties: { - adapter: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) - } + object.overrideProperty(kitConfig.value, { + name: 'adapter', + value: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) }); } else { // creates the `kit` property when absent - object.overrideProperties(config, { - properties: { - kit: object.create({ - adapter: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) - }) - } + object.overrideProperty(config, { + name: 'kit', + value: object.create({ + adapter: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) + }) }); } From 719e117c887cff9f169430293b3ec4e73cd99895 Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 10:57:59 +0200 Subject: [PATCH 07/32] refacto to use overrideProperty & path --- packages/addons/sveltekit-adapter/index.ts | 29 +++------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 6b6d64b01..265795222 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -80,32 +80,11 @@ export default defineAddon({ } const { value: config } = exports.createDefault(ast, { fallback: object.create({}) }); - const kitConfig = config.properties.find( - (p) => p.type === 'Property' && p.key.type === 'Identifier' && p.key.name === 'kit' - ) as AstTypes.Property | undefined; - if (kitConfig && kitConfig.value.type === 'ObjectExpression') { - const adapterProp = kitConfig.value.properties.find( - (p) => p.type === 'Property' && p.key.type === 'Identifier' && p.key.name === 'adapter' - ); - if (adapterProp) { - adapterProp.leadingComments = []; - } - - // only overrides the `adapter` property so we can reset it's args - object.overrideProperty(kitConfig.value, { - name: 'adapter', - value: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) - }); - } else { - // creates the `kit` property when absent - object.overrideProperty(config, { - name: 'kit', - value: object.create({ - adapter: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) - }) - }); - } + object.overrideProperty(config, { + path: ['kit', 'adapter'], + value: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) + }); return generateCode(); }); From dc2fa9cfebc4d9a6a6c702d45a0d7c4e864ab30f Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 11:05:28 +0200 Subject: [PATCH 08/32] discard one change that is not part --- packages/addons/playwright/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/addons/playwright/index.ts b/packages/addons/playwright/index.ts index 43f0dd770..59a30c764 100644 --- a/packages/addons/playwright/index.ts +++ b/packages/addons/playwright/index.ts @@ -25,9 +25,9 @@ export default defineAddon({ }); sv.file('.gitignore', (content) => { - if (!content) return 'test-results\n'; + if (!content) return content; if (content.includes('test-results')) return content; - return content.trim() + '\ntest-results\n'; + return 'test-results\n' + content.trim(); }); sv.file(`e2e/demo.test.${ext}`, (content) => { From b4f1916a39bcc0d70f998a141a1b0f72200e1b1f Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 11:07:06 +0200 Subject: [PATCH 09/32] linting friend --- packages/addons/sveltekit-adapter/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 265795222..ccc7eb11e 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -1,5 +1,5 @@ import { defineAddon, defineAddonOptions } from '@sveltejs/cli-core'; -import { exports, functions, imports, object, type AstTypes } from '@sveltejs/cli-core/js'; +import { exports, functions, imports, object } from '@sveltejs/cli-core/js'; import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; type Adapter = { From fb8a23d70758fefc8f9e77a34e0799b138522c47 Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 11:07:09 +0200 Subject: [PATCH 10/32] changeset --- .changeset/eighty-deer-bake.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/eighty-deer-bake.md diff --git a/.changeset/eighty-deer-bake.md b/.changeset/eighty-deer-bake.md new file mode 100644 index 000000000..4b5fe9cbc --- /dev/null +++ b/.changeset/eighty-deer-bake.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +chore: streamline object exports function From 27741efc6d54457a475186610c711dc21caf784d Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 11:18:59 +0200 Subject: [PATCH 11/32] rmv leading comment --- .changeset/eighty-deer-bake.md | 2 +- packages/addons/sveltekit-adapter/index.ts | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.changeset/eighty-deer-bake.md b/.changeset/eighty-deer-bake.md index 4b5fe9cbc..45d6a7dc7 100644 --- a/.changeset/eighty-deer-bake.md +++ b/.changeset/eighty-deer-bake.md @@ -2,4 +2,4 @@ 'sv': patch --- -chore: streamline object exports function +chore(core): streamline object helpers diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index ccc7eb11e..177586ca7 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -1,5 +1,5 @@ import { defineAddon, defineAddonOptions } from '@sveltejs/cli-core'; -import { exports, functions, imports, object } from '@sveltejs/cli-core/js'; +import { exports, functions, imports, object, type AstTypes } from '@sveltejs/cli-core/js'; import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; type Adapter = { @@ -81,6 +81,20 @@ export default defineAddon({ const { value: config } = exports.createDefault(ast, { fallback: object.create({}) }); + // remove leading comments from the `adapter` property + const kitConfig = config.properties.find( + (p) => p.type === 'Property' && p.key.type === 'Identifier' && p.key.name === 'kit' + ) as AstTypes.Property | undefined; + if (kitConfig && kitConfig.value.type === 'ObjectExpression') { + const adapterProp = kitConfig.value.properties.find( + (p) => p.type === 'Property' && p.key.type === 'Identifier' && p.key.name === 'adapter' + ); + if (adapterProp) { + adapterProp.leadingComments = []; + } + } + + // override the `adapter` property object.overrideProperty(config, { path: ['kit', 'adapter'], value: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) From 620a8cc7d192d789d6e86273e861f3aa75ff79e5 Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 13:52:42 +0200 Subject: [PATCH 12/32] have a way to transform property --- packages/addons/sveltekit-adapter/index.ts | 26 ++++++-------- .../core/tests/js/object/transform/input.ts | 3 ++ .../core/tests/js/object/transform/output.ts | 1 + .../core/tests/js/object/transform/run.ts | 19 ++++++++++ packages/core/tooling/js/object.ts | 36 ++++++++++++------- 5 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 packages/core/tests/js/object/transform/input.ts create mode 100644 packages/core/tests/js/object/transform/output.ts create mode 100644 packages/core/tests/js/object/transform/run.ts diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 177586ca7..418fecc15 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -1,5 +1,5 @@ import { defineAddon, defineAddonOptions } from '@sveltejs/cli-core'; -import { exports, functions, imports, object, type AstTypes } from '@sveltejs/cli-core/js'; +import { exports, functions, imports, object } from '@sveltejs/cli-core/js'; import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; type Adapter = { @@ -81,23 +81,19 @@ export default defineAddon({ const { value: config } = exports.createDefault(ast, { fallback: object.create({}) }); - // remove leading comments from the `adapter` property - const kitConfig = config.properties.find( - (p) => p.type === 'Property' && p.key.type === 'Identifier' && p.key.name === 'kit' - ) as AstTypes.Property | undefined; - if (kitConfig && kitConfig.value.type === 'ObjectExpression') { - const adapterProp = kitConfig.value.properties.find( - (p) => p.type === 'Property' && p.key.type === 'Identifier' && p.key.name === 'adapter' - ); - if (adapterProp) { - adapterProp.leadingComments = []; - } - } - // override the `adapter` property object.overrideProperty(config, { path: ['kit', 'adapter'], - value: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) + value: functions.createCall({ + name: adapterName, + args: [], + useIdentifiers: true + }), + transform: (p) => { + // reset the comment for non-auto adapters + if (adapter.package !== 'adapter-auto') p.leadingComments = []; + return p; + } }); return generateCode(); diff --git a/packages/core/tests/js/object/transform/input.ts b/packages/core/tests/js/object/transform/input.ts new file mode 100644 index 000000000..90fd31b4e --- /dev/null +++ b/packages/core/tests/js/object/transform/input.ts @@ -0,0 +1,3 @@ +const test = { + a: { keep: 'me' } +}; diff --git a/packages/core/tests/js/object/transform/output.ts b/packages/core/tests/js/object/transform/output.ts new file mode 100644 index 000000000..8b341273b --- /dev/null +++ b/packages/core/tests/js/object/transform/output.ts @@ -0,0 +1 @@ +const test = { a: { keep: 'me', b: { /*aka: bond, james bond*/ c: '007' } } }; diff --git a/packages/core/tests/js/object/transform/run.ts b/packages/core/tests/js/object/transform/run.ts new file mode 100644 index 000000000..216fd06cb --- /dev/null +++ b/packages/core/tests/js/object/transform/run.ts @@ -0,0 +1,19 @@ +import { variables, object, common, type AstTypes } from '@sveltejs/cli-core/js'; + +export function run(ast: AstTypes.Program): void { + const variable = variables.declaration(ast, { + kind: 'const', + name: 'test', + value: object.create({}) + }); + const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; + const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; + object.overrideProperty(objectExpression, { + path: ['a', 'b', 'c'], + value: common.createLiteral('007'), + transform: (p) => { + p.leadingComments = [{ type: 'Block', value: 'aka: bond, james bond' }]; + return p; + } + }); +} diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index 91e5ca3d2..8c4a8104a 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -7,14 +7,16 @@ export function property( options: { name: string; fallback: T; + transform?: (prop: AstTypes.Property) => AstTypes.Property; } ): T { const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); let prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); - let propertyValue: T; if (prop) { - propertyValue = prop.value as T; + if (options.transform) { + prop = options.transform(prop); + } } else { let isShorthand = false; if (options.fallback.type === 'Identifier') { @@ -22,7 +24,6 @@ export function property( isShorthand = identifier.name === options.name; } - propertyValue = options.fallback; prop = { type: 'Property', shorthand: isShorthand, @@ -30,22 +31,26 @@ export function property( type: 'Identifier', name: options.name }, - value: propertyValue, + value: options.fallback, kind: 'init', computed: false, method: false }; + if (options.transform) { + prop = options.transform(prop); + } + node.properties.push(prop); } - return propertyValue; + return prop.value as T; } -type OverridePropertyOptions = { value: T } & ( - | { name: string; path?: never } - | { name?: never; path: string[] } -); +type OverridePropertyOptions = { + value: T; + transform?: (value: AstTypes.Property) => AstTypes.Property; +} & ({ name: string; path?: never } | { name?: never; path: string[] }); export function overrideProperty( node: AstTypes.ObjectExpression, options: OverridePropertyOptions @@ -55,17 +60,22 @@ export function overrideProperty( } const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); - const prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); + let prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); if (!prop) { return property(node, { name: options.name, - fallback: options.value + fallback: options.value, + transform: options.transform }); } prop.value = options.value; + if (options.transform) { + prop = options.transform(prop); + } + return options.value; } @@ -84,6 +94,7 @@ function ensureNestedProperty( options: { path: string[]; value: T; + transform?: (value: AstTypes.Property) => AstTypes.Property; } ): T { let current = node; @@ -113,7 +124,8 @@ function ensureNestedProperty( const finalPropertyName = options.path[options.path.length - 1]; return overrideProperty(current, { name: finalPropertyName, - value: options.value + value: options.value, + transform: options.transform }); } From 1191b68ccf3df583f7e653120028c59234762a3d Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 2 Sep 2025 13:59:30 +0200 Subject: [PATCH 13/32] fix naming --- packages/addons/sveltekit-adapter/index.ts | 6 +----- packages/core/tooling/js/object.ts | 6 +++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 418fecc15..b3a5de382 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -84,11 +84,7 @@ export default defineAddon({ // override the `adapter` property object.overrideProperty(config, { path: ['kit', 'adapter'], - value: functions.createCall({ - name: adapterName, - args: [], - useIdentifiers: true - }), + value: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }), transform: (p) => { // reset the comment for non-auto adapters if (adapter.package !== 'adapter-auto') p.leadingComments = []; diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index 8c4a8104a..9bc8b1f58 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -7,7 +7,7 @@ export function property( options: { name: string; fallback: T; - transform?: (prop: AstTypes.Property) => AstTypes.Property; + transform?: (property: AstTypes.Property) => AstTypes.Property; } ): T { const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); @@ -49,7 +49,7 @@ export function property( type OverridePropertyOptions = { value: T; - transform?: (value: AstTypes.Property) => AstTypes.Property; + transform?: (property: AstTypes.Property) => AstTypes.Property; } & ({ name: string; path?: never } | { name?: never; path: string[] }); export function overrideProperty( node: AstTypes.ObjectExpression, @@ -94,7 +94,7 @@ function ensureNestedProperty( options: { path: string[]; value: T; - transform?: (value: AstTypes.Property) => AstTypes.Property; + transform?: (property: AstTypes.Property) => AstTypes.Property; } ): T { let current = node; From aa7304e618842b2263c5bceb751f19fc61a4c9d7 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sat, 6 Sep 2025 15:01:35 +0200 Subject: [PATCH 14/32] remove unused `removeProperty` --- .../core/tests/js/object/remove-property/input.ts | 4 ---- .../core/tests/js/object/remove-property/output.ts | 1 - .../core/tests/js/object/remove-property/run.ts | 13 ------------- packages/core/tooling/js/object.ts | 14 -------------- 4 files changed, 32 deletions(-) delete mode 100644 packages/core/tests/js/object/remove-property/input.ts delete mode 100644 packages/core/tests/js/object/remove-property/output.ts delete mode 100644 packages/core/tests/js/object/remove-property/run.ts diff --git a/packages/core/tests/js/object/remove-property/input.ts b/packages/core/tests/js/object/remove-property/input.ts deleted file mode 100644 index 3967f063c..000000000 --- a/packages/core/tests/js/object/remove-property/input.ts +++ /dev/null @@ -1,4 +0,0 @@ -const test = { - 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 deleted file mode 100644 index f3129ed1e..000000000 --- a/packages/core/tests/js/object/remove-property/output.ts +++ /dev/null @@ -1 +0,0 @@ -const test = {}; diff --git a/packages/core/tests/js/object/remove-property/run.ts b/packages/core/tests/js/object/remove-property/run.ts deleted file mode 100644 index 9f7f2b8d5..000000000 --- a/packages/core/tests/js/object/remove-property/run.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { variables, object, type AstTypes } from '@sveltejs/cli-core/js'; - -export function run(ast: AstTypes.Program): void { - const variable = variables.declaration(ast, { - kind: 'const', - name: 'test', - value: object.create({}) - }); - const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; - const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; - object.removeProperty(objectExpression, { name: 'foo' }); - object.removeProperty(objectExpression, { name: 'bar' }); -} diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index 9bc8b1f58..171da54ef 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -129,20 +129,6 @@ function ensureNestedProperty( }); } -export function removeProperty( - node: AstTypes.ObjectExpression, - options: { - name: string; - } -): void { - const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); - const propIdx = properties.findIndex((x) => (x.key as AstTypes.Identifier).name === options.name); - - if (propIdx !== -1) { - node.properties.splice(propIdx, 1); - } -} - type ObjectPrimitiveValues = string | number | boolean | undefined | null; type ObjectValues = ObjectPrimitiveValues | Record | ObjectValues[]; type ObjectMap = Record; From e0ce18dad866896897341f7053e4e153cc0144e1 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sat, 6 Sep 2025 15:53:39 +0200 Subject: [PATCH 15/32] thx types! --- packages/addons/sveltekit-adapter/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index f09dd24f7..78905e45c 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -81,7 +81,7 @@ export default defineAddon({ value: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }), transform: (p) => { // reset the comment for non-auto adapters - if (adapter.package !== 'adapter-auto') p.leadingComments = []; + if (adapter.package !== '@sveltejs/adapter-auto') p.leadingComments = []; return p; } }); From ebaca7aa48a98b4f2883f9fc7f12344a8faa87a7 Mon Sep 17 00:00:00 2001 From: Manuel Serret Date: Sat, 6 Sep 2025 16:37:24 +0200 Subject: [PATCH 16/32] use `object.create` like syntax --- packages/addons/lucia/index.ts | 134 ++++++--------- packages/addons/mdsvex/index.ts | 5 +- packages/addons/playwright/index.ts | 15 +- packages/addons/sveltekit-adapter/index.ts | 25 ++- .../js/object/ensure-nested-property/run.ts | 7 +- .../tests/js/object/override-property/run.ts | 15 +- .../core/tests/js/object/transform/run.ts | 22 ++- packages/core/tooling/js/object.ts | 154 ++++++++++-------- 8 files changed, 184 insertions(+), 193 deletions(-) diff --git a/packages/addons/lucia/index.ts b/packages/addons/lucia/index.ts index 366177be4..3fa87d713 100644 --- a/packages/addons/lucia/index.ts +++ b/packages/addons/lucia/index.ts @@ -144,112 +144,70 @@ export default defineAddon({ from: 'drizzle-orm/sqlite-core', imports: ['sqliteTable', 'text', 'integer'] }); - js.object.overrideProperties(userAttributes, [ - { name: 'id', value: js.common.parseExpression("text('id').primaryKey()") } - ]); + js.object.overrideProperties(userAttributes, { + id: js.common.parseExpression("text('id').primaryKey()") + }); if (options.demo) { - js.object.overrideProperties(userAttributes, [ - { - name: 'username', - value: js.common.parseExpression("text('username').notNull().unique()") - }, - { - name: 'passwordHash', - value: js.common.parseExpression("text('password_hash').notNull()") - } - ]); + js.object.overrideProperties(userAttributes, { + username: js.common.parseExpression("text('username').notNull().unique()"), + passwordHash: js.common.parseExpression("text('password_hash').notNull()") + }); } - js.object.overrideProperties(sessionAttributes, [ - { name: 'id', value: js.common.parseExpression("text('id').primaryKey()") }, - { - name: 'userId', - value: js.common.parseExpression("text('user_id').notNull().references(() => user.id)") - }, - { - name: 'expiresAt', - value: js.common.parseExpression( - "integer('expires_at', { mode: 'timestamp' }).notNull()" - ) - } - ]); + js.object.overrideProperties(sessionAttributes, { + id: js.common.parseExpression("text('id').primaryKey()"), + userId: js.common.parseExpression("text('user_id').notNull().references(() => user.id)"), + expiresAt: js.common.parseExpression( + "integer('expires_at', { mode: 'timestamp' }).notNull()" + ) + }); } if (drizzleDialect === 'mysql') { js.imports.addNamed(ast, { from: 'drizzle-orm/mysql-core', imports: ['mysqlTable', 'varchar', 'datetime'] }); - js.object.overrideProperties(userAttributes, [ - { - name: 'id', - value: js.common.parseExpression("varchar('id', { length: 255 }).primaryKey()") - } - ]); + js.object.overrideProperties(userAttributes, { + id: js.common.parseExpression("varchar('id', { length: 255 }).primaryKey()") + }); if (options.demo) { - js.object.overrideProperties(userAttributes, [ - { - name: 'username', - value: js.common.parseExpression( - "varchar('username', { length: 32 }).notNull().unique()" - ) - }, - { - name: 'passwordHash', - value: js.common.parseExpression( - "varchar('password_hash', { length: 255 }).notNull()" - ) - } - ]); - } - js.object.overrideProperties(sessionAttributes, [ - { - name: 'id', - value: js.common.parseExpression("varchar('id', { length: 255 }).primaryKey()") - }, - { - name: 'userId', - value: js.common.parseExpression( - "varchar('user_id', { length: 255 }).notNull().references(() => user.id)" + js.object.overrideProperties(userAttributes, { + username: js.common.parseExpression( + "varchar('username', { length: 32 }).notNull().unique()" + ), + passwordHash: js.common.parseExpression( + "varchar('password_hash', { length: 255 }).notNull()" ) - }, - { - name: 'expiresAt', - value: js.common.parseExpression("datetime('expires_at').notNull()") - } - ]); + }); + } + js.object.overrideProperties(sessionAttributes, { + id: js.common.parseExpression("varchar('id', { length: 255 }).primaryKey()"), + userId: js.common.parseExpression( + "varchar('user_id', { length: 255 }).notNull().references(() => user.id)" + ), + expiresAt: js.common.parseExpression("datetime('expires_at').notNull()") + }); } if (drizzleDialect === 'postgresql') { js.imports.addNamed(ast, { from: 'drizzle-orm/pg-core', imports: ['pgTable', 'text', 'timestamp'] }); - js.object.overrideProperties(userAttributes, [ - { name: 'id', value: js.common.parseExpression("text('id').primaryKey()") } - ]); + js.object.overrideProperties(userAttributes, { + id: js.common.parseExpression("text('id').primaryKey()") + }); if (options.demo) { - js.object.overrideProperties(userAttributes, [ - { - name: 'username', - value: js.common.parseExpression("text('username').notNull().unique()") - }, - { - name: 'passwordHash', - value: js.common.parseExpression("text('password_hash').notNull()") - } - ]); + js.object.overrideProperties(userAttributes, { + username: js.common.parseExpression("text('username').notNull().unique()"), + passwordHash: js.common.parseExpression("text('password_hash').notNull()") + }); } - js.object.overrideProperties(sessionAttributes, [ - { name: 'id', value: js.common.parseExpression("text('id').primaryKey()") }, - { - name: 'userId', - value: js.common.parseExpression("text('user_id').notNull().references(() => user.id)") - }, - { - name: 'expiresAt', - value: js.common.parseExpression( - "timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()" - ) - } - ]); + js.object.overrideProperties(sessionAttributes, { + id: js.common.parseExpression("text('id').primaryKey()"), + userId: js.common.parseExpression("text('user_id').notNull().references(() => user.id)"), + expiresAt: js.common.parseExpression( + "timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()" + ) + }); } let code = generateCode(); diff --git a/packages/addons/mdsvex/index.ts b/packages/addons/mdsvex/index.ts index 653d58041..4831c426c 100644 --- a/packages/addons/mdsvex/index.ts +++ b/packages/addons/mdsvex/index.ts @@ -30,9 +30,8 @@ export default defineAddon({ const previousElement = preprocessorArray; preprocessorArray = array.create(); array.append(preprocessorArray, previousElement); - object.overrideProperty(exportDefault, { - name: 'preprocess', - value: preprocessorArray + object.overrideProperties(exportDefault, { + preprocess: preprocessorArray }); } diff --git a/packages/addons/playwright/index.ts b/packages/addons/playwright/index.ts index 59a30c764..ccff9d8c2 100644 --- a/packages/addons/playwright/index.ts +++ b/packages/addons/playwright/index.ts @@ -49,13 +49,12 @@ export default defineAddon({ const { value: defaultExport } = exports.createDefault(ast, { fallback: defineConfig }); const webServerConfig = { - name: 'webServer', - value: object.create({ + webServer: { command: 'npm run build && npm run preview', port: 4173 - }) + } }; - const testDirConfig = { name: 'testDir', value: common.createLiteral('e2e') }; + const testDirConfig = { testDir: 'e2e' }; if ( defaultExport.type === 'CallExpression' && @@ -63,12 +62,12 @@ export default defineAddon({ ) { // uses the `defineConfig` helper imports.addNamed(ast, { imports: ['defineConfig'], from: '@playwright/test' }); - object.overrideProperty(defaultExport.arguments[0], webServerConfig); - object.overrideProperty(defaultExport.arguments[0], testDirConfig); + object.overrideProperties(defaultExport.arguments[0], webServerConfig); + object.overrideProperties(defaultExport.arguments[0], testDirConfig); } else if (defaultExport.type === 'ObjectExpression') { // if the config is just an object expression, just add the properties - object.overrideProperty(defaultExport, webServerConfig); - object.overrideProperty(defaultExport, testDirConfig); + object.overrideProperties(defaultExport, webServerConfig); + object.overrideProperties(defaultExport, testDirConfig); } else { // unexpected config shape log.warn('Unexpected playwright config for playwright add-on. Could not update.'); diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 78905e45c..1c1b4657e 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -76,15 +76,26 @@ export default defineAddon({ const { value: config } = exports.createDefault(ast, { fallback: object.create({}) }); // override the `adapter` property - object.overrideProperty(config, { - path: ['kit', 'adapter'], - value: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }), - transform: (p) => { + object.overrideProperties( + config, + { + kit: { + adapter: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) + } + }, + (property) => { + if ( + property.key.type !== 'Identifier' || + property.key.name !== 'adapter' || + adapter.package === '@sveltejs/adapter-auto' + ) + return property; + // reset the comment for non-auto adapters - if (adapter.package !== '@sveltejs/adapter-auto') p.leadingComments = []; - return p; + property.leadingComments = []; + return property; } - }); + ); return generateCode(); }); diff --git a/packages/core/tests/js/object/ensure-nested-property/run.ts b/packages/core/tests/js/object/ensure-nested-property/run.ts index 856942be1..47d00e02e 100644 --- a/packages/core/tests/js/object/ensure-nested-property/run.ts +++ b/packages/core/tests/js/object/ensure-nested-property/run.ts @@ -1,4 +1,4 @@ -import { variables, object, common, type AstTypes } from '@sveltejs/cli-core/js'; +import { variables, object, type AstTypes } from '@sveltejs/cli-core/js'; export function run(ast: AstTypes.Program): void { const variable = variables.declaration(ast, { @@ -8,8 +8,7 @@ export function run(ast: AstTypes.Program): void { }); const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; - object.overrideProperty(objectExpression, { - path: ['a', 'b', 'c'], - value: common.createLiteral('007') + object.overrideProperties(objectExpression, { + a: { b: { c: '007' } } }); } diff --git a/packages/core/tests/js/object/override-property/run.ts b/packages/core/tests/js/object/override-property/run.ts index 35debe5a2..7b9f06cd1 100644 --- a/packages/core/tests/js/object/override-property/run.ts +++ b/packages/core/tests/js/object/override-property/run.ts @@ -1,4 +1,4 @@ -import { variables, object, common, type AstTypes } from '@sveltejs/cli-core/js'; +import { variables, object, type AstTypes } from '@sveltejs/cli-core/js'; export function run(ast: AstTypes.Program): void { const variable = variables.declaration(ast, { @@ -8,12 +8,11 @@ export function run(ast: AstTypes.Program): void { }); const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; - object.overrideProperty(objectExpression, { - name: 'foo', - value: common.createLiteral(2) + object.overrideProperties(objectExpression, { + foo: 2 + }); + object.overrideProperties(objectExpression, { + bar: 'string2', + lorem: false }); - object.overrideProperties(objectExpression, [ - { name: 'bar', value: common.createLiteral('string2') }, - { name: 'lorem', value: common.createLiteral(false) } - ]); } diff --git a/packages/core/tests/js/object/transform/run.ts b/packages/core/tests/js/object/transform/run.ts index 216fd06cb..3bfb9e605 100644 --- a/packages/core/tests/js/object/transform/run.ts +++ b/packages/core/tests/js/object/transform/run.ts @@ -1,4 +1,4 @@ -import { variables, object, common, type AstTypes } from '@sveltejs/cli-core/js'; +import { variables, object, type AstTypes } from '@sveltejs/cli-core/js'; export function run(ast: AstTypes.Program): void { const variable = variables.declaration(ast, { @@ -8,12 +8,18 @@ export function run(ast: AstTypes.Program): void { }); const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; - object.overrideProperty(objectExpression, { - path: ['a', 'b', 'c'], - value: common.createLiteral('007'), - transform: (p) => { - p.leadingComments = [{ type: 'Block', value: 'aka: bond, james bond' }]; - return p; + + // Create the nested structure a.b.c = '007' + object.overrideProperties( + objectExpression, + { + a: { b: { c: '007' } } + }, + (property) => { + if (property.key.type !== 'Identifier' || property.key.name !== 'c') return property; + + property.leadingComments = [{ type: 'Block', value: 'aka: bond, james bond' }]; + return property; } - }); + ); } diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index 171da54ef..e5531a0f4 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -2,12 +2,14 @@ import type { AstTypes } from '../index.ts'; import * as array from './array.ts'; import * as common from './common.ts'; +type TransformProperty = (property: AstTypes.Property) => AstTypes.Property; + export function property( node: AstTypes.ObjectExpression, options: { name: string; fallback: T; - transform?: (property: AstTypes.Property) => AstTypes.Property; + transform?: TransformProperty; } ): T { const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); @@ -48,17 +50,14 @@ export function property( } type OverridePropertyOptions = { + name: string; value: T; - transform?: (property: AstTypes.Property) => AstTypes.Property; -} & ({ name: string; path?: never } | { name?: never; path: string[] }); -export function overrideProperty( + transform?: TransformProperty; +}; +function overrideProperty( node: AstTypes.ObjectExpression, options: OverridePropertyOptions ): T { - if (options.path) { - return ensureNestedProperty(node, options); - } - const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); let prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); @@ -79,67 +78,46 @@ export function overrideProperty( return options.value; } -export function overrideProperties( - node: AstTypes.ObjectExpression, - options: Array> -): void { - for (const option of options) { - overrideProperty(node, option); - } -} - -// internal helper function -function ensureNestedProperty( - node: AstTypes.ObjectExpression, - options: { - path: string[]; - value: T; - transform?: (property: AstTypes.Property) => AstTypes.Property; - } -): T { - let current = node; - - // Navigate/create the path, stopping at the last level - for (let i = 0; i < options.path.length - 1; i++) { - const pathSegment = options.path[i]; - - let nextNode = property(current, { - name: pathSegment, - fallback: create({}) - }); - - // Ensure the next level exists as an ObjectExpression - if (nextNode.type !== 'ObjectExpression') { - nextNode = create({}); - overrideProperty(current, { - name: pathSegment, - value: nextNode - }); - } - - current = nextNode; - } - - // Set the final property - const finalPropertyName = options.path[options.path.length - 1]; - return overrideProperty(current, { - name: finalPropertyName, - value: options.value, - transform: options.transform - }); -} - type ObjectPrimitiveValues = string | number | boolean | undefined | null; type ObjectValues = ObjectPrimitiveValues | Record | ObjectValues[]; type ObjectMap = Record; export function create(properties: ObjectMap): AstTypes.ObjectExpression { - const objExpression: AstTypes.ObjectExpression = { + const objectExpression: AstTypes.ObjectExpression = { type: 'ObjectExpression', properties: [] }; - const getExpression = (value: any): AstTypes.Expression => { + return populateObjectExpression({ + objectExpression, + properties, + override: false + }); +} + +export function overrideProperties( + objectExpression: AstTypes.ObjectExpression, + properties: ObjectMap, + transform?: TransformProperty +): void { + populateObjectExpression({ + objectExpression, + properties, + override: true, + transform + }); +} + +function populateObjectExpression(options: { + objectExpression: AstTypes.ObjectExpression; + properties: ObjectMap; + override: boolean; + transform?: TransformProperty; +}): AstTypes.ObjectExpression { + const getExpression = ( + value: any, + existingExpression?: AstTypes.ObjectExpression + ): AstTypes.Expression => { let expression: AstTypes.Expression; if (Array.isArray(value)) { expression = array.create(); @@ -148,21 +126,63 @@ export function create(properties: ObjectMap): AstTypes.ObjectExpression { } } else if (typeof value === 'object' && value !== null) { // if the type property is defined, we assume it's an AST type - expression = value.type !== undefined ? (value as AstTypes.Expression) : create(value); + if (value.type !== undefined) { + expression = value as AstTypes.Expression; + } else { + // If we're overriding and there's an existing object expression, merge with it + if ( + options.override && + existingExpression && + existingExpression.type === 'ObjectExpression' + ) { + expression = populateObjectExpression({ + objectExpression: existingExpression, + properties: value, + override: options.override, + transform: options.transform + }); + } else { + expression = populateObjectExpression({ + objectExpression: create({}), + properties: value, + override: options.override, + transform: options.transform + }); + } + } } else { expression = common.createLiteral(value); } return expression; }; - for (const [prop, value] of Object.entries(properties)) { + for (const [prop, value] of Object.entries(options.properties)) { if (value === undefined) continue; - property(objExpression, { - name: prop, - fallback: getExpression(value) - }); + if (options.override) { + // Get existing property to potentially merge with + const existingProperties = options.objectExpression.properties.filter( + (x): x is AstTypes.Property => x.type === 'Property' + ); + const existingProperty = existingProperties.find( + (x) => (x.key as AstTypes.Identifier).name === prop + ); + const existingExpression = + existingProperty?.value.type === 'ObjectExpression' ? existingProperty.value : undefined; + + overrideProperty(options.objectExpression, { + name: prop, + value: getExpression(value, existingExpression), + transform: options.transform + }); + } else { + property(options.objectExpression, { + name: prop, + fallback: getExpression(value), + transform: options.transform + }); + } } - return objExpression; + return options.objectExpression; } From dd9c7a6d1566b59b3885924e0099bb92ede39925 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 13:23:42 +0200 Subject: [PATCH 17/32] add transformProperty <3 --- packages/addons/sveltekit-adapter/index.ts | 30 +++----- .../core/tests/js/object/transform/run.ts | 23 +++--- packages/core/tooling/js/object.ts | 70 +++++++++++-------- 3 files changed, 63 insertions(+), 60 deletions(-) diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 1c1b4657e..c5036fd41 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -1,5 +1,5 @@ import { defineAddon, defineAddonOptions } from '@sveltejs/cli-core'; -import { exports, functions, imports, object } from '@sveltejs/cli-core/js'; +import { exports, imports, object } from '@sveltejs/cli-core/js'; import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; const adapters = [ @@ -75,27 +75,17 @@ export default defineAddon({ const { value: config } = exports.createDefault(ast, { fallback: object.create({}) }); - // override the `adapter` property - object.overrideProperties( - config, - { + // reset the comment for non-auto adapters + if (adapter.package !== '@sveltejs/adapter-auto') { + object.transformProperty(config, { kit: { - adapter: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) + adapter: (property) => { + property.leadingComments = []; + return property; + } } - }, - (property) => { - if ( - property.key.type !== 'Identifier' || - property.key.name !== 'adapter' || - adapter.package === '@sveltejs/adapter-auto' - ) - return property; - - // reset the comment for non-auto adapters - property.leadingComments = []; - return property; - } - ); + }); + } return generateCode(); }); diff --git a/packages/core/tests/js/object/transform/run.ts b/packages/core/tests/js/object/transform/run.ts index 3bfb9e605..9d5eec5bf 100644 --- a/packages/core/tests/js/object/transform/run.ts +++ b/packages/core/tests/js/object/transform/run.ts @@ -10,16 +10,19 @@ export function run(ast: AstTypes.Program): void { const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; // Create the nested structure a.b.c = '007' - object.overrideProperties( - objectExpression, - { - a: { b: { c: '007' } } - }, - (property) => { - if (property.key.type !== 'Identifier' || property.key.name !== 'c') return property; + object.overrideProperties(objectExpression, { + a: { b: { c: '007' } } + }); - property.leadingComments = [{ type: 'Block', value: 'aka: bond, james bond' }]; - return property; + // Transform the 'c' property to add a comment using nested structure + object.transformProperty(objectExpression, { + a: { + b: { + c: (property) => { + property.leadingComments = [{ type: 'Block', value: 'aka: bond, james bond' }]; + return property; + } + } } - ); + }); } diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index e5531a0f4..f4c0e12b2 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -4,22 +4,21 @@ import * as common from './common.ts'; type TransformProperty = (property: AstTypes.Property) => AstTypes.Property; +type TransformMap = { + [key: string]: TransformProperty | TransformMap; +}; + export function property( node: AstTypes.ObjectExpression, options: { name: string; fallback: T; - transform?: TransformProperty; } ): T { const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); let prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); - if (prop) { - if (options.transform) { - prop = options.transform(prop); - } - } else { + if (!prop) { let isShorthand = false; if (options.fallback.type === 'Identifier') { const identifier: AstTypes.Identifier = options.fallback; @@ -39,10 +38,6 @@ export function property( method: false }; - if (options.transform) { - prop = options.transform(prop); - } - node.properties.push(prop); } @@ -52,29 +47,23 @@ export function property( type OverridePropertyOptions = { name: string; value: T; - transform?: TransformProperty; }; function overrideProperty( node: AstTypes.ObjectExpression, options: OverridePropertyOptions ): T { const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); - let prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); + const prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); if (!prop) { return property(node, { name: options.name, - fallback: options.value, - transform: options.transform + fallback: options.value }); } prop.value = options.value; - if (options.transform) { - prop = options.transform(prop); - } - return options.value; } @@ -91,20 +80,32 @@ export function create(properties: ObjectMap): AstTypes.ObjectExpression { return populateObjectExpression({ objectExpression, properties, - override: false + override: false, + transform: false }); } export function overrideProperties( objectExpression: AstTypes.ObjectExpression, - properties: ObjectMap, - transform?: TransformProperty + properties: ObjectMap ): void { populateObjectExpression({ objectExpression, properties, override: true, - transform + transform: false + }); +} + +export function transformProperty( + objectExpression: AstTypes.ObjectExpression, + transformMap: TransformMap +): void { + populateObjectExpression({ + objectExpression, + properties: transformMap, + override: true, + transform: true }); } @@ -112,7 +113,7 @@ function populateObjectExpression(options: { objectExpression: AstTypes.ObjectExpression; properties: ObjectMap; override: boolean; - transform?: TransformProperty; + transform: boolean; }): AstTypes.ObjectExpression { const getExpression = ( value: any, @@ -170,16 +171,25 @@ function populateObjectExpression(options: { const existingExpression = existingProperty?.value.type === 'ObjectExpression' ? existingProperty.value : undefined; - overrideProperty(options.objectExpression, { - name: prop, - value: getExpression(value, existingExpression), - transform: options.transform - }); + if (options.transform && typeof value === 'function') { + // Transform mode - apply the transform function to existing property + if (existingProperty) { + const transformedProperty = value(existingProperty); + const index = options.objectExpression.properties.indexOf(existingProperty); + if (index !== -1) { + options.objectExpression.properties[index] = transformedProperty; + } + } + } else { + overrideProperty(options.objectExpression, { + name: prop, + value: getExpression(value, existingExpression) + }); + } } else { property(options.objectExpression, { name: prop, - fallback: getExpression(value), - transform: options.transform + fallback: getExpression(value) }); } } From ba12fa9c8721de323f9326db556e2c9af434f20c Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 13:26:14 +0200 Subject: [PATCH 18/32] pos --- packages/core/tooling/js/object.ts | 54 +++++++++++++++--------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index f4c0e12b2..bd5815d98 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -8,6 +8,10 @@ type TransformMap = { [key: string]: TransformProperty | TransformMap; }; +type ObjectPrimitiveValues = string | number | boolean | undefined | null; +type ObjectValues = ObjectPrimitiveValues | Record | ObjectValues[]; +type ObjectMap = Record; + export function property( node: AstTypes.ObjectExpression, options: { @@ -44,33 +48,6 @@ export function property( return prop.value as T; } -type OverridePropertyOptions = { - name: string; - value: T; -}; -function overrideProperty( - node: AstTypes.ObjectExpression, - options: OverridePropertyOptions -): T { - const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); - const prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); - - if (!prop) { - return property(node, { - name: options.name, - fallback: options.value - }); - } - - prop.value = options.value; - - return options.value; -} - -type ObjectPrimitiveValues = string | number | boolean | undefined | null; -type ObjectValues = ObjectPrimitiveValues | Record | ObjectValues[]; -type ObjectMap = Record; - export function create(properties: ObjectMap): AstTypes.ObjectExpression { const objectExpression: AstTypes.ObjectExpression = { type: 'ObjectExpression', @@ -109,6 +86,29 @@ export function transformProperty( }); } +type OverridePropertyOptions = { + name: string; + value: T; +}; +function overrideProperty( + node: AstTypes.ObjectExpression, + options: OverridePropertyOptions +): T { + const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); + const prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); + + if (!prop) { + return property(node, { + name: options.name, + fallback: options.value + }); + } + + prop.value = options.value; + + return options.value; +} + function populateObjectExpression(options: { objectExpression: AstTypes.ObjectExpression; properties: ObjectMap; From 2d741e629c84ed51d9fec2ec2fb2e046fe2fae11 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 13:33:30 +0200 Subject: [PATCH 19/32] reduce types --- packages/core/tooling/js/object.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index bd5815d98..81450f2ad 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -14,10 +14,7 @@ type ObjectMap = Record; export function property( node: AstTypes.ObjectExpression, - options: { - name: string; - fallback: T; - } + options: { name: string; fallback: T } ): T { const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); let prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); @@ -86,13 +83,9 @@ export function transformProperty( }); } -type OverridePropertyOptions = { - name: string; - value: T; -}; function overrideProperty( node: AstTypes.ObjectExpression, - options: OverridePropertyOptions + options: { name: string; value: T } ): T { const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); const prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); From 9e46d991e7d1729b5949ccfdb449a62700874315 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 13:55:30 +0200 Subject: [PATCH 20/32] focus object test of object --- .../js/object/ensure-nested-property/run.ts | 14 +++++-------- .../core/tests/js/object/objectTestHelper.ts | 14 +++++++++++++ .../tests/js/object/override-property/run.ts | 21 ++++++------------- packages/core/tests/js/object/property/run.ts | 13 ++++-------- .../core/tests/js/object/transform/run.ts | 15 +++++-------- 5 files changed, 34 insertions(+), 43 deletions(-) create mode 100644 packages/core/tests/js/object/objectTestHelper.ts diff --git a/packages/core/tests/js/object/ensure-nested-property/run.ts b/packages/core/tests/js/object/ensure-nested-property/run.ts index 47d00e02e..6d7de24a1 100644 --- a/packages/core/tests/js/object/ensure-nested-property/run.ts +++ b/packages/core/tests/js/object/ensure-nested-property/run.ts @@ -1,14 +1,10 @@ -import { variables, object, type AstTypes } from '@sveltejs/cli-core/js'; +import { object, type AstTypes } from '@sveltejs/cli-core/js'; +import { getTestObjectExpression } from '../objectTestHelper.ts'; export function run(ast: AstTypes.Program): void { - const variable = variables.declaration(ast, { - kind: 'const', - name: 'test', - value: object.create({}) - }); - const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; - const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; - object.overrideProperties(objectExpression, { + const obj = getTestObjectExpression(ast); + + object.overrideProperties(obj, { a: { b: { c: '007' } } }); } diff --git a/packages/core/tests/js/object/objectTestHelper.ts b/packages/core/tests/js/object/objectTestHelper.ts new file mode 100644 index 000000000..364450d2e --- /dev/null +++ b/packages/core/tests/js/object/objectTestHelper.ts @@ -0,0 +1,14 @@ +import { variables, object, type AstTypes } from '@sveltejs/cli-core/js'; + +export const getTestObjectExpression = (ast: AstTypes.Program) => { + const variable = variables.declaration(ast, { + kind: 'const', + name: 'test', + value: object.create({}) + }); + + const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; + const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; + + return objectExpression; +}; diff --git a/packages/core/tests/js/object/override-property/run.ts b/packages/core/tests/js/object/override-property/run.ts index 7b9f06cd1..508d4848a 100644 --- a/packages/core/tests/js/object/override-property/run.ts +++ b/packages/core/tests/js/object/override-property/run.ts @@ -1,18 +1,9 @@ -import { variables, object, type AstTypes } from '@sveltejs/cli-core/js'; +import { object, type AstTypes } from '@sveltejs/cli-core/js'; +import { getTestObjectExpression } from '../objectTestHelper.ts'; export function run(ast: AstTypes.Program): void { - const variable = variables.declaration(ast, { - kind: 'const', - name: 'test', - value: object.create({}) - }); - const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; - const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; - object.overrideProperties(objectExpression, { - foo: 2 - }); - object.overrideProperties(objectExpression, { - bar: 'string2', - lorem: false - }); + const obj = getTestObjectExpression(ast); + + object.overrideProperties(obj, { foo: 2 }); + object.overrideProperties(obj, { bar: 'string2', lorem: false }); } diff --git a/packages/core/tests/js/object/property/run.ts b/packages/core/tests/js/object/property/run.ts index cf90f5e3c..953aad80e 100644 --- a/packages/core/tests/js/object/property/run.ts +++ b/packages/core/tests/js/object/property/run.ts @@ -1,15 +1,10 @@ -import { variables, object, common, type AstTypes } from '@sveltejs/cli-core/js'; +import { object, common, type AstTypes } from '@sveltejs/cli-core/js'; +import { getTestObjectExpression } from '../objectTestHelper.ts'; export function run(ast: AstTypes.Program): void { - const variable = variables.declaration(ast, { - kind: 'const', - name: 'test', - value: object.create({}) - }); - const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; - const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; + const obj = getTestObjectExpression(ast); - object.property(objectExpression, { + object.property(obj, { name: 'bar', fallback: common.createLiteral('string') }); diff --git a/packages/core/tests/js/object/transform/run.ts b/packages/core/tests/js/object/transform/run.ts index 9d5eec5bf..1344af774 100644 --- a/packages/core/tests/js/object/transform/run.ts +++ b/packages/core/tests/js/object/transform/run.ts @@ -1,21 +1,16 @@ -import { variables, object, type AstTypes } from '@sveltejs/cli-core/js'; +import { object, type AstTypes } from '@sveltejs/cli-core/js'; +import { getTestObjectExpression } from '../objectTestHelper.ts'; export function run(ast: AstTypes.Program): void { - const variable = variables.declaration(ast, { - kind: 'const', - name: 'test', - value: object.create({}) - }); - const objectDeclarator = variable.declarations[0] as AstTypes.VariableDeclarator; - const objectExpression = objectDeclarator.init as AstTypes.ObjectExpression; + const obj = getTestObjectExpression(ast); // Create the nested structure a.b.c = '007' - object.overrideProperties(objectExpression, { + object.overrideProperties(obj, { a: { b: { c: '007' } } }); // Transform the 'c' property to add a comment using nested structure - object.transformProperty(objectExpression, { + object.transformProperty(obj, { a: { b: { c: (property) => { From 2ff1cd605d912a78608edfca08cbd743a7d2e82b Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 13:57:27 +0200 Subject: [PATCH 21/32] check --- packages/core/tests/js/object/objectTestHelper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/tests/js/object/objectTestHelper.ts b/packages/core/tests/js/object/objectTestHelper.ts index 364450d2e..967b15c58 100644 --- a/packages/core/tests/js/object/objectTestHelper.ts +++ b/packages/core/tests/js/object/objectTestHelper.ts @@ -1,6 +1,6 @@ import { variables, object, type AstTypes } from '@sveltejs/cli-core/js'; -export const getTestObjectExpression = (ast: AstTypes.Program) => { +export const getTestObjectExpression = (ast: AstTypes.Program): AstTypes.ObjectExpression => { const variable = variables.declaration(ast, { kind: 'const', name: 'test', From b75a37fd5121d692e9a2e3eca35be050fe83333b Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 14:25:56 +0200 Subject: [PATCH 22/32] playwrite using the latest syntax --- packages/addons/playwright/index.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/addons/playwright/index.ts b/packages/addons/playwright/index.ts index ccff9d8c2..7930b2fdf 100644 --- a/packages/addons/playwright/index.ts +++ b/packages/addons/playwright/index.ts @@ -48,13 +48,13 @@ export default defineAddon({ const defineConfig = common.parseExpression('defineConfig({})'); const { value: defaultExport } = exports.createDefault(ast, { fallback: defineConfig }); - const webServerConfig = { + const config = { webServer: { command: 'npm run build && npm run preview', port: 4173 - } + }, + testDir: 'e2e' }; - const testDirConfig = { testDir: 'e2e' }; if ( defaultExport.type === 'CallExpression' && @@ -62,12 +62,10 @@ export default defineAddon({ ) { // uses the `defineConfig` helper imports.addNamed(ast, { imports: ['defineConfig'], from: '@playwright/test' }); - object.overrideProperties(defaultExport.arguments[0], webServerConfig); - object.overrideProperties(defaultExport.arguments[0], testDirConfig); + object.overrideProperties(defaultExport.arguments[0], config); } else if (defaultExport.type === 'ObjectExpression') { // if the config is just an object expression, just add the properties - object.overrideProperties(defaultExport, webServerConfig); - object.overrideProperties(defaultExport, testDirConfig); + object.overrideProperties(defaultExport, config); } else { // unexpected config shape log.warn('Unexpected playwright config for playwright add-on. Could not update.'); From e9cf2a99659eaa1c6e4a807a6f53dcd8f7bf483c Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 14:46:25 +0200 Subject: [PATCH 23/32] adding another test case --- .../js/object/override-transform/input.ts | 3 ++ .../js/object/override-transform/output.ts | 1 + .../tests/js/object/override-transform/run.ts | 19 ++++++++++ packages/core/tooling/js/object.ts | 38 +++++++++++++++++-- 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 packages/core/tests/js/object/override-transform/input.ts create mode 100644 packages/core/tests/js/object/override-transform/output.ts create mode 100644 packages/core/tests/js/object/override-transform/run.ts diff --git a/packages/core/tests/js/object/override-transform/input.ts b/packages/core/tests/js/object/override-transform/input.ts new file mode 100644 index 000000000..90fd31b4e --- /dev/null +++ b/packages/core/tests/js/object/override-transform/input.ts @@ -0,0 +1,3 @@ +const test = { + a: { keep: 'me' } +}; diff --git a/packages/core/tests/js/object/override-transform/output.ts b/packages/core/tests/js/object/override-transform/output.ts new file mode 100644 index 000000000..d6c37cd4d --- /dev/null +++ b/packages/core/tests/js/object/override-transform/output.ts @@ -0,0 +1 @@ +const test = { a: { keep: 'me', b: { /*aka: bond, james bond*/ c: true } } }; diff --git a/packages/core/tests/js/object/override-transform/run.ts b/packages/core/tests/js/object/override-transform/run.ts new file mode 100644 index 000000000..c41685c17 --- /dev/null +++ b/packages/core/tests/js/object/override-transform/run.ts @@ -0,0 +1,19 @@ +import { common, object, type AstTypes } from '@sveltejs/cli-core/js'; +import { getTestObjectExpression } from '../objectTestHelper.ts'; + +export function run(ast: AstTypes.Program): void { + const obj = getTestObjectExpression(ast); + + // Create & Transform the 'c' property to add a comment using nested structure + object.transformProperty(obj, { + a: { + b: { + c: (property) => { + property.value = common.createLiteral(true); + property.leadingComments = [{ type: 'Block', value: 'aka: bond, james bond' }]; + return property; + } + } + } + }); +} diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index 81450f2ad..b25fba257 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -166,13 +166,45 @@ function populateObjectExpression(options: { if (options.transform && typeof value === 'function') { // Transform mode - apply the transform function to existing property - if (existingProperty) { - const transformedProperty = value(existingProperty); - const index = options.objectExpression.properties.indexOf(existingProperty); + if (!existingProperty) { + property(options.objectExpression, { + name: prop, + fallback: common.createLiteral(null) + }); + } + // Find the property again after potentially creating it + const targetProperty = options.objectExpression.properties.find( + (p): p is AstTypes.Property => + p.type === 'Property' && (p.key as AstTypes.Identifier).name === prop + ); + if (targetProperty) { + const transformedProperty = value(targetProperty); + const index = options.objectExpression.properties.indexOf(targetProperty); if (index !== -1) { options.objectExpression.properties[index] = transformedProperty; } } + } else if ( + options.transform && + typeof value === 'object' && + value !== null && + !Array.isArray(value) && + !value.type + ) { + // Handle nested transform maps recursively + const targetObject = + existingExpression || + (overrideProperty(options.objectExpression, { + name: prop, + value: create({}) + }) as AstTypes.ObjectExpression); + // Recursively apply transforms to the nested object + populateObjectExpression({ + objectExpression: targetObject, + properties: value as ObjectMap, + override: options.override, + transform: options.transform + }); } else { overrideProperty(options.objectExpression, { name: prop, From 8c37c744c999dae2f67136db9f5866196d19afb2 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 14:46:37 +0200 Subject: [PATCH 24/32] adding tests for auto adapter --- .../addons/_tests/sveltekit-adapter/test.ts | 20 ++++++++++++++ packages/addons/sveltekit-adapter/index.ts | 26 ++++++++++++------- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/packages/addons/_tests/sveltekit-adapter/test.ts b/packages/addons/_tests/sveltekit-adapter/test.ts index 3adc35175..c93034ade 100644 --- a/packages/addons/_tests/sveltekit-adapter/test.ts +++ b/packages/addons/_tests/sveltekit-adapter/test.ts @@ -15,5 +15,25 @@ test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { // kill server process when we're done ctx.onTestFinished(async () => await close()); + // check the import expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch('adapter-auto'); + // check the comment + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch( + 'adapter-auto only supports some environments' + ); +}); + +test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { [addonId]: { adapter: 'auto' } }); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); + + // check the import + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch('adapter-auto'); + // check the comment + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch( + 'adapter-auto only supports some environments' + ); }); diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index c5036fd41..585fa60f2 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -1,5 +1,5 @@ import { defineAddon, defineAddonOptions } from '@sveltejs/cli-core'; -import { exports, imports, object } from '@sveltejs/cli-core/js'; +import { exports, functions, imports, object } from '@sveltejs/cli-core/js'; import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; const adapters = [ @@ -75,17 +75,25 @@ export default defineAddon({ const { value: config } = exports.createDefault(ast, { fallback: object.create({}) }); - // reset the comment for non-auto adapters - if (adapter.package !== '@sveltejs/adapter-auto') { - object.transformProperty(config, { - kit: { - adapter: (property) => { + object.transformProperty(config, { + kit: { + adapter: (property) => { + // overrides the `adapter` property so we can reset it's args + property.value = functions.createCall({ + name: adapterName, + args: [], + useIdentifiers: true + }); + + // reset the comment for non-auto adapters + if (adapter.package !== '@sveltejs/adapter-auto') { property.leadingComments = []; - return property; } + + return property; } - }); - } + } + }); return generateCode(); }); From 7c2c0444edb4ae8d1efb961db418168f3ef3dbda Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 16:20:15 +0200 Subject: [PATCH 25/32] let's confirm that only the value is changed. YES --- .../core/tests/js/object/ensure-nested-property/input.ts | 5 ++++- .../core/tests/js/object/ensure-nested-property/output.ts | 2 +- packages/core/tests/js/object/ensure-nested-property/run.ts | 4 ++++ packages/core/tests/js/object/override-property/input.ts | 1 + packages/core/tests/js/object/override-property/output.ts | 2 +- 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/core/tests/js/object/ensure-nested-property/input.ts b/packages/core/tests/js/object/ensure-nested-property/input.ts index 90fd31b4e..9cd10e586 100644 --- a/packages/core/tests/js/object/ensure-nested-property/input.ts +++ b/packages/core/tests/js/object/ensure-nested-property/input.ts @@ -1,3 +1,6 @@ const test = { - a: { keep: 'me' } + a: { + /** a comment */ + keep: 'me' + } }; diff --git a/packages/core/tests/js/object/ensure-nested-property/output.ts b/packages/core/tests/js/object/ensure-nested-property/output.ts index fdf47f478..08bd5fbf9 100644 --- a/packages/core/tests/js/object/ensure-nested-property/output.ts +++ b/packages/core/tests/js/object/ensure-nested-property/output.ts @@ -1 +1 @@ -const test = { a: { keep: 'me', b: { c: '007' } } }; +const test = { a: { /** a comment */ keep: 'you', b: { c: '007' } } }; diff --git a/packages/core/tests/js/object/ensure-nested-property/run.ts b/packages/core/tests/js/object/ensure-nested-property/run.ts index 6d7de24a1..34ae577ea 100644 --- a/packages/core/tests/js/object/ensure-nested-property/run.ts +++ b/packages/core/tests/js/object/ensure-nested-property/run.ts @@ -7,4 +7,8 @@ export function run(ast: AstTypes.Program): void { object.overrideProperties(obj, { a: { b: { c: '007' } } }); + + object.overrideProperties(obj, { + a: { keep: 'you' } + }); } diff --git a/packages/core/tests/js/object/override-property/input.ts b/packages/core/tests/js/object/override-property/input.ts index 72b9d2087..d82f0bb39 100644 --- a/packages/core/tests/js/object/override-property/input.ts +++ b/packages/core/tests/js/object/override-property/input.ts @@ -1,4 +1,5 @@ const test = { + /** a comment */ 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 c9790a5aa..fbdef76fe 100644 --- a/packages/core/tests/js/object/override-property/output.ts +++ b/packages/core/tests/js/object/override-property/output.ts @@ -1 +1 @@ -const test = { foo: 2, bar: 'string2', lorem: false }; +const test = { /** a comment */ foo: 2, bar: 'string2', lorem: false }; From 4255c6726a58af6234c77e9ab70effd5f5db6365 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 16:41:20 +0200 Subject: [PATCH 26/32] adapter okay --- packages/addons/sveltekit-adapter/index.ts | 27 +++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 585fa60f2..8b0690069 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -75,25 +75,24 @@ export default defineAddon({ const { value: config } = exports.createDefault(ast, { fallback: object.create({}) }); - object.transformProperty(config, { + // override the adapter property + object.overrideProperties(config, { kit: { - adapter: (property) => { - // overrides the `adapter` property so we can reset it's args - property.value = functions.createCall({ - name: adapterName, - args: [], - useIdentifiers: true - }); + adapter: functions.createCall({ name: adapterName, args: [], useIdentifiers: true }) + } + }); - // reset the comment for non-auto adapters - if (adapter.package !== '@sveltejs/adapter-auto') { + // reset the comment for non-auto adapters + if (adapter.package !== '@sveltejs/adapter-auto') { + object.transformProperty(config, { + kit: { + adapter: (property) => { property.leadingComments = []; + return property; } - - return property; } - } - }); + }); + } return generateCode(); }); From ac620b2ab9415d661576e0812ea87898c2df28d1 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 17:38:17 +0200 Subject: [PATCH 27/32] add propertyNode --- packages/addons/sveltekit-adapter/index.ts | 16 ++++++++-------- packages/core/tooling/js/object.ts | 9 ++++++++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 8b0690069..5a6d6c2f3 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -84,14 +84,14 @@ export default defineAddon({ // reset the comment for non-auto adapters if (adapter.package !== '@sveltejs/adapter-auto') { - object.transformProperty(config, { - kit: { - adapter: (property) => { - property.leadingComments = []; - return property; - } - } - }); + const configKit = object.propertyNode(config, { name: 'kit', fallback: object.create({}) }); + if (configKit.value.type === 'ObjectExpression') { + const configAdapter = object.propertyNode(configKit.value, { + name: 'adapter', + fallback: object.create({}) + }); + configAdapter.leadingComments = []; + } } return generateCode(); diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index b25fba257..5694e3821 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -16,6 +16,13 @@ export function property( node: AstTypes.ObjectExpression, options: { name: string; fallback: T } ): T { + return propertyNode(node, options).value as T; +} + +export function propertyNode( + node: AstTypes.ObjectExpression, + options: { name: string; fallback: T } +): AstTypes.Property { const properties = node.properties.filter((x): x is AstTypes.Property => x.type === 'Property'); let prop = properties.find((x) => (x.key as AstTypes.Identifier).name === options.name); @@ -42,7 +49,7 @@ export function property( node.properties.push(prop); } - return prop.value as T; + return prop as AstTypes.Property; } export function create(properties: ObjectMap): AstTypes.ObjectExpression { From de250f6c3281dac556e846fced6ce3c1db1a9102 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 17:52:49 +0200 Subject: [PATCH 28/32] simplify api by removing transformProperty! You want to go raw, use object.properyNode(). --- packages/addons/sveltekit-adapter/index.ts | 8 +- .../js/object/override-transform/input.ts | 3 - .../js/object/override-transform/output.ts | 1 - .../tests/js/object/override-transform/run.ts | 19 ----- .../tests/js/object/property-node/input.ts | 4 + .../tests/js/object/property-node/output.ts | 1 + .../core/tests/js/object/property-node/run.ts | 18 ++++ .../core/tests/js/object/transform/input.ts | 3 - .../core/tests/js/object/transform/output.ts | 1 - .../core/tests/js/object/transform/run.ts | 23 ------ packages/core/tooling/js/object.ts | 82 ++----------------- 11 files changed, 34 insertions(+), 129 deletions(-) delete mode 100644 packages/core/tests/js/object/override-transform/input.ts delete mode 100644 packages/core/tests/js/object/override-transform/output.ts delete mode 100644 packages/core/tests/js/object/override-transform/run.ts create mode 100644 packages/core/tests/js/object/property-node/input.ts create mode 100644 packages/core/tests/js/object/property-node/output.ts create mode 100644 packages/core/tests/js/object/property-node/run.ts delete mode 100644 packages/core/tests/js/object/transform/input.ts delete mode 100644 packages/core/tests/js/object/transform/output.ts delete mode 100644 packages/core/tests/js/object/transform/run.ts diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 5a6d6c2f3..a8a338140 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -84,12 +84,10 @@ export default defineAddon({ // reset the comment for non-auto adapters if (adapter.package !== '@sveltejs/adapter-auto') { - const configKit = object.propertyNode(config, { name: 'kit', fallback: object.create({}) }); + const fallback = object.create({}); + const configKit = object.propertyNode(config, { name: 'kit', fallback }); if (configKit.value.type === 'ObjectExpression') { - const configAdapter = object.propertyNode(configKit.value, { - name: 'adapter', - fallback: object.create({}) - }); + const configAdapter = object.propertyNode(configKit.value, { name: 'adapter', fallback }); configAdapter.leadingComments = []; } } diff --git a/packages/core/tests/js/object/override-transform/input.ts b/packages/core/tests/js/object/override-transform/input.ts deleted file mode 100644 index 90fd31b4e..000000000 --- a/packages/core/tests/js/object/override-transform/input.ts +++ /dev/null @@ -1,3 +0,0 @@ -const test = { - a: { keep: 'me' } -}; diff --git a/packages/core/tests/js/object/override-transform/output.ts b/packages/core/tests/js/object/override-transform/output.ts deleted file mode 100644 index d6c37cd4d..000000000 --- a/packages/core/tests/js/object/override-transform/output.ts +++ /dev/null @@ -1 +0,0 @@ -const test = { a: { keep: 'me', b: { /*aka: bond, james bond*/ c: true } } }; diff --git a/packages/core/tests/js/object/override-transform/run.ts b/packages/core/tests/js/object/override-transform/run.ts deleted file mode 100644 index c41685c17..000000000 --- a/packages/core/tests/js/object/override-transform/run.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { common, object, type AstTypes } from '@sveltejs/cli-core/js'; -import { getTestObjectExpression } from '../objectTestHelper.ts'; - -export function run(ast: AstTypes.Program): void { - const obj = getTestObjectExpression(ast); - - // Create & Transform the 'c' property to add a comment using nested structure - object.transformProperty(obj, { - a: { - b: { - c: (property) => { - property.value = common.createLiteral(true); - property.leadingComments = [{ type: 'Block', value: 'aka: bond, james bond' }]; - return property; - } - } - } - }); -} diff --git a/packages/core/tests/js/object/property-node/input.ts b/packages/core/tests/js/object/property-node/input.ts new file mode 100644 index 000000000..4b075890b --- /dev/null +++ b/packages/core/tests/js/object/property-node/input.ts @@ -0,0 +1,4 @@ +const test = { + /** a comment */ + foo: 1 +}; diff --git a/packages/core/tests/js/object/property-node/output.ts b/packages/core/tests/js/object/property-node/output.ts new file mode 100644 index 000000000..98da8dea4 --- /dev/null +++ b/packages/core/tests/js/object/property-node/output.ts @@ -0,0 +1 @@ +const test = { /*a comment updated*/ foo: 1, /*aka: bond, james bond*/ james: '007' }; diff --git a/packages/core/tests/js/object/property-node/run.ts b/packages/core/tests/js/object/property-node/run.ts new file mode 100644 index 000000000..9db2672ea --- /dev/null +++ b/packages/core/tests/js/object/property-node/run.ts @@ -0,0 +1,18 @@ +import { object, common, type AstTypes } from '@sveltejs/cli-core/js'; +import { getTestObjectExpression } from '../objectTestHelper.ts'; + +export function run(ast: AstTypes.Program): void { + const obj = getTestObjectExpression(ast); + + const p1 = object.propertyNode(obj, { + name: 'foo', + fallback: object.create({}) + }); + p1.leadingComments = [{ type: 'Block', value: 'a comment updated' }]; + + const p2 = object.propertyNode(obj, { + name: 'james', + fallback: common.createLiteral('007') + }); + p2.leadingComments = [{ type: 'Block', value: 'aka: bond, james bond' }]; +} diff --git a/packages/core/tests/js/object/transform/input.ts b/packages/core/tests/js/object/transform/input.ts deleted file mode 100644 index 90fd31b4e..000000000 --- a/packages/core/tests/js/object/transform/input.ts +++ /dev/null @@ -1,3 +0,0 @@ -const test = { - a: { keep: 'me' } -}; diff --git a/packages/core/tests/js/object/transform/output.ts b/packages/core/tests/js/object/transform/output.ts deleted file mode 100644 index 8b341273b..000000000 --- a/packages/core/tests/js/object/transform/output.ts +++ /dev/null @@ -1 +0,0 @@ -const test = { a: { keep: 'me', b: { /*aka: bond, james bond*/ c: '007' } } }; diff --git a/packages/core/tests/js/object/transform/run.ts b/packages/core/tests/js/object/transform/run.ts deleted file mode 100644 index 1344af774..000000000 --- a/packages/core/tests/js/object/transform/run.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { object, type AstTypes } from '@sveltejs/cli-core/js'; -import { getTestObjectExpression } from '../objectTestHelper.ts'; - -export function run(ast: AstTypes.Program): void { - const obj = getTestObjectExpression(ast); - - // Create the nested structure a.b.c = '007' - object.overrideProperties(obj, { - a: { b: { c: '007' } } - }); - - // Transform the 'c' property to add a comment using nested structure - object.transformProperty(obj, { - a: { - b: { - c: (property) => { - property.leadingComments = [{ type: 'Block', value: 'aka: bond, james bond' }]; - return property; - } - } - } - }); -} diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index 5694e3821..df92a8747 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -2,12 +2,6 @@ import type { AstTypes } from '../index.ts'; import * as array from './array.ts'; import * as common from './common.ts'; -type TransformProperty = (property: AstTypes.Property) => AstTypes.Property; - -type TransformMap = { - [key: string]: TransformProperty | TransformMap; -}; - type ObjectPrimitiveValues = string | number | boolean | undefined | null; type ObjectValues = ObjectPrimitiveValues | Record | ObjectValues[]; type ObjectMap = Record; @@ -61,8 +55,7 @@ export function create(properties: ObjectMap): AstTypes.ObjectExpression { return populateObjectExpression({ objectExpression, properties, - override: false, - transform: false + override: false }); } @@ -73,20 +66,7 @@ export function overrideProperties( populateObjectExpression({ objectExpression, properties, - override: true, - transform: false - }); -} - -export function transformProperty( - objectExpression: AstTypes.ObjectExpression, - transformMap: TransformMap -): void { - populateObjectExpression({ - objectExpression, - properties: transformMap, - override: true, - transform: true + override: true }); } @@ -113,7 +93,6 @@ function populateObjectExpression(options: { objectExpression: AstTypes.ObjectExpression; properties: ObjectMap; override: boolean; - transform: boolean; }): AstTypes.ObjectExpression { const getExpression = ( value: any, @@ -139,15 +118,13 @@ function populateObjectExpression(options: { expression = populateObjectExpression({ objectExpression: existingExpression, properties: value, - override: options.override, - transform: options.transform + override: options.override }); } else { expression = populateObjectExpression({ objectExpression: create({}), properties: value, - override: options.override, - transform: options.transform + override: options.override }); } } @@ -171,53 +148,10 @@ function populateObjectExpression(options: { const existingExpression = existingProperty?.value.type === 'ObjectExpression' ? existingProperty.value : undefined; - if (options.transform && typeof value === 'function') { - // Transform mode - apply the transform function to existing property - if (!existingProperty) { - property(options.objectExpression, { - name: prop, - fallback: common.createLiteral(null) - }); - } - // Find the property again after potentially creating it - const targetProperty = options.objectExpression.properties.find( - (p): p is AstTypes.Property => - p.type === 'Property' && (p.key as AstTypes.Identifier).name === prop - ); - if (targetProperty) { - const transformedProperty = value(targetProperty); - const index = options.objectExpression.properties.indexOf(targetProperty); - if (index !== -1) { - options.objectExpression.properties[index] = transformedProperty; - } - } - } else if ( - options.transform && - typeof value === 'object' && - value !== null && - !Array.isArray(value) && - !value.type - ) { - // Handle nested transform maps recursively - const targetObject = - existingExpression || - (overrideProperty(options.objectExpression, { - name: prop, - value: create({}) - }) as AstTypes.ObjectExpression); - // Recursively apply transforms to the nested object - populateObjectExpression({ - objectExpression: targetObject, - properties: value as ObjectMap, - override: options.override, - transform: options.transform - }); - } else { - overrideProperty(options.objectExpression, { - name: prop, - value: getExpression(value, existingExpression) - }); - } + overrideProperty(options.objectExpression, { + name: prop, + value: getExpression(value, existingExpression) + }); } else { property(options.objectExpression, { name: prop, From 6dea5a5b079f9a3b789982fca68e8965bf5cce65 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 18:04:01 +0200 Subject: [PATCH 29/32] Check import & comments --- packages/addons/_tests/sveltekit-adapter/test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/addons/_tests/sveltekit-adapter/test.ts b/packages/addons/_tests/sveltekit-adapter/test.ts index c93034ade..9e14d5cf6 100644 --- a/packages/addons/_tests/sveltekit-adapter/test.ts +++ b/packages/addons/_tests/sveltekit-adapter/test.ts @@ -15,9 +15,7 @@ test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { // kill server process when we're done ctx.onTestFinished(async () => await close()); - // check the import expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch('adapter-auto'); - // check the comment expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).not.toMatch( 'adapter-auto only supports some environments' ); @@ -30,9 +28,7 @@ test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { // kill server process when we're done ctx.onTestFinished(async () => await close()); - // check the import expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch('adapter-auto'); - // check the comment expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch( 'adapter-auto only supports some environments' ); From de8acd469ac7ff48b5b65918b7d5430eb659f5a5 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 18:35:11 +0200 Subject: [PATCH 30/32] ;) --- packages/addons/sveltekit-adapter/index.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index a8a338140..c4d9e8b6b 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -85,11 +85,9 @@ export default defineAddon({ // reset the comment for non-auto adapters if (adapter.package !== '@sveltejs/adapter-auto') { const fallback = object.create({}); - const configKit = object.propertyNode(config, { name: 'kit', fallback }); - if (configKit.value.type === 'ObjectExpression') { - const configAdapter = object.propertyNode(configKit.value, { name: 'adapter', fallback }); - configAdapter.leadingComments = []; - } + const cfgKitValue = object.property(config, { name: 'kit', fallback }); + const cfgAdapter = object.propertyNode(cfgKitValue, { name: 'adapter', fallback }); + cfgAdapter.leadingComments = []; } return generateCode(); From 52961f0ca521c4d61f6e676bcff07450c3d060da Mon Sep 17 00:00:00 2001 From: jycouet Date: Sun, 7 Sep 2025 20:28:51 +0200 Subject: [PATCH 31/32] Opti tests, no need preview when page not requested. --- packages/addons/_tests/_setup/suite.ts | 2 ++ packages/addons/_tests/all-addons/test.ts | 2 +- packages/addons/_tests/devtools-json/test.ts | 27 +++---------------- packages/addons/_tests/eslint/test.ts | 2 +- packages/addons/_tests/lucia/test.ts | 2 +- packages/addons/_tests/paraglide/test.ts | 2 +- packages/addons/_tests/playwright/test.ts | 2 +- packages/addons/_tests/prettier/test.ts | 2 +- .../addons/_tests/sveltekit-adapter/test.ts | 11 +++----- packages/addons/_tests/vitest/test.ts | 2 +- 10 files changed, 16 insertions(+), 38 deletions(-) diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index 65615a8c6..3d9a543cb 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -117,6 +117,8 @@ async function prepareServer( if (buildCommand) execSync(buildCommand, { cwd, stdio: 'pipe' }); // start preview server + if (!previewCommand) return { url: null, close: () => {} }; + const { url, close } = await startPreview({ cwd, command: previewCommand }); // increases timeout as 30s is not always enough when running the full suite diff --git a/packages/addons/_tests/all-addons/test.ts b/packages/addons/_tests/all-addons/test.ts index 845f468ff..4230ad0e1 100644 --- a/packages/addons/_tests/all-addons/test.ts +++ b/packages/addons/_tests/all-addons/test.ts @@ -22,7 +22,7 @@ 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 }); + const { close } = await prepareServer({ cwd, page, previewCommand: null! }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/devtools-json/test.ts b/packages/addons/_tests/devtools-json/test.ts index a7830682c..d492c6395 100644 --- a/packages/addons/_tests/devtools-json/test.ts +++ b/packages/addons/_tests/devtools-json/test.ts @@ -8,10 +8,11 @@ const { test, variants, prepareServer } = setupTest({ devtoolsJson } as { devtoolsJson?: typeof devtoolsJson; }); -test.concurrent.for(variants)('default - %s', async (variant, { page, ...ctx }) => { +const kitOnly = variants.filter((v) => v.includes('kit')); +test.concurrent.for(kitOnly)('default - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { devtoolsJson: {} }); - const { close } = await prepareServer({ cwd, page }); + const { close } = await prepareServer({ cwd, page, previewCommand: null! }); // kill server process when we're done ctx.onTestFinished(async () => await close()); @@ -26,25 +27,3 @@ test.concurrent.for(variants)('default - %s', async (variant, { page, ...ctx }) // Check if it's called expect(viteContent).toContain(`devtoolsJson()`); }); - -test.concurrent.for(variants)( - 'without selecting the addon specifically - %s', - async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, {}); - - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); - - const ext = variant.includes('ts') ? 'ts' : 'js'; - const viteFile = path.resolve(cwd, `vite.config.${ext}`); - const viteContent = fs.readFileSync(viteFile, 'utf8'); - - // Check if we have the import part - expect(viteContent).toContain(`import devtoolsJson from`); - expect(viteContent).toContain(`vite-plugin-devtools-json`); - - // Check if it's called - expect(viteContent).toContain(`devtoolsJson()`); - } -); diff --git a/packages/addons/_tests/eslint/test.ts b/packages/addons/_tests/eslint/test.ts index 34e9a45d3..f4ea631d7 100644 --- a/packages/addons/_tests/eslint/test.ts +++ b/packages/addons/_tests/eslint/test.ts @@ -10,7 +10,7 @@ const { test, variants, prepareServer } = setupTest({ eslint }); test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { eslint: {} }); - const { close } = await prepareServer({ cwd, page }); + const { close } = await prepareServer({ cwd, page, previewCommand: null! }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/lucia/test.ts b/packages/addons/_tests/lucia/test.ts index c95ac959f..58ebaeef7 100644 --- a/packages/addons/_tests/lucia/test.ts +++ b/packages/addons/_tests/lucia/test.ts @@ -12,7 +12,7 @@ test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { lucia: { demo: true } }); - const { close } = await prepareServer({ cwd, page }); + const { close } = await prepareServer({ cwd, page, previewCommand: null! }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/paraglide/test.ts b/packages/addons/_tests/paraglide/test.ts index 67c68eff9..59a897159 100644 --- a/packages/addons/_tests/paraglide/test.ts +++ b/packages/addons/_tests/paraglide/test.ts @@ -8,7 +8,7 @@ const kitOnly = variants.filter((v) => v.includes('kit')); test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { paraglide: { demo: true, languageTags: 'en' } }); - const { close } = await prepareServer({ cwd, page }); + const { close } = await prepareServer({ cwd, page, previewCommand: null! }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/playwright/test.ts b/packages/addons/_tests/playwright/test.ts index e8d735f7d..7cf9a0a8b 100644 --- a/packages/addons/_tests/playwright/test.ts +++ b/packages/addons/_tests/playwright/test.ts @@ -7,7 +7,7 @@ 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 }); + const { close } = await prepareServer({ cwd, page, previewCommand: null! }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/prettier/test.ts b/packages/addons/_tests/prettier/test.ts index 1826d66b1..f0012ba14 100644 --- a/packages/addons/_tests/prettier/test.ts +++ b/packages/addons/_tests/prettier/test.ts @@ -10,7 +10,7 @@ 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 }); + const { close } = await prepareServer({ cwd, page, previewCommand: null! }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/sveltekit-adapter/test.ts b/packages/addons/_tests/sveltekit-adapter/test.ts index 9e14d5cf6..76ea04e45 100644 --- a/packages/addons/_tests/sveltekit-adapter/test.ts +++ b/packages/addons/_tests/sveltekit-adapter/test.ts @@ -8,10 +8,10 @@ const addonId = sveltekitAdapter.id; const { test, variants, prepareServer } = setupTest({ [addonId]: sveltekitAdapter }); const kitOnly = variants.filter((v) => v.includes('kit')); -test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { +test.concurrent.for(kitOnly)('core node - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { [addonId]: { adapter: 'node' } }); - const { close } = await prepareServer({ cwd, page }); + const { close } = await prepareServer({ cwd, page, previewCommand: null! }); // kill server process when we're done ctx.onTestFinished(async () => await close()); @@ -21,13 +21,10 @@ test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { ); }); -test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { +test.concurrent.for(kitOnly)('core auto - %s', async (variant, { ...ctx }) => { const cwd = await ctx.run(variant, { [addonId]: { adapter: 'auto' } }); - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); - + // Check only generated files. expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch('adapter-auto'); expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch( 'adapter-auto only supports some environments' diff --git a/packages/addons/_tests/vitest/test.ts b/packages/addons/_tests/vitest/test.ts index cfe9a06c5..736ed9ce1 100644 --- a/packages/addons/_tests/vitest/test.ts +++ b/packages/addons/_tests/vitest/test.ts @@ -8,7 +8,7 @@ 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 }); + const { close } = await prepareServer({ cwd, page, previewCommand: null! }); execSync('pnpm exec playwright install chromium', { cwd, stdio: 'pipe' }); execSync('pnpm test', { cwd, stdio: 'pipe' }); From 5518f9c888b2e161e8ee98a82721b9f5aaf5e107 Mon Sep 17 00:00:00 2001 From: jycouet Date: Tue, 9 Sep 2025 09:47:08 +0200 Subject: [PATCH 32/32] Revert "Opti tests, no need preview when page not requested." This reverts commit 52961f0ca521c4d61f6e676bcff07450c3d060da. --- packages/addons/_tests/_setup/suite.ts | 2 -- packages/addons/_tests/all-addons/test.ts | 2 +- packages/addons/_tests/devtools-json/test.ts | 27 ++++++++++++++++--- packages/addons/_tests/eslint/test.ts | 2 +- packages/addons/_tests/lucia/test.ts | 2 +- packages/addons/_tests/paraglide/test.ts | 2 +- packages/addons/_tests/playwright/test.ts | 2 +- packages/addons/_tests/prettier/test.ts | 2 +- .../addons/_tests/sveltekit-adapter/test.ts | 11 +++++--- packages/addons/_tests/vitest/test.ts | 2 +- 10 files changed, 38 insertions(+), 16 deletions(-) diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index 3d9a543cb..65615a8c6 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -117,8 +117,6 @@ async function prepareServer( if (buildCommand) execSync(buildCommand, { cwd, stdio: 'pipe' }); // start preview server - if (!previewCommand) return { url: null, close: () => {} }; - const { url, close } = await startPreview({ cwd, command: previewCommand }); // increases timeout as 30s is not always enough when running the full suite diff --git a/packages/addons/_tests/all-addons/test.ts b/packages/addons/_tests/all-addons/test.ts index 4230ad0e1..845f468ff 100644 --- a/packages/addons/_tests/all-addons/test.ts +++ b/packages/addons/_tests/all-addons/test.ts @@ -22,7 +22,7 @@ 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, previewCommand: null! }); + const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/devtools-json/test.ts b/packages/addons/_tests/devtools-json/test.ts index d492c6395..a7830682c 100644 --- a/packages/addons/_tests/devtools-json/test.ts +++ b/packages/addons/_tests/devtools-json/test.ts @@ -8,11 +8,10 @@ const { test, variants, prepareServer } = setupTest({ devtoolsJson } as { devtoolsJson?: typeof devtoolsJson; }); -const kitOnly = variants.filter((v) => v.includes('kit')); -test.concurrent.for(kitOnly)('default - %s', async (variant, { page, ...ctx }) => { +test.concurrent.for(variants)('default - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { devtoolsJson: {} }); - const { close } = await prepareServer({ cwd, page, previewCommand: null! }); + const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); @@ -27,3 +26,25 @@ test.concurrent.for(kitOnly)('default - %s', async (variant, { page, ...ctx }) = // Check if it's called expect(viteContent).toContain(`devtoolsJson()`); }); + +test.concurrent.for(variants)( + 'without selecting the addon specifically - %s', + async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, {}); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); + + const ext = variant.includes('ts') ? 'ts' : 'js'; + const viteFile = path.resolve(cwd, `vite.config.${ext}`); + const viteContent = fs.readFileSync(viteFile, 'utf8'); + + // Check if we have the import part + expect(viteContent).toContain(`import devtoolsJson from`); + expect(viteContent).toContain(`vite-plugin-devtools-json`); + + // Check if it's called + expect(viteContent).toContain(`devtoolsJson()`); + } +); diff --git a/packages/addons/_tests/eslint/test.ts b/packages/addons/_tests/eslint/test.ts index f4ea631d7..34e9a45d3 100644 --- a/packages/addons/_tests/eslint/test.ts +++ b/packages/addons/_tests/eslint/test.ts @@ -10,7 +10,7 @@ const { test, variants, prepareServer } = setupTest({ eslint }); test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { eslint: {} }); - const { close } = await prepareServer({ cwd, page, previewCommand: null! }); + const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/lucia/test.ts b/packages/addons/_tests/lucia/test.ts index 58ebaeef7..c95ac959f 100644 --- a/packages/addons/_tests/lucia/test.ts +++ b/packages/addons/_tests/lucia/test.ts @@ -12,7 +12,7 @@ test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { lucia: { demo: true } }); - const { close } = await prepareServer({ cwd, page, previewCommand: null! }); + const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/paraglide/test.ts b/packages/addons/_tests/paraglide/test.ts index 59a897159..67c68eff9 100644 --- a/packages/addons/_tests/paraglide/test.ts +++ b/packages/addons/_tests/paraglide/test.ts @@ -8,7 +8,7 @@ const kitOnly = variants.filter((v) => v.includes('kit')); test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { paraglide: { demo: true, languageTags: 'en' } }); - const { close } = await prepareServer({ cwd, page, previewCommand: null! }); + const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/playwright/test.ts b/packages/addons/_tests/playwright/test.ts index 7cf9a0a8b..e8d735f7d 100644 --- a/packages/addons/_tests/playwright/test.ts +++ b/packages/addons/_tests/playwright/test.ts @@ -7,7 +7,7 @@ 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, previewCommand: null! }); + const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/prettier/test.ts b/packages/addons/_tests/prettier/test.ts index f0012ba14..1826d66b1 100644 --- a/packages/addons/_tests/prettier/test.ts +++ b/packages/addons/_tests/prettier/test.ts @@ -10,7 +10,7 @@ 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, previewCommand: null! }); + const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/_tests/sveltekit-adapter/test.ts b/packages/addons/_tests/sveltekit-adapter/test.ts index 76ea04e45..9e14d5cf6 100644 --- a/packages/addons/_tests/sveltekit-adapter/test.ts +++ b/packages/addons/_tests/sveltekit-adapter/test.ts @@ -8,10 +8,10 @@ const addonId = sveltekitAdapter.id; const { test, variants, prepareServer } = setupTest({ [addonId]: sveltekitAdapter }); const kitOnly = variants.filter((v) => v.includes('kit')); -test.concurrent.for(kitOnly)('core node - %s', async (variant, { page, ...ctx }) => { +test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { [addonId]: { adapter: 'node' } }); - const { close } = await prepareServer({ cwd, page, previewCommand: null! }); + const { close } = await prepareServer({ cwd, page }); // kill server process when we're done ctx.onTestFinished(async () => await close()); @@ -21,10 +21,13 @@ test.concurrent.for(kitOnly)('core node - %s', async (variant, { page, ...ctx }) ); }); -test.concurrent.for(kitOnly)('core auto - %s', async (variant, { ...ctx }) => { +test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { [addonId]: { adapter: 'auto' } }); - // Check only generated files. + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); + expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch('adapter-auto'); expect(await readFile(join(cwd, 'svelte.config.js'), 'utf8')).toMatch( 'adapter-auto only supports some environments' diff --git a/packages/addons/_tests/vitest/test.ts b/packages/addons/_tests/vitest/test.ts index 736ed9ce1..cfe9a06c5 100644 --- a/packages/addons/_tests/vitest/test.ts +++ b/packages/addons/_tests/vitest/test.ts @@ -8,7 +8,7 @@ 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, previewCommand: null! }); + const { close } = await prepareServer({ cwd, page }); execSync('pnpm exec playwright install chromium', { cwd, stdio: 'pipe' }); execSync('pnpm test', { cwd, stdio: 'pipe' });