@imjp/writenex-astro 1.3.6 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/chunk-E4PQLKAH.js +282 -0
  2. package/dist/chunk-E4PQLKAH.js.map +1 -0
  3. package/dist/{chunk-NSW7AIVF.js → chunk-EEUN46Q2.js} +3 -3
  4. package/dist/{chunk-YBCPOLMY.js → chunk-P5KMSHFP.js} +2 -1
  5. package/dist/{chunk-YBCPOLMY.js.map → chunk-P5KMSHFP.js.map} +1 -1
  6. package/dist/{chunk-JMNCPNQX.js → chunk-XVQNYPOI.js} +65 -3
  7. package/dist/chunk-XVQNYPOI.js.map +1 -0
  8. package/dist/chunk-YRSIZLHE.js +1 -0
  9. package/dist/{chunk-N37EPLKG.js → chunk-ZWUGHWHD.js} +79 -10
  10. package/dist/chunk-ZWUGHWHD.js.map +1 -0
  11. package/dist/client/index.css +1 -1
  12. package/dist/client/index.css.map +1 -1
  13. package/dist/client/index.js +114 -114
  14. package/dist/client/index.js.map +1 -1
  15. package/dist/config/index.d.ts +3 -2
  16. package/dist/config/index.js +11 -3
  17. package/dist/{config-CliL0CoN.d.ts → config-B7t8CjL1.d.ts} +38 -60
  18. package/dist/{content-TuL3GT66.d.ts → content-CwcgR8P6.d.ts} +1 -1
  19. package/dist/discovery/index.d.ts +2 -2
  20. package/dist/discovery/index.js +2 -2
  21. package/dist/fields/index.d.ts +16 -0
  22. package/dist/fields/index.js +13 -0
  23. package/dist/fields-DUSm13nm.d.ts +223 -0
  24. package/dist/filesystem/index.d.ts +2 -2
  25. package/dist/filesystem/index.js +1 -1
  26. package/dist/index.d.ts +5 -4
  27. package/dist/index.js +13 -5
  28. package/dist/index.js.map +1 -1
  29. package/dist/{loader-53VVP2IN.js → loader-B5WZCVBC.js} +3 -3
  30. package/dist/loader-B5WZCVBC.js.map +1 -0
  31. package/dist/{schema-DDJyoVkj.d.ts → schema-nLMfZ9-o.d.ts} +79 -53
  32. package/dist/server/index.d.ts +2 -2
  33. package/dist/server/index.js +3 -3
  34. package/package.json +5 -1
  35. package/src/client/components/FrontmatterForm/FrontmatterForm.css +104 -0
  36. package/src/client/components/FrontmatterForm/FrontmatterForm.tsx +452 -26
  37. package/src/config/defaults.ts +1 -0
  38. package/src/config/index.ts +3 -0
  39. package/src/config/schema.ts +114 -73
  40. package/src/discovery/schema.ts +120 -1
  41. package/src/fields/collection.ts +67 -0
  42. package/src/fields/fields.ts +150 -0
  43. package/src/fields/index.ts +42 -0
  44. package/src/fields/resolve.ts +203 -0
  45. package/src/fields/types.ts +179 -0
  46. package/src/index.ts +3 -0
  47. package/src/types/config.ts +87 -63
  48. package/src/types/index.ts +3 -0
  49. package/dist/chunk-JMNCPNQX.js.map +0 -1
  50. package/dist/chunk-KIKIPIFA.js +0 -1
  51. package/dist/chunk-N37EPLKG.js.map +0 -1
  52. /package/dist/{chunk-NSW7AIVF.js.map → chunk-EEUN46Q2.js.map} +0 -0
  53. /package/dist/{chunk-KIKIPIFA.js.map → chunk-YRSIZLHE.js.map} +0 -0
  54. /package/dist/{loader-53VVP2IN.js.map → fields/index.js.map} +0 -0
@@ -10,9 +10,6 @@
10
10
  import { z } from "zod";
11
11
  import type { WritenexConfig } from "@/types";
12
12
 
