@imjp/writenex-astro 1.3.6 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-NSW7AIVF.js → chunk-EEUN46Q2.js} +3 -3
- package/dist/chunk-HNS5YKP3.js +241 -0
- package/dist/chunk-HNS5YKP3.js.map +1 -0
- package/dist/{chunk-YBCPOLMY.js → chunk-P5KMSHFP.js} +2 -1
- package/dist/{chunk-YBCPOLMY.js.map → chunk-P5KMSHFP.js.map} +1 -1
- package/dist/{chunk-JMNCPNQX.js → chunk-XVQNYPOI.js} +65 -3
- package/dist/chunk-XVQNYPOI.js.map +1 -0
- package/dist/chunk-YRSIZLHE.js +1 -0
- package/dist/{chunk-N37EPLKG.js → chunk-ZWUGHWHD.js} +79 -10
- package/dist/chunk-ZWUGHWHD.js.map +1 -0
- package/dist/client/index.css +1 -1
- package/dist/client/index.css.map +1 -1
- package/dist/client/index.js +114 -114
- package/dist/client/index.js.map +1 -1
- package/dist/config/index.d.ts +3 -2
- package/dist/config/index.js +11 -3
- package/dist/{config-CliL0CoN.d.ts → config-B7t8CjL1.d.ts} +38 -60
- package/dist/{content-TuL3GT66.d.ts → content-CwcgR8P6.d.ts} +1 -1
- package/dist/discovery/index.d.ts +2 -2
- package/dist/discovery/index.js +2 -2
- package/dist/fields/index.d.ts +16 -0
- package/dist/fields/index.js +13 -0
- package/dist/fields-DUSm13nm.d.ts +223 -0
- package/dist/filesystem/index.d.ts +2 -2
- package/dist/filesystem/index.js +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/{loader-53VVP2IN.js → loader-B5WZCVBC.js} +3 -3
- package/dist/loader-B5WZCVBC.js.map +1 -0
- package/dist/{schema-DDJyoVkj.d.ts → schema-nLMfZ9-o.d.ts} +79 -53
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +3 -3
- package/package.json +5 -1
- package/src/client/components/FrontmatterForm/FrontmatterForm.css +104 -0
- package/src/client/components/FrontmatterForm/FrontmatterForm.tsx +452 -26
- package/src/config/defaults.ts +1 -0
- package/src/config/index.ts +3 -0
- package/src/config/schema.ts +114 -73
- package/src/discovery/schema.ts +120 -1
- package/src/fields/collection.ts +67 -0
- package/src/fields/fields.ts +150 -0
- package/src/fields/index.ts +42 -0
- package/src/fields/resolve.ts +149 -0
- package/src/fields/types.ts +179 -0
- package/src/index.ts +3 -0
- package/src/types/config.ts +86 -63
- package/src/types/index.ts +3 -0
- package/dist/chunk-JMNCPNQX.js.map +0 -1
- package/dist/chunk-KIKIPIFA.js +0 -1
- package/dist/chunk-N37EPLKG.js.map +0 -1
- package/dist/client/index.d.ts +0 -19
- /package/dist/{chunk-NSW7AIVF.js.map → chunk-EEUN46Q2.js.map} +0 -0
- /package/dist/{chunk-KIKIPIFA.js.map → chunk-YRSIZLHE.js.map} +0 -0
- /package/dist/{loader-53VVP2IN.js.map → fields/index.js.map} +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview FieldDefinition to SchemaField conversion
|
|
3
|
+
*
|
|
4
|
+
* This module converts FieldDefinition objects (from the builder API)
|
|
5
|
+
* to the internal SchemaField format used by the form system.
|
|
6
|
+
*
|
|
7
|
+
* @module @writenex/astro/fields/resolve
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { SchemaField } from "@/types";
|
|
11
|
+
import type { FieldDefinition } from "./types";
|
|
12
|
+
|
|
13
|
+
const FIELD_KIND_TO_TYPE: Record<string, string> = {
|
|
14
|
+
text: "string",
|
|
15
|
+
slug: "string",
|
|
16
|
+
url: "string",
|
|
17
|
+
number: "number",
|
|
18
|
+
integer: "number",
|
|
19
|
+
select: "string",
|
|
20
|
+
multiselect: "array",
|
|
21
|
+
checkbox: "boolean",
|
|
22
|
+
date: "date",
|
|
23
|
+
datetime: "date",
|
|
24
|
+
image: "image",
|
|
25
|
+
file: "file",
|
|
26
|
+
object: "object",
|
|
27
|
+
array: "array",
|
|
28
|
+
blocks: "blocks",
|
|
29
|
+
relationship: "relationship",
|
|
30
|
+
"path-reference": "string",
|
|
31
|
+
markdoc: "markdoc",
|
|
32
|
+
mdx: "mdx",
|
|
33
|
+
conditional: "object",
|
|
34
|
+
child: "child",
|
|
35
|
+
"cloud-image": "image",
|
|
36
|
+
empty: "empty",
|
|
37
|
+
"empty-content": "empty-content",
|
|
38
|
+
"empty-document": "empty-document",
|
|
39
|
+
ignored: "ignored",
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export function resolveFieldDefinition(field: FieldDefinition): SchemaField {
|
|
43
|
+
const type = FIELD_KIND_TO_TYPE[field.fieldKind] ?? "string";
|
|
44
|
+
const base: SchemaField = {
|
|
45
|
+
type: type as SchemaField["type"],
|
|
46
|
+
required: field.validation?.isRequired ?? false,
|
|
47
|
+
label: field.label,
|
|
48
|
+
description: field.description,
|
|
49
|
+
default: field.defaultValue,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
switch (field.fieldKind) {
|
|
53
|
+
case "select":
|
|
54
|
+
return {
|
|
55
|
+
...base,
|
|
56
|
+
options: field.options,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
case "multiselect":
|
|
60
|
+
return {
|
|
61
|
+
...base,
|
|
62
|
+
items: "string",
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
case "image":
|
|
66
|
+
return {
|
|
67
|
+
...base,
|
|
68
|
+
directory: field.directory,
|
|
69
|
+
publicPath: field.publicPath,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
case "file":
|
|
73
|
+
return {
|
|
74
|
+
...base,
|
|
75
|
+
directory: field.directory,
|
|
76
|
+
publicPath: field.publicPath,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
case "object":
|
|
80
|
+
return {
|
|
81
|
+
...base,
|
|
82
|
+
fields: resolveObjectFields(field.fields),
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
case "array":
|
|
86
|
+
return {
|
|
87
|
+
...base,
|
|
88
|
+
itemField: resolveFieldDefinition(field.itemField),
|
|
89
|
+
itemLabel: field.itemLabel,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
case "blocks":
|
|
93
|
+
return {
|
|
94
|
+
...base,
|
|
95
|
+
blockTypes: resolveBlockTypes(field.blockTypes),
|
|
96
|
+
itemLabel: field.itemLabel,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
case "relationship":
|
|
100
|
+
return {
|
|
101
|
+
...base,
|
|
102
|
+
collection: field.collection,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
case "conditional":
|
|
106
|
+
return {
|
|
107
|
+
...base,
|
|
108
|
+
matchField: field.matchField,
|
|
109
|
+
matchValue: field.matchValue,
|
|
110
|
+
showField: resolveFieldDefinition(field.showField),
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
case "text":
|
|
114
|
+
return {
|
|
115
|
+
...base,
|
|
116
|
+
multiline: field.multiline,
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
case "date":
|
|
120
|
+
case "datetime":
|
|
121
|
+
return {
|
|
122
|
+
...base,
|
|
123
|
+
format: field.fieldKind === "datetime" ? "datetime-local" : "date",
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
default:
|
|
127
|
+
return base;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function resolveObjectFields(
|
|
132
|
+
fields: Record<string, FieldDefinition>
|
|
133
|
+
): Record<string, SchemaField> {
|
|
134
|
+
const result: Record<string, SchemaField> = {};
|
|
135
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
136
|
+
result[key] = resolveFieldDefinition(value);
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function resolveBlockTypes(
|
|
142
|
+
blockTypes: Record<string, FieldDefinition>
|
|
143
|
+
): Record<string, SchemaField> {
|
|
144
|
+
const result: Record<string, SchemaField> = {};
|
|
145
|
+
for (const [key, value] of Object.entries(blockTypes)) {
|
|
146
|
+
result[key] = resolveFieldDefinition(value);
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Field type definitions for the Fields API
|
|
3
|
+
*
|
|
4
|
+
* This module defines the FieldDefinition interface and per-field-type
|
|
5
|
+
* config interfaces for the builder pattern API.
|
|
6
|
+
*
|
|
7
|
+
* @module @writenex/astro/fields/types
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type FieldKind =
|
|
11
|
+
| "text"
|
|
12
|
+
| "slug"
|
|
13
|
+
| "url"
|
|
14
|
+
| "number"
|
|
15
|
+
| "integer"
|
|
16
|
+
| "select"
|
|
17
|
+
| "multiselect"
|
|
18
|
+
| "checkbox"
|
|
19
|
+
| "date"
|
|
20
|
+
| "datetime"
|
|
21
|
+
| "image"
|
|
22
|
+
| "file"
|
|
23
|
+
| "object"
|
|
24
|
+
| "array"
|
|
25
|
+
| "blocks"
|
|
26
|
+
| "relationship"
|
|
27
|
+
| "path-reference"
|
|
28
|
+
| "markdoc"
|
|
29
|
+
| "mdx"
|
|
30
|
+
| "conditional"
|
|
31
|
+
| "child"
|
|
32
|
+
| "cloud-image"
|
|
33
|
+
| "empty"
|
|
34
|
+
| "empty-content"
|
|
35
|
+
| "empty-document"
|
|
36
|
+
| "ignored";
|
|
37
|
+
|
|
38
|
+
export interface ValidationOptions {
|
|
39
|
+
isRequired?: boolean;
|
|
40
|
+
min?: number;
|
|
41
|
+
max?: number;
|
|
42
|
+
minLength?: number;
|
|
43
|
+
maxLength?: number;
|
|
44
|
+
pattern?: string;
|
|
45
|
+
patternDescription?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface BaseFieldConfig {
|
|
49
|
+
label?: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
validation?: ValidationOptions;
|
|
52
|
+
defaultValue?: unknown;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface TextFieldConfig extends BaseFieldConfig {
|
|
56
|
+
multiline?: boolean;
|
|
57
|
+
placeholder?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface SlugFieldConfig extends BaseFieldConfig {
|
|
61
|
+
name?: {
|
|
62
|
+
label?: string;
|
|
63
|
+
placeholder?: string;
|
|
64
|
+
};
|
|
65
|
+
pathname?: {
|
|
66
|
+
label?: string;
|
|
67
|
+
placeholder?: string;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface UrlFieldConfig extends BaseFieldConfig {
|
|
72
|
+
placeholder?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface NumberFieldConfig extends BaseFieldConfig {
|
|
76
|
+
placeholder?: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface IntegerFieldConfig extends BaseFieldConfig {
|
|
80
|
+
placeholder?: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface SelectFieldConfig extends BaseFieldConfig {
|
|
84
|
+
options: string[];
|
|
85
|
+
defaultValue?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface MultiselectFieldConfig extends BaseFieldConfig {
|
|
89
|
+
options: string[];
|
|
90
|
+
defaultValue?: string[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface CheckboxFieldConfig extends BaseFieldConfig {
|
|
94
|
+
defaultValue?: boolean;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface DateFieldConfig extends BaseFieldConfig {
|
|
98
|
+
defaultValue?: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface DatetimeFieldConfig extends BaseFieldConfig {
|
|
102
|
+
defaultValue?: string;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface ImageFieldConfig extends BaseFieldConfig {
|
|
106
|
+
directory?: string;
|
|
107
|
+
publicPath?: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface FileFieldConfig extends BaseFieldConfig {
|
|
111
|
+
directory?: string;
|
|
112
|
+
publicPath?: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface ObjectFieldConfig extends BaseFieldConfig {
|
|
116
|
+
fields: Record<string, FieldDefinition>;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface ArrayFieldConfig extends BaseFieldConfig {
|
|
120
|
+
itemField: FieldDefinition;
|
|
121
|
+
itemLabel?: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface BlocksFieldConfig extends BaseFieldConfig {
|
|
125
|
+
blockTypes: Record<string, FieldDefinition>;
|
|
126
|
+
itemLabel?: string;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface RelationshipFieldConfig extends BaseFieldConfig {
|
|
130
|
+
collection: string;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface PathReferenceFieldConfig extends BaseFieldConfig {
|
|
134
|
+
contentTypes?: string[];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface MarkdocFieldConfig extends BaseFieldConfig {}
|
|
138
|
+
|
|
139
|
+
export interface MdxFieldConfig extends BaseFieldConfig {}
|
|
140
|
+
|
|
141
|
+
export interface ConditionalFieldConfig extends BaseFieldConfig {
|
|
142
|
+
matchField: string;
|
|
143
|
+
matchValue: unknown;
|
|
144
|
+
showField: FieldDefinition;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface ChildFieldConfig extends BaseFieldConfig {}
|
|
148
|
+
|
|
149
|
+
export interface CloudImageFieldConfig extends BaseFieldConfig {
|
|
150
|
+
provider?: string;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export type FieldDefinition =
|
|
154
|
+
| ({ fieldKind: "text" } & TextFieldConfig)
|
|
155
|
+
| ({ fieldKind: "slug" } & SlugFieldConfig)
|
|
156
|
+
| ({ fieldKind: "url" } & UrlFieldConfig)
|
|
157
|
+
| ({ fieldKind: "number" } & NumberFieldConfig)
|
|
158
|
+
| ({ fieldKind: "integer" } & IntegerFieldConfig)
|
|
159
|
+
| ({ fieldKind: "select" } & SelectFieldConfig)
|
|
160
|
+
| ({ fieldKind: "multiselect" } & MultiselectFieldConfig)
|
|
161
|
+
| ({ fieldKind: "checkbox" } & CheckboxFieldConfig)
|
|
162
|
+
| ({ fieldKind: "date" } & DateFieldConfig)
|
|
163
|
+
| ({ fieldKind: "datetime" } & DatetimeFieldConfig)
|
|
164
|
+
| ({ fieldKind: "image" } & ImageFieldConfig)
|
|
165
|
+
| ({ fieldKind: "file" } & FileFieldConfig)
|
|
166
|
+
| ({ fieldKind: "object" } & ObjectFieldConfig)
|
|
167
|
+
| ({ fieldKind: "array" } & ArrayFieldConfig)
|
|
168
|
+
| ({ fieldKind: "blocks" } & BlocksFieldConfig)
|
|
169
|
+
| ({ fieldKind: "relationship" } & RelationshipFieldConfig)
|
|
170
|
+
| ({ fieldKind: "path-reference" } & PathReferenceFieldConfig)
|
|
171
|
+
| ({ fieldKind: "markdoc" } & MarkdocFieldConfig)
|
|
172
|
+
| ({ fieldKind: "mdx" } & MdxFieldConfig)
|
|
173
|
+
| ({ fieldKind: "conditional" } & ConditionalFieldConfig)
|
|
174
|
+
| ({ fieldKind: "child" } & ChildFieldConfig)
|
|
175
|
+
| ({ fieldKind: "cloud-image" } & CloudImageFieldConfig)
|
|
176
|
+
| ({ fieldKind: "empty" } & BaseFieldConfig)
|
|
177
|
+
| ({ fieldKind: "empty-content" } & BaseFieldConfig)
|
|
178
|
+
| ({ fieldKind: "empty-document" } & BaseFieldConfig)
|
|
179
|
+
| ({ fieldKind: "ignored" } & BaseFieldConfig);
|
package/src/index.ts
CHANGED
|
@@ -32,6 +32,7 @@ export { default, default as writenex } from "./integration";
|
|
|
32
32
|
// =============================================================================
|
|
33
33
|
|
|
34
34
|
export { defineConfig, loadConfig, validateConfig } from "@/config";
|
|
35
|
+
export { collection, fields, singleton } from "@/fields";
|
|
35
36
|
|
|
36
37
|
// =============================================================================
|
|
37
38
|
// Core Types (essential for consumers)
|
|
@@ -45,10 +46,12 @@ export type {
|
|
|
45
46
|
DiscoveredCollection,
|
|
46
47
|
DiscoveryConfig,
|
|
47
48
|
EditorConfig,
|
|
49
|
+
FieldKind,
|
|
48
50
|
FieldType,
|
|
49
51
|
ImageConfig,
|
|
50
52
|
ImageStrategy,
|
|
51
53
|
SchemaField,
|
|
54
|
+
ValidationOptions,
|
|
52
55
|
VersionHistoryConfig,
|
|
53
56
|
WritenexConfig,
|
|
54
57
|
WritenexOptions,
|
package/src/types/config.ts
CHANGED
|
@@ -9,9 +9,34 @@
|
|
|
9
9
|
|
|
10
10
|
import type { VersionHistoryConfig } from "./version";
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
export type FieldKind =
|
|
13
|
+
| "text"
|
|
14
|
+
| "slug"
|
|
15
|
+
| "url"
|
|
16
|
+
| "number"
|
|
17
|
+
| "integer"
|
|
18
|
+
| "select"
|
|
19
|
+
| "multiselect"
|
|
20
|
+
| "checkbox"
|
|
21
|
+
| "date"
|
|
22
|
+
| "datetime"
|
|
23
|
+
| "image"
|
|
24
|
+
| "file"
|
|
25
|
+
| "object"
|
|
26
|
+
| "array"
|
|
27
|
+
| "blocks"
|
|
28
|
+
| "relationship"
|
|
29
|
+
| "path-reference"
|
|
30
|
+
| "markdoc"
|
|
31
|
+
| "mdx"
|
|
32
|
+
| "conditional"
|
|
33
|
+
| "child"
|
|
34
|
+
| "cloud-image"
|
|
35
|
+
| "empty"
|
|
36
|
+
| "empty-content"
|
|
37
|
+
| "empty-document"
|
|
38
|
+
| "ignored";
|
|
39
|
+
|
|
15
40
|
export type FieldType =
|
|
16
41
|
| "string"
|
|
17
42
|
| "number"
|
|
@@ -19,116 +44,114 @@ export type FieldType =
|
|
|
19
44
|
| "date"
|
|
20
45
|
| "array"
|
|
21
46
|
| "image"
|
|
22
|
-
| "object"
|
|
47
|
+
| "object"
|
|
48
|
+
| "file"
|
|
49
|
+
| "blocks"
|
|
50
|
+
| "relationship"
|
|
51
|
+
| "markdoc"
|
|
52
|
+
| "mdx"
|
|
53
|
+
| "child"
|
|
54
|
+
| "slug"
|
|
55
|
+
| "url"
|
|
56
|
+
| "integer"
|
|
57
|
+
| "select"
|
|
58
|
+
| "multiselect"
|
|
59
|
+
| "datetime"
|
|
60
|
+
| "cloud-image"
|
|
61
|
+
| "path-reference"
|
|
62
|
+
| "conditional"
|
|
63
|
+
| "empty"
|
|
64
|
+
| "empty-content"
|
|
65
|
+
| "empty-document"
|
|
66
|
+
| "ignored"
|
|
67
|
+
| "checkbox";
|
|
68
|
+
|
|
69
|
+
export interface ValidationOptions {
|
|
70
|
+
isRequired?: boolean;
|
|
71
|
+
min?: number;
|
|
72
|
+
max?: number;
|
|
73
|
+
minLength?: number;
|
|
74
|
+
maxLength?: number;
|
|
75
|
+
pattern?: string;
|
|
76
|
+
patternDescription?: string;
|
|
77
|
+
}
|
|
23
78
|
|
|
24
|
-
/**
|
|
25
|
-
* Schema field definition for frontmatter
|
|
26
|
-
*/
|
|
27
79
|
export interface SchemaField {
|
|
28
|
-
/** The type of the field */
|
|
29
80
|
type: FieldType;
|
|
30
|
-
/** Whether the field is required */
|
|
31
81
|
required?: boolean;
|
|
32
|
-
/** Default value for the field */
|
|
33
82
|
default?: unknown;
|
|
34
|
-
/** For array types, the type of items */
|
|
35
83
|
items?: string;
|
|
36
|
-
/** Description shown in the editor */
|
|
37
84
|
description?: string;
|
|
85
|
+
label?: string;
|
|
86
|
+
options?: string[];
|
|
87
|
+
directory?: string;
|
|
88
|
+
publicPath?: string;
|
|
89
|
+
validation?: ValidationOptions;
|
|
90
|
+
fields?: Record<string, SchemaField>;
|
|
91
|
+
itemField?: SchemaField;
|
|
92
|
+
blockTypes?: Record<string, SchemaField>;
|
|
93
|
+
collection?: string;
|
|
94
|
+
multiline?: boolean;
|
|
95
|
+
format?: string;
|
|
96
|
+
itemLabel?: string;
|
|
97
|
+
matchField?: string;
|
|
98
|
+
matchValue?: unknown;
|
|
99
|
+
showField?: SchemaField;
|
|
100
|
+
accept?: string;
|
|
101
|
+
allowExternal?: boolean;
|
|
102
|
+
inline?: boolean;
|
|
38
103
|
}
|
|
39
104
|
|
|
40
|
-
/**
|
|
41
|
-
* Collection schema definition
|
|
42
|
-
*/
|
|
43
105
|
export type CollectionSchema = Record<string, SchemaField>;
|
|
44
106
|
|
|
45
|
-
/**
|
|
46
|
-
* Image handling strategy
|
|
47
|
-
*/
|
|
48
107
|
export type ImageStrategy = "colocated" | "public" | "custom";
|
|
49
108
|
|
|
50
|
-
/**
|
|
51
|
-
* Image configuration for a collection
|
|
52
|
-
*/
|
|
53
109
|
export interface ImageConfig {
|
|
54
|
-
/** Where to store uploaded images */
|
|
55
110
|
strategy: ImageStrategy;
|
|
56
|
-
/** URL path prefix for images */
|
|
57
111
|
publicPath?: string;
|
|
58
|
-
/** Filesystem path for storing images (for 'public' and 'custom' strategies) */
|
|
59
112
|
storagePath?: string;
|
|
60
113
|
}
|
|
61
114
|
|
|
62
|
-
/**
|
|
63
|
-
* Collection configuration
|
|
64
|
-
*/
|
|
65
115
|
export interface CollectionConfig {
|
|
66
|
-
/** Unique name of the collection */
|
|
67
116
|
name: string;
|
|
68
|
-
/** Filesystem path to the collection (relative to project root) */
|
|
69
117
|
path: string;
|
|
70
|
-
/** File naming pattern using tokens like {slug}, {date}, {year}, etc. */
|
|
71
118
|
filePattern?: string;
|
|
72
|
-
/** URL pattern for preview links */
|
|
73
119
|
previewUrl?: string;
|
|
74
|
-
/** Frontmatter schema definition */
|
|
75
120
|
schema?: CollectionSchema;
|
|
76
|
-
/** Image handling configuration for this collection */
|
|
77
121
|
images?: ImageConfig;
|
|
78
122
|
}
|
|
79
123
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
124
|
+
export interface SingletonConfig {
|
|
125
|
+
name: string;
|
|
126
|
+
path: string;
|
|
127
|
+
previewUrl?: string;
|
|
128
|
+
schema?: CollectionSchema;
|
|
129
|
+
images?: ImageConfig;
|
|
130
|
+
}
|
|
131
|
+
|
|
83
132
|
export interface DiscoveryConfig {
|
|
84
|
-
/** Whether auto-discovery is enabled */
|
|
85
133
|
enabled: boolean;
|
|
86
|
-
/** Glob patterns to ignore during discovery */
|
|
87
134
|
ignore?: string[];
|
|
88
135
|
}
|
|
89
136
|
|
|
90
|
-
/**
|
|
91
|
-
* Editor behavior configuration
|
|
92
|
-
*/
|
|
93
137
|
export interface EditorConfig {
|
|
94
|
-
/** Whether autosave is enabled */
|
|
95
138
|
autosave?: boolean;
|
|
96
|
-
/** Autosave interval in milliseconds */
|
|
97
139
|
autosaveInterval?: number;
|
|
98
140
|
}
|
|
99
141
|
|
|
100
|
-
/**
|
|
101
|
-
* Main Writenex configuration
|
|
102
|
-
*/
|
|
103
142
|
export interface WritenexConfig {
|
|
104
|
-
/** Collection definitions */
|
|
105
143
|
collections?: CollectionConfig[];
|
|
106
|
-
|
|
144
|
+
singletons?: SingletonConfig[];
|
|
107
145
|
images?: ImageConfig;
|
|
108
|
-
/** Editor behavior configuration */
|
|
109
146
|
editor?: EditorConfig;
|
|
110
|
-
/** Auto-discovery configuration */
|
|
111
147
|
discovery?: DiscoveryConfig;
|
|
112
|
-
/** Version history configuration */
|
|
113
148
|
versionHistory?: VersionHistoryConfig;
|
|
114
149
|
}
|
|
115
150
|
|
|
116
|
-
/**
|
|
117
|
-
* Options passed to the Writenex integration
|
|
118
|
-
*/
|
|
119
151
|
export interface WritenexOptions {
|
|
120
|
-
/**
|
|
121
|
-
* Allow the integration to run in production builds.
|
|
122
|
-
* Use with caution - only enable for staging/preview environments.
|
|
123
|
-
* @default false
|
|
124
|
-
*/
|
|
125
152
|
allowProduction?: boolean;
|
|
126
153
|
}
|
|
127
154
|
|
|
128
|
-
/**
|
|
129
|
-
* Resolved configuration with defaults applied
|
|
130
|
-
*/
|
|
131
155
|
export interface ResolvedConfig extends Required<WritenexConfig> {
|
|
132
|
-
/** Resolved collection configurations */
|
|
133
156
|
collections: Required<CollectionConfig>[];
|
|
134
157
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -21,11 +21,14 @@ export type {
|
|
|
21
21
|
CollectionSchema,
|
|
22
22
|
DiscoveryConfig,
|
|
23
23
|
EditorConfig,
|
|
24
|
+
FieldKind,
|
|
24
25
|
FieldType,
|
|
25
26
|
ImageConfig,
|
|
26
27
|
ImageStrategy,
|
|
27
28
|
ResolvedConfig,
|
|
28
29
|
SchemaField,
|
|
30
|
+
SingletonConfig,
|
|
31
|
+
ValidationOptions,
|
|
29
32
|
WritenexConfig,
|
|
30
33
|
WritenexOptions,
|
|
31
34
|
} from "./config";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/discovery/schema.ts","../src/discovery/collections.ts"],"sourcesContent":["/**\n * @fileoverview Schema auto-detection for content collections\n *\n * This module analyzes frontmatter from sample content files to automatically\n * infer the schema (field types, required status, enums, etc.).\n *\n * ## Detection Process:\n * 1. Read sample files from the collection (up to 20)\n * 2. Parse frontmatter from each file\n * 3. Analyze field patterns across all samples\n * 4. Infer field types and constraints\n * 5. Generate schema definition\n *\n * ## Detected Types:\n * - string: Plain text values\n * - number: Numeric values\n * - boolean: True/false values\n * - date: ISO date strings or Date objects\n * - array: Arrays (with item type detection)\n * - image: Paths ending with image extensions\n *\n * @module @writenex/astro/discovery/schema\n */\n\nimport { readCollection } from \"@/filesystem/reader\";\nimport type { CollectionSchema, FieldType, SchemaField } from \"@/types\";\n\n/**\n * Maximum number of files to sample for schema detection\n */\nconst MAX_SAMPLE_FILES = 20;\n\n/**\n * Minimum presence ratio to consider a field required\n * (field must appear in at least 90% of files)\n */\nconst REQUIRED_THRESHOLD = 0.9;\n\n/**\n * Maximum unique values to consider a field as enum\n */\nconst ENUM_MAX_VALUES = 10;\n\n/**\n * Minimum ratio of unique values to total to NOT be an enum\n * (if uniqueValues / total < 0.3, it's likely an enum)\n */\nconst ENUM_RATIO_THRESHOLD = 0.3;\n\n/**\n * Image file extensions for detection\n */\nconst IMAGE_EXTENSIONS = [\n \".jpg\",\n \".jpeg\",\n \".png\",\n \".gif\",\n \".webp\",\n \".avif\",\n \".svg\",\n];\n\n/**\n * Field analysis data collected from samples\n */\ninterface FieldAnalysis {\n /** Number of files where this field appears */\n presentCount: number;\n /** Detected types for this field across samples */\n types: Set<string>;\n /** Sample values for enum detection */\n values: unknown[];\n /** Whether values look like image paths */\n hasImagePaths: boolean;\n /** Whether values look like dates */\n hasDateValues: boolean;\n /** For arrays, analysis of item types */\n arrayItemTypes: Set<string>;\n}\n\n/**\n * Result of schema detection\n */\nexport interface SchemaDetectionResult {\n /** The detected schema */\n schema: CollectionSchema;\n /** Number of files analyzed */\n samplesAnalyzed: number;\n /** Confidence score (0-1) based on sample consistency */\n confidence: number;\n /** Fields that had inconsistent types across samples */\n warnings: string[];\n}\n\n/**\n * Check if a string looks like an image path\n *\n * @param value - Value to check\n * @returns True if it looks like an image path\n */\nfunction isImagePath(value: unknown): boolean {\n if (typeof value !== \"string\") return false;\n\n const lowered = value.toLowerCase();\n return IMAGE_EXTENSIONS.some((ext) => lowered.endsWith(ext));\n}\n\n/**\n * Check if a value looks like a date\n *\n * @param value - Value to check\n * @returns True if it looks like a date\n */\nfunction isDateValue(value: unknown): boolean {\n // Already a Date object\n if (value instanceof Date) return true;\n\n // ISO date string (YYYY-MM-DD or full ISO)\n if (typeof value === \"string\") {\n // Full ISO format\n if (/^\\d{4}-\\d{2}-\\d{2}(T|\\s)/.test(value)) return true;\n // Simple date format\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return true;\n }\n\n return false;\n}\n\n/**\n * Detect the JavaScript type of a value\n *\n * @param value - Value to analyze\n * @returns Detected type string\n */\nfunction detectValueType(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"boolean\") return \"boolean\";\n if (typeof value === \"number\") return \"number\";\n if (typeof value === \"string\") return \"string\";\n if (Array.isArray(value)) return \"array\";\n if (value instanceof Date) return \"date\";\n if (typeof value === \"object\") return \"object\";\n return \"unknown\";\n}\n\n/**\n * Convert detected type to schema field type\n *\n * @param analysis - Field analysis data\n * @returns The appropriate FieldType\n */\nfunction inferFieldType(analysis: FieldAnalysis): FieldType {\n // If it has image paths, it's an image field\n if (analysis.hasImagePaths) return \"image\";\n\n // If it has date values, it's a date field\n if (analysis.hasDateValues) return \"date\";\n\n // Check detected types (excluding null)\n const nonNullTypes = new Set([...analysis.types].filter((t) => t !== \"null\"));\n\n // Single type is easy\n if (nonNullTypes.size === 1) {\n const type = [...nonNullTypes][0];\n switch (type) {\n case \"boolean\":\n return \"boolean\";\n case \"number\":\n return \"number\";\n case \"array\":\n return \"array\";\n case \"object\":\n return \"object\";\n case \"date\":\n return \"date\";\n default:\n return \"string\";\n }\n }\n\n // Mixed types - default to string (most flexible)\n return \"string\";\n}\n\n/**\n * Detect if a field should be treated as an enum\n *\n * @param values - All values seen for this field\n * @param totalSamples - Total number of samples\n * @returns Array of enum values, or undefined if not an enum\n */\nfunction detectEnum(\n values: unknown[],\n totalSamples: number\n): string[] | undefined {\n // Filter to string values only\n const stringValues = values.filter(\n (v): v is string => typeof v === \"string\" && v.length > 0\n );\n\n if (stringValues.length === 0) return undefined;\n\n // Get unique values\n const uniqueValues = [...new Set(stringValues)];\n\n // Check if it's a good candidate for enum\n if (uniqueValues.length > ENUM_MAX_VALUES) return undefined;\n\n // Check ratio of unique to total\n const ratio = uniqueValues.length / totalSamples;\n if (ratio > ENUM_RATIO_THRESHOLD) return undefined;\n\n // Must have at least 2 unique values and appear multiple times\n if (uniqueValues.length < 2) return undefined;\n if (stringValues.length < totalSamples * 0.5) return undefined;\n\n return uniqueValues.sort();\n}\n\n/**\n * Detect item type for array fields\n *\n * @param analysis - Field analysis data\n * @returns The detected item type, or undefined\n */\nfunction detectArrayItemType(analysis: FieldAnalysis): string | undefined {\n if (analysis.arrayItemTypes.size === 0) return undefined;\n\n // Filter out null\n const types = [...analysis.arrayItemTypes].filter((t) => t !== \"null\");\n\n if (types.length === 0) return undefined;\n if (types.length === 1) return types[0];\n\n // Mixed types - default to string\n return \"string\";\n}\n\n/**\n * Analyze frontmatter from content items to detect schema\n *\n * @param collectionPath - Absolute path to the collection directory\n * @returns Schema detection result\n *\n * @example\n * ```typescript\n * const result = await detectSchema('/project/src/content/blog');\n * console.log(result.schema);\n * // {\n * // title: { type: 'string', required: true },\n * // pubDate: { type: 'date', required: true },\n * // draft: { type: 'boolean', required: false, default: false },\n * // tags: { type: 'array', required: false, items: 'string' },\n * // }\n * ```\n */\nexport async function detectSchema(\n collectionPath: string\n): Promise<SchemaDetectionResult> {\n const warnings: string[] = [];\n\n // Read sample content files\n const items = await readCollection(collectionPath, {\n includeDrafts: true,\n });\n\n // Limit to max samples\n const samples = items.slice(0, MAX_SAMPLE_FILES);\n\n if (samples.length === 0) {\n return {\n schema: {},\n samplesAnalyzed: 0,\n confidence: 0,\n warnings: [\"No content files found in collection\"],\n };\n }\n\n // Analyze each field across all samples\n const fieldAnalyses = new Map<string, FieldAnalysis>();\n\n for (const item of samples) {\n for (const [fieldName, value] of Object.entries(item.frontmatter)) {\n // Get or create field analysis\n let analysis = fieldAnalyses.get(fieldName);\n if (!analysis) {\n analysis = {\n presentCount: 0,\n types: new Set(),\n values: [],\n hasImagePaths: false,\n hasDateValues: false,\n arrayItemTypes: new Set(),\n };\n fieldAnalyses.set(fieldName, analysis);\n }\n\n // Update analysis\n analysis.presentCount++;\n analysis.types.add(detectValueType(value));\n analysis.values.push(value);\n\n // Check for special types\n if (isImagePath(value)) {\n analysis.hasImagePaths = true;\n }\n if (isDateValue(value)) {\n analysis.hasDateValues = true;\n }\n\n // Analyze array items\n if (Array.isArray(value)) {\n for (const item of value) {\n analysis.arrayItemTypes.add(detectValueType(item));\n }\n }\n }\n }\n\n // Generate schema from analysis\n const schema: CollectionSchema = {};\n const totalSamples = samples.length;\n\n for (const [fieldName, analysis] of fieldAnalyses) {\n const fieldType = inferFieldType(analysis);\n const isRequired =\n analysis.presentCount / totalSamples >= REQUIRED_THRESHOLD;\n\n const field: SchemaField = {\n type: fieldType,\n required: isRequired,\n };\n\n // Add array item type if applicable\n if (fieldType === \"array\") {\n const itemType = detectArrayItemType(analysis);\n if (itemType) {\n field.items = itemType;\n }\n }\n\n // Detect enum for string fields\n if (fieldType === \"string\") {\n const enumValues = detectEnum(analysis.values, totalSamples);\n if (enumValues) {\n // Store enum values in the field\n // Note: We use 'default' to store enum options since SchemaField\n // doesn't have an 'enum' property - this can be enhanced later\n field.description = `Options: ${enumValues.join(\", \")}`;\n }\n }\n\n // Detect default value for boolean fields\n if (fieldType === \"boolean\") {\n const boolValues = analysis.values.filter(\n (v): v is boolean => typeof v === \"boolean\"\n );\n if (boolValues.length > 0) {\n // Use most common value as default\n const trueCount = boolValues.filter((v) => v === true).length;\n const falseCount = boolValues.filter((v) => v === false).length;\n field.default = trueCount > falseCount ? true : false;\n }\n }\n\n // Check for type inconsistencies\n const nonNullTypes = [...analysis.types].filter((t) => t !== \"null\");\n if (nonNullTypes.length > 1) {\n warnings.push(\n `Field \"${fieldName}\" has inconsistent types: ${nonNullTypes.join(\", \")}`\n );\n }\n\n schema[fieldName] = field;\n }\n\n // Calculate confidence based on consistency\n const inconsistentFields = warnings.filter((w) =>\n w.includes(\"inconsistent\")\n ).length;\n const confidence = Math.max(\n 0,\n 1 - inconsistentFields / Math.max(1, fieldAnalyses.size)\n );\n\n return {\n schema,\n samplesAnalyzed: totalSamples,\n confidence,\n warnings,\n };\n}\n\n/**\n * Merge detected schema with user-provided schema\n *\n * User schema takes precedence over detected schema.\n *\n * @param detected - Auto-detected schema\n * @param userSchema - User-provided schema overrides\n * @returns Merged schema\n */\nexport function mergeSchema(\n detected: CollectionSchema,\n userSchema?: CollectionSchema\n): CollectionSchema {\n if (!userSchema) return detected;\n\n const merged: CollectionSchema = { ...detected };\n\n for (const [fieldName, userField] of Object.entries(userSchema)) {\n merged[fieldName] = {\n ...detected[fieldName],\n ...userField,\n };\n }\n\n return merged;\n}\n\n/**\n * Convert schema to a human-readable description\n *\n * @param schema - The schema to describe\n * @returns Human-readable description\n */\nexport function describeSchema(schema: CollectionSchema): string {\n const lines: string[] = [];\n\n for (const [fieldName, field] of Object.entries(schema)) {\n let desc = `- ${fieldName}: ${field.type}`;\n\n if (field.required) {\n desc += \" (required)\";\n }\n\n if (field.items) {\n desc += ` of ${field.items}`;\n }\n\n if (field.default !== undefined) {\n desc += ` [default: ${JSON.stringify(field.default)}]`;\n }\n\n if (field.description) {\n desc += ` - ${field.description}`;\n }\n\n lines.push(desc);\n }\n\n return lines.join(\"\\n\");\n}\n","/**\n * @fileoverview Collection discovery for Astro content collections\n *\n * This module provides functions to auto-discover content collections\n * from an Astro project's src/content directory.\n *\n * ## Discovery Process:\n * 1. Scan src/content/ for subdirectories\n * 2. Each subdirectory is treated as a collection\n * 3. Count content files in each collection\n * 4. Detect file patterns from existing files\n * 5. Auto-detect frontmatter schema from sample files\n *\n * @module @writenex/astro/discovery/collections\n */\n\nimport { existsSync } from \"node:fs\";\nimport { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { DEFAULT_FILE_PATTERN } from \"@/config/defaults\";\nimport { getCollectionCount } from \"@/filesystem/reader\";\nimport type { CollectionConfig, DiscoveredCollection } from \"@/types\";\nimport { detectFilePattern as detectPattern } from \"./patterns\";\nimport { detectSchema } from \"./schema\";\n\n/**\n * Default content directory path relative to project root\n */\nconst DEFAULT_CONTENT_DIR = \"src/content\";\n\n/**\n * Directories to ignore during discovery\n */\nconst IGNORED_DIRECTORIES = new Set([\"node_modules\", \".git\", \"_\", \".\"]);\n\n/**\n * Check if a directory should be ignored\n *\n * @param name - Directory name\n * @returns True if should be ignored\n */\nfunction shouldIgnore(name: string): boolean {\n return (\n IGNORED_DIRECTORIES.has(name) ||\n name.startsWith(\"_\") ||\n name.startsWith(\".\")\n );\n}\n\n/**\n * Discover all content collections in a project\n *\n * Scans the src/content directory for subdirectories and treats\n * each as a content collection.\n *\n * @param projectRoot - Absolute path to the project root\n * @param contentDir - Relative path to content directory (default: src/content)\n * @returns Array of discovered collections\n *\n * @example\n * ```typescript\n * const collections = await discoverCollections('/path/to/project');\n * // Returns: [\n * // { name: 'blog', path: 'src/content/blog', count: 10, ... },\n * // { name: 'docs', path: 'src/content/docs', count: 5, ... },\n * // ]\n * ```\n */\nexport async function discoverCollections(\n projectRoot: string,\n contentDir: string = DEFAULT_CONTENT_DIR\n): Promise<DiscoveredCollection[]> {\n const contentPath = join(projectRoot, contentDir);\n\n // Check if content directory exists\n if (!existsSync(contentPath)) {\n return [];\n }\n\n const collections: DiscoveredCollection[] = [];\n\n try {\n const entries = await readdir(contentPath, { withFileTypes: true });\n\n for (const entry of entries) {\n // Skip non-directories and ignored directories\n if (!entry.isDirectory() || shouldIgnore(entry.name)) {\n continue;\n }\n\n const collectionPath = join(contentPath, entry.name);\n const relativePath = join(contentDir, entry.name);\n\n // Count content files in this collection\n const count = await getCollectionCount(collectionPath);\n\n // Detect file pattern using pattern detection module\n const patternResult = await detectPattern(collectionPath);\n const filePattern = patternResult.pattern;\n\n // Auto-detect schema from sample files\n const schemaResult = await detectSchema(collectionPath);\n const schema =\n Object.keys(schemaResult.schema).length > 0\n ? schemaResult.schema\n : undefined;\n\n // Generate default preview URL pattern\n const previewUrl = `/${entry.name}/{slug}`;\n\n collections.push({\n name: entry.name,\n path: relativePath,\n filePattern,\n count,\n schema,\n previewUrl,\n });\n }\n } catch (error) {\n console.error(`[writenex] Failed to discover collections: ${error}`);\n }\n\n return collections;\n}\n\n/**\n * Merge discovered collections with configured collections\n *\n * Configured collections take precedence over discovered ones.\n * This allows users to override auto-discovered settings.\n *\n * @param discovered - Auto-discovered collections\n * @param configured - User-configured collections\n * @returns Merged collection list\n */\nexport function mergeCollections(\n discovered: DiscoveredCollection[],\n configured: CollectionConfig[]\n): DiscoveredCollection[] {\n const configuredNames = new Set(configured.map((c) => c.name));\n const result: DiscoveredCollection[] = [];\n\n // Add configured collections first (they take precedence)\n for (const config of configured) {\n const discoveredMatch = discovered.find((d) => d.name === config.name);\n\n result.push({\n name: config.name,\n path: config.path,\n filePattern:\n config.filePattern ??\n discoveredMatch?.filePattern ??\n DEFAULT_FILE_PATTERN,\n count: discoveredMatch?.count ?? 0,\n schema: config.schema ?? discoveredMatch?.schema,\n previewUrl:\n config.previewUrl ??\n discoveredMatch?.previewUrl ??\n `/${config.name}/{slug}`,\n });\n }\n\n // Add discovered collections that weren't configured\n for (const disc of discovered) {\n if (!configuredNames.has(disc.name)) {\n result.push(disc);\n }\n }\n\n return result;\n}\n\n/**\n * Get a single collection by name\n *\n * @param projectRoot - Absolute path to the project root\n * @param collectionName - Name of the collection\n * @param contentDir - Relative path to content directory\n * @returns The collection if found, undefined otherwise\n */\nexport async function getCollection(\n projectRoot: string,\n collectionName: string,\n contentDir: string = DEFAULT_CONTENT_DIR\n): Promise<DiscoveredCollection | undefined> {\n const collections = await discoverCollections(projectRoot, contentDir);\n return collections.find((c) => c.name === collectionName);\n}\n\n/**\n * Check if a collection exists\n *\n * @param projectRoot - Absolute path to the project root\n * @param collectionName - Name of the collection\n * @param contentDir - Relative path to content directory\n * @returns True if the collection exists\n */\nexport async function collectionExists(\n projectRoot: string,\n collectionName: string,\n contentDir: string = DEFAULT_CONTENT_DIR\n): Promise<boolean> {\n const collectionPath = join(projectRoot, contentDir, collectionName);\n\n if (!existsSync(collectionPath)) {\n return false;\n }\n\n try {\n const stats = await stat(collectionPath);\n return stats.isDirectory();\n } catch {\n return false;\n }\n}\n"],"mappings":";;;;;;;;;;AA8BA,IAAM,mBAAmB;AAMzB,IAAM,qBAAqB;AAK3B,IAAM,kBAAkB;AAMxB,IAAM,uBAAuB;AAK7B,IAAM,mBAAmB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAwCA,SAAS,YAAY,OAAyB;AAC5C,MAAI,OAAO,UAAU,SAAU,QAAO;AAEtC,QAAM,UAAU,MAAM,YAAY;AAClC,SAAO,iBAAiB,KAAK,CAAC,QAAQ,QAAQ,SAAS,GAAG,CAAC;AAC7D;AAQA,SAAS,YAAY,OAAyB;AAE5C,MAAI,iBAAiB,KAAM,QAAO;AAGlC,MAAI,OAAO,UAAU,UAAU;AAE7B,QAAI,2BAA2B,KAAK,KAAK,EAAG,QAAO;AAEnD,QAAI,sBAAsB,KAAK,KAAK,EAAG,QAAO;AAAA,EAChD;AAEA,SAAO;AACT;AAQA,SAAS,gBAAgB,OAAwB;AAC/C,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,OAAO,UAAU,UAAW,QAAO;AACvC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,MAAI,iBAAiB,KAAM,QAAO;AAClC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO;AACT;AAQA,SAAS,eAAe,UAAoC;AAE1D,MAAI,SAAS,cAAe,QAAO;AAGnC,MAAI,SAAS,cAAe,QAAO;AAGnC,QAAM,eAAe,IAAI,IAAI,CAAC,GAAG,SAAS,KAAK,EAAE,OAAO,CAAC,MAAM,MAAM,MAAM,CAAC;AAG5E,MAAI,aAAa,SAAS,GAAG;AAC3B,UAAM,OAAO,CAAC,GAAG,YAAY,EAAE,CAAC;AAChC,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAGA,SAAO;AACT;AASA,SAAS,WACP,QACA,cACsB;AAEtB,QAAM,eAAe,OAAO;AAAA,IAC1B,CAAC,MAAmB,OAAO,MAAM,YAAY,EAAE,SAAS;AAAA,EAC1D;AAEA,MAAI,aAAa,WAAW,EAAG,QAAO;AAGtC,QAAM,eAAe,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC;AAG9C,MAAI,aAAa,SAAS,gBAAiB,QAAO;AAGlD,QAAM,QAAQ,aAAa,SAAS;AACpC,MAAI,QAAQ,qBAAsB,QAAO;AAGzC,MAAI,aAAa,SAAS,EAAG,QAAO;AACpC,MAAI,aAAa,SAAS,eAAe,IAAK,QAAO;AAErD,SAAO,aAAa,KAAK;AAC3B;AAQA,SAAS,oBAAoB,UAA6C;AACxE,MAAI,SAAS,eAAe,SAAS,EAAG,QAAO;AAG/C,QAAM,QAAQ,CAAC,GAAG,SAAS,cAAc,EAAE,OAAO,CAAC,MAAM,MAAM,MAAM;AAErE,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,CAAC;AAGtC,SAAO;AACT;AAoBA,eAAsB,aACpB,gBACgC;AAChC,QAAM,WAAqB,CAAC;AAG5B,QAAM,QAAQ,MAAM,eAAe,gBAAgB;AAAA,IACjD,eAAe;AAAA,EACjB,CAAC;AAGD,QAAM,UAAU,MAAM,MAAM,GAAG,gBAAgB;AAE/C,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,MACL,QAAQ,CAAC;AAAA,MACT,iBAAiB;AAAA,MACjB,YAAY;AAAA,MACZ,UAAU,CAAC,sCAAsC;AAAA,IACnD;AAAA,EACF;AAGA,QAAM,gBAAgB,oBAAI,IAA2B;AAErD,aAAW,QAAQ,SAAS;AAC1B,eAAW,CAAC,WAAW,KAAK,KAAK,OAAO,QAAQ,KAAK,WAAW,GAAG;AAEjE,UAAI,WAAW,cAAc,IAAI,SAAS;AAC1C,UAAI,CAAC,UAAU;AACb,mBAAW;AAAA,UACT,cAAc;AAAA,UACd,OAAO,oBAAI,IAAI;AAAA,UACf,QAAQ,CAAC;AAAA,UACT,eAAe;AAAA,UACf,eAAe;AAAA,UACf,gBAAgB,oBAAI,IAAI;AAAA,QAC1B;AACA,sBAAc,IAAI,WAAW,QAAQ;AAAA,MACvC;AAGA,eAAS;AACT,eAAS,MAAM,IAAI,gBAAgB,KAAK,CAAC;AACzC,eAAS,OAAO,KAAK,KAAK;AAG1B,UAAI,YAAY,KAAK,GAAG;AACtB,iBAAS,gBAAgB;AAAA,MAC3B;AACA,UAAI,YAAY,KAAK,GAAG;AACtB,iBAAS,gBAAgB;AAAA,MAC3B;AAGA,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,mBAAWA,SAAQ,OAAO;AACxB,mBAAS,eAAe,IAAI,gBAAgBA,KAAI,CAAC;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAA2B,CAAC;AAClC,QAAM,eAAe,QAAQ;AAE7B,aAAW,CAAC,WAAW,QAAQ,KAAK,eAAe;AACjD,UAAM,YAAY,eAAe,QAAQ;AACzC,UAAM,aACJ,SAAS,eAAe,gBAAgB;AAE1C,UAAM,QAAqB;AAAA,MACzB,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAGA,QAAI,cAAc,SAAS;AACzB,YAAM,WAAW,oBAAoB,QAAQ;AAC7C,UAAI,UAAU;AACZ,cAAM,QAAQ;AAAA,MAChB;AAAA,IACF;AAGA,QAAI,cAAc,UAAU;AAC1B,YAAM,aAAa,WAAW,SAAS,QAAQ,YAAY;AAC3D,UAAI,YAAY;AAId,cAAM,cAAc,YAAY,WAAW,KAAK,IAAI,CAAC;AAAA,MACvD;AAAA,IACF;AAGA,QAAI,cAAc,WAAW;AAC3B,YAAM,aAAa,SAAS,OAAO;AAAA,QACjC,CAAC,MAAoB,OAAO,MAAM;AAAA,MACpC;AACA,UAAI,WAAW,SAAS,GAAG;AAEzB,cAAM,YAAY,WAAW,OAAO,CAAC,MAAM,MAAM,IAAI,EAAE;AACvD,cAAM,aAAa,WAAW,OAAO,CAAC,MAAM,MAAM,KAAK,EAAE;AACzD,cAAM,UAAU,YAAY,aAAa,OAAO;AAAA,MAClD;AAAA,IACF;AAGA,UAAM,eAAe,CAAC,GAAG,SAAS,KAAK,EAAE,OAAO,CAAC,MAAM,MAAM,MAAM;AACnE,QAAI,aAAa,SAAS,GAAG;AAC3B,eAAS;AAAA,QACP,UAAU,SAAS,6BAA6B,aAAa,KAAK,IAAI,CAAC;AAAA,MACzE;AAAA,IACF;AAEA,WAAO,SAAS,IAAI;AAAA,EACtB;AAGA,QAAM,qBAAqB,SAAS;AAAA,IAAO,CAAC,MAC1C,EAAE,SAAS,cAAc;AAAA,EAC3B,EAAE;AACF,QAAM,aAAa,KAAK;AAAA,IACtB;AAAA,IACA,IAAI,qBAAqB,KAAK,IAAI,GAAG,cAAc,IAAI;AAAA,EACzD;AAEA,SAAO;AAAA,IACL;AAAA,IACA,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACF;AAWO,SAAS,YACd,UACA,YACkB;AAClB,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,SAA2B,EAAE,GAAG,SAAS;AAE/C,aAAW,CAAC,WAAW,SAAS,KAAK,OAAO,QAAQ,UAAU,GAAG;AAC/D,WAAO,SAAS,IAAI;AAAA,MAClB,GAAG,SAAS,SAAS;AAAA,MACrB,GAAG;AAAA,IACL;AAAA,EACF;AAEA,SAAO;AACT;AAQO,SAAS,eAAe,QAAkC;AAC/D,QAAM,QAAkB,CAAC;AAEzB,aAAW,CAAC,WAAW,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACvD,QAAI,OAAO,KAAK,SAAS,KAAK,MAAM,IAAI;AAExC,QAAI,MAAM,UAAU;AAClB,cAAQ;AAAA,IACV;AAEA,QAAI,MAAM,OAAO;AACf,cAAQ,OAAO,MAAM,KAAK;AAAA,IAC5B;AAEA,QAAI,MAAM,YAAY,QAAW;AAC/B,cAAQ,cAAc,KAAK,UAAU,MAAM,OAAO,CAAC;AAAA,IACrD;AAEA,QAAI,MAAM,aAAa;AACrB,cAAQ,MAAM,MAAM,WAAW;AAAA,IACjC;AAEA,UAAM,KAAK,IAAI;AAAA,EACjB;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACpbA,SAAS,kBAAkB;AAC3B,SAAS,SAAS,YAAY;AAC9B,SAAS,YAAY;AAUrB,IAAM,sBAAsB;AAK5B,IAAM,sBAAsB,oBAAI,IAAI,CAAC,gBAAgB,QAAQ,KAAK,GAAG,CAAC;AAQtE,SAAS,aAAa,MAAuB;AAC3C,SACE,oBAAoB,IAAI,IAAI,KAC5B,KAAK,WAAW,GAAG,KACnB,KAAK,WAAW,GAAG;AAEvB;AAqBA,eAAsB,oBACpB,aACA,aAAqB,qBACY;AACjC,QAAM,cAAc,KAAK,aAAa,UAAU;AAGhD,MAAI,CAAC,WAAW,WAAW,GAAG;AAC5B,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,cAAsC,CAAC;AAE7C,MAAI;AACF,UAAM,UAAU,MAAM,QAAQ,aAAa,EAAE,eAAe,KAAK,CAAC;AAElE,eAAW,SAAS,SAAS;AAE3B,UAAI,CAAC,MAAM,YAAY,KAAK,aAAa,MAAM,IAAI,GAAG;AACpD;AAAA,MACF;AAEA,YAAM,iBAAiB,KAAK,aAAa,MAAM,IAAI;AACnD,YAAM,eAAe,KAAK,YAAY,MAAM,IAAI;AAGhD,YAAM,QAAQ,MAAM,mBAAmB,cAAc;AAGrD,YAAM,gBAAgB,MAAM,kBAAc,cAAc;AACxD,YAAM,cAAc,cAAc;AAGlC,YAAM,eAAe,MAAM,aAAa,cAAc;AACtD,YAAM,SACJ,OAAO,KAAK,aAAa,MAAM,EAAE,SAAS,IACtC,aAAa,SACb;AAGN,YAAM,aAAa,IAAI,MAAM,IAAI;AAEjC,kBAAY,KAAK;AAAA,QACf,MAAM,MAAM;AAAA,QACZ,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,8CAA8C,KAAK,EAAE;AAAA,EACrE;AAEA,SAAO;AACT;AAYO,SAAS,iBACd,YACA,YACwB;AACxB,QAAM,kBAAkB,IAAI,IAAI,WAAW,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC7D,QAAM,SAAiC,CAAC;AAGxC,aAAW,UAAU,YAAY;AAC/B,UAAM,kBAAkB,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO,IAAI;AAErE,WAAO,KAAK;AAAA,MACV,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,aACE,OAAO,eACP,iBAAiB,eACjB;AAAA,MACF,OAAO,iBAAiB,SAAS;AAAA,MACjC,QAAQ,OAAO,UAAU,iBAAiB;AAAA,MAC1C,YACE,OAAO,cACP,iBAAiB,cACjB,IAAI,OAAO,IAAI;AAAA,IACnB,CAAC;AAAA,EACH;AAGA,aAAW,QAAQ,YAAY;AAC7B,QAAI,CAAC,gBAAgB,IAAI,KAAK,IAAI,GAAG;AACnC,aAAO,KAAK,IAAI;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AACT;AAUA,eAAsB,cACpB,aACA,gBACA,aAAqB,qBACsB;AAC3C,QAAM,cAAc,MAAM,oBAAoB,aAAa,UAAU;AACrE,SAAO,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,cAAc;AAC1D;AAUA,eAAsB,iBACpB,aACA,gBACA,aAAqB,qBACH;AAClB,QAAM,iBAAiB,KAAK,aAAa,YAAY,cAAc;AAEnE,MAAI,CAAC,WAAW,cAAc,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,QAAQ,MAAM,KAAK,cAAc;AACvC,WAAO,MAAM,YAAY;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":["item"]}
|
package/dist/chunk-KIKIPIFA.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=chunk-KIKIPIFA.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/loader.ts","../src/config/schema.ts"],"sourcesContent":["/**\n * @fileoverview Configuration loader for @writenex/astro\n *\n * This module handles loading Writenex configuration from various sources:\n * - writenex.config.ts (TypeScript)\n * - writenex.config.js (JavaScript)\n * - writenex.config.mjs (ES Module)\n *\n * The loader searches for configuration files in the project root and\n * applies default values for any missing options.\n *\n * @module @writenex/astro/config/loader\n */\n\nimport { existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { WritenexConfig } from \"@/types\";\nimport { applyConfigDefaults } from \"./defaults\";\nimport { validateConfig } from \"./schema\";\n\n/**\n * Normalize a project root path that may have come from URL.pathname.\n *\n * On Windows, `config.root.pathname` returns `/C:/Users/...` — a leading slash\n * before the drive letter that makes every subsequent `path.join` and\n * `fs.existsSync` call fail silently. Strip it so downstream code gets a\n * valid Windows path like `C:\\Users\\...`.\n *\n * On macOS/Linux the path starts with a real `/` so the regex won't match\n * and the string is returned unchanged.\n */\nfunction normalizeProjectRoot(projectRoot: string): string {\n return projectRoot.replace(/^\\/([A-Za-z]:)/, \"$1\");\n}\n\n/**\n * Supported configuration file names in order of priority\n */\nconst CONFIG_FILE_NAMES = [\n \"writenex.config.ts\",\n \"writenex.config.mts\",\n \"writenex.config.js\",\n \"writenex.config.mjs\",\n];\n\n/**\n * Result of loading configuration\n */\nexport interface LoadConfigResult {\n /** The loaded and validated configuration with defaults applied */\n config: Required<WritenexConfig>;\n /** Path to the configuration file (if found) */\n configPath: string | null;\n /** Whether a configuration file was found */\n hasConfigFile: boolean;\n /** Any warnings generated during loading */\n warnings: string[];\n}\n\n/**\n * Find the configuration file in the project root\n *\n * @param projectRoot - The root directory of the Astro project\n * @returns Path to the configuration file, or null if not found\n */\nexport function findConfigFile(projectRoot: string): string | null {\n projectRoot = normalizeProjectRoot(projectRoot);\n for (const fileName of CONFIG_FILE_NAMES) {\n const filePath = join(projectRoot, fileName);\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n return null;\n}\n\n/**\n * Load configuration from a file\n *\n * @param configPath - Path to the configuration file\n * @returns The loaded configuration object\n * @throws Error if the file cannot be loaded or parsed\n */\nasync function loadConfigFile(configPath: string): Promise<WritenexConfig> {\n try {\n // Convert to file URL for dynamic import (required for Windows compatibility)\n const fileUrl = pathToFileURL(resolve(configPath)).href;\n\n // Dynamic import the configuration file\n const module = await import(fileUrl);\n\n // Support both default export and named export\n const config = module.default ?? module.config ?? module;\n\n return config as WritenexConfig;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(\n `Failed to load configuration from ${configPath}: ${message}`\n );\n }\n}\n\n/**\n * Load Writenex configuration from the project root\n *\n * This function:\n * 1. Searches for a configuration file in the project root\n * 2. Loads and validates the configuration if found\n * 3. Applies default values for any missing options\n * 4. Returns the resolved configuration\n *\n * If no configuration file is found, default configuration is returned\n * with auto-discovery enabled.\n *\n * @param projectRoot - The root directory of the Astro project\n * @returns LoadConfigResult with the resolved configuration\n *\n * @example\n * ```typescript\n * const { config, hasConfigFile, warnings } = await loadConfig('/path/to/project');\n *\n * if (!hasConfigFile) {\n * console.log('Using auto-discovery mode');\n * }\n *\n * if (warnings.length > 0) {\n * warnings.forEach(w => console.warn(w));\n * }\n * ```\n */\nexport async function loadConfig(\n projectRoot: string\n): Promise<LoadConfigResult> {\n projectRoot = normalizeProjectRoot(projectRoot);\n const warnings: string[] = [];\n let userConfig: WritenexConfig = {};\n let configPath: string | null = null;\n let hasConfigFile = false;\n\n // Try to find and load configuration file\n configPath = findConfigFile(projectRoot);\n\n if (configPath) {\n hasConfigFile = true;\n\n try {\n userConfig = await loadConfigFile(configPath);\n\n // Validate the loaded configuration\n const validationResult = validateConfig(userConfig);\n\n if (!validationResult.success) {\n const errors = validationResult.error.issues\n .map(\n (e: import(\"zod\").ZodIssue) => `${e.path.join(\".\")}: ${e.message}`\n )\n .join(\", \");\n warnings.push(`Configuration validation warnings: ${errors}`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warnings.push(`Failed to load config file: ${message}. Using defaults.`);\n userConfig = {};\n }\n }\n\n // Apply defaults to the configuration\n const config = applyConfigDefaults(userConfig);\n\n return {\n config,\n configPath,\n hasConfigFile,\n warnings,\n };\n}\n\n/**\n * Check if a content directory exists in the project\n *\n * @param projectRoot - The root directory of the Astro project\n * @param contentPath - Relative path to the content directory\n * @returns True if the content directory exists\n */\nexport function contentDirectoryExists(\n projectRoot: string,\n contentPath: string = \"src/content\"\n): boolean {\n projectRoot = normalizeProjectRoot(projectRoot);\n const fullPath = join(projectRoot, contentPath);\n return existsSync(fullPath);\n}\n","/**\n * @fileoverview Configuration schema and validation for @writenex/astro\n *\n * This module provides Zod schemas for validating Writenex configuration\n * and a helper function for defining type-safe configurations.\n *\n * @module @writenex/astro/config/schema\n */\n\nimport { z } from \"zod\";\nimport type { WritenexConfig } from \"@/types\";\n\n/**\n * Schema for field type definitions\n */\nconst fieldTypeSchema = z.enum([\n \"string\",\n \"number\",\n \"boolean\",\n \"date\",\n \"array\",\n \"image\",\n \"object\",\n]);\n\n/**\n * Schema for individual schema field definition\n */\nconst schemaFieldSchema = z.object({\n type: fieldTypeSchema,\n required: z.boolean().optional(),\n default: z.unknown().optional(),\n items: z.string().optional(),\n description: z.string().optional(),\n});\n\n/**\n * Schema for collection schema (record of field definitions)\n */\nconst collectionSchemaSchema = z.record(z.string(), schemaFieldSchema);\n\n/**\n * Schema for image strategy\n */\nconst imageStrategySchema = z.enum([\"colocated\", \"public\", \"custom\"]);\n\n/**\n * Schema for image configuration\n */\nconst imageConfigSchema = z.object({\n strategy: imageStrategySchema,\n publicPath: z.string().optional(),\n storagePath: z.string().optional(),\n});\n\n/**\n * Schema for collection configuration\n */\nconst collectionConfigSchema = z.object({\n name: z.string().min(1, \"Collection name is required\"),\n path: z.string().min(1, \"Collection path is required\"),\n filePattern: z.string().optional(),\n previewUrl: z.string().optional(),\n schema: collectionSchemaSchema.optional(),\n images: imageConfigSchema.optional(),\n});\n\n/**\n * Schema for discovery configuration\n */\nconst discoveryConfigSchema = z.object({\n enabled: z.boolean(),\n ignore: z.array(z.string()).optional(),\n});\n\n/**\n * Schema for editor configuration\n */\nconst editorConfigSchema = z.object({\n autosave: z.boolean().optional(),\n autosaveInterval: z.number().positive().optional(),\n});\n\n/**\n * Schema for version history configuration\n */\nconst versionHistoryConfigSchema = z.object({\n enabled: z.boolean().optional(),\n maxVersions: z.number().int().positive().optional(),\n storagePath: z.string().optional(),\n});\n\n/**\n * Main Writenex configuration schema\n */\nexport const writenexConfigSchema = z.object({\n collections: z.array(collectionConfigSchema).optional(),\n images: imageConfigSchema.optional(),\n editor: editorConfigSchema.optional(),\n discovery: discoveryConfigSchema.optional(),\n versionHistory: versionHistoryConfigSchema.optional(),\n});\n\n/**\n * Schema for integration options\n */\nexport const writenexOptionsSchema = z.object({\n allowProduction: z.boolean().optional(),\n});\n\n/**\n * Helper function for defining type-safe Writenex configuration.\n *\n * This function provides IDE autocompletion and type checking for\n * the configuration object. It's the recommended way to create\n * a writenex.config.ts file.\n *\n * @param config - The Writenex configuration object\n * @returns The same configuration object (identity function for type safety)\n *\n * @example\n * ```typescript\n * // writenex.config.ts\n * import { defineConfig } from '@writenex/astro';\n *\n * export default defineConfig({\n * collections: [\n * {\n * name: 'blog',\n * path: 'src/content/blog',\n * filePattern: '{slug}.md',\n * },\n * ],\n * });\n * ```\n */\nexport function defineConfig(config: WritenexConfig): WritenexConfig {\n // Validate the configuration\n const result = writenexConfigSchema.safeParse(config);\n\n if (!result.success) {\n const errors = result.error.issues\n .map((e: z.ZodIssue) => ` - ${e.path.join(\".\")}: ${e.message}`)\n .join(\"\\n\");\n console.warn(`[writenex] Invalid configuration:\\n${errors}`);\n }\n\n return config;\n}\n\n/**\n * Validate a Writenex configuration object\n *\n * @param config - The configuration to validate\n * @returns Validation result with success status and parsed data or errors\n */\nexport function validateConfig(\n config: unknown\n):\n | { success: true; data: WritenexConfig }\n | { success: false; error: z.ZodError } {\n return writenexConfigSchema.safeParse(config) as\n | { success: true; data: WritenexConfig }\n | { success: false; error: z.ZodError };\n}\n"],"mappings":"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","names":[]}
|