@content-collections/core 0.1.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.
Files changed (87) hide show
  1. package/.turbo/turbo-build.log +14 -0
  2. package/.turbo/turbo-test.log +47 -0
  3. package/.turbo/turbo-typecheck.log +4 -0
  4. package/LICENSE +21 -0
  5. package/coverage/.tmp/coverage-0.json +1 -0
  6. package/coverage/.tmp/coverage-1.json +1 -0
  7. package/coverage/.tmp/coverage-2.json +1 -0
  8. package/coverage/.tmp/coverage-3.json +1 -0
  9. package/coverage/.tmp/coverage-4.json +1 -0
  10. package/coverage/.tmp/coverage-5.json +1 -0
  11. package/coverage/.tmp/coverage-6.json +1 -0
  12. package/coverage/.tmp/coverage-7.json +1 -0
  13. package/coverage/.tmp/coverage-8.json +1 -0
  14. package/coverage/.tmp/coverage-9.json +1 -0
  15. package/coverage/base.css +224 -0
  16. package/coverage/block-navigation.js +87 -0
  17. package/coverage/builder.ts.html +424 -0
  18. package/coverage/clover.xml +960 -0
  19. package/coverage/collector.ts.html +427 -0
  20. package/coverage/config.ts.html +403 -0
  21. package/coverage/configurationReader.ts.html +409 -0
  22. package/coverage/coverage-final.json +11 -0
  23. package/coverage/events.ts.html +310 -0
  24. package/coverage/favicon.png +0 -0
  25. package/coverage/index.html +251 -0
  26. package/coverage/index.ts.html +106 -0
  27. package/coverage/prettify.css +1 -0
  28. package/coverage/prettify.js +2 -0
  29. package/coverage/sort-arrow-sprite.png +0 -0
  30. package/coverage/sorter.js +196 -0
  31. package/coverage/synchronizer.ts.html +394 -0
  32. package/coverage/transformer.ts.html +607 -0
  33. package/coverage/utils.ts.html +118 -0
  34. package/coverage/writer.ts.html +424 -0
  35. package/dist/index.cjs +416 -0
  36. package/dist/index.d.cts +59 -0
  37. package/dist/index.d.ts +146 -0
  38. package/dist/index.js +630 -0
  39. package/package.json +39 -0
  40. package/src/__tests__/.content-collections/cache/config.001.ts.js +19 -0
  41. package/src/__tests__/.content-collections/cache/config.002.mjs +16 -0
  42. package/src/__tests__/.content-collections/cache/config.002.ts.js +16 -0
  43. package/src/__tests__/.content-collections/cache/config.003.ts.js +24 -0
  44. package/src/__tests__/.content-collections/cache/config.004.mjs +47 -0
  45. package/src/__tests__/.content-collections/different-cache-dir/different.config.js +19 -0
  46. package/src/__tests__/.content-collections/generated-config.002/allPosts.json +13 -0
  47. package/src/__tests__/.content-collections/generated-config.002/index.d.ts +7 -0
  48. package/src/__tests__/.content-collections/generated-config.002/index.js +5 -0
  49. package/src/__tests__/.content-collections/generated-config.004/allAuthors.json +13 -0
  50. package/src/__tests__/.content-collections/generated-config.004/allPosts.json +13 -0
  51. package/src/__tests__/.content-collections/generated-config.004/index.d.ts +10 -0
  52. package/src/__tests__/.content-collections/generated-config.004/index.js +6 -0
  53. package/src/__tests__/collections/posts.ts +15 -0
  54. package/src/__tests__/config.001.ts +19 -0
  55. package/src/__tests__/config.002.ts +14 -0
  56. package/src/__tests__/config.003.ts +6 -0
  57. package/src/__tests__/config.004.ts +47 -0
  58. package/src/__tests__/invalid +1 -0
  59. package/src/__tests__/sources/authors/trillian.md +8 -0
  60. package/src/__tests__/sources/posts/first.md +6 -0
  61. package/src/__tests__/sources/test/001.md +5 -0
  62. package/src/__tests__/sources/test/002.md +5 -0
  63. package/src/__tests__/sources/test/broken-frontmatter +6 -0
  64. package/src/builder.test.ts +180 -0
  65. package/src/builder.ts +113 -0
  66. package/src/collector.test.ts +157 -0
  67. package/src/collector.ts +114 -0
  68. package/src/config.ts +106 -0
  69. package/src/configurationReader.test.ts +104 -0
  70. package/src/configurationReader.ts +108 -0
  71. package/src/events.test.ts +84 -0
  72. package/src/events.ts +75 -0
  73. package/src/index.ts +7 -0
  74. package/src/synchronizer.test.ts +192 -0
  75. package/src/synchronizer.ts +103 -0
  76. package/src/transformer.test.ts +431 -0
  77. package/src/transformer.ts +174 -0
  78. package/src/types.test.ts +137 -0
  79. package/src/types.ts +33 -0
  80. package/src/utils.test.ts +48 -0
  81. package/src/utils.ts +11 -0
  82. package/src/watcher.test.ts +200 -0
  83. package/src/watcher.ts +56 -0
  84. package/src/writer.test.ts +135 -0
  85. package/src/writer.ts +113 -0
  86. package/tsconfig.json +27 -0
  87. package/vite.config.ts +24 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,416 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ applyConfig: () => applyConfig,
