@content-collections/core 0.5.0 → 0.6.1
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.cjs +919 -0
- package/dist/index.d.cts +206 -0
- package/dist/index.d.ts +12 -9
- package/dist/index.js +81 -94
- package/package.json +11 -6
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -23,13 +23,17 @@ declare const parsers: {
|
|
|
23
23
|
|
|
24
24
|
type CacheFn = <TInput, TOutput>(input: TInput, compute: (input: TInput) => Promise<TOutput> | TOutput) => Promise<TOutput>;
|
|
25
25
|
|
|
26
|
-
declare const literalSchema: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined]>;
|
|
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
27
|
type Literal = z.infer<typeof literalSchema>;
|
|
28
|
-
type
|
|
29
|
-
[key: string]:
|
|
30
|
-
} |
|
|
31
|
-
|
|
32
|
-
|
|
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>;
|
|
33
37
|
|
|
34
38
|
type Meta = {
|
|
35
39
|
filePath: string;
|
|
@@ -75,13 +79,12 @@ type Collection<TName extends string, TShape extends ZodRawShape, TParser extend
|
|
|
75
79
|
parser: TParser;
|
|
76
80
|
};
|
|
77
81
|
type AnyCollection = Collection<any, ZodRawShape, Parser, any, any, any>;
|
|
78
|
-
type NonJSONObjectError = "The return type of the transform function must be an valid JSONObject, the following type is not valid:";
|
|
79
82
|
declare const InvalidReturnTypeSymbol: unique symbol;
|
|
80
83
|
type InvalidReturnType<TMessage extends string, TObject> = {
|
|
81
84
|
[InvalidReturnTypeSymbol]: TMessage;
|
|
82
85
|
object: TObject;
|
|
83
86
|
};
|
|
84
|
-
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
|
|
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;
|
|
85
88
|
type Cache = "memory" | "file" | "none";
|
|
86
89
|
type Configuration<TCollections extends Array<AnyCollection>> = {
|
|
87
90
|
collections: TCollections;
|
|
@@ -200,4 +203,4 @@ declare function createBuilder(configurationPath: string, options?: Options): Pr
|
|
|
200
203
|
}>;
|
|
201
204
|
type Builder = Awaited<ReturnType<typeof createBuilder>>;
|
|
202
205
|
|
|
203
|
-
export { AnyCollection, AnyConfiguration, Builder, BuilderEvents, CollectError, Collection, CollectionRequest, Configuration, ConfigurationError, Context, Document, GetTypeByName, Meta, Modification, Schema, TransformError, createBuilder, defineCollection, defineConfig };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -41,56 +41,6 @@ function defineConfig(config) {
|
|
|
41
41
|
import * as esbuild from "esbuild";
|
|
42
42
|
import fs from "fs/promises";
|
|
43
43
|
import path from "path";
|
|
44
|
-
|
|
45
|
-
// package.json
|
|
46
|
-
var package_default = {
|
|
47
|
-
name: "@content-collections/core",
|
|
48
|
-
version: "0.5.0",
|
|
49
|
-
type: "module",
|
|
50
|
-
main: "dist/index.js",
|
|
51
|
-
types: "./dist/index.d.ts",
|
|
52
|
-
exports: {
|
|
53
|
-
"./package.json": "./package.json",
|
|
54
|
-
".": {
|
|
55
|
-
import: "./dist/index.js",
|
|
56
|
-
types: "./dist/index.d.ts"
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
files: [
|
|
60
|
-
"dist",
|
|
61
|
-
"README.md"
|
|
62
|
-
],
|
|
63
|
-
scripts: {
|
|
64
|
-
build: "tsup src/index.ts --format esm --dts -d dist",
|
|
65
|
-
typecheck: "tsc",
|
|
66
|
-
test: "vitest --run --coverage",
|
|
67
|
-
prepack: "cp ../../README.md ./README.md",
|
|
68
|
-
postpack: "rm -f ./README.md"
|
|
69
|
-
},
|
|
70
|
-
devDependencies: {
|
|
71
|
-
"@types/micromatch": "^4.0.7",
|
|
72
|
-
"@types/node": "^20.9.0",
|
|
73
|
-
"@types/pluralize": "^0.0.33",
|
|
74
|
-
"@vitest/coverage-v8": "^1.5.0",
|
|
75
|
-
tsup: "^7.2.0",
|
|
76
|
-
tsx: "^4.1.1",
|
|
77
|
-
typescript: "^5.4.5",
|
|
78
|
-
vitest: "^1.5.0"
|
|
79
|
-
},
|
|
80
|
-
dependencies: {
|
|
81
|
-
"@parcel/watcher": "^2.4.1",
|
|
82
|
-
camelcase: "^8.0.0",
|
|
83
|
-
esbuild: "^0.20.2",
|
|
84
|
-
"fast-glob": "^3.3.2",
|
|
85
|
-
"gray-matter": "^4.0.3",
|
|
86
|
-
micromatch: "^4.0.5",
|
|
87
|
-
pluralize: "^8.0.0",
|
|
88
|
-
yaml: "^2.4.1",
|
|
89
|
-
zod: "^3.22.5"
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
// src/configurationReader.ts
|
|
94
44
|
import { existsSync } from "fs";
|
|
95
45
|
import { createHash } from "crypto";
|
|
96
46
|
var ConfigurationError = class extends Error {
|
|
@@ -115,18 +65,26 @@ function resolveCacheDir(config, options) {
|
|
|
115
65
|
}
|
|
116
66
|
return path.join(path.dirname(config), ".content-collections", "cache");
|
|
117
67
|
}
|
|
68
|
+
var externalPackagesPlugin = (configPath) => ({
|
|
69
|
+
name: "external-packages",
|
|
70
|
+
setup: (build2) => {
|
|
71
|
+
const filter = /^[^.\/]|^\.[^.\/]|^\.\.[^\/]/;
|
|
72
|
+
build2.onResolve({ filter }, ({ path: path7 }) => {
|
|
73
|
+
const external = !path7.includes(configPath);
|
|
74
|
+
return { path: path7, external };
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
});
|
|
118
78
|
async function compile(configurationPath, outfile) {
|
|
119
|
-
const plugins = [
|
|
79
|
+
const plugins = [
|
|
80
|
+
externalPackagesPlugin(configurationPath)
|
|
81
|
+
];
|
|
120
82
|
if (process.env.NODE_ENV === "test") {
|
|
121
83
|
plugins.push(importPathPlugin);
|
|
122
84
|
}
|
|
123
85
|
await esbuild.build({
|
|
124
86
|
entryPoints: [configurationPath],
|
|
125
87
|
packages: "external",
|
|
126
|
-
external: [
|
|
127
|
-
...Object.keys(package_default.dependencies),
|
|
128
|
-
"@content-collections/*"
|
|
129
|
-
],
|
|
130
88
|
bundle: true,
|
|
131
89
|
platform: "node",
|
|
132
90
|
format: "esm",
|
|
@@ -288,6 +246,38 @@ function createCollector(emitter, baseDirectory = ".") {
|
|
|
288
246
|
import fs2 from "fs/promises";
|
|
289
247
|
import path3 from "path";
|
|
290
248
|
import pluralize2 from "pluralize";
|
|
249
|
+
|
|
250
|
+
// src/serializer.ts
|
|
251
|
+
import z2 from "zod";
|
|
252
|
+
import serializeJs from "serialize-javascript";
|
|
253
|
+
var literalSchema = z2.union([
|
|
254
|
+
// json
|
|
255
|
+
z2.string(),
|
|
256
|
+
z2.number(),
|
|
257
|
+
z2.boolean(),
|
|
258
|
+
z2.null(),
|
|
259
|
+
// serializable-javascript
|
|
260
|
+
z2.undefined(),
|
|
261
|
+
z2.date(),
|
|
262
|
+
z2.map(z2.unknown(), z2.unknown()),
|
|
263
|
+
z2.set(z2.unknown()),
|
|
264
|
+
z2.bigint()
|
|
265
|
+
]);
|
|
266
|
+
var schema = z2.lazy(
|
|
267
|
+
() => z2.union([literalSchema, z2.array(schema), z2.record(schema)])
|
|
268
|
+
);
|
|
269
|
+
var extension = "js";
|
|
270
|
+
var serializableSchema = z2.record(schema);
|
|
271
|
+
function serialize(value) {
|
|
272
|
+
const serializedValue = serializeJs(value, {
|
|
273
|
+
space: 2,
|
|
274
|
+
unsafe: true,
|
|
275
|
+
ignoreFunction: true
|
|
276
|
+
});
|
|
277
|
+
return `export default ${serializedValue};`;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// src/writer.ts
|
|
291
281
|
function createArrayConstName(name) {
|
|
292
282
|
let suffix = name.charAt(0).toUpperCase() + name.slice(1);
|
|
293
283
|
return "all" + pluralize2(suffix);
|
|
@@ -295,15 +285,11 @@ function createArrayConstName(name) {
|
|
|
295
285
|
async function createDataFile(directory, collection) {
|
|
296
286
|
const dataPath = path3.join(
|
|
297
287
|
directory,
|
|
298
|
-
`${createArrayConstName(collection.name)}
|
|
288
|
+
`${createArrayConstName(collection.name)}.${extension}`
|
|
299
289
|
);
|
|
300
290
|
await fs2.writeFile(
|
|
301
291
|
dataPath,
|
|
302
|
-
|
|
303
|
-
collection.documents.map((doc) => doc.document),
|
|
304
|
-
null,
|
|
305
|
-
2
|
|
306
|
-
)
|
|
292
|
+
serialize(collection.documents.map((doc) => doc.document))
|
|
307
293
|
);
|
|
308
294
|
}
|
|
309
295
|
function createDataFiles(directory, collections) {
|
|
@@ -319,7 +305,7 @@ async function createJavaScriptFile(directory, configuration) {
|
|
|
319
305
|
|
|
320
306
|
`;
|
|
321
307
|
for (const name of collections) {
|
|
322
|
-
content += `import ${name} from "./${name}
|
|
308
|
+
content += `import ${name} from "./${name}.${extension}";
|
|
323
309
|
`;
|
|
324
310
|
}
|
|
325
311
|
content += "\n";
|
|
@@ -327,7 +313,9 @@ async function createJavaScriptFile(directory, configuration) {
|
|
|
327
313
|
await fs2.writeFile(path3.join(directory, "index.js"), content, "utf-8");
|
|
328
314
|
}
|
|
329
315
|
function createImportPath(directory, target) {
|
|
330
|
-
let importPath = path3.posix.join(
|
|
316
|
+
let importPath = path3.posix.join(
|
|
317
|
+
...path3.relative(directory, target).split(path3.sep)
|
|
318
|
+
);
|
|
331
319
|
if (!importPath.startsWith(".")) {
|
|
332
320
|
importPath = "./" + importPath;
|
|
333
321
|
}
|
|
@@ -368,22 +356,6 @@ async function createWriter(directory) {
|
|
|
368
356
|
// src/transformer.ts
|
|
369
357
|
import { basename, dirname, extname } from "path";
|
|
370
358
|
import { z as z3 } from "zod";
|
|
371
|
-
|
|
372
|
-
// src/json.ts
|
|
373
|
-
import z2 from "zod";
|
|
374
|
-
var literalSchema = z2.union([
|
|
375
|
-
z2.string(),
|
|
376
|
-
z2.number(),
|
|
377
|
-
z2.boolean(),
|
|
378
|
-
z2.null(),
|
|
379
|
-
z2.undefined()
|
|
380
|
-
]);
|
|
381
|
-
var jsonSchema = z2.lazy(
|
|
382
|
-
() => z2.union([literalSchema, z2.array(jsonSchema), z2.record(jsonSchema)])
|
|
383
|
-
);
|
|
384
|
-
var jsonObjectScheme = z2.record(jsonSchema);
|
|
385
|
-
|
|
386
|
-
// src/transformer.ts
|
|
387
359
|
var TransformError = class extends Error {
|
|
388
360
|
type;
|
|
389
361
|
constructor(type, message) {
|
|
@@ -399,20 +371,20 @@ function createPath(path7, ext) {
|
|
|
399
371
|
return p;
|
|
400
372
|
}
|
|
401
373
|
function createTransformer(emitter, cacheManager) {
|
|
402
|
-
function createSchema(parserName,
|
|
374
|
+
function createSchema(parserName, schema2) {
|
|
403
375
|
const parser = parsers[parserName];
|
|
404
376
|
if (!parser.hasContent) {
|
|
405
|
-
return z3.object(
|
|
377
|
+
return z3.object(schema2);
|
|
406
378
|
}
|
|
407
379
|
return z3.object({
|
|
408
380
|
content: z3.string(),
|
|
409
|
-
...
|
|
381
|
+
...schema2
|
|
410
382
|
});
|
|
411
383
|
}
|
|
412
384
|
async function parseFile(collection, file) {
|
|
413
385
|
const { data, path: path7 } = file;
|
|
414
|
-
const
|
|
415
|
-
let parsedData = await
|
|
386
|
+
const schema2 = createSchema(collection.parser, collection.schema);
|
|
387
|
+
let parsedData = await schema2.safeParseAsync(data);
|
|
416
388
|
if (!parsedData.success) {
|
|
417
389
|
emitter.emit("transformer:validation-error", {
|
|
418
390
|
collection,
|
|
@@ -422,9 +394,9 @@ function createTransformer(emitter, cacheManager) {
|
|
|
422
394
|
return null;
|
|
423
395
|
}
|
|
424
396
|
const ext = extname(path7);
|
|
425
|
-
let
|
|
426
|
-
if (
|
|
427
|
-
|
|
397
|
+
let extension2 = ext;
|
|
398
|
+
if (extension2.startsWith(".")) {
|
|
399
|
+
extension2 = extension2.slice(1);
|
|
428
400
|
}
|
|
429
401
|
const document = {
|
|
430
402
|
...parsedData.data,
|
|
@@ -432,7 +404,7 @@ function createTransformer(emitter, cacheManager) {
|
|
|
432
404
|
filePath: path7,
|
|
433
405
|
fileName: basename(path7),
|
|
434
406
|
directory: dirname(path7),
|
|
435
|
-
extension,
|
|
407
|
+
extension: extension2,
|
|
436
408
|
path: createPath(path7, ext)
|
|
437
409
|
}
|
|
438
410
|
};
|
|
@@ -506,7 +478,7 @@ function createTransformer(emitter, cacheManager) {
|
|
|
506
478
|
async function validateDocuments(collection, documents) {
|
|
507
479
|
const docs = [];
|
|
508
480
|
for (const doc of documents) {
|
|
509
|
-
let parsedData = await
|
|
481
|
+
let parsedData = await serializableSchema.safeParseAsync(doc.document);
|
|
510
482
|
if (parsedData.success) {
|
|
511
483
|
docs.push(doc);
|
|
512
484
|
} else {
|
|
@@ -698,13 +670,22 @@ async function createCacheDirectory(directory) {
|
|
|
698
670
|
function fileName(input) {
|
|
699
671
|
return input.replace(/[^a-z0-9]/gi, "_").toLowerCase();
|
|
700
672
|
}
|
|
673
|
+
async function readMapping(mappingPath) {
|
|
674
|
+
if (existsSync2(mappingPath)) {
|
|
675
|
+
try {
|
|
676
|
+
return JSON.parse(await readFile2(mappingPath, "utf-8"));
|
|
677
|
+
} catch (e) {
|
|
678
|
+
console.error(
|
|
679
|
+
"Failed to parse the cache mapping. We will recreate the cache."
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return {};
|
|
684
|
+
}
|
|
701
685
|
async function createCacheManager(baseDirectory, configChecksum) {
|
|
702
686
|
const cacheDirectory = await createCacheDirectory(baseDirectory);
|
|
703
|
-
let mapping = {};
|
|
704
687
|
const mappingPath = join(cacheDirectory, "mapping.json");
|
|
705
|
-
|
|
706
|
-
mapping = JSON.parse(await readFile2(mappingPath, "utf-8"));
|
|
707
|
-
}
|
|
688
|
+
const mapping = await readMapping(mappingPath);
|
|
708
689
|
async function flush() {
|
|
709
690
|
await writeFile(mappingPath, JSON.stringify(mapping));
|
|
710
691
|
}
|
|
@@ -731,7 +712,13 @@ async function createCacheManager(baseDirectory, configChecksum) {
|
|
|
731
712
|
const filePath = join(directory, `${key}.cache`);
|
|
732
713
|
if (fileMapping?.includes(key) || newFileMapping.includes(key)) {
|
|
733
714
|
if (existsSync2(filePath)) {
|
|
734
|
-
|
|
715
|
+
try {
|
|
716
|
+
return JSON.parse(await readFile2(filePath, "utf-8"));
|
|
717
|
+
} catch (e) {
|
|
718
|
+
console.error(
|
|
719
|
+
"Failed to parse the cache file. We will recompute the value."
|
|
720
|
+
);
|
|
721
|
+
}
|
|
735
722
|
}
|
|
736
723
|
}
|
|
737
724
|
const output = await fn(input);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@content-collections/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -15,12 +15,16 @@
|
|
|
15
15
|
"dist",
|
|
16
16
|
"README.md"
|
|
17
17
|
],
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"typescript": "^5.0.2"
|
|
20
|
+
},
|
|
18
21
|
"devDependencies": {
|
|
19
22
|
"@types/micromatch": "^4.0.7",
|
|
20
|
-
"@types/node": "^20.9
|
|
23
|
+
"@types/node": "^20.14.9",
|
|
21
24
|
"@types/pluralize": "^0.0.33",
|
|
25
|
+
"@types/serialize-javascript": "^5.0.4",
|
|
22
26
|
"@vitest/coverage-v8": "^1.5.0",
|
|
23
|
-
"tsup": "^
|
|
27
|
+
"tsup": "^8.0.2",
|
|
24
28
|
"tsx": "^4.1.1",
|
|
25
29
|
"typescript": "^5.4.5",
|
|
26
30
|
"vitest": "^1.5.0"
|
|
@@ -28,12 +32,13 @@
|
|
|
28
32
|
"dependencies": {
|
|
29
33
|
"@parcel/watcher": "^2.4.1",
|
|
30
34
|
"camelcase": "^8.0.0",
|
|
31
|
-
"esbuild": "^0.
|
|
35
|
+
"esbuild": "^0.21.4",
|
|
32
36
|
"fast-glob": "^3.3.2",
|
|
33
37
|
"gray-matter": "^4.0.3",
|
|
34
|
-
"micromatch": "^4.0.
|
|
38
|
+
"micromatch": "^4.0.7",
|
|
35
39
|
"pluralize": "^8.0.0",
|
|
36
|
-
"
|
|
40
|
+
"serialize-javascript": "^6.0.2",
|
|
41
|
+
"yaml": "^2.4.5",
|
|
37
42
|
"zod": "^3.22.5"
|
|
38
43
|
},
|
|
39
44
|
"scripts": {
|