@zenith-open/zenithcms-db-mongodb 0.1.0 → 1.0.0-beta.1
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/LICENSE +21 -0
- package/README.md +31 -0
- package/dist/MongooseAdapter.d.ts +8 -19
- package/dist/MongooseAdapter.js +254 -220
- package/dist/MongooseAdapter.js.map +1 -1
- package/dist/model-factory.js +3 -0
- package/dist/model-factory.js.map +1 -1
- package/package.json +26 -23
- package/eslint.config.mjs +0 -26
- package/src/MongooseAdapter.ts +0 -643
- package/src/index.ts +0 -2
- package/src/model-factory.ts +0 -179
- package/tsconfig.eslint.json +0 -8
- package/tsconfig.json +0 -11
package/src/model-factory.ts
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import mongoose, { Schema, Model } from 'mongoose'
|
|
2
|
-
import { CollectionConfig, FieldConfig } from '@zenith-open/zenithcms-types'
|
|
3
|
-
|
|
4
|
-
const models: Record<string, Model<unknown>> = {}
|
|
5
|
-
|
|
6
|
-
function mapFieldToMongoose(field: any): unknown {
|
|
7
|
-
let type: unknown
|
|
8
|
-
|
|
9
|
-
switch (field.type) {
|
|
10
|
-
case 'text':
|
|
11
|
-
case 'email':
|
|
12
|
-
case 'textarea':
|
|
13
|
-
case 'select':
|
|
14
|
-
type = String
|
|
15
|
-
break
|
|
16
|
-
case 'richtext':
|
|
17
|
-
type = field.format === 'json' ? Schema.Types.Mixed : String
|
|
18
|
-
break
|
|
19
|
-
case 'number':
|
|
20
|
-
type = Number
|
|
21
|
-
break
|
|
22
|
-
case 'boolean':
|
|
23
|
-
case 'checkbox':
|
|
24
|
-
type = Boolean
|
|
25
|
-
break
|
|
26
|
-
case 'date':
|
|
27
|
-
type = Date
|
|
28
|
-
break
|
|
29
|
-
case 'json':
|
|
30
|
-
type = Schema.Types.Mixed
|
|
31
|
-
break
|
|
32
|
-
case 'media':
|
|
33
|
-
type = new Schema(
|
|
34
|
-
{
|
|
35
|
-
url: String,
|
|
36
|
-
id: String,
|
|
37
|
-
alt: String,
|
|
38
|
-
width: Number,
|
|
39
|
-
height: Number,
|
|
40
|
-
},
|
|
41
|
-
{ _id: false }
|
|
42
|
-
)
|
|
43
|
-
break
|
|
44
|
-
case 'relation':
|
|
45
|
-
// Use String instead of ObjectId to support database-agnostic string IDs and UUIDs
|
|
46
|
-
type = String
|
|
47
|
-
break
|
|
48
|
-
case 'array':
|
|
49
|
-
if (field.fields) {
|
|
50
|
-
type = [new Schema(generateSchemaFields(field.fields), { _id: false })]
|
|
51
|
-
} else {
|
|
52
|
-
type = [Schema.Types.Mixed]
|
|
53
|
-
}
|
|
54
|
-
break
|
|
55
|
-
case 'group':
|
|
56
|
-
if (field.fields) {
|
|
57
|
-
type = new Schema(generateSchemaFields(field.fields), { _id: false })
|
|
58
|
-
} else {
|
|
59
|
-
type = Schema.Types.Mixed
|
|
60
|
-
}
|
|
61
|
-
break
|
|
62
|
-
case 'blocks':
|
|
63
|
-
if (field.blocks && field.blocks.length > 0) {
|
|
64
|
-
// Blocks are stored as objects with a blockType discriminator
|
|
65
|
-
type = [
|
|
66
|
-
new Schema(
|
|
67
|
-
{
|
|
68
|
-
blockType: { type: String, index: true },
|
|
69
|
-
},
|
|
70
|
-
{ strict: false, _id: false }
|
|
71
|
-
),
|
|
72
|
-
]
|
|
73
|
-
} else {
|
|
74
|
-
type = [Schema.Types.Mixed]
|
|
75
|
-
}
|
|
76
|
-
break
|
|
77
|
-
case 'code':
|
|
78
|
-
case 'radio':
|
|
79
|
-
type = String
|
|
80
|
-
break
|
|
81
|
-
case 'collapsible':
|
|
82
|
-
if (field.fields) {
|
|
83
|
-
type = new Schema(generateSchemaFields(field.fields), { _id: false })
|
|
84
|
-
} else {
|
|
85
|
-
type = Schema.Types.Mixed
|
|
86
|
-
}
|
|
87
|
-
break
|
|
88
|
-
case 'join':
|
|
89
|
-
// Virtual read-only field — stored as array of Mixed
|
|
90
|
-
type = [Schema.Types.Mixed]
|
|
91
|
-
break
|
|
92
|
-
case 'point':
|
|
93
|
-
// Stored as [lng, lat] tuple
|
|
94
|
-
type = [Number]
|
|
95
|
-
break
|
|
96
|
-
case 'row':
|
|
97
|
-
case 'ui':
|
|
98
|
-
// Layout/presentational fields — no data stored
|
|
99
|
-
return undefined as any
|
|
100
|
-
default:
|
|
101
|
-
type = Schema.Types.Mixed
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (field.hasMany && field.type !== 'array') {
|
|
105
|
-
type = [type]
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Handle i18n
|
|
109
|
-
if (field.localized) {
|
|
110
|
-
type = new Schema(
|
|
111
|
-
{
|
|
112
|
-
// We use a Mixed object to store any locale keys (en, es, fr, etc.)
|
|
113
|
-
},
|
|
114
|
-
{ strict: false, _id: false }
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const mongooseField: any = {
|
|
119
|
-
type,
|
|
120
|
-
required: field.required || false,
|
|
121
|
-
default: field.defaultValue,
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (field.unique !== undefined) mongooseField.unique = field.unique;
|
|
125
|
-
if (field.index !== undefined) mongooseField.index = field.index;
|
|
126
|
-
|
|
127
|
-
return mongooseField;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function generateSchemaFields(fields: FieldConfig[]) {
|
|
131
|
-
const schemaFields: Record<string, unknown> = {}
|
|
132
|
-
fields.forEach((field) => {
|
|
133
|
-
// Skip layout/presentational fields that produce no schema mapping
|
|
134
|
-
if (field.type === 'row' || field.type === 'ui') return
|
|
135
|
-
schemaFields[field.name] = mapFieldToMongoose(field)
|
|
136
|
-
})
|
|
137
|
-
return schemaFields
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export function getModelForCollection(config: CollectionConfig): Model<unknown> {
|
|
141
|
-
if (models[config.slug]) return models[config.slug]
|
|
142
|
-
|
|
143
|
-
const schemaFields = generateSchemaFields(config.fields)
|
|
144
|
-
|
|
145
|
-
const schema = new Schema(schemaFields, {
|
|
146
|
-
timestamps: config.timestamps !== false,
|
|
147
|
-
collection: config.slug,
|
|
148
|
-
strict: false, // Allow extra dynamic fields
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
// Global meta fields
|
|
152
|
-
schema.add({
|
|
153
|
-
siteId: { type: String, index: true },
|
|
154
|
-
isFocused: { type: Boolean, default: false },
|
|
155
|
-
_status: {
|
|
156
|
-
type: String,
|
|
157
|
-
enum: ['draft', 'published'],
|
|
158
|
-
default: config.drafts ? 'draft' : 'published',
|
|
159
|
-
},
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
// Scheduling support
|
|
163
|
-
if (config.scheduling) {
|
|
164
|
-
schema.add({
|
|
165
|
-
scheduledAt: { type: Date, index: true },
|
|
166
|
-
})
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Soft Delete support
|
|
170
|
-
if (config.softDelete) {
|
|
171
|
-
schema.add({
|
|
172
|
-
deletedAt: { type: Date, default: null, index: true },
|
|
173
|
-
})
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const model = mongoose.models[config.slug] || mongoose.model(config.slug, schema)
|
|
177
|
-
models[config.slug] = model
|
|
178
|
-
return model
|
|
179
|
-
}
|
package/tsconfig.eslint.json
DELETED