prisma-client-php 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,7 +28,9 @@ Follow these steps to install and set up Prisma Client PHP:
28
28
  npx create-prisma-php-app@latest
29
29
  ```
30
30
 
31
- 3. **Generate Prisma Client PHP classes** by running:
31
+ 3. **Remember to chose Prisma PHP ORM when prompted**.
32
+
33
+ 4. **Generate Prisma Client PHP classes** by running:
32
34
 
33
35
  ```bash
34
36
  npx ppo generate
@@ -36,6 +38,20 @@ Follow these steps to install and set up Prisma Client PHP:
36
38
 
37
39
  This command will convert your `schema.prisma` models into PHP classes, enabling you to interact with your database using these generated classes.
38
40
 
41
+ ## Adding Prisma Client PHP to an Existing Prisma PHP Project
42
+
43
+ If you already have a Prisma PHP project and want to integrate Prisma Client PHP, follow these steps:
44
+
45
+ 1. **Open your terminal**.
46
+
47
+ 2. **Install Prisma Client PHP** by running the following command:
48
+
49
+ ```bash
50
+ npx ppo init
51
+ ```
52
+
53
+ This command will install all the necessary packages required for Prisma Client PHP to function within your existing project.
54
+
39
55
  ## Features
40
56
 
41
57
  - **Auto-Generated PHP Classes**: Prisma Client PHP automatically generates PHP classes based on your Prisma schema.
package/dist/index.js CHANGED
@@ -2,42 +2,44 @@
2
2
  import chalk from "chalk";
3
3
  import fs from "fs";
4
4
  import path from "path";
5
- import { fileURLToPath, pathToFileURL } from "url";
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = path.dirname(__filename);
5
+ import { pathToFileURL } from "url";
6
+ import { getFileMeta } from "./utils.js";
7
+ const { __dirname } = getFileMeta();
8
8
  const args = process.argv.slice(2);
9
- const command = args.join(" ");
10
9
  const commandsToExecute = {
11
- generate: "generate",
10
+ generate: "generate",
11
+ init: "init",
12
12
  };
