Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion packages/sdk/src/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export type FieldDef = {
unique?: boolean;
updatedAt?: boolean;
attributes?: AttributeApplication[];
default?: MappedBuiltinType | Expression;
default?: MappedBuiltinType | Expression | unknown[];
relation?: RelationInfo;
foreignKeyFor?: string[];
computed?: boolean;
Expand Down
53 changes: 30 additions & 23 deletions packages/sdk/src/ts-schema-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,7 @@ export class TsSchemaGenerator {
}

private createDataModelFieldObject(field: DataModelField) {
const objectFields = [
ts.factory.createPropertyAssignment(
'type',
ts.factory.createStringLiteral(field.type.type ?? field.type.reference!.$refText),
),
];
const objectFields = [ts.factory.createPropertyAssignment('type', this.generateFieldTypeLiteral(field))];

if (isIdField(field)) {
objectFields.push(ts.factory.createPropertyAssignment('id', ts.factory.createTrue()));
Expand Down Expand Up @@ -325,7 +320,7 @@ export class TsSchemaGenerator {

const defaultValue = this.getMappedDefault(field);
if (defaultValue !== undefined) {
if (typeof defaultValue === 'object') {
if (typeof defaultValue === 'object' && !Array.isArray(defaultValue)) {
if ('call' in defaultValue) {
objectFields.push(
ts.factory.createPropertyAssignment(
Expand Down Expand Up @@ -371,18 +366,20 @@ export class TsSchemaGenerator {
throw new Error(`Unsupported default value type for field ${field.name}`);
}
} else {
objectFields.push(
ts.factory.createPropertyAssignment(
'default',
typeof defaultValue === 'string'
? ts.factory.createStringLiteral(defaultValue)
: typeof defaultValue === 'number'
? ts.factory.createNumericLiteral(defaultValue)
: defaultValue === true
? ts.factory.createTrue()
: ts.factory.createFalse(),
),
);
if (Array.isArray(defaultValue)) {
objectFields.push(
ts.factory.createPropertyAssignment(
'default',
ts.factory.createArrayLiteralExpression(
defaultValue.map((item) => this.createLiteralNode(item as any)),
),
),
);
} else {
objectFields.push(
ts.factory.createPropertyAssignment('default', this.createLiteralNode(defaultValue)),
);
}
}
}

Expand Down Expand Up @@ -440,7 +437,7 @@ export class TsSchemaGenerator {

private getMappedDefault(
field: DataModelField,
): string | number | boolean | { call: string; args: any[] } | { authMember: string[] } | undefined {
): string | number | boolean | unknown[] | { call: string; args: any[] } | { authMember: string[] } | undefined {
const defaultAttr = getAttribute(field, '@default');
if (!defaultAttr) {
return undefined;
Expand All @@ -456,6 +453,8 @@ export class TsSchemaGenerator {
: ['Int', 'Float', 'Decimal', 'BigInt'].includes(field.type.type!)
? Number(lit)
: lit;
} else if (isArrayExpr(defaultValue)) {
return defaultValue.items.map((item) => this.getLiteral(item));
} else if (isReferenceExpr(defaultValue) && isEnumField(defaultValue.target.ref)) {
return defaultValue.target.ref.name;
} else if (isInvocationExpr(defaultValue)) {
Expand Down Expand Up @@ -681,9 +680,17 @@ export class TsSchemaGenerator {
return ts.factory.createObjectLiteralExpression(properties, true);
}

private generateFieldTypeLiteral(field: DataModelField): ts.Expression {
invariant(field.type.type || field.type.reference, 'Field type must be a primitive or reference');
return ts.factory.createStringLiteral(field.type.type ?? field.type.reference!.$refText);
private generateFieldTypeLiteral(field: DataModelField | ProcedureParam): ts.Expression {
invariant(
field.type.type || field.type.reference || field.type.unsupported,
'Field type must be a primitive, reference, or Unsupported',
);

return field.type.type
? ts.factory.createStringLiteral(field.type.type)
: field.type.reference
? ts.factory.createStringLiteral(field.type.reference.$refText)
: ts.factory.createStringLiteral('unknown');
}

private createEnumObject(e: Enum) {
Expand Down
11 changes: 4 additions & 7 deletions tests/e2e/cal.com/cal-com.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { generateTsSchema } from '@zenstackhq/testtools';
import { describe, it } from 'vitest';
import { describe, expect, it } from 'vitest';
import fs from 'node:fs';
import path from 'node:path';

describe('Cal.com e2e tests', () => {
it('has a working schema', async () => {
const generated = await generateTsSchema(
fs.readFileSync(path.join(__dirname, 'schema.zmodel'), 'utf8'),
'postgresql',
'cal-com',
);
console.log(generated);
await expect(
generateTsSchema(fs.readFileSync(path.join(__dirname, 'schema.zmodel'), 'utf8'), 'postgresql', 'cal-com'),
).resolves.toBeTruthy();
});
});
12 changes: 12 additions & 0 deletions tests/e2e/formbricks/formbricks.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { generateTsSchema } from '@zenstackhq/testtools';
import { describe, expect, it } from 'vitest';
import fs from 'node:fs';
import path from 'node:path';

describe('Formbricks e2e tests', () => {
it('has a working schema', async () => {
await expect(
generateTsSchema(fs.readFileSync(path.join(__dirname, 'schema.zmodel'), 'utf8'), 'postgresql', 'cal-com'),
).resolves.toBeTruthy();
});
});
Loading
Loading