Skip to content

Commit fef9ccf

Browse files
committed
Post-merge fix-ups for drizzle-kit local verification
Production changes - validations/common.ts: pre-merge import path lost its src/ alias; switch back to relative ../../utils/schemaValidator so jiti resolves at test time. - utils-node.ts loadModule: jiti.import branch was missing the mod.default ?? mod unwrap that the Bun/Deno and ESM branches both perform. Without it drizzleConfigFromFile receives a namespace object with default-forwarding proxy fields that zod's safeParse drops, so config.schema / config.sql / config.tablesFilter become undefined and the prepare* helpers throw RequiredParamsCliError on otherwise valid configs. - commands/utils.ts prepareExportConfig: take sql from the CLI options first, then from the config file, then default true; previously the CLI --sql=false flag was ignored when the rest of the command came from a config file. Also re-export the CheckConfig type the dispatch needs. Test adaptations - 8 cli-*.test.ts files: replaced vi.spyOn(console, 'log') + 'process.exit unexpectedly called with "1"' assertions with res.error.message checks built from the same error() / wrapParam() helpers the runtime uses, so the captured CliError message matches byte-for-byte (including ANSI). Three GenerateConfig / push expected fixtures gained the missing explain + hints fields. cli-check.test.ts, cli-pull.test.ts, cli-studio.test.ts now self-set TEST_CONFIG_PATH_PREFIX so they work under test:other (which doesn't set it). - conformance-live-db.test.ts push mysql describe gained a beforeAll that drops every table in the active mysql database. Without it, leftover tables from earlier mysql test files in the same run made the diff engine treat new tables as rename_or_create candidates and emit missing_hints instead of the expected ok / no_changes envelopes.
1 parent 7617b8d commit fef9ccf

11 files changed

Lines changed: 111 additions & 202 deletions

File tree

