octocms 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/agentDocs-Z5BI2Y2G.js +38 -0
  2. package/dist/agentDocs-Z5BI2Y2G.js.map +1 -0
  3. package/dist/chunk-4MPOTHTY.js +9 -0
  4. package/dist/chunk-4MPOTHTY.js.map +1 -0
  5. package/dist/chunk-4VLN5EX2.js +9204 -0
  6. package/dist/chunk-4VLN5EX2.js.map +1 -0
  7. package/dist/chunk-6PHFHGTZ.js +35 -0
  8. package/dist/chunk-6PHFHGTZ.js.map +1 -0
  9. package/dist/chunk-7CFFE2I6.js +55 -0
  10. package/dist/chunk-7CFFE2I6.js.map +1 -0
  11. package/dist/chunk-B47VXAHT.js +28 -0
  12. package/dist/chunk-B47VXAHT.js.map +1 -0
  13. package/dist/chunk-BRTXBBVQ.js +46 -0
  14. package/dist/chunk-BRTXBBVQ.js.map +1 -0
  15. package/dist/chunk-C62C776U.js +79 -0
  16. package/dist/chunk-C62C776U.js.map +1 -0
  17. package/dist/chunk-I7KNSICQ.js +114 -0
  18. package/dist/chunk-I7KNSICQ.js.map +1 -0
  19. package/dist/chunk-Q73JSGXV.js +123 -0
  20. package/dist/chunk-Q73JSGXV.js.map +1 -0
  21. package/dist/chunk-W6QJTGBC.js +57 -0
  22. package/dist/chunk-W6QJTGBC.js.map +1 -0
  23. package/dist/cli/index.js +196 -0
  24. package/dist/cli/index.js.map +1 -0
  25. package/dist/components/public/index.d.mts +40 -0
  26. package/dist/components/public/index.js +401 -0
  27. package/dist/components/public/index.js.map +1 -0
  28. package/dist/config.d.mts +4 -0
  29. package/dist/config.js +13 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/defineConfig.d.mts +126 -0
  32. package/dist/defineConfig.js +8 -0
  33. package/dist/defineConfig.js.map +1 -0
  34. package/dist/dev-QY534GEH.js +87 -0
  35. package/dist/dev-QY534GEH.js.map +1 -0
  36. package/dist/index.d.mts +5 -0
  37. package/dist/index.js +17 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/init-UGUTJFFI.js +145 -0
  40. package/dist/init-UGUTJFFI.js.map +1 -0
  41. package/dist/jiti-VYEW7A6R.js +3068 -0
  42. package/dist/jiti-VYEW7A6R.js.map +1 -0
  43. package/dist/localReader-I2THES24.js +40 -0
  44. package/dist/localReader-I2THES24.js.map +1 -0
  45. package/dist/query.d.mts +112 -0
  46. package/dist/query.js +11 -0
  47. package/dist/query.js.map +1 -0
  48. package/dist/types.d.mts +352 -0
  49. package/dist/types.js +1 -0
  50. package/dist/types.js.map +1 -0
  51. package/dist/typesGen-WBC6CNBG.js +241 -0
  52. package/dist/typesGen-WBC6CNBG.js.map +1 -0
  53. package/dist/update-RMGZMS56.js +57 -0
  54. package/dist/update-RMGZMS56.js.map +1 -0
  55. package/dist/validate-OTJ6ULMP.js +297 -0
  56. package/dist/validate-OTJ6ULMP.js.map +1 -0
  57. package/dist/withOctoCMS.d.mts +6 -0
  58. package/dist/withOctoCMS.js +9 -0
  59. package/dist/withOctoCMS.js.map +1 -0
  60. package/docs/index.md +27 -0
  61. package/docs/overview.md +113 -0
  62. package/docs/schema.md +279 -0
  63. package/globals.css +198 -0
  64. package/package.json +116 -0
