@content-collections/core 0.6.2 → 0.6.4
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/dist/index.d.ts +2 -2
- package/dist/index.js +7 -4
- package/package.json +1 -1
- package/dist/index.cjs +0 -919
- package/dist/index.d.cts +0 -206
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import z__default, { ZodRawShape, z as z$1, ZodObject, ZodTypeAny, ZodString } from 'zod';
|
|
2
2
|
export * from 'zod';
|
|
3
|
-
import { parse } from 'yaml';
|
|
4
3
|
|
|
5
4
|
type Parsers = typeof parsers;
|
|
6
5
|
type Parser = keyof typeof parsers;
|
|
6
|
+
declare function parseYaml(content: string): any;
|
|
7
7
|
declare function frontmatterParser(fileContent: string): {
|
|
8
8
|
content: string;
|
|
9
9
|
};
|
|
@@ -18,7 +18,7 @@ declare const parsers: {
|
|
|
18
18
|
};
|
|
19
19
|
readonly yaml: {
|
|
20
20
|
readonly hasContent: false;
|
|
21
|
-
readonly parse: typeof
|
|
21
|
+
readonly parse: typeof parseYaml;
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
|
package/dist/index.js
CHANGED
|
@@ -134,11 +134,14 @@ import path2 from "path";
|
|
|
134
134
|
// src/parser.ts
|
|
135
135
|
import matter from "gray-matter";
|
|
136
136
|
import { parse, stringify } from "yaml";
|
|
137
|
+
function parseYaml(content) {
|
|
138
|
+
return parse(content.trim());
|
|
139
|
+
}
|
|
137
140
|
function frontmatterParser(fileContent) {
|
|
138
141
|
const { data, content } = matter(fileContent, {
|
|
139
142
|
engines: {
|
|
140
143
|
yaml: {
|
|
141
|
-
parse,
|
|
144
|
+
parse: parseYaml,
|
|
142
145
|
stringify
|
|
143
146
|
}
|
|
144
147
|
}
|
|
@@ -159,7 +162,7 @@ var parsers = {
|
|
|
159
162
|
},
|
|
160
163
|
yaml: {
|
|
161
164
|
hasContent: false,
|
|
162
|
-
parse
|
|
165
|
+
parse: parseYaml
|
|
163
166
|
}
|
|
164
167
|
};
|
|
165
168
|
|
|
@@ -520,8 +523,8 @@ function createSynchronizer(readCollectionFile, collections, baseDirectory = "."
|
|
|
520
523
|
const resolvedCollectionPath = path4.resolve(baseDirectory, collectionPath);
|
|
521
524
|
const resolvedFilePath = path4.resolve(filePath);
|
|
522
525
|
let relativePath = resolvedFilePath.slice(resolvedCollectionPath.length);
|
|
523
|
-
if (relativePath.startsWith(
|
|
524
|
-
relativePath = relativePath.slice(
|
|
526
|
+
if (relativePath.startsWith(path4.sep)) {
|
|
527
|
+
relativePath = relativePath.slice(path4.sep.length);
|
|
525
528
|
}
|
|
526
529
|
return relativePath;
|
|
527
530
|
}
|
package/package.json
CHANGED
package/dist/index.cjs
DELETED
|
@@ -1,919 +0,0 @@
|
|
|
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
|
-
CollectError: () => CollectError,
|
|
34
|
-
ConfigurationError: () => ConfigurationError,
|
|
35
|
-
TransformError: () => TransformError,
|
|
36
|
-
createBuilder: () => createBuilder,
|
|
37
|
-
defineCollection: () => defineCollection,
|
|
38
|
-
defineConfig: () => defineConfig
|
|
39
|
-
});
|
|
40
|
-
module.exports = __toCommonJS(src_exports);
|
|
41
|
-
|
|
42
|
-
// src/config.ts
|
|
43
|
-
var import_zod = require("zod");
|
|
44
|
-
|
|
45
|
-
// src/utils.ts
|
|
46
|
-
var import_pluralize = __toESM(require("pluralize"), 1);
|
|
47
|
-
function camelCase(name) {
|
|
48
|
-
return name.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
49
|
-
}
|
|
50
|
-
function generateTypeName(name) {
|
|
51
|
-
const singularName = import_pluralize.default.singular(name);
|
|
52
|
-
return camelCase(singularName);
|
|
53
|
-
}
|
|
54
|
-
function isDefined(value) {
|
|
55
|
-
return value !== void 0 && value !== null;
|
|
56
|
-
}
|
|
57
|
-
function orderByPath(a, b) {
|
|
58
|
-
return a.path.localeCompare(b.path);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// src/config.ts
|
|
62
|
-
var InvalidReturnTypeSymbol = Symbol(`InvalidReturnType`);
|
|
63
|
-
function defineCollection(collection) {
|
|
64
|
-
let typeName = collection.typeName;
|
|
65
|
-
if (!typeName) {
|
|
66
|
-
typeName = generateTypeName(collection.name);
|
|
67
|
-
}
|
|
68
|
-
let parser = collection.parser;
|
|
69
|
-
if (!parser) {
|
|
70
|
-
parser = "frontmatter";
|
|
71
|
-
}
|
|
72
|
-
return {
|
|
73
|
-
...collection,
|
|
74
|
-
typeName,
|
|
75
|
-
parser,
|
|
76
|
-
schema: collection.schema(import_zod.z)
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
function defineConfig(config) {
|
|
80
|
-
return config;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// src/configurationReader.ts
|
|
84
|
-
var esbuild = __toESM(require("esbuild"), 1);
|
|
85
|
-
var import_promises = __toESM(require("fs/promises"), 1);
|
|
86
|
-
var import_node_path = __toESM(require("path"), 1);
|
|
87
|
-
|
|
88
|
-
// package.json
|
|
89
|
-
var package_default = {
|
|
90
|
-
name: "@content-collections/core",
|
|
91
|
-
version: "0.6.0",
|
|
92
|
-
type: "module",
|
|
93
|
-
main: "dist/index.cjs",
|
|
94
|
-
types: "./dist/index.d.cts",
|
|
95
|
-
exports: {
|
|
96
|
-
"./package.json": "./package.json",
|
|
97
|
-
".": {
|
|
98
|
-
import: {
|
|
99
|
-
default: "./dist/index.js",
|
|
100
|
-
types: "./dist/index.d.ts"
|
|
101
|
-
},
|
|
102
|
-
require: {
|
|
103
|
-
default: "./dist/index.cjs",
|
|
104
|
-
types: "./dist/index.d.cts"
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
files: [
|
|
109
|
-
"dist",
|
|
110
|
-
"README.md"
|
|
111
|
-
],
|
|
112
|
-
scripts: {
|
|
113
|
-
build: "tsup src/index.ts --format esm,cjs --dts -d dist",
|
|
114
|
-
typecheck: "tsc",
|
|
115
|
-
test: "vitest --run --coverage",
|
|
116
|
-
prepack: "cp ../../README.md ./README.md",
|
|
117
|
-
postpack: "rm -f ./README.md"
|
|
118
|
-
},
|
|
119
|
-
peerDependencies: {
|
|
120
|
-
typescript: "^5.0.2"
|
|
121
|
-
},
|
|
122
|
-
devDependencies: {
|
|
123
|
-
"@types/micromatch": "^4.0.7",
|
|
124
|
-
"@types/node": "^20.14.9",
|
|
125
|
-
"@types/pluralize": "^0.0.33",
|
|
126
|
-
"@types/serialize-javascript": "^5.0.4",
|
|
127
|
-
"@vitest/coverage-v8": "^1.5.0",
|
|
128
|
-
tsup: "^8.0.2",
|
|
129
|
-
tsx: "^4.1.1",
|
|
130
|
-
typescript: "^5.4.5",
|
|
131
|
-
vitest: "^1.5.0"
|
|
132
|
-
},
|
|
133
|
-
dependencies: {
|
|
134
|
-
"@parcel/watcher": "^2.4.1",
|
|
135
|
-
esbuild: "^0.21.4",
|
|
136
|
-
"fast-glob": "^3.3.2",
|
|
137
|
-
"gray-matter": "^4.0.3",
|
|
138
|
-
micromatch: "^4.0.7",
|
|
139
|
-
pluralize: "^8.0.0",
|
|
140
|
-
"serialize-javascript": "^6.0.2",
|
|
141
|
-
yaml: "^2.4.1",
|
|
142
|
-
zod: "^3.22.5"
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
// src/configurationReader.ts
|
|
147
|
-
var import_node_fs = require("fs");
|
|
148
|
-
var import_node_crypto = require("crypto");
|
|
149
|
-
var ConfigurationError = class extends Error {
|
|
150
|
-
type;
|
|
151
|
-
constructor(type, message) {
|
|
152
|
-
super(message);
|
|
153
|
-
this.type = type;
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
var importPathPlugin = {
|
|
157
|
-
name: "import-path",
|
|
158
|
-
setup(build2) {
|
|
159
|
-
build2.onResolve({ filter: /^\@content-collections\/core$/ }, () => {
|
|
160
|
-
return { path: import_node_path.default.join(__dirname, "index.ts"), external: true };
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
var defaultConfigName = "content-collection-config.mjs";
|
|
165
|
-
function resolveCacheDir(config, options) {
|
|
166
|
-
if (options.cacheDir) {
|
|
167
|
-
return options.cacheDir;
|
|
168
|
-
}
|
|
169
|
-
return import_node_path.default.join(import_node_path.default.dirname(config), ".content-collections", "cache");
|
|
170
|
-
}
|
|
171
|
-
var makeAllPackagesExternalPlugin = (configPath) => ({
|
|
172
|
-
name: "make-all-packages-external",
|
|
173
|
-
setup: (build2) => {
|
|
174
|
-
const filter = /^[^.\/]|^\.[^.\/]|^\.\.[^\/]/;
|
|
175
|
-
build2.onResolve({ filter }, (args) => {
|
|
176
|
-
if (args.path.includes(configPath)) {
|
|
177
|
-
return { path: args.path, external: false };
|
|
178
|
-
}
|
|
179
|
-
return { path: args.path, external: true };
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
async function compile(configurationPath, outfile) {
|
|
184
|
-
const plugins = [makeAllPackagesExternalPlugin(configurationPath)];
|
|
185
|
-
if (process.env.NODE_ENV === "test") {
|
|
186
|
-
plugins.push(importPathPlugin);
|
|
187
|
-
}
|
|
188
|
-
await esbuild.build({
|
|
189
|
-
entryPoints: [configurationPath],
|
|
190
|
-
packages: "external",
|
|
191
|
-
external: [
|
|
192
|
-
...Object.keys(package_default.dependencies),
|
|
193
|
-
"@content-collections/*"
|
|
194
|
-
],
|
|
195
|
-
bundle: true,
|
|
196
|
-
platform: "node",
|
|
197
|
-
format: "esm",
|
|
198
|
-
plugins,
|
|
199
|
-
outfile
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
function createConfigurationReader() {
|
|
203
|
-
return async (configurationPath, options = {
|
|
204
|
-
configName: defaultConfigName
|
|
205
|
-
}) => {
|
|
206
|
-
if (!(0, import_node_fs.existsSync)(configurationPath)) {
|
|
207
|
-
throw new ConfigurationError(
|
|
208
|
-
"Read",
|
|
209
|
-
`configuration file ${configurationPath} does not exist`
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
const cacheDir = resolveCacheDir(configurationPath, options);
|
|
213
|
-
await import_promises.default.mkdir(cacheDir, { recursive: true });
|
|
214
|
-
const outfile = import_node_path.default.join(cacheDir, options.configName);
|
|
215
|
-
try {
|
|
216
|
-
await compile(configurationPath, outfile);
|
|
217
|
-
} catch (error) {
|
|
218
|
-
throw new ConfigurationError(
|
|
219
|
-
"Compile",
|
|
220
|
-
`configuration file ${configurationPath} is invalid: ${error}`
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
const module2 = await import(`file://${import_node_path.default.resolve(outfile)}?x=${Date.now()}`);
|
|
224
|
-
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
225
|
-
hash.update(await import_promises.default.readFile(outfile, "utf-8"));
|
|
226
|
-
const checksum = hash.digest("hex");
|
|
227
|
-
return {
|
|
228
|
-
...module2.default,
|
|
229
|
-
path: configurationPath,
|
|
230
|
-
generateTypes: true,
|
|
231
|
-
checksum
|
|
232
|
-
};
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// src/collector.ts
|
|
237
|
-
var import_fast_glob = __toESM(require("fast-glob"), 1);
|
|
238
|
-
var import_promises2 = require("fs/promises");
|
|
239
|
-
var import_path = __toESM(require("path"), 1);
|
|
240
|
-
|
|
241
|
-
// src/parser.ts
|
|
242
|
-
var import_gray_matter = __toESM(require("gray-matter"), 1);
|
|
243
|
-
var import_yaml = require("yaml");
|
|
244
|
-
function frontmatterParser(fileContent) {
|
|
245
|
-
const { data, content } = (0, import_gray_matter.default)(fileContent, {
|
|
246
|
-
engines: {
|
|
247
|
-
yaml: {
|
|
248
|
-
parse: import_yaml.parse,
|
|
249
|
-
stringify: import_yaml.stringify
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
return {
|
|
254
|
-
...data,
|
|
255
|
-
content: content.trim()
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
var parsers = {
|
|
259
|
-
frontmatter: {
|
|
260
|
-
hasContent: true,
|
|
261
|
-
parse: frontmatterParser
|
|
262
|
-
},
|
|
263
|
-
json: {
|
|
264
|
-
hasContent: false,
|
|
265
|
-
parse: JSON.parse
|
|
266
|
-
},
|
|
267
|
-
yaml: {
|
|
268
|
-
hasContent: false,
|
|
269
|
-
parse: import_yaml.parse
|
|
270
|
-
}
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
// src/collector.ts
|
|
274
|
-
var CollectError = class extends Error {
|
|
275
|
-
type;
|
|
276
|
-
constructor(type, message) {
|
|
277
|
-
super(message);
|
|
278
|
-
this.type = type;
|
|
279
|
-
}
|
|
280
|
-
};
|
|
281
|
-
function createCollector(emitter, baseDirectory = ".") {
|
|
282
|
-
async function read(filePath) {
|
|
283
|
-
try {
|
|
284
|
-
return await (0, import_promises2.readFile)(filePath, "utf-8");
|
|
285
|
-
} catch (error) {
|
|
286
|
-
emitter.emit("collector:read-error", {
|
|
287
|
-
filePath,
|
|
288
|
-
error: new CollectError("Read", String(error))
|
|
289
|
-
});
|
|
290
|
-
return null;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
async function collectFile(collection, filePath) {
|
|
294
|
-
const absolutePath = import_path.default.join(baseDirectory, collection.directory, filePath);
|
|
295
|
-
const file = await read(absolutePath);
|
|
296
|
-
if (!file) {
|
|
297
|
-
return null;
|
|
298
|
-
}
|
|
299
|
-
try {
|
|
300
|
-
const data = parsers[collection.parser].parse(file);
|
|
301
|
-
return {
|
|
302
|
-
data,
|
|
303
|
-
path: filePath
|
|
304
|
-
};
|
|
305
|
-
} catch (error) {
|
|
306
|
-
emitter.emit("collector:parse-error", {
|
|
307
|
-
filePath: import_path.default.join(collection.directory, filePath),
|
|
308
|
-
error: new CollectError("Parse", String(error))
|
|
309
|
-
});
|
|
310
|
-
return null;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
function createIgnorePattern(collection) {
|
|
314
|
-
if (collection.exclude) {
|
|
315
|
-
if (Array.isArray(collection.exclude)) {
|
|
316
|
-
return collection.exclude;
|
|
317
|
-
} else {
|
|
318
|
-
return [collection.exclude];
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
return void 0;
|
|
322
|
-
}
|
|
323
|
-
async function resolveCollection(collection) {
|
|
324
|
-
const collectionDirectory = import_path.default.join(baseDirectory, collection.directory);
|
|
325
|
-
const filePaths = await (0, import_fast_glob.default)(collection.include, {
|
|
326
|
-
cwd: collectionDirectory,
|
|
327
|
-
onlyFiles: true,
|
|
328
|
-
absolute: false,
|
|
329
|
-
ignore: createIgnorePattern(collection)
|
|
330
|
-
});
|
|
331
|
-
const promises = filePaths.map(
|
|
332
|
-
(filePath) => collectFile(collection, filePath)
|
|
333
|
-
);
|
|
334
|
-
const files = await Promise.all(promises);
|
|
335
|
-
return {
|
|
336
|
-
...collection,
|
|
337
|
-
files: files.filter(isDefined).sort(orderByPath)
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
async function collect(unresolvedCollections) {
|
|
341
|
-
const promises = unresolvedCollections.map(
|
|
342
|
-
(collection) => resolveCollection(collection)
|
|
343
|
-
);
|
|
344
|
-
return await Promise.all(promises);
|
|
345
|
-
}
|
|
346
|
-
return {
|
|
347
|
-
collect,
|
|
348
|
-
collectFile
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
// src/writer.ts
|
|
353
|
-
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
354
|
-
var import_node_path2 = __toESM(require("path"), 1);
|
|
355
|
-
var import_pluralize2 = __toESM(require("pluralize"), 1);
|
|
356
|
-
|
|
357
|
-
// src/serializer.ts
|
|
358
|
-
var import_zod2 = __toESM(require("zod"), 1);
|
|
359
|
-
var import_serialize_javascript = __toESM(require("serialize-javascript"), 1);
|
|
360
|
-
var literalSchema = import_zod2.default.union([
|
|
361
|
-
// json
|
|
362
|
-
import_zod2.default.string(),
|
|
363
|
-
import_zod2.default.number(),
|
|
364
|
-
import_zod2.default.boolean(),
|
|
365
|
-
import_zod2.default.null(),
|
|
366
|
-
// serializable-javascript
|
|
367
|
-
import_zod2.default.undefined(),
|
|
368
|
-
import_zod2.default.date(),
|
|
369
|
-
import_zod2.default.map(import_zod2.default.unknown(), import_zod2.default.unknown()),
|
|
370
|
-
import_zod2.default.set(import_zod2.default.unknown()),
|
|
371
|
-
import_zod2.default.bigint()
|
|
372
|
-
]);
|
|
373
|
-
var schema = import_zod2.default.lazy(
|
|
374
|
-
() => import_zod2.default.union([literalSchema, import_zod2.default.array(schema), import_zod2.default.record(schema)])
|
|
375
|
-
);
|
|
376
|
-
var extension = "js";
|
|
377
|
-
var serializableSchema = import_zod2.default.record(schema);
|
|
378
|
-
function serialize(value) {
|
|
379
|
-
const serializedValue = (0, import_serialize_javascript.default)(value, {
|
|
380
|
-
space: 2,
|
|
381
|
-
unsafe: true,
|
|
382
|
-
ignoreFunction: true
|
|
383
|
-
});
|
|
384
|
-
return `export default ${serializedValue};`;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// src/writer.ts
|
|
388
|
-
function createArrayConstName(name) {
|
|
389
|
-
let suffix = name.charAt(0).toUpperCase() + name.slice(1);
|
|
390
|
-
return "all" + (0, import_pluralize2.default)(suffix);
|
|
391
|
-
}
|
|
392
|
-
async function createDataFile(directory, collection) {
|
|
393
|
-
const dataPath = import_node_path2.default.join(
|
|
394
|
-
directory,
|
|
395
|
-
`${createArrayConstName(collection.name)}.${extension}`
|
|
396
|
-
);
|
|
397
|
-
await import_promises3.default.writeFile(
|
|
398
|
-
dataPath,
|
|
399
|
-
serialize(collection.documents.map((doc) => doc.document))
|
|
400
|
-
);
|
|
401
|
-
}
|
|
402
|
-
function createDataFiles(directory, collections) {
|
|
403
|
-
return Promise.all(
|
|
404
|
-
collections.map((collection) => createDataFile(directory, collection))
|
|
405
|
-
);
|
|
406
|
-
}
|
|
407
|
-
async function createJavaScriptFile(directory, configuration) {
|
|
408
|
-
const collections = configuration.collections.map(
|
|
409
|
-
({ name }) => createArrayConstName(name)
|
|
410
|
-
);
|
|
411
|
-
let content = `// generated by content-collections at ${/* @__PURE__ */ new Date()}
|
|
412
|
-
|
|
413
|
-
`;
|
|
414
|
-
for (const name of collections) {
|
|
415
|
-
content += `import ${name} from "./${name}.${extension}";
|
|
416
|
-
`;
|
|
417
|
-
}
|
|
418
|
-
content += "\n";
|
|
419
|
-
content += "export { " + collections.join(", ") + " };\n";
|
|
420
|
-
await import_promises3.default.writeFile(import_node_path2.default.join(directory, "index.js"), content, "utf-8");
|
|
421
|
-
}
|
|
422
|
-
function createImportPath(directory, target) {
|
|
423
|
-
let importPath = import_node_path2.default.posix.join(
|
|
424
|
-
...import_node_path2.default.relative(directory, target).split(import_node_path2.default.sep)
|
|
425
|
-
);
|
|
426
|
-
if (!importPath.startsWith(".")) {
|
|
427
|
-
importPath = "./" + importPath;
|
|
428
|
-
}
|
|
429
|
-
return importPath;
|
|
430
|
-
}
|
|
431
|
-
async function createTypeDefinitionFile(directory, configuration) {
|
|
432
|
-
if (!configuration.generateTypes) {
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
const importPath = createImportPath(directory, configuration.path);
|
|
436
|
-
let content = `import configuration from "${importPath}";
|
|
437
|
-
import { GetTypeByName } from "@content-collections/core";
|
|
438
|
-
`;
|
|
439
|
-
const collections = configuration.collections;
|
|
440
|
-
for (const collection of collections) {
|
|
441
|
-
content += `
|
|
442
|
-
`;
|
|
443
|
-
content += `export type ${collection.typeName} = GetTypeByName<typeof configuration, "${collection.name}">;
|
|
444
|
-
`;
|
|
445
|
-
content += `export declare const ${createArrayConstName(
|
|
446
|
-
collection.name
|
|
447
|
-
)}: Array<${collection.typeName}>;
|
|
448
|
-
`;
|
|
449
|
-
}
|
|
450
|
-
content += "\n";
|
|
451
|
-
content += "export {};\n";
|
|
452
|
-
await import_promises3.default.writeFile(import_node_path2.default.join(directory, "index.d.ts"), content, "utf-8");
|
|
453
|
-
}
|
|
454
|
-
async function createWriter(directory) {
|
|
455
|
-
await import_promises3.default.mkdir(directory, { recursive: true });
|
|
456
|
-
return {
|
|
457
|
-
createJavaScriptFile: (configuration) => createJavaScriptFile(directory, configuration),
|
|
458
|
-
createTypeDefinitionFile: (configuration) => createTypeDefinitionFile(directory, configuration),
|
|
459
|
-
createDataFiles: (collections) => createDataFiles(directory, collections)
|
|
460
|
-
};
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
// src/transformer.ts
|
|
464
|
-
var import_node_path3 = require("path");
|
|
465
|
-
var import_zod3 = require("zod");
|
|
466
|
-
var TransformError = class extends Error {
|
|
467
|
-
type;
|
|
468
|
-
constructor(type, message) {
|
|
469
|
-
super(message);
|
|
470
|
-
this.type = type;
|
|
471
|
-
}
|
|
472
|
-
};
|
|
473
|
-
function createPath(path7, ext) {
|
|
474
|
-
let p = path7.slice(0, -ext.length);
|
|
475
|
-
if (p.endsWith("/index")) {
|
|
476
|
-
p = p.slice(0, -6);
|
|
477
|
-
}
|
|
478
|
-
return p;
|
|
479
|
-
}
|
|
480
|
-
function createTransformer(emitter, cacheManager) {
|
|
481
|
-
function createSchema(parserName, schema2) {
|
|
482
|
-
const parser = parsers[parserName];
|
|
483
|
-
if (!parser.hasContent) {
|
|
484
|
-
return import_zod3.z.object(schema2);
|
|
485
|
-
}
|
|
486
|
-
return import_zod3.z.object({
|
|
487
|
-
content: import_zod3.z.string(),
|
|
488
|
-
...schema2
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
async function parseFile(collection, file) {
|
|
492
|
-
const { data, path: path7 } = file;
|
|
493
|
-
const schema2 = createSchema(collection.parser, collection.schema);
|
|
494
|
-
let parsedData = await schema2.safeParseAsync(data);
|
|
495
|
-
if (!parsedData.success) {
|
|
496
|
-
emitter.emit("transformer:validation-error", {
|
|
497
|
-
collection,
|
|
498
|
-
file,
|
|
499
|
-
error: new TransformError("Validation", parsedData.error.message)
|
|
500
|
-
});
|
|
501
|
-
return null;
|
|
502
|
-
}
|
|
503
|
-
const ext = (0, import_node_path3.extname)(path7);
|
|
504
|
-
let extension2 = ext;
|
|
505
|
-
if (extension2.startsWith(".")) {
|
|
506
|
-
extension2 = extension2.slice(1);
|
|
507
|
-
}
|
|
508
|
-
const document = {
|
|
509
|
-
...parsedData.data,
|
|
510
|
-
_meta: {
|
|
511
|
-
filePath: path7,
|
|
512
|
-
fileName: (0, import_node_path3.basename)(path7),
|
|
513
|
-
directory: (0, import_node_path3.dirname)(path7),
|
|
514
|
-
extension: extension2,
|
|
515
|
-
path: createPath(path7, ext)
|
|
516
|
-
}
|
|
517
|
-
};
|
|
518
|
-
return {
|
|
519
|
-
document
|
|
520
|
-
};
|
|
521
|
-
}
|
|
522
|
-
async function parseCollection(collection) {
|
|
523
|
-
const promises = collection.files.map(
|
|
524
|
-
(file) => parseFile(collection, file)
|
|
525
|
-
);
|
|
526
|
-
return {
|
|
527
|
-
...collection,
|
|
528
|
-
documents: (await Promise.all(promises)).filter(isDefined)
|
|
529
|
-
};
|
|
530
|
-
}
|
|
531
|
-
function createContext(collections, collection, cache) {
|
|
532
|
-
return {
|
|
533
|
-
documents: (collection2) => {
|
|
534
|
-
const resolved = collections.find((c) => c.name === collection2.name);
|
|
535
|
-
if (!resolved) {
|
|
536
|
-
throw new TransformError(
|
|
537
|
-
"Configuration",
|
|
538
|
-
`Collection ${collection2.name} not found, do you have registered it in your configuration?`
|
|
539
|
-
);
|
|
540
|
-
}
|
|
541
|
-
return resolved.documents.map((doc) => doc.document);
|
|
542
|
-
},
|
|
543
|
-
collection: {
|
|
544
|
-
name: collection.name,
|
|
545
|
-
directory: collection.directory
|
|
546
|
-
},
|
|
547
|
-
cache: cache.cacheFn
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
async function transformCollection(collections, collection) {
|
|
551
|
-
if (collection.transform) {
|
|
552
|
-
const docs = [];
|
|
553
|
-
for (const doc of collection.documents) {
|
|
554
|
-
const cache = cacheManager.cache(
|
|
555
|
-
collection.name,
|
|
556
|
-
doc.document._meta.path
|
|
557
|
-
);
|
|
558
|
-
const context = createContext(collections, collection, cache);
|
|
559
|
-
try {
|
|
560
|
-
const document = await collection.transform(doc.document, context);
|
|
561
|
-
docs.push({
|
|
562
|
-
...doc,
|
|
563
|
-
document
|
|
564
|
-
});
|
|
565
|
-
await cache.tidyUp();
|
|
566
|
-
} catch (error) {
|
|
567
|
-
if (error instanceof TransformError) {
|
|
568
|
-
emitter.emit("transformer:error", {
|
|
569
|
-
collection,
|
|
570
|
-
error
|
|
571
|
-
});
|
|
572
|
-
} else {
|
|
573
|
-
emitter.emit("transformer:error", {
|
|
574
|
-
collection,
|
|
575
|
-
error: new TransformError("Transform", String(error))
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
await cacheManager.flush();
|
|
581
|
-
return docs;
|
|
582
|
-
}
|
|
583
|
-
return collection.documents;
|
|
584
|
-
}
|
|
585
|
-
async function validateDocuments(collection, documents) {
|
|
586
|
-
const docs = [];
|
|
587
|
-
for (const doc of documents) {
|
|
588
|
-
let parsedData = await serializableSchema.safeParseAsync(doc.document);
|
|
589
|
-
if (parsedData.success) {
|
|
590
|
-
docs.push(doc);
|
|
591
|
-
} else {
|
|
592
|
-
emitter.emit("transformer:result-error", {
|
|
593
|
-
collection,
|
|
594
|
-
document: doc.document,
|
|
595
|
-
error: new TransformError("Result", parsedData.error.message)
|
|
596
|
-
});
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
return docs;
|
|
600
|
-
}
|
|
601
|
-
return async (untransformedCollections) => {
|
|
602
|
-
const promises = untransformedCollections.map(
|
|
603
|
-
(collection) => parseCollection(collection)
|
|
604
|
-
);
|
|
605
|
-
const collections = await Promise.all(promises);
|
|
606
|
-
for (const collection of collections) {
|
|
607
|
-
const documents = await transformCollection(collections, collection);
|
|
608
|
-
collection.documents = await validateDocuments(collection, documents);
|
|
609
|
-
}
|
|
610
|
-
return collections;
|
|
611
|
-
};
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
// src/synchronizer.ts
|
|
615
|
-
var import_micromatch = __toESM(require("micromatch"), 1);
|
|
616
|
-
var import_node_path4 = __toESM(require("path"), 1);
|
|
617
|
-
function createSynchronizer(readCollectionFile, collections, baseDirectory = ".") {
|
|
618
|
-
function findCollections(filePath) {
|
|
619
|
-
const resolvedFilePath = import_node_path4.default.resolve(filePath);
|
|
620
|
-
return collections.filter((collection) => {
|
|
621
|
-
return resolvedFilePath.startsWith(
|
|
622
|
-
import_node_path4.default.resolve(baseDirectory, collection.directory)
|
|
623
|
-
);
|
|
624
|
-
});
|
|
625
|
-
}
|
|
626
|
-
function createRelativePath(collectionPath, filePath) {
|
|
627
|
-
const resolvedCollectionPath = import_node_path4.default.resolve(baseDirectory, collectionPath);
|
|
628
|
-
const resolvedFilePath = import_node_path4.default.resolve(filePath);
|
|
629
|
-
let relativePath = resolvedFilePath.slice(resolvedCollectionPath.length);
|
|
630
|
-
if (relativePath.startsWith("/")) {
|
|
631
|
-
relativePath = relativePath.slice(1);
|
|
632
|
-
}
|
|
633
|
-
return relativePath;
|
|
634
|
-
}
|
|
635
|
-
function resolve(filePath) {
|
|
636
|
-
const collections2 = findCollections(filePath);
|
|
637
|
-
return collections2.map((collection) => {
|
|
638
|
-
const relativePath = createRelativePath(collection.directory, filePath);
|
|
639
|
-
return {
|
|
640
|
-
collection,
|
|
641
|
-
relativePath
|
|
642
|
-
};
|
|
643
|
-
}).filter(({ collection, relativePath }) => {
|
|
644
|
-
return import_micromatch.default.isMatch(relativePath, collection.include, {
|
|
645
|
-
ignore: collection.exclude
|
|
646
|
-
});
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
|
-
function deleted(filePath) {
|
|
650
|
-
const resolvedCollections = resolve(filePath);
|
|
651
|
-
if (resolvedCollections.length === 0) {
|
|
652
|
-
return false;
|
|
653
|
-
}
|
|
654
|
-
let changed2 = false;
|
|
655
|
-
for (const { collection, relativePath } of resolvedCollections) {
|
|
656
|
-
const index = collection.files.findIndex(
|
|
657
|
-
(file) => file.path === relativePath
|
|
658
|
-
);
|
|
659
|
-
const deleted2 = collection.files.splice(index, 1);
|
|
660
|
-
if (deleted2.length > 0) {
|
|
661
|
-
changed2 = true;
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
return changed2;
|
|
665
|
-
}
|
|
666
|
-
async function changed(filePath) {
|
|
667
|
-
const resolvedCollections = resolve(filePath);
|
|
668
|
-
if (resolvedCollections.length === 0) {
|
|
669
|
-
return false;
|
|
670
|
-
}
|
|
671
|
-
let changed2 = false;
|
|
672
|
-
for (const { collection, relativePath } of resolvedCollections) {
|
|
673
|
-
const index = collection.files.findIndex(
|
|
674
|
-
(file2) => file2.path === relativePath
|
|
675
|
-
);
|
|
676
|
-
const file = await readCollectionFile(collection, relativePath);
|
|
677
|
-
if (file) {
|
|
678
|
-
changed2 = true;
|
|
679
|
-
if (index === -1) {
|
|
680
|
-
collection.files.push(file);
|
|
681
|
-
collection.files.sort(orderByPath);
|
|
682
|
-
} else {
|
|
683
|
-
collection.files[index] = file;
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
return changed2;
|
|
688
|
-
}
|
|
689
|
-
return {
|
|
690
|
-
deleted,
|
|
691
|
-
changed
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
// src/builder.ts
|
|
696
|
-
var import_node_path6 = __toESM(require("path"), 1);
|
|
697
|
-
|
|
698
|
-
// src/watcher.ts
|
|
699
|
-
var watcher = __toESM(require("@parcel/watcher"), 1);
|
|
700
|
-
async function createWatcher(emitter, paths, sync, build2) {
|
|
701
|
-
const onChange = async (error, events) => {
|
|
702
|
-
if (error) {
|
|
703
|
-
console.error(error);
|
|
704
|
-
return;
|
|
705
|
-
}
|
|
706
|
-
let rebuild = false;
|
|
707
|
-
for (const event of events) {
|
|
708
|
-
if (await sync(event.type, event.path)) {
|
|
709
|
-
emitter.emit("watcher:file-changed", {
|
|
710
|
-
filePath: event.path,
|
|
711
|
-
modification: event.type
|
|
712
|
-
});
|
|
713
|
-
rebuild = true;
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
if (rebuild) {
|
|
717
|
-
await build2();
|
|
718
|
-
}
|
|
719
|
-
};
|
|
720
|
-
const subscriptions = await Promise.all(
|
|
721
|
-
paths.map((path7) => watcher.subscribe(path7, onChange))
|
|
722
|
-
);
|
|
723
|
-
return {
|
|
724
|
-
unsubscribe: async () => {
|
|
725
|
-
await Promise.all(
|
|
726
|
-
subscriptions.map((subscription) => subscription.unsubscribe())
|
|
727
|
-
);
|
|
728
|
-
return;
|
|
729
|
-
}
|
|
730
|
-
};
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
// src/events.ts
|
|
734
|
-
var import_node_events = require("events");
|
|
735
|
-
function isEventWithError(event) {
|
|
736
|
-
return typeof event === "object" && event !== null && "error" in event;
|
|
737
|
-
}
|
|
738
|
-
function createEmitter() {
|
|
739
|
-
const emitter = new import_node_events.EventEmitter();
|
|
740
|
-
function on(key, listener) {
|
|
741
|
-
emitter.on(key, listener);
|
|
742
|
-
}
|
|
743
|
-
function emit(key, event) {
|
|
744
|
-
emitter.emit(key, event);
|
|
745
|
-
if (isEventWithError(event)) {
|
|
746
|
-
emitter.emit("_error", {
|
|
747
|
-
...event,
|
|
748
|
-
_event: key
|
|
749
|
-
});
|
|
750
|
-
}
|
|
751
|
-
emitter.emit("_all", {
|
|
752
|
-
...event,
|
|
753
|
-
_event: key
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
return {
|
|
757
|
-
on,
|
|
758
|
-
emit
|
|
759
|
-
};
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// src/cache.ts
|
|
763
|
-
var import_node_path5 = __toESM(require("path"), 1);
|
|
764
|
-
var import_promises4 = require("fs/promises");
|
|
765
|
-
var import_node_fs2 = require("fs");
|
|
766
|
-
var import_node_crypto2 = require("crypto");
|
|
767
|
-
function createKey(config, input) {
|
|
768
|
-
return (0, import_node_crypto2.createHash)("sha256").update(config).update(JSON.stringify(input)).digest("hex");
|
|
769
|
-
}
|
|
770
|
-
async function createCacheDirectory(directory) {
|
|
771
|
-
const cacheDirectory = import_node_path5.default.join(directory, ".content-collections", "cache");
|
|
772
|
-
if (!(0, import_node_fs2.existsSync)(cacheDirectory)) {
|
|
773
|
-
await (0, import_promises4.mkdir)(cacheDirectory, { recursive: true });
|
|
774
|
-
}
|
|
775
|
-
return cacheDirectory;
|
|
776
|
-
}
|
|
777
|
-
function fileName(input) {
|
|
778
|
-
return input.replace(/[^a-z0-9]/gi, "_").toLowerCase();
|
|
779
|
-
}
|
|
780
|
-
async function createCacheManager(baseDirectory, configChecksum) {
|
|
781
|
-
const cacheDirectory = await createCacheDirectory(baseDirectory);
|
|
782
|
-
let mapping = {};
|
|
783
|
-
const mappingPath = (0, import_node_path5.join)(cacheDirectory, "mapping.json");
|
|
784
|
-
if ((0, import_node_fs2.existsSync)(mappingPath)) {
|
|
785
|
-
mapping = JSON.parse(await (0, import_promises4.readFile)(mappingPath, "utf-8"));
|
|
786
|
-
}
|
|
787
|
-
async function flush() {
|
|
788
|
-
await (0, import_promises4.writeFile)(mappingPath, JSON.stringify(mapping));
|
|
789
|
-
}
|
|
790
|
-
function cache(collection, file) {
|
|
791
|
-
const directory = (0, import_node_path5.join)(
|
|
792
|
-
cacheDirectory,
|
|
793
|
-
fileName(collection),
|
|
794
|
-
fileName(file)
|
|
795
|
-
);
|
|
796
|
-
let collectionMapping = mapping[collection];
|
|
797
|
-
if (!collectionMapping) {
|
|
798
|
-
collectionMapping = {};
|
|
799
|
-
mapping[collection] = collectionMapping;
|
|
800
|
-
}
|
|
801
|
-
let fileMapping = collectionMapping[file];
|
|
802
|
-
if (!fileMapping) {
|
|
803
|
-
fileMapping = [];
|
|
804
|
-
collectionMapping[file] = fileMapping;
|
|
805
|
-
}
|
|
806
|
-
let newFileMapping = [];
|
|
807
|
-
const cacheFn = async (input, fn) => {
|
|
808
|
-
const key = createKey(configChecksum, input);
|
|
809
|
-
newFileMapping.push(key);
|
|
810
|
-
const filePath = (0, import_node_path5.join)(directory, `${key}.cache`);
|
|
811
|
-
if (fileMapping?.includes(key) || newFileMapping.includes(key)) {
|
|
812
|
-
if ((0, import_node_fs2.existsSync)(filePath)) {
|
|
813
|
-
return JSON.parse(await (0, import_promises4.readFile)(filePath, "utf-8"));
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
const output = await fn(input);
|
|
817
|
-
if (!(0, import_node_fs2.existsSync)(directory)) {
|
|
818
|
-
await (0, import_promises4.mkdir)(directory, { recursive: true });
|
|
819
|
-
}
|
|
820
|
-
await (0, import_promises4.writeFile)(filePath, JSON.stringify(output));
|
|
821
|
-
return output;
|
|
822
|
-
};
|
|
823
|
-
const tidyUp = async () => {
|
|
824
|
-
const filesToDelete = fileMapping?.filter((key) => !newFileMapping.includes(key)) || [];
|
|
825
|
-
for (const key of filesToDelete) {
|
|
826
|
-
const filePath = (0, import_node_path5.join)(directory, `${key}.cache`);
|
|
827
|
-
if ((0, import_node_fs2.existsSync)(filePath)) {
|
|
828
|
-
await (0, import_promises4.unlink)(filePath);
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
if (collectionMapping) {
|
|
832
|
-
collectionMapping[file] = newFileMapping;
|
|
833
|
-
}
|
|
834
|
-
};
|
|
835
|
-
return {
|
|
836
|
-
cacheFn,
|
|
837
|
-
tidyUp
|
|
838
|
-
};
|
|
839
|
-
}
|
|
840
|
-
return {
|
|
841
|
-
cache,
|
|
842
|
-
flush
|
|
843
|
-
};
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
// src/builder.ts
|
|
847
|
-
function resolveOutputDir(baseDirectory, options) {
|
|
848
|
-
if (options.outputDir) {
|
|
849
|
-
return options.outputDir;
|
|
850
|
-
}
|
|
851
|
-
return import_node_path6.default.join(baseDirectory, ".content-collections", "generated");
|
|
852
|
-
}
|
|
853
|
-
async function createBuilder(configurationPath, options = {
|
|
854
|
-
configName: defaultConfigName
|
|
855
|
-
}) {
|
|
856
|
-
const emitter = createEmitter();
|
|
857
|
-
const readConfiguration = createConfigurationReader();
|
|
858
|
-
const configuration = await readConfiguration(configurationPath, options);
|
|
859
|
-
const baseDirectory = import_node_path6.default.dirname(configurationPath);
|
|
860
|
-
const directory = resolveOutputDir(baseDirectory, options);
|
|
861
|
-
const collector = createCollector(emitter, baseDirectory);
|
|
862
|
-
const writer = await createWriter(directory);
|
|
863
|
-
const [resolved] = await Promise.all([
|
|
864
|
-
collector.collect(configuration.collections),
|
|
865
|
-
writer.createJavaScriptFile(configuration),
|
|
866
|
-
writer.createTypeDefinitionFile(configuration)
|
|
867
|
-
]);
|
|
868
|
-
const synchronizer = createSynchronizer(
|
|
869
|
-
collector.collectFile,
|
|
870
|
-
resolved,
|
|
871
|
-
baseDirectory
|
|
872
|
-
);
|
|
873
|
-
const cacheManager = await createCacheManager(baseDirectory, configuration.checksum);
|
|
874
|
-
const transform = createTransformer(emitter, cacheManager);
|
|
875
|
-
async function sync(modification, filePath) {
|
|
876
|
-
if (modification === "delete") {
|
|
877
|
-
return synchronizer.deleted(filePath);
|
|
878
|
-
}
|
|
879
|
-
return synchronizer.changed(filePath);
|
|
880
|
-
}
|
|
881
|
-
async function build2() {
|
|
882
|
-
const startedAt = Date.now();
|
|
883
|
-
emitter.emit("builder:start", {
|
|
884
|
-
startedAt
|
|
885
|
-
});
|
|
886
|
-
const collections = await transform(resolved);
|
|
887
|
-
await writer.createDataFiles(collections);
|
|
888
|
-
const pendingOnSuccess = collections.filter((collection) => Boolean(collection.onSuccess)).map(
|
|
889
|
-
(collection) => collection.onSuccess?.(collection.documents.map((doc) => doc.document))
|
|
890
|
-
);
|
|
891
|
-
await Promise.all(pendingOnSuccess.filter(isDefined));
|
|
892
|
-
emitter.emit("builder:end", {
|
|
893
|
-
startedAt,
|
|
894
|
-
endedAt: Date.now()
|
|
895
|
-
});
|
|
896
|
-
}
|
|
897
|
-
async function watch() {
|
|
898
|
-
const paths = resolved.map(
|
|
899
|
-
(collection) => import_node_path6.default.join(baseDirectory, collection.directory)
|
|
900
|
-
);
|
|
901
|
-
const watcher2 = await createWatcher(emitter, paths, sync, build2);
|
|
902
|
-
return watcher2;
|
|
903
|
-
}
|
|
904
|
-
return {
|
|
905
|
-
sync,
|
|
906
|
-
build: build2,
|
|
907
|
-
watch,
|
|
908
|
-
on: emitter.on
|
|
909
|
-
};
|
|
910
|
-
}
|
|
911
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
912
|
-
0 && (module.exports = {
|
|
913
|
-
CollectError,
|
|
914
|
-
ConfigurationError,
|
|
915
|
-
TransformError,
|
|
916
|
-
createBuilder,
|
|
917
|
-
defineCollection,
|
|
918
|
-
defineConfig
|
|
919
|
-
});
|
package/dist/index.d.cts
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import z, { ZodRawShape, z as z$1, ZodObject, ZodTypeAny, ZodString } from 'zod';
|
|
2
|
-
import { parse } from 'yaml';
|
|
3
|
-
|
|
4
|
-
type Parsers = typeof parsers;
|
|
5
|
-
type Parser = keyof typeof parsers;
|
|
6
|
-
declare function frontmatterParser(fileContent: string): {
|
|
7
|
-
content: string;
|
|
8
|
-
};
|
|
9
|
-
declare const parsers: {
|
|
10
|
-
readonly frontmatter: {
|
|
11
|
-
readonly hasContent: true;
|
|
12
|
-
readonly parse: typeof frontmatterParser;
|
|
13
|
-
};
|
|
14
|
-
readonly json: {
|
|
15
|
-
readonly hasContent: false;
|
|
16
|
-
readonly parse: (text: string, reviver?: ((this: any, key: string, value: any) => any) | undefined) => any;
|
|
17
|
-
};
|
|
18
|
-
readonly yaml: {
|
|
19
|
-
readonly hasContent: false;
|
|
20
|
-
readonly parse: typeof parse;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
type CacheFn = <TInput, TOutput>(input: TInput, compute: (input: TInput) => Promise<TOutput> | TOutput) => Promise<TOutput>;
|
|
25
|
-
|
|
26
|
-
declare const literalSchema: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined, z.ZodDate, z.ZodMap<z.ZodUnknown, z.ZodUnknown>, z.ZodSet<z.ZodUnknown>, z.ZodBigInt]>;
|
|
27
|
-
type Literal = z.infer<typeof literalSchema>;
|
|
28
|
-
type SchemaType = Literal | {
|
|
29
|
-
[key: string]: SchemaType;
|
|
30
|
-
} | SchemaType[];
|
|
31
|
-
type NotSerializableError = `The return type of the transform function must be an object serializable object.
|
|
32
|
-
See https://www.content-collections.dev/docs/serialization for more information.
|
|
33
|
-
|
|
34
|
-
The following type is not valid:`;
|
|
35
|
-
declare const serializableSchema: z.ZodRecord<z.ZodString, z.ZodType<SchemaType, z.ZodTypeDef, SchemaType>>;
|
|
36
|
-
type Serializable = z.infer<typeof serializableSchema>;
|
|
37
|
-
|
|
38
|
-
type Meta = {
|
|
39
|
-
filePath: string;
|
|
40
|
-
fileName: string;
|
|
41
|
-
directory: string;
|
|
42
|
-
path: string;
|
|
43
|
-
extension: string;
|
|
44
|
-
};
|
|
45
|
-
type WithContent = {
|
|
46
|
-
content: ZodString;
|
|
47
|
-
};
|
|
48
|
-
type AddContent<TShape extends ZodRawShape> = TShape extends {
|
|
49
|
-
content: ZodTypeAny;
|
|
50
|
-
} ? TShape : TShape & WithContent;
|
|
51
|
-
type GetParsedShape<TParser extends Parser, TShape extends ZodRawShape> = Parsers[TParser]["hasContent"] extends true ? AddContent<TShape> : TShape;
|
|
52
|
-
type GetShape<TParser extends Parser | undefined, TShape extends ZodRawShape> = TParser extends Parser ? GetParsedShape<TParser, TShape> : AddContent<TShape>;
|
|
53
|
-
type Schema<TParser extends Parser | undefined, TShape extends ZodRawShape> = z$1.infer<ZodObject<GetShape<TParser, TShape>>> & {
|
|
54
|
-
_meta: Meta;
|
|
55
|
-
};
|
|
56
|
-
type Context = {
|
|
57
|
-
documents<TCollection extends AnyCollection>(collection: TCollection): Array<Schema<TCollection["parser"], TCollection["schema"]>>;
|
|
58
|
-
cache: CacheFn;
|
|
59
|
-
collection: {
|
|
60
|
-
name: string;
|
|
61
|
-
directory: string;
|
|
62
|
-
};
|
|
63
|
-
};
|
|
64
|
-
type Z = typeof z$1;
|
|
65
|
-
type CollectionRequest<TName extends string, TShape extends ZodRawShape, TParser, TSchema, TTransformResult, TDocument> = {
|
|
66
|
-
name: TName;
|
|
67
|
-
parser?: TParser;
|
|
68
|
-
typeName?: string;
|
|
69
|
-
schema: (z: Z) => TShape;
|
|
70
|
-
transform?: (data: TSchema, context: Context) => TTransformResult;
|
|
71
|
-
directory: string;
|
|
72
|
-
include: string | string[];
|
|
73
|
-
exclude?: string | string[];
|
|
74
|
-
onSuccess?: (documents: Array<TDocument>) => void | Promise<void>;
|
|
75
|
-
};
|
|
76
|
-
type Collection<TName extends string, TShape extends ZodRawShape, TParser extends Parser, TSchema, TTransformResult, TDocument> = Omit<CollectionRequest<TName, TShape, TParser, TSchema, TTransformResult, TDocument>, "schema"> & {
|
|
77
|
-
typeName: string;
|
|
78
|
-
schema: TShape;
|
|
79
|
-
parser: TParser;
|
|
80
|
-
};
|
|
81
|
-
type AnyCollection = Collection<any, ZodRawShape, Parser, any, any, any>;
|
|
82
|
-
declare const InvalidReturnTypeSymbol: unique symbol;
|
|
83
|
-
type InvalidReturnType<TMessage extends string, TObject> = {
|
|
84
|
-
[InvalidReturnTypeSymbol]: TMessage;
|
|
85
|
-
object: TObject;
|
|
86
|
-
};
|
|
87
|
-
declare function defineCollection<TName extends string, TShape extends ZodRawShape, TParser extends Parser = "frontmatter", TSchema = Schema<TParser, TShape>, TTransformResult = never, TDocument = [TTransformResult] extends [never] ? Schema<TParser, TShape> : Awaited<TTransformResult>, TResult = TDocument extends Serializable ? Collection<TName, TShape, TParser, TSchema, TTransformResult, TDocument> : InvalidReturnType<NotSerializableError, TDocument>>(collection: CollectionRequest<TName, TShape, TParser, TSchema, TTransformResult, TDocument>): TResult;
|
|
88
|
-
type Cache = "memory" | "file" | "none";
|
|
89
|
-
type Configuration<TCollections extends Array<AnyCollection>> = {
|
|
90
|
-
collections: TCollections;
|
|
91
|
-
cache?: Cache;
|
|
92
|
-
};
|
|
93
|
-
type AnyConfiguration = Configuration<Array<AnyCollection>>;
|
|
94
|
-
declare function defineConfig<TConfig extends AnyConfiguration>(config: TConfig): TConfig;
|
|
95
|
-
|
|
96
|
-
type Modification = "create" | "update" | "delete";
|
|
97
|
-
type Document = {
|
|
98
|
-
_meta: Meta;
|
|
99
|
-
};
|
|
100
|
-
type CollectionFile = {
|
|
101
|
-
data: {
|
|
102
|
-
content?: string;
|
|
103
|
-
[key: string]: unknown;
|
|
104
|
-
};
|
|
105
|
-
path: string;
|
|
106
|
-
};
|
|
107
|
-
type CollectionByName<TConfiguration extends AnyConfiguration> = {
|
|
108
|
-
[TCollection in TConfiguration["collections"][number] as TCollection["name"]]: TCollection;
|
|
109
|
-
};
|
|
110
|
-
type GetDocument<TCollection extends AnyCollection> = TCollection extends Collection<any, ZodRawShape, any, any, any, infer TDocument> ? TDocument : never;
|
|
111
|
-
type GetTypeByName<TConfiguration extends AnyConfiguration, TName extends keyof CollectionByName<TConfiguration>, TCollection = CollectionByName<TConfiguration>[TName]> = TCollection extends AnyCollection ? GetDocument<TCollection> : never;
|
|
112
|
-
|
|
113
|
-
type CollectorEvents = {
|
|
114
|
-
"collector:read-error": {
|
|
115
|
-
filePath: string;
|
|
116
|
-
error: CollectError;
|
|
117
|
-
};
|
|
118
|
-
"collector:parse-error": {
|
|
119
|
-
filePath: string;
|
|
120
|
-
error: CollectError;
|
|
121
|
-
};
|
|
122
|
-
};
|
|
123
|
-
type ErrorType$2 = "Parse" | "Read";
|
|
124
|
-
declare class CollectError extends Error {
|
|
125
|
-
type: ErrorType$2;
|
|
126
|
-
constructor(type: ErrorType$2, message: string);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
type TransformerEvents = {
|
|
130
|
-
"transformer:validation-error": {
|
|
131
|
-
collection: AnyCollection;
|
|
132
|
-
file: CollectionFile;
|
|
133
|
-
error: TransformError;
|
|
134
|
-
};
|
|
135
|
-
"transformer:result-error": {
|
|
136
|
-
collection: AnyCollection;
|
|
137
|
-
document: any;
|
|
138
|
-
error: TransformError;
|
|
139
|
-
};
|
|
140
|
-
"transformer:error": {
|
|
141
|
-
collection: AnyCollection;
|
|
142
|
-
error: TransformError;
|
|
143
|
-
};
|
|
144
|
-
};
|
|
145
|
-
type ErrorType$1 = "Validation" | "Configuration" | "Transform" | "Result";
|
|
146
|
-
declare class TransformError extends Error {
|
|
147
|
-
type: ErrorType$1;
|
|
148
|
-
constructor(type: ErrorType$1, message: string);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
type WatcherEvents = {
|
|
152
|
-
"watcher:file-changed": {
|
|
153
|
-
filePath: string;
|
|
154
|
-
modification: Modification;
|
|
155
|
-
};
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
type EventWithError = {
|
|
159
|
-
error: Error;
|
|
160
|
-
};
|
|
161
|
-
type SystemEvent = {
|
|
162
|
-
_event: string;
|
|
163
|
-
};
|
|
164
|
-
type ErrorEvent = EventWithError & SystemEvent;
|
|
165
|
-
type Events = BuilderEvents & CollectorEvents & TransformerEvents & WatcherEvents;
|
|
166
|
-
type SystemEvents = {
|
|
167
|
-
_error: ErrorEvent;
|
|
168
|
-
_all: SystemEvent;
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
type ErrorType = "Read" | "Compile";
|
|
172
|
-
declare class ConfigurationError extends Error {
|
|
173
|
-
type: ErrorType;
|
|
174
|
-
constructor(type: ErrorType, message: string);
|
|
175
|
-
}
|
|
176
|
-
type Options$1 = {
|
|
177
|
-
configName: string;
|
|
178
|
-
cacheDir?: string;
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
type BuilderEvents = {
|
|
182
|
-
"builder:start": {
|
|
183
|
-
startedAt: number;
|
|
184
|
-
};
|
|
185
|
-
"builder:end": {
|
|
186
|
-
startedAt: number;
|
|
187
|
-
endedAt: number;
|
|
188
|
-
};
|
|
189
|
-
};
|
|
190
|
-
type Options = Options$1 & {
|
|
191
|
-
outputDir?: string;
|
|
192
|
-
};
|
|
193
|
-
declare function createBuilder(configurationPath: string, options?: Options): Promise<{
|
|
194
|
-
sync: (modification: Modification, filePath: string) => Promise<boolean>;
|
|
195
|
-
build: () => Promise<void>;
|
|
196
|
-
watch: () => Promise<{
|
|
197
|
-
unsubscribe: () => Promise<void>;
|
|
198
|
-
}>;
|
|
199
|
-
on: {
|
|
200
|
-
<TKey extends "builder:start" | "builder:end" | "collector:read-error" | "collector:parse-error" | "transformer:validation-error" | "transformer:result-error" | "transformer:error" | "watcher:file-changed">(key: TKey, listener: (event: Events[TKey]) => void): void;
|
|
201
|
-
<TKey_1 extends "_error" | "_all">(key: TKey_1, listener: (event: SystemEvents[TKey_1]) => void): void;
|
|
202
|
-
};
|
|
203
|
-
}>;
|
|
204
|
-
type Builder = Awaited<ReturnType<typeof createBuilder>>;
|
|
205
|
-
|
|
206
|
-
export { type AnyCollection, type AnyConfiguration, type Builder, type BuilderEvents, CollectError, type Collection, type CollectionRequest, type Configuration, ConfigurationError, type Context, type Document, type GetTypeByName, type Meta, type Modification, type Schema, TransformError, createBuilder, defineCollection, defineConfig };
|