13
- /**
14
- * Schema for field type definitions
15
- */
16
13
  const fieldTypeSchema = z.enum([
17
14
  "string",
18
15
  "number",
@@ -21,41 +18,124 @@ const fieldTypeSchema = z.enum([
21
18
  "array",
22
19
  "image",
23
20
  "object",
21
+ "file",
22
+ "blocks",
23
+ "relationship",
24
+ "markdoc",
25
+ "mdx",
26
+ "child",
27
+ "slug",
28
+ "url",
29
+ "integer",
30
+ "select",
31
+ "multiselect",
32
+ "datetime",
33
+ "cloud-image",
34
+ "path-reference",
35
+ "conditional",
36
+ "empty",
37
+ "empty-content",
38
+ "empty-document",
39
+ "ignored",
40
+ "checkbox",
24
41
  ]);
25
42
 
26
- /**
27
- * Schema for individual schema field definition
28
- */
29
- const schemaFieldSchema = z.object({
30
- type: fieldTypeSchema,
31
- required: z.boolean().optional(),
32
- default: z.unknown().optional(),
33
- items: z.string().optional(),
34
- description: z.string().optional(),
35
- });
43
+ const validationSchema = z
44
+ .object({
45
+ isRequired: z.boolean().optional(),
46
+ min: z.number().optional(),
47
+ max: z.number().optional(),
48
+ minLength: z.number().optional(),
49
+ maxLength: z.number().optional(),
50
+ pattern: z.string().optional(),
51
+ patternDescription: z.string().optional(),
52
+ })
53
+ .optional();
54
+
55
+ type SchemaFieldInput = {
56
+ type: z.infer<typeof fieldTypeSchema>;
57
+ required?: boolean;
58
+ default?: unknown;
59
+ items?: string;
60
+ description?: string;
61
+ label?: string;
62
+ options?: string[];
63
+ directory?: string;
64
+ publicPath?: string;
65
+ validation?: z.infer<typeof validationSchema>;
66
+ fields?: Record<string, SchemaFieldInput>;
67
+ itemField?: SchemaFieldInput;
68
+ blockTypes?: Record<string, SchemaFieldInput>;
69
+ collection?: string;
70
+ multiline?: boolean;
71
+ format?: string;
72
+ itemLabel?: string;
73
+ matchField?: string;
74
+ matchValue?: unknown;
75
+ showField?: SchemaFieldInput;
76
+ accept?: string;
77
+ allowExternal?: boolean;
78
+ inline?: boolean;
79
+ };
80
+
81
+ function createSchemaFieldSchema(): z.ZodType<SchemaFieldInput> {
82
+ let schemaFieldSchema: z.ZodType<SchemaFieldInput>;
83
+
84
+ const baseFields = {
85
+ type: fieldTypeSchema,
86
+ required: z.boolean().optional(),
87
+ default: z.unknown().optional(),
88
+ items: z.string().optional(),
89
+ description: z.string().optional(),
90
+ label: z.string().optional(),
91
+ options: z.array(z.string()).optional(),
92
+ directory: z.string().optional(),
93
+ publicPath: z.string().optional(),
94
+ validation: validationSchema,
95
+ collection: z.string().optional(),
96
+ multiline: z.boolean().optional(),
97
+ format: z.string().optional(),
98
+ itemLabel: z.string().optional(),
99
+ matchField: z.string().optional(),
100
+ matchValue: z.unknown().optional(),
101
+ accept: z.string().optional(),
102
+ allowExternal: z.boolean().optional(),
103
+ inline: z.boolean().optional(),
104
+ };
105
+
106
+ schemaFieldSchema = z.object({
107
+ ...baseFields,
108
+ fields: z
109
+ .record(
110
+ z.string(),
111
+ z.lazy(() => schemaFieldSchema)
112
+ )
113
+ .optional(),
114
+ itemField: z.lazy(() => schemaFieldSchema).optional(),
115
+ blockTypes: z
116
+ .record(
117
+ z.string(),
118
+ z.lazy(() => schemaFieldSchema)
119
+ )
120
+ .optional(),
121
+ showField: z.lazy(() => schemaFieldSchema).optional(),
122
+ });
123
+
124
+ return schemaFieldSchema;
125
+ }
126
+
127
+ const schemaFieldSchema = createSchemaFieldSchema();
36
128
 
37
- /**
38
- * Schema for collection schema (record of field definitions)
39
- */
40
129
  const collectionSchemaSchema = z.record(z.string(), schemaFieldSchema);
41
130
 
42
- /**
43
- * Schema for image strategy
44
- */
45
131
  const imageStrategySchema = z.enum(["colocated", "public", "custom"]);
46
132
 
47
- /**
48
- * Schema for image configuration
49
- */
50
133
  const imageConfigSchema = z.object({
51
134
  strategy: imageStrategySchema,
52
135
  publicPath: z.string().optional(),
53
136
  storagePath: z.string().optional(),
54
137
  });
55
138
 
56
- /**
57
- * Schema for collection configuration
58
- */
59
139
  const collectionConfigSchema = z.object({
60
140
  name: z.string().min(1, "Collection name is required"),
61
141
  path: z.string().min(1, "Collection path is required"),
@@ -65,77 +145,44 @@ const collectionConfigSchema = z.object({
65
145
  images: imageConfigSchema.optional(),
66
146
  });
67
147
 
68
- /**
69
- * Schema for discovery configuration
70
- */
148
+ const singletonConfigSchema = z.object({
149
+ name: z.string().min(1, "Singleton name is required"),
150
+ path: z.string().min(1, "Singleton path is required"),
151
+ previewUrl: z.string().optional(),
152
+ schema: collectionSchemaSchema.optional(),
153
+ images: imageConfigSchema.optional(),
154
+ });
155
+
71
156
  const discoveryConfigSchema = z.object({
72
157
  enabled: z.boolean(),
73
158
  ignore: z.array(z.string()).optional(),
74
159
  });
75
160
 
76
- /**
77
- * Schema for editor configuration
78
- */
79
161
  const editorConfigSchema = z.object({
80
162
  autosave: z.boolean().optional(),
81
163
  autosaveInterval: z.number().positive().optional(),
82
164
  });
83
165
 
84
- /**
85
- * Schema for version history configuration
86
- */
87
166
  const versionHistoryConfigSchema = z.object({
88
167
  enabled: z.boolean().optional(),
89
168
  maxVersions: z.number().int().positive().optional(),
90
169
  storagePath: z.string().optional(),
91
170
  });
92
171
 
93
- /**
94
- * Main Writenex configuration schema
95
- */
96
172
  export const writenexConfigSchema = z.object({
97
173
  collections: z.array(collectionConfigSchema).optional(),
174
+ singletons: z.array(singletonConfigSchema).optional(),
98
175
  images: imageConfigSchema.optional(),
99
176
  editor: editorConfigSchema.optional(),
100
177
  discovery: discoveryConfigSchema.optional(),
101
178
  versionHistory: versionHistoryConfigSchema.optional(),
102
179
  });
103
180
 
104
- /**
105
- * Schema for integration options
106
- */
107
181
  export const writenexOptionsSchema = z.object({
108
182
  allowProduction: z.boolean().optional(),
109
183
  });
110
184
 
111
- /**
112
- * Helper function for defining type-safe Writenex configuration.
113
- *
114
- * This function provides IDE autocompletion and type checking for
115
- * the configuration object. It's the recommended way to create
116
- * a writenex.config.ts file.
117
- *
118
- * @param config - The Writenex configuration object
119
- * @returns The same configuration object (identity function for type safety)
120
- *
121
- * @example
122
- * ```typescript
123
- * // writenex.config.ts
124
- * import { defineConfig } from '@writenex/astro';
125
- *
126
- * export default defineConfig({
127
- * collections: [
128
- * {
129
- * name: 'blog',
130
- * path: 'src/content/blog',
131
- * filePattern: '{slug}.md',
132
- * },
133
- * ],
134
- * });
135
- * ```
136
- */
137
185
  export function defineConfig(config: WritenexConfig): WritenexConfig {
138
- // Validate the configuration
139
186
  const result = writenexConfigSchema.safeParse(config);
140
187
 
141
188
  if (!result.success) {
@@ -148,12 +195,6 @@ export function defineConfig(config: WritenexConfig): WritenexConfig {
148
195
  return config;
149
196
  }
150
197
 
151
- /**
152
- * Validate a Writenex configuration object
153
- *
154
- * @param config - The configuration to validate
155
- * @returns Validation result with success status and parsed data or errors
156
- */
157
198
  export function validateConfig(
158
199
  config: unknown
159
200
  ):
@@ -60,6 +60,69 @@ const IMAGE_EXTENSIONS = [
60
60
  ".svg",
61
61
  ];
62
62
 
63
+ /**
64
+ * URL pattern detection
65
+ */
66
+ const URL_PATTERN = /^https?:\/\//;
67
+
68
+ /**
69
+ * Slug pattern detection (lowercase, hyphenated)
70
+ */
71
+ const SLUG_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
72
+
73
+ /**
74
+ * Datetime pattern detection (ISO datetime)
75
+ */
76
+ const DATETIME_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/;
77
+
78
+ /**
79
+ * Check if a string looks like a URL
80
+ */
81
+ function isUrlValue(value: unknown): boolean {
82
+ if (typeof value !== "string") return false;
83
+ return URL_PATTERN.test(value);
84
+ }
85
+
86
+ /**
87
+ * Check if a string looks like a slug
88
+ */
89
+ function isSlugValue(value: unknown): boolean {
90
+ if (typeof value !== "string") return false;
91
+ if (value.length < 2 || value.length > 100) return false;
92
+ return SLUG_PATTERN.test(value);
93
+ }
94
+
95
+ /**
96
+ * Check if a string looks like a datetime
97
+ */
98
+ function isDatetimeValue(value: unknown): boolean {
99
+ if (typeof value !== "string") return false;
100
+ return DATETIME_PATTERN.test(value);
101
+ }
102
+
103
+ /**
104
+ * Check if a string looks like a file path (non-image)
105
+ */
106
+ function isFilePath(value: unknown): boolean {
107
+ if (typeof value !== "string") return false;
108
+ if (isImagePath(value)) return false;
109
+ return /\.\w{2,5}$/.test(value);
110
+ }
111
+
112
+ /**
113
+ * Check if an array looks like a multiselect (array of strings from a small set)
114
+ */
115
+ function isMultiselectArray(values: unknown[]): boolean {
116
+ if (values.length === 0) return false;
117
+ const allStrings = values.every((v) => typeof v === "string" && v.length > 0);
118
+ if (!allStrings) return false;
119
+ const uniqueValues = [...new Set(values)];
120
+ return (
121
+ uniqueValues.length <= ENUM_MAX_VALUES &&
122
+ values.length > uniqueValues.length
123
+ );
124
+ }
125
+
63
126
  /**
64
127
  * Field analysis data collected from samples
65
128
  */
@@ -74,6 +137,18 @@ interface FieldAnalysis {
74
137
  hasImagePaths: boolean;
75
138
  /** Whether values look like dates */
76
139
  hasDateValues: boolean;
140
+ /** Whether values look like URLs */
141
+ hasUrlValues: boolean;
142
+ /** Whether values look like slugs */
143
+ hasSlugValues: boolean;
144
+ /** Whether values look like datetimes */
145
+ hasDatetimeValues: boolean;
146
+ /** Whether values look like file paths */
147
+ hasFilePaths: boolean;
148
+ /** Whether all number values are integers */
149
+ allIntegers: boolean;
150
+ /** Whether array looks like multiselect */
151
+ isMultiselect: boolean;
77
152
  /** For arrays, analysis of item types */
78
153
  arrayItemTypes: Set<string>;
79
154
  }
@@ -153,9 +228,29 @@ function inferFieldType(analysis: FieldAnalysis): FieldType {
153
228
  // If it has image paths, it's an image field
154
229
  if (analysis.hasImagePaths) return "image";
155
230
 
231
+ // If it has datetime values, it's a datetime field
232
+ if (analysis.hasDatetimeValues) return "datetime";
233
+
156
234
  // If it has date values, it's a date field
157
235
  if (analysis.hasDateValues) return "date";
158
236
 
237
+ // If it has file paths, it's a file field
238
+ if (analysis.hasFilePaths) return "file";
239
+
240
+ // If it has URL values, it's a url field
241
+ if (analysis.hasUrlValues) return "url";
242
+
243
+ // If it has slug values and is a single string type
244
+ if (analysis.hasSlugValues && analysis.types.size === 1) {
245
+ const typesArr = [...analysis.types];
246
+ if (typesArr.length === 1 && typesArr[0] === "string") {
247
+ return "slug";
248
+ }
249
+ }
250
+
251
+ // Check for multiselect arrays
252
+ if (analysis.isMultiselect) return "multiselect";
253
+
159
254
  // Check detected types (excluding null)
160
255
  const nonNullTypes = new Set([...analysis.types].filter((t) => t !== "null"));
161
256
 
@@ -166,7 +261,7 @@ function inferFieldType(analysis: FieldAnalysis): FieldType {
166
261
  case "boolean":
167
262
  return "boolean";
168
263
  case "number":
169
- return "number";
264
+ return analysis.allIntegers ? "integer" : "number";
170
265
  case "array":
171
266
  return "array";
172
267
  case "object":
@@ -290,6 +385,12 @@ export async function detectSchema(
290
385
  values: [],
291
386
  hasImagePaths: false,
292
387
  hasDateValues: false,
388
+ hasUrlValues: false,
389
+ hasSlugValues: false,
390
+ hasDatetimeValues: false,
391
+ hasFilePaths: false,
392
+ allIntegers: true,
393
+ isMultiselect: false,
293
394
  arrayItemTypes: new Set(),
294
395
  };
295
396
  fieldAnalyses.set(fieldName, analysis);
@@ -307,12 +408,30 @@ export async function detectSchema(
307
408
  if (isDateValue(value)) {
308
409
  analysis.hasDateValues = true;
309
410
  }
411
+ if (isUrlValue(value)) {
412
+ analysis.hasUrlValues = true;
413
+ }
414
+ if (isSlugValue(value)) {
415
+ analysis.hasSlugValues = true;
416
+ }
417
+ if (isDatetimeValue(value)) {
418
+ analysis.hasDatetimeValues = true;
419
+ }
420
+ if (isFilePath(value)) {
421
+ analysis.hasFilePaths = true;
422
+ }
423
+ if (typeof value === "number" && !Number.isInteger(value)) {
424
+ analysis.allIntegers = false;
425
+ }
310
426
 
311
427
  // Analyze array items
312
428
  if (Array.isArray(value)) {
313
429
  for (const item of value) {
314
430
  analysis.arrayItemTypes.add(detectValueType(item));
315
431
  }
432
+ if (isMultiselectArray(value)) {
433
+ analysis.isMultiselect = true;
434
+ }
316
435
  }
317
436
  }
318
437
  }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @fileoverview Collection and Singleton schema helpers
3
+ *
4
+ * These helpers provide a typed way to define collection and singleton
5
+ * schemas using the fields builder API. They convert FieldDefinition
6
+ * objects to internal SchemaField format.
7
+ *
8
+ * @module @writenex/astro/fields/collection
9
+ */
10
+
11
+ import type { CollectionConfig, ImageConfig } from "@/types";
12
+ import { resolveFieldDefinition } from "./resolve";
13
+ import type { FieldDefinition } from "./types";
14
+
15
+ export interface CollectionSchemaConfig {
16
+ name: string;
17
+ path: string;
18
+ filePattern?: string;
19
+ previewUrl?: string;
20
+ schema: Record<string, FieldDefinition>;
21
+ images?: ImageConfig;
22
+ }
23
+
24
+ export interface SingletonSchemaConfig {
25
+ name: string;
26
+ path: string;
27
+ previewUrl?: string;
28
+ schema: Record<string, FieldDefinition>;
29
+ images?: ImageConfig;
30
+ }
31
+
32
+ export function collection(config: CollectionSchemaConfig): CollectionConfig {
33
+ const schema: Record<string, import("@/types").SchemaField> = {};
34
+ for (const [key, fieldDef] of Object.entries(config.schema)) {
35
+ schema[key] = resolveFieldDefinition(fieldDef);
36
+ }
37
+
38
+ return {
39
+ name: config.name,
40
+ path: config.path,
41
+ filePattern: config.filePattern,
42
+ previewUrl: config.previewUrl,
43
+ schema,
44
+ images: config.images,
45
+ };
46
+ }
47
+
48
+ export function singleton(config: SingletonSchemaConfig): {
49
+ name: string;
50
+ path: string;
51
+ previewUrl?: string;
52
+ schema: Record<string, import("@/types").SchemaField>;
53
+ images?: ImageConfig;
54
+ } {
55
+ const schema: Record<string, import("@/types").SchemaField> = {};
56
+ for (const [key, fieldDef] of Object.entries(config.schema)) {
57
+ schema[key] = resolveFieldDefinition(fieldDef);
58
+ }
59
+
60
+ return {
61
+ name: config.name,
62
+ path: config.path,
63
+ previewUrl: config.previewUrl,
64
+ schema,
65
+ images: config.images,
66
+ };
67
+ }
@@ -0,0 +1,150 @@
1
+ /**
2
+ * @fileoverview Fields builder API for @writenex/astro
3
+ *
4
+ * This module provides a TypeScript-first builder pattern for defining
5
+ * content schema fields. Each field type is a method on the `fields` object.
6
+ *
7
+ * @module @writenex/astro/fields/fields
8
+ */
9
+
10
+ import type {
11
+ ArrayFieldConfig,
12
+ BaseFieldConfig,
13
+ BlocksFieldConfig,
14
+ CheckboxFieldConfig,
15
+ ChildFieldConfig,
16
+ CloudImageFieldConfig,
17
+ ConditionalFieldConfig,
18
+ DateFieldConfig,
19
+ DatetimeFieldConfig,
20
+ FieldDefinition,
21
+ FileFieldConfig,
22
+ ImageFieldConfig,
23
+ IntegerFieldConfig,
24
+ MarkdocFieldConfig,
25
+ MdxFieldConfig,
26
+ MultiselectFieldConfig,
27
+ NumberFieldConfig,
28
+ ObjectFieldConfig,
29
+ PathReferenceFieldConfig,
30
+ RelationshipFieldConfig,
31
+ SelectFieldConfig,
32
+ SlugFieldConfig,
33
+ TextFieldConfig,
34
+ UrlFieldConfig,
35
+ } from "./types";
36
+
37
+ function createField<K extends FieldDefinition["fieldKind"]>(
38
+ fieldKind: K,
39
+ config: Omit<Extract<FieldDefinition, { fieldKind: K }>, "fieldKind">
40
+ ): Extract<FieldDefinition, { fieldKind: K }> {
41
+ return { fieldKind, ...config } as Extract<FieldDefinition, { fieldKind: K }>;
42
+ }
43
+
44
+ export const fields = {
45
+ text(config: TextFieldConfig = {}): FieldDefinition {
46
+ return createField("text", config);
47
+ },
48
+
49
+ slug(config: SlugFieldConfig = {}): FieldDefinition {
50
+ return createField("slug", config);
51
+ },
52
+
53
+ url(config: UrlFieldConfig = {}): FieldDefinition {
54
+ return createField("url", config);
55
+ },
56
+
57
+ number(config: NumberFieldConfig = {}): FieldDefinition {
58
+ return createField("number", config);
59
+ },
60
+
61
+ integer(config: IntegerFieldConfig = {}): FieldDefinition {
62
+ return createField("integer", config);
63
+ },
64
+
65
+ select(config: SelectFieldConfig): FieldDefinition {
66
+ return createField("select", config);
67
+ },
68
+
69
+ multiselect(config: MultiselectFieldConfig): FieldDefinition {
70
+ return createField("multiselect", config);
71
+ },
72
+
73
+ checkbox(config: CheckboxFieldConfig = {}): FieldDefinition {
74
+ return createField("checkbox", config);
75
+ },
76
+
77
+ date(config: DateFieldConfig = {}): FieldDefinition {
78
+ return createField("date", config);
79
+ },
80
+
81
+ datetime(config: DatetimeFieldConfig = {}): FieldDefinition {
82
+ return createField("datetime", config);
83
+ },
84
+
85
+ image(config: ImageFieldConfig = {}): FieldDefinition {
86
+ return createField("image", config);
87
+ },
88
+
89
+ file(config: FileFieldConfig = {}): FieldDefinition {
90
+ return createField("file", config);
91
+ },
92
+
93
+ object(config: ObjectFieldConfig): FieldDefinition {
94
+ return createField("object", config);
95
+ },
96
+
97
+ array(config: ArrayFieldConfig): FieldDefinition {
98
+ return createField("array", config);
99
+ },
100
+
101
+ blocks(config: BlocksFieldConfig): FieldDefinition {
102
+ return createField("blocks", config);
103
+ },
104
+
105
+ relationship(config: RelationshipFieldConfig): FieldDefinition {
106
+ return createField("relationship", config);
107
+ },
108
+
109
+ pathReference(config: PathReferenceFieldConfig = {}): FieldDefinition {
110
+ return createField("path-reference", config);
111
+ },
112
+
113
+ markdoc(config: MarkdocFieldConfig = {}): FieldDefinition {
114
+ return createField("markdoc", config);
115
+ },
116
+
117
+ mdx(config: MdxFieldConfig = {}): FieldDefinition {
118
+ return createField("mdx", config);
119
+ },
120
+
121
+ conditional(config: ConditionalFieldConfig): FieldDefinition {
122
+ return createField("conditional", config);
123
+ },
124
+
125
+ child(config: ChildFieldConfig = {}): FieldDefinition {
126
+ return createField("child", config);
127
+ },
128
+
129
+ cloudImage(config: CloudImageFieldConfig = {}): FieldDefinition {
130
+ return createField("cloud-image", config);
131
+ },
132
+
133
+ empty(config: BaseFieldConfig = {}): FieldDefinition {
134
+ return createField("empty", config);
135
+ },
136
+
137
+ emptyContent(config: BaseFieldConfig = {}): FieldDefinition {
138
+ return createField("empty-content", config);
139
+ },
140
+
141
+ emptyDocument(config: BaseFieldConfig = {}): FieldDefinition {
142
+ return createField("empty-document", config);
143
+ },
144
+
145
+ ignored(config: BaseFieldConfig = {}): FieldDefinition {
146
+ return createField("ignored", config);
147
+ },
148
+ };
149
+
150
+ export type Fields = typeof fields;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @fileoverview Fields API barrel exports
3
+ *
4
+ * @module @writenex/astro/fields
5
+ */
6
+
7
+ export type {
8
+ CollectionSchemaConfig,
9
+ SingletonSchemaConfig,
10
+ } from "./collection";
11
+ export { collection, singleton } from "./collection";
12
+ export type { Fields } from "./fields";
13
+ export { fields } from "./fields";
14
+ export { resolveFieldDefinition } from "./resolve";
15
+ export type {
16
+ ArrayFieldConfig,
17
+ BaseFieldConfig,
18
+ BlocksFieldConfig,
19
+ CheckboxFieldConfig,
20
+ ChildFieldConfig,
21
+ CloudImageFieldConfig,
22
+ ConditionalFieldConfig,
23
+ DateFieldConfig,
24
+ DatetimeFieldConfig,
25
+ FieldDefinition,
26
+ FieldKind,
27
+ FileFieldConfig,
28
+ ImageFieldConfig,
29
+ IntegerFieldConfig,
30
+ MarkdocFieldConfig,
31
+ MdxFieldConfig,
32
+ MultiselectFieldConfig,
33
+ NumberFieldConfig,
34
+ ObjectFieldConfig,
35
+ PathReferenceFieldConfig,
36
+ RelationshipFieldConfig,
37
+ SelectFieldConfig,
38
+ SlugFieldConfig,
39
+ TextFieldConfig,
40
+ UrlFieldConfig,
41
+ ValidationOptions,
42
+ } from "./types";