/** */ import { Database } from '../database'; import type { Collectable, Collection, Template, TinaField, TinaSchema } from '@tinacms/schema-tools'; import type { GraphQLConfig } from '../types'; interface ResolverConfig { config?: GraphQLConfig; database: Database; tinaSchema: TinaSchema; isAudit: boolean; } export declare const createResolver: (args: ResolverConfig) => Resolver; export declare const resolveFieldData: ({ namespace, ...field }: TinaField, rawData: unknown, accumulator: { [key: string]: unknown; }, tinaSchema: TinaSchema, config?: GraphQLConfig, isAudit?: boolean) => Promise<{ [key: string]: unknown; }>; export declare const transformDocumentIntoPayload: (fullPath: string, rawData: { _collection: any; _template: any; }, tinaSchema: TinaSchema, config?: GraphQLConfig, isAudit?: boolean, hasReferences?: boolean) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }>; /** * Updates a property in an object using a JSONPath. * @param obj - The object to update. * @param path - The JSONPath string. * @param newValue - The new value to set at the specified path. * @returns the updated object. */ export declare const updateObjectWithJsonPath: (obj: any, path: string, oldValue: any, newValue: any) => { object: any; updated: boolean; }; /** * The resolver provides functions for all possible types of lookup * values and retrieves them from the database */ export declare class Resolver { init: ResolverConfig; config: GraphQLConfig; database: Database; tinaSchema: TinaSchema; isAudit: boolean; constructor(init: ResolverConfig); resolveCollection: (_args: any, collectionName: string, hasDocuments?: boolean) => Promise<{ fields: TinaField[]; templates?: undefined; label?: string; name: string; path: string; indexes?: { name: string; fields: { name: string; }[]; }[]; format?: import("@tinacms/schema-tools").ContentFormat; ui?: import("@tinacms/schema-tools").UICollection; defaultItem?: import("@tinacms/schema-tools").DefaultItem>; frontmatterFormat?: import("@tinacms/schema-tools").ContentFrontmatterFormat; frontmatterDelimiters?: [string, string] | string; yamlMaxLineWidth?: number; match?: { include?: string; exclude?: string; }; isDetached?: boolean; isAuthCollection?: boolean; namespace: string[]; documents: { collection: Collection; hasDocuments: boolean; }; } | { templates: Template[]; fields?: undefined; label?: string; name: string; path: string; indexes?: { name: string; fields: { name: string; }[]; }[]; format?: import("@tinacms/schema-tools").ContentFormat; ui?: import("@tinacms/schema-tools").UICollection; defaultItem?: import("@tinacms/schema-tools").DefaultItem>; frontmatterFormat?: import("@tinacms/schema-tools").ContentFrontmatterFormat; frontmatterDelimiters?: [string, string] | string; yamlMaxLineWidth?: number; match?: { include?: string; exclude?: string; }; isDetached?: boolean; isAuthCollection?: boolean; namespace: string[]; documents: { collection: Collection; hasDocuments: boolean; }; }>; getRaw: (fullPath: unknown) => Promise<{ _collection: string; _template: string; }>; getDocumentOrDirectory: (fullPath: unknown) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; } | { __typename: string; name: any; path: any; }>; getDocument: (fullPath: unknown, opts?: { collection?: Collection; checkReferences?: boolean; }) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }>; deleteDocument: (fullPath: unknown) => Promise; buildObjectMutations: (fieldValue: any, field: Collectable, existingData?: Record | Record[]) => Promise<{ [key: string]: unknown; } | { [key: string]: unknown; }[] | { _template: string; }[]>; resolveAddPendingDocument: ({ collectionName, relativePath, templateName, }: { collectionName: string; relativePath: string; templateName: string; }) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }>; /** * Returns top-level fields which are not defined in the collection, so their * values are not eliminated from Tina when new values are saved */ resolveLegacyValues: (oldDoc: any, collection: Collection) => {}; private getCollectionWithName; /** * validatePath ensures that the provided path remains within the boundaries * of the collection's directory and that the file extension matches the * collection's configured format. This is a critical security check to prevent * path traversal attacks where a user might attempt to read or write files * outside of the intended collection. */ private static sanitizePath; /** * Validates that relativePath is non-empty and contains only allowed * characters: a-z, A-Z, 0-9, hyphens, underscores, periods, and * forward slashes. */ private static validateRelativePath; private validatePath; /** * Helper method to get collection and construct validated path. * This encapsulates the common pattern of getting a collection, joining paths, * and validating the result, ensuring security checks are always performed. * * @param collectionName - Name of the collection * @param relativePath - Relative path within the collection * @param options - Optional configuration * @returns Object containing the collection and validated real path */ private getValidatedPath; resolveRetrievedDocument: ({ collectionName, relativePath, }: { collectionName: string; relativePath: string; }) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }>; resolveCreateFolder: ({ collectionName, relativePath, }: { collectionName: string; relativePath: string; }) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }>; resolveCreateDocument: ({ collectionName, relativePath, body, }: { collectionName: string; relativePath: string; body: Record; }) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }>; resolveUpdateDocument: ({ collectionName, relativePath, newRelativePath, newBody, }: { collectionName: string; relativePath: string; newRelativePath?: string; newBody?: Record; }) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }>; resolveDeleteDocument: ({ collectionName, relativePath, }: { collectionName: string; relativePath: string; }) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }>; private resolveAndValidateCollection; /** * @deprecated - To be removed in next major version. */ createResolveDocument: ({ collection, realPath, args, isAddPendingDocument, }: { collection: Collection; realPath: string; args: unknown; isAddPendingDocument: boolean; }) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }>; /** * @deprecated - To be removed in next major version. */ updateResolveDocument: ({ collection, realPath, args, isAddPendingDocument, isCollectionSpecific, }: { collection: Collection; realPath: string; args: unknown; isAddPendingDocument: boolean; isCollectionSpecific: boolean; }) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }>; /** * @deprecated */ resolveDocument: ({ args, collection: collectionName, isMutation, isCreation, isDeletion, isFolderCreation, isAddPendingDocument, isCollectionSpecific, isUpdateName, }: { args: unknown; collection?: string; isMutation: boolean; isCreation?: boolean; isDeletion?: boolean; isFolderCreation?: boolean; isAddPendingDocument?: boolean; isCollectionSpecific?: boolean; isUpdateName?: boolean; }) => Promise<{ _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }>; resolveCollectionConnections: ({ ids }: { ids: string[]; }) => Promise<{ totalCount: number; edges: { node: { _sys: { title: any; basename: string; filename: string; extension: string; hasReferences: boolean; path: string; relativePath: string; breadcrumbs: string[]; collection: Collection; template: string | number; }; _values: { _collection: any; _template: any; }; _rawData: { _collection: any; _template: any; }; _collection: any; _template: any; __typename: string; id: string; }; }[]; }>; private referenceResolver; private resolveFilterConditions; resolveCollectionConnection: ({ args, collection, hydrator, }: { args: Record | string | number>; collection: Collection; hydrator?: (string: any) => any; }) => Promise<{ totalCount: number; edges: { node: any; cursor: string; }[]; pageInfo: { hasPreviousPage: boolean; hasNextPage: boolean; startCursor: string; endCursor: string; }; }>; /** * Checks if a document has references to it * @param id The id of the document to check for references * @param c The collection to check for references * @returns true if the document has references, false otherwise */ private hasReferences; /** * Finds references to a document * @param id the id of the document to find references to * @param c the collection to find references in * @returns a map of references to the document */ private findReferences; private buildFieldMutations; /** * A mutation looks nearly identical between updateDocument: * ```graphql * updateDocument(collection: $collection,relativePath: $path, params: { * post: { * title: "Hello, World" * } * })` * ``` * and `updatePostDocument`: * ```graphql * updatePostDocument(relativePath: $path, params: { * title: "Hello, World" * }) * ``` * The problem here is that we don't know whether the payload came from `updateDocument` * or `updatePostDocument` (we could, but for now it's easier not to pipe those details through), * But we do know that when given a `args.collection` value, we can assume that * this was a `updateDocument` request, and thus - should grab the data * from the corresponding field name in the key */ private buildParams; } export {};