Skip to content

Commit 1e6f015

Browse files
authored
73 allow to process prisma schemas programtically (#74)
* feat: allow generate prisma schema from function * update * fix: docs * update
1 parent ef42a7d commit 1e6f015

4 files changed

Lines changed: 106 additions & 2 deletions

File tree

.changeset/soft-cooks-camp.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"prisma-openapi": minor
3+
---
4+
5+
Allow to generate schemas with sdk

README.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ A Prisma generator that automatically creates OpenAPI specifications from your P
1919
- [Usage](#usage)
2020
- [Examples](#examples)
2121
- [Basic Usage](#basic-usage)
22-
- [Custom Configuration](#custom-configuration)
2322
- [JSDoc Integration](#jsdoc-integration)
2423
- [Prisma Comments as Descriptions](#prisma-comments-as-descriptions)
2524
- [Configuration](#configuration)
@@ -34,6 +33,7 @@ A Prisma generator that automatically creates OpenAPI specifications from your P
3433
- 🧩 **Relationship Support**: Properly maps Prisma relationships to OpenAPI references
3534
- *️⃣ **Enum Support**: Full support for Prisma enums in your API documentation
3635
- 📝 **JSDoc Generation**: Create JSDoc comments for your TypeScript types based on the Prisma schema
36+
- 🧰 **Programmatic Schema Generation**: Generate schema directly from code
3737

3838
## Setup
3939

@@ -150,6 +150,36 @@ components:
150150
- published
151151
- author
152152
- authorId
153+
154+
### Programmatic Schema Generation
155+
156+
Generate a schema programmatically from a Prisma schema string:
157+
158+
```ts
159+
import { generateOpenApiSchema } from "prisma-openapi";
160+
161+
const schema = `
162+
datasource db {
163+
provider = "postgresql"
164+
}
165+
166+
model User {
167+
id Int @id @default(autoincrement())
168+
email String @unique
169+
name String?
170+
}
171+
`;
172+
173+
const { yaml, json } = await generateOpenApiSchema({
174+
prismaSchema: schema,
175+
title: "My API",
176+
description: "Generated via SDK",
177+
generateYaml: true,
178+
generateJson: true,
179+
});
180+
181+
console.log(yaml);
182+
```
153183
```
154184

155185
### Custom Configuration

package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@
99
"prisma-openapi": "./dist/index.js"
1010
},
1111
"type": "module",
12-
"exports": "./dist/index.js",
12+
"exports": {
13+
".": {
14+
"types": "./dist/index.d.ts",
15+
"default": "./dist/index.js"
16+
},
17+
"./lib": {
18+
"types": "./dist/lib/index.d.ts",
19+
"default": "./dist/lib/index.js"
20+
}
21+
},
1322
"types": "./dist/index.d.ts",
1423
"scripts": {
1524
"clean": "rimraf dist prisma/openapi",

src/lib/index.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import {getDMMF} from '@prisma/internals';
2+
import {generateOpenApiSpec} from '../on-generate/generate-open-api-spec.js';
3+
import {
4+
defaultOptions,
5+
parseCommaSeparatedList,
6+
type PrismaOpenApiOptions,
7+
} from '../on-generate/generator-options.js';
8+
9+
export type PrismaOpenApiSchemaOptions = Partial<PrismaOpenApiOptions>;
10+
11+
export async function generateOpenApiSchema(
12+
prismaSchema: string,
13+
options: PrismaOpenApiSchemaOptions = {},
14+
): Promise<string> {
15+
if (!prismaSchema.trim()) {
16+
throw new Error('Prisma schema must be a non-empty string.');
17+
}
18+
19+
const dmmf = await getDMMF({datamodel: prismaSchema});
20+
const prismaOpenApiOptions: PrismaOpenApiOptions = {
21+
...defaultOptions,
22+
...options,
23+
};
24+
25+
let filteredModels = [...dmmf.datamodel.models];
26+
const includeModelsList = parseCommaSeparatedList(
27+
prismaOpenApiOptions.includeModels,
28+
);
29+
const excludeModelsList = parseCommaSeparatedList(
30+
prismaOpenApiOptions.excludeModels,
31+
);
32+
33+
if (includeModelsList && includeModelsList.length > 0) {
34+
filteredModels = filteredModels.filter((model) =>
35+
includeModelsList.includes(model.name),
36+
);
37+
}
38+
39+
if (excludeModelsList && excludeModelsList.length > 0) {
40+
filteredModels = filteredModels.filter(
41+
(model) => !excludeModelsList.includes(model.name),
42+
);
43+
}
44+
45+
const openApiBuilder = generateOpenApiSpec(
46+
filteredModels,
47+
dmmf.datamodel.enums,
48+
prismaOpenApiOptions,
49+
);
50+
51+
if (prismaOpenApiOptions.generateJson && !prismaOpenApiOptions.generateYaml) {
52+
return openApiBuilder.getSpecAsJson();
53+
}
54+
55+
if (prismaOpenApiOptions.generateYaml) {
56+
return openApiBuilder.getSpecAsYaml();
57+
}
58+
59+
return openApiBuilder.getSpecAsJson();
60+
}

0 commit comments

Comments
 (0)