diff --git a/docker-compose.yml b/docker-compose.yml index 7308096..87fee77 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,31 +11,31 @@ services: POSTGRES_PASSWORD: ${DATABASE_PASSWORD} POSTGRES_DB: ${DATABASE_NAME} - minio: - image: minio/minio - ports: - - "9000:9000" - - "9001:9001" - volumes: - - minio-data:/data - environment: - MINIO_ROOT_USER: ${MINIO_USERNAME} - MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD} - command: server --console-address ":9001" /data + # minio: + # image: minio/minio + # ports: + # - "9000:9000" + # - "9001:9001" + # volumes: + # - minio-data:/data + # environment: + # MINIO_ROOT_USER: ${MINIO_USERNAME} + # MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD} + # command: server --console-address ":9001" /data - createbuckets: - image: minio/mc - depends_on: - - minio - entrypoint: > - /bin/sh -c " - /usr/bin/mc config host add myminio http://minio:9000 ${MINIO_USERNAME} ${MINIO_PASSWORD}; - /usr/bin/mc rm -r --force myminio/${MINIO_BUCKETNAME}; - /usr/bin/mc mb myminio/${MINIO_BUCKETNAME}; - /usr/bin/mc anonymous set public myminio/${MINIO_BUCKETNAME}; - exit 0; - " + # createbuckets: + # image: minio/mc + # depends_on: + # - minio + # entrypoint: > + # /bin/sh -c " + # /usr/bin/mc config host add myminio http://minio:9000 ${MINIO_USERNAME} ${MINIO_PASSWORD}; + # /usr/bin/mc rm -r --force myminio/${MINIO_BUCKETNAME}; + # /usr/bin/mc mb myminio/${MINIO_BUCKETNAME}; + # /usr/bin/mc anonymous set public myminio/${MINIO_BUCKETNAME}; + # exit 0; + # " volumes: dataset-db: - minio-data: \ No newline at end of file + # minio-data: \ No newline at end of file diff --git a/docs/schema.md b/docs/schema.md index 2e46673..67e01cd 100644 --- a/docs/schema.md +++ b/docs/schema.md @@ -11,13 +11,13 @@ Schema: type: string description: string maxLength?: number | null - nullable: boolean - unique: boolean + isNullable: boolean + isUnique: boolean default?: string | null - autoincrement?: boolean - uuid?: boolean + isAutoIncrement?: boolean + isUuid?: boolean isId?: boolean - vectorEmbed?: boolean + isVectorEmbed?: boolean embeddingAlgo?: string isForeignKey?: boolean isList?: boolean diff --git a/src/checks.ts b/src/checks.ts index 3a2a276..69061f0 100644 --- a/src/checks.ts +++ b/src/checks.ts @@ -24,6 +24,7 @@ export function checkJSON( failOnWarn = false ): Schema { const newModelObjects = []; + const models = jsonData.schema.map((model) => { if (!existingData.models.includes(model.schemaName)) { newModelObjects.push(model); @@ -89,9 +90,22 @@ function sanitizeJSONSchema( for (const model of jsonData.schema) { model.schemaName = fixDashesAndSpaces(model.schemaName); let isPrimaryPresent = false; + let isUnqiueAndNullable = false; + let isUniqueAndNotNullable = false; + const uniqueWithNullables = []; + for (const field of model.fields) { field.fieldName = fixDashesAndSpaces(field.fieldName); - isPrimaryPresent = isPrimaryPresent || field.isId || field.unique; + isPrimaryPresent = isPrimaryPresent || field.isId; + + if (field.isNullable && field.isUnique) { + isUnqiueAndNullable = true; + uniqueWithNullables.push(field.fieldName); + } else if (!field.isNullable && field.isUnique) { + isUniqueAndNotNullable = true; + isPrimaryPresent = true; + } + checkIllegalCombinationOfFieldAttributes( field, definedTypes, @@ -101,7 +115,7 @@ function sanitizeJSONSchema( if (!isPrimaryPresent) { console.warn( - `Model ${model.schemaName} does not have a primary key, adding a default 'dummy_id_' field with "unique" constraint` + `Model ${model.schemaName} does not have a primary key or a non optional/nullable unique field adding a default 'dummy_id' field with "unique" constraint` ); if (failOnWarn) process.exit(1); else { diff --git a/src/commands.ts b/src/commands.ts index 0a4da70..9a089d0 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -23,7 +23,7 @@ function runCommand(command, args) { }); } -export function runDBPull() { +export function runPrismaDBPull() { exec("npx prisma db pull", (error, stdout, stderr) => { if (error) { console.error('Error executing "npx prisma db pull"', error); @@ -45,9 +45,96 @@ export function runDBPull() { }); } +export function runPrismaFormat() { + return runCommand("npx", ["prisma", "format"]) + .then(() => { + console.log("Prisma schema has been formatted successfully."); + return { + status: true, + message: "Prisma schema has been formatted successfully.", + }; + }) + .catch((error) => { + console.error("An error occurred:", error); + throw new Error( + JSON.stringify({ + error: true, + message: `Error formatting Prisma schema: ${error}`, + }) + ); + }); +} + +export function runPrismaValidate() { + return runCommand("npx", ["prisma", "validate"]) + .then(() => { + console.log("Prisma schema is valid."); + return { + status: true, + message: "Prisma schema is valid.", + }; + }) + .catch((error) => { + console.error("An error occurred:", error); + throw new Error( + JSON.stringify({ + error: true, + message: `Error validating Prisma schema: ${error}`, + }) + ); + }); +} + +export function createMigrations(migrateModels) { + return runCommand("npx", [ + "prisma", + "migrate", + "dev", + "--name", + `${Date.now()}_dynamo_prisma_` + migrateModels.join("_"), + "--create-only", + ]) + .then(() => { + console.log("Migrations have been generated successfully."); + return { + status: true, + message: "Migrations have been generated successfully.", + }; + }) + .catch((error) => { + console.error("An error occurred:", error); + throw new Error( + JSON.stringify({ + error: true, + message: `Error applying migrations: ${error}`, + }) + ); + }); +} + +export function applyMigrations() { + return runCommand("npx", ["prisma", "migrate", "deploy"]) + .then(() => { + console.log("Migrations have been successfully deployed."); + return { + status: true, + message: "Migrations have been successfully deployed.", + }; + }) + .catch((error) => { + console.error("An error occurred:", error); + throw new Error( + JSON.stringify({ + error: true, + message: `Error applying migrations: ${error}`, + }) + ); + }); +} + export function validateAndMigrate(migrateModels: string[]) { console.log("migrateModels: ", migrateModels); - runCommand("npx", ["prisma", "validate"]) + return runCommand("npx", ["prisma", "validate"]) .then(() => { console.log("Prisma schema is valid."); @@ -66,6 +153,10 @@ export function validateAndMigrate(migrateModels: string[]) { }) .then(() => { console.log("Migrations have been successfully deployed."); + return { + status: true, + message: "migrations applied and generated successfully", + }; }) .catch((error) => { console.error("An error occurred:", error); @@ -76,9 +167,4 @@ export function validateAndMigrate(migrateModels: string[]) { }) ); }); - - return { - status: true, - message: "migrations applied and generated successfully", - }; } diff --git a/src/dsl-helper.ts b/src/dsl-helper.ts index 3149086..e8044fb 100644 --- a/src/dsl-helper.ts +++ b/src/dsl-helper.ts @@ -46,13 +46,13 @@ export function createFields(fields: Field[]): any[] { fieldData.fieldName, fieldData.type as ScalarType, fieldData.isList || undefined, //isList boolean | undefined - !fieldData.nullable || false, //isRequired boolean | undefined - fieldData.isId ? fieldData.isId : fieldData.unique || false, + !fieldData.isNullable || false, //isRequired boolean | undefined + fieldData.isId ? fieldData.isId : fieldData.isUnique || false, fieldData.isId || false, undefined, // isUpdatedAt - fieldData.isId && fieldData.autoincrement + fieldData.isId && fieldData.isAutoIncrement ? { callee: AUTO_INCREMENT } - : fieldData.isId && fieldData.uuid + : fieldData.isId && fieldData.isUuid ? { callee: UUID } : fieldData.default || undefined, // default values SaclarFeildDefault | undefined undefined, // documentation string | undefined @@ -61,7 +61,7 @@ export function createFields(fields: Field[]): any[] { ) ); - if (fieldData.vectorEmbed) { + if (fieldData.isVectorEmbed) { if ( Object.keys(EMBEDDING_ALGO_SIZE).includes(fieldData.embeddingAlgo) === false @@ -89,7 +89,7 @@ export function createFields(fields: Field[]): any[] { `${fieldData.fieldName}Embedding`, `Unsupported("vector(${ EMBEDDING_ALGO_SIZE[fieldData.embeddingAlgo] - })")` as ScalarType, + })")?` as ScalarType, false, true, false, diff --git a/src/schemaGenerator.ts b/src/schemaGenerator.ts index 523424c..82793c6 100644 --- a/src/schemaGenerator.ts +++ b/src/schemaGenerator.ts @@ -6,7 +6,11 @@ import { createModels } from "./dsl-helper"; import { checkJSON } from "./checks"; import { createSchema, print } from "prisma-schema-dsl"; import { Schema } from "./types/dynamoPrisma.types"; -import { parseExistingEnums, parsePrismaSchemaModels } from "./utils/utils"; +import { + formatValidateAndWrite, + parseExistingEnums, + parsePrismaSchemaModels, +} from "./utils/utils"; import { validateAndMigrate } from "./commands"; export async function generateIfNoSchema( @@ -46,7 +50,8 @@ export async function generateIfNoSchema( fs.mkdirSync(prismaFilePath.split("/schema.prisma")[0], { recursive: true, }); - fs.writeFileSync(prismaFilePath, result); + // fs.writeFileSync(prismaFilePath, result); + await formatValidateAndWrite(result, prismaFilePath); console.log("🚀 Prisma schema generated successfully!"); migrateModels.push(...jsonData.schema.map((model) => model.schemaName)); } catch (err) { @@ -74,7 +79,8 @@ export async function generateSchemaWhenFilePresent( const migrateModels: string[] = []; try { - fs.appendFileSync(prismaFilePath, "\n\n" + schemaString, "utf8"); + // fs.appendFileSync(prismaFilePath, "\n\n" + schemaString, "utf8"); + await formatValidateAndWrite(schemaString, prismaFilePath); console.log("🚀 Prisma schema generated successfully!"); migrateModels.push(...jsonData.schema.map((model) => model.schemaName)); } catch (err) { diff --git a/src/types/dynamoPrisma.types.ts b/src/types/dynamoPrisma.types.ts index ec7d605..5bb3b81 100644 --- a/src/types/dynamoPrisma.types.ts +++ b/src/types/dynamoPrisma.types.ts @@ -9,13 +9,13 @@ export interface Field { type: string; description: string; maxLength?: number | null; - nullable: boolean; - unique: boolean; + isNullable: boolean; + isUnique: boolean; default?: string | null; - autoincrement?: boolean; - uuid?: boolean; + isAutoIncrement?: boolean; + isUuid?: boolean; isId?: boolean; - vectorEmbed?: boolean; + isVectorEmbed?: boolean; embeddingAlgo?: string; isForeignKey?: boolean; isList?: boolean; diff --git a/src/utils/utils.ts b/src/utils/utils.ts index c483ca5..a2b0f23 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -6,6 +6,7 @@ import { UUID_LEGAL_TYPES, } from "./constants"; import { Field, Schema } from "../types/dynamoPrisma.types"; +import { runPrismaFormat, runPrismaValidate } from "../commands"; export function fixDashesAndSpaces(str: string): string { let modified = str; let hasDashes = str.includes("-"); @@ -35,32 +36,59 @@ export function generateDummyID() { description: "Dummy ID of the user", maxLength: null, default: null, - nullable: false, - unique: true, + isNullable: false, + isUnique: true, isId: true, - uuid: true, + isUuid: true, }; } +export function matchAndFixFieldTypeCasing( + field: Field, + definedTypes: string[] +) { + const fieldType = field.type.toLowerCase(); + let isPresent = false; + for (const definedType of definedTypes) { + if (definedType.toLowerCase() === fieldType) { + isPresent = true; + field.type = definedType; + break; + } + } + + if (!isPresent) { + throw new Error( + JSON.stringify({ + error: true, + message: `Field type ${field.type} is not supported`, + }) + ); + } +} + export function checkIllegalCombinationOfFieldAttributes( field: Field, definedTypes: string[], schemaName: string ) { - // make sure the field is of a supported type - if (!definedTypes.includes(field.type)) { + matchAndFixFieldTypeCasing(field, definedTypes); + // make sure that the field is not both id and nullable + if (field.isNullable && (field.isId || field.isForeignKey)) { throw new Error( JSON.stringify({ error: true, - message: `${field.fieldName} in model ${schemaName} is of type ${ - field.type - } which is not included in the following types ${definedTypes.toString()}`, + message: `${ + field.fieldName + } in model ${schemaName} cannot be both nullable and ${ + field.isId ? "id" : "foreign key" + }`, }) ); } // make sure that the field is not both autoincrement and uuid - if (field.autoincrement && field.uuid) { + if (field.isAutoIncrement && field.isUuid) { throw new Error( JSON.stringify({ error: true, @@ -70,7 +98,10 @@ export function checkIllegalCombinationOfFieldAttributes( } // make sure if a field is autoincrement then it is of a legal type that supports autoincrement - if (field.autoincrement && !AUTO_INCREMENT_LEGAL_TYPES.includes(field.type)) { + if ( + field.isAutoIncrement && + !AUTO_INCREMENT_LEGAL_TYPES.includes(field.type) + ) { throw new Error( JSON.stringify({ error: true, @@ -82,7 +113,7 @@ export function checkIllegalCombinationOfFieldAttributes( } // make sure if a field is uuid then it is of a legal type that supports uuid - if (field.uuid && !UUID_LEGAL_TYPES.includes(field.type)) { + if (field.isUuid && !UUID_LEGAL_TYPES.includes(field.type)) { throw new Error( JSON.stringify({ error: true, @@ -117,7 +148,6 @@ export function parseExistingEnums(fileContent: string) { enums.push(enumName); } - console.log("Enums:", enums); return enums; } @@ -127,3 +157,53 @@ export function readJsonFile(filePath: string): Schema { } return JSON.parse(fs.readFileSync(filePath, "utf8")) as unknown as Schema; } + +/** + * @description Formats and validates the generated prisma schema and updates/creates the schema.prisma file accordiongly + */ +export async function formatValidateAndWrite( + schemaString: string, + filePath: string +) { + // 1. save the current schema.prisma as schema.prisma.bak + // 2. save the new schema as schema.prisma + // 3. run prismaformat + // 4. run prisma validate + // 5. if validate fails, then delete schema.prisma and rename schema.prisma.bak as schema.prisma + // if validate passes, then delete schema.prisma.bak + + let fileExists = false; + let originalPrismaContent = ""; + if (fs.existsSync(filePath)) { + fileExists = true; + originalPrismaContent = fs.readFileSync(filePath, "utf8"); + fs.renameSync(filePath, filePath + ".bak"); + } + + fs.writeFileSync( + filePath, + originalPrismaContent + "\n" + schemaString, + "utf8" + ); + + try { + await runPrismaFormat(); + await runPrismaValidate(); + // delete the backup + // TODO: Add error handling with custom error codes on file operations so that the user can perform a manual cleanup and the entire process does not fail + if (fs.existsSync(filePath + ".bak")) fs.unlinkSync(filePath + ".bak"); + } catch (err) { + console.log("Error while running prisma format and validate: ", err); + if (fileExists) { + fs.unlinkSync(filePath); + fs.renameSync(filePath + ".bak", filePath); + } + throw new Error( + JSON.stringify({ + error: true, + message: + "Previous schema unchanged, the package is not able to generate a valid schema.prisma file for the said input, please check your schema for any errors and report the issue to pacakge maintainers by opening an issue on github with the relevant input", + }) + ); + } +} diff --git a/test/cli.ts b/test/cli.ts index f4355c5..2a0b83d 100644 --- a/test/cli.ts +++ b/test/cli.ts @@ -4,7 +4,11 @@ */ import { generatePrismaSchemaFile } from "../src/schemaGenerator"; import { readJsonFile } from "../src/utils/utils"; -import { validateAndMigrate } from "../src/commands"; +import { + applyMigrations, + createMigrations, + validateAndMigrate, +} from "../src/commands"; export async function main(argv: string[]) { console.warn(argv); @@ -17,8 +21,8 @@ export async function main(argv: string[]) { const data = readJsonFile(filePath); const migrateModels: any = await generatePrismaSchemaFile(data); console.log("migration models: ", migrateModels); - validateAndMigrate(migrateModels); - + await createMigrations(migrateModels); + await applyMigrations(); return filePath; } diff --git a/test/schema-generation.spec.ts b/test/schema-generation.spec.ts index 37fcad8..f121b92 100644 --- a/test/schema-generation.spec.ts +++ b/test/schema-generation.spec.ts @@ -26,15 +26,47 @@ describe("tests for schema generation", () => { "utf8" ); expect(schemaPrismaContent).toBeDefined(); - console.log("schemaPrismaContent: ", schemaPrismaContent); const models = parsePrismaSchemaModels(schemaPrismaContent); - console.log("models: ", models); expect(models).toContain("User"); expect(models).toContain("Post"); expect(models).toContain("Comment"); }); }); + it("should generate a schema.prisma with dummy_id for a schema with no id and only unique field being optional", async () => { + const fileContent = readJsonFile("./test/schemas/optional_unique.json"); + await generatePrismaSchemaFile(fileContent).then((migrationModels) => { + expect(migrationModels).toBeDefined(); + expect(fs.existsSync("./prisma/schema.prisma")).toBe(true); + const schemaPrismaContent = fs.readFileSync( + "./prisma/schema.prisma", + "utf8" + ); + expect(schemaPrismaContent).toBeDefined(); + const models = parsePrismaSchemaModels(schemaPrismaContent); + expect(models).toContain("User"); + expect(models).toContain("Post"); + expect(models).toContain("Comment"); + }); + }); + + it("should generate a schema.prisma for a basic file with different casing for types ", async () => { + const fileContent = readJsonFile("./test/schemas/casing.json"); + await generatePrismaSchemaFile(fileContent).then((migrationModels) => { + expect(migrationModels).toBeDefined(); + expect(fs.existsSync("./prisma/schema.prisma")).toBe(true); + const schemaPrismaContent = fs.readFileSync( + "./prisma/schema.prisma", + "utf8" + ); + expect(schemaPrismaContent).toBeDefined(); + const models = parsePrismaSchemaModels(schemaPrismaContent); + expect(models).toContain("uSer"); + expect(models).toContain("Post"); + expect(models).toContain("Comment"); + }); + }); + it("should generate a schema.prisma for a file with dashes in schema and field name", async () => { const fileContent = readJsonFile("./test/schemas/dash_name.json"); const migrationModels = await generatePrismaSchemaFile(fileContent); @@ -45,9 +77,7 @@ describe("tests for schema generation", () => { "utf8" ); expect(schemaPrismaContent).toBeDefined(); - console.log("schemaPrismaContent: ", schemaPrismaContent); const models = parsePrismaSchemaModels(schemaPrismaContent); - console.log("models: ", models); expect(models).toContain("dash_name"); }); @@ -61,9 +91,7 @@ describe("tests for schema generation", () => { "utf8" ); expect(schemaPrismaContent).toBeDefined(); - console.log("schemaPrismaContent: ", schemaPrismaContent); const models = parsePrismaSchemaModels(schemaPrismaContent); - console.log("models: ", models); expect(models).toContain("no_unique"); }); }); @@ -78,9 +106,7 @@ describe("tests for schema generation", () => { "utf8" ); expect(schemaPrismaContent).toBeDefined(); - console.log("schemaPrismaContent: ", schemaPrismaContent); const models = parsePrismaSchemaModels(schemaPrismaContent); - console.log("models: ", models); expect(models).toContain("white_space_name"); }); }); @@ -95,9 +121,7 @@ describe("tests for schema generation", () => { "utf8" ); expect(schemaPrismaContent).toBeDefined(); - console.log("schemaPrismaContent: ", schemaPrismaContent); const models = parsePrismaSchemaModels(schemaPrismaContent); - console.log("models: ", models); expect(models).toContain("vector_embedding"); const pattern = /@default\("text-embedding-ada-002"\)/; expect(pattern.test(schemaPrismaContent)).toBe(true); @@ -114,12 +138,9 @@ describe("tests for schema generation", () => { "utf8" ); expect(schemaPrismaContent).toBeDefined(); - console.log("schemaPrismaContent: ", schemaPrismaContent); const models = parsePrismaSchemaModels(schemaPrismaContent); - console.log("models: ", models); expect(models).toContain("User"); const enums = parseExistingEnums(schemaPrismaContent); - console.log("enums: ", enums); expect(enums).toBeDefined(); expect(enums.length).toBeGreaterThan(0); expect(enums).toContain("UserType"); diff --git a/test/schemas/casing.json b/test/schemas/casing.json new file mode 100644 index 0000000..6bc5757 --- /dev/null +++ b/test/schemas/casing.json @@ -0,0 +1,182 @@ +{ + "schema": [ + { + "schemaName": "uSer", + "fields": [ + { + "fieldName": "id", + "type": "String", + "description": "ID of the user", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": false, + "isId": true, + "isUuid": true + }, + { + "fieldName": "username", + "type": "String", + "description": "Username of the user", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": true, + "isUuid": true + }, + { + "fieldName": "email", + "type": "String", + "description": "Email of the user", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": true, + "isUuid": true + }, + { + "fieldName": "type", + "type": "String", + "description": "Type of the user", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": false, + "isUuid": true + }, + { + "fieldName": "password", + "type": "STRING", + "description": "Password of the user", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": false, + "isUuid": true + }, + { + "fieldName": "posts", + "type": "Post", + "description": "Posts authored by the user", + "maxLength": null, + "default": null, + "isNullable": true, + "isUnique": false + } + ], + "description": "User model" + }, + { + "schemaName": "Post", + "fields": [ + { + "fieldName": "id", + "type": "Int", + "description": "ID of the post", + "maxLength": null, + "isNullable": false, + "isId": true, + "isUnique": true, + "autoincrement": true + }, + { + "fieldName": "title", + "type": "String", + "description": "Title of the post", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": false + }, + { + "fieldName": "content", + "type": "String", + "description": "Content of the post", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": false + }, + { + "fieldName": "author", + "type": "String", + "description": "Author of the post", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": false + }, + { + "fieldName": "comments", + "type": "Comment", + "description": "Comments associated with the post", + "maxLength": null, + "default": null, + "isNullable": true, + "isUnique": false + } + ], + "description": "Post model" + }, + { + "schemaName": "Comment", + "fields": [ + { + "fieldName": "id", + "type": "String", + "description": "ID of the comment", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": false, + "isId": true + }, + { + "fieldName": "content", + "type": "String", + "description": "Content of the comment", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": false + }, + { + "fieldName": "author", + "type": "User", + "description": "Author of the comment", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": false + }, + { + "fieldName": "post", + "type": "String", + "description": "Post associated with the comment", + "maxLength": null, + "default": null, + "isNullable": false, + "isUnique": false, + "isForeignKey": true, + "vectorEmbed": true, + "embeddingAlgo": "text-embedding-3-large" + } + ], + "description": "Comment model" + } + ], + + "dataSource": { + "name": "db", + "provider": "postgresql", + "url": { + "fromEnv": "DATABASE_URL" + }, + "extensions": ["vector", "pg_trgm"] + }, + "generator": { + "provider": "prisma-client-js", + "generatorName": "client", + "previewFeatures": ["postgresqlExtensions", "views"] + } +} diff --git a/test/schemas/dash_name.json b/test/schemas/dash_name.json index 6077e21..ef5ba7e 100644 --- a/test/schemas/dash_name.json +++ b/test/schemas/dash_name.json @@ -8,9 +8,9 @@ "type": "String", "description": "", "maxLength": "", - "nullable": false, - "unique": false, - "vectorEmbed": false + "isNullable": false, + "isUnique": false, + "isVectorEmbed": false } ], "description": "Schema for seed treating materials data with details of each order" diff --git a/test/schemas/demo.json b/test/schemas/demo.json index 22187ef..b6af43c 100644 --- a/test/schemas/demo.json +++ b/test/schemas/demo.json @@ -9,10 +9,10 @@ "description": "ID of the user", "maxLength": null, "default": null, - "nullable": false, - "unique": false, + "isNullable": false, + "isUnique": false, "isId": true, - "uuid": true + "isUuid": true }, { "fieldName": "username", @@ -20,8 +20,9 @@ "description": "Username of the user", "maxLength": null, "default": null, - "nullable": false, - "unique": true + "isNullable": false, + "isUnique": true, + "isUuid": true }, { "fieldName": "email", @@ -29,8 +30,9 @@ "description": "Email of the user", "maxLength": null, "default": null, - "nullable": false, - "unique": true + "isNullable": false, + "isUnique": true, + "isUuid": true }, { "fieldName": "type", @@ -38,8 +40,9 @@ "description": "Type of the user", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false, + "isUuid": true }, { "fieldName": "password", @@ -47,8 +50,9 @@ "description": "Password of the user", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false, + "isUuid": true }, { "fieldName": "posts", @@ -56,8 +60,8 @@ "description": "Posts authored by the user", "maxLength": null, "default": null, - "nullable": true, - "unique": false + "isNullable": true, + "isUnique": false } ], "description": "User model" @@ -70,9 +74,9 @@ "type": "Int", "description": "ID of the post", "maxLength": null, - "nullable": false, + "isNullable": false, "isId": true, - "unique": true, + "isUnique": true, "autoincrement": true }, { @@ -81,8 +85,8 @@ "description": "Title of the post", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "content", @@ -90,8 +94,8 @@ "description": "Content of the post", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "author", @@ -99,8 +103,8 @@ "description": "Author of the post", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "comments", @@ -108,8 +112,8 @@ "description": "Comments associated with the post", "maxLength": null, "default": null, - "nullable": true, - "unique": false + "isNullable": true, + "isUnique": false } ], "description": "Post model" @@ -123,8 +127,8 @@ "description": "ID of the comment", "maxLength": null, "default": null, - "nullable": false, - "unique": false, + "isNullable": false, + "isUnique": false, "isId": true }, { @@ -133,8 +137,8 @@ "description": "Content of the comment", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "author", @@ -142,8 +146,8 @@ "description": "Author of the comment", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "post", @@ -151,8 +155,8 @@ "description": "Post associated with the comment", "maxLength": null, "default": null, - "nullable": false, - "unique": false, + "isNullable": false, + "isUnique": false, "isForeignKey": true, "vectorEmbed": true, "embeddingAlgo": "text-embedding-3-large" diff --git a/test/schemas/enum.json b/test/schemas/enum.json index 6a2b385..b98f4ad 100644 --- a/test/schemas/enum.json +++ b/test/schemas/enum.json @@ -9,10 +9,10 @@ "description": "ID of the user", "maxLength": null, "default": null, - "nullable": false, - "unique": false, + "isNullable": false, + "isUnique": false, "isId": true, - "uuid": true + "isUuid": true }, { "fieldName": "username", @@ -20,8 +20,8 @@ "description": "Username of the user", "maxLength": null, "default": null, - "nullable": false, - "unique": true + "isNullable": false, + "isUnique": true }, { "fieldName": "email", @@ -29,8 +29,8 @@ "description": "Email of the user", "maxLength": null, "default": null, - "nullable": false, - "unique": true + "isNullable": false, + "isUnique": true }, { "fieldName": "type", @@ -38,8 +38,8 @@ "description": "Type of the user", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "password", @@ -47,8 +47,8 @@ "description": "Password of the user", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "posts", @@ -56,8 +56,8 @@ "description": "Posts authored by the user", "maxLength": null, "default": null, - "nullable": true, - "unique": false + "isNullable": true, + "isUnique": false } ], "description": "User model" @@ -70,9 +70,9 @@ "type": "Int", "description": "ID of the post", "maxLength": null, - "nullable": false, + "isNullable": false, "isId": true, - "unique": true, + "isUnique": true, "autoincrement": true }, { @@ -81,8 +81,8 @@ "description": "Title of the post", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "content", @@ -90,8 +90,8 @@ "description": "Content of the post", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "author", @@ -99,8 +99,8 @@ "description": "Author of the post", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "comments", @@ -108,8 +108,8 @@ "description": "Comments associated with the post", "maxLength": null, "default": null, - "nullable": true, - "unique": false + "isNullable": true, + "isUnique": false } ], "description": "Post model" @@ -123,8 +123,8 @@ "description": "ID of the comment", "maxLength": null, "default": null, - "nullable": false, - "unique": false, + "isNullable": false, + "isUnique": false, "isId": true }, { @@ -133,8 +133,8 @@ "description": "Content of the comment", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "author", @@ -142,8 +142,8 @@ "description": "Author of the comment", "maxLength": null, "default": null, - "nullable": false, - "unique": false + "isNullable": false, + "isUnique": false }, { "fieldName": "post", @@ -151,10 +151,10 @@ "description": "Post associated with the comment", "maxLength": null, "default": null, - "nullable": false, - "unique": false, + "isNullable": false, + "isUnique": false, "isForeignKey": true, - "vectorEmbed": true, + "isVectorEmbed": true, "embeddingAlgo": "text-embedding-3-large" } ], diff --git a/test/schemas/no_unique.json b/test/schemas/no_unique.json index ae26936..f74ba46 100644 --- a/test/schemas/no_unique.json +++ b/test/schemas/no_unique.json @@ -8,9 +8,9 @@ "type": "String", "description": "", "maxLength": "", - "nullable": false, - "unique": false, - "vectorEmbed": false + "isNullable": false, + "isUnique": false, + "isVectorEmbed": false } ], "description": "Schema for seed treating materials data with details of each order" diff --git a/test/schemas/optional_unique.json b/test/schemas/optional_unique.json new file mode 100644 index 0000000..be58329 --- /dev/null +++ b/test/schemas/optional_unique.json @@ -0,0 +1,45 @@ +{ + "schema": [ + { + "schemaName": "questions01", + "fields": [ + { + "fieldName": "question", + "type": "String", + "description": "", + "maxLength": 10, + "isNullable": true, + "isUnique": false, + "isVectorEmbed": true, + "isUuid": true, + "embeddingAlgo": "text-embedding-ada-002" + }, + { + "fieldName": "answer", + "type": "String", + "description": "", + "maxLength": "", + "isNullable": true, + "isId": false, + "isUuid": false, + "isUnique": true, + "isVectorEmbed": false + } + ], + "description": "schema for questions and answers" + } + ], + "dataSource": { + "name": "db", + "provider": "postgresql", + "url": { + "fromEnv": "DATABASE_URL" + }, + "extensions": ["vector", "pg_trgm"] + }, + "generator": { + "provider": "prisma-client-js", + "generatorName": "client", + "previewFeatures": ["postgresqlExtensions", "views"] + } +} diff --git a/test/schemas/vector_embeddings.json b/test/schemas/vector_embeddings.json index 15392ca..b2b6fdd 100644 --- a/test/schemas/vector_embeddings.json +++ b/test/schemas/vector_embeddings.json @@ -8,9 +8,9 @@ "type": "String", "description": "", "maxLength": "", - "nullable": false, - "unique": false, - "vectorEmbed": true, + "isNullable": false, + "isUnique": false, + "isVectorEmbed": true, "embeddingAlgo": "text-embedding-ada-002" } ], diff --git a/test/schemas/whitespace_name.json b/test/schemas/whitespace_name.json index 9d6e8c8..f684dce 100644 --- a/test/schemas/whitespace_name.json +++ b/test/schemas/whitespace_name.json @@ -8,9 +8,9 @@ "type": "String", "description": "", "maxLength": "", - "nullable": false, - "unique": false, - "vectorEmbed": false + "isNullable": false, + "isUnique": false, + "isVectorEmbed": false } ], "description": "Schema for seed treating materials data with details of each order"