@zenstackhq/cli 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/index.cjs +88 -5
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +89 -6
  4. package/dist/index.js.map +1 -1
  5. package/package.json +17 -9
  6. package/.turbo/turbo-build.log +0 -22
  7. package/eslint.config.js +0 -4
  8. package/scripts/post-build.ts +0 -20
  9. package/src/actions/action-utils.ts +0 -146
  10. package/src/actions/check.ts +0 -22
  11. package/src/actions/db.ts +0 -51
  12. package/src/actions/format.ts +0 -27
  13. package/src/actions/generate.ts +0 -226
  14. package/src/actions/index.ts +0 -10
  15. package/src/actions/info.ts +0 -71
  16. package/src/actions/init.ts +0 -61
  17. package/src/actions/migrate.ts +0 -149
  18. package/src/actions/seed.ts +0 -38
  19. package/src/actions/templates.ts +0 -58
  20. package/src/cli-error.ts +0 -4
  21. package/src/constants.ts +0 -5
  22. package/src/index.ts +0 -233
  23. package/src/plugins/index.ts +0 -2
  24. package/src/plugins/prisma.ts +0 -21
  25. package/src/plugins/typescript.ts +0 -40
  26. package/src/telemetry.ts +0 -139
  27. package/src/utils/exec-utils.ts +0 -61
  28. package/src/utils/is-ci.ts +0 -5
  29. package/src/utils/is-container.ts +0 -23
  30. package/src/utils/is-docker.ts +0 -31
  31. package/src/utils/is-wsl.ts +0 -18
  32. package/src/utils/machine-id-utils.ts +0 -76
  33. package/src/utils/version-utils.ts +0 -50
  34. package/test/check.test.ts +0 -101
  35. package/test/db.test.ts +0 -61
  36. package/test/format.test.ts +0 -33
  37. package/test/generate.test.ts +0 -76
  38. package/test/init.test.ts +0 -14
  39. package/test/migrate.test.ts +0 -72
  40. package/test/plugins/custom-plugin.test.ts +0 -50
  41. package/test/plugins/prisma-plugin.test.ts +0 -81
  42. package/test/ts-schema-gen.test.ts +0 -445
  43. package/test/utils.ts +0 -23
  44. package/tsconfig.json +0 -4
  45. package/tsup.config.ts +0 -13
  46. package/vitest.config.ts +0 -4
