astro 4.13.3 → 4.14.0
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/components/Code.astro +9 -0
- package/dist/@types/astro.d.ts +251 -2
- package/dist/actions/consts.d.ts +1 -1
- package/dist/actions/consts.js +1 -1
- package/dist/actions/index.js +12 -21
- package/dist/actions/runtime/virtual/server.js +9 -3
- package/dist/actions/runtime/virtual/shared.js +25 -3
- package/dist/assets/utils/resolveImports.d.ts +9 -0
- package/dist/assets/utils/resolveImports.js +22 -0
- package/dist/cli/add/index.d.ts +2 -2
- package/dist/cli/add/index.js +2 -2
- package/dist/cli/build/index.d.ts +2 -2
- package/dist/cli/build/index.js +5 -1
- package/dist/cli/check/index.d.ts +2 -2
- package/dist/cli/check/index.js +5 -2
- package/dist/cli/db/index.d.ts +4 -3
- package/dist/cli/db/index.js +10 -3
- package/dist/cli/dev/index.d.ts +2 -2
- package/dist/cli/dev/index.js +1 -0
- package/dist/cli/docs/index.d.ts +2 -2
- package/dist/cli/flags.d.ts +3 -1
- package/dist/cli/flags.js +2 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +26 -13
- package/dist/cli/info/index.d.ts +2 -2
- package/dist/cli/preferences/index.d.ts +2 -2
- package/dist/cli/preferences/index.js +1 -1
- package/dist/cli/preview/index.d.ts +2 -2
- package/dist/cli/sync/index.d.ts +2 -2
- package/dist/cli/sync/index.js +5 -2
- package/dist/cli/telemetry/index.d.ts +2 -2
- package/dist/container/index.js +3 -1
- package/dist/content/consts.d.ts +16 -2
- package/dist/content/consts.js +32 -2
- package/dist/content/content-layer.d.ts +40 -0
- package/dist/content/content-layer.js +253 -0
- package/dist/content/data-store.d.ts +114 -0
- package/dist/content/data-store.js +323 -0
- package/dist/content/loaders/file.d.ts +7 -0
- package/dist/content/loaders/file.js +72 -0
- package/dist/content/loaders/glob.d.ts +25 -0
- package/dist/content/loaders/glob.js +218 -0
- package/dist/content/loaders/index.d.ts +3 -0
- package/dist/content/loaders/index.js +7 -0
- package/dist/content/loaders/types.d.ts +36 -0
- package/dist/content/loaders/types.js +0 -0
- package/dist/content/runtime.d.ts +46 -8
- package/dist/content/runtime.js +225 -31
- package/dist/content/types-generator.js +125 -35
- package/dist/content/utils.d.ts +306 -2
- package/dist/content/utils.js +93 -7
- package/dist/content/vite-plugin-content-assets.js +9 -1
- package/dist/content/vite-plugin-content-virtual-mod.js +94 -2
- package/dist/core/app/common.js +4 -1
- package/dist/core/app/index.js +5 -3
- package/dist/core/app/types.d.ts +3 -1
- package/dist/core/build/generate.js +4 -2
- package/dist/core/build/index.js +17 -8
- package/dist/core/build/plugins/plugin-manifest.js +5 -2
- package/dist/core/build/plugins/plugin-ssr.js +35 -3
- package/dist/core/build/static-build.js +2 -0
- package/dist/core/build/types.d.ts +1 -0
- package/dist/core/config/config.d.ts +2 -5
- package/dist/core/config/config.js +0 -12
- package/dist/core/config/index.d.ts +1 -1
- package/dist/core/config/index.js +0 -2
- package/dist/core/config/schema.d.ts +34 -0
- package/dist/core/config/schema.js +6 -2
- package/dist/core/config/settings.js +5 -3
- package/dist/core/constants.js +1 -1
- package/dist/core/create-vite.js +1 -1
- package/dist/core/dev/container.js +2 -1
- package/dist/core/dev/dev.js +34 -2
- package/dist/core/dev/restart.js +25 -10
- package/dist/core/encryption.d.ts +24 -0
- package/dist/core/encryption.js +64 -0
- package/dist/core/errors/errors-data.d.ts +21 -0
- package/dist/core/errors/errors-data.js +13 -0
- package/dist/core/index.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/core/render-context.js +1 -0
- package/dist/core/server-islands/endpoint.js +5 -1
- package/dist/core/sync/constants.d.ts +1 -0
- package/dist/core/sync/constants.js +4 -0
- package/dist/core/sync/index.d.ts +12 -4
- package/dist/core/sync/index.js +56 -25
- package/dist/core/sync/write-files.d.ts +4 -0
- package/dist/core/sync/write-files.js +69 -0
- package/dist/core/util.js +1 -1
- package/dist/env/sync.js +6 -4
- package/dist/integrations/hooks.d.ts +7 -1
- package/dist/integrations/hooks.js +54 -0
- package/dist/preferences/index.d.ts +1 -1
- package/dist/preferences/index.js +2 -2
- package/dist/runtime/server/render/server-islands.js +9 -5
- package/dist/vite-plugin-astro-server/plugin.js +2 -0
- package/dist/vite-plugin-env/index.d.ts +3 -1
- package/dist/vite-plugin-env/index.js +11 -1
- package/dist/vite-plugin-markdown/content-entry-type.js +25 -2
- package/dist/vite-plugin-scanner/index.js +15 -5
- package/dist/vite-plugin-scanner/scan.js +1 -1
- package/package.json +15 -9
- package/templates/content/module.mjs +6 -1
- package/templates/content/types.d.ts +18 -5
- package/types/content.d.ts +34 -1
- package/dist/core/sync/setup-env-ts.d.ts +0 -8
- package/dist/core/sync/setup-env-ts.js +0 -79
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
3
|
+
import fastGlob from "fast-glob";
|
|
4
|
+
import { bold, green } from "kleur/colors";
|
|
5
|
+
import micromatch from "micromatch";
|
|
6
|
+
import pLimit from "p-limit";
|
|
7
|
+
import { getContentEntryIdAndSlug, getEntryConfigByExtMap, posixRelative } from "../utils.js";
|
|
8
|
+
function generateIdDefault({ entry, base, data }) {
|
|
9
|
+
if (data.slug) {
|
|
10
|
+
return data.slug;
|
|
11
|
+
}
|
|
12
|
+
const entryURL = new URL(entry, base);
|
|
13
|
+
const { slug } = getContentEntryIdAndSlug({
|
|
14
|
+
entry: entryURL,
|
|
15
|
+
contentDir: base,
|
|
16
|
+
collection: ""
|
|
17
|
+
});
|
|
18
|
+
return slug;
|
|
19
|
+
}
|
|
20
|
+
function glob(globOptions) {
|
|
21
|
+
if (globOptions.pattern.startsWith("../")) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
"Glob patterns cannot start with `../`. Set the `base` option to a parent directory instead."
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
if (globOptions.pattern.startsWith("/")) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
"Glob patterns cannot start with `/`. Set the `base` option to a parent directory or use a relative path instead."
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
const generateId = globOptions?.generateId ?? generateIdDefault;
|
|
32
|
+
const fileToIdMap = /* @__PURE__ */ new Map();
|
|
33
|
+
return {
|
|
34
|
+
name: "glob-loader",
|
|
35
|
+
load: async ({ settings, logger, watcher, parseData, store, generateDigest }) => {
|
|
36
|
+
const renderFunctionByContentType = /* @__PURE__ */ new WeakMap();
|
|
37
|
+
const untouchedEntries = new Set(store.keys());
|
|
38
|
+
async function syncData(entry, base, entryType) {
|
|
39
|
+
if (!entryType) {
|
|
40
|
+
logger.warn(`No entry type found for ${entry}`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const fileUrl = new URL(entry, base);
|
|
44
|
+
const contents = await fs.readFile(fileUrl, "utf-8").catch((err) => {
|
|
45
|
+
logger.error(`Error reading ${entry}: ${err.message}`);
|
|
46
|
+
return;
|
|
47
|
+
});
|
|
48
|
+
if (!contents) {
|
|
49
|
+
logger.warn(`No contents found for ${entry}`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const { body, data } = await entryType.getEntryInfo({
|
|
53
|
+
contents,
|
|
54
|
+
fileUrl
|
|
55
|
+
});
|
|
56
|
+
const id = generateId({ entry, base, data });
|
|
57
|
+
untouchedEntries.delete(id);
|
|
58
|
+
const existingEntry = store.get(id);
|
|
59
|
+
const digest = generateDigest(contents);
|
|
60
|
+
if (existingEntry && existingEntry.digest === digest && existingEntry.filePath) {
|
|
61
|
+
if (existingEntry.deferredRender) {
|
|
62
|
+
store.addModuleImport(existingEntry.filePath);
|
|
63
|
+
}
|
|
64
|
+
if (existingEntry.rendered?.metadata?.imagePaths?.length) {
|
|
65
|
+
store.addAssetImports(
|
|
66
|
+
existingEntry.rendered.metadata.imagePaths,
|
|
67
|
+
existingEntry.filePath
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
await parseData(existingEntry);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const filePath = fileURLToPath(fileUrl);
|
|
74
|
+
const relativePath = posixRelative(fileURLToPath(settings.config.root), filePath);
|
|
75
|
+
const parsedData = await parseData({
|
|
76
|
+
id,
|
|
77
|
+
data,
|
|
78
|
+
filePath
|
|
79
|
+
});
|
|
80
|
+
if (entryType.getRenderFunction) {
|
|
81
|
+
let render = renderFunctionByContentType.get(entryType);
|
|
82
|
+
if (!render) {
|
|
83
|
+
render = await entryType.getRenderFunction(settings);
|
|
84
|
+
renderFunctionByContentType.set(entryType, render);
|
|
85
|
+
}
|
|
86
|
+
let rendered = void 0;
|
|
87
|
+
try {
|
|
88
|
+
rendered = await render?.({
|
|
89
|
+
id,
|
|
90
|
+
data: parsedData,
|
|
91
|
+
body,
|
|
92
|
+
filePath,
|
|
93
|
+
digest
|
|
94
|
+
});
|
|
95
|
+
} catch (error) {
|
|
96
|
+
logger.error(`Error rendering ${entry}: ${error.message}`);
|
|
97
|
+
}
|
|
98
|
+
store.set({
|
|
99
|
+
id,
|
|
100
|
+
data: parsedData,
|
|
101
|
+
body,
|
|
102
|
+
filePath: relativePath,
|
|
103
|
+
digest,
|
|
104
|
+
rendered
|
|
105
|
+
});
|
|
106
|
+
if (rendered?.metadata?.imagePaths?.length) {
|
|
107
|
+
store.addAssetImports(rendered.metadata.imagePaths, relativePath);
|
|
108
|
+
}
|
|
109
|
+
} else if ("contentModuleTypes" in entryType) {
|
|
110
|
+
store.set({
|
|
111
|
+
id,
|
|
112
|
+
data: parsedData,
|
|
113
|
+
body,
|
|
114
|
+
filePath: relativePath,
|
|
115
|
+
digest,
|
|
116
|
+
deferredRender: true
|
|
117
|
+
});
|
|
118
|
+
} else {
|
|
119
|
+
store.set({ id, data: parsedData, body, filePath: relativePath, digest });
|
|
120
|
+
}
|
|
121
|
+
fileToIdMap.set(filePath, id);
|
|
122
|
+
}
|
|
123
|
+
const entryConfigByExt = getEntryConfigByExtMap([
|
|
124
|
+
...settings.contentEntryTypes,
|
|
125
|
+
...settings.dataEntryTypes
|
|
126
|
+
]);
|
|
127
|
+
const baseDir = globOptions.base ? new URL(globOptions.base, settings.config.root) : settings.config.root;
|
|
128
|
+
if (!baseDir.pathname.endsWith("/")) {
|
|
129
|
+
baseDir.pathname = `${baseDir.pathname}/`;
|
|
130
|
+
}
|
|
131
|
+
const files = await fastGlob(globOptions.pattern, {
|
|
132
|
+
cwd: fileURLToPath(baseDir)
|
|
133
|
+
});
|
|
134
|
+
function configForFile(file) {
|
|
135
|
+
const ext = file.split(".").at(-1);
|
|
136
|
+
if (!ext) {
|
|
137
|
+
logger.warn(`No extension found for ${file}`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
return entryConfigByExt.get(`.${ext}`);
|
|
141
|
+
}
|
|
142
|
+
const limit = pLimit(10);
|
|
143
|
+
const skippedFiles = [];
|
|
144
|
+
const contentDir = new URL("content/", settings.config.srcDir);
|
|
145
|
+
function isInContentDir(file) {
|
|
146
|
+
const fileUrl = new URL(file, baseDir);
|
|
147
|
+
return fileUrl.href.startsWith(contentDir.href);
|
|
148
|
+
}
|
|
149
|
+
const configFiles = new Set(
|
|
150
|
+
["config.js", "config.ts", "config.mjs"].map((file) => new URL(file, contentDir).href)
|
|
151
|
+
);
|
|
152
|
+
function isConfigFile(file) {
|
|
153
|
+
const fileUrl = new URL(file, baseDir);
|
|
154
|
+
return configFiles.has(fileUrl.href);
|
|
155
|
+
}
|
|
156
|
+
await Promise.all(
|
|
157
|
+
files.map((entry) => {
|
|
158
|
+
if (isConfigFile(entry)) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (isInContentDir(entry)) {
|
|
162
|
+
skippedFiles.push(entry);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
return limit(async () => {
|
|
166
|
+
const entryType = configForFile(entry);
|
|
167
|
+
await syncData(entry, baseDir, entryType);
|
|
168
|
+
});
|
|
169
|
+
})
|
|
170
|
+
);
|
|
171
|
+
const skipCount = skippedFiles.length;
|
|
172
|
+
if (skipCount > 0) {
|
|
173
|
+
logger.warn(`The glob() loader cannot be used for files in ${bold("src/content")}.`);
|
|
174
|
+
if (skipCount > 10) {
|
|
175
|
+
logger.warn(
|
|
176
|
+
`Skipped ${green(skippedFiles.length)} files that matched ${green(globOptions.pattern)}.`
|
|
177
|
+
);
|
|
178
|
+
} else {
|
|
179
|
+
logger.warn(`Skipped the following files that matched ${green(globOptions.pattern)}:`);
|
|
180
|
+
skippedFiles.forEach((file) => logger.warn(`\u2022 ${green(file)}`));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
untouchedEntries.forEach((id) => store.delete(id));
|
|
184
|
+
if (!watcher) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const matcher = micromatch.makeRe(globOptions.pattern);
|
|
188
|
+
const matchesGlob = (entry) => !entry.startsWith("../") && matcher.test(entry);
|
|
189
|
+
const basePath = fileURLToPath(baseDir);
|
|
190
|
+
async function onChange(changedPath) {
|
|
191
|
+
const entry = posixRelative(basePath, changedPath);
|
|
192
|
+
if (!matchesGlob(entry)) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const entryType = configForFile(changedPath);
|
|
196
|
+
const baseUrl = pathToFileURL(basePath);
|
|
197
|
+
await syncData(entry, baseUrl, entryType);
|
|
198
|
+
logger.info(`Reloaded data from ${green(entry)}`);
|
|
199
|
+
}
|
|
200
|
+
watcher.on("change", onChange);
|
|
201
|
+
watcher.on("add", onChange);
|
|
202
|
+
watcher.on("unlink", async (deletedPath) => {
|
|
203
|
+
const entry = posixRelative(basePath, deletedPath);
|
|
204
|
+
if (!matchesGlob(entry)) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const id = fileToIdMap.get(deletedPath);
|
|
208
|
+
if (id) {
|
|
209
|
+
store.delete(id);
|
|
210
|
+
fileToIdMap.delete(deletedPath);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
export {
|
|
217
|
+
glob
|
|
218
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { FSWatcher } from 'vite';
|
|
2
|
+
import type { ZodSchema } from 'zod';
|
|
3
|
+
import type { AstroIntegrationLogger, AstroSettings } from '../../@types/astro.js';
|
|
4
|
+
import type { MetaStore, ScopedDataStore } from '../data-store.js';
|
|
5
|
+
export interface ParseDataOptions<TData extends Record<string, unknown>> {
|
|
6
|
+
/** The ID of the entry. Unique per collection */
|
|
7
|
+
id: string;
|
|
8
|
+
/** The raw, unvalidated data of the entry */
|
|
9
|
+
data: TData;
|
|
10
|
+
/** An optional file path, where the entry represents a local file. */
|
|
11
|
+
filePath?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface LoaderContext {
|
|
14
|
+
/** The unique name of the collection */
|
|
15
|
+
collection: string;
|
|
16
|
+
/** A database abstraction to store the actual data */
|
|
17
|
+
store: ScopedDataStore;
|
|
18
|
+
/** A simple KV store, designed for things like sync tokens */
|
|
19
|
+
meta: MetaStore;
|
|
20
|
+
logger: AstroIntegrationLogger;
|
|
21
|
+
settings: AstroSettings;
|
|
22
|
+
/** Validates and parses the data according to the collection schema */
|
|
23
|
+
parseData<TData extends Record<string, unknown>>(props: ParseDataOptions<TData>): Promise<TData>;
|
|
24
|
+
/** Generates a non-cryptographic content digest. This can be used to check if the data has changed */
|
|
25
|
+
generateDigest(data: Record<string, unknown> | string): string;
|
|
26
|
+
/** When running in dev, this is a filesystem watcher that can be used to trigger updates */
|
|
27
|
+
watcher?: FSWatcher;
|
|
28
|
+
}
|
|
29
|
+
export interface Loader {
|
|
30
|
+
/** Unique name of the loader, e.g. the npm package name */
|
|
31
|
+
name: string;
|
|
32
|
+
/** Do the actual loading of the data */
|
|
33
|
+
load: (context: LoaderContext) => Promise<void>;
|
|
34
|
+
/** Optionally, define the schema of the data. Will be overridden by user-defined schema */
|
|
35
|
+
schema?: ZodSchema | Promise<ZodSchema> | (() => ZodSchema | Promise<ZodSchema>);
|
|
36
|
+
}
|
|
File without changes
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { MarkdownHeading } from '@astrojs/markdown-remark';
|
|
2
|
+
import { z } from 'zod';
|
|
2
3
|
import { type AstroComponentFactory } from '../runtime/server/index.js';
|
|
4
|
+
import { type DataEntry } from './data-store.js';
|
|
3
5
|
import type { ContentLookupMap } from './utils.js';
|
|
4
6
|
type LazyImport = () => Promise<any>;
|
|
5
7
|
type GlobResult = Record<string, LazyImport>;
|
|
@@ -16,9 +18,10 @@ export declare function createGetCollection({ contentCollectionToEntryMap, dataC
|
|
|
16
18
|
getRenderEntryImport: GetEntryImport;
|
|
17
19
|
cacheEntriesByCollection: Map<string, any[]>;
|
|
18
20
|
}): (collection: string, filter?: (entry: any) => unknown) => Promise<any[]>;
|
|
19
|
-
export declare function createGetEntryBySlug({ getEntryImport, getRenderEntryImport, }: {
|
|
21
|
+
export declare function createGetEntryBySlug({ getEntryImport, getRenderEntryImport, collectionNames, }: {
|
|
20
22
|
getEntryImport: GetEntryImport;
|
|
21
23
|
getRenderEntryImport: GetEntryImport;
|
|
24
|
+
collectionNames: Set<string>;
|
|
22
25
|
}): (collection: string, slug: string) => Promise<{
|
|
23
26
|
id: any;
|
|
24
27
|
slug: any;
|
|
@@ -27,13 +30,14 @@ export declare function createGetEntryBySlug({ getEntryImport, getRenderEntryImp
|
|
|
27
30
|
data: any;
|
|
28
31
|
render(): Promise<RenderResult>;
|
|
29
32
|
} | undefined>;
|
|
30
|
-
export declare function createGetDataEntryById({ getEntryImport }: {
|
|
33
|
+
export declare function createGetDataEntryById({ getEntryImport, collectionNames, }: {
|
|
31
34
|
getEntryImport: GetEntryImport;
|
|
35
|
+
collectionNames: Set<string>;
|
|
32
36
|
}): (collection: string, id: string) => Promise<{
|
|
33
37
|
id: any;
|
|
34
38
|
collection: any;
|
|
35
39
|
data: any;
|
|
36
|
-
}>;
|
|
40
|
+
} | undefined>;
|
|
37
41
|
type ContentEntryResult = {
|
|
38
42
|
id: string;
|
|
39
43
|
slug: string;
|
|
@@ -54,9 +58,10 @@ type EntryLookupObject = {
|
|
|
54
58
|
collection: string;
|
|
55
59
|
slug: string;
|
|
56
60
|
};
|
|
57
|
-
export declare function createGetEntry({ getEntryImport, getRenderEntryImport, }: {
|
|
61
|
+
export declare function createGetEntry({ getEntryImport, getRenderEntryImport, collectionNames, }: {
|
|
58
62
|
getEntryImport: GetEntryImport;
|
|
59
63
|
getRenderEntryImport: GetEntryImport;
|
|
64
|
+
collectionNames: Set<string>;
|
|
60
65
|
}): (collectionOrLookupObject: string | EntryLookupObject, _lookupId?: string) => Promise<ContentEntryResult | DataEntryResult | undefined>;
|
|
61
66
|
export declare function createGetEntries(getEntry: ReturnType<typeof createGetEntry>): (entries: {
|
|
62
67
|
collection: string;
|
|
@@ -70,15 +75,48 @@ type RenderResult = {
|
|
|
70
75
|
headings: MarkdownHeading[];
|
|
71
76
|
remarkPluginFrontmatter: Record<string, any>;
|
|
72
77
|
};
|
|
78
|
+
export declare function renderEntry(entry: DataEntry | {
|
|
79
|
+
render: () => Promise<{
|
|
80
|
+
Content: AstroComponentFactory;
|
|
81
|
+
}>;
|
|
82
|
+
}): Promise<{
|
|
83
|
+
Content: AstroComponentFactory;
|
|
84
|
+
} | {
|
|
85
|
+
Content: any;
|
|
86
|
+
headings: any;
|
|
87
|
+
remarkPluginFrontmatter: any;
|
|
88
|
+
}>;
|
|
73
89
|
export declare function createReference({ lookupMap }: {
|
|
74
90
|
lookupMap: ContentLookupMap;
|
|
75
|
-
}): (collection: string) =>
|
|
91
|
+
}): (collection: string) => z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodObject<{
|
|
92
|
+
id: z.ZodString;
|
|
93
|
+
collection: z.ZodString;
|
|
94
|
+
}, "strip", z.ZodTypeAny, {
|
|
95
|
+
id: string;
|
|
96
|
+
collection: string;
|
|
97
|
+
}, {
|
|
98
|
+
id: string;
|
|
99
|
+
collection: string;
|
|
100
|
+
}>, z.ZodObject<{
|
|
101
|
+
slug: z.ZodString;
|
|
102
|
+
collection: z.ZodString;
|
|
103
|
+
}, "strip", z.ZodTypeAny, {
|
|
104
|
+
collection: string;
|
|
76
105
|
slug: string;
|
|
106
|
+
}, {
|
|
107
|
+
collection: string;
|
|
108
|
+
slug: string;
|
|
109
|
+
}>]>, {
|
|
110
|
+
id: string;
|
|
77
111
|
collection: string;
|
|
78
|
-
id?: undefined;
|
|
79
112
|
} | {
|
|
113
|
+
slug: string;
|
|
114
|
+
collection: string;
|
|
115
|
+
} | undefined, string | {
|
|
80
116
|
id: string;
|
|
81
117
|
collection: string;
|
|
82
|
-
|
|
83
|
-
|
|
118
|
+
} | {
|
|
119
|
+
collection: string;
|
|
120
|
+
slug: string;
|
|
121
|
+
}>;
|
|
84
122
|
export {};
|