|
1 |
| -import { filesystem } from '@stacksjs/storage' |
2 |
| -import { frameworkPath, projectPath } from '@stacksjs/path' |
3 |
| -import type { Model, SchemaOptions } from '@stacksjs/types' |
4 |
| -import { titleCase } from '@stacksjs/strings' |
5 |
| - |
6 |
| -const { fs } = filesystem |
7 |
| - |
8 |
| -function generatePrismaSchema(models: Model[], path: string, options: SchemaOptions): void { |
9 |
| - let schema = `datasource db { |
10 |
| - provider = "${options.database}" |
11 |
| - url = env("DATABASE_URL") |
12 |
| -} |
13 |
| -
|
14 |
| -generator client { |
15 |
| - provider = "prisma-client-js" |
16 |
| -} |
17 |
| -
|
18 |
| -` |
19 |
| - |
20 |
| - for (const model of models) { |
21 |
| - schema += `model ${model.name} { |
22 |
| - id Int @id @default(autoincrement()) |
23 |
| -` |
24 |
| - |
25 |
| - for (const fieldName in model.fields) { |
26 |
| - const field = model.fields[fieldName] |
27 |
| - |
28 |
| - let columnSchema = ` ${fieldName} ${field.type}` |
29 |
| - |
30 |
| - if (field.required) |
31 |
| - columnSchema += ' @required' |
32 |
| - |
33 |
| - if (field.unique) |
34 |
| - columnSchema += ' @unique' |
35 |
| - |
36 |
| - if (field.default) |
37 |
| - columnSchema += ` @default(${field.default})` |
38 |
| - |
39 |
| - columnSchema += '\n' |
40 |
| - schema += columnSchema |
41 |
| - } |
42 |
| - |
43 |
| - if (model.hasOne) { |
44 |
| - schema += ` ${model.hasOne} ${titleCase(model.hasOne)}?` |
45 |
| - schema += ` @relation(fields: [${model.hasOne}Id], references: [id])\n` |
46 |
| - schema += ` ${model.hasOne}Id Int\n` |
47 |
| - } |
48 |
| - |
49 |
| - if (model.belongsToMany) { |
50 |
| - schema += ` ${model.belongsToMany} ${titleCase(model.belongsToMany)}` |
51 |
| - schema += ` @relation(fields: [${model.belongsToMany}Id], references: [id])\n` |
52 |
| - schema += ` ${model.belongsToMany}Id Int\n` |
53 |
| - } |
54 |
| - |
55 |
| - if (model.hasMany) { |
56 |
| - schema += ` ${model.hasMany} ${titleCase(model.hasMany)}[]` |
57 |
| - schema += ` @relation(fields: [id], references: [${model.name?.toLowerCase()}Id])\n` |
58 |
| - } |
59 |
| - |
60 |
| - if (model.hasThrough) { |
61 |
| - schema += ` ${model.hasThrough.model} ${titleCase(model.hasThrough.model)}[]` |
62 |
| - schema += ` @relation("${model.hasThrough.using}")` |
63 |
| - schema += ` ${model.hasThrough.using} ${titleCase(model.hasThrough.using)}` |
64 |
| - schema += ` @relation("${model.hasThrough.through}")` |
65 |
| - schema += ` ${model.hasThrough.through} ${titleCase(model.hasThrough.through)}` |
66 |
| - schema += ` @relation(fields: [${model.hasThrough.using}], references: [id])\n` |
67 |
| - } |
68 |
| - |
69 |
| - schema += ' createdAt DateTime @default(now())\n' |
70 |
| - schema += ' updatedAt DateTime @updatedAt()\n' |
71 |
| - schema += '}\n\n' |
72 |
| - |
73 |
| - if (model.hasMany) { |
74 |
| - schema += `model ${titleCase(model.hasMany)} { |
75 |
| -id Int @id @default(autoincrement()) |
76 |
| -createdAt DateTime @default(now()) |
77 |
| -updatedAt DateTime @updatedAt() |
78 |
| -${model.name?.toLowerCase()}Id Int |
79 |
| -${model.name?.toLowerCase()} ${titleCase(model.name)} |
80 |
| -@relation(fields: [${model.name?.toLowerCase()}Id], references: [id]) |
81 |
| -}\n\n` |
82 |
| - } |
83 |
| - |
84 |
| - if (model.hasOne || model.belongsToMany) { |
85 |
| - const relatedModelName = model.hasOne || model.belongsToMany |
86 |
| - schema += `model ${titleCase(relatedModelName)} { |
87 |
| -id Int @id @default(autoincrement()) |
88 |
| -createdAt DateTime @default(now()) |
89 |
| -updatedAt DateTime @updatedAt() |
90 |
| -${model.name?.toLowerCase()} ${titleCase(model.name)}? |
91 |
| -${model.name?.toLowerCase()}Id Int? |
92 |
| -@unique |
93 |
| -}\n\n` |
94 |
| - } |
95 |
| - } |
96 |
| - |
97 |
| - if (!fs.existsSync(frameworkPath('database'))) |
98 |
| - fs.mkdirSync(frameworkPath('database')) |
99 |
| - |
100 |
| - fs.writeFile(path, schema, (err) => { |
101 |
| - if (err) |
102 |
| - console.error(`Error writing schema file: ${err.message}`) |
103 |
| - else |
104 |
| - // eslint-disable-next-line no-console |
105 |
| - console.log(`Schema file generated successfully at path: ${path}`) |
106 |
| - }) |
107 |
| -} |
108 |
| - |
109 |
| -function readModelsFromFolder(folderPath: string): Promise<Model[]> { |
110 |
| - return new Promise((resolve, reject) => { |
111 |
| - const models: Model[] = [] |
112 |
| - |
113 |
| - fs.readdir(folderPath, (err, files) => { |
114 |
| - if (err) |
115 |
| - reject(err) |
116 |
| - |
117 |
| - const promises = files |
118 |
| - .filter(file => file.endsWith('.ts')) |
119 |
| - .map((file) => { |
120 |
| - const filePath = `${folderPath}/${file}` |
121 |
| - |
122 |
| - return import(filePath).then((data) => { |
123 |
| - models.push({ |
124 |
| - name: data.default.name, |
125 |
| - fields: data.default.fields, |
126 |
| - }) |
127 |
| - }) |
128 |
| - }) |
129 |
| - |
130 |
| - Promise.all(promises) |
131 |
| - .then(() => resolve(models)) |
132 |
| - .catch(err => reject(err)) |
133 |
| - }) |
134 |
| - }) |
135 |
| -} |
136 |
| - |
137 |
| -async function migrate(path: string, options: SchemaOptions): Promise<void> { |
138 |
| - const models = await readModelsFromFolder(projectPath('app/models')) |
139 |
| - |
140 |
| - generatePrismaSchema(models, path, options) |
141 |
| -} |
142 |
| - |
143 |
| -export { |
144 |
| - migrate, |
145 |
| -} |
| 1 | +// import { filesystem } from '@stacksjs/storage' |
| 2 | +// import { frameworkPath, projectPath } from '@stacksjs/path' |
| 3 | +// import type { Model, SchemaOptions } from '@stacksjs/types' |
| 4 | +// import { titleCase } from '@stacksjs/strings' |
| 5 | + |
| 6 | +// const { fs } = filesystem |
| 7 | + |
| 8 | +// function generatePrismaSchema(models: Model[], path: string, options: SchemaOptions): void { |
| 9 | +// let schema = `datasource db { |
| 10 | +// provider = "${options.database}" |
| 11 | +// url = env("DATABASE_URL") |
| 12 | +// } |
| 13 | + |
| 14 | +// generator client { |
| 15 | +// provider = "prisma-client-js" |
| 16 | +// } |
| 17 | + |
| 18 | +// ` |
| 19 | + |
| 20 | +// for (const model of models) { |
| 21 | +// schema += `model ${model.name} { |
| 22 | +// id Int @id @default(autoincrement()) |
| 23 | +// ` |
| 24 | + |
| 25 | +// for (const fieldName in model.fields) { |
| 26 | +// const field = model.fields[fieldName] |
| 27 | + |
| 28 | +// let columnSchema = ` ${fieldName} ${field.type}` |
| 29 | + |
| 30 | +// if (field.required) |
| 31 | +// columnSchema += ' @required' |
| 32 | + |
| 33 | +// if (field.unique) |
| 34 | +// columnSchema += ' @unique' |
| 35 | + |
| 36 | +// if (field.default) |
| 37 | +// columnSchema += ` @default(${field.default})` |
| 38 | + |
| 39 | +// columnSchema += '\n' |
| 40 | +// schema += columnSchema |
| 41 | +// } |
| 42 | + |
| 43 | +// if (model.hasOne) { |
| 44 | +// schema += ` ${model.hasOne} ${titleCase(model.hasOne)}?` |
| 45 | +// schema += ` @relation(fields: [${model.hasOne}Id], references: [id])\n` |
| 46 | +// schema += ` ${model.hasOne}Id Int\n` |
| 47 | +// } |
| 48 | + |
| 49 | +// if (model.belongsToMany) { |
| 50 | +// schema += ` ${model.belongsToMany} ${titleCase(model.belongsToMany)}` |
| 51 | +// schema += ` @relation(fields: [${model.belongsToMany}Id], references: [id])\n` |
| 52 | +// schema += ` ${model.belongsToMany}Id Int\n` |
| 53 | +// } |
| 54 | + |
| 55 | +// if (model.hasMany) { |
| 56 | +// schema += ` ${model.hasMany} ${titleCase(model.hasMany)}[]` |
| 57 | +// schema += ` @relation(fields: [id], references: [${model.name?.toLowerCase()}Id])\n` |
| 58 | +// } |
| 59 | + |
| 60 | +// if (model.hasThrough) { |
| 61 | +// schema += ` ${model.hasThrough.model} ${titleCase(model.hasThrough.model)}[]` |
| 62 | +// schema += ` @relation("${model.hasThrough.using}")` |
| 63 | +// schema += ` ${model.hasThrough.using} ${titleCase(model.hasThrough.using)}` |
| 64 | +// schema += ` @relation("${model.hasThrough.through}")` |
| 65 | +// schema += ` ${model.hasThrough.through} ${titleCase(model.hasThrough.through)}` |
| 66 | +// schema += ` @relation(fields: [${model.hasThrough.using}], references: [id])\n` |
| 67 | +// } |
| 68 | + |
| 69 | +// schema += ' createdAt DateTime @default(now())\n' |
| 70 | +// schema += ' updatedAt DateTime @updatedAt()\n' |
| 71 | +// schema += '}\n\n' |
| 72 | + |
| 73 | +// if (model.hasMany) { |
| 74 | +// schema += `model ${titleCase(model.hasMany)} { |
| 75 | +// id Int @id @default(autoincrement()) |
| 76 | +// createdAt DateTime @default(now()) |
| 77 | +// updatedAt DateTime @updatedAt() |
| 78 | +// ${model.name?.toLowerCase()}Id Int |
| 79 | +// ${model.name?.toLowerCase()} ${titleCase(model.name)} |
| 80 | +// @relation(fields: [${model.name?.toLowerCase()}Id], references: [id]) |
| 81 | +// }\n\n` |
| 82 | +// } |
| 83 | + |
| 84 | +// if (model.hasOne || model.belongsToMany) { |
| 85 | +// const relatedModelName = model.hasOne || model.belongsToMany |
| 86 | +// schema += `model ${titleCase(relatedModelName)} { |
| 87 | +// id Int @id @default(autoincrement()) |
| 88 | +// createdAt DateTime @default(now()) |
| 89 | +// updatedAt DateTime @updatedAt() |
| 90 | +// ${model.name?.toLowerCase()} ${titleCase(model.name)}? |
| 91 | +// ${model.name?.toLowerCase()}Id Int? |
| 92 | +// @unique |
| 93 | +// }\n\n` |
| 94 | +// } |
| 95 | +// } |
| 96 | + |
| 97 | +// if (!fs.existsSync(frameworkPath('database'))) |
| 98 | +// fs.mkdirSync(frameworkPath('database')) |
| 99 | + |
| 100 | +// fs.writeFile(path, schema, (err) => { |
| 101 | +// if (err) |
| 102 | +// console.error(`Error writing schema file: ${err.message}`) |
| 103 | +// else |
| 104 | +// // eslint-disable-next-line no-console |
| 105 | +// console.log(`Schema file generated successfully at path: ${path}`) |
| 106 | +// }) |
| 107 | +// } |
| 108 | + |
| 109 | +// function readModelsFromFolder(folderPath: string): Promise<Model[]> { |
| 110 | +// return new Promise((resolve, reject) => { |
| 111 | +// const models: Model[] = [] |
| 112 | + |
| 113 | +// fs.readdir(folderPath, (err, files) => { |
| 114 | +// if (err) |
| 115 | +// reject(err) |
| 116 | + |
| 117 | +// const promises = files |
| 118 | +// .filter(file => file.endsWith('.ts')) |
| 119 | +// .map((file) => { |
| 120 | +// const filePath = `${folderPath}/${file}` |
| 121 | + |
| 122 | +// return import(filePath).then((data) => { |
| 123 | +// models.push({ |
| 124 | +// name: data.default.name, |
| 125 | +// fields: data.default.fields, |
| 126 | +// }) |
| 127 | +// }) |
| 128 | +// }) |
| 129 | + |
| 130 | +// Promise.all(promises) |
| 131 | +// .then(() => resolve(models)) |
| 132 | +// .catch(err => reject(err)) |
| 133 | +// }) |
| 134 | +// }) |
| 135 | +// } |
| 136 | + |
| 137 | +// async function migrate(path: string, options: SchemaOptions): Promise<void> { |
| 138 | +// const models = await readModelsFromFolder(projectPath('app/models')) |
| 139 | + |
| 140 | +// generatePrismaSchema(models, path, options) |
| 141 | +// } |
| 142 | + |
| 143 | +// export { |
| 144 | +// migrate, |
| 145 | +// } |
| 146 | + |
| 147 | +export {} |
0 commit comments