@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
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { AccessQuery, CmsUser, CollectionDefinition, HookContext, HookOperation } from '@forge-cms/core';
|
|
2
|
+
type ChangeCtx = Omit<HookContext, 'collection'>;
|
|
3
|
+
/** Runs first on every operation, before access control resolves. */
|
|
4
|
+
export declare function runBeforeOperationHooks(collection: CollectionDefinition, ctx: {
|
|
5
|
+
operation: HookOperation;
|
|
6
|
+
user?: CmsUser | null;
|
|
7
|
+
overrideAccess?: boolean;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
/** Runs last on every operation, with whatever is about to be returned. */
|
|
10
|
+
export declare function runAfterOperationHooks(collection: CollectionDefinition, ctx: {
|
|
11
|
+
operation: HookOperation;
|
|
12
|
+
user?: CmsUser | null;
|
|
13
|
+
overrideAccess?: boolean;
|
|
14
|
+
result: unknown;
|
|
15
|
+
}): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Runs before validation, so a hook can normalise or derive a value that then has to pass the
|
|
18
|
+
* schema. Throwing rejects the write, same as `beforeChange`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function runBeforeValidateHooks(collection: CollectionDefinition, ctx: ChangeCtx): Promise<Record<string, unknown>>;
|
|
21
|
+
export declare function runBeforeChangeHooks(collection: CollectionDefinition, ctx: ChangeCtx): Promise<Record<string, unknown>>;
|
|
22
|
+
export declare function runAfterChangeHooks(collection: CollectionDefinition, ctx: ChangeCtx & {
|
|
23
|
+
result: Record<string, unknown>;
|
|
24
|
+
doc?: Record<string, unknown>;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
/** Runs once per read operation and may narrow the query before it is issued. */
|
|
27
|
+
export declare function runBeforeReadHooks(collection: CollectionDefinition, ctx: {
|
|
28
|
+
user?: CmsUser | null;
|
|
29
|
+
overrideAccess?: boolean;
|
|
30
|
+
query: AccessQuery;
|
|
31
|
+
}): Promise<AccessQuery>;
|
|
32
|
+
/** Runs per document on the way out. Returns the document to hand to the caller. */
|
|
33
|
+
export declare function runAfterReadHooks(collection: CollectionDefinition, ctx: {
|
|
34
|
+
user?: CmsUser | null;
|
|
35
|
+
overrideAccess?: boolean;
|
|
36
|
+
doc: Record<string, unknown>;
|
|
37
|
+
}): Promise<Record<string, unknown>>;
|
|
38
|
+
export declare function runBeforeDeleteHooks(collection: CollectionDefinition, ctx: {
|
|
39
|
+
user?: CmsUser | null;
|
|
40
|
+
overrideAccess?: boolean;
|
|
41
|
+
id: string;
|
|
42
|
+
doc: Record<string, unknown>;
|
|
43
|
+
}): Promise<void>;
|
|
44
|
+
export declare function runAfterDeleteHooks(collection: CollectionDefinition, ctx: {
|
|
45
|
+
user?: CmsUser | null;
|
|
46
|
+
overrideAccess?: boolean;
|
|
47
|
+
id: string;
|
|
48
|
+
doc: Record<string, unknown>;
|
|
49
|
+
}): Promise<void>;
|
|
50
|
+
type FieldHookName = 'beforeValidate' | 'beforeChange' | 'afterRead';
|
|
51
|
+
/** Threads every top-level and nested field's value through its hook chain. */
|
|
52
|
+
export declare function runFieldHooks(collection: CollectionDefinition, name: FieldHookName, ctx: {
|
|
53
|
+
data: Record<string, unknown>;
|
|
54
|
+
previousData?: Record<string, unknown>;
|
|
55
|
+
operation: HookOperation;
|
|
56
|
+
user?: CmsUser | null;
|
|
57
|
+
overrideAccess?: boolean;
|
|
58
|
+
}): Promise<Record<string, unknown>>;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs side-effect hooks without letting a failure roll back work that already happened. These run
|
|
3
|
+
* after the write is committed, so throwing would report failure for an operation that succeeded.
|
|
4
|
+
*/
|
|
5
|
+
async function runSideEffects(hooks, ctx, label, collection) {
|
|
6
|
+
if (!hooks || hooks.length === 0)
|
|
7
|
+
return;
|
|
8
|
+
for (const hook of hooks) {
|
|
9
|
+
try {
|
|
10
|
+
await hook(ctx);
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
console.error(`${label} hook failed for collection '${collection.slug}':`, err);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Runs first on every operation, before access control resolves. */
|
|
18
|
+
export async function runBeforeOperationHooks(collection, ctx) {
|
|
19
|
+
await runSideEffects(collection.hooks?.beforeOperation, { ...ctx, collection }, 'beforeOperation', collection);
|
|
20
|
+
}
|
|
21
|
+
/** Runs last on every operation, with whatever is about to be returned. */
|
|
22
|
+
export async function runAfterOperationHooks(collection, ctx) {
|
|
23
|
+
await runSideEffects(collection.hooks?.afterOperation, { ...ctx, collection }, 'afterOperation', collection);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Runs before validation, so a hook can normalise or derive a value that then has to pass the
|
|
27
|
+
* schema. Throwing rejects the write, same as `beforeChange`.
|
|
28
|
+
*/
|
|
29
|
+
export async function runBeforeValidateHooks(collection, ctx) {
|
|
30
|
+
const hooks = collection.hooks?.beforeValidate;
|
|
31
|
+
if (!hooks || hooks.length === 0)
|
|
32
|
+
return ctx.data;
|
|
33
|
+
let data = ctx.data;
|
|
34
|
+
for (const hook of hooks) {
|
|
35
|
+
data = await hook({ ...ctx, collection, data });
|
|
36
|
+
}
|
|
37
|
+
return data;
|
|
38
|
+
}
|
|
39
|
+
export async function runBeforeChangeHooks(collection, ctx) {
|
|
40
|
+
const hooks = collection.hooks?.beforeChange;
|
|
41
|
+
if (!hooks || hooks.length === 0)
|
|
42
|
+
return ctx.data;
|
|
43
|
+
let data = ctx.data;
|
|
44
|
+
for (const hook of hooks) {
|
|
45
|
+
data = await hook({ ...ctx, collection, data });
|
|
46
|
+
}
|
|
47
|
+
return data;
|
|
48
|
+
}
|
|
49
|
+
export async function runAfterChangeHooks(collection, ctx) {
|
|
50
|
+
// `doc` is the spec-021 name, `result` the spec-013 one. Both are passed so hooks written against
|
|
51
|
+
// either shape keep working.
|
|
52
|
+
const doc = ctx.doc ?? ctx.result;
|
|
53
|
+
await runSideEffects(collection.hooks?.afterChange, { ...ctx, collection, doc, result: ctx.result }, 'afterChange', collection);
|
|
54
|
+
}
|
|
55
|
+
/** Runs once per read operation and may narrow the query before it is issued. */
|
|
56
|
+
export async function runBeforeReadHooks(collection, ctx) {
|
|
57
|
+
const hooks = collection.hooks?.beforeRead;
|
|
58
|
+
if (!hooks || hooks.length === 0)
|
|
59
|
+
return ctx.query;
|
|
60
|
+
let query = ctx.query;
|
|
61
|
+
for (const hook of hooks) {
|
|
62
|
+
query = await hook({ ...ctx, collection, operation: 'read', query });
|
|
63
|
+
}
|
|
64
|
+
return query;
|
|
65
|
+
}
|
|
66
|
+
/** Runs per document on the way out. Returns the document to hand to the caller. */
|
|
67
|
+
export async function runAfterReadHooks(collection, ctx) {
|
|
68
|
+
const hooks = collection.hooks?.afterRead;
|
|
69
|
+
if (!hooks || hooks.length === 0)
|
|
70
|
+
return ctx.doc;
|
|
71
|
+
let doc = ctx.doc;
|
|
72
|
+
for (const hook of hooks) {
|
|
73
|
+
doc = await hook({ ...ctx, collection, operation: 'read', doc });
|
|
74
|
+
}
|
|
75
|
+
return doc;
|
|
76
|
+
}
|
|
77
|
+
export async function runBeforeDeleteHooks(collection, ctx) {
|
|
78
|
+
const hooks = collection.hooks?.beforeDelete;
|
|
79
|
+
if (!hooks || hooks.length === 0)
|
|
80
|
+
return;
|
|
81
|
+
// Unlike the after* hooks, a throwing beforeDelete aborts the delete — that is the point of having
|
|
82
|
+
// one (referential-integrity guards, "this document is still in use" checks).
|
|
83
|
+
for (const hook of hooks) {
|
|
84
|
+
await hook({ ...ctx, collection, operation: 'delete' });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export async function runAfterDeleteHooks(collection, ctx) {
|
|
88
|
+
await runSideEffects(collection.hooks?.afterDelete, { ...ctx, collection, operation: 'delete' }, 'afterDelete', collection);
|
|
89
|
+
}
|
|
90
|
+
function hooksFor(field, name) {
|
|
91
|
+
return field.options.hooks?.[name];
|
|
92
|
+
}
|
|
93
|
+
function isPlainRecord(value) {
|
|
94
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
95
|
+
}
|
|
96
|
+
async function runFieldHookChain(field, name, ctx) {
|
|
97
|
+
let value = ctx.value;
|
|
98
|
+
for (const hook of hooksFor(field, name) ?? []) {
|
|
99
|
+
value = await hook({
|
|
100
|
+
value,
|
|
101
|
+
data: ctx.data,
|
|
102
|
+
...(ctx.previousValue !== undefined && { previousValue: ctx.previousValue }),
|
|
103
|
+
fieldName: ctx.fieldName,
|
|
104
|
+
collection: ctx.collection,
|
|
105
|
+
operation: ctx.operation,
|
|
106
|
+
user: ctx.user ?? null,
|
|
107
|
+
...(ctx.overrideAccess !== undefined && { overrideAccess: ctx.overrideAccess })
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
async function runFieldMapHooks(fields, name, ctx) {
|
|
113
|
+
let data = { ...ctx.data };
|
|
114
|
+
for (const [fieldName, field] of Object.entries(fields)) {
|
|
115
|
+
const path = ctx.pathPrefix ? `${ctx.pathPrefix}.${fieldName}` : fieldName;
|
|
116
|
+
const hasOwnValue = Object.prototype.hasOwnProperty.call(data, fieldName);
|
|
117
|
+
const hasHooks = (hooksFor(field, name)?.length ?? 0) > 0;
|
|
118
|
+
let value = data[fieldName];
|
|
119
|
+
value = await runFieldHookChain(field, name, {
|
|
120
|
+
value,
|
|
121
|
+
data,
|
|
122
|
+
...(ctx.previousData !== undefined && { previousValue: ctx.previousData[fieldName] }),
|
|
123
|
+
fieldName: path,
|
|
124
|
+
collection: ctx.collection,
|
|
125
|
+
operation: ctx.operation,
|
|
126
|
+
...(ctx.user !== undefined && { user: ctx.user }),
|
|
127
|
+
...(ctx.overrideAccess !== undefined && { overrideAccess: ctx.overrideAccess })
|
|
128
|
+
});
|
|
129
|
+
let shouldAssign = hasOwnValue || hasHooks;
|
|
130
|
+
if (field.kind === 'group' && isPlainRecord(value)) {
|
|
131
|
+
const previousValue = ctx.previousData?.[fieldName];
|
|
132
|
+
value = await runFieldMapHooks(field.options.fields, name, {
|
|
133
|
+
data: value,
|
|
134
|
+
...(isPlainRecord(previousValue) && { previousData: previousValue }),
|
|
135
|
+
pathPrefix: path,
|
|
136
|
+
collection: ctx.collection,
|
|
137
|
+
operation: ctx.operation,
|
|
138
|
+
...(ctx.user !== undefined && { user: ctx.user }),
|
|
139
|
+
...(ctx.overrideAccess !== undefined && { overrideAccess: ctx.overrideAccess })
|
|
140
|
+
});
|
|
141
|
+
shouldAssign = true;
|
|
142
|
+
}
|
|
143
|
+
if (field.kind === 'array' && Array.isArray(value)) {
|
|
144
|
+
const previousRows = ctx.previousData?.[fieldName];
|
|
145
|
+
value = await Promise.all(value.map(async (row, index) => {
|
|
146
|
+
if (!isPlainRecord(row))
|
|
147
|
+
return row;
|
|
148
|
+
const previousRow = Array.isArray(previousRows) ? previousRows[index] : undefined;
|
|
149
|
+
return runFieldMapHooks(field.options.fields, name, {
|
|
150
|
+
data: row,
|
|
151
|
+
...(isPlainRecord(previousRow) && { previousData: previousRow }),
|
|
152
|
+
pathPrefix: `${path}.${index}`,
|
|
153
|
+
collection: ctx.collection,
|
|
154
|
+
operation: ctx.operation,
|
|
155
|
+
...(ctx.user !== undefined && { user: ctx.user }),
|
|
156
|
+
...(ctx.overrideAccess !== undefined && { overrideAccess: ctx.overrideAccess })
|
|
157
|
+
});
|
|
158
|
+
}));
|
|
159
|
+
shouldAssign = true;
|
|
160
|
+
}
|
|
161
|
+
if (field.kind === 'blocks' && Array.isArray(value)) {
|
|
162
|
+
const previousRows = ctx.previousData?.[fieldName];
|
|
163
|
+
const blocks = new Map(field.options.blocks.map((block) => [block.slug, block]));
|
|
164
|
+
value = await Promise.all(value.map(async (row, index) => {
|
|
165
|
+
if (!isPlainRecord(row) || typeof row.blockType !== 'string')
|
|
166
|
+
return row;
|
|
167
|
+
const block = blocks.get(row.blockType);
|
|
168
|
+
if (!block)
|
|
169
|
+
return row;
|
|
170
|
+
const previousRow = Array.isArray(previousRows) ? previousRows[index] : undefined;
|
|
171
|
+
return runFieldMapHooks(block.fields, name, {
|
|
172
|
+
data: row,
|
|
173
|
+
...(isPlainRecord(previousRow) && { previousData: previousRow }),
|
|
174
|
+
pathPrefix: `${path}.${index}`,
|
|
175
|
+
collection: ctx.collection,
|
|
176
|
+
operation: ctx.operation,
|
|
177
|
+
...(ctx.user !== undefined && { user: ctx.user }),
|
|
178
|
+
...(ctx.overrideAccess !== undefined && { overrideAccess: ctx.overrideAccess })
|
|
179
|
+
});
|
|
180
|
+
}));
|
|
181
|
+
shouldAssign = true;
|
|
182
|
+
}
|
|
183
|
+
if (shouldAssign) {
|
|
184
|
+
data = { ...data, [fieldName]: value };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return data;
|
|
188
|
+
}
|
|
189
|
+
/** Threads every top-level and nested field's value through its hook chain. */
|
|
190
|
+
export async function runFieldHooks(collection, name, ctx) {
|
|
191
|
+
return runFieldMapHooks(collection.fields, name, { ...ctx, collection });
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type { AdapterSet, ForgeCmsConfig } from './config.js';
|
|
2
|
+
export type { OperationContext } from './context.js';
|
|
3
|
+
export { ForgeCmsRuntime } from './runtime.js';
|
|
4
|
+
export { handleList, handleRead, handleCreate, handleUpdate, handleDelete, handleGlobalRead, handleGlobalUpdate, handleListVersions, handleGetVersion, handleRestoreVersion, handlePreview, type HandlerOptions, type PreviewOptions, DEFAULT_LIMIT, MAX_LIMIT } from './handlers.js';
|
|
5
|
+
export { handleFile, type FileHandlerOptions } from './files.js';
|
|
6
|
+
export { applyFieldDefaults, applyAutoSlugs } from './defaults.js';
|
|
7
|
+
export { find, findByID, count, create, update, deleteDocument, type PaginatedDocs, type BaseOperationArgs, type FindArgs, type FindByIDArgs, type CountArgs, type CreateArgs, type UpdateArgs, type DeleteArgs } from './operations.js';
|
|
8
|
+
export { getGlobal, updateGlobal, type GlobalBaseArgs, type GetGlobalArgs, type UpdateGlobalArgs } from './globals.js';
|
|
9
|
+
export { listVersions, getVersion, restoreVersion, createVersion, versionsEnabled, autosaveEnabled, type ListVersionsArgs, type GetVersionArgs, type RestoreVersionArgs, type CreateVersionArgs } from './versions.js';
|
|
10
|
+
export { resolveLocale, getLocalizedValue, setLocalizedValue, isLocalizedCollection, isLocalizedField, extractLocaleFromRequest, resolveLocalizedDocument, storeLocalizedDocument } from './localization.js';
|
|
11
|
+
export { findRelationFields, findReferencingDocuments, checkDeleteRestrictions, handleCascadeDelete, handleSetNullOnDelete, findOrphanedDocuments } from './relation-integrity.js';
|
|
12
|
+
export { ForgeError, NotFoundError, InvalidInputError, InvalidQueryError, UnknownFieldError, ValidationFailedError, UnauthorizedError, AccessDeniedError, isForgeError, toApiErrorBody, type ForgeErrorCode, type ForgeApiErrorBody } from './errors.js';
|
|
13
|
+
export { populateRecord, populateRecords } from './populate.js';
|
|
14
|
+
export { describeCollection, describeCollections, describeFields, describeGlobal, describeGlobals, type CollectionDescription, type GlobalDescription, type FieldDescription, type BlockDescription } from './describe.js';
|
|
15
|
+
export { resolveAccess, resolveFieldAccess, mergeWhere, documentMatches, type AccessDecision } from './access.js';
|
|
16
|
+
export { runBeforeOperationHooks, runAfterOperationHooks, runBeforeValidateHooks, runBeforeChangeHooks, runAfterChangeHooks, runBeforeReadHooks, runAfterReadHooks, runBeforeDeleteHooks, runAfterDeleteHooks, runFieldHooks } from './hooks.js';
|
|
17
|
+
export { filterReadableFields, assertWritableFields, FieldAccessError } from './field-access.js';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,aAAa,EACb,SAAS,EACV,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGjE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGnE,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,MAAM,EACN,MAAM,EACN,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACtB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,YAAY,EACZ,UAAU,EACV,cAAc,EACd,aAAa,EACb,eAAe,EACf,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,eAAe,EACf,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export { ForgeCmsRuntime } from './runtime.js';
|
|
2
|
+
export { handleList, handleRead, handleCreate, handleUpdate, handleDelete, handleGlobalRead, handleGlobalUpdate, handleListVersions, handleGetVersion, handleRestoreVersion, handlePreview, DEFAULT_LIMIT, MAX_LIMIT } from './handlers.js';
|
|
3
|
+
// Serving stored files (spec 040)
|
|
4
|
+
export { handleFile } from './files.js';
|
|
5
|
+
// Field defaults and auto-slugs (spec 040)
|
|
6
|
+
export { applyFieldDefaults, applyAutoSlugs } from './defaults.js';
|
|
7
|
+
// Local API (spec 019) — the transport-free way to run CMS operations from server code.
|
|
8
|
+
export { find, findByID, count, create, update, deleteDocument } from './operations.js';
|
|
9
|
+
// Globals — singleton documents (site-wide config: nav, footer, SEO defaults).
|
|
10
|
+
export { getGlobal, updateGlobal } from './globals.js';
|
|
11
|
+
// Versions — document history, diff, restore.
|
|
12
|
+
export { listVersions, getVersion, restoreVersion, createVersion, versionsEnabled, autosaveEnabled } from './versions.js';
|
|
13
|
+
// Localization — i18n fields, locale resolution, fallback chain.
|
|
14
|
+
export { resolveLocale, getLocalizedValue, setLocalizedValue, isLocalizedCollection, isLocalizedField, extractLocaleFromRequest, resolveLocalizedDocument, storeLocalizedDocument } from './localization.js';
|
|
15
|
+
// Relation integrity — cascade, restrict, set-null on delete.
|
|
16
|
+
export { findRelationFields, findReferencingDocuments, checkDeleteRestrictions, handleCascadeDelete, handleSetNullOnDelete, findOrphanedDocuments } from './relation-integrity.js';
|
|
17
|
+
export { ForgeError, NotFoundError, InvalidInputError, InvalidQueryError, UnknownFieldError, ValidationFailedError, UnauthorizedError, AccessDeniedError, isForgeError, toApiErrorBody } from './errors.js';
|
|
18
|
+
export { populateRecord, populateRecords } from './populate.js';
|
|
19
|
+
// Schema metadata for clients (the admin UI builds its form from this).
|
|
20
|
+
export { describeCollection, describeCollections, describeFields, describeGlobal, describeGlobals } from './describe.js';
|
|
21
|
+
// Access control (spec 020)
|
|
22
|
+
export { resolveAccess, resolveFieldAccess, mergeWhere, documentMatches } from './access.js';
|
|
23
|
+
// Hook pipeline (spec 021)
|
|
24
|
+
export { runBeforeOperationHooks, runAfterOperationHooks, runBeforeValidateHooks, runBeforeChangeHooks, runAfterChangeHooks, runBeforeReadHooks, runAfterReadHooks, runBeforeDeleteHooks, runAfterDeleteHooks, runFieldHooks } from './hooks.js';
|
|
25
|
+
export { filterReadableFields, assertWritableFields, FieldAccessError } from './field-access.js';
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EAGb,aAAa,EACb,SAAS,EACV,MAAM,eAAe,CAAC;AAEvB,kCAAkC;AAClC,OAAO,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAEjE,2CAA2C;AAC3C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEnE,wFAAwF;AACxF,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,MAAM,EACN,MAAM,EACN,cAAc,EASf,MAAM,iBAAiB,CAAC;AAEzB,+EAA+E;AAC/E,OAAO,EACL,SAAS,EACT,YAAY,EAIb,MAAM,cAAc,CAAC;AAEtB,8CAA8C;AAC9C,OAAO,EACL,YAAY,EACZ,UAAU,EACV,cAAc,EACd,aAAa,EACb,eAAe,EACf,eAAe,EAKhB,MAAM,eAAe,CAAC;AAEvB,iEAAiE;AACjE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,8DAA8D;AAC9D,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EAGf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhE,wEAAwE;AACxE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,eAAe,EAKhB,MAAM,eAAe,CAAC;AAEvB,4BAA4B;AAC5B,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,eAAe,EAEhB,MAAM,aAAa,CAAC;AAErB,2BAA2B;AAC3B,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { CollectionDefinition } from '@forge-cms/core';
|
|
2
|
+
/**
|
|
3
|
+
* Localization utilities for handling localized fields and locale resolution.
|
|
4
|
+
*
|
|
5
|
+
* Localized fields store values as objects with locale codes as keys:
|
|
6
|
+
* `{ en: "Hello", es: "Hola" }`
|
|
7
|
+
*
|
|
8
|
+
* Locale resolution follows a fallback chain:
|
|
9
|
+
* - Exact match: `es-MX` -> value for `es-MX`
|
|
10
|
+
* - Language fallback: `es-MX` -> value for `es`
|
|
11
|
+
* - Default fallback: first locale in collection's locales array
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Resolves the locale to use for reading a localized field.
|
|
15
|
+
* Returns the best matching locale from the available locales.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveLocale(requestedLocale: string | undefined, availableLocales: string[]): string;
|
|
18
|
+
/**
|
|
19
|
+
* Gets the value for a specific locale from a localized field value.
|
|
20
|
+
* Implements fallback chain: exact -> language -> default.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getLocalizedValue(localizedValue: Record<string, unknown> | unknown, locale: string, availableLocales: string[]): unknown;
|
|
23
|
+
/**
|
|
24
|
+
* Sets a value for a specific locale in a localized field.
|
|
25
|
+
* Returns the updated localized value object.
|
|
26
|
+
*/
|
|
27
|
+
export declare function setLocalizedValue(currentValue: Record<string, unknown> | unknown, locale: string, newValue: unknown): Record<string, unknown>;
|
|
28
|
+
/**
|
|
29
|
+
* Checks if a collection has localization enabled.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isLocalizedCollection(collection: CollectionDefinition): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Checks if a field is localized.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isLocalizedField(field: {
|
|
36
|
+
options: {
|
|
37
|
+
localized?: boolean;
|
|
38
|
+
};
|
|
39
|
+
}): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Extracts the locale from query parameters or headers.
|
|
42
|
+
*/
|
|
43
|
+
export declare function extractLocaleFromRequest(request: Request, collection: CollectionDefinition): string | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Processes a document for reading, resolving localized fields to the requested locale.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveLocalizedDocument(document: Record<string, unknown>, collection: CollectionDefinition, locale: string | undefined): Record<string, unknown>;
|
|
48
|
+
/**
|
|
49
|
+
* Processes a document for writing, storing values in the appropriate locale.
|
|
50
|
+
*/
|
|
51
|
+
export declare function storeLocalizedDocument(data: Record<string, unknown>, collection: CollectionDefinition, locale: string | undefined, existing?: Record<string, unknown>): Record<string, unknown>;
|
|
52
|
+
//# sourceMappingURL=localization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localization.d.ts","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D;;;;;;;;;;GAUG;AAEH;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,gBAAgB,EAAE,MAAM,EAAE,GACzB,MAAM,CAwBR;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EACjD,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,EAAE,GACzB,OAAO,CAgCT;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAC/C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,OAAO,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAE/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,GAAG,OAAO,CAErF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,oBAAoB,GAC/B,MAAM,GAAG,SAAS,CAkCpB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBzB"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Localization utilities for handling localized fields and locale resolution.
|
|
3
|
+
*
|
|
4
|
+
* Localized fields store values as objects with locale codes as keys:
|
|
5
|
+
* `{ en: "Hello", es: "Hola" }`
|
|
6
|
+
*
|
|
7
|
+
* Locale resolution follows a fallback chain:
|
|
8
|
+
* - Exact match: `es-MX` -> value for `es-MX`
|
|
9
|
+
* - Language fallback: `es-MX` -> value for `es`
|
|
10
|
+
* - Default fallback: first locale in collection's locales array
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Resolves the locale to use for reading a localized field.
|
|
14
|
+
* Returns the best matching locale from the available locales.
|
|
15
|
+
*/
|
|
16
|
+
export function resolveLocale(requestedLocale, availableLocales) {
|
|
17
|
+
if (!requestedLocale || availableLocales.length === 0) {
|
|
18
|
+
return availableLocales[0] ?? 'en';
|
|
19
|
+
}
|
|
20
|
+
// Exact match
|
|
21
|
+
if (availableLocales.includes(requestedLocale)) {
|
|
22
|
+
return requestedLocale;
|
|
23
|
+
}
|
|
24
|
+
// Language fallback (e.g., es-MX -> es)
|
|
25
|
+
const language = requestedLocale.split('-')[0];
|
|
26
|
+
if (language && availableLocales.includes(language)) {
|
|
27
|
+
return language;
|
|
28
|
+
}
|
|
29
|
+
// Find any locale with matching language prefix
|
|
30
|
+
const matchingLocale = availableLocales.find((locale) => locale.startsWith(language + '-'));
|
|
31
|
+
if (matchingLocale) {
|
|
32
|
+
return matchingLocale;
|
|
33
|
+
}
|
|
34
|
+
// Default to first available locale
|
|
35
|
+
return availableLocales[0] ?? 'en';
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Gets the value for a specific locale from a localized field value.
|
|
39
|
+
* Implements fallback chain: exact -> language -> default.
|
|
40
|
+
*/
|
|
41
|
+
export function getLocalizedValue(localizedValue, locale, availableLocales) {
|
|
42
|
+
if (typeof localizedValue !== 'object' ||
|
|
43
|
+
localizedValue === null ||
|
|
44
|
+
Array.isArray(localizedValue)) {
|
|
45
|
+
return localizedValue;
|
|
46
|
+
}
|
|
47
|
+
const valueObj = localizedValue;
|
|
48
|
+
const resolvedLocale = resolveLocale(locale, availableLocales);
|
|
49
|
+
// Try exact locale
|
|
50
|
+
if (valueObj[resolvedLocale] !== undefined) {
|
|
51
|
+
return valueObj[resolvedLocale];
|
|
52
|
+
}
|
|
53
|
+
// Try language fallback
|
|
54
|
+
const language = resolvedLocale.split('-')[0];
|
|
55
|
+
if (language && valueObj[language] !== undefined) {
|
|
56
|
+
return valueObj[language];
|
|
57
|
+
}
|
|
58
|
+
// Try default locale (first in array)
|
|
59
|
+
const defaultLocale = availableLocales[0];
|
|
60
|
+
if (defaultLocale && valueObj[defaultLocale] !== undefined) {
|
|
61
|
+
return valueObj[defaultLocale];
|
|
62
|
+
}
|
|
63
|
+
// Return first available value
|
|
64
|
+
const firstKey = Object.keys(valueObj)[0];
|
|
65
|
+
return firstKey ? valueObj[firstKey] : undefined;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Sets a value for a specific locale in a localized field.
|
|
69
|
+
* Returns the updated localized value object.
|
|
70
|
+
*/
|
|
71
|
+
export function setLocalizedValue(currentValue, locale, newValue) {
|
|
72
|
+
const existing = typeof currentValue === 'object' && currentValue !== null && !Array.isArray(currentValue)
|
|
73
|
+
? { ...currentValue }
|
|
74
|
+
: {};
|
|
75
|
+
existing[locale] = newValue;
|
|
76
|
+
return existing;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Checks if a collection has localization enabled.
|
|
80
|
+
*/
|
|
81
|
+
export function isLocalizedCollection(collection) {
|
|
82
|
+
return collection.locales !== undefined && collection.locales.length > 0;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Checks if a field is localized.
|
|
86
|
+
*/
|
|
87
|
+
export function isLocalizedField(field) {
|
|
88
|
+
return field.options.localized === true;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Extracts the locale from query parameters or headers.
|
|
92
|
+
*/
|
|
93
|
+
export function extractLocaleFromRequest(request, collection) {
|
|
94
|
+
// Try query parameter first
|
|
95
|
+
const url = new URL(request.url);
|
|
96
|
+
const queryLocale = url.searchParams.get('locale');
|
|
97
|
+
if (queryLocale && collection.locales?.includes(queryLocale)) {
|
|
98
|
+
return queryLocale;
|
|
99
|
+
}
|
|
100
|
+
// Try Accept-Language header
|
|
101
|
+
const acceptLanguage = request.headers.get('accept-language');
|
|
102
|
+
if (acceptLanguage && collection.locales) {
|
|
103
|
+
// Parse Accept-Language header (e.g., "en-US,en;q=0.9,es;q=0.8")
|
|
104
|
+
const languages = acceptLanguage.split(',').map((lang) => {
|
|
105
|
+
const [code, q] = lang.trim().split(';q=');
|
|
106
|
+
return { code: code?.trim(), quality: q ? parseFloat(q) : 1.0 };
|
|
107
|
+
});
|
|
108
|
+
// Sort by quality descending
|
|
109
|
+
languages.sort((a, b) => b.quality - a.quality);
|
|
110
|
+
// Find first matching locale
|
|
111
|
+
for (const { code } of languages) {
|
|
112
|
+
if (code && collection.locales.includes(code)) {
|
|
113
|
+
return code;
|
|
114
|
+
}
|
|
115
|
+
// Try language fallback
|
|
116
|
+
const language = code?.split('-')[0];
|
|
117
|
+
if (language && collection.locales.includes(language)) {
|
|
118
|
+
return language;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Processes a document for reading, resolving localized fields to the requested locale.
|
|
126
|
+
*/
|
|
127
|
+
export function resolveLocalizedDocument(document, collection, locale) {
|
|
128
|
+
if (!isLocalizedCollection(collection) || !locale) {
|
|
129
|
+
return document;
|
|
130
|
+
}
|
|
131
|
+
const resolved = {};
|
|
132
|
+
for (const [fieldName, value] of Object.entries(document)) {
|
|
133
|
+
const field = collection.fields[fieldName];
|
|
134
|
+
if (field && isLocalizedField(field)) {
|
|
135
|
+
resolved[fieldName] = getLocalizedValue(value, locale, collection.locales);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
resolved[fieldName] = value;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return resolved;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Processes a document for writing, storing values in the appropriate locale.
|
|
145
|
+
*/
|
|
146
|
+
export function storeLocalizedDocument(data, collection, locale, existing) {
|
|
147
|
+
if (!isLocalizedCollection(collection) || !locale) {
|
|
148
|
+
return data;
|
|
149
|
+
}
|
|
150
|
+
const stored = {};
|
|
151
|
+
for (const [fieldName, value] of Object.entries(data)) {
|
|
152
|
+
const field = collection.fields[fieldName];
|
|
153
|
+
if (field && isLocalizedField(field)) {
|
|
154
|
+
const existingValue = existing?.[fieldName];
|
|
155
|
+
stored[fieldName] = setLocalizedValue(existingValue, locale, value);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
stored[fieldName] = value;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return stored;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=localization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localization.js","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { CmsUser, DraftStatus } from '@forge-cms/core';
|
|
2
|
+
import type { DatabaseRecord, DatabaseWhere } from '@forge-cms/db';
|
|
3
|
+
import type { OperationContext } from './context.js';
|
|
4
|
+
import { populateRecord, populateRecords } from './populate.js';
|
|
5
|
+
/** A page of documents plus everything a paginator needs. */
|
|
6
|
+
export interface PaginatedDocs<TDoc = DatabaseRecord> {
|
|
7
|
+
docs: TDoc[];
|
|
8
|
+
/** Total documents matching the query, ignoring limit/offset. */
|
|
9
|
+
totalDocs: number;
|
|
10
|
+
limit: number | undefined;
|
|
11
|
+
offset: number;
|
|
12
|
+
/** 1-based page number derived from limit/offset; always 1 when unpaginated. */
|
|
13
|
+
page: number;
|
|
14
|
+
totalPages: number;
|
|
15
|
+
hasNextPage: boolean;
|
|
16
|
+
hasPrevPage: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface BaseOperationArgs {
|
|
19
|
+
collection: string;
|
|
20
|
+
/**
|
|
21
|
+
* The user the operation runs as. `null`/omitted means anonymous.
|
|
22
|
+
*/
|
|
23
|
+
user?: CmsUser | null;
|
|
24
|
+
/**
|
|
25
|
+
* Skip collection- and field-level access checks. Defaults to **true**: a direct Local API call
|
|
26
|
+
* comes from trusted server code that has already decided it is allowed to do this. The HTTP layer
|
|
27
|
+
* always passes `false` so requests from the network are checked.
|
|
28
|
+
*/
|
|
29
|
+
overrideAccess?: boolean;
|
|
30
|
+
/** `1` replaces relation ids with the related document. Only one level is supported. */
|
|
31
|
+
depth?: 0 | 1;
|
|
32
|
+
/** Locale for reading/writing localized fields. */
|
|
33
|
+
locale?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface FindArgs extends BaseOperationArgs {
|
|
36
|
+
where?: DatabaseWhere;
|
|
37
|
+
limit?: number;
|
|
38
|
+
offset?: number;
|
|
39
|
+
sort?: string;
|
|
40
|
+
order?: 'asc' | 'desc';
|
|
41
|
+
/** Only meaningful on a `drafts: true` collection. Defaults to `published`. */
|
|
42
|
+
status?: DraftStatus | 'all';
|
|
43
|
+
}
|
|
44
|
+
export interface FindByIDArgs extends BaseOperationArgs {
|
|
45
|
+
id: string;
|
|
46
|
+
}
|
|
47
|
+
export interface CountArgs extends BaseOperationArgs {
|
|
48
|
+
where?: DatabaseWhere;
|
|
49
|
+
status?: DraftStatus | 'all';
|
|
50
|
+
}
|
|
51
|
+
export interface CreateArgs extends BaseOperationArgs {
|
|
52
|
+
data: Record<string, unknown>;
|
|
53
|
+
}
|
|
54
|
+
export interface UpdateArgs extends BaseOperationArgs {
|
|
55
|
+
id: string;
|
|
56
|
+
data: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
export interface DeleteArgs extends BaseOperationArgs {
|
|
59
|
+
id: string;
|
|
60
|
+
}
|
|
61
|
+
export declare function find(ctx: OperationContext, args: FindArgs): Promise<PaginatedDocs>;
|
|
62
|
+
export declare function findByID(ctx: OperationContext, args: FindByIDArgs & {
|
|
63
|
+
status?: DraftStatus | 'all';
|
|
64
|
+
}): Promise<DatabaseRecord>;
|
|
65
|
+
export declare function count(ctx: OperationContext, args: CountArgs): Promise<number>;
|
|
66
|
+
export declare function create(ctx: OperationContext, args: CreateArgs): Promise<DatabaseRecord>;
|
|
67
|
+
export declare function update(ctx: OperationContext, args: UpdateArgs): Promise<DatabaseRecord>;
|
|
68
|
+
export declare function deleteDocument(ctx: OperationContext, args: DeleteArgs): Promise<DatabaseRecord>;
|
|
69
|
+
export { populateRecord, populateRecords };
|
|
70
|
+
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../src/operations.ts"],"names":[],"mappings":"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"}
|