@zenstackhq/cli 3.0.0-alpha.9 → 3.0.0-beta.10
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.
- package/.turbo/turbo-build.log +11 -11
- package/dist/index.cjs +652 -120
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -4
- package/dist/index.d.ts +1 -4
- package/dist/index.js +654 -112
- package/dist/index.js.map +1 -1
- package/package.json +15 -11
- package/scripts/post-build.ts +20 -0
- package/src/actions/action-utils.ts +69 -4
- package/src/actions/check.ts +22 -0
- package/src/actions/db.ts +9 -6
- package/src/actions/generate.ts +110 -36
- package/src/actions/index.ts +2 -1
- package/src/actions/info.ts +4 -1
- package/src/actions/migrate.ts +54 -16
- package/src/actions/templates.ts +4 -3
- package/src/constants.ts +5 -0
- package/src/index.ts +99 -28
- package/src/plugins/index.ts +2 -0
- package/src/plugins/prisma.ts +21 -0
- package/src/plugins/typescript.ts +21 -0
- package/src/telemetry.ts +139 -0
- package/src/utils/is-ci.ts +5 -0
- package/src/utils/is-container.ts +23 -0
- package/src/utils/is-docker.ts +31 -0
- package/src/utils/is-wsl.ts +18 -0
- package/src/utils/machine-id-utils.ts +76 -0
- package/src/utils/version-utils.ts +37 -0
- package/test/check.test.ts +101 -0
- package/test/generate.test.ts +12 -9
- package/test/init.test.ts +2 -1
- package/test/migrate.test.ts +33 -1
- package/test/plugins/custom-plugin.test.ts +50 -0
- package/test/plugins/prisma-plugin.test.ts +81 -0
- package/test/ts-schema-gen.test.ts +240 -1
- package/tsconfig.json +0 -3
- package/vitest.config.ts +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ExpressionUtils } from '@zenstackhq/runtime/schema';
|
|
2
|
-
import { generateTsSchema } from '@zenstackhq/testtools';
|
|
2
|
+
import { createTestProject, generateTsSchema, generateTsSchemaInPlace } from '@zenstackhq/testtools';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
3
5
|
import { describe, expect, it } from 'vitest';
|
|
4
6
|
|
|
5
7
|
describe('TypeScript schema generation tests', () => {
|
|
@@ -181,4 +183,241 @@ model Post {
|
|
|
181
183
|
},
|
|
182
184
|
});
|
|
183
185
|
});
|
|
186
|
+
|
|
187
|
+
it('merges fields and attributes from mixins', async () => {
|
|
188
|
+
const { schema } = await generateTsSchema(`
|
|
189
|
+
type Timestamped {
|
|
190
|
+
createdAt DateTime @default(now())
|
|
191
|
+
updatedAt DateTime @updatedAt
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
type Named {
|
|
195
|
+
name String
|
|
196
|
+
@@unique([name])
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
model User with Timestamped Named {
|
|
200
|
+
id String @id @default(uuid())
|
|
201
|
+
email String @unique
|
|
202
|
+
}
|
|
203
|
+
`);
|
|
204
|
+
expect(schema).toMatchObject({
|
|
205
|
+
models: {
|
|
206
|
+
User: {
|
|
207
|
+
fields: {
|
|
208
|
+
id: { type: 'String' },
|
|
209
|
+
email: { type: 'String' },
|
|
210
|
+
createdAt: {
|
|
211
|
+
type: 'DateTime',
|
|
212
|
+
default: expect.objectContaining({ function: 'now', kind: 'call' }),
|
|
213
|
+
},
|
|
214
|
+
updatedAt: { type: 'DateTime', updatedAt: true },
|
|
215
|
+
name: { type: 'String' },
|
|
216
|
+
},
|
|
217
|
+
uniqueFields: expect.objectContaining({
|
|
218
|
+
name: { type: 'String' },
|
|
219
|
+
}),
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('generates type definitions', async () => {
|
|
226
|
+
const { schema } = await generateTsSchema(`
|
|
227
|
+
type Base {
|
|
228
|
+
name String
|
|
229
|
+
@@meta('foo', 'bar')
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
type Address with Base {
|
|
233
|
+
street String
|
|
234
|
+
city String
|
|
235
|
+
}
|
|
236
|
+
`);
|
|
237
|
+
expect(schema).toMatchObject({
|
|
238
|
+
typeDefs: {
|
|
239
|
+
Base: {
|
|
240
|
+
fields: {
|
|
241
|
+
name: { type: 'String' },
|
|
242
|
+
},
|
|
243
|
+
attributes: [
|
|
244
|
+
{
|
|
245
|
+
name: '@@meta',
|
|
246
|
+
args: [
|
|
247
|
+
{ name: 'name', value: { kind: 'literal', value: 'foo' } },
|
|
248
|
+
{ name: 'value', value: { kind: 'literal', value: 'bar' } },
|
|
249
|
+
],
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
},
|
|
253
|
+
Address: {
|
|
254
|
+
fields: {
|
|
255
|
+
street: { type: 'String' },
|
|
256
|
+
city: { type: 'String' },
|
|
257
|
+
},
|
|
258
|
+
attributes: [
|
|
259
|
+
{
|
|
260
|
+
name: '@@meta',
|
|
261
|
+
args: [
|
|
262
|
+
{ name: 'name', value: { kind: 'literal', value: 'foo' } },
|
|
263
|
+
{ name: 'value', value: { kind: 'literal', value: 'bar' } },
|
|
264
|
+
],
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('merges fields and attributes from base models', async () => {
|
|
273
|
+
const { schema } = await generateTsSchema(`
|
|
274
|
+
model Base {
|
|
275
|
+
id String @id @default(uuid())
|
|
276
|
+
createdAt DateTime @default(now())
|
|
277
|
+
updatedAt DateTime @updatedAt
|
|
278
|
+
type String
|
|
279
|
+
@@delegate(type)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
model User extends Base {
|
|
283
|
+
email String @unique
|
|
284
|
+
}
|
|
285
|
+
`);
|
|
286
|
+
expect(schema).toMatchObject({
|
|
287
|
+
models: {
|
|
288
|
+
Base: {
|
|
289
|
+
fields: {
|
|
290
|
+
id: {
|
|
291
|
+
type: 'String',
|
|
292
|
+
id: true,
|
|
293
|
+
default: expect.objectContaining({ function: 'uuid', kind: 'call' }),
|
|
294
|
+
},
|
|
295
|
+
createdAt: {
|
|
296
|
+
type: 'DateTime',
|
|
297
|
+
default: expect.objectContaining({ function: 'now', kind: 'call' }),
|
|
298
|
+
},
|
|
299
|
+
updatedAt: { type: 'DateTime', updatedAt: true },
|
|
300
|
+
type: { type: 'String' },
|
|
301
|
+
},
|
|
302
|
+
attributes: [
|
|
303
|
+
{
|
|
304
|
+
name: '@@delegate',
|
|
305
|
+
args: [{ name: 'discriminator', value: { kind: 'field', field: 'type' } }],
|
|
306
|
+
},
|
|
307
|
+
],
|
|
308
|
+
isDelegate: true,
|
|
309
|
+
},
|
|
310
|
+
User: {
|
|
311
|
+
baseModel: 'Base',
|
|
312
|
+
fields: {
|
|
313
|
+
id: { type: 'String' },
|
|
314
|
+
createdAt: {
|
|
315
|
+
type: 'DateTime',
|
|
316
|
+
default: expect.objectContaining({ function: 'now', kind: 'call' }),
|
|
317
|
+
originModel: 'Base',
|
|
318
|
+
},
|
|
319
|
+
updatedAt: { type: 'DateTime', updatedAt: true, originModel: 'Base' },
|
|
320
|
+
type: { type: 'String', originModel: 'Base' },
|
|
321
|
+
email: { type: 'String' },
|
|
322
|
+
},
|
|
323
|
+
uniqueFields: expect.objectContaining({
|
|
324
|
+
email: { type: 'String' },
|
|
325
|
+
}),
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
it('merges all declarations from imported modules', async () => {
|
|
332
|
+
const workDir = createTestProject();
|
|
333
|
+
fs.writeFileSync(
|
|
334
|
+
path.join(workDir, 'a.zmodel'),
|
|
335
|
+
`
|
|
336
|
+
enum Role {
|
|
337
|
+
Admin
|
|
338
|
+
User
|
|
339
|
+
}
|
|
340
|
+
`,
|
|
341
|
+
);
|
|
342
|
+
fs.writeFileSync(
|
|
343
|
+
path.join(workDir, 'b.zmodel'),
|
|
344
|
+
`
|
|
345
|
+
import './a'
|
|
346
|
+
|
|
347
|
+
datasource db {
|
|
348
|
+
provider = 'sqlite'
|
|
349
|
+
url = 'file:./test.db'
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
model User {
|
|
353
|
+
id Int @id
|
|
354
|
+
role Role
|
|
355
|
+
}
|
|
356
|
+
`,
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
const { schema } = await generateTsSchemaInPlace(path.join(workDir, 'b.zmodel'));
|
|
360
|
+
expect(schema.enums).toMatchObject({ Role: expect.any(Object) });
|
|
361
|
+
expect(schema.models).toMatchObject({ User: expect.any(Object) });
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
it('generates correct default literal function arguments', async () => {
|
|
365
|
+
const { schema } = await generateTsSchema(`
|
|
366
|
+
model User {
|
|
367
|
+
id String @id @default(uuid(7))
|
|
368
|
+
}
|
|
369
|
+
`);
|
|
370
|
+
|
|
371
|
+
expect(schema.models).toMatchObject({
|
|
372
|
+
User: {
|
|
373
|
+
name: 'User',
|
|
374
|
+
fields: {
|
|
375
|
+
id: {
|
|
376
|
+
name: 'id',
|
|
377
|
+
type: 'String',
|
|
378
|
+
id: true,
|
|
379
|
+
attributes: [
|
|
380
|
+
{
|
|
381
|
+
name: '@id',
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
name: '@default',
|
|
385
|
+
args: [
|
|
386
|
+
{
|
|
387
|
+
name: 'value',
|
|
388
|
+
value: {
|
|
389
|
+
kind: 'call',
|
|
390
|
+
function: 'uuid',
|
|
391
|
+
args: [
|
|
392
|
+
{
|
|
393
|
+
kind: 'literal',
|
|
394
|
+
value: 7,
|
|
395
|
+
},
|
|
396
|
+
],
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
],
|
|
400
|
+
},
|
|
401
|
+
],
|
|
402
|
+
default: {
|
|
403
|
+
kind: 'call',
|
|
404
|
+
function: 'uuid',
|
|
405
|
+
args: [
|
|
406
|
+
{
|
|
407
|
+
kind: 'literal',
|
|
408
|
+
value: 7,
|
|
409
|
+
},
|
|
410
|
+
],
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
idFields: ['id'],
|
|
415
|
+
uniqueFields: {
|
|
416
|
+
id: {
|
|
417
|
+
type: 'String',
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
});
|
|
422
|
+
});
|
|
184
423
|
});
|
package/tsconfig.json
CHANGED