@nuxt/content
Version:
Write your content inside your Nuxt app
687 lines (665 loc) • 22.1 kB
text/typescript
import * as _nuxt_schema from '@nuxt/schema';
import { ListenOptions } from 'listhen';
import { BuiltinTheme, ThemeRegistrationRaw, BuiltinLanguage, LanguageRegistration, ThemeRegistrationAny } from 'shiki';
import { Toc, Highlighter } from '@nuxtjs/mdc';
export { Toc, TocLink } from '@nuxtjs/mdc';
import { MinimarkText, MinimarkElement, MinimarkNode, MinimarkTree } from 'minimark';
export { MinimarkElement, MinimarkNode, MinimarkText, MinimarkTree } from 'minimark';
import { StandardSchemaV1 } from '@standard-schema/spec';
import * as c12 from 'c12';
import { z as z$1 } from 'zod';
import { Primitive, Connector } from 'db0';
interface GitInfo {
name: string;
owner: string;
url: string;
}
/**
* @deprecated Use `MinimarkText` instead
*/
type MinimalText = MinimarkText;
/**
* @deprecated Use `MinimarkElement` instead
*/
type MinimalElement = MinimarkElement;
/**
* @deprecated Use `MinimarkNode` instead
*/
type MinimalNode = MinimarkNode;
/**
* @deprecated Use `MinimarkTree` instead
*/
type MinimalTree = {
type: 'minimal';
value: MinimalNode[];
};
interface ContentFile extends Record<string, unknown> {
id: string;
body: string;
path: string;
dirname?: string;
extension?: string;
}
interface TransformedContent {
id: string;
/**
* `__metadata` is a special field that transformers can provide information about the file.
* This field will not be stored in the database.
*/
__metadata?: {
components?: string[];
[key: string]: unknown;
};
[key: string]: unknown;
}
interface TransformContentOptions {
transformers?: ContentTransformer[];
[key: string]: unknown;
}
type ContentTransformer = {
name: string;
extensions: string[];
parse(file: ContentFile, options: Record<string, unknown>): Promise<TransformedContent> | TransformedContent;
transform?(content: TransformedContent, options: Record<string, unknown>): Promise<TransformedContent> | TransformedContent;
} | {
name: string;
extensions: string[];
parse?(file: ContentFile, options: Record<string, unknown>): Promise<TransformedContent> | TransformedContent;
transform(content: TransformedContent, options: Record<string, unknown>): Promise<TransformedContent> | TransformedContent;
};
interface MarkdownPlugin extends Record<string, unknown> {
instance?: unknown;
options?: Record<string, unknown>;
}
interface MarkdownOptions {
/**
* Enable/Disable MDC components.
*/
mdc: boolean;
toc: {
/**
* Maximum heading depth to include in the table of contents.
*/
depth: number;
searchDepth: number;
};
tags: Record<string, string>;
remarkPlugins: Record<string, false | MarkdownPlugin>;
rehypePlugins: Record<string, false | MarkdownPlugin>;
highlight?: {
highlighter?: Highlighter;
[key: string]: unknown;
};
}
declare const ContentFileExtension: {
readonly Markdown: "md";
readonly Yaml: "yaml";
readonly Yml: "yml";
readonly Json: "json";
readonly Csv: "csv";
readonly Xml: "xml";
};
declare const ContentFileType: {
readonly Markdown: "markdown";
readonly Yaml: "yaml";
readonly Json: "json";
readonly Csv: "csv";
};
interface MarkdownRoot extends MinimarkTree {
props?: Record<string, unknown>;
toc?: Toc;
}
interface ParsedContentFile extends TransformedContent {
}
interface SlugifyOptions {
/**
* Characters to remove from the slug
*
* @default undefined
*/
remove?: RegExp;
replacement?: string;
/**
* Convert the slug to lowercase
*
* @default true
*/
lower?: boolean;
strict?: boolean;
locale?: string;
trim?: boolean;
}
interface PathMetaOptions {
/**
* If set to `true`, the path will be prefixed with a leading slash.
*
* @default true
*/
forceLeadingSlash?: boolean;
/**
* Slugify options
*
* @see https://github.com/simov/slugify#options
*/
slugifyOptions?: SlugifyOptions;
}
interface D1DatabaseConfig {
type: 'd1';
bindingName: string;
/**
* @deprecated Use `bindingName` instead
*/
binding?: string;
}
interface SqliteDatabaseConfig {
type: 'sqlite';
filename: string;
}
type PostgreSQLDatabaseConfig = {
type: 'postgres';
url: string;
};
type LibSQLDatabaseConfig = {
type: 'libsql';
/**
* The URL of the libSQL/Turso database
*/
url: string;
/**
* The authentication token for the libSQL/Turso database
*/
authToken: string;
};
interface PreviewOptions {
/**
* Enable preview in production by setting API URL
*/
api?: string;
/**
* Enable preview mode in development
*/
dev?: boolean;
/**
* Override Git information for preview validation
*/
gitInfo?: GitInfo;
}
interface ModuleOptions {
/**
* @private
* @default { type: 'sqlite', filename: '.data/content/local.db' }
*/
_localDatabase: SqliteDatabaseConfig | D1DatabaseConfig;
/**
* Production database configuration
* @default { type: 'sqlite', filename: './contents.sqlite' }
*/
database: D1DatabaseConfig | SqliteDatabaseConfig | PostgreSQLDatabaseConfig | LibSQLDatabaseConfig;
/**
* Preview mode configuration
* @default {}
*/
preview?: PreviewOptions;
/**
* Development HMR
* @default { enabled: true }
*/
watch?: Partial<ListenOptions> & {
enabled?: boolean;
};
renderer: {
/**
* Tags will be used to replace markdown components and render custom components instead of default ones.
*
* @default {}
*/
alias?: Record<string, string>;
/**
* Anchor link generation config
*
* @default {}
*/
anchorLinks?: boolean | Partial<Record<'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6', boolean>>;
};
build: {
/**
* List of user-defined transformers.
*/
transformers?: string[];
markdown?: {
/**
* Control behavior of Table of Contents generation
*/
toc?: {
/**
* Maximum heading depth that includes in the table of contents.
*
* @default 2
*/
depth?: number;
/**
* Maximum depth of nested tags to search for heading.
*
* @default 2
*/
searchDepth?: number;
};
/**
* By default, Nuxt Content extracts content from the first H1 heading and paragraphs below it.
* And uses this title and paragraph as default value for the `title` and `description` fields.
*
* Setting this option to `false` will disable this behavior.
*
* @default true
*/
contentHeading?: boolean;
/**
* Register custom remark plugin to provide new feature into your markdown contents.
* Checkout: https://github.com/remarkjs/remark/blob/main/doc/plugins.md
*
* @default []
*/
remarkPlugins?: Record<string, false | MarkdownPlugin>;
/**
* Register custom remark plugin to provide new feature into your markdown contents.
* Checkout: https://github.com/rehypejs/rehype/blob/main/doc/plugins.md
*
* @default []
*/
rehypePlugins?: Record<string, false | MarkdownPlugin>;
/**
* Content module uses `shiki` to highlight code blocks.
* You can configure Shiki options to control its behavior.
*/
highlight?: false | {
/**
* Default theme that will be used for highlighting code blocks.
*/
theme?: BuiltinTheme | {
default: BuiltinTheme | ThemeRegistrationRaw | string;
[theme: string]: BuiltinTheme | ThemeRegistrationRaw | string;
};
/**
* Preloaded languages that will be available for highlighting code blocks.
*
* @deprecated Use `langs` instead
*/
preload?: (BuiltinLanguage | LanguageRegistration)[];
/**
* Languages to be bundled loaded by Shiki
*
* All languages used has to be included in this list at build time, to create granular bundles.
*
* Unlike the `preload` option, when this option is provided, it will override the default languages.
*
* @default ['js','jsx','json','ts','tsx','vue','css','html','vue','bash','md','mdc','yaml']
*/
langs?: (BuiltinLanguage | LanguageRegistration)[];
/**
* Additional themes to be bundled loaded by Shiki.
*/
themes?: (BuiltinTheme | ThemeRegistrationAny)[];
};
};
pathMeta?: PathMetaOptions;
/**
* Options for yaml parser.
*
* @default {}
*/
yaml?: false | Record<string, unknown>;
/**
* Options for csv parser.
*
* @default {}
*/
csv?: false | {
json?: boolean;
delimiter?: string;
};
};
experimental?: {
/**
* Use Node.js native SQLite bindings instead of `better-sqlite3` if available
* Node.js SQLite introduced in v22.5.0
*
* @default false
* @deprecated Use `sqliteConnector: 'native'` instead
*/
nativeSqlite?: boolean;
/**
* Use given SQLite connector instead of `better-sqlite3` if available
*
* @default undefined
*/
sqliteConnector?: SQLiteConnector;
};
}
interface RuntimeConfig {
content: {
version: string;
databaseVersion: string;
database: D1DatabaseConfig | SqliteDatabaseConfig | PostgreSQLDatabaseConfig;
localDatabase: SqliteDatabaseConfig;
integrityCheck: boolean;
};
}
interface PublicRuntimeConfig {
preview: {
api?: string;
iframeMessagingAllowedOrigins?: string;
};
}
type SQLiteConnector = 'native' | 'sqlite3' | 'better-sqlite3';
interface Draft07 {
$schema: 'http://json-schema.org/draft-07/schema#';
$ref: string;
definitions: Record<string, Draft07Definition>;
}
interface Draft07Definition {
type: string;
properties: Record<string, Draft07DefinitionProperty | Draft07DefinitionPropertyAnyOf | Draft07DefinitionPropertyAllOf>;
required: string[];
additionalProperties: boolean;
}
interface Draft07DefinitionProperty {
type?: string;
items?: Draft07DefinitionProperty;
properties?: Record<string, Draft07DefinitionProperty>;
required?: string[];
default?: unknown;
maxLength?: number;
format?: string;
enum?: string[];
additionalProperties?: boolean | Record<string, Draft07DefinitionProperty>;
$content?: {
editor?: EditorOptions;
};
}
interface Draft07DefinitionPropertyAnyOf {
anyOf: Draft07DefinitionProperty[];
}
interface Draft07DefinitionPropertyAllOf {
allOf: Draft07DefinitionProperty[];
}
interface ContentConfig {
editor?: EditorOptions;
inherit?: string;
}
interface EditorOptions {
input?: 'media' | 'icon';
hidden?: boolean;
iconLibraries?: string[];
}
interface ContentStandardSchemaV1<Input = unknown, Output = Input> extends StandardSchemaV1<Input, Output> {
$content?: ContentConfig;
}
interface PageCollections {
}
interface Collections {
}
type CollectionType = 'page' | 'data';
type CollectionSource = {
include: string;
prefix?: string;
exclude?: string[];
repository?: string;
authToken?: string;
authBasic?: {
username: string;
password: string;
};
cwd?: string;
};
interface ResolvedCollectionSource extends CollectionSource {
_resolved: true;
prepare?: (opts: {
rootDir: string;
}) => Promise<void>;
getKeys?: () => Promise<string[]>;
getItem?: (path: string) => Promise<string>;
cwd: string;
}
interface CustomCollectionSource {
prepare?: (opts: {
rootDir: string;
}) => Promise<void>;
getKeys: () => Promise<string[]>;
getItem: (path: string) => Promise<string>;
}
interface ResolvedCustomCollectionSource extends ResolvedCollectionSource {
_custom: true;
}
interface PageCollection<T> {
type: 'page';
source?: string | CollectionSource | CollectionSource[] | ResolvedCustomCollectionSource;
schema?: ContentStandardSchemaV1<T>;
}
interface DataCollection<T> {
type: 'data';
source?: string | CollectionSource | CollectionSource[] | ResolvedCustomCollectionSource;
schema: ContentStandardSchemaV1<T>;
}
type Collection<T> = PageCollection<T> | DataCollection<T>;
interface DefinedCollection {
type: CollectionType;
source: ResolvedCollectionSource[] | undefined;
schema: Draft07;
extendedSchema: Draft07;
fields: Record<string, 'string' | 'number' | 'boolean' | 'date' | 'json'>;
}
interface ResolvedCollection extends DefinedCollection {
name: string;
tableName: string;
/**
* Whether the collection is private or not.
* Private collections will not be available in the runtime.
*/
private: boolean;
}
interface CollectionInfo {
name: string;
pascalName: string;
tableName: string;
source: ResolvedCollectionSource[];
type: CollectionType;
schema: Draft07;
fields: Record<string, 'string' | 'number' | 'boolean' | 'date' | 'json'>;
tableDefinition: string;
}
interface CollectionItemBase {
id: string;
stem: string;
extension: string;
meta: Record<string, unknown>;
}
interface PageCollectionItemBase extends CollectionItemBase {
path: string;
title: string;
description: string;
seo: {
title?: string;
description?: string;
[key: string]: unknown;
};
body: MarkdownRoot;
navigation?: boolean | {
title: string;
description: string;
icon: string;
};
}
interface DataCollectionItemBase extends CollectionItemBase {
}
interface ParserOptions {
pathMeta: PathMetaOptions;
markdown: {
compress: boolean;
rehypePlugins: Record<string, unknown>;
remarkPlugins: Record<string, unknown>;
[key: string]: unknown;
};
}
interface FileBeforeParseHook {
file: ContentFile;
collection: ResolvedCollection;
parserOptions: ParserOptions;
}
interface FileAfterParseHook {
file: ContentFile;
content: ParsedContentFile;
collection: ResolvedCollection;
}
declare module '@nuxt/schema' {
interface NuxtHooks {
'content:file:beforeParse': (ctx: FileBeforeParseHook) => Promise<void> | void;
'content:file:afterParse': (ctx: FileAfterParseHook) => Promise<void> | void;
}
}
interface ContentNavigationItem {
title: string;
path: string;
stem?: string;
children?: ContentNavigationItem[];
page?: false;
[key: string]: unknown;
}
interface SurroundOptions<T> {
before?: number;
after?: number;
fields?: Array<T>;
}
type SQLOperator = '=' | '>=' | '<=' | '>' | '<' | '<>' | 'IN' | 'BETWEEN' | 'NOT BETWEEN' | 'IS NULL' | 'IS NOT NULL' | 'LIKE' | 'NOT LIKE';
type QueryGroupFunction<T> = (group: CollectionQueryGroup<T>) => CollectionQueryGroup<T>;
interface CollectionQueryBuilder<T> {
path(path: string): CollectionQueryBuilder<T>;
select<K extends keyof T>(...fields: K[]): CollectionQueryBuilder<Pick<T, K>>;
order(field: keyof T, direction: 'ASC' | 'DESC'): CollectionQueryBuilder<T>;
skip(skip: number): CollectionQueryBuilder<T>;
limit(limit: number): CollectionQueryBuilder<T>;
all(): Promise<T[]>;
first(): Promise<T | null>;
count(field?: keyof T | '*', distinct?: boolean): Promise<number>;
where(field: string, operator: SQLOperator, value?: unknown): CollectionQueryBuilder<T>;
andWhere(groupFactory: QueryGroupFunction<T>): CollectionQueryBuilder<T>;
orWhere(groupFactory: QueryGroupFunction<T>): CollectionQueryBuilder<T>;
}
interface CollectionQueryGroup<T> {
where(field: string, operator: SQLOperator, value?: unknown): CollectionQueryGroup<T>;
andWhere(groupFactory: QueryGroupFunction<T>): CollectionQueryGroup<T>;
orWhere(groupFactory: QueryGroupFunction<T>): CollectionQueryGroup<T>;
}
type CacheEntry = {
id: string;
value: string;
checksum: string;
};
type DatabaseBindParams = Primitive[];
type DatabaseBindable = number | string | boolean | null | undefined;
interface DatabaseAdapter {
first<T>(sql: string, params?: DatabaseBindParams): Promise<T | null | undefined>;
all<T>(sql: string, params?: DatabaseBindParams): Promise<T[]>;
exec(sql: string, params?: DatabaseBindParams): Promise<unknown>;
}
type DatabaseAdapterFactory<Options> = (otps?: Options) => DatabaseAdapter;
interface LocalDevelopmentDatabase {
fetchDevelopmentCache(): Promise<Record<string, CacheEntry>>;
fetchDevelopmentCacheForKey(key: string): Promise<CacheEntry | undefined>;
insertDevelopmentCache(id: string, checksum: string, parsedContent: string): void;
deleteDevelopmentCache(id: string): void;
dropContentTables(): void;
exec(sql: string): void;
close(): void;
database?: Connector;
}
interface ParsedContentv2 {
_id: string;
_source?: string;
_path?: string;
title?: string;
_draft?: boolean;
_partial?: boolean;
_locale?: string;
_type?: 'markdown' | 'yaml' | 'json' | 'csv';
_file?: string;
_extension?: 'md' | 'yaml' | 'yml' | 'json' | 'json5' | 'csv';
excerpt?: Record<string, unknown>;
body: Record<string, unknown> | null;
layout?: string;
[key: string]: unknown;
}
interface DraftSyncData {
files: DraftSyncFile[];
additions: DraftFile[];
deletions: DraftFile[];
}
interface DraftSyncFile {
path: string;
parsed?: ParsedContentv2;
}
interface DraftFile {
path: string;
parsed?: ParsedContentv2;
new?: boolean;
oldPath?: string;
pathMeta?: Record<string, unknown>;
}
type FileStatus = 'created' | 'updated' | 'deleted' | 'renamed';
interface PreviewFile {
id: number;
name: string;
nameWithoutPrefix: string;
type: 'file';
path: string;
pathPreview: string;
pathWithoutRoot: string;
pathRoute: string;
status: FileStatus;
content: string;
updatedAt: string;
parsed: ParsedContentv2;
}
interface FileChangeMessagePayload {
additions: PreviewFile[];
deletions: {
path: string;
}[];
}
interface FileSelectMessagePayload {
path: string;
}
type FileMessageType = 'nuxt-content:editor:file-selected' | 'nuxt-content:editor:file-changed' | 'nuxt-content:editor:media-changed' | 'nuxt-content:config:file-changed';
interface FileMessageData {
type: FileMessageType;
payload: FileChangeMessagePayload | FileSelectMessagePayload;
navigate: boolean;
}
declare const metaStandardSchema: Draft07;
declare const pageStandardSchema: Draft07;
type Property<T> = T & {
editor: (opts: EditorOptions) => Property<T>;
markdown: () => Property<T>;
inherit: (componentPath: string) => Property<T>;
};
declare function property<T extends ContentStandardSchemaV1>(input: T): Property<T>;
declare function defineCollection<T>(collection: Collection<T>): DefinedCollection;
declare function defineCollectionSource(source: CustomCollectionSource): ResolvedCustomCollectionSource;
type NuxtContentConfig = {
collections: Record<string, DefinedCollection>;
};
declare const defineContentConfig: c12.DefineConfig<NuxtContentConfig, c12.ConfigLayerMeta>;
declare const defineTransformer: (transformer: ContentTransformer) => ContentTransformer;
declare module 'zod' {
interface ZodTypeDef {
editor?: EditorOptions;
}
interface ZodType {
editor(options: EditorOptions): this;
}
}
declare const z: typeof z$1;
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
// @ts-ignore
export = _default;
export { ContentFileExtension, ContentFileType, defineCollection, defineCollectionSource, defineContentConfig, defineTransformer, metaStandardSchema, pageStandardSchema, property, z };
export type { CacheEntry, Collection, CollectionInfo, CollectionItemBase, CollectionQueryBuilder, CollectionQueryGroup, CollectionSource, CollectionType, Collections, ContentConfig, ContentFile, ContentNavigationItem, ContentStandardSchemaV1, ContentTransformer, CustomCollectionSource, D1DatabaseConfig, DataCollection, DataCollectionItemBase, DatabaseAdapter, DatabaseAdapterFactory, DatabaseBindParams, DatabaseBindable, DefinedCollection, Draft07, Draft07Definition, Draft07DefinitionProperty, Draft07DefinitionPropertyAllOf, Draft07DefinitionPropertyAnyOf, DraftFile, DraftSyncData, DraftSyncFile, EditorOptions, FileAfterParseHook, FileBeforeParseHook, FileChangeMessagePayload, FileMessageData, FileMessageType, FileSelectMessagePayload, FileStatus, LibSQLDatabaseConfig, LocalDevelopmentDatabase, MarkdownOptions, MarkdownPlugin, MarkdownRoot, MinimalElement, MinimalNode, MinimalText, MinimalTree, ModuleOptions, PageCollection, PageCollectionItemBase, PageCollections, ParsedContentFile, ParsedContentv2, PostgreSQLDatabaseConfig, PreviewFile, PreviewOptions, PublicRuntimeConfig, QueryGroupFunction, ResolvedCollection, ResolvedCollectionSource, ResolvedCustomCollectionSource, RuntimeConfig, SQLOperator, SQLiteConnector, SqliteDatabaseConfig, SurroundOptions, TransformContentOptions, TransformedContent };