package/src/telemetry.ts DELETED
@@ -1,139 +0,0 @@
1
- import { init, type Mixpanel } from 'mixpanel';
2
- import { randomUUID } from 'node:crypto';
3
- import fs from 'node:fs';
4
- import * as os from 'os';
5
- import { TELEMETRY_TRACKING_TOKEN } from './constants';
6
- import { isInCi } from './utils/is-ci';
7
- import { isInContainer } from './utils/is-container';
8
- import isDocker from './utils/is-docker';
9
- import { isWsl } from './utils/is-wsl';
10
- import { getMachineId } from './utils/machine-id-utils';
11
- import { getVersion } from './utils/version-utils';
12
-
13
- /**
14
- * Telemetry events
15
- */
16
- export type TelemetryEvents =
17
- | 'cli:start'
18
- | 'cli:complete'
19
- | 'cli:error'
20
- | 'cli:command:start'
21
- | 'cli:command:complete'
22
- | 'cli:command:error'
23
- | 'cli:plugin:start'
24
- | 'cli:plugin:complete'
25
- | 'cli:plugin:error';
26
-
27
- /**
28
- * Utility class for sending telemetry
29
- */
30
- export class Telemetry {
31
- private readonly mixpanel: Mixpanel | undefined;
32
- private readonly hostId = getMachineId();
33
- private readonly sessionid = randomUUID();
34
- private readonly _os_type = os.type();
35
- private readonly _os_release = os.release();
36
- private readonly _os_arch = os.arch();
37
- private readonly _os_version = os.version();
38
- private readonly _os_platform = os.platform();
39
- private readonly version = getVersion();
40
- private readonly prismaVersion = this.getPrismaVersion();
41
- private readonly isDocker = isDocker();
42
- private readonly isWsl = isWsl();
43
- private readonly isContainer = isInContainer();
44
- private readonly isCi = isInCi;
45
-
46
- constructor() {
47
- if (process.env['DO_NOT_TRACK'] !== '1' && TELEMETRY_TRACKING_TOKEN) {
48
- this.mixpanel = init(TELEMETRY_TRACKING_TOKEN, {
49
- geolocate: true,
50
- });
51
- }
52
- }
53
-
54
- get isTracking() {
55
- return !!this.mixpanel;
56
- }
57
-
58
- track(event: TelemetryEvents, properties: Record<string, unknown> = {}) {
59
- if (this.mixpanel) {
60
- const payload = {
61
- distinct_id: this.hostId,
62
- session: this.sessionid,
63
- time: new Date(),
64
- $os: this._os_type,
65
- osType: this._os_type,
66
- osRelease: this._os_release,
67
- osPlatform: this._os_platform,
68
- osArch: this._os_arch,
69
- osVersion: this._os_version,
70
- nodeVersion: process.version,
71
- version: this.version,
72
- prismaVersion: this.prismaVersion,
73
- isDocker: this.isDocker,
74
- isWsl: this.isWsl,
75
- isContainer: this.isContainer,
76
- isCi: this.isCi,
77
- ...properties,
78
- };
79
- this.mixpanel.track(event, payload);
80
- }
81
- }
82
-
83
- trackError(err: Error) {
84
- this.track('cli:error', {
85
- message: err.message,
86
- stack: err.stack,
87
- });
88
- }
89
-
90
- async trackSpan<T>(
91
- startEvent: TelemetryEvents,
92
- completeEvent: TelemetryEvents,
93
- errorEvent: TelemetryEvents,
94
- properties: Record<string, unknown>,
95
- action: () => Promise<T> | T,
96
- ) {
97
- this.track(startEvent, properties);
98
- const start = Date.now();
99
- let success = true;
100
- try {
101
- return await action();
102
- } catch (err: any) {
103
- this.track(errorEvent, {
104
- message: err.message,
105
- stack: err.stack,
106
- ...properties,
107
- });
108
- success = false;
109
- throw err;
110
- } finally {
111
- this.track(completeEvent, {
112
- duration: Date.now() - start,
113
- success,
114
- ...properties,
115
- });
116
- }
117
- }
118
-
119
- async trackCommand(command: string, action: () => Promise<void> | void) {
120
- await this.trackSpan('cli:command:start', 'cli:command:complete', 'cli:command:error', { command }, action);
121
- }
122
-
123
- async trackCli(action: () => Promise<void> | void) {
124
- await this.trackSpan('cli:start', 'cli:complete', 'cli:error', {}, action);
125
- }
126
-
127
- getPrismaVersion() {
128
- try {
129
- const packageJsonPath = import.meta.resolve('prisma/package.json');
130
- const packageJsonUrl = new URL(packageJsonPath);
131
- const packageJson = JSON.parse(fs.readFileSync(packageJsonUrl, 'utf8'));
132
- return packageJson.version;
133
- } catch {
134
- return undefined;
135
- }
136
- }
137
- }
138
-
139
- export const telemetry = new Telemetry();
@@ -1,61 +0,0 @@
1
- import { execSync as _exec, type ExecSyncOptions } from 'child_process';
2
- import { fileURLToPath } from 'url';
3
-
4
- /**
5
- * Utility for executing command synchronously and prints outputs on current console
6
- */
7
- export function execSync(cmd: string, options?: Omit<ExecSyncOptions, 'env'> & { env?: Record<string, string> }): void {
8
- const { env, ...restOptions } = options ?? {};
9
- const mergedEnv = env ? { ...process.env, ...env } : undefined;
10
- _exec(cmd, {
11
- encoding: 'utf-8',
12
- stdio: options?.stdio ?? 'inherit',
13
- env: mergedEnv,
14
- ...restOptions,
15
- });
16
- }
17
-
18
- /**
19
- * Utility for running package commands through npx/bunx
20
- */
21
- export function execPackage(
22
- cmd: string,
23
- options?: Omit<ExecSyncOptions, 'env'> & { env?: Record<string, string> },
24
- ): void {
25
- const packageManager = process?.versions?.['bun'] ? 'bunx' : 'npx';
26
- execSync(`${packageManager} ${cmd}`, options);
27
- }
28
-
29
- /**
30
- * Utility for running prisma commands
31
- */
32
- export function execPrisma(args: string, options?: Omit<ExecSyncOptions, 'env'> & { env?: Record<string, string> }) {
33
- let prismaPath: string | undefined;
34
- try {
35
- if (typeof import.meta.resolve === 'function') {
36
- // esm
37
- prismaPath = fileURLToPath(import.meta.resolve('prisma/build/index.js'));
38
- } else {
39
- // cjs
40
- prismaPath = require.resolve('prisma/build/index.js');
41
- }
42
- } catch {
43
- // ignore and fallback
44
- }
45
-
46
- const _options = {
47
- ...options,
48
- env: {
49
- ...options?.env,
50
- PRISMA_HIDE_UPDATE_MESSAGE: '1',
51
- },
52
- };
53
-
54
- if (!prismaPath) {
55
- // fallback to npx/bunx execute
56
- execPackage(`prisma ${args}`, _options);
57
- return;
58
- }
59
-
60
- execSync(`node ${prismaPath} ${args}`, _options);
61
- }
@@ -1,5 +0,0 @@
1
- import { env } from 'node:process';
2
- export const isInCi =
3
- env['CI'] !== '0' &&
4
- env['CI'] !== 'false' &&
5
- ('CI' in env || 'CONTINUOUS_INTEGRATION' in env || Object.keys(env).some((key) => key.startsWith('CI_')));
@@ -1,23 +0,0 @@
1
- import fs from 'node:fs';
2
- import isDocker from './is-docker';
3
-
4
- let cachedResult: boolean | undefined;
5
-
6
- // Podman detection
7
- const hasContainerEnv = () => {
8
- try {
9
- fs.statSync('/run/.containerenv');
10
- return true;
11
- } catch {
12
- return false;
13
- }
14
- };
15
-
16
- export function isInContainer() {
17
- // TODO: Use `??=` when targeting Node.js 16.
18
- if (cachedResult === undefined) {
19
- cachedResult = hasContainerEnv() || isDocker();
20
- }
21
-
22
- return cachedResult;
23
- }
@@ -1,31 +0,0 @@
1
- // Copied over from https://github.com/sindresorhus/is-docker for CJS compatibility
2
-
3
- import fs from 'node:fs';
4
-
5
- let isDockerCached: boolean | undefined;
6
-
7
- function hasDockerEnv() {
8
- try {
9
- fs.statSync('/.dockerenv');
10
- return true;
11
- } catch {
12
- return false;
13
- }
14
- }
15
-
16
- function hasDockerCGroup() {
17
- try {
18
- return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
19
- } catch {
20
- return false;
21
- }
22
- }
23
-
24
- export default function isDocker() {
25
- // TODO: Use `??=` when targeting Node.js 16.
26
- if (isDockerCached === undefined) {
27
- isDockerCached = hasDockerEnv() || hasDockerCGroup();
28
- }
29
-
30
- return isDockerCached;
31
- }
@@ -1,18 +0,0 @@
1
- import process from 'node:process';
2
- import os from 'node:os';
3
- import fs from 'node:fs';
4
- export const isWsl = () => {
5
- if (process.platform !== 'linux') {
6
- return false;
7
- }
8
-
9
- if (os.release().toLowerCase().includes('microsoft')) {
10
- return true;
11
- }
12
-
13
- try {
14
- return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft');
15
- } catch {
16
- return false;
17
- }
18
- };
@@ -1,76 +0,0 @@
1
- // modified from https://github.com/automation-stack/node-machine-id
2
-
3
- import { execSync } from 'child_process';
4
- import { createHash, randomUUID } from 'node:crypto';
5
-
6
- const { platform } = process;
7
- const win32RegBinPath = {
8
- native: '%windir%\\System32',
9
- mixed: '%windir%\\sysnative\\cmd.exe /c %windir%\\System32',
10
- };
11
- const guid = {
12
- darwin: 'ioreg -rd1 -c IOPlatformExpertDevice',
13
- win32:
14
- `${win32RegBinPath[isWindowsProcessMixedOrNativeArchitecture()]}\\REG.exe ` +
15
- 'QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography ' +
16
- '/v MachineGuid',
17
- linux: '( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname 2> /dev/null) | head -n 1 || :',
18
- freebsd: 'kenv -q smbios.system.uuid || sysctl -n kern.hostuuid',
19
- };
20
-
21
- function isWindowsProcessMixedOrNativeArchitecture() {
22
- // eslint-disable-next-line no-prototype-builtins
23
- if (process.arch === 'ia32' && process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432')) {
24
- return 'mixed';
25
- }
26
- return 'native';
27
- }
28
-
29
- function hash(guid: string): string {
30
- return createHash('sha256').update(guid).digest('hex');
31
- }
32
-
33
- function expose(result: string): string | undefined {
34
- switch (platform) {
35
- case 'darwin':
36
- return result
37
- .split('IOPlatformUUID')[1]
38
- ?.split('\n')[0]
39
- ?.replace(/=|\s+|"/gi, '')
40
- .toLowerCase();
41
- case 'win32':
42
- return result
43
- .toString()
44
- .split('REG_SZ')[1]
45
- ?.replace(/\r+|\n+|\s+/gi, '')
46
- .toLowerCase();
47
- case 'linux':
48
- return result
49
- .toString()
50
- .replace(/\r+|\n+|\s+/gi, '')
51
- .toLowerCase();
52
- case 'freebsd':
53
- return result
54
- .toString()
55
- .replace(/\r+|\n+|\s+/gi, '')
56
- .toLowerCase();
57
- default:
58
- throw new Error(`Unsupported platform: ${process.platform}`);
59
- }
60
- }
61
-
62
- export function getMachineId() {
63
- if (!(platform in guid)) {
64
- return randomUUID();
65
- }
66
- try {
67
- const value = execSync(guid[platform as keyof typeof guid]);
68
- const id = expose(value.toString());
69
- if (!id) {
70
- return randomUUID();
71
- }
72
- return hash(id);
73
- } catch {
74
- return randomUUID();
75
- }
76
- }
@@ -1,50 +0,0 @@
1
- import colors from 'colors';
2
- import fs from 'node:fs';
3
- import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- import semver from 'semver';
6
-
7
- const CHECK_VERSION_TIMEOUT = 2000;
8
- const VERSION_CHECK_TAG = 'next';
9
-
10
- export function getVersion() {
11
- try {
12
- // isomorphic __dirname
13
- const _dirname = typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url));
14
- return JSON.parse(fs.readFileSync(path.join(_dirname, '../package.json'), 'utf8')).version;
15
- } catch {
16
- return undefined;
17
- }
18
- }
19
-
20
- export async function checkNewVersion() {
21
- const currVersion = getVersion();
22
- let latestVersion: string;
23
- try {
24
- latestVersion = await getLatestVersion();
25
- } catch {
26
- // noop
27
- return;
28
- }
29
-
30
- if (latestVersion && currVersion && semver.gt(latestVersion, currVersion)) {
31
- console.log(`A newer version ${colors.cyan(latestVersion)} is available.`);
32
- }
33
- }
34
-
35
- export async function getLatestVersion() {
36
- const fetchResult = await fetch(`https://registry.npmjs.org/@zenstackhq/cli/${VERSION_CHECK_TAG}`, {
37
- headers: { accept: 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' },
38
- signal: AbortSignal.timeout(CHECK_VERSION_TIMEOUT),
39
- });
40
-
41
- if (fetchResult.ok) {
42
- const data: any = await fetchResult.json();
43
- const latestVersion = data?.version;
44
- if (typeof latestVersion === 'string' && semver.valid(latestVersion)) {
45
- return latestVersion;
46
- }
47
- }
48
-
49
- throw new Error('invalid npm registry response');
50
- }
@@ -1,101 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { describe, expect, it } from 'vitest';
4
- import { createProject, runCli } from './utils';
5
-
6
- const validModel = `
7
- model User {
8
- id String @id @default(cuid())
9
- email String @unique
10
- name String?
11
- posts Post[]
12
- }
13
-
14
- model Post {
15
- id String @id @default(cuid())
16
- title String
17
- content String?
18
- author User @relation(fields: [authorId], references: [id])
19
- authorId String
20
- }
21
- `;
22
-
23
- const invalidModel = `
24
- model User {
25
- id String @id @default(cuid())
26
- email String @unique
27
- posts Post[]
28
- }
29
-
30
- model Post {
31
- id String @id @default(cuid())
32
- title String
33
- author User @relation(fields: [authorId], references: [id])
34
- // Missing authorId field - should cause validation error
35
- }
36
- `;
37
-
38
- describe('CLI validate command test', () => {
39
- it('should validate a valid schema successfully', () => {
40
- const workDir = createProject(validModel);
41
-
42
- // Should not throw an error
43
- expect(() => runCli('check', workDir)).not.toThrow();
44
- });
45
-
46
- it('should fail validation for invalid schema', () => {
47
- const workDir = createProject(invalidModel);
48
-
49
- // Should throw an error due to validation failure
50
- expect(() => runCli('check', workDir)).toThrow();
51
- });
52
-
53
- it('should respect custom schema location', () => {
54
- const workDir = createProject(validModel);
55
- fs.renameSync(path.join(workDir, 'zenstack/schema.zmodel'), path.join(workDir, 'zenstack/custom.zmodel'));
56
-
57
- // Should not throw an error when using custom schema path
58
- expect(() => runCli('check --schema ./zenstack/custom.zmodel', workDir)).not.toThrow();
59
- });
60
-
61
- it('should fail when schema file does not exist', () => {
62
- const workDir = createProject(validModel);
63
-
64
- // Should throw an error when schema file doesn't exist
65
- expect(() => runCli('check --schema ./nonexistent.zmodel', workDir)).toThrow();
66
- });
67
-
68
- it('should respect package.json config', () => {
69
- const workDir = createProject(validModel);
70
- fs.mkdirSync(path.join(workDir, 'foo'));
71
- fs.renameSync(path.join(workDir, 'zenstack/schema.zmodel'), path.join(workDir, 'foo/schema.zmodel'));
72
- fs.rmdirSync(path.join(workDir, 'zenstack'));
73
-
74
- const pkgJson = JSON.parse(fs.readFileSync(path.join(workDir, 'package.json'), 'utf8'));
75
- pkgJson.zenstack = {
76
- schema: './foo/schema.zmodel',
77
- };
78
- fs.writeFileSync(path.join(workDir, 'package.json'), JSON.stringify(pkgJson, null, 2));
79
-
80
- // Should not throw an error when using package.json config
81
- expect(() => runCli('check', workDir)).not.toThrow();
82
- });
83
-
84
- it('should validate schema with syntax errors', () => {
85
- const modelWithSyntaxError = `
86
- datasource db {
87
- provider = "sqlite"
88
- url = "file:./dev.db"
89
- }
90
-
91
- model User {
92
- id String @id @default(cuid())
93
- email String @unique
94
- // Missing closing brace - syntax error
95
- `;
96
- const workDir = createProject(modelWithSyntaxError, false);
97
-
98
- // Should throw an error due to syntax error
99
- expect(() => runCli('check', workDir)).toThrow();
100
- });
101
- });
package/test/db.test.ts DELETED
@@ -1,61 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { describe, expect, it } from 'vitest';
4
- import { createProject, runCli } from './utils';
5
-
6
- const model = `
7
- model User {
8
- id String @id @default(cuid())
9
- }
10
- `;
11
-
12
- describe('CLI db commands test', () => {
13
- it('should generate a database with db push', () => {
14
- const workDir = createProject(model);
15
- runCli('db push', workDir);
16
- expect(fs.existsSync(path.join(workDir, 'zenstack/dev.db'))).toBe(true);
17
- });
18
-
19
- it('should seed the database with db seed with seed script', () => {
20
- const workDir = createProject(model);
21
- const pkgJson = JSON.parse(fs.readFileSync(path.join(workDir, 'package.json'), 'utf8'));
22
- pkgJson.zenstack = {
23
- seed: 'node seed.js',
24
- };
25
- fs.writeFileSync(path.join(workDir, 'package.json'), JSON.stringify(pkgJson, null, 2));
26
- fs.writeFileSync(
27
- path.join(workDir, 'seed.js'),
28
- `
29
- import fs from 'node:fs';
30
- fs.writeFileSync('seed.txt', 'success');
31
- `,
32
- );
33
-
34
- runCli('db seed', workDir);
35
- expect(fs.readFileSync(path.join(workDir, 'seed.txt'), 'utf8')).toBe('success');
36
- });
37
-
38
- it('should seed the database after migrate reset', () => {
39
- const workDir = createProject(model);
40
- const pkgJson = JSON.parse(fs.readFileSync(path.join(workDir, 'package.json'), 'utf8'));
41
- pkgJson.zenstack = {
42
- seed: 'node seed.js',
43
- };
44
- fs.writeFileSync(path.join(workDir, 'package.json'), JSON.stringify(pkgJson, null, 2));
45
- fs.writeFileSync(
46
- path.join(workDir, 'seed.js'),
47
- `
48
- import fs from 'node:fs';
49
- fs.writeFileSync('seed.txt', 'success');
50
- `,
51
- );
52
-
53
- runCli('migrate reset --force', workDir);
54
- expect(fs.readFileSync(path.join(workDir, 'seed.txt'), 'utf8')).toBe('success');
55
- });
56
-
57
- it('should skip seeding the database without seed script', () => {
58
- const workDir = createProject(model);
59
- runCli('db seed', workDir);
60
- });
61
- });
@@ -1,33 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { createProject, runCli } from './utils';
3
- import fs from 'node:fs';
4
-
5
- const model = `
6
- model User {
7
- id String @id @default(cuid())
8
- email String @unique
9
- }
10
- `;
11
-
12
- describe('CLI format command test', () => {
13
- it('should format a valid schema successfully', () => {
14
- const workDir = createProject(model);
15
- expect(() => runCli('format', workDir)).not.toThrow();
16
- const updatedContent = fs.readFileSync(`${workDir}/zenstack/schema.zmodel`, 'utf-8');
17
- expect(
18
- updatedContent.includes(`model User {
19
- id String @id @default(cuid())
20
- email String @unique
21
- }`),
22
- ).toBeTruthy();
23
- });
24
-
25
- it('should silently ignore invalid schema', () => {
26
- const invalidModel = `
27
- model User {
28
- id String @id @default(cuid())
29
- `;
30
- const workDir = createProject(invalidModel);
31
- expect(() => runCli('format', workDir)).not.toThrow();
32
- });
33
- });
@@ -1,76 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { describe, expect, it } from 'vitest';
4
- import { createProject, runCli } from './utils';
5
-
6
- const model = `
7
- model User {
8
- id String @id @default(cuid())
9
- }
10
- `;
11
-
12
- describe('CLI generate command test', () => {
13
- it('should generate a TypeScript schema', () => {
14
- const workDir = createProject(model);
15
- runCli('generate', workDir);
16
- expect(fs.existsSync(path.join(workDir, 'zenstack/schema.ts'))).toBe(true);
17
- expect(fs.existsSync(path.join(workDir, 'zenstack/schema.prisma'))).toBe(false);
18
- });
19
-
20
- it('should respect custom output directory', () => {
21
- const workDir = createProject(model);
22
- runCli('generate --output ./zen', workDir);
23
- expect(fs.existsSync(path.join(workDir, 'zen/schema.ts'))).toBe(true);
24
- });
25
-
26
- it('should respect custom schema location', () => {
27
- const workDir = createProject(model);
28
- fs.renameSync(path.join(workDir, 'zenstack/schema.zmodel'), path.join(workDir, 'zenstack/foo.zmodel'));
29
- runCli('generate --schema ./zenstack/foo.zmodel', workDir);
30
- expect(fs.existsSync(path.join(workDir, 'zenstack/schema.ts'))).toBe(true);
31
- });
32
-
33
- it('should respect package.json config', () => {
34
- const workDir = createProject(model);
35
- fs.mkdirSync(path.join(workDir, 'foo'));
36
- fs.renameSync(path.join(workDir, 'zenstack/schema.zmodel'), path.join(workDir, 'foo/schema.zmodel'));
37
- fs.rmdirSync(path.join(workDir, 'zenstack'));
38
- const pkgJson = JSON.parse(fs.readFileSync(path.join(workDir, 'package.json'), 'utf8'));
39
- pkgJson.zenstack = {
40
- schema: './foo/schema.zmodel',
41
- output: './bar',
42
- };
43
- fs.writeFileSync(path.join(workDir, 'package.json'), JSON.stringify(pkgJson, null, 2));
44
- runCli('generate', workDir);
45
- expect(fs.existsSync(path.join(workDir, 'bar/schema.ts'))).toBe(true);
46
- });
47
-
48
- it('should respect package.json schema dir config', () => {
49
- const workDir = createProject(model);
50
- fs.mkdirSync(path.join(workDir, 'foo'));
51
- fs.renameSync(path.join(workDir, 'zenstack/schema.zmodel'), path.join(workDir, 'foo/schema.zmodel'));
52
- fs.rmdirSync(path.join(workDir, 'zenstack'));
53
- const pkgJson = JSON.parse(fs.readFileSync(path.join(workDir, 'package.json'), 'utf8'));
54
- pkgJson.zenstack = {
55
- schema: './foo',
56
- output: './bar',
57
- };
58
- fs.writeFileSync(path.join(workDir, 'package.json'), JSON.stringify(pkgJson, null, 2));
59
- runCli('generate', workDir);
60
- expect(fs.existsSync(path.join(workDir, 'bar/schema.ts'))).toBe(true);
61
- });
62
-
63
- it('should respect lite option', () => {
64
- const workDir = createProject(model);
65
- runCli('generate --lite', workDir);
66
- expect(fs.existsSync(path.join(workDir, 'zenstack/schema.ts'))).toBe(true);
67
- expect(fs.existsSync(path.join(workDir, 'zenstack/schema-lite.ts'))).toBe(true);
68
- });
69
-
70
- it('should respect liteOnly option', () => {
71
- const workDir = createProject(model);
72
- runCli('generate --lite-only', workDir);
73
- expect(fs.existsSync(path.join(workDir, 'zenstack/schema.ts'))).toBe(false);
74
- expect(fs.existsSync(path.join(workDir, 'zenstack/schema-lite.ts'))).toBe(true);
75
- });
76
- });