@zenstackhq/cli 3.0.0-alpha.8 → 3.0.0-beta.1

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.
@@ -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,181 @@ 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
+ });
184
363
  });
package/tsconfig.json CHANGED
@@ -1,7 +1,4 @@
1
1
  {
2
2
  "extends": "@zenstackhq/typescript-config/base.json",
3
- "compilerOptions": {
4
- "outDir": "dist"
5
- },
6
3
  "include": ["src/**/*.ts"]
7
4
  }
package/tsup.config.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
1
3
  import { defineConfig } from 'tsup';
2
4
 
3
5
  export default defineConfig({
@@ -10,4 +12,19 @@ export default defineConfig({
10
12
  clean: true,
11
13
  dts: true,
12
14
  format: ['esm', 'cjs'],
15
+ onSuccess: async () => {
16
+ if (!process.env['TELEMETRY_TRACKING_TOKEN']) {
17
+ return;
18
+ }
19
+ const filesToProcess = ['dist/index.js', 'dist/index.cjs'];
20
+ for (const file of filesToProcess) {
21
+ console.log(`Processing ${file} for telemetry token...`);
22
+ const content = fs.readFileSync(path.join(__dirname, file), 'utf-8');
23
+ const updatedContent = content.replace(
24
+ '<TELEMETRY_TRACKING_TOKEN>',
25
+ process.env['TELEMETRY_TRACKING_TOKEN'],
26
+ );
27
+ fs.writeFileSync(file, updatedContent, 'utf-8');
28
+ }
29
+ },
13
30
  });
package/vitest.config.ts CHANGED
@@ -1,4 +1,4 @@
1
+ import base from '@zenstackhq/vitest-config/base';
1
2
  import { defineConfig, mergeConfig } from 'vitest/config';
2
- import base from '../../vitest.base.config';
3
3
 
4
4
  export default mergeConfig(base, defineConfig({}));