Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(json): support recursive definitions #1865

Merged
merged 1 commit into from
Nov 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/sdk/src/code-gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export function createProject(options?: CompilerOptions) {
strict: true,
skipLibCheck: true,
noEmitOnError: true,
noImplicitAny: false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Reconsider disabling noImplicitAny as it reduces type safety

Setting noImplicitAny: false is a significant change that weakens TypeScript's type checking. While this may fix the recursive JSON type issue, it could:

  1. Allow untyped code to pass compilation
  2. Hide potential type errors
  3. Reduce code maintainability and type safety across the codebase

Consider keeping noImplicitAny: true and instead handle recursive types explicitly:

-            noImplicitAny: false,

Committable suggestion skipped: line range outside the PR's diff.

...options,
},
});
Expand Down
45 changes: 45 additions & 0 deletions tests/integration/tests/enhancements/json/crud.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,49 @@ describe('Json field CRUD', () => {
expect(u2.profile.ownerId).toBe(2);
expect(u2.profile.nested.userId).toBe(3);
});

it('works with recursive types', async () => {
const params = await loadSchema(
`
type Content {
type String
content Content[]?
text String?
}

model Post {
id Int @id @default(autoincrement())
content Content @json
@@allow('all', true)
}
`,
{
provider: 'postgresql',
dbUrl,
}
);

prisma = params.prisma;
const db = params.enhance();
const post = await db.post.create({
data: {
content: {
type: 'text',
content: [
{
type: 'text',
content: [
{
type: 'text',
text: 'hello',
},
],
},
],
},
},
});

await expect(post.content.content[0].content[0].text).toBe('hello');
});
});
53 changes: 53 additions & 0 deletions tests/integration/tests/enhancements/json/typing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,59 @@ async function main() {
dateTime: new Date(),
json: { a: 1 },
}
}
`,
},
],
}
);
});

it('supports recursive definition', async () => {
await loadSchema(
`
type Content {
type String
content Content[]?
text String?
}

model Post {
id Int @id @default(autoincrement())
content Content @json
}
`,
{
provider: 'postgresql',
pushDb: false,
compile: true,
extraSourceFiles: [
{
name: 'main.ts',
content: `
import type { Content } from '.zenstack/models';
import { enhance } from '.zenstack/enhance';
import { PrismaClient } from '@prisma/client';

async function main() {
const content: Content = {
type: 'text',
content: [
{
type: 'text',
content: [
{
type: 'text',
text: 'hello',
},
],
},
],
}

const db = enhance(new PrismaClient());
const post = await db.post.create({ data: { content } });
console.log(post.content.content?.[0].content?.[0].text);
}
`,
},
Expand Down
Loading