@forge-cms/runtime 0.0.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 +14 -0
- package/dist/access.d.ts +30 -0
- package/dist/access.d.ts.map +1 -0
- package/dist/access.js +64 -0
- package/dist/access.js.map +1 -0
- package/dist/config.d.ts +20 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +16 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +2 -0
- package/dist/context.js.map +1 -0
- package/dist/defaults.d.ts +20 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +73 -0
- package/dist/defaults.js.map +1 -0
- package/dist/describe.d.ts +54 -0
- package/dist/describe.d.ts.map +1 -0
- package/dist/describe.js +88 -0
- package/dist/describe.js.map +1 -0
- package/dist/errors.d.ts +39 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +68 -0
- package/dist/errors.js.map +1 -0
- package/dist/field-access.d.ts +14 -0
- package/dist/field-access.d.ts.map +1 -0
- package/dist/field-access.js +49 -0
- package/dist/field-access.js.map +1 -0
- package/dist/files.d.ts +24 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +46 -0
- package/dist/files.js.map +1 -0
- package/dist/globals.d.ts +24 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +161 -0
- package/dist/globals.js.map +1 -0
- package/dist/handlers.d.ts +37 -0
- package/dist/handlers.d.ts.map +1 -0
- package/dist/handlers.js +611 -0
- package/dist/handlers.js.map +1 -0
- package/dist/hooks.d.ts +60 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +193 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/localization.d.ts +52 -0
- package/dist/localization.d.ts.map +1 -0
- package/dist/localization.js +163 -0
- package/dist/localization.js.map +1 -0
- package/dist/operations.d.ts +70 -0
- package/dist/operations.d.ts.map +1 -0
- package/dist/operations.js +402 -0
- package/dist/operations.js.map +1 -0
- package/dist/populate.d.ts +6 -0
- package/dist/populate.d.ts.map +1 -0
- package/dist/populate.js +65 -0
- package/dist/populate.js.map +1 -0
- package/dist/relation-integrity.d.ts +39 -0
- package/dist/relation-integrity.d.ts.map +1 -0
- package/dist/relation-integrity.js +150 -0
- package/dist/relation-integrity.js.map +1 -0
- package/dist/runtime.d.ts +61 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +155 -0
- package/dist/runtime.js.map +1 -0
- package/dist/versions.d.ts +51 -0
- package/dist/versions.d.ts.map +1 -0
- package/dist/versions.js +122 -0
- package/dist/versions.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { InvalidInputError } from './errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Relation integrity utilities for handling cascade, restrict, and set-null on delete.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Finds all relation fields in a collection that reference a target collection.
|
|
7
|
+
*/
|
|
8
|
+
export function findRelationFields(collection, targetCollection) {
|
|
9
|
+
const relations = [];
|
|
10
|
+
for (const [fieldName, field] of Object.entries(collection.fields)) {
|
|
11
|
+
if (field.kind === 'relation') {
|
|
12
|
+
const options = field.options;
|
|
13
|
+
if (options.collection === targetCollection) {
|
|
14
|
+
relations.push({ fieldName, options });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return relations;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Finds all documents in a collection that reference a specific document ID.
|
|
22
|
+
*/
|
|
23
|
+
export async function findReferencingDocuments(ctx, collection, fieldName, documentId, many) {
|
|
24
|
+
if (many) {
|
|
25
|
+
// For many relations, we need to check if the ID is in the array
|
|
26
|
+
const allDocs = await ctx.adapters.database.findMany({ collection: collection.slug });
|
|
27
|
+
return allDocs.filter((doc) => {
|
|
28
|
+
const value = doc[fieldName];
|
|
29
|
+
return Array.isArray(value) && value.includes(documentId);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// For single relations, use where clause
|
|
34
|
+
return ctx.adapters.database.findMany({
|
|
35
|
+
collection: collection.slug,
|
|
36
|
+
where: { [fieldName]: documentId }
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Checks if a document can be deleted based on relation constraints.
|
|
42
|
+
* Throws InvalidInputError if deletion is restricted.
|
|
43
|
+
*/
|
|
44
|
+
export async function checkDeleteRestrictions(ctx, targetCollection, documentId) {
|
|
45
|
+
// Check all collections for relations to this collection
|
|
46
|
+
for (const collection of ctx.getCollections()) {
|
|
47
|
+
if (collection.slug === targetCollection.slug)
|
|
48
|
+
continue;
|
|
49
|
+
const relations = findRelationFields(collection, targetCollection.slug);
|
|
50
|
+
for (const { fieldName, options } of relations) {
|
|
51
|
+
const onDelete = options.onDelete ?? 'restrict';
|
|
52
|
+
if (onDelete === 'restrict') {
|
|
53
|
+
const referencing = await findReferencingDocuments(ctx, collection, fieldName, documentId, options.many ?? false);
|
|
54
|
+
if (referencing.length > 0) {
|
|
55
|
+
throw new InvalidInputError(`Cannot delete document '${documentId}' from '${targetCollection.slug}': ` +
|
|
56
|
+
`referenced by ${referencing.length} document(s) in '${collection.slug}'`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Handles cascade delete: deletes all documents that reference the deleted document.
|
|
64
|
+
*/
|
|
65
|
+
export async function handleCascadeDelete(ctx, targetCollection, documentId) {
|
|
66
|
+
for (const collection of ctx.getCollections()) {
|
|
67
|
+
if (collection.slug === targetCollection.slug)
|
|
68
|
+
continue;
|
|
69
|
+
const relations = findRelationFields(collection, targetCollection.slug);
|
|
70
|
+
for (const { fieldName, options } of relations) {
|
|
71
|
+
const onDelete = options.onDelete ?? 'restrict';
|
|
72
|
+
if (onDelete === 'cascade') {
|
|
73
|
+
const referencing = await findReferencingDocuments(ctx, collection, fieldName, documentId, options.many ?? false);
|
|
74
|
+
// Delete all referencing documents
|
|
75
|
+
for (const doc of referencing) {
|
|
76
|
+
await ctx.adapters.database.delete(collection.slug, doc.id);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Handles set-null: sets relation fields to null in all referencing documents.
|
|
84
|
+
*/
|
|
85
|
+
export async function handleSetNullOnDelete(ctx, targetCollection, documentId) {
|
|
86
|
+
for (const collection of ctx.getCollections()) {
|
|
87
|
+
if (collection.slug === targetCollection.slug)
|
|
88
|
+
continue;
|
|
89
|
+
const relations = findRelationFields(collection, targetCollection.slug);
|
|
90
|
+
for (const { fieldName, options } of relations) {
|
|
91
|
+
const onDelete = options.onDelete ?? 'restrict';
|
|
92
|
+
if (onDelete === 'set-null') {
|
|
93
|
+
const referencing = await findReferencingDocuments(ctx, collection, fieldName, documentId, options.many ?? false);
|
|
94
|
+
// Update each referencing document
|
|
95
|
+
for (const doc of referencing) {
|
|
96
|
+
if (options.many) {
|
|
97
|
+
// Remove the ID from the array
|
|
98
|
+
const currentValue = doc[fieldName];
|
|
99
|
+
const newValue = currentValue.filter((id) => id !== documentId);
|
|
100
|
+
await ctx.adapters.database.update(collection.slug, doc.id, {
|
|
101
|
+
[fieldName]: newValue
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// Set to null
|
|
106
|
+
await ctx.adapters.database.update(collection.slug, doc.id, {
|
|
107
|
+
[fieldName]: null
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Finds orphaned documents: documents with relation fields pointing to non-existent documents.
|
|
117
|
+
*/
|
|
118
|
+
export async function findOrphanedDocuments(ctx, collection) {
|
|
119
|
+
const orphans = [];
|
|
120
|
+
const allDocs = await ctx.adapters.database.findMany({ collection: collection.slug });
|
|
121
|
+
for (const [fieldName, field] of Object.entries(collection.fields)) {
|
|
122
|
+
if (field.kind !== 'relation')
|
|
123
|
+
continue;
|
|
124
|
+
const options = field.options;
|
|
125
|
+
const targetCollection = options.collection;
|
|
126
|
+
for (const doc of allDocs) {
|
|
127
|
+
const value = doc[fieldName];
|
|
128
|
+
if (options.many && Array.isArray(value)) {
|
|
129
|
+
// Check each ID in the array
|
|
130
|
+
for (const id of value) {
|
|
131
|
+
if (typeof id === 'string') {
|
|
132
|
+
const target = await ctx.adapters.database.findById(targetCollection, id);
|
|
133
|
+
if (!target) {
|
|
134
|
+
orphans.push({ document: doc, fieldName, missingId: id });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else if (typeof value === 'string') {
|
|
140
|
+
// Check single relation
|
|
141
|
+
const target = await ctx.adapters.database.findById(targetCollection, value);
|
|
142
|
+
if (!target) {
|
|
143
|
+
orphans.push({ document: doc, fieldName, missingId: value });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return orphans;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=relation-integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-integrity.js","sourceRoot":"","sources":["../src/relation-integrity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { ForgeCmsConfig, AdapterSet } from './config.js';
|
|
2
|
+
import type { CollectionDefinition, GlobalDefinition } from '@forge-cms/core';
|
|
3
|
+
import type { DatabaseRecord } from '@forge-cms/db';
|
|
4
|
+
import type { OperationContext } from './context.js';
|
|
5
|
+
import type { CountArgs, CreateArgs, DeleteArgs, FindArgs, FindByIDArgs, PaginatedDocs, UpdateArgs } from './operations.js';
|
|
6
|
+
import type { GetGlobalArgs, UpdateGlobalArgs } from './globals.js';
|
|
7
|
+
import type { ListVersionsArgs, GetVersionArgs, RestoreVersionArgs, CreateVersionArgs } from './versions.js';
|
|
8
|
+
import type { Version } from '@forge-cms/core';
|
|
9
|
+
/**
|
|
10
|
+
* The CMS instance: collections bound to adapters, plus the **Local API** — `find`, `findByID`,
|
|
11
|
+
* `create`, `update`, `delete`, `count`, `getGlobal`, `updateGlobal`.
|
|
12
|
+
*
|
|
13
|
+
* The Local API is the primary way to use ForgeCMS from server code (an Analog.js `.server.ts`
|
|
14
|
+
* route, a Nitro handler, a seed script). It runs the full pipeline — hooks, access, drafts,
|
|
15
|
+
* relation population, validation — with no HTTP hop and no `Request` to fabricate. The HTTP
|
|
16
|
+
* handlers in `handlers.ts` are a thin transport layer over these same methods.
|
|
17
|
+
*
|
|
18
|
+
* Access control is **skipped by default** here (`overrideAccess` defaults to `true`), because a
|
|
19
|
+
* direct call comes from trusted server code. Pass `overrideAccess: false` together with a `user` to
|
|
20
|
+
* run an operation as that user — which is exactly what the HTTP layer does.
|
|
21
|
+
*/
|
|
22
|
+
export declare class ForgeCmsRuntime<TEnv = unknown> implements OperationContext {
|
|
23
|
+
readonly config: ForgeCmsConfig<TEnv>;
|
|
24
|
+
readonly adapters: AdapterSet;
|
|
25
|
+
constructor(config: ForgeCmsConfig<TEnv>);
|
|
26
|
+
/** Initialise all adapters with the runtime environment */
|
|
27
|
+
init(): this;
|
|
28
|
+
/** Sync database schema for all registered collections and globals */
|
|
29
|
+
syncSchema(): Promise<void>;
|
|
30
|
+
/** Find a collection definition by slug */
|
|
31
|
+
getCollection(slug: string): CollectionDefinition | undefined;
|
|
32
|
+
/** Get all registered collection definitions */
|
|
33
|
+
getCollections(): readonly CollectionDefinition[];
|
|
34
|
+
/** Find a global definition by slug */
|
|
35
|
+
getGlobal(slug: string): GlobalDefinition | undefined;
|
|
36
|
+
/** Get all registered global definitions */
|
|
37
|
+
getGlobals(): readonly GlobalDefinition[];
|
|
38
|
+
find(args: FindArgs): Promise<PaginatedDocs>;
|
|
39
|
+
findByID(args: FindByIDArgs): Promise<DatabaseRecord>;
|
|
40
|
+
count(args: CountArgs): Promise<number>;
|
|
41
|
+
create(args: CreateArgs): Promise<DatabaseRecord>;
|
|
42
|
+
update(args: UpdateArgs): Promise<DatabaseRecord>;
|
|
43
|
+
delete(args: DeleteArgs): Promise<DatabaseRecord>;
|
|
44
|
+
getGlobalDocument(args: GetGlobalArgs): Promise<DatabaseRecord | null>;
|
|
45
|
+
updateGlobalDocument(args: UpdateGlobalArgs): Promise<DatabaseRecord>;
|
|
46
|
+
listVersions(args: ListVersionsArgs): Promise<Version[]>;
|
|
47
|
+
getVersion(args: GetVersionArgs): Promise<Version>;
|
|
48
|
+
restoreVersion(args: RestoreVersionArgs): Promise<DatabaseRecord>;
|
|
49
|
+
createVersion(args: CreateVersionArgs): Promise<Version>;
|
|
50
|
+
/**
|
|
51
|
+
* Generates a preview of a document by merging stored data with unsaved changes.
|
|
52
|
+
* If id is provided, merges changes with existing document. Otherwise, previews new document.
|
|
53
|
+
*/
|
|
54
|
+
preview(args: {
|
|
55
|
+
collection: string;
|
|
56
|
+
data: Record<string, unknown>;
|
|
57
|
+
id?: string;
|
|
58
|
+
depth?: 0 | 1;
|
|
59
|
+
}): Promise<DatabaseRecord>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAY,MAAM,iBAAiB,CAAC;AAExF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EACV,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,UAAU,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAe,CAAC,IAAI,GAAG,OAAO,CAAE,YAAW,gBAAgB;IACtE,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;gBAElB,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC;IAKxC,2DAA2D;IAC3D,IAAI,IAAI,IAAI;IAQZ,sEAAsE;IAChE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAuCjC,2CAA2C;IAC3C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAI7D,gDAAgD;IAChD,cAAc,IAAI,SAAS,oBAAoB,EAAE;IAIjD,uCAAuC;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAIrD,4CAA4C;IAC5C,UAAU,IAAI,SAAS,gBAAgB,EAAE;IAMzC,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IAI5C,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC;IAIrD,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAIvC,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC;IAIjD,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC;IAIjD,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC;IAMjD,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAItE,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;IAMrE,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAIxD,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlD,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC;IAIjE,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAMxD;;;OAGG;IACG,OAAO,CAAC,IAAI,EAAE;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;KACf,GAAG,OAAO,CAAC,cAAc,CAAC;CAqC5B"}
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { defineField } from '@forge-cms/core';
|
|
2
|
+
import * as operations from './operations.js';
|
|
3
|
+
import * as globalOps from './globals.js';
|
|
4
|
+
import * as versionOps from './versions.js';
|
|
5
|
+
/**
|
|
6
|
+
* The CMS instance: collections bound to adapters, plus the **Local API** — `find`, `findByID`,
|
|
7
|
+
* `create`, `update`, `delete`, `count`, `getGlobal`, `updateGlobal`.
|
|
8
|
+
*
|
|
9
|
+
* The Local API is the primary way to use ForgeCMS from server code (an Analog.js `.server.ts`
|
|
10
|
+
* route, a Nitro handler, a seed script). It runs the full pipeline — hooks, access, drafts,
|
|
11
|
+
* relation population, validation — with no HTTP hop and no `Request` to fabricate. The HTTP
|
|
12
|
+
* handlers in `handlers.ts` are a thin transport layer over these same methods.
|
|
13
|
+
*
|
|
14
|
+
* Access control is **skipped by default** here (`overrideAccess` defaults to `true`), because a
|
|
15
|
+
* direct call comes from trusted server code. Pass `overrideAccess: false` together with a `user` to
|
|
16
|
+
* run an operation as that user — which is exactly what the HTTP layer does.
|
|
17
|
+
*/
|
|
18
|
+
export class ForgeCmsRuntime {
|
|
19
|
+
config;
|
|
20
|
+
adapters;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.config = config;
|
|
23
|
+
this.adapters = config.adapters;
|
|
24
|
+
}
|
|
25
|
+
/** Initialise all adapters with the runtime environment */
|
|
26
|
+
init() {
|
|
27
|
+
const env = this.config.env;
|
|
28
|
+
this.adapters.database.init(env);
|
|
29
|
+
this.adapters.auth.init(env);
|
|
30
|
+
this.adapters.storage.init(env);
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
/** Sync database schema for all registered collections and globals */
|
|
34
|
+
async syncSchema() {
|
|
35
|
+
await this.adapters.database.syncSchema(this.config.collections);
|
|
36
|
+
for (const global of this.config.globals ?? []) {
|
|
37
|
+
await this.adapters.database.syncSchema([
|
|
38
|
+
{
|
|
39
|
+
slug: `_global_${global.slug}`,
|
|
40
|
+
fields: global.fields,
|
|
41
|
+
...(global.drafts === true && { drafts: true })
|
|
42
|
+
}
|
|
43
|
+
]);
|
|
44
|
+
}
|
|
45
|
+
// Create version tables for collections with versions enabled
|
|
46
|
+
for (const collection of this.config.collections) {
|
|
47
|
+
if (collection.versions === true ||
|
|
48
|
+
(typeof collection.versions === 'object' && collection.versions !== null)) {
|
|
49
|
+
const versionFields = {
|
|
50
|
+
documentId: defineField.text({ required: true }),
|
|
51
|
+
versionNumber: defineField.number({ required: true }),
|
|
52
|
+
data: defineField.json({ required: true }),
|
|
53
|
+
createdAt: defineField.date({ required: true }),
|
|
54
|
+
createdBy: defineField.text(),
|
|
55
|
+
autosave: defineField.boolean(),
|
|
56
|
+
label: defineField.text()
|
|
57
|
+
};
|
|
58
|
+
await this.adapters.database.syncSchema([
|
|
59
|
+
{
|
|
60
|
+
slug: `_versions_${collection.slug}`,
|
|
61
|
+
fields: versionFields
|
|
62
|
+
}
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Find a collection definition by slug */
|
|
68
|
+
getCollection(slug) {
|
|
69
|
+
return this.config.collections.find((c) => c.slug === slug);
|
|
70
|
+
}
|
|
71
|
+
/** Get all registered collection definitions */
|
|
72
|
+
getCollections() {
|
|
73
|
+
return this.config.collections;
|
|
74
|
+
}
|
|
75
|
+
/** Find a global definition by slug */
|
|
76
|
+
getGlobal(slug) {
|
|
77
|
+
return this.config.globals?.find((g) => g.slug === slug);
|
|
78
|
+
}
|
|
79
|
+
/** Get all registered global definitions */
|
|
80
|
+
getGlobals() {
|
|
81
|
+
return this.config.globals ?? [];
|
|
82
|
+
}
|
|
83
|
+
// --- Local API ---------------------------------------------------------------------------
|
|
84
|
+
find(args) {
|
|
85
|
+
return operations.find(this, args);
|
|
86
|
+
}
|
|
87
|
+
findByID(args) {
|
|
88
|
+
return operations.findByID(this, args);
|
|
89
|
+
}
|
|
90
|
+
count(args) {
|
|
91
|
+
return operations.count(this, args);
|
|
92
|
+
}
|
|
93
|
+
create(args) {
|
|
94
|
+
return operations.create(this, args);
|
|
95
|
+
}
|
|
96
|
+
update(args) {
|
|
97
|
+
return operations.update(this, args);
|
|
98
|
+
}
|
|
99
|
+
delete(args) {
|
|
100
|
+
return operations.deleteDocument(this, args);
|
|
101
|
+
}
|
|
102
|
+
// --- Globals -----------------------------------------------------------------------------
|
|
103
|
+
getGlobalDocument(args) {
|
|
104
|
+
return globalOps.getGlobal(this, args);
|
|
105
|
+
}
|
|
106
|
+
updateGlobalDocument(args) {
|
|
107
|
+
return globalOps.updateGlobal(this, args);
|
|
108
|
+
}
|
|
109
|
+
// --- Versions ---------------------------------------------------------------------------
|
|
110
|
+
listVersions(args) {
|
|
111
|
+
return versionOps.listVersions(this, args);
|
|
112
|
+
}
|
|
113
|
+
getVersion(args) {
|
|
114
|
+
return versionOps.getVersion(this, args);
|
|
115
|
+
}
|
|
116
|
+
restoreVersion(args) {
|
|
117
|
+
return versionOps.restoreVersion(this, args);
|
|
118
|
+
}
|
|
119
|
+
createVersion(args) {
|
|
120
|
+
return versionOps.createVersion(this, args);
|
|
121
|
+
}
|
|
122
|
+
// --- Preview ----------------------------------------------------------------------------
|
|
123
|
+
/**
|
|
124
|
+
* Generates a preview of a document by merging stored data with unsaved changes.
|
|
125
|
+
* If id is provided, merges changes with existing document. Otherwise, previews new document.
|
|
126
|
+
*/
|
|
127
|
+
async preview(args) {
|
|
128
|
+
const collection = this.getCollection(args.collection);
|
|
129
|
+
if (!collection) {
|
|
130
|
+
throw new (await import('./errors.js')).NotFoundError(`Collection '${args.collection}' not found`);
|
|
131
|
+
}
|
|
132
|
+
let previewData;
|
|
133
|
+
let existing = null;
|
|
134
|
+
if (args.id) {
|
|
135
|
+
existing = await this.adapters.database.findById(args.collection, args.id);
|
|
136
|
+
if (!existing) {
|
|
137
|
+
throw new (await import('./errors.js')).NotFoundError(`Document '${args.id}' not found`);
|
|
138
|
+
}
|
|
139
|
+
previewData = { ...existing, ...args.data };
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
previewData = args.data;
|
|
143
|
+
}
|
|
144
|
+
// Apply field defaults and auto-slugs
|
|
145
|
+
const { applyFieldDefaults, applyAutoSlugs } = await import('./defaults.js');
|
|
146
|
+
previewData = applyAutoSlugs(collection, applyFieldDefaults(collection, previewData), existing ?? undefined);
|
|
147
|
+
// Populate relations if depth > 0
|
|
148
|
+
if (args.depth && args.depth > 0) {
|
|
149
|
+
const { populateRecord } = await import('./populate.js');
|
|
150
|
+
previewData = await populateRecord(previewData, collection, this);
|
|
151
|
+
}
|
|
152
|
+
return previewData;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { CmsUser, CollectionDefinition, Version } from '@forge-cms/core';
|
|
2
|
+
import type { DatabaseRecord } from '@forge-cms/db';
|
|
3
|
+
import type { OperationContext } from './context.js';
|
|
4
|
+
export interface ListVersionsArgs {
|
|
5
|
+
collection: string;
|
|
6
|
+
documentId: string;
|
|
7
|
+
user?: CmsUser | null;
|
|
8
|
+
overrideAccess?: boolean;
|
|
9
|
+
limit?: number;
|
|
10
|
+
offset?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface GetVersionArgs {
|
|
13
|
+
collection: string;
|
|
14
|
+
versionId: string;
|
|
15
|
+
user?: CmsUser | null;
|
|
16
|
+
overrideAccess?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface RestoreVersionArgs {
|
|
19
|
+
collection: string;
|
|
20
|
+
versionId: string;
|
|
21
|
+
user?: CmsUser | null;
|
|
22
|
+
overrideAccess?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface CreateVersionArgs {
|
|
25
|
+
collection: string;
|
|
26
|
+
documentId: string;
|
|
27
|
+
data: Record<string, unknown>;
|
|
28
|
+
user?: CmsUser | null;
|
|
29
|
+
autosave?: boolean;
|
|
30
|
+
label?: string;
|
|
31
|
+
}
|
|
32
|
+
declare function versionsEnabled(collection: CollectionDefinition): boolean;
|
|
33
|
+
declare function autosaveEnabled(collection: CollectionDefinition): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Lists all versions of a document, newest first.
|
|
36
|
+
*/
|
|
37
|
+
export declare function listVersions(ctx: OperationContext, args: ListVersionsArgs): Promise<Version[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Gets a specific version by id.
|
|
40
|
+
*/
|
|
41
|
+
export declare function getVersion(ctx: OperationContext, args: GetVersionArgs): Promise<Version>;
|
|
42
|
+
/**
|
|
43
|
+
* Restores a document to a specific version. Creates a new version with the restored data.
|
|
44
|
+
*/
|
|
45
|
+
export declare function restoreVersion(ctx: OperationContext, args: RestoreVersionArgs): Promise<DatabaseRecord>;
|
|
46
|
+
/**
|
|
47
|
+
* Creates a new version of a document. Called automatically on updates when versions are enabled.
|
|
48
|
+
*/
|
|
49
|
+
export declare function createVersion(ctx: OperationContext, args: CreateVersionArgs): Promise<Version>;
|
|
50
|
+
export { versionsEnabled, autosaveEnabled };
|
|
51
|
+
//# sourceMappingURL=versions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../src/versions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAQD,iBAAS,eAAe,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAKlE;AAED,iBAAS,eAAe,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAKlE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,OAAO,EAAE,CAAC,CAiBpB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAW9F;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,cAAc,CAAC,CA8BzB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,OAAO,CAAC,CAiClB;AAiBD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC"}
|
package/dist/versions.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { NotFoundError } from './errors.js';
|
|
2
|
+
function getCollectionOrThrow(ctx, slug) {
|
|
3
|
+
const collection = ctx.getCollection(slug);
|
|
4
|
+
if (!collection)
|
|
5
|
+
throw new NotFoundError(`Collection '${slug}' not found`);
|
|
6
|
+
return collection;
|
|
7
|
+
}
|
|
8
|
+
function versionsEnabled(collection) {
|
|
9
|
+
return (collection.versions === true ||
|
|
10
|
+
(typeof collection.versions === 'object' && collection.versions !== null));
|
|
11
|
+
}
|
|
12
|
+
function autosaveEnabled(collection) {
|
|
13
|
+
if (typeof collection.versions === 'object' && collection.versions !== null) {
|
|
14
|
+
return collection.versions.autosave === true;
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Lists all versions of a document, newest first.
|
|
20
|
+
*/
|
|
21
|
+
export async function listVersions(ctx, args) {
|
|
22
|
+
const collection = getCollectionOrThrow(ctx, args.collection);
|
|
23
|
+
if (!versionsEnabled(collection)) {
|
|
24
|
+
throw new Error(`Collection '${args.collection}' does not have versions enabled`);
|
|
25
|
+
}
|
|
26
|
+
const versionsCollection = `_versions_${args.collection}`;
|
|
27
|
+
const records = await ctx.adapters.database.findMany({
|
|
28
|
+
collection: versionsCollection,
|
|
29
|
+
where: { documentId: args.documentId },
|
|
30
|
+
sort: 'versionNumber',
|
|
31
|
+
order: 'desc',
|
|
32
|
+
...(args.limit !== undefined && { limit: args.limit }),
|
|
33
|
+
...(args.offset !== undefined && { offset: args.offset })
|
|
34
|
+
});
|
|
35
|
+
return records.map(toVersion);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Gets a specific version by id.
|
|
39
|
+
*/
|
|
40
|
+
export async function getVersion(ctx, args) {
|
|
41
|
+
const collection = getCollectionOrThrow(ctx, args.collection);
|
|
42
|
+
if (!versionsEnabled(collection)) {
|
|
43
|
+
throw new Error(`Collection '${args.collection}' does not have versions enabled`);
|
|
44
|
+
}
|
|
45
|
+
const versionsCollection = `_versions_${args.collection}`;
|
|
46
|
+
const record = await ctx.adapters.database.findById(versionsCollection, args.versionId);
|
|
47
|
+
if (!record)
|
|
48
|
+
throw new NotFoundError(`Version '${args.versionId}' not found`);
|
|
49
|
+
return toVersion(record);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Restores a document to a specific version. Creates a new version with the restored data.
|
|
53
|
+
*/
|
|
54
|
+
export async function restoreVersion(ctx, args) {
|
|
55
|
+
const collection = getCollectionOrThrow(ctx, args.collection);
|
|
56
|
+
if (!versionsEnabled(collection)) {
|
|
57
|
+
throw new Error(`Collection '${args.collection}' does not have versions enabled`);
|
|
58
|
+
}
|
|
59
|
+
const version = await getVersion(ctx, {
|
|
60
|
+
collection: args.collection,
|
|
61
|
+
versionId: args.versionId,
|
|
62
|
+
...(args.user !== undefined && { user: args.user }),
|
|
63
|
+
...(args.overrideAccess !== undefined && { overrideAccess: args.overrideAccess })
|
|
64
|
+
});
|
|
65
|
+
// Update the document with the version data
|
|
66
|
+
const record = await ctx.adapters.database.update(args.collection, version.documentId, version.data);
|
|
67
|
+
// Create a new version for the restore
|
|
68
|
+
await createVersion(ctx, {
|
|
69
|
+
collection: args.collection,
|
|
70
|
+
documentId: version.documentId,
|
|
71
|
+
data: version.data,
|
|
72
|
+
...(args.user !== undefined && { user: args.user }),
|
|
73
|
+
label: `Restored from version ${version.versionNumber}`
|
|
74
|
+
});
|
|
75
|
+
return record;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Creates a new version of a document. Called automatically on updates when versions are enabled.
|
|
79
|
+
*/
|
|
80
|
+
export async function createVersion(ctx, args) {
|
|
81
|
+
const collection = getCollectionOrThrow(ctx, args.collection);
|
|
82
|
+
if (!versionsEnabled(collection)) {
|
|
83
|
+
throw new Error(`Collection '${args.collection}' does not have versions enabled`);
|
|
84
|
+
}
|
|
85
|
+
const versionsCollection = `_versions_${args.collection}`;
|
|
86
|
+
// Get the latest version number for this document
|
|
87
|
+
const existingVersions = await ctx.adapters.database.findMany({
|
|
88
|
+
collection: versionsCollection,
|
|
89
|
+
where: { documentId: args.documentId },
|
|
90
|
+
sort: 'versionNumber',
|
|
91
|
+
order: 'desc',
|
|
92
|
+
limit: 1
|
|
93
|
+
});
|
|
94
|
+
const lastVersionNumber = existingVersions.length > 0 ? (existingVersions[0]?.versionNumber ?? 0) : 0;
|
|
95
|
+
const versionRecord = {
|
|
96
|
+
id: crypto.randomUUID(),
|
|
97
|
+
documentId: args.documentId,
|
|
98
|
+
versionNumber: lastVersionNumber + 1,
|
|
99
|
+
data: JSON.stringify(args.data),
|
|
100
|
+
createdAt: new Date().toISOString(),
|
|
101
|
+
createdBy: args.user?.id ?? null,
|
|
102
|
+
autosave: args.autosave ?? false,
|
|
103
|
+
...(args.label !== undefined && { label: args.label })
|
|
104
|
+
};
|
|
105
|
+
const created = await ctx.adapters.database.create(versionsCollection, versionRecord);
|
|
106
|
+
return toVersion(created);
|
|
107
|
+
}
|
|
108
|
+
function toVersion(record) {
|
|
109
|
+
const data = typeof record.data === 'string' ? JSON.parse(record.data) : record.data;
|
|
110
|
+
return {
|
|
111
|
+
id: record.id,
|
|
112
|
+
documentId: record.documentId,
|
|
113
|
+
versionNumber: record.versionNumber,
|
|
114
|
+
data: data,
|
|
115
|
+
createdAt: record.createdAt,
|
|
116
|
+
createdBy: record.createdBy ?? null,
|
|
117
|
+
autosave: record.autosave ?? false,
|
|
118
|
+
...(record.label !== undefined && { label: record.label })
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
export { versionsEnabled, autosaveEnabled };
|
|
122
|
+
//# sourceMappingURL=versions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versions.js","sourceRoot":"","sources":["../src/versions.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@forge-cms/runtime",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Runtime orchestrator for ForgeCMS — binds schema, adapters, and handlers.",
|
|
5
|
+
"author": "ForgeCMS contributors",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Andersseen/ForgeCMS.git",
|
|
10
|
+
"directory": "packages/runtime"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/Andersseen/ForgeCMS/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/Andersseen/ForgeCMS/tree/main/packages/runtime#readme",
|
|
16
|
+
"keywords": [
|
|
17
|
+
"cms",
|
|
18
|
+
"runtime",
|
|
19
|
+
"orchestrator",
|
|
20
|
+
"typescript"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"default": "./dist/index.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@forge-cms/api": "0.0.1",
|
|
39
|
+
"@forge-cms/db": "0.0.1",
|
|
40
|
+
"@forge-cms/auth": "0.0.1",
|
|
41
|
+
"@forge-cms/core": "0.0.1",
|
|
42
|
+
"@forge-cms/storage": "0.0.1"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"typescript": "5.9.2",
|
|
46
|
+
"vitest": "^4.1.6"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc -p tsconfig.build.json",
|
|
50
|
+
"test": "vitest run --dir .",
|
|
51
|
+
"test:watch": "vitest --dir .",
|
|
52
|
+
"lint": "eslint .",
|
|
53
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
54
|
+
"clean": "rm -rf dist coverage"
|
|
55
|
+
}
|
|
56
|
+
}
|