Skip to content

Commit e0e8b0a

Browse files
benmccannmanuel3108AdrianGonz97
authored
chore: leverage expressionFromString more in drizzle adder (#556)
* chore: leverage expressionFromString more in drizzle adder * fix drizzle output * do not format js test results with prettier * do not format js test results with prettier * add failing quote test * fix drizzle output * fix drizzle output * use stripAst to remove raw property * remove undefined * extra comma * fix test * error on preexisting files --------- Co-authored-by: Manuel Serret <[email protected]> Co-authored-by: AdrianGonz97 <[email protected]>
1 parent e9485a2 commit e0e8b0a

File tree

6 files changed

+54
-43
lines changed

6 files changed

+54
-43
lines changed

packages/addons/_tests/drizzle/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ test.concurrent.for(testCases)(
4343

4444
const ts = variant === 'kit-ts';
4545
const drizzleConfig = path.resolve(cwd, `drizzle.config.${ts ? 'ts' : 'js'}`);
46-
const content = fs.readFileSync(drizzleConfig, 'utf8').replace('strict: true,', '');
46+
const content = fs.readFileSync(drizzleConfig, 'utf8').replace(/strict: true[,\s]/, '');
4747
fs.writeFileSync(drizzleConfig, content, 'utf8');
4848

4949
const routes = path.resolve(cwd, 'src', 'routes');

packages/addons/drizzle/index.ts

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import fs from 'node:fs';
2+
import path from 'node:path';
13
import { common, exports, functions, imports, object, variables } from '@sveltejs/cli-core/js';
24
import { defineAddon, defineAddonOptions, dedent, type OptionValues } from '@sveltejs/cli-core';
35
import { parseJson, parseScript } from '@sveltejs/cli-core/parsers';
@@ -69,8 +71,21 @@ export default defineAddon({
6971
shortDescription: 'database orm',
7072
homepage: 'https://orm.drizzle.team',
7173
options,
72-
setup: ({ kit, unsupported }) => {
74+
setup: ({ kit, unsupported, cwd, typescript }) => {
75+
const ext = typescript ? 'ts' : 'js';
7376
if (!kit) unsupported('Requires SvelteKit');
77+
78+
const baseDBPath = path.resolve(kit!.libDirectory, 'server', 'db');
79+
const paths = {
80+
'drizzle config': path.relative(cwd, path.resolve(cwd, `drizzle.config.${ext}`)),
81+
'database schema': path.relative(cwd, path.resolve(baseDBPath, `schema.${ext}`)),
82+
database: path.relative(cwd, path.resolve(baseDBPath, `index.${ext}`))
83+
};
84+
for (const [fileType, filePath] of Object.entries(paths)) {
85+
if (fs.existsSync(filePath)) {
86+
unsupported(`Preexisting ${fileType} file at '${filePath}'`);
87+
}
88+
}
7489
},
7590
run: ({ sv, typescript, options, kit }) => {
7691
const ext = typescript ? 'ts' : 'js';
@@ -178,41 +193,27 @@ export default defineAddon({
178193

179194
imports.addNamed(ast, 'drizzle-kit', { defineConfig: 'defineConfig' });
180195

181-
const envCheckStatement = common.statementFromString(
182-
"if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');"
196+
common.addStatement(
197+
ast,
198+
common.statementFromString(
199+
"if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');"
200+
)
183201
);
184-
common.addStatement(ast, envCheckStatement);
185-
186-
const fallback = common.expressionFromString('defineConfig({})');
187-
const { value: exportDefault } = exports.defaultExport(ast, fallback);
188-
if (exportDefault.type !== 'CallExpression') return content;
189-
190-
const objExpression = exportDefault.arguments?.[0];
191-
if (!objExpression || objExpression.type !== 'ObjectExpression') return content;
192-
193-
const authToken =
194-
options.sqlite === 'turso'
195-
? common.expressionFromString('process.env.DATABASE_AUTH_TOKEN')
196-
: undefined;
197-
198-
object.properties(objExpression, {
199-
schema: common.createLiteral(`./src/lib/server/db/schema.${typescript ? 'ts' : 'js'}`),
200-
dbCredentials: object.create({
201-
url: common.expressionFromString('process.env.DATABASE_URL'),
202-
authToken
203-
}),
204-
verbose: { type: 'Literal', value: true },
205-
strict: { type: 'Literal', value: true }
206-
});
207-
208-
const dialect = options.sqlite === 'turso' ? 'turso' : options.database;
209-
object.overrideProperties(objExpression, {
210-
dialect: common.createLiteral(dialect)
211-
});
212202

213-
// The `driver` property is only required for _some_ sqlite DBs.
214-
// We'll need to remove it if it's anything but sqlite
215-
if (options.database !== 'sqlite') object.removeProperty(objExpression, 'driver');
203+
exports.defaultExport(
204+
ast,
205+
common.expressionFromString(`
206+
defineConfig({
207+
schema: "./src/lib/server/db/schema.${typescript ? 'ts' : 'js'}",
208+
dialect: "${options.sqlite === 'turso' ? 'turso' : options.database}",
209+
dbCredentials: {
210+
${options.sqlite === 'turso' ? 'authToken: process.env.DATABASE_AUTH_TOKEN,' : ''}
211+
url: process.env.DATABASE_URL
212+
},
213+
verbose: true,
214+
strict: true
215+
})`)
216+
);
216217

217218
return generateCode();
218219
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default defineConfig({ path: 'some/string/as/path.js', valid: true });
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { common, exports, type AstTypes } from '@sveltejs/cli-core/js';
2+
3+
export function run(ast: AstTypes.Program): void {
4+
exports.defaultExport(
5+
ast,
6+
common.expressionFromString(`
7+
defineConfig({
8+
path: "some/string/as/path.js",
9+
valid: true
10+
})
11+
`)
12+
);
13+
}

packages/core/tests/js/index.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
import fs from 'node:fs';
22
import { join, resolve } from 'node:path';
33
import { fileURLToPath } from 'node:url';
4-
import prettier from 'prettier';
54
import { describe, expect, test } from 'vitest';
65
import { parseScript, serializeScript } from '../../tooling/index.ts';
76

87
const baseDir = resolve(fileURLToPath(import.meta.url), '..');
98
const categoryDirectories = getDirectoryNames(baseDir);
109

11-
const prettierConfig = await prettier.resolveConfig(import.meta.url);
12-
if (!prettierConfig) throw new Error('Failed to resolve prettier config');
13-
prettierConfig.filepath = 'output.ts';
14-
1510
for (const categoryDirectory of categoryDirectories) {
1611
describe(categoryDirectory, () => {
1712
const testNames = getDirectoryNames(join(baseDir, categoryDirectory));
@@ -27,9 +22,9 @@ for (const categoryDirectory of categoryDirectories) {
2722
const module = await import(`./${categoryDirectory}/${testName}/run.ts`);
2823
module.run(ast);
2924

30-
const output = serializeScript(ast, input);
31-
const formattedOutput = await prettier.format(output, prettierConfig);
32-
await expect(formattedOutput).toMatchFileSnapshot(`${testDirectoryPath}/output.ts`);
25+
let output = serializeScript(ast, input);
26+
if (!output.endsWith('\n')) output += '\n';
27+
await expect(output).toMatchFileSnapshot(`${testDirectoryPath}/output.ts`);
3328
});
3429
}
3530
});

packages/core/tooling/js/common.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ export function addFromString(
115115

116116
export function expressionFromString(value: string): AstTypes.Expression {
117117
const program = parseScript(dedent(value));
118+
stripAst(program, ['raw']);
118119
const statement = program.body[0]!;
119120
if (statement.type !== 'ExpressionStatement') {
120121
throw new Error('value passed was not an expression');

0 commit comments

Comments
 (0)