Skip to content

Commit

Permalink
✨ feat: better optional handling
Browse files Browse the repository at this point in the history
  • Loading branch information
m1212e committed Mar 25, 2024
1 parent 09022f9 commit 7acb6f3
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 20 deletions.
13 changes: 9 additions & 4 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ generator client {
}

generator prismabox {
provider = "node ./dist/cli.js"
provider = "node ./dist/cli.js"
dataModel = true
}

Expand All @@ -33,11 +33,16 @@ model User {
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
User User? @relation(fields: [userId], references: [id])
User User? @relation(fields: [userId], references: [id])
/// @prismabox.options{max: 10}
/// this is the user id
userId Int?
status Status
userId Int?
status Status
status2 Status?
blah String
blah2 String?
successorId Int? @unique
successor Post? @relation("history", fields: [successorId], references: [id])
Expand Down
34 changes: 30 additions & 4 deletions src/generator/dataModel.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import type { DMMF } from "@prisma/generator-helper";
import { typeboxImportVariableName } from "./typeboxImport";
import { Annotation, parseDocumentation } from "./documentation";
import { PrimitiveField, isPrimitivePrismaFieldType } from "./plainModel";
import {
NullableVariant,
PrimitiveField,
isPrimitivePrismaFieldType,
} from "./plainModel";
import type { Models } from "../util/modelMap";
import { RelationField } from "./relationModel";

Expand All @@ -11,9 +15,23 @@ export function enableDataModel() {
}

export function DataModel(
data: Pick<DMMF.Model, "fields" | "documentation">,
referenceableEnums: Models
) {
return internal(data, referenceableEnums, false);
}

export function DataModelOptional(
data: Pick<DMMF.Model, "fields" | "documentation">,
referenceableEnums: Models
) {
return internal(data, referenceableEnums, true);
}

function internal(
data: Pick<DMMF.Model, "fields" | "documentation">,
referenceableEnums: Models,
optional = false
optional: boolean
) {
if (!enabled) return undefined;
const modelDoc = parseDocumentation(data.documentation);
Expand Down Expand Up @@ -43,7 +61,11 @@ export function DataModel(
fieldType: field.type,
list: field.isList,
name: field.name,
optional,
optional: field.isRequired
? optional
? NullableVariant.OPTIONAL
: NullableVariant.REQUIRED
: NullableVariant.NULLABLE,
options: doc.options,
referenceableModels: referenceableEnums,
});
Expand Down Expand Up @@ -77,7 +99,11 @@ export function DataModel(
fieldType: field.type as any, // we checked earlier if it's a primitive type
list: field.isList,
name: field.name,
optional,
optional: field.isRequired
? optional
? NullableVariant.OPTIONAL
: NullableVariant.REQUIRED
: NullableVariant.NULLABLE,
options: parseDocumentation(field.documentation).options,
});
})
Expand Down
23 changes: 18 additions & 5 deletions src/generator/plainModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ import type { DMMF } from "@prisma/generator-helper";
import { typeboxImportVariableName } from "./typeboxImport";
import { Annotation, parseDocumentation } from "./documentation";

export enum NullableVariant {
NULLABLE = 0, // null, undefined or the value
OPTIONAL = 1, // undefined or the value
REQUIRED = 2, // the value
}

export function PlainModel(data: Pick<DMMF.Model, "fields" | "documentation">) {
const modelDoc = parseDocumentation(data.documentation);

if (modelDoc.annotations.includes(Annotation.HIDDEN)) return undefined;

const fields = data.fields
Expand All @@ -17,7 +23,9 @@ export function PlainModel(data: Pick<DMMF.Model, "fields" | "documentation">) {
name: field.name,
fieldType: field.type,
list: field.isList,
optional: !field.isRequired,
optional: field.isRequired
? NullableVariant.REQUIRED
: NullableVariant.NULLABLE,
options: doc.options,
});
})
Expand Down Expand Up @@ -63,13 +71,15 @@ export function PrimitiveField({
fieldType: PrimitivePrismaFieldType;
options: string;
name: string;
optional: boolean;
optional: NullableVariant;
list: boolean;
}) {
let ret = `${name}: `;

if (optional) {
if (optional === NullableVariant.NULLABLE) {
ret += "Nullable(";
} else if (optional === NullableVariant.OPTIONAL) {
ret += `${typeboxImportVariableName}.Optional(`;
}

if (list) {
Expand All @@ -90,7 +100,10 @@ export function PrimitiveField({
ret += `${typeboxImportVariableName}.Boolean(${options})`;
} else throw new Error("Invalid type for primitive generation");

if (optional) {
if (
optional === NullableVariant.NULLABLE ||
optional === NullableVariant.OPTIONAL
) {
ret += ")";
}

Expand Down
17 changes: 12 additions & 5 deletions src/generator/relationModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { DMMF } from "@prisma/generator-helper";
import { typeboxImportVariableName } from "./typeboxImport";
import { Annotation, parseDocumentation } from "./documentation";
import type { Models } from "../util/modelMap";
import { isPrimitivePrismaFieldType } from "./plainModel";
import { NullableVariant, isPrimitivePrismaFieldType } from "./plainModel";

export function RelationModel(
data: Pick<DMMF.Model, "fields" | "documentation">,
Expand All @@ -21,7 +21,9 @@ export function RelationModel(
name: field.name,
fieldType: field.type,
list: field.isList,
optional: !field.isRequired,
optional: field.isRequired
? NullableVariant.REQUIRED
: NullableVariant.NULLABLE,
options: doc.options,
referenceableModels,
});
Expand All @@ -42,7 +44,7 @@ export function RelationField({
fieldType: string;
options: string;
name: string;
optional: boolean;
optional: NullableVariant;
list: boolean;
referenceableModels: Models;
}) {
Expand All @@ -54,8 +56,10 @@ export function RelationField({

let ret = `${name}: `;

if (optional) {
if (optional === NullableVariant.NULLABLE) {
ret += "Nullable(";
} else if (optional === NullableVariant.OPTIONAL) {
ret += `${typeboxImportVariableName}.Optional(`;
}

if (list) {
Expand All @@ -71,7 +75,10 @@ export function RelationField({
}
ret += referencedFieldModel;

if (optional) {
if (
optional === NullableVariant.NULLABLE ||
optional === NullableVariant.OPTIONAL
) {
ret += ")";
}

Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { setAdditionalProperties } from "./generator/documentation";
import { Composite } from "./generator/composite";
import { WhereModel } from "./generator/whereModel";
import { Nullable } from "./generator/nullable";
import { DataModel, enableDataModel } from "./generator/dataModel";
import { DataModel, DataModelOptional, enableDataModel } from "./generator/dataModel";

generatorHandler({
onManifest() {
Expand Down Expand Up @@ -113,7 +113,7 @@ generatorHandler({

optionalDataTasks.push(
...options.dmmf.datamodel.models.map(async (e) => {
const model = DataModel(e, enumTypes, true);
const model = DataModelOptional(e, enumTypes);
if (model) {
optionalDataTypes.set(e.name, model);
}
Expand Down

0 comments on commit 7acb6f3

Please sign in to comment.