Files
metabuilder/dbal/shared/tools/codegen/gen_prisma_schema.js

171 lines
5.8 KiB
JavaScript

#!/usr/bin/env node
/* eslint-disable no-console */
const fs = require('fs')
const path = require('path')
const header = `datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}`
const models = [
{
name: 'User',
fields: [
{ name: 'id', type: 'String', attributes: ['@id'] },
{ name: 'username', type: 'String', attributes: ['@unique'] },
{ name: 'email', type: 'String', attributes: ['@unique'] },
{ name: 'role', type: 'String' },
{ name: 'profilePicture', type: 'String?' },
{ name: 'bio', type: 'String?' },
{ name: 'createdAt', type: 'BigInt' },
{ name: 'tenantId', type: 'String?' },
{ name: 'isInstanceOwner', type: 'Boolean', attributes: ['@default(false)'] },
{ name: 'passwordChangeTimestamp', type: 'BigInt?' },
{ name: 'firstLogin', type: 'Boolean', attributes: ['@default(false)'] },
],
blockAttributes: ['@@index([tenantId])', '@@index([role])'],
},
{
name: 'Credential',
fields: [
{ name: 'username', type: 'String', attributes: ['@id'] },
{ name: 'passwordHash', type: 'String' },
],
},
{
name: 'Session',
fields: [
{ name: 'id', type: 'String', attributes: ['@id'] },
{ name: 'userId', type: 'String' },
{ name: 'token', type: 'String', attributes: ['@unique'] },
{ name: 'expiresAt', type: 'BigInt' },
{ name: 'createdAt', type: 'BigInt' },
{ name: 'lastActivity', type: 'BigInt' },
{ name: 'ipAddress', type: 'String?' },
{ name: 'userAgent', type: 'String?' },
],
blockAttributes: ['@@index([userId])', '@@index([expiresAt])', '@@index([token])'],
},
{
name: 'PageConfig',
fields: [
{ name: 'id', type: 'String', attributes: ['@id'] },
{ name: 'tenantId', type: 'String?' },
{ name: 'packageId', type: 'String?' },
{ name: 'path', type: 'String', comment: '// Route pattern: /media/jobs, /forum/:id' },
{ name: 'title', type: 'String' },
{ name: 'description', type: 'String?' },
{ name: 'icon', type: 'String?' },
{ name: 'component', type: 'String?' },
{ name: 'componentTree', type: 'String', comment: '// JSON: full component tree' },
{ name: 'level', type: 'Int' },
{ name: 'requiresAuth', type: 'Boolean' },
{ name: 'requiredRole', type: 'String?' },
{ name: 'parentPath', type: 'String?' },
{ name: 'sortOrder', type: 'Int', attributes: ['@default(0)'] },
{ name: 'isPublished', type: 'Boolean', attributes: ['@default(true)'] },
{ name: 'params', type: 'String?' },
{ name: 'meta', type: 'String?' },
{ name: 'createdAt', type: 'BigInt?' },
{ name: 'updatedAt', type: 'BigInt?' },
],
blockAttributes: [
'@@unique([tenantId, path])',
'@@index([tenantId])',
'@@index([packageId])',
'@@index([level])',
'@@index([parentPath])',
],
},
{
name: 'ComponentNode',
fields: [
{ name: 'id', type: 'String', attributes: ['@id'] },
{ name: 'type', type: 'String' },
{ name: 'parentId', type: 'String?' },
{ name: 'childIds', type: 'String', comment: '// JSON: string[]' },
{ name: 'order', type: 'Int' },
{ name: 'pageId', type: 'String' },
],
blockAttributes: ['@@index([pageId])', '@@index([parentId])'],
},
{
name: 'ComponentConfig',
fields: [
{ name: 'id', type: 'String', attributes: ['@id'] },
{ name: 'componentId', type: 'String' },
{ name: 'props', type: 'String', comment: '// JSON' },
{ name: 'styles', type: 'String', comment: '// JSON' },
{ name: 'events', type: 'String', comment: '// JSON' },
{ name: 'conditionalRendering', type: 'String?' },
],
blockAttributes: ['@@index([componentId])'],
},
{
name: 'Workflow',
fields: [
{ name: 'id', type: 'String', attributes: ['@id'] },
{ name: 'tenantId', type: 'String?' },
{ name: 'name', type: 'String' },
{ name: 'description', type: 'String?' },
{ name: 'nodes', type: 'String', comment: '// JSON: WorkflowNode[]' },
{ name: 'edges', type: 'String', comment: '// JSON: WorkflowEdge[]' },
{ name: 'enabled', type: 'Boolean' },
{ name: 'version', type: 'Int', attributes: ['@default(1)'] },
{ name: 'createdAt', type: 'BigInt?' },
{ name: 'updatedAt', type: 'BigInt?' },
{ name: 'createdBy', type: 'String?' },
],
blockAttributes: ['@@index([tenantId])', '@@index([enabled])'],
},
{
name: 'InstalledPackage',
fields: [
{ name: 'packageId', type: 'String', attributes: ['@id'] },
{ name: 'tenantId', type: 'String?' },
{ name: 'installedAt', type: 'BigInt' },
{ name: 'version', type: 'String' },
{ name: 'enabled', type: 'Boolean' },
{ name: 'config', type: 'String?' },
],
blockAttributes: ['@@index([tenantId])'],
},
{
name: 'PackageData',
fields: [
{ name: 'packageId', type: 'String', attributes: ['@id'] },
{ name: 'data', type: 'String', comment: '// JSON' },
],
},
]
const renderField = (field) => {
const attrs = field.attributes ? ` ${field.attributes.join(' ')}` : ''
const comment = field.comment ? ` ${field.comment}` : ''
return ` ${field.name} ${field.type}${attrs}${comment}`
}
const renderModel = (model) => {
const lines = [`model ${model.name} {`]
model.fields.forEach((field) => {
lines.push(renderField(field))
})
if (model.blockAttributes) {
model.blockAttributes.forEach((attr) => {
lines.push(` ${attr}`)
})
}
lines.push('}')
return lines.join('\n')
}
const schema = [header, models.map(renderModel).join('\n\n')].join('\n\n')
const outputPath = path.resolve(__dirname, '../../../../prisma/schema.prisma')
fs.writeFileSync(outputPath, schema + '\n', 'utf8')
console.log(`Prisma schema written to ${outputPath}`)