// deno-lint-ignore-file no-explicit-any import type Collection from "./core/collection.ts"; import type Document from "./core/document.ts"; import type Upload from "./core/upload.ts"; import type Git from "./core/git.ts"; import type { CmsOptions, CollectionOptions, DocumentOptions, UploadOptions, } from "./core/cms.ts"; import type { Options as GitOptions } from "./core/git.ts"; /** Generic data to store */ export type Data = Record; /** A storage entry source information */ export interface EntrySource { /** The entry name (i.e: "index.md") */ name: string; /** The full path of the entry (i.e: "posts/index.md") */ path: string; /** The full location of the entry (i.e: the raw GitHub file URL) */ src: string; } export interface DocumentLabel { label: string; icon?: string; flags?: Record; } export type EntryMetadata = EntrySource & DocumentLabel; export interface SiteInfo { name?: string; description?: string; url?: string; body?: string; } export interface AuthProviderOptions { basePath: string; users: Map; } /** The interface to implement different auth providers */ export interface AuthProvider { init(options: AuthProviderOptions): void; login(request: Request): Response | string | Promise; logout(request: Request): Response | Promise; fetch(request: Request): Response | Promise; } /** A storage mechanism for data */ export interface Storage extends AsyncIterable { name(name?: string): string; get(name: string): Entry; source(name: string): EntrySource; directory(name: string): Storage; delete(name: string): void | Promise; rename(name: string, newName: string): void | Promise; } export interface Entry { readonly storage: Storage; readonly source: EntrySource; readData(): Data | Promise; writeData(content: Data): void | Promise; readText(): string | Promise; writeText(content: string): void | Promise; readFile(): File | Promise; writeFile(content: File): void | Promise; } export interface Version { name: string; isCurrent: boolean; isProduction: boolean; } /** A transformer to convert from/to Data */ export interface Transformer { toData(content: T): Data | Promise; fromData(data: Data): T | Promise; } export interface Field { /** The name of the field */ name: string; /** The type of the field */ type: string; /** Default value when a new document is created */ value?: V; /** Function to execute on init the field */ init?( field: T, content: CMSContent, data?: Data, document?: Document, ): void | Promise; /** Function to transform the value before saved */ transform?(value: any): any; } export interface ResolvedField { /** View name in which this field is visible */ view?: string; /** Function to apply the changes in the data object */ applyChanges( data: Data, changes: Data, field: T, document: Document, content: CMSContent, ): void | Promise; } /** A field definition to be used by the CMS */ export type FieldDefinition< T extends ResolvedField & Field = ResolvedField & Field, > = { /** The tagName used in the HTML for the custom element */ tag: string; /** The JavaScript import path for the custom element */ jsImport: string; /** Function to execute on init the field definition */ init?( field: T, content: CMSContent, data?: Data, document?: Document, ): void | Promise; /** Function to apply the changes in the data object */ applyChanges( data: Data, changes: Data, field: T, document: Document, content: CMSContent, ): void | Promise; transform?(value: T["value"]): T["value"] | unknown; }; /** Option item for a select or datalist */ export type Option = T | { value: T; label: string }; export interface ResolvedGroupField extends ResolvedField { /** The fields that belong to this group */ fields: Lume.CMS.ResolvedField[]; } /** A function to generate a preview URL for a file */ export type PreviewUrl = ( file: string, cms: CMSContent, changed: boolean, storage: Storage, ) => undefined | string | Promise; /** Field visible in the UI */ export interface UIField extends Field { /** The visible name in the UI. If it's not defined, the name option will be used. */ label?: string; /** An optional description visible next to the label in the UI. */ description?: string; /** View name in which this field is visible */ view?: string; /** CSS selector to highlight the element in the preview panel */ cssSelector?: string; } /** Field for input values */ export interface InputField< T extends ResolvedField = ResolvedField, A = Record, > extends UIField { attributes?: Prettify; } /** Field for groups */ export interface GroupField extends UIField { /** The fields that belong to this group */ fields: Lume.CMS.Field[]; } /** Common attributes for inputs */ export interface InputAttributes { /** Whether the value is required or not */ required?: boolean; /** The placeholder text */ placeholder?: string; /** If it's true, the value can't be edited by the user */ readonly?: boolean; [key: string]: unknown; } /** Pretty */ type Prettify = & { [K in keyof T]: T[K]; } // deno-lint-ignore ban-types & {}; export type Labelizer = (name: string) => string | DocumentLabel; export interface CMSContent { basePath: string; site: SiteInfo; collections: Record; documents: Record; uploads: Record; git?: Git; data: Record; } export interface UserConfiguration { password: string; name?: string; email?: string; language?: string; permissions?: Record; } export interface Permissions { create?: boolean; delete?: boolean; edit?: boolean; rename?: boolean; } declare global { namespace Lume.CMS { type FieldStrings = `${string}:${" " | ""}${keyof Fields}${ | "!" | ""}`; export type Field = | Fields[keyof Fields] | ParentFields[keyof ParentFields] | FieldStrings; export type ResolvedField = ResolvedFields[keyof ResolvedFields]; export type { CMSContent as Content, CmsOptions, CollectionOptions, DocumentOptions, GitOptions, UploadOptions, }; } }