drizzle-kit/src/cli/commands/utils.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ export const prepareExportConfig = async (
167167
? await drizzleConfigFromFile(options.config, true)
168168
: options;
169169

170-
const { schema, dialect, sql } = config;
170+
const { schema, dialect } = config;
171+
const sql = options.sql ?? (config as { sql?: boolean }).sql ?? true;
171172

172173
if (!schema || !dialect) {
173174
throw new RequiredParamsCliError(
@@ -183,7 +184,7 @@ export const prepareExportConfig = async (
183184
const fileNames = prepareFilenames(schema);
184185
return {
185186
dialect: dialect,
186-
sql: sql ?? true,
187+
sql: sql,
187188
filenames: fileNames,
188189
};
189190
};

drizzle-kit/src/cli/validations/common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import chalk from 'chalk';
22
import type { UnionToIntersection } from 'hono/utils/types';
3-
import { dialect } from 'src/utils/schemaValidator';
43
import type { TypeOf } from 'zod';
54
import { any, boolean, coerce, enum as enum_, literal, object, string, union } from 'zod';
5+
import { dialect } from '../../utils/schemaValidator';
66
import { AmbiguousParamsCliError } from '../errors';
77
import { outputs } from './outputs';
88

drizzle-kit/src/utils/utils-node.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,8 @@ export const loadModule = async <T = unknown>(
465465
alias: aliases,
466466
requireCache: false,
467467
});
468-
return jiti.import(absoluteModulePath);
468+
const mod = await jiti.import<any>(absoluteModulePath);
469+
return mod?.default ?? mod;
469470
}
470471
const fileUrl = pathToFileURL(absoluteModulePath).href;
471472
const mod = await import(fileUrl);

drizzle-kit/tests/other/cli-check.test.ts

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
import { test as brotest } from '@drizzle-team/brocli';
22
import { unlinkSync } from 'node:fs';
3-
import { CheckConfig } from 'src/cli/commands/utils';
4-
import { check } from 'src/cli/schema';
5-
import { assert, expect, test, vi } from 'vitest';
3+
import { afterEach, assert, expect, test, vi } from 'vitest';
4+
import { CheckConfig } from '../../src/cli/commands/utils';
5+
import { check } from '../../src/cli/schema';
6+
import { wrapParam } from '../../src/cli/validations/common';
7+
import { error } from '../../src/cli/views';
68
import { createConfig } from './utils';
79

10+
const originalPrefix = process.env.TEST_CONFIG_PATH_PREFIX;
11+
process.env.TEST_CONFIG_PATH_PREFIX = './tests/cli/';
12+
afterEach(() => {
13+
process.env.TEST_CONFIG_PATH_PREFIX = originalPrefix ?? './tests/cli/';
14+
});
15+
816
// should point to test/cli
917
const prefix = process.env.TEST_CONFIG_PATH_PREFIX || '';
1018
test('validate config #1', async (t) => {
@@ -58,8 +66,6 @@ test('validate config #3', async (t) => {
5866
});
5967

6068
test('validate config #4', async (t) => {
61-
const spy = vi.spyOn(console, 'log');
62-
6369
const { path, name } = createConfig(
6470
// @ts-expect-error
6571
{ out: 'test' },
@@ -71,38 +77,16 @@ test('validate config #4', async (t) => {
7177
unlinkSync(path);
7278

7379
expect(res.type).toBe('error');
74-
75-
expect(spy).toHaveBeenNthCalledWith(1, `Reading config file '${path}'`);
76-
expect(spy).toHaveBeenNthCalledWith(
77-
2,
78-
`Error Please provide required params:
79-
[x] dialect: undefined`,
80-
);
81-
82-
let error: any = res.type === 'error' ? res.error : undefined;
83-
expect(error).toBeDefined();
84-
expect(error).toBeInstanceOf(Error);
85-
expect(error.message).toBe('process.exit unexpectedly called with "1"');
86-
87-
spy.mockRestore();
80+
if (res.type !== 'error') return;
81+
expect((res.error as Error).message).toBe(error("Please specify 'dialect' param in config file"));
8882
});
8983

9084
test('validate config #5', async (t) => {
91-
const spy = vi.spyOn(console, 'log');
92-
9385
const res = await brotest(check, `--out=test`);
9486

9587
expect(res.type).toBe('error');
96-
97-
expect(spy).toHaveBeenCalledWith(
98-
`Error Please provide required params:
99-
[x] dialect: undefined`,
88+
if (res.type !== 'error') return;
89+
expect((res.error as Error).message).toBe(
90+
[error('Please provide required params:'), wrapParam('dialect', undefined)].join('\n'),
10091
);
101-
102-
let error: any = res.type === 'error' ? res.error : undefined;
103-
expect(error).toBeDefined();
104-
expect(error).toBeInstanceOf(Error);
105-
expect(error.message).toBe('process.exit unexpectedly called with "1"');
106-
107-
spy.mockRestore();
10892
});

drizzle-kit/tests/other/cli-export.test.ts

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { join } from 'node:path';
44
import { afterEach, assert, expect, test, vi } from 'vitest';
55
import { ExportConfig } from '../../src/cli/commands/utils';
66
import { exportRaw } from '../../src/cli/schema';
7+
import { wrapParam } from '../../src/cli/validations/common';
8+
import { error } from '../../src/cli/views';
79
import { createConfig } from './utils';
810

911
const originalPrefix = process.env.TEST_CONFIG_PATH_PREFIX;
@@ -133,8 +135,6 @@ test('validate config #2', async (t) => {
133135
});
134136

135137
test('validate config #3', async (t) => {
136-
const spy = vi.spyOn(console, 'log');
137-
138138
const { path, name } = createConfig(
139139
{ dialect: 'postgresql' },
140140
prefix,
@@ -145,24 +145,17 @@ test('validate config #3', async (t) => {
145145
unlinkSync(path);
146146

147147
expect(res.type).toBe('error');
148-
149-
expect(spy).toHaveBeenCalledWith(
150-
`Error Please provide required params:
151-
[✓] dialect: 'postgresql'
152-
[x] schema: undefined`,
148+
if (res.type !== 'error') return;
149+
expect((res.error as Error).message).toBe(
150+
[
151+
error('Please provide required params:'),
152+
wrapParam('schema', undefined),
153+
wrapParam('dialect', 'postgresql'),
154+
].join('\n'),
153155
);
154-
155-
let error: any = res.type === 'error' ? res.error : undefined;
156-
expect(error).toBeDefined();
157-
expect(error).toBeInstanceOf(Error);
158-
expect(error.message).toBe('process.exit unexpectedly called with "1"');
159-
160-
spy.mockRestore();
161156
});
162157

163158
test('validate config #4', async (t) => {
164-
const spy = vi.spyOn(console, 'log');
165-
166159
const { path, name } = createConfig(
167160
// @ts-expect-error
168161
{ schema: 'schema.ts' },
@@ -174,17 +167,6 @@ test('validate config #4', async (t) => {
174167
unlinkSync(path);
175168

176169
expect(res.type).toBe('error');
177-
178-
expect(spy).toHaveBeenCalledWith(
179-
`Error Please provide required params:
180-
[x] dialect: undefined
181-
[✓] schema: 'schema.ts'`,
182-
);
183-
184-
let error: any = res.type === 'error' ? res.error : undefined;
185-
expect(error).toBeDefined();
186-
expect(error).toBeInstanceOf(Error);
187-
expect(error.message).toBe('process.exit unexpectedly called with "1"');
188-
189-
spy.mockRestore();
170+
if (res.type !== 'error') return;
171+
expect((res.error as Error).message).toBe(error("Please specify 'dialect' param in config file"));
190172
});

drizzle-kit/tests/other/cli-generate.test.ts

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { afterEach, assert, expect, test, vi } from 'vitest';
55
import { GenerateConfig } from '../../src/cli/commands/utils';
66
import { HintsHandler } from '../../src/cli/hints';
77
import { generate } from '../../src/cli/schema';
8+
import { wrapParam } from '../../src/cli/validations/common';
9+
import { error } from '../../src/cli/views';
810
import { createConfig } from './utils';
911

1012
const originalPrefix = process.env.TEST_CONFIG_PATH_PREFIX;
@@ -427,8 +429,6 @@ test('validate config #2', async (t) => {
427429
});
428430

429431
test('validate config #3', async (t) => {
430-
const spy = vi.spyOn(console, 'log');
431-
432432
const { path, name } = createConfig(
433433
{ dialect: 'postgresql', driver: 'aws-data-api', out: 'test' },
434434
prefix,
@@ -439,30 +439,18 @@ test('validate config #3', async (t) => {
439439
unlinkSync(path);
440440

441441
expect(res.type).toBe('error');
442-
443-
// first call
444-
expect(spy).toHaveBeenNthCalledWith(1, `Reading config file '${path}'`);
445-
// second call
446-
// we need to check second call
447-
expect(spy).toHaveBeenNthCalledWith(
448-
2,
449-
`Error Please provide required params:
450-
[✓] dialect: 'postgresql'
451-
[x] schema: undefined`,
442+
if (res.type !== 'error') return;
443+
expect((res.error as Error).message).toBe(
444+
[
445+
error('Please provide required params:'),
446+
wrapParam('schema', undefined),
447+
wrapParam('dialect', 'postgresql'),
448+
wrapParam('out', 'test', true),
449+
].join('\n'),
452450
);
453-
454-
let error: any = res.type === 'error' ? res.error : undefined;
455-
expect(error).toBeDefined();
456-
expect(error).toBeInstanceOf(Error);
457-
expect(error.message).toBe('process.exit unexpectedly called with "1"');
458-
459-
spy.mockRestore();
460451
});
461452

462453
test('validate config #4', async (t) => {
463-
const spyLog = vi.spyOn(console, 'log');
464-
const spyError = vi.spyOn(console, 'error');
465-
466454
const { path, name } = createConfig(
467455
// @ts-expect-error
468456
{ dialect: 1, schema: 'path-to-schema' },
@@ -473,21 +461,10 @@ test('validate config #4', async (t) => {
473461

474462
unlinkSync(path);
475463

476-
// wrong dialect data type
464+
// wrong dialect data type → ConfigValidationCliError
477465
expect(res.type).toBe('error');
478-
479-
expect(spyLog).toHaveBeenNthCalledWith(1, `Reading config file '${path}'`);
480-
expect(spyLog).toHaveBeenCalledTimes(1);
481-
482-
expect(spyError).toHaveBeenCalledWith(expect.objectContaining({ name: 'ZodError' }));
483-
484-
let error: any = res.type === 'error' ? res.error : undefined;
485-
expect(error).toBeDefined();
486-
expect(error).toBeInstanceOf(Error);
487-
expect(error.message).toBe('process.exit unexpectedly called with "1"');
488-
489-
spyLog.mockRestore();
490-
spyError.mockRestore();
466+
if (res.type !== 'error') return;
467+
expect((res.error as Error).name).toBe('ConfigValidationCliError');
491468
});
492469

493470
test('validate config #5', async (t) => {

drizzle-kit/tests/other/cli-migrate.test.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { test as brotest } from '@drizzle-team/brocli';
22
import { unlinkSync } from 'fs';
33
import { afterEach, assert, expect, test, vi } from 'vitest';
44
import { migrate } from '../../src/cli/schema';
5+
import { wrapParam } from '../../src/cli/validations/common';
6+
import { error } from '../../src/cli/views';
57
import { createConfig } from './utils';
68

79
const originalPrefix = process.env.TEST_CONFIG_PATH_PREFIX;
@@ -221,8 +223,6 @@ test('validate config #3', async (t) => {
221223
});
222224

223225
test('validate config #3', async (t) => {
224-
const spy = vi.spyOn(console, 'log');
225-
226226
const { path, name } = createConfig(
227227
// @ts-expect-error
228228
{ driver: 'aws-data-api', out: 'test' },
@@ -234,18 +234,6 @@ test('validate config #3', async (t) => {
234234
unlinkSync(path);
235235

236236
expect(res.type).toBe('error');
237-
238-
expect(spy).toHaveBeenNthCalledWith(1, `Reading config file '${path}'`);
239-
expect(spy).toHaveBeenNthCalledWith(
240-
2,
241-
`Error Please provide required params:
242-
[x] dialect: undefined`,
243-
);
244-
245-
let error: any = res.type === 'error' ? res.error : undefined;
246-
expect(error).toBeDefined();
247-
expect(error).toBeInstanceOf(Error);
248-
expect(error.message).toBe('process.exit unexpectedly called with "1"');
249-
250-
spy.mockRestore();
237+
if (res.type !== 'error') return;
238+
expect((res.error as Error).message).toBe(error("Please specify 'dialect' param in config file"));
251239
});

drizzle-kit/tests/other/cli-pull.test.ts

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
import { test as brotest } from '@drizzle-team/brocli';
22
import { unlinkSync } from 'node:fs';
33
import { join } from 'node:path';
4-
import { assert, expect, test, vi } from 'vitest';
4+
import { afterEach, assert, expect, test, vi } from 'vitest';
55
import { pull } from '../../src/cli/schema';
6+
import { wrapParam } from '../../src/cli/validations/common';
7+
import { error } from '../../src/cli/views';
68
import { createConfig } from './utils';
79

10+
const originalPrefix = process.env.TEST_CONFIG_PATH_PREFIX;
11+
process.env.TEST_CONFIG_PATH_PREFIX = './tests/cli/';
12+
afterEach(() => {
13+
process.env.TEST_CONFIG_PATH_PREFIX = originalPrefix ?? './tests/cli/';
14+
});
15+
816
test('pull #1', async (t) => {
917
const res = await brotest(pull, '');
1018
if (res.type !== 'handler') assert.fail(res.type, 'handler');
@@ -342,8 +350,6 @@ test('validate config #4', async (t) => {
342350
});
343351

344352
test('validate config #5', async (t) => {
345-
const spy = vi.spyOn(console, 'log');
346-
347353
// @ts-expect-error
348354
const { path, name } = createConfig({
349355
// dialect: 'mysql',
@@ -357,25 +363,11 @@ test('validate config #5', async (t) => {
357363
unlinkSync(path);
358364

359365
expect(res.type).toBe('error');
360-
361-
expect(spy).toHaveBeenNthCalledWith(1, `Reading config file '${path}'`);
362-
expect(spy).toHaveBeenNthCalledWith(
363-
2,
364-
`Error Please provide required params:
365-
[x] dialect: undefined`,
366-
);
367-
368-
let error: any = res.type === 'error' ? res.error : undefined;
369-
expect(error).toBeDefined();
370-
expect(error).toBeInstanceOf(Error);
371-
expect(error.message).toBe('process.exit unexpectedly called with "1"');
372-
373-
spy.mockRestore();
366+
if (res.type !== 'error') return;
367+
expect((res.error as Error).message).toBe(error("Please specify 'dialect' param in config file"));
374368
});
375369

376370
test('validate config #6', async (t) => {
377-
const spy = vi.spyOn(console, 'log');
378-
379371
const { path, name } = createConfig({
380372
dialect: 'mysql',
381373
dbCredentials: {
@@ -388,17 +380,6 @@ test('validate config #6', async (t) => {
388380
unlinkSync(path);
389381

390382
expect(res.type).toBe('error');
391-
392-
expect(spy).toHaveBeenNthCalledWith(1, `Reading config file '${path}'`);
393-
expect(spy).toHaveBeenNthCalledWith(
394-
2,
395-
'Error Please provide required params for MySQL driver:',
396-
);
397-
398-
let error: any = res.type === 'error' ? res.error : undefined;
399-
expect(error).toBeDefined();
400-
expect(error).toBeInstanceOf(Error);
401-
expect(error.message).toBe('process.exit unexpectedly called with "1"');
402-
403-
spy.mockRestore();
383+
if (res.type !== 'error') return;
384+
expect((res.error as Error).message).toContain('MySQL driver');
404385
});

0 commit comments

Comments
 (0)