@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,49 @@
|
|
|
1
|
+
import { resolveFieldAccess } from './access.js';
|
|
2
|
+
export class FieldAccessError extends Error {
|
|
3
|
+
field;
|
|
4
|
+
constructor(field) {
|
|
5
|
+
super(`Forbidden: cannot set field '${field}'`);
|
|
6
|
+
this.field = field;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Omits fields the user may not read (`field.options.access.read`). A rule can now be a predicate as
|
|
11
|
+
* well as a role list (spec 020), so resolution is async.
|
|
12
|
+
*/
|
|
13
|
+
export async function filterReadableFields(record, collection, user) {
|
|
14
|
+
const filtered = {};
|
|
15
|
+
for (const [key, value] of Object.entries(record)) {
|
|
16
|
+
const field = collection.fields[key];
|
|
17
|
+
if (field) {
|
|
18
|
+
const allowed = await resolveFieldAccess(field.options.access?.read, {
|
|
19
|
+
user,
|
|
20
|
+
operation: 'read',
|
|
21
|
+
collection,
|
|
22
|
+
fieldName: key,
|
|
23
|
+
doc: record
|
|
24
|
+
});
|
|
25
|
+
if (!allowed)
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
filtered[key] = value;
|
|
29
|
+
}
|
|
30
|
+
return filtered;
|
|
31
|
+
}
|
|
32
|
+
/** Throws {@link FieldAccessError} naming the first field the user may not write. */
|
|
33
|
+
export async function assertWritableFields(body, collection, user, operation = 'create') {
|
|
34
|
+
for (const key of Object.keys(body)) {
|
|
35
|
+
const field = collection.fields[key];
|
|
36
|
+
if (!field)
|
|
37
|
+
continue;
|
|
38
|
+
const allowed = await resolveFieldAccess(field.options.access?.write, {
|
|
39
|
+
user,
|
|
40
|
+
operation,
|
|
41
|
+
collection,
|
|
42
|
+
fieldName: key,
|
|
43
|
+
data: body
|
|
44
|
+
});
|
|
45
|
+
if (!allowed)
|
|
46
|
+
throw new FieldAccessError(key);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=field-access.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-access.js","sourceRoot":"","sources":["../src/field-access.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACpB;IAArB,YAAqB,KAAa;QAChC,KAAK,CAAC,gCAAgC,KAAK,GAAG,CAAC,CAAC;QAD7B,UAAK,GAAL,KAAK,CAAQ;IAElC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAsB,EACtB,UAAgC,EAChC,IAAoB;IAEpB,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE;gBACnE,IAAI;gBACJ,SAAS,EAAE,MAAM;gBACjB,UAAU;gBACV,SAAS,EAAE,GAAG;gBACd,GAAG,EAAE,MAAM;aACZ,CAAC,CAAC;YACH,IAAI,CAAC,OAAO;gBAAE,SAAS;QACzB,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACxB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAA6B,EAC7B,UAAgC,EAChC,IAAoB,EACpB,YAAiC,QAAQ;IAEzC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK;YAAE,SAAS;QAErB,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE;YACpE,IAAI;YACJ,SAAS;YACT,UAAU;YACV,SAAS,EAAE,GAAG;YACd,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QACH,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
|
package/dist/files.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ApiContext } from '@forge-cms/api';
|
|
2
|
+
import type { ForgeCmsRuntime } from './runtime.js';
|
|
3
|
+
export interface FileHandlerOptions<TEnv = unknown> {
|
|
4
|
+
runtime: ForgeCmsRuntime<TEnv>;
|
|
5
|
+
/** `cache-control` for a hit. Defaults to a conservative minute. */
|
|
6
|
+
cacheControl?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Serves a stored file back over HTTP.
|
|
10
|
+
*
|
|
11
|
+
* Spec 016 stores uploaded bytes through the `StorageAdapter` and writes a public URL onto the
|
|
12
|
+
* document, but nothing served those bytes — so on any deployment without a public bucket (local
|
|
13
|
+
* development, the in-memory adapter, a private R2) every uploaded image was a broken link. Mount
|
|
14
|
+
* this on the path your storage adapter's public URL points at:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* // apps/<app>/src/server/routes/api/media/[...key].get.ts
|
|
18
|
+
* export default defineEventHandler((event) =>
|
|
19
|
+
* handleFile({ request: toWebRequest(event), params: { key: getRouterParam(event, 'key') ?? '' } }, { runtime })
|
|
20
|
+
* );
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function handleFile<TEnv = unknown>(context: ApiContext<TEnv>, options: FileHandlerOptions<TEnv>): Promise<Response>;
|
|
24
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,kBAAkB,CAAC,IAAI,GAAG,OAAO;IAChD,OAAO,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC;IAC/B,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,CAAC,IAAI,GAAG,OAAO,EAC7C,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,EACzB,OAAO,EAAE,kBAAkB,CAAC,IAAI,CAAC,GAChC,OAAO,CAAC,QAAQ,CAAC,CAkCnB"}
|
package/dist/files.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serves a stored file back over HTTP.
|
|
3
|
+
*
|
|
4
|
+
* Spec 016 stores uploaded bytes through the `StorageAdapter` and writes a public URL onto the
|
|
5
|
+
* document, but nothing served those bytes — so on any deployment without a public bucket (local
|
|
6
|
+
* development, the in-memory adapter, a private R2) every uploaded image was a broken link. Mount
|
|
7
|
+
* this on the path your storage adapter's public URL points at:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* // apps/<app>/src/server/routes/api/media/[...key].get.ts
|
|
11
|
+
* export default defineEventHandler((event) =>
|
|
12
|
+
* handleFile({ request: toWebRequest(event), params: { key: getRouterParam(event, 'key') ?? '' } }, { runtime })
|
|
13
|
+
* );
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export async function handleFile(context, options) {
|
|
17
|
+
const raw = context.params?.['key'];
|
|
18
|
+
if (!raw) {
|
|
19
|
+
return new Response(JSON.stringify({ error: 'Missing file key' }), {
|
|
20
|
+
status: 400,
|
|
21
|
+
headers: { 'content-type': 'application/json' }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const key = decodeURIComponent(raw);
|
|
25
|
+
try {
|
|
26
|
+
const object = await options.runtime.adapters.storage.get(key);
|
|
27
|
+
if (!object?.body) {
|
|
28
|
+
return new Response(JSON.stringify({ error: `File '${key}' not found` }), {
|
|
29
|
+
status: 404,
|
|
30
|
+
headers: { 'content-type': 'application/json' }
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return new Response(object.body, {
|
|
34
|
+
status: 200,
|
|
35
|
+
headers: {
|
|
36
|
+
'content-type': object.contentType ?? 'application/octet-stream',
|
|
37
|
+
'cache-control': options.cacheControl ?? 'public, max-age=60',
|
|
38
|
+
...(object.size !== undefined && { 'content-length': String(object.size) })
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
return new Response(JSON.stringify({ error: err instanceof Error ? err.message : 'Failed to read file' }), { status: 500, headers: { 'content-type': 'application/json' } });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAAyB,EACzB,OAAiC;IAEjC,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,EAAE;YACjE,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;SAChD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,GAAG,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;YAClB,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,GAAG,aAAa,EAAE,CAAC,EAAE;gBACxE,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;aAChD,CAAC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE;YAC/B,MAAM,EAAE,GAAG;YACX,OAAO,EAAE;gBACP,cAAc,EAAE,MAAM,CAAC,WAAW,IAAI,0BAA0B;gBAChE,eAAe,EAAE,OAAO,CAAC,YAAY,IAAI,oBAAoB;gBAC7D,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;aAC5E;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,IAAI,QAAQ,CACjB,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,EAAE,CAAC,EACrF,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE,CACjE,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CmsUser } from '@forge-cms/core';
|
|
2
|
+
import type { DatabaseRecord } from '@forge-cms/db';
|
|
3
|
+
import type { OperationContext } from './context.js';
|
|
4
|
+
export interface GlobalBaseArgs {
|
|
5
|
+
global: string;
|
|
6
|
+
user?: CmsUser | null;
|
|
7
|
+
overrideAccess?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface GetGlobalArgs extends GlobalBaseArgs {
|
|
10
|
+
depth?: 0 | 1;
|
|
11
|
+
}
|
|
12
|
+
export interface UpdateGlobalArgs extends GlobalBaseArgs {
|
|
13
|
+
data: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Reads the singleton global document. Returns `null` if the global has never been written.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getGlobal(ctx: OperationContext, args: GetGlobalArgs): Promise<DatabaseRecord | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Creates or updates the singleton global document. Unlike collections, globals always have
|
|
21
|
+
* exactly one document — the first write creates it, subsequent writes update it.
|
|
22
|
+
*/
|
|
23
|
+
export declare function updateGlobal(ctx: OperationContext, args: UpdateGlobalArgs): Promise<DatabaseRecord>;
|
|
24
|
+
//# sourceMappingURL=globals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../src/globals.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAoB,MAAM,iBAAiB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAwBrD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CACf;AAED,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAwED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA6BhC;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,cAAc,CAAC,CAsGzB"}
|
package/dist/globals.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { validateCollection } from '@forge-cms/core';
|
|
2
|
+
import { AccessDeniedError, ForgeError, InvalidInputError, NotFoundError, ValidationFailedError } from './errors.js';
|
|
3
|
+
import { resolveAccess } from './access.js';
|
|
4
|
+
import { applyFieldDefaults } from './defaults.js';
|
|
5
|
+
import { runAfterChangeHooks, runAfterOperationHooks, runAfterReadHooks, runBeforeChangeHooks, runBeforeOperationHooks, runBeforeValidateHooks, runFieldHooks } from './hooks.js';
|
|
6
|
+
import { assertWritableFields, filterReadableFields, FieldAccessError } from './field-access.js';
|
|
7
|
+
const GLOBAL_ID = 'global';
|
|
8
|
+
function getGlobalOrThrow(ctx, slug) {
|
|
9
|
+
const global = ctx.getGlobal(slug);
|
|
10
|
+
if (!global)
|
|
11
|
+
throw new NotFoundError(`Global '${slug}' not found`);
|
|
12
|
+
return global;
|
|
13
|
+
}
|
|
14
|
+
async function checkGlobalAccess(global, operation, args) {
|
|
15
|
+
if (args.overrideAccess !== false)
|
|
16
|
+
return { allowed: true };
|
|
17
|
+
const decision = await resolveAccess(global.access?.[operation], {
|
|
18
|
+
user: args.user ?? null,
|
|
19
|
+
operation,
|
|
20
|
+
collection: { ...global, upload: false },
|
|
21
|
+
...(args.data !== undefined && { data: args.data }),
|
|
22
|
+
...(args.doc !== undefined && { doc: args.doc })
|
|
23
|
+
});
|
|
24
|
+
if (decision === undefined)
|
|
25
|
+
return { allowed: true };
|
|
26
|
+
if (!decision.allowed)
|
|
27
|
+
throw new AccessDeniedError();
|
|
28
|
+
return decision;
|
|
29
|
+
}
|
|
30
|
+
async function runRejectableStage(stage, label) {
|
|
31
|
+
try {
|
|
32
|
+
return await stage();
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
if (err instanceof ForgeError)
|
|
36
|
+
throw err;
|
|
37
|
+
throw new InvalidInputError(err instanceof Error ? err.message : `${label} failed`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function prepareGlobalForRead(ctx, global, record, args) {
|
|
41
|
+
if (!record)
|
|
42
|
+
return null;
|
|
43
|
+
const user = args.user ?? null;
|
|
44
|
+
const overrideAccess = args.overrideAccess !== false;
|
|
45
|
+
let doc = record;
|
|
46
|
+
if (args.overrideAccess === false) {
|
|
47
|
+
doc = await filterReadableFields(doc, { ...global, upload: false }, user);
|
|
48
|
+
}
|
|
49
|
+
const withFieldHooks = await runFieldHooks({ ...global, upload: false }, 'afterRead', {
|
|
50
|
+
data: doc,
|
|
51
|
+
operation: 'read',
|
|
52
|
+
user,
|
|
53
|
+
overrideAccess
|
|
54
|
+
});
|
|
55
|
+
return runAfterReadHooks({ ...global, upload: false }, { user, overrideAccess, doc: withFieldHooks });
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Reads the singleton global document. Returns `null` if the global has never been written.
|
|
59
|
+
*/
|
|
60
|
+
export async function getGlobal(ctx, args) {
|
|
61
|
+
const global = getGlobalOrThrow(ctx, args.global);
|
|
62
|
+
const user = args.user ?? null;
|
|
63
|
+
const overrideAccess = args.overrideAccess !== false;
|
|
64
|
+
await runBeforeOperationHooks({ ...global, upload: false }, { operation: 'read', user, overrideAccess });
|
|
65
|
+
await checkGlobalAccess(global, 'read', args);
|
|
66
|
+
const record = await ctx.adapters.database.findById(`_global_${global.slug}`, GLOBAL_ID);
|
|
67
|
+
if (!record) {
|
|
68
|
+
await runAfterOperationHooks({ ...global, upload: false }, { operation: 'read', user, overrideAccess, result: null });
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const doc = await prepareGlobalForRead(ctx, global, record, args);
|
|
72
|
+
await runAfterOperationHooks({ ...global, upload: false }, { operation: 'read', user, overrideAccess, result: doc });
|
|
73
|
+
return doc;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Creates or updates the singleton global document. Unlike collections, globals always have
|
|
77
|
+
* exactly one document — the first write creates it, subsequent writes update it.
|
|
78
|
+
*/
|
|
79
|
+
export async function updateGlobal(ctx, args) {
|
|
80
|
+
const global = getGlobalOrThrow(ctx, args.global);
|
|
81
|
+
const user = args.user ?? null;
|
|
82
|
+
const overrideAccess = args.overrideAccess !== false;
|
|
83
|
+
const collectionProxy = { ...global, upload: false };
|
|
84
|
+
await runBeforeOperationHooks(collectionProxy, { operation: 'update', user, overrideAccess });
|
|
85
|
+
const existing = await ctx.adapters.database.findById(`_global_${global.slug}`, GLOBAL_ID);
|
|
86
|
+
await checkGlobalAccess(global, 'update', {
|
|
87
|
+
...args,
|
|
88
|
+
...(existing !== null && { doc: existing })
|
|
89
|
+
});
|
|
90
|
+
if (args.overrideAccess === false) {
|
|
91
|
+
try {
|
|
92
|
+
await assertWritableFields(args.data, collectionProxy, user, existing ? 'update' : 'create');
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
if (err instanceof FieldAccessError)
|
|
96
|
+
throw new AccessDeniedError(err.message);
|
|
97
|
+
throw err;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const seeded = applyFieldDefaults(collectionProxy, args.data);
|
|
101
|
+
let data = await runRejectableStage(async () => runBeforeValidateHooks(collectionProxy, {
|
|
102
|
+
operation: existing ? 'update' : 'create',
|
|
103
|
+
data: await runFieldHooks(collectionProxy, 'beforeValidate', {
|
|
104
|
+
data: seeded,
|
|
105
|
+
operation: existing ? 'update' : 'create',
|
|
106
|
+
user,
|
|
107
|
+
overrideAccess
|
|
108
|
+
}),
|
|
109
|
+
user,
|
|
110
|
+
overrideAccess
|
|
111
|
+
}), 'beforeValidate hook');
|
|
112
|
+
if (global.drafts === true && data._status === undefined) {
|
|
113
|
+
data = { ...data, _status: 'draft' };
|
|
114
|
+
}
|
|
115
|
+
if (data._status !== undefined && data._status !== 'draft' && data._status !== 'published') {
|
|
116
|
+
throw new InvalidInputError(`Invalid status '${String(data._status)}', expected 'draft' or 'published'`);
|
|
117
|
+
}
|
|
118
|
+
const validation = validateCollection(collectionProxy, data);
|
|
119
|
+
if (!validation.valid)
|
|
120
|
+
throw new ValidationFailedError(validation.errors);
|
|
121
|
+
data = await runRejectableStage(async () => runBeforeChangeHooks(collectionProxy, {
|
|
122
|
+
operation: existing ? 'update' : 'create',
|
|
123
|
+
data: await runFieldHooks(collectionProxy, 'beforeChange', {
|
|
124
|
+
data,
|
|
125
|
+
...(existing !== null && { previousData: existing }),
|
|
126
|
+
operation: existing ? 'update' : 'create',
|
|
127
|
+
user,
|
|
128
|
+
overrideAccess
|
|
129
|
+
}),
|
|
130
|
+
...(existing !== null && { previousData: existing }),
|
|
131
|
+
user,
|
|
132
|
+
overrideAccess
|
|
133
|
+
}), 'beforeChange hook');
|
|
134
|
+
const globalCollection = `_global_${global.slug}`;
|
|
135
|
+
let record;
|
|
136
|
+
if (existing) {
|
|
137
|
+
record = await ctx.adapters.database.update(globalCollection, GLOBAL_ID, data);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
record = await ctx.adapters.database.create(globalCollection, { ...data, id: GLOBAL_ID });
|
|
141
|
+
}
|
|
142
|
+
await runAfterChangeHooks(collectionProxy, {
|
|
143
|
+
operation: existing ? 'update' : 'create',
|
|
144
|
+
data,
|
|
145
|
+
...(existing !== null && { previousData: existing }),
|
|
146
|
+
result: record,
|
|
147
|
+
doc: record,
|
|
148
|
+
user,
|
|
149
|
+
overrideAccess
|
|
150
|
+
});
|
|
151
|
+
const doc = await prepareGlobalForRead(ctx, global, record, args);
|
|
152
|
+
const result = doc ?? record;
|
|
153
|
+
await runAfterOperationHooks(collectionProxy, {
|
|
154
|
+
operation: 'update',
|
|
155
|
+
user,
|
|
156
|
+
overrideAccess,
|
|
157
|
+
result
|
|
158
|
+
});
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=globals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globals.js","sourceRoot":"","sources":["../src/globals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ApiContext } from '@forge-cms/api';
|
|
2
|
+
import type { ForgeCmsRuntime } from './runtime.js';
|
|
3
|
+
import type { UserRole } from '@forge-cms/auth';
|
|
4
|
+
import * as operations from './operations.js';
|
|
5
|
+
declare const DEFAULT_LIMIT = 50;
|
|
6
|
+
declare const MAX_LIMIT = 500;
|
|
7
|
+
export interface HandlerOptions<TEnv = unknown> {
|
|
8
|
+
runtime: ForgeCmsRuntime<TEnv>;
|
|
9
|
+
requireAuth?: boolean;
|
|
10
|
+
allowedRoles?: UserRole[];
|
|
11
|
+
upload?: {
|
|
12
|
+
maxFileSize?: number;
|
|
13
|
+
mimeTypes?: string[];
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare function handleList<TEnv = unknown>(context: ApiContext<TEnv>, options: HandlerOptions<TEnv>): Promise<Response>;
|
|
17
|
+
export declare function handleRead<TEnv = unknown>(context: ApiContext<TEnv>, options: HandlerOptions<TEnv>): Promise<Response>;
|
|
18
|
+
export declare function handleCreate<TEnv = unknown>(context: ApiContext<TEnv>, options: HandlerOptions<TEnv>): Promise<Response>;
|
|
19
|
+
export declare function handleUpdate<TEnv = unknown>(context: ApiContext<TEnv>, options: HandlerOptions<TEnv>): Promise<Response>;
|
|
20
|
+
export declare function handleDelete<TEnv = unknown>(context: ApiContext<TEnv>, options: HandlerOptions<TEnv>): Promise<Response>;
|
|
21
|
+
export declare function handleGlobalRead<TEnv = unknown>(context: ApiContext<TEnv>, options: HandlerOptions<TEnv>): Promise<Response>;
|
|
22
|
+
export declare function handleGlobalUpdate<TEnv = unknown>(context: ApiContext<TEnv>, options: HandlerOptions<TEnv>): Promise<Response>;
|
|
23
|
+
export declare function handleListVersions<TEnv = unknown>(context: ApiContext<TEnv>, options: HandlerOptions<TEnv>): Promise<Response>;
|
|
24
|
+
export declare function handleGetVersion<TEnv = unknown>(context: ApiContext<TEnv>, options: HandlerOptions<TEnv>): Promise<Response>;
|
|
25
|
+
export declare function handleRestoreVersion<TEnv = unknown>(context: ApiContext<TEnv>, options: HandlerOptions<TEnv>): Promise<Response>;
|
|
26
|
+
export interface PreviewOptions {
|
|
27
|
+
/** Allow previewing drafts without authentication (for preview tokens). */
|
|
28
|
+
allowDraftPreview?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Generates a preview of a document by merging stored data with unsaved changes.
|
|
32
|
+
* Useful for live preview in the admin UI before saving.
|
|
33
|
+
*/
|
|
34
|
+
export declare function handlePreview<TEnv = unknown>(context: ApiContext<TEnv>, options: HandlerOptions<TEnv> & PreviewOptions): Promise<Response>;
|
|
35
|
+
export { operations };
|
|
36
|
+
export { DEFAULT_LIMIT, MAX_LIMIT };
|
|
37
|
+
//# sourceMappingURL=handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"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"}
|