34
+ build: () => build2,
35
+ createRunner: () => createRunner,
36
+ defineCollection: () => defineCollection,
37
+ defineConfig: () => defineConfig
38
+ });
39
+ module.exports = __toCommonJS(src_exports);
40
+ var import_path2 = __toESM(require("path"), 1);
41
+
42
+ // src/applyConfig.ts
43
+ var esbuild = __toESM(require("esbuild"), 1);
44
+ var import_promises = __toESM(require("fs/promises"), 1);
45
+ var import_node_path = __toESM(require("path"), 1);
46
+
47
+ // package.json
48
+ var package_default = {
49
+ name: "@mdx-collections/core",
50
+ version: "1.0.0",
51
+ type: "module",
52
+ main: "dist/index.cjs",
53
+ exports: {
54
+ "./package.json": "./package.json",
55
+ ".": {
56
+ import: "./dist/index.js",
57
+ require: "./dist/index.cjs"
58
+ }
59
+ },
60
+ types: "./dist/index.d.ts",
61
+ scripts: {
62
+ build: "tsup src/index.ts --format esm,cjs --dts -d dist",
63
+ typecheck: "tsc",
64
+ test: "vitest --run --coverage"
65
+ },
66
+ devDependencies: {
67
+ "@types/micromatch": "^4.0.6",
68
+ "@types/node": "^20.9.0",
69
+ "@types/pluralize": "^0.0.33",
70
+ "@vitest/coverage-v8": "^0.34.6",
71
+ tsup: "^7.2.0",
72
+ tsx: "^4.1.1",
73
+ typescript: "^5.3.2",
74
+ vitest: "^0.34.6"
75
+ },
76
+ dependencies: {
77
+ camelcase: "^8.0.0",
78
+ esbuild: "^0.19.5",
79
+ "fast-glob": "^3.3.2",
80
+ "gray-matter": "^4.0.3",
81
+ micromatch: "^4.0.5",
82
+ pluralize: "^8.0.0",
83
+ zod: "^3.22.4"
84
+ }
85
+ };
86
+
87
+ // src/applyConfig.ts
88
+ var importPathPlugin = {
89
+ name: "import-path",
90
+ setup(build3) {
91
+ build3.onResolve({ filter: /^\@mdx-collections\/core$/ }, () => {
92
+ return { path: import_node_path.default.join(__dirname, "index.ts"), external: true };
93
+ });
94
+ }
95
+ };
96
+ function resolveCacheDir(config, options) {
97
+ if (options.cacheDir) {
98
+ return options.cacheDir;
99
+ }
100
+ return import_node_path.default.join(import_node_path.default.dirname(config), ".mdx-collections", "cache");
101
+ }
102
+ async function applyConfig(config, options = {
103
+ configName: "mdx-collection-config.mjs"
104
+ }) {
105
+ const cacheDir = resolveCacheDir(config, options);
106
+ await import_promises.default.mkdir(cacheDir, { recursive: true });
107
+ const outfile = import_node_path.default.join(cacheDir, options.configName);
108
+ const plugins = [];
109
+ if (process.env.NODE_ENV === "test") {
110
+ plugins.push(importPathPlugin);
111
+ }
112
+ await esbuild.build({
113
+ entryPoints: [config],
114
+ external: [...Object.keys(package_default.dependencies), "@mdx-collections/*"],
115
+ bundle: true,
116
+ platform: "node",
117
+ format: "esm",
118
+ plugins,
119
+ outfile
120
+ });
121
+ const module2 = await import(`file://${import_node_path.default.resolve(outfile)}?x=${Date.now()}`);
122
+ return {
123
+ ...module2.default,
124
+ path: config,
125
+ generateTypes: true
126
+ };
127
+ }
128
+
129
+ // src/run.ts
130
+ var import_promises3 = __toESM(require("fs/promises"), 1);
131
+ var import_node_path2 = __toESM(require("path"), 1);
132
+ var import_pluralize = __toESM(require("pluralize"), 1);
133
+
134
+ // src/collect.ts
135
+ var import_gray_matter = __toESM(require("gray-matter"), 1);
136
+ var import_fast_glob = __toESM(require("fast-glob"), 1);
137
+ var import_promises2 = require("fs/promises");
138
+ var import_path = __toESM(require("path"), 1);
139
+ var import_micromatch = __toESM(require("micromatch"), 1);
140
+ async function collectFile(directory, filePath) {
141
+ const file = await (0, import_promises2.readFile)(import_path.default.join(directory, filePath), "utf-8");
142
+ const { data, content: body } = (0, import_gray_matter.default)(file);
143
+ return {
144
+ data,
145
+ body,
146
+ path: filePath
147
+ };
148
+ }
149
+ async function resolveCollection(collection) {
150
+ const filePaths = await (0, import_fast_glob.default)(collection.include, {
151
+ cwd: collection.directory,
152
+ onlyFiles: true,
153
+ absolute: false
154
+ });
155
+ const promises = filePaths.map(
156
+ (filePath) => collectFile(collection.directory, filePath)
157
+ );
158
+ return {
159
+ ...collection,
160
+ files: await Promise.all(promises)
161
+ };
162
+ }
163
+ async function collect(unresolvedCollections) {
164
+ const promises = unresolvedCollections.map(
165
+ (collection) => resolveCollection(collection)
166
+ );
167
+ return await Promise.all(promises);
168
+ }
169
+ function createRelativePath(directory, filePath) {
170
+ if (!filePath.startsWith(directory)) {
171
+ throw new Error("Path is not in collection directory");
172
+ }
173
+ let relativePath = filePath.slice(directory.length);
174
+ if (relativePath.startsWith("/")) {
175
+ relativePath = relativePath.slice(1);
176
+ }
177
+ return relativePath;
178
+ }
179
+ function isIncluded(collection, path5) {
180
+ if (path5.startsWith(collection.directory)) {
181
+ const relativePath = createRelativePath(collection.directory, path5);
182
+ return import_micromatch.default.isMatch(relativePath, collection.include);
183
+ }
184
+ return false;
185
+ }
186
+ async function syncFile(collection, modification, path5) {
187
+ if ("added" === modification) {
188
+ const file = await collectFile(collection.directory, path5);
189
+ collection.files.push(file);
190
+ } else if ("changed" === modification) {
191
+ const file = await collectFile(collection.directory, path5);
192
+ const index = collection.files.findIndex((file2) => file2.path === path5);
193
+ collection.files[index] = file;
194
+ } else if ("removed" === modification) {
195
+ const index = collection.files.findIndex((file) => file.path === path5);
196
+ collection.files.splice(index, 1);
197
+ }
198
+ }
199
+ function sync(collection, modification, path5) {
200
+ const relativePath = createRelativePath(collection.directory, path5);
201
+ return syncFile(collection, modification, relativePath);
202
+ }
203
+
204
+ // src/transformer.ts
205
+ var TransformError = class extends Error {
206
+ type;
207
+ constructor(type, message) {
208
+ super(message);
209
+ this.type = type;
210
+ }
211
+ };
212
+ var throwingErrorHandler = (error) => {
213
+ throw error;
214
+ };
215
+ function isDefined(value) {
216
+ return value !== void 0 && value !== null;
217
+ }
218
+ async function transform(untransformedCollections, errorHandler = throwingErrorHandler) {
219
+ async function parseFile(collection, file) {
220
+ const { data, body, path: path5 } = file;
221
+ let parsedData = await collection.schema.safeParseAsync(data);
222
+ if (!parsedData.success) {
223
+ errorHandler(new TransformError("Validation", parsedData.error.message));
224
+ return null;
225
+ }
226
+ const document = {
227
+ ...parsedData.data,
228
+ _meta: {
229
+ path: path5
230
+ }
231
+ };
232
+ return {
233
+ document,
234
+ content: body
235
+ };
236
+ }
237
+ async function parseCollection(collection) {
238
+ const promises2 = collection.files.map(
239
+ (file) => parseFile(collection, file)
240
+ );
241
+ return {
242
+ ...collection,
243
+ documents: (await Promise.all(promises2)).filter(isDefined)
244
+ };
245
+ }
246
+ function createContext(collections2, file) {
247
+ return {
248
+ content: async () => file.content,
249
+ documents: (collection) => {
250
+ const resolved = collections2.find((c) => c.name === collection.name);
251
+ if (!resolved) {
252
+ throw new TransformError(
253
+ "Configuration",
254
+ `Collection ${collection.name} not found, do you have registered it in your configuration?`
255
+ );
256
+ }
257
+ return resolved.documents.map((doc) => doc.document);
258
+ }
259
+ };
260
+ }
261
+ async function transformCollection(collections2, collection) {
262
+ if (collection.transform) {
263
+ const docs = [];
264
+ for (const doc of collection.documents) {
265
+ const context = createContext(collections2, doc);
266
+ try {
267
+ docs.push({
268
+ ...doc,
269
+ document: await collection.transform(context, doc.document)
270
+ });
271
+ } catch (error) {
272
+ if (error instanceof TransformError) {
273
+ errorHandler(error);
274
+ } else {
275
+ errorHandler(new TransformError("Transform", String(error)));
276
+ }
277
+ }
278
+ }
279
+ return docs;
280
+ }
281
+ return collection.documents;
282
+ }
283
+ const promises = untransformedCollections.map(
284
+ (collection) => parseCollection(collection)
285
+ );
286
+ const collections = await Promise.all(promises);
287
+ for (const collection of collections) {
288
+ collection.documents = await transformCollection(collections, collection);
289
+ }
290
+ return collections;
291
+ }
292
+
293
+ // src/run.ts
294
+ function createArrayConstName(name) {
295
+ let suffix = name.charAt(0).toUpperCase() + name.slice(1);
296
+ return "all" + (0, import_pluralize.default)(suffix);
297
+ }
298
+ async function createDataFiles(collections, directory) {
299
+ for (const collection of collections) {
300
+ const dataPath = import_node_path2.default.join(
301
+ directory,
302
+ `${createArrayConstName(collection.name)}.json`
303
+ );
304
+ await import_promises3.default.writeFile(
305
+ dataPath,
306
+ JSON.stringify(
307
+ collection.documents.map((doc) => doc.document),
308
+ null,
309
+ 2
310
+ )
311
+ );
312
+ }
313
+ }
314
+ async function createJavaScriptFile(configuration, directory) {
315
+ const collections = configuration.collections.map(
316
+ ({ name }) => createArrayConstName(name)
317
+ );
318
+ let content = "";
319
+ for (const name of collections) {
320
+ content += `import ${name} from "./${name}.json";
321
+ `;
322
+ }
323
+ content += "\n";
324
+ content += "export { " + collections.join(", ") + " };\n";
325
+ await import_promises3.default.writeFile(import_node_path2.default.join(directory, "index.js"), content, "utf-8");
326
+ }
327
+ async function createTypeDefinitionFile(configuration, directory) {
328
+ const importPath = import_node_path2.default.relative(directory, configuration.path);
329
+ let content = `import mdxConfiguration from "${importPath}";
330
+ import { GetTypeByName } from "@mdx-collections/core";
331
+ `;
332
+ const collections = configuration.collections;
333
+ for (const collection of collections) {
334
+ content += `
335
+ `;
336
+ content += `export type ${collection.typeName} = GetTypeByName<typeof mdxConfiguration, "${collection.name}">;
337
+ `;
338
+ content += `export declare const ${createArrayConstName(
339
+ collection.name
340
+ )}: Array<${collection.typeName}>;
341
+ `;
342
+ }
343
+ content += "\n";
344
+ content += "export {};\n";
345
+ await import_promises3.default.writeFile(import_node_path2.default.join(directory, "index.d.ts"), content, "utf-8");
346
+ }
347
+ async function createRunner(configuration, directory) {
348
+ await import_promises3.default.mkdir(directory, { recursive: true });
349
+ const resolved = await collect(configuration.collections);
350
+ await createJavaScriptFile(configuration, directory);
351
+ if (configuration.generateTypes) {
352
+ await createTypeDefinitionFile(configuration, directory);
353
+ }
354
+ async function run() {
355
+ const collections = await transform(resolved);
356
+ await createDataFiles(collections, directory);
357
+ for (const collection of collections) {
358
+ if (collection.onSuccess) {
359
+ await collection.onSuccess(
360
+ collection.documents.map((doc) => doc.document)
361
+ );
362
+ }
363
+ }
364
+ }
365
+ return {
366
+ run,
367
+ sync: async (event, path5) => {
368
+ for (const collection of resolved) {
369
+ if (isIncluded(collection, path5)) {
370
+ await sync(collection, event, path5);
371
+ await run();
372
+ }
373
+ }
374
+ }
375
+ };
376
+ }
377
+
378
+ // src/utils.ts
379
+ var import_camelcase = __toESM(require("camelcase"), 1);
380
+ var import_pluralize2 = __toESM(require("pluralize"), 1);
381
+ function generateTypeName(name) {
382
+ const singularName = import_pluralize2.default.singular(name);
383
+ return (0, import_camelcase.default)(singularName, { pascalCase: true });
384
+ }
385
+
386
+ // src/config.ts
387
+ function defineCollection(collection) {
388
+ let typeName = collection.typeName;
389
+ if (!typeName) {
390
+ typeName = generateTypeName(collection.name);
391
+ }
392
+ return {
393
+ ...collection,
394
+ typeName
395
+ };
396
+ }
397
+ function defineConfig(config) {
398
+ return config;
399
+ }
400
+
401
+ // src/index.ts
402
+ async function build2(config) {
403
+ const configuration = await applyConfig(config);
404
+ const baseDirectory = import_path2.default.dirname(config);
405
+ const directory = import_path2.default.join(baseDirectory, ".mdx-collections", "generated");
406
+ const runner = await createRunner(configuration, directory);
407
+ await runner.run();
408
+ }
409
+ // Annotate the CommonJS export names for ESM import in node:
410
+ 0 && (module.exports = {
411
+ applyConfig,
412
+ build,
413
+ createRunner,
414
+ defineCollection,
415
+ defineConfig
416
+ });
@@ -0,0 +1,59 @@
1
+ import { ZodTypeAny, z } from 'zod';
2
+
3
+ type Meta = {
4
+ path: string;
5
+ };
6
+ type Document<TSchema extends ZodTypeAny> = z.infer<TSchema> & {
7
+ _meta: Meta;
8
+ };
9
+ type Context = {
10
+ content(): Promise<string>;
11
+ documents<TCollection extends AnyCollection>(collection: TCollection): Array<Document<TCollection["schema"]>>;
12
+ };
13
+ type TransformFn<TSchema extends ZodTypeAny> = ((context: Context, data: Document<TSchema>) => any) | undefined;
14
+ type CollectionRequest<TSchema extends ZodTypeAny, TName extends string, TTransform extends TransformFn<TSchema>, TDocument> = {
15
+ name: TName;
16
+ typeName?: string;
17
+ schema: TSchema;
18
+ transform?: TTransform;
19
+ directory: string;
20
+ include: string | string[];
21
+ onSuccess?: (documents: Array<TDocument>) => void | Promise<void>;
22
+ };
23
+ type Collection<TSchema extends ZodTypeAny, TName extends string, TTransform extends TransformFn<TSchema>, TDocument> = CollectionRequest<TSchema, TName, TTransform, TDocument> & {
24
+ typeName: string;
25
+ };
26
+ type AnyCollection = Collection<ZodTypeAny, any, any, any>;
27
+ declare function defineCollection<TSchema extends ZodTypeAny, TName extends string, TTransform extends TransformFn<TSchema>, TDocument = [TTransform] extends [(...args: any) => any] ? Awaited<ReturnType<TTransform>> : Document<TSchema>>(collection: CollectionRequest<TSchema, TName, TTransform, TDocument>): Collection<TSchema, TName, TTransform, TDocument>;
28
+ type Configuration<TCollections extends Array<AnyCollection>> = {
29
+ collections: TCollections;
30
+ };
31
+ type AnyConfiguration = Configuration<Array<AnyCollection>>;
32
+ declare function defineConfig<TConfig extends AnyConfiguration>(config: TConfig): TConfig;
33
+
34
+ type InternalConfiguration = {
35
+ collections: Array<AnyCollection>;
36
+ path: string;
37
+ generateTypes?: boolean;
38
+ };
39
+ type Options = {
40
+ configName: string;
41
+ cacheDir?: string;
42
+ };
43
+ declare function applyConfig(config: string, options?: Options): Promise<InternalConfiguration>;
44
+
45
+ type Modification = "added" | "changed" | "removed";
46
+ type CollectionByName<TConfiguration extends AnyConfiguration> = {
47
+ [TCollection in TConfiguration["collections"][number] as TCollection["name"]]: TCollection;
48
+ };
49
+ type GetDocument<TCollection extends AnyCollection> = TCollection extends Collection<ZodTypeAny, any, any, infer TDocument> ? TDocument : never;
50
+ type GetTypeByName<TConfiguration extends AnyConfiguration, TName extends keyof CollectionByName<TConfiguration>, TCollection = CollectionByName<TConfiguration>[TName]> = TCollection extends AnyCollection ? GetDocument<TCollection> : never;
51
+
52
+ declare function createRunner(configuration: InternalConfiguration, directory: string): Promise<{
53
+ run: () => Promise<void>;
54
+ sync: (event: Modification, path: string) => Promise<void>;
55
+ }>;
56
+
57
+ declare function build(config: string): Promise<void>;
58
+
59
+ export { AnyCollection, AnyConfiguration, Collection, CollectionRequest, Configuration, Context, Document, GetTypeByName, Meta, Modification, applyConfig, build, createRunner, defineCollection, defineConfig };
@@ -0,0 +1,146 @@
1
+ import { ZodRawShape, z, ZodObject, ZodTypeAny, ZodString } from 'zod';
2
+
3
+ type Meta = {
4
+ filePath: string;
5
+ fileName: string;
6
+ directory: string;
7
+ path: string;
8
+ extension: string;
9
+ };
10
+ type WithContent = {
11
+ content: ZodString;
12
+ };
13
+ type AddContent<TShape extends ZodRawShape> = TShape extends {
14
+ content: ZodTypeAny;
15
+ } ? TShape : TShape & WithContent;
16
+ type Schema<TShape extends ZodRawShape> = z.infer<ZodObject<AddContent<TShape>>> & {
17
+ _meta: Meta;
18
+ };
19
+ type Context = {
20
+ documents<TCollection extends AnyCollection>(collection: TCollection): Array<Schema<TCollection["schema"]>>;
21
+ };
22
+ type Z = typeof z;
23
+ type CollectionRequest<TName extends string, TShape extends ZodRawShape, TSchema, TTransformResult, TDocument> = {
24
+ name: TName;
25
+ typeName?: string;
26
+ schema: (z: Z) => TShape;
27
+ transform?: (context: Context, data: TSchema) => TTransformResult;
28
+ directory: string;
29
+ include: string | string[];
30
+ onSuccess?: (documents: Array<TDocument>) => void | Promise<void>;
31
+ };
32
+ type Collection<TName extends string, TShape extends ZodRawShape, TSchema, TTransformResult, TDocument> = Omit<CollectionRequest<TName, TShape, TSchema, TTransformResult, TDocument>, "schema"> & {
33
+ typeName: string;
34
+ schema: TShape;
35
+ };
36
+ type AnyCollection = Collection<any, ZodRawShape, any, any, any>;
37
+ declare function defineCollection<TName extends string, TShape extends ZodRawShape, TSchema = Schema<TShape>, TTransformResult = never, TDocument = [TTransformResult] extends [never] ? Schema<TShape> : Awaited<TTransformResult>>(collection: CollectionRequest<TName, TShape, TSchema, TTransformResult, TDocument>): Collection<TName, TShape, TSchema, TTransformResult, TDocument>;
38
+ type Configuration<TCollections extends Array<AnyCollection>> = {
39
+ collections: TCollections;
40
+ };
41
+ type AnyConfiguration = Configuration<Array<AnyCollection>>;
42
+ declare function defineConfig<TConfig extends AnyConfiguration>(config: TConfig): TConfig;
43
+
44
+ type Modification = "create" | "update" | "delete";
45
+ type CollectionFile = {
46
+ data: {
47
+ content: string;
48
+ [key: string]: unknown;
49
+ };
50
+ path: string;
51
+ };
52
+ type CollectionByName<TConfiguration extends AnyConfiguration> = {
53
+ [TCollection in TConfiguration["collections"][number] as TCollection["name"]]: TCollection;
54
+ };
55
+ type GetDocument<TCollection extends AnyCollection> = TCollection extends Collection<any, ZodRawShape, any, any, infer TDocument> ? TDocument : never;
56
+ type GetTypeByName<TConfiguration extends AnyConfiguration, TName extends keyof CollectionByName<TConfiguration>, TCollection = CollectionByName<TConfiguration>[TName]> = TCollection extends AnyCollection ? GetDocument<TCollection> : never;
57
+
58
+ type CollectorEvents = {
59
+ "collector:read-error": {
60
+ filePath: string;
61
+ error: CollectError;
62
+ };
63
+ "collector:parse-error": {
64
+ filePath: string;
65
+ error: CollectError;
66
+ };
67
+ };
68
+ type ErrorType$2 = "Parse" | "Read";
69
+ declare class CollectError extends Error {
70
+ type: ErrorType$2;
71
+ constructor(type: ErrorType$2, message: string);
72
+ }
73
+
74
+ type TransformerEvents = {
75
+ "transformer:validation-error": {
76
+ collection: AnyCollection;
77
+ file: CollectionFile;
78
+ error: TransformError;
79
+ };
80
+ "transformer:error": {
81
+ collection: AnyCollection;
82
+ error: TransformError;
83
+ };
84
+ };
85
+ type ErrorType$1 = "Validation" | "Configuration" | "Transform";
86
+ declare class TransformError extends Error {
87
+ type: ErrorType$1;
88
+ constructor(type: ErrorType$1, message: string);
89
+ }
90
+
91
+ type WatcherEvents = {
92
+ "watcher:file-changed": {
93
+ filePath: string;
94
+ modification: Modification;
95
+ };
96
+ };
97
+
98
+ type EventWithError = {
99
+ error: Error;
100
+ };
101
+ type SystemEvent = {
102
+ _event: string;
103
+ };
104
+ type ErrorEvent = EventWithError & SystemEvent;
105
+ type Events = BuilderEvents & CollectorEvents & TransformerEvents & WatcherEvents;
106
+ type SystemEvents = {
107
+ _error: ErrorEvent;
108
+ _all: SystemEvent;
109
+ };
110
+
111
+ type ErrorType = "Read" | "Compile";
112
+ declare class ConfigurationError extends Error {
113
+ type: ErrorType;
114
+ constructor(type: ErrorType, message: string);
115
+ }
116
+ type Options$1 = {
117
+ configName: string;
118
+ cacheDir?: string;
119
+ };
120
+
121
+ type BuilderEvents = {
122
+ "builder:start": {
123
+ startedAt: number;
124
+ };
125
+ "builder:end": {
126
+ startedAt: number;
127
+ endedAt: number;
128
+ };
129
+ };
130
+ type Options = Options$1 & {
131
+ outputDir?: string;
132
+ };
133
+ declare function createBuilder(configurationPath: string, options?: Options): Promise<{
134
+ sync: (modification: Modification, filePath: string) => Promise<boolean>;
135
+ build: () => Promise<void>;
136
+ watch: () => Promise<{
137
+ unsubscribe: () => Promise<void>;
138
+ }>;
139
+ on: {
140
+ <TKey extends "builder:start" | "builder:end" | "collector:read-error" | "collector:parse-error" | "transformer:validation-error" | "transformer:error" | "watcher:file-changed">(key: TKey, listener: (event: Events[TKey]) => void): void;
141
+ <TKey_1 extends "_error" | "_all">(key: TKey_1, listener: (event: SystemEvents[TKey_1]) => void): void;
142
+ };
143
+ }>;
144
+ type Builder = Awaited<ReturnType<typeof createBuilder>>;
145
+
146
+ export { AnyCollection, AnyConfiguration, Builder, BuilderEvents, CollectError, Collection, CollectionRequest, Configuration, ConfigurationError, Context, GetTypeByName, Meta, Modification, Schema, TransformError, createBuilder, defineCollection, defineConfig };