Skip to content

Commit

Permalink
commit init
Browse files Browse the repository at this point in the history
  • Loading branch information
ogroppo committed Nov 24, 2024
1 parent 9484a53 commit 985ddae
Show file tree
Hide file tree
Showing 30 changed files with 4,349 additions and 1,499 deletions.
11 changes: 11 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/[email protected]/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": true,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: [codeledge]
38 changes: 38 additions & 0 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Changesets
on:
push:
branches:
- main
env:
CI: true
PNPM_CACHE_FOLDER: .pnpm-store
jobs:
version:
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: checkout code repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: setup node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: install pnpm
run: npm i pnpm@latest -g
- name: Setup npmrc
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc
- name: setup pnpm config
run: pnpm config set store-dir $PNPM_CACHE_FOLDER
- name: install dependencies
run: pnpm install --no-frozen-lockfile
- name: create and publish versions
uses: changesets/action@v1
with:
version: pnpm ci:version
commit: "chore: update versions"
title: "chore: update versions"
publish: pnpm ci:publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
"test": "turbo run test",
"dev": "turbo run dev --parallel --no-cache",
"build": "turbo run build",
"kill": "pnpm run kill --filter apps/*"
"kill": "pnpm run kill --filter apps/*",
"publish-packages": "turbo run build lint && changeset version && changeset publish"
},
"devDependencies": {
"turbo": "^1.13.0"
"turbo": "^2.3.1"
},
"packageManager": "[email protected]+sha512.140036830124618d624a2187b50d04289d5a087f326c9edfc0ccd733d76c4f52c3a313d4fc148794a2a9d81553016004e6742e8cf850670268a7387fc220c903"
}
1 change: 1 addition & 0 deletions packages/config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "config",
"version": "0.0.0",
"private": true,
"main": "index.js",
"license": "MIT",
"files": [
Expand Down
11 changes: 10 additions & 1 deletion packages/eslint-config-custom/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
module.exports = {
extends: ["next", "turbo", "prettier", "eslint:recommended"],
extends: [
"next",
"turbo",
"prettier",
"eslint:recommended",
"alloy",
"alloy/typescript",
],
rules: {
"@next/next/no-html-link-for-pages": "off",
"no-unused-vars": "off",
"no-unreachable": 1,
},
plugins: ["sort-imports-es6-autofix", "import"],
};
13 changes: 13 additions & 0 deletions packages/prisma-client-types-generator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
dist
node_modules
.DS_Store
*.pem
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
3 changes: 3 additions & 0 deletions packages/prisma-client-types-generator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Prisma Client Types Generator

Docs coming soon...
4 changes: 4 additions & 0 deletions packages/prisma-client-types-generator/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: ["eslint-config-custom"],
};
58 changes: 58 additions & 0 deletions packages/prisma-client-types-generator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"name": "prisma-client-types-generator",
"version": "0.0.1",
"description": "Generate safe types for the browser and other uses",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"scripts": {
"build": "tsup src/index.ts --format esm,cjs --dts --treeshake",
"dev": "pnpm build --watch",
"lint": "eslint src --fix",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
"prepublish": "pnpm build",
"test": "pnpm prisma generate --schema test/schemas/full.prisma",
"release": "pnpm changeset && pnpm changeset version"
},
"files": [
"/dist"
],
"keywords": [
"prisma",
"generator",
"types",
"safe",
"client"
],
"repository": {
"type": "git",
"url": "https://github.com/codeledge/prisma-tools.git",
"directory": "packages/prisma-client-types-generator"
},
"author": "Orlando Groppo <[email protected]>",
"license": "MIT",
"peerDependencies": {
"@prisma/client": ">=5",
"prisma": ">=5"
},
"dependencies": {
"@prisma/generator-helper": "^5.22.0"
},
"devDependencies": {
"@babel/core": "7.26.0",
"@babel/preset-env": "^7.26.0",
"@babel/preset-typescript": "^7.26.0",
"@changesets/cli": "^2.27.10",
"@prisma/client": "^5.22.0",
"@types/jest": "^29.5.14",
"@types/node": "^22.9.3",
"deverything": "^1.10.1",
"eslint-config-custom": "workspace:*",
"jest": "^29.7.0",
"prisma": "^5.22.0",
"ts-node": "^10.9.2",
"tsup": "^8.3.5",
"tsx": "^4.19.2",
"typescript": "^5.7.2"
}
}
24 changes: 24 additions & 0 deletions packages/prisma-client-types-generator/src/generateEnum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { DMMF } from "@prisma/generator-helper";
import { getPascalName } from "./getPascalName";