13
- const executeFile = async (fileName) => {
14
- const filePath = path.join(__dirname, fileName);
15
- if (!fs.existsSync(filePath)) {
16
- console.error(chalk.red(`File '${fileName}' not found.`));
17
- process.exit(1);
18
- }
19
- try {
20
- const module = await import(pathToFileURL(filePath).toString());
21
- if (module.default) {
22
- module.default();
23
- }
24
- }
25
- catch (error) {
26
- console.error("Error executing file:", error);
13
+ const executeFile = async (fileName, extraArgs = []) => {
14
+ const filePath = path.join(__dirname, fileName);
15
+ if (!fs.existsSync(filePath)) {
16
+ console.error(chalk.red(`File '${fileName}' not found.`));
17
+ process.exit(1);
18
+ }
19
+ try {
20
+ const module = await import(pathToFileURL(filePath).toString());
21
+ if (module.default) {
22
+ module.default(extraArgs); // Pass extraArgs (even if empty)
27
23
  }
24
+ } catch (error) {
25
+ console.error("Error executing file:", error);
26
+ }
28
27
  };
29
28
  const main = async () => {
30
- if (args.length === 0) {
31
- console.log("No command provided.");
32
- return;
33
- }
34
- if (commandsToExecute.generate === command) {
35
- await executeFile("generate.js");
36
- }
37
- else {
38
- console.log(chalk.red("Invalid command. Use: npx ppo generate"));
39
- }
29
+ if (args.length === 0) {
30
+ console.log("No command provided.");
31
+ return;
32
+ }
33
+ const commandName = args[0]; // First argument is the command (e.g., "init" or "generate")
34
+ const extraArgs = args.slice(1); // Capture any additional arguments (e.g., "--prisma-php")
35
+ if (commandsToExecute.generate === commandName) {
36
+ await executeFile("generate.js", extraArgs);
37
+ } else if (commandsToExecute.init === commandName) {
38
+ await executeFile("init.js", extraArgs);
39
+ } else {
40
+ console.log(chalk.red("Invalid command. Use: npx ppo generate"));
41
+ }
40
42
  };
41
43
  main().catch((error) => {
42
- console.error("Unhandled error in main function:", error);
44
+ console.error("Unhandled error in main function:", error);
43
45
  });
package/dist/init.js ADDED
@@ -0,0 +1,158 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { execSync } from "child_process";
4
+ import { getFileMeta } from "./utils.js";
5
+ const { __dirname } = getFileMeta();
6
+ /**
7
+ * Recursively copies all files and folders from `src` to `dest`,
8
+ * overwriting existing files if they already exist.
9
+ *
10
+ * The `base` parameter represents the original root of the copy.
11
+ * It is used for computing a relative path for cleaner logging.
12
+ */
13
+ function copyRecursiveSync(src, dest, base = src) {
14
+ if (!fs.existsSync(src)) {
15
+ console.error(`Source folder does not exist: ${src}`);
16
+ return;
17
+ }
18
+ if (!fs.existsSync(dest)) {
19
+ fs.mkdirSync(dest, { recursive: true });
20
+ }
21
+ const entries = fs.readdirSync(src, { withFileTypes: true });
22
+ for (const entry of entries) {
23
+ const srcPath = path.join(src, entry.name);
24
+ const destPath = path.join(dest, entry.name);
25
+ if (entry.isDirectory()) {
26
+ copyRecursiveSync(srcPath, destPath, base);
27
+ } else {
28
+ // Compute the relative path for logging
29
+ const relative = path.relative(base, srcPath);
30
+ const display = path.join(path.basename(base), relative);
31
+ // Copy the file (this will overwrite if it exists)
32
+ fs.copyFileSync(srcPath, destPath);
33
+ console.log(`Copied file: ${display}`);
34
+ }
35
+ }
36
+ }
37
+ // Configuration for directories to copy (copying the whole directory recursively)
38
+ const directoriesToCopy = [
39
+ {
40
+ srcFolder: path.join(__dirname, "src"),
41
+ destFolder: path.join(process.cwd(), "src"),
42
+ },
43
+ {
44
+ srcFolder: path.join(__dirname, "settings"),
45
+ destFolder: path.join(process.cwd(), "settings"),
46
+ },
47
+ {
48
+ srcFolder: path.join(__dirname, "prisma"),
49
+ destFolder: path.join(process.cwd(), "prisma"),
50
+ },
51
+ ];
52
+ /**
53
+ * Installs specified packages using npm in the current working directory.
54
+ */
55
+ function installPackages() {
56
+ const packages = [
57
+ "prisma@^6.4.1",
58
+ "@prisma/client@^6.4.1",
59
+ "@prisma/internals@^6.4.1",
60
+ ];
61
+ const packagesStr = packages.join(" ");
62
+ try {
63
+ console.log(`Installing packages: ${packagesStr}`);
64
+ execSync(`npm install ${packagesStr}`, {
65
+ stdio: "inherit",
66
+ cwd: process.cwd(),
67
+ });
68
+ console.log("Packages installed successfully.");
69
+ } catch (error) {
70
+ console.error("Error installing packages:", error);
71
+ }
72
+ }
73
+ /**
74
+ * Runs the `npx prisma init` command to initialize Prisma.
75
+ * If the prisma folder already exists, the command is skipped.
76
+ */
77
+ function initPrisma() {
78
+ const prismaFolderPath = path.join(process.cwd(), "prisma");
79
+ if (fs.existsSync(prismaFolderPath)) {
80
+ console.warn("Prisma folder already exists. Skipping prisma init.");
81
+ return;
82
+ }
83
+ try {
84
+ console.log("Initializing Prisma...");
85
+ execSync(`npx prisma init`, {
86
+ stdio: "inherit",
87
+ cwd: process.cwd(),
88
+ });
89
+ console.log("Prisma initialized successfully.");
90
+ } catch (error) {
91
+ console.error("Error initializing Prisma:", error);
92
+ }
93
+ }
94
+ /**
95
+ * Updates the composer.json file by adding "calicastle/cuid": "^2.0.0" to its require section.
96
+ */
97
+ async function updateComposerJson(baseDir) {
98
+ const composerJsonPath = path.join(baseDir, "composer.json");
99
+ let composerJson;
100
+ if (fs.existsSync(composerJsonPath)) {
101
+ const composerJsonContent = fs.readFileSync(composerJsonPath, "utf8");
102
+ composerJson = JSON.parse(composerJsonContent);
103
+ } else {
104
+ console.error("composer.json does not exist.");
105
+ return;
106
+ }
107
+ composerJson.require = {
108
+ ...composerJson.require,
109
+ "calicastle/cuid": "^2.0.0",
110
+ };
111
+ fs.writeFileSync(composerJsonPath, JSON.stringify(composerJson, null, 2));
112
+ console.log("composer.json updated successfully.");
113
+ }
114
+ /**
115
+ * Installs the Composer package "calicastle/cuid": "^2.0.0" using the require command.
116
+ */
117
+ function runComposerInstall() {
118
+ try {
119
+ console.log("Installing Composer package calicastle/cuid...");
120
+ execSync(
121
+ `C:\\xampp\\php\\php.exe C:\\ProgramData\\ComposerSetup\\bin\\composer.phar require calicastle/cuid:^2.0.0`,
122
+ {
123
+ stdio: "inherit",
124
+ }
125
+ );
126
+ console.log("Composer package calicastle/cuid installed successfully.");
127
+ } catch (error) {
128
+ console.error("Error installing Composer package calicastle/cuid:", error);
129
+ }
130
+ }
131
+ /**
132
+ * Main execution flow.
133
+ *
134
+ * If the flag "--prisma-php" is passed, it will update composer.json.
135
+ * Otherwise, it will run Composer install to install the package.
136
+ * Then, it proceeds with npm package installation, Prisma initialization, and file copying.
137
+ */
138
+ async function main() {
139
+ const isPrismaPHP = process.argv.includes("--prisma-php");
140
+ if (isPrismaPHP) {
141
+ // Always update composer.json
142
+ await updateComposerJson(process.cwd());
143
+ } else {
144
+ // Install the Composer package "calicastle/cuid": "^2.0.0"
145
+ runComposerInstall();
146
+ }
147
+ installPackages();
148
+ initPrisma();
149
+ directoriesToCopy.forEach((config) => {
150
+ // Pass the srcFolder as the base for computing relative paths in the log
151
+ copyRecursiveSync(config.srcFolder, config.destFolder, config.srcFolder);
152
+ });
153
+ console.log("Finished copying directories.");
154
+ }
155
+ // Run the main function
156
+ main().catch((error) => {
157
+ console.error("Error during execution:", error);
158
+ });
@@ -0,0 +1,35 @@
1
+ // This is your Prisma schema file,
2
+ // learn more about it in the docs: https://pris.ly/d/prisma-schema
3
+
4
+ // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
5
+ // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
6
+
7
+ generator client {
8
+ provider = "prisma-client-js"
9
+ }
10
+
11
+ datasource db {
12
+ provider = "postgresql"
13
+ url = env("DATABASE_URL")
14
+ }
15
+
16
+ model User {
17
+ id String @id @default(cuid())
18
+ name String?
19
+ email String? @unique
20
+ password String?
21
+ emailVerified DateTime?
22
+ image String?
23
+ createdAt DateTime @default(now())
24
+ updatedAt DateTime @updatedAt
25
+
26
+ roleId Int?
27
+ userRole UserRole? @relation(fields: [roleId], references: [id])
28
+ }
29
+
30
+ model UserRole {
31
+ id Int @id @default(autoincrement())
32
+ name String @unique
33
+
34
+ user User[]
35
+ }
@@ -0,0 +1,74 @@
1
+ // import { PrismaClient } from "@prisma/client";
2
+
3
+ // const prisma = new PrismaClient();
4
+
5
+ // // UserRole
6
+ // const userRoleData = [
7
+ // {
8
+ // name: "Admin",
9
+ // },
10
+ // {
11
+ // name: "User",
12
+ // },
13
+ // ];
14
+
15
+ // // User
16
+ // const userData = [
17
+ // {
18
+ // name: "Juan",
19
+ // email: "j@gmail.com",
20
+ // password: "$2b$10$mgjotYzIXwrK1MCWmu4tgeUVnLcb.qzvqwxOq4FXEL8k2obwXivDi", // TODO: template password 1234 (bcrypt) testing only
21
+ // roleId: 1,
22
+ // },
23
+ // ];
24
+
25
+ // async function main() {
26
+ // ========================================
27
+ // Code for PostgreSQL
28
+ // ----------------------------------------
29
+ // UserRole
30
+ // ----------------------------------------
31
+ // await prisma.userRole.deleteMany();
32
+ // await prisma.userRole.createMany({ data: userRoleData });
33
+ // await prisma.$executeRaw`ALTER SEQUENCE "UserRole_id_seq" RESTART WITH 1`;
34
+ // ----------------------------------------
35
+ // User
36
+ // ----------------------------------------
37
+ // await prisma.user.deleteMany();
38
+ // await prisma.user.createMany({ data: userData });
39
+ // ========================================
40
+ // Code for MySQL
41
+ // ----------------------------------------
42
+ // UserRole
43
+ // ----------------------------------------
44
+ // await prisma.userRole.deleteMany();
45
+ // await prisma.userRole.createMany({ data: userRoleData });
46
+ // await prisma.$executeRaw`ALTER TABLE UserRole AUTO_INCREMENT = 1`;
47
+ // ----------------------------------------
48
+ // User
49
+ // ----------------------------------------
50
+ // await prisma.user.deleteMany();
51
+ // await prisma.user.createMany({ data: userData });
52
+ // ========================================
53
+ // Code for SQLite
54
+ // ========================================
55
+ // UserRole
56
+ // ----------------------------------------
57
+ // await prisma.userRole.deleteMany();
58
+ // await prisma.userRole.createMany({ data: userRoleData });
59
+ // SQLite automatically handles ID incrementation and does not require manual sequence reset
60
+ // ----------------------------------------
61
+ // User
62
+ // ----------------------------------------
63
+ // await prisma.user.deleteMany();
64
+ // await prisma.user.createMany({ data: userData });
65
+ // ========================================
66
+ // }
67
+
68
+ // main()
69
+ // .catch((e) => {
70
+ // throw e;
71
+ // })
72
+ // .finally(async () => {
73
+ // await prisma.$disconnect();
74
+ // });
@@ -0,0 +1,103 @@
1
+ {
2
+ "datamodel": {
3
+ "enums": [],
4
+ "models": []
5
+ },
6
+ "schema": {
7
+ "inputObjectTypes": {},
8
+ "outputObjectTypes": {
9
+ "prisma": [
10
+ {
11
+ "name": "Query",
12
+ "fields": []
13
+ },
14
+ {
15
+ "name": "Mutation",
16
+ "fields": [
17
+ {
18
+ "name": "executeRaw",
19
+ "args": [
20
+ {
21
+ "name": "query",
22
+ "isRequired": true,
23
+ "isNullable": false,
24
+ "inputTypes": [
25
+ {
26
+ "type": "String",
27
+ "location": "scalar",
28
+ "isList": false
29
+ }
30
+ ]
31
+ },
32
+ {
33
+ "name": "parameters",
34
+ "isRequired": false,
35
+ "isNullable": false,
36
+ "inputTypes": [
37
+ {
38
+ "type": "Json",
39
+ "location": "scalar",
40
+ "isList": false
41
+ }
42
+ ]
43
+ }
44
+ ],
45
+ "isNullable": false,
46
+ "outputType": {
47
+ "type": "Json",
48
+ "location": "scalar",
49
+ "isList": false
50
+ }
51
+ },
52
+ {
53
+ "name": "queryRaw",
54
+ "args": [
55
+ {
56
+ "name": "query",
57
+ "isRequired": true,
58
+ "isNullable": false,
59
+ "inputTypes": [
60
+ {
61
+ "type": "String",
62
+ "location": "scalar",
63
+ "isList": false
64
+ }
65
+ ]
66
+ },
67
+ {
68
+ "name": "parameters",
69
+ "isRequired": false,
70
+ "isNullable": false,
71
+ "inputTypes": [
72
+ {
73
+ "type": "Json",
74
+ "location": "scalar",
75
+ "isList": false
76
+ }
77
+ ]
78
+ }
79
+ ],
80
+ "isNullable": false,
81
+ "outputType": {
82
+ "type": "Json",
83
+ "location": "scalar",
84
+ "isList": false
85
+ }
86
+ }
87
+ ]
88
+ }
89
+ ]
90
+ },
91
+ "enumTypes": {}
92
+ },
93
+ "mappings": {
94
+ "modelOperations": [],
95
+ "otherOperations": {
96
+ "read": [],
97
+ "write": [
98
+ "executeRaw",
99
+ "queryRaw"
100
+ ]
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,30 @@
1
+ import { resolve } from "path";
2
+ import { readFileSync, writeFileSync } from "fs";
3
+ import psdk from "@prisma/internals";
4
+ import { fileURLToPath } from "url";
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ const { getDMMF } = psdk;
10
+ const schemaPath: string = resolve(__dirname, "../prisma/schema.prisma");
11
+ const prismaSchemaJsonPath: string = resolve(__dirname, "prisma-schema.json");
12
+
13
+ export const prismaSdk = async (): Promise<void> => {
14
+ try {
15
+ const schema = readFileSync(schemaPath, "utf-8");
16
+
17
+ // Parse the schema into DMMF (Data Model Meta Format) and then convert to JSON
18
+ const dmmf = await getDMMF({ datamodel: schema });
19
+
20
+ // Write the DMMF schema to JSON
21
+ writeFileSync(prismaSchemaJsonPath, JSON.stringify(dmmf, null, 2));
22
+ console.log("Schema converted to JSON!");
23
+ } catch (error) {
24
+ console.error("Error parsing schema:", error);
25
+ }
26
+ };
27
+
28
+ if (process.argv[1] && process.argv[1].endsWith("prisma-sdk.ts")) {
29
+ prismaSdk();
30
+ }