@@ -0,0 +1,40 @@
1
+ import "./chunk-7CFFE2I6.js";
2
+
3
+ // lib/localReader.ts
4
+ import fsPromises from "fs/promises";
5
+ import path from "path";
6
+ async function readLocalContentFile(filePath) {
7
+ const fullPath = path.join(process.cwd(), filePath);
8
+ try {
9
+ const data = await fsPromises.readFile(fullPath, { encoding: "utf8" });
10
+ return JSON.parse(data);
11
+ } catch (error) {
12
+ if ((error == null ? void 0 : error.code) === "ENOENT" || error instanceof SyntaxError) return null;
13
+ throw error;
14
+ }
15
+ }
16
+ async function readLocalRawFile(filePath) {
17
+ const fullPath = path.join(process.cwd(), filePath);
18
+ try {
19
+ return await fsPromises.readFile(fullPath, { encoding: "utf8" });
20
+ } catch (error) {
21
+ if ((error == null ? void 0 : error.code) === "ENOENT") return "";
22
+ throw error;
23
+ }
24
+ }
25
+ async function listLocalCollectionFiles(dirPath) {
26
+ const fullDir = path.join(process.cwd(), dirPath);
27
+ try {
28
+ const entries = await fsPromises.readdir(fullDir, { withFileTypes: true });
29
+ return entries.filter((e) => e.isFile() && e.name.endsWith(".json")).map((e) => `${dirPath}/${e.name}`);
30
+ } catch (error) {
31
+ if ((error == null ? void 0 : error.code) === "ENOENT") return [];
32
+ throw error;
33
+ }
34
+ }
35
+ export {
36
+ listLocalCollectionFiles,
37
+ readLocalContentFile,
38
+ readLocalRawFile
39
+ };
40
+ //# sourceMappingURL=localReader-I2THES24.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../lib/localReader.ts"],"sourcesContent":["import fsPromises from 'fs/promises';\nimport path from 'path';\n\n/** Read a JSON content file from local disk. Returns null on ENOENT or parse error. */\nexport async function readLocalContentFile(filePath: string): Promise<unknown | null> {\n const fullPath = path.join(process.cwd(), filePath);\n try {\n const data = await fsPromises.readFile(fullPath, { encoding: 'utf8' });\n return JSON.parse(data);\n } catch (error: any) {\n if (error?.code === 'ENOENT' || error instanceof SyntaxError) return null;\n throw error;\n }\n}\n\n/** Read a raw text file (e.g. companion .md) from local disk. Returns '' on ENOENT. */\nexport async function readLocalRawFile(filePath: string): Promise<string> {\n const fullPath = path.join(process.cwd(), filePath);\n try {\n return await fsPromises.readFile(fullPath, { encoding: 'utf8' });\n } catch (error: any) {\n if (error?.code === 'ENOENT') return '';\n throw error;\n }\n}\n\n/** List .json files in a collection directory on local disk. Returns [] if directory does not exist. */\nexport async function listLocalCollectionFiles(dirPath: string): Promise<string[]> {\n const fullDir = path.join(process.cwd(), dirPath);\n try {\n const entries = await fsPromises.readdir(fullDir, { withFileTypes: true });\n return entries.filter((e) => e.isFile() && e.name.endsWith('.json')).map((e) => `${dirPath}/${e.name}`);\n } catch (error: any) {\n if (error?.code === 'ENOENT') return [];\n throw error;\n }\n}\n"],"mappings":";;;AAAA,OAAO,gBAAgB;AACvB,OAAO,UAAU;AAGjB,eAAsB,qBAAqB,UAA2C;AACpF,QAAM,WAAW,KAAK,KAAK,QAAQ,IAAI,GAAG,QAAQ;AAClD,MAAI;AACF,UAAM,OAAO,MAAM,WAAW,SAAS,UAAU,EAAE,UAAU,OAAO,CAAC;AACrE,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,SAAS,OAAY;AACnB,SAAI,+BAAO,UAAS,YAAY,iBAAiB,YAAa,QAAO;AACrE,UAAM;AAAA,EACR;AACF;AAGA,eAAsB,iBAAiB,UAAmC;AACxE,QAAM,WAAW,KAAK,KAAK,QAAQ,IAAI,GAAG,QAAQ;AAClD,MAAI;AACF,WAAO,MAAM,WAAW,SAAS,UAAU,EAAE,UAAU,OAAO,CAAC;AAAA,EACjE,SAAS,OAAY;AACnB,SAAI,+BAAO,UAAS,SAAU,QAAO;AACrC,UAAM;AAAA,EACR;AACF;AAGA,eAAsB,yBAAyB,SAAoC;AACjF,QAAM,UAAU,KAAK,KAAK,QAAQ,IAAI,GAAG,OAAO;AAChD,MAAI;AACF,UAAM,UAAU,MAAM,WAAW,QAAQ,SAAS,EAAE,eAAe,KAAK,CAAC;AACzE,WAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,KAAK,EAAE,KAAK,SAAS,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,OAAO,IAAI,EAAE,IAAI,EAAE;AAAA,EACxG,SAAS,OAAY;AACnB,SAAI,+BAAO,UAAS,SAAU,QAAO,CAAC;AACtC,UAAM;AAAA,EACR;AACF;","names":[]}
@@ -0,0 +1,112 @@
1
+ import { Config } from './types.mjs';
2
+ import { InferConditions, CollectionNames } from './defineConfig.mjs';
3
+
4
+ type SortDirection = 'asc' | 'desc';
5
+ /**
6
+ * Chainable query builder for reading collection entries.
7
+ *
8
+ * Instantiate via `createQuery()`:
9
+ * ```ts
10
+ * // cms/__generated__/query.ts (auto-generated)
11
+ * import { createQuery } from 'octocms/query';
12
+ * import { config, type OctoConfig } from 'octocms/config';
13
+ * import type { EntryMap } from './types';
14
+ *
15
+ * export const query = createQuery<EntryMap, OctoConfig>(config);
16
+ * ```
17
+ *
18
+ * Then use:
19
+ * ```ts
20
+ * import { query } from 'cms/__generated__/query';
21
+ *
22
+ * const posts = await query('post')
23
+ * .filter((p) => p.fields.title !== '')
24
+ * .sort('publishedAt', 'desc')
25
+ * .limit(10)
26
+ * .toArray();
27
+ * ```
28
+ */
29
+ declare class QueryBuilder<TEntryMap extends Record<string, any>, TOctoConfig extends Config, C extends keyof TEntryMap & string> {
30
+ private _collection;
31
+ private _octoConfig;
32
+ private _conditions;
33
+ private _filters;
34
+ private _sortField;
35
+ private _sortDir;
36
+ private _skip;
37
+ private _limit;
38
+ private _includeDrafts;
39
+ constructor(collection: C, octoConfig: TOctoConfig);
40
+ /**
41
+ * Set branch selections for conditional fields. Maps each conditional field name
42
+ * to the branch key to resolve. When called, only the selected branch value is returned
43
+ * for each conditional field; an error is thrown if a top-level conditional field key
44
+ * is missing.
45
+ *
46
+ * Without `.conditions()`, all branches are returned as a keyed object.
47
+ */
48
+ conditions(conds: InferConditions<TOctoConfig, C & CollectionNames<TOctoConfig>>): QueryBuilder<TEntryMap, TOctoConfig, C>;
49
+ /**
50
+ * Filter entries. Accepts either:
51
+ * - A **predicate function** for full control:
52
+ * `.filter((e) => e.fields.publishedAt !== null)`
53
+ * - A **partial fields object** for simple equality matching:
54
+ * `.filter({ title: 'Hello' })`
55
+ *
56
+ * Multiple `.filter()` calls are ANDed together.
57
+ */
58
+ filter(predicate: ((entry: TEntryMap[C]) => boolean) | Partial<TEntryMap[C]['fields']>): QueryBuilder<TEntryMap, TOctoConfig, C>;
59
+ /**
60
+ * Sort entries by a field name.
61
+ */
62
+ sort(field: Extract<keyof TEntryMap[C]['fields'], string>, direction?: SortDirection): QueryBuilder<TEntryMap, TOctoConfig, C>;
63
+ /** Skip the first `n` results (for pagination). */
64
+ skip(n: number): QueryBuilder<TEntryMap, TOctoConfig, C>;
65
+ /** Limit the result to at most `n` entries. */
66
+ limit(n: number): QueryBuilder<TEntryMap, TOctoConfig, C>;
67
+ /**
68
+ * Include draft and archived entries in results.
69
+ *
70
+ * By default, `query()` excludes entries with `sys.status` of `draft` or `archived`.
71
+ * Call `.includeDrafts()` to return all entries regardless of status.
72
+ */
73
+ includeDrafts(): QueryBuilder<TEntryMap, TOctoConfig, C>;
74
+ /** Execute the query and return all matching entries as an array. */
75
+ toArray(): Promise<TEntryMap[C][]>;
76
+ /**
77
+ * Execute the query and return the first matching entry, or `null`.
78
+ */
79
+ first(): Promise<TEntryMap[C] | null>;
80
+ /**
81
+ * Execute the query and return `{ items, total, hasMore }`.
82
+ */
83
+ paginate(): Promise<{
84
+ items: TEntryMap[C][];
85
+ total: number;
86
+ hasMore: boolean;
87
+ }>;
88
+ }
89
+ /**
90
+ * Create a type-safe content query function bound to your app's config and generated types.
91
+ *
92
+ * Call this once to create your app's `query` function, then import and use it everywhere:
93
+ *
94
+ * ```ts
95
+ * // cms/__generated__/query.ts (auto-generated by `npm run types:gen`)
96
+ * import { createQuery } from 'octocms/query';
97
+ * import { config, type OctoConfig } from 'octocms/config';
98
+ * import type { EntryMap } from './types';
99
+ *
100
+ * export const query = createQuery<EntryMap, OctoConfig>(config);
101
+ * ```
102
+ *
103
+ * Then in your pages/components:
104
+ * ```ts
105
+ * import { query } from 'cms/__generated__/query';
106
+ *
107
+ * const posts = await query('post').sort('publishedAt', 'desc').toArray();
108
+ * ```
109
+ */
110
+ declare function createQuery<TEntryMap extends Record<string, any>, TOctoConfig extends Config>(octoConfig: TOctoConfig): <C extends keyof TEntryMap & string>(collection: C) => QueryBuilder<TEntryMap, TOctoConfig, C>;
111
+
112
+ export { QueryBuilder, createQuery };
package/dist/query.js ADDED
@@ -0,0 +1,11 @@
1
+ import {
2
+ QueryBuilder,
3
+ createQuery
4
+ } from "./chunk-4VLN5EX2.js";
5
+ import "./chunk-B47VXAHT.js";
6
+ import "./chunk-7CFFE2I6.js";
7
+ export {
8
+ QueryBuilder,
9
+ createQuery
10
+ };
11
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,352 @@
1
+ type EntryStatus = 'draft' | 'published' | 'changed' | 'archived' | 'merged';
2
+ type FieldFormat = 'string' | 'text' | 'markdown' | 'boolean' | 'reference' | 'image' | 'number' | 'datetime' | 'json' | 'slug' | 'select' | 'url' | 'color' | 'conditional' | 'richtext';
3
+ type ReferenceFieldConfig = {
4
+ /** Which collections this reference can point to. Defaults to all collections. */
5
+ collections?: string[];
6
+ /** 'one' = single reference, 'many' = array of references. Defaults to 'many'. */
7
+ cardinality?: 'one' | 'many';
8
+ /** Minimum number of references (for 'many'). */
9
+ min?: number;
10
+ /** Maximum number of references (for 'many'). */
11
+ max?: number;
12
+ };
13
+ /** Shared keys on every collection field definition. */
14
+ type CollectionFieldBase = {
15
+ label: string;
16
+ entryTitle?: boolean;
17
+ /** When true, the field must be non-empty; save is blocked until valid. */
18
+ required?: boolean;
19
+ /** Optional helper text shown below the field in the admin UI. */
20
+ hint?: string;
21
+ /** Include in search index. Defaults to true for text-like formats (string, text, markdown, richtext, slug, select). Set false to exclude. */
22
+ searchable?: boolean;
23
+ };
24
+ type SelectOption = {
25
+ label: string;
26
+ value: string;
27
+ };
28
+ /** A branch in a conditional field — either inline fields or a reference to a collection. */
29
+ type ConditionalBranchConfig = {
30
+ /** Unique key identifying this branch (used at query time to select it). */
31
+ key: string;
32
+ label: string;
33
+ /** Inline field definitions for this branch. */
34
+ fields: Record<string, CollectionField>;
35
+ collection?: never;
36
+ } | {
37
+ /** Unique key identifying this branch (used at query time to select it). */
38
+ key: string;
39
+ label: string;
40
+ /** Reference branch — reuses an existing collection's schema. */
41
+ collection: string;
42
+ fields?: never;
43
+ };
44
+ type ConditionalFieldConfig = {
45
+ branches: readonly ConditionalBranchConfig[];
46
+ };
47
+ /** Prop definition for a custom component in a richtext field. */
48
+ type RichTextComponentProp = {
49
+ name: string;
50
+ label: string;
51
+ type: 'string' | 'number' | 'boolean' | 'url' | 'image' | 'select';
52
+ options?: readonly SelectOption[];
53
+ required?: boolean;
54
+ defaultValue?: string | number | boolean;
55
+ };
56
+ /** A custom component that can be embedded in a richtext field. */
57
+ type RichTextComponentDef = {
58
+ label: string;
59
+ /** Inline = sits within a paragraph. Block = occupies its own line. */
60
+ kind: 'inline' | 'block';
61
+ props: RichTextComponentProp[];
62
+ };
63
+ /** Controls which standard toolbar buttons appear in the richtext editor. All default to `true`. */
64
+ type RichTextToolbarConfig = {
65
+ /** Bold / italic / underline toggles. */
66
+ formatting?: boolean;
67
+ /** Heading / paragraph block type selector. */
68
+ headings?: boolean;
69
+ /** Ordered / unordered list toggles. */
70
+ lists?: boolean;
71
+ /** Inline code toggle. */
72
+ code?: boolean;
73
+ /** Code block insertion. */
74
+ codeBlock?: boolean;
75
+ /** Link creation button. */
76
+ links?: boolean;
77
+ /** Table insertion button. */
78
+ tables?: boolean;
79
+ /** Horizontal rule insertion. */
80
+ thematicBreak?: boolean;
81
+ /** Standard markdown image insertion (URL-based). */
82
+ images?: boolean;
83
+ /** Undo / redo buttons. */
84
+ undoRedo?: boolean;
85
+ };
86
+ /** Configuration for the richtext field type's embeddable content. */
87
+ type RichTextFieldConfig = {
88
+ embeds?: {
89
+ /** Allow embedding references to other entries. */
90
+ references?: {
91
+ collections?: string[];
92
+ /** Whether references can appear inline, as blocks, or both. Default: 'both'. */
93
+ display?: 'inline' | 'block' | 'both';
94
+ };
95
+ /** Allow embedding conditional (A/B) content branches. */
96
+ conditions?: boolean;
97
+ /** Allow embedding images from the media library. */
98
+ images?: boolean;
99
+ /** Allowed template variable names (e.g. ['user.firstName', 'site.name']). */
100
+ variables?: string[];
101
+ /** Custom components that can be embedded in the editor. */
102
+ components?: Record<string, RichTextComponentDef>;
103
+ };
104
+ /** Customize which standard toolbar buttons are shown. Omitted keys default to `true`. */
105
+ toolbar?: RichTextToolbarConfig;
106
+ };
107
+ /**
108
+ * Per-format field definitions (discriminated union on `format`).
109
+ * Use `as const` on `options` (and default arrays) in cms/octocms.config.ts for literal type inference in `InferFields`.
110
+ */
111
+ type CollectionField = (CollectionFieldBase & {
112
+ format: 'string';
113
+ /**
114
+ * When `true`, the field stores a JSON array of strings (`string[]`) and the editor shows a tag-style list.
115
+ */
116
+ list?: true;
117
+ }) | (CollectionFieldBase & {
118
+ format: 'text';
119
+ /** Textarea height; defaults to 4 in the editor. */
120
+ rows?: number;
121
+ }) | (CollectionFieldBase & {
122
+ format: 'markdown';
123
+ }) | (CollectionFieldBase & {
124
+ format: 'boolean';
125
+ /** When set, new entries get `"true"` or `"false"` in JSON. */
126
+ defaultBoolean?: boolean;
127
+ /** Radio labels in the editor (default Yes / No). */
128
+ booleanLabels?: {
129
+ true: string;
130
+ false: string;
131
+ };
132
+ }) | (CollectionFieldBase & {
133
+ format: 'reference';
134
+ /** @deprecated Use `reference` config instead. Kept for backward compatibility. */
135
+ collection?: string;
136
+ reference?: ReferenceFieldConfig;
137
+ }) | (CollectionFieldBase & {
138
+ format: 'image';
139
+ }) | (CollectionFieldBase & {
140
+ format: 'number';
141
+ min?: number;
142
+ max?: number;
143
+ step?: number | 'any';
144
+ valueType?: 'int' | 'float';
145
+ }) | (CollectionFieldBase & {
146
+ format: 'datetime';
147
+ dateOnly?: boolean;
148
+ defaultNow?: boolean;
149
+ }) | (CollectionFieldBase & {
150
+ format: 'json';
151
+ }) | (CollectionFieldBase & {
152
+ format: 'slug';
153
+ /**
154
+ * Field key to auto-generate from (must be a non-list `string` or `text` field).
155
+ * If omitted, the field marked `entryTitle: true` is used.
156
+ */
157
+ slugSource?: string;
158
+ }) | (CollectionFieldBase & {
159
+ format: 'url';
160
+ }) | (CollectionFieldBase & {
161
+ format: 'color';
162
+ /** When true, show a hex text field synced with the native color picker. */
163
+ allowInput?: boolean;
164
+ }) | (CollectionFieldBase & {
165
+ format: 'select';
166
+ options: readonly SelectOption[];
167
+ multiple?: boolean;
168
+ /** Default for new entries when `multiple` is not true; must match an option `value`. */
169
+ defaultOption?: string;
170
+ /** Default for new entries when `multiple: true`; each entry must match an option `value`. */
171
+ defaultOptions?: readonly string[];
172
+ }) | (CollectionFieldBase & {
173
+ format: 'conditional';
174
+ conditional: ConditionalFieldConfig;
175
+ }) | (CollectionFieldBase & {
176
+ format: 'richtext';
177
+ richtext?: RichTextFieldConfig;
178
+ });
179
+ type Collection = {
180
+ label: string;
181
+ hasMany?: boolean;
182
+ fields: Record<string, CollectionField>;
183
+ };
184
+ /** Git / GitHub integration — branch names live in config (not environment variables). */
185
+ type GitIntegrationConfig = {
186
+ /** Default branch; feature branches are created from here and PRs target this ref. */
187
+ baseBranch: string;
188
+ /**
189
+ * Branch that holds `cms/published.json` so Publish avoids committing to a protected base branch.
190
+ * When omitted, the pointer file is read and written on `baseBranch`.
191
+ */
192
+ publishedPointerBranch?: string;
193
+ };
194
+ type PublicCollectionSearchConfig = {
195
+ /** URL pattern with `:fieldName` placeholders resolved from entry fields.
196
+ * Examples: '/blog/:slug', '/items/:id', '/' (fixed path for singletons) */
197
+ urlPattern: string;
198
+ };
199
+ type SearchConfig = {
200
+ /** Collections searchable on the public site + their URL mapping.
201
+ * Omit or set to empty object = public search disabled. */
202
+ publicCollections?: Record<string, PublicCollectionSearchConfig>;
203
+ };
204
+ type Config = {
205
+ projectName: string;
206
+ contentFolder: string;
207
+ mediaFolder: string;
208
+ mediaAllowedFormats: string[];
209
+ git: GitIntegrationConfig;
210
+ collections: Record<string, Collection>;
211
+ /** Full-text search configuration. */
212
+ search?: SearchConfig;
213
+ };
214
+ /** Narrowed field types for parsers that only apply to one format. */
215
+ type NumberCollectionField = Extract<CollectionField, {
216
+ format: 'number';
217
+ }>;
218
+ type DatetimeCollectionField = Extract<CollectionField, {
219
+ format: 'datetime';
220
+ }>;
221
+ type JsonCollectionField = Extract<CollectionField, {
222
+ format: 'json';
223
+ }>;
224
+ type SlugCollectionField = Extract<CollectionField, {
225
+ format: 'slug';
226
+ }>;
227
+ type SelectCollectionField = Extract<CollectionField, {
228
+ format: 'select';
229
+ }>;
230
+ type ConditionalCollectionField = Extract<CollectionField, {
231
+ format: 'conditional';
232
+ }>;
233
+ type RichTextCollectionField = Extract<CollectionField, {
234
+ format: 'richtext';
235
+ }>;
236
+ type SelectedFile = {
237
+ type: string;
238
+ id: string;
239
+ path: string;
240
+ };
241
+ type EntryListItem = {
242
+ type: string;
243
+ /** Filename stem (last path segment without `.json`), e.g. `post-123` for `post/post-123.json`. */
244
+ id: string;
245
+ /** Full repo-relative JSON path, e.g. `cms/content/post/post-123.json`. Use with `toReferenceKey(path)` for storage keys. */
246
+ path: string;
247
+ title: string;
248
+ status: EntryStatus;
249
+ /** ISO 8601 last-modified timestamp. Populated from fs.stat in dev mode; undefined in production. */
250
+ updatedAt?: string;
251
+ };
252
+ /** A reference item stored in a reference field value. */
253
+ type ReferenceItem = {
254
+ /** The collection type (e.g. 'post', 'author'). */
255
+ type: string;
256
+ /** The entry ID (UUID or fixed ID). */
257
+ id: string;
258
+ /** Normalized reference key (e.g. 'post-abc.json'). */
259
+ path: string;
260
+ /** Display title extracted from the entry's entryTitle field. */
261
+ title: string;
262
+ };
263
+ type FileContextValues = {
264
+ selectedType: string | undefined;
265
+ selectedFile: SelectedFile | undefined;
266
+ onTypeClick: (type: string | undefined) => void;
267
+ onFileClick: (file: SelectedFile | undefined) => void;
268
+ };
269
+ /** Shape of `format: 'image'` fields after `query()` / `processEntry` resolution. */
270
+ type ResolvedImageField = {
271
+ src: string;
272
+ alt: string;
273
+ width: number | null;
274
+ height: number | null;
275
+ blurDataURL: string | null;
276
+ };
277
+ type RichTextNode = {
278
+ type: 'paragraph';
279
+ children: RichTextNode[];
280
+ } | {
281
+ type: 'blockquote';
282
+ children: RichTextNode[];
283
+ } | {
284
+ type: 'heading';
285
+ level: 1 | 2 | 3 | 4 | 5 | 6;
286
+ children: RichTextNode[];
287
+ } | {
288
+ type: 'text';
289
+ value: string;
290
+ marks?: ('bold' | 'italic' | 'underline' | 'code')[];
291
+ } | {
292
+ type: 'link';
293
+ url: string;
294
+ children: RichTextNode[];
295
+ } | {
296
+ type: 'image';
297
+ image: ResolvedImageField;
298
+ } | {
299
+ type: 'reference';
300
+ entry: unknown;
301
+ display: 'inline' | 'block';
302
+ } | {
303
+ type: 'condition';
304
+ field: string;
305
+ branches: Record<string, RichTextDocument> | RichTextDocument;
306
+ } | {
307
+ type: 'variable';
308
+ name: string;
309
+ } | {
310
+ type: 'component';
311
+ name: string;
312
+ props: Record<string, unknown>;
313
+ children?: RichTextNode[];
314
+ } | {
315
+ type: 'list';
316
+ ordered: boolean;
317
+ children: RichTextNode[];
318
+ } | {
319
+ type: 'listItem';
320
+ children: RichTextNode[];
321
+ } | {
322
+ type: 'thematicBreak';
323
+ } | {
324
+ type: 'code';
325
+ lang?: string;
326
+ value: string;
327
+ } | {
328
+ type: 'html';
329
+ value: string;
330
+ } | {
331
+ type: 'break';
332
+ };
333
+ type RichTextDocument = {
334
+ type: 'doc';
335
+ content: RichTextNode[];
336
+ };
337
+ type MediaFile = {
338
+ id: string;
339
+ /** Required for new uploads; used as default alt text when the image is referenced. */
340
+ title: string;
341
+ originalName: string;
342
+ path: string;
343
+ folder: string;
344
+ publicUrl: string;
345
+ extension: string;
346
+ width: number | null;
347
+ height: number | null;
348
+ /** True when the entry stores a blur placeholder (data URL omitted from list payloads). */
349
+ hasBlurPlaceholder: boolean;
350
+ };
351
+
352
+ export type { Collection, CollectionField, ConditionalBranchConfig, ConditionalCollectionField, ConditionalFieldConfig, Config, DatetimeCollectionField, EntryListItem, EntryStatus, FieldFormat, FileContextValues, GitIntegrationConfig, JsonCollectionField, MediaFile, NumberCollectionField, PublicCollectionSearchConfig, ReferenceFieldConfig, ReferenceItem, ResolvedImageField, RichTextCollectionField, RichTextComponentDef, RichTextComponentProp, RichTextDocument, RichTextFieldConfig, RichTextNode, RichTextToolbarConfig, SearchConfig, SelectCollectionField, SelectOption, SelectedFile, SlugCollectionField };
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}