export const generateEnum = (
prismaEnum: DMMF.DatamodelEnum,
aliases?: Record<string, string>
) => {
let out = "";

const name = getPascalName(prismaEnum.name, aliases);

out += `export const ${name} = {\n`;

for (const value of prismaEnum.values) {
out += ` ${value.name}: '${value.name}',\n`;
}

out += `} as const;\n`;
out += "\n";
out += `export type ${name} = (typeof ${name})[keyof typeof ${name}]\n`;
out += "\n";

return out;
};
134 changes: 134 additions & 0 deletions packages/prisma-client-types-generator/src/generateModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { DMMF } from "@prisma/generator-helper";
import { getPascalName } from "./getPascalName";
import { prismaTypeMap } from "./prismaTypeMap";

const formatNull = (field: DMMF.Field) => {
return !field.isRequired ? " | null" : "";
};

const isBaseField = (field: DMMF.Field, foreignKeysMap: Record<string, 1>) => {
return !(
field.isId ||
field.isUnique ||
field.kind === "object" ||
foreignKeysMap[field.name]
);
};

export const generateModel = (
model: DMMF.Model,
aliases?: Record<string, string>
) => {
let out = "";

const modelTypeName = getPascalName(model.name, aliases); // TODO: use also model.dbName with alias?

// console.log(model.fields);

// Example of foreignKeysMap:
// { categoryId: 1, userId: 1 }
const foreignKeysMap = model.fields
.filter((field) => field.kind === "object")
.reduce((acc, field) => {
field.relationFromFields?.forEach((fromField) => {
acc[fromField] = 1;
});
return acc;
}, {} as Record<string, 1>);

// Create Keys type
out += `export type ${modelTypeName}Keys = {\n`;

for (const field of model.fields) {
if (isBaseField(field, foreignKeysMap)) {
continue;
}
switch (field.kind) {
case "scalar":
out += ` ${field.name}: ${prismaTypeMap.get(field.type)}${
field.isList ? "[]" : ""
}${formatNull(field)}\n`;
break;
default:
break;
}
}

out += `}\n`;
out += "\n";

// Create Values type
out += `export type ${modelTypeName}Values = {\n`;

for (const field of model.fields) {
if (!isBaseField(field, foreignKeysMap)) {
continue;
}
switch (field.kind) {
case "enum":
out += ` ${field.name}: ${getPascalName(field.type)}${formatNull(
field
)}\n`;
break;
case "scalar":
case "unsupported": // Untested
out += ` ${field.name}: ${prismaTypeMap.get(field.type)}${
field.isList ? "[]" : ""
}${formatNull(field)}\n`;
break;
default:
break;
}
}

out += `}\n`;
out += "\n";

// Create Relations type
out += `export type ${modelTypeName}Relations = {\n`;

for (const field of model.fields) {
switch (field.kind) {
case "object":
out += ` ${field.name}: ${field.type}${
field.isList ? "[]" : ""
}${formatNull(field)}\n`;
break;
default:
break;
}
}

out += `}\n`;
out += "\n";

// Create DB type
out += `export type ${modelTypeName} = ${modelTypeName}Keys & ${modelTypeName}Values\n`;
out += "\n";

// Create Extended type
out += `export type ${modelTypeName}Extended = ${modelTypeName} & ${modelTypeName}Relations\n`;
out += "\n";

return out;
};

// Examples:
// RELATION
// {
// name: 'author',
// kind: 'object',
// isList: false,
// isRequired: false,
// isUnique: false,
// isId: false,
// isReadOnly: false,
// hasDefaultValue: false,
// type: 'AdminUser',
// relationName: 'AdminUserToAudit',
// relationFromFields: [ 'authorId' ],
// relationToFields: [ 'id' ],
// relationOnDelete: 'Cascade',
// isGenerated: false,
// isUpdatedAt: false
// }
27 changes: 27 additions & 0 deletions packages/prisma-client-types-generator/src/generateTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { DMMF } from "@prisma/generator-helper";
import { generateEnum } from "./generateEnum";
import { generateModel } from "./generateModel";

export const generateTypes = (
datamodel: DMMF.Datamodel,
{
aliases,
}: {
aliases?: Record<string, string>;
}
) => {
let file = `// This file was generated by a custom prisma generator, do not edit manually.\n`;

const models = datamodel.models;

for (const model of models) {
file += generateModel(model, aliases);
}

const enums = datamodel.enums;
for (const enumItem of enums) {
file += generateEnum(enumItem, aliases);
}

return file;
};
15 changes: 15 additions & 0 deletions packages/prisma-client-types-generator/src/getPascalName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const getPascalName = (
str: string,
aliases: Record<string, string> = {}
) => {
if (str in aliases) {
return aliases[str];
}

const pascalCase = str
.split("_")
.map((s) => s[0].toUpperCase() + s.slice(1))
.join("");

return pascalCase;
};
9 changes: 9 additions & 0 deletions packages/prisma-client-types-generator/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { generatorHandler } from "@prisma/generator-helper";
import { onGenerate } from "./onGenerate";
import { onManifest } from "./onManifest";

// Defines the entry point of the generator.
generatorHandler({
onManifest,
onGenerate,
});
Loading

0 comments on commit 985ddae

Please sign in to comment.