@airdraft/content 0.1.3 → 0.1.5
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/CHANGELOG.md +18 -0
- package/README.md +143 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.1.5](https://github.com/aevrHQ/airdraft/compare/content@v0.1.4...content@v0.1.5) (2026-05-23)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **auth:** implement server-side silent token refresh and extend refresh token TTL to 30 days ([2418571](https://github.com/aevrHQ/airdraft/commit/2418571ec2aa037995dc9b5eb94fb06f79c949b8))
|
|
11
|
+
* **EntryDetail:** enhance component to support injected props and dynamic field resolution ([a65f19c](https://github.com/aevrHQ/airdraft/commit/a65f19c57c0f85ba6deb5d64b59592a82d614258))
|
|
12
|
+
* **README:** add documentation for @airdraft/content functions and usage examples ([b43ab62](https://github.com/aevrHQ/airdraft/commit/b43ab621da781056a32de816547d2b1ba7421ed3))
|
|
13
|
+
|
|
14
|
+
### [0.1.4](https://github.com/aevrHQ/airdraft/compare/content@v0.1.3...content@v0.1.4) (2026-05-23)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* **build:** bump react-content peer dependencies ([9c33815](https://github.com/aevrHQ/airdraft/commit/9c338158eca40c418f5ad37e829b0a2f213a2e33))
|
|
20
|
+
* move @airdraft/core to peerDependencies in all consumer-facing packages ([f7653ff](https://github.com/aevrHQ/airdraft/commit/f7653ffd7109cbe76f09df8766a70de1b24afdba))
|
|
21
|
+
* **react-content:** entryCard children injection and sub-component auto-read ([a57cc48](https://github.com/aevrHQ/airdraft/commit/a57cc483b96986d5825e1c6d28a66c400bd57972))
|
|
22
|
+
|
|
5
23
|
### 0.1.3 (2026-05-23)
|
|
6
24
|
|
|
7
25
|
|
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# @airdraft/content
|
|
2
|
+
|
|
3
|
+
Framework-agnostic pure functions for resolving and parsing Airdraft CMS content. No React required — safe to use in server actions, API routes, `generateMetadata`, middleware, or any non-React context.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @airdraft/content
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Media / Image
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import {
|
|
15
|
+
resolveMediaUrl,
|
|
16
|
+
resolveMediaUrls,
|
|
17
|
+
resolveImageDimensions,
|
|
18
|
+
} from '@airdraft/content'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### `resolveMediaUrl(fieldName, data)`
|
|
22
|
+
|
|
23
|
+
Resolves a single `media` or `image` field to a URL string.
|
|
24
|
+
|
|
25
|
+
Resolution chain (first truthy wins):
|
|
26
|
+
1. `data["{field}_media"].url` — managed media object URL
|
|
27
|
+
2. `data["{field}_url"]` — raw URL stored alongside the key
|
|
28
|
+
3. `data["{field}"]` as string — raw storage key, prefixed with `/` if relative
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
const url = resolveMediaUrl('cover', entry.data)
|
|
32
|
+
// → 'https://cdn.example.com/covers/my-post.jpg' | undefined
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Useful for `<meta property="og:image">`, `next/image` `src`, or any place you need the URL value rather than a rendered element.
|
|
36
|
+
|
|
37
|
+
### `resolveMediaUrls(fieldName, data)`
|
|
38
|
+
|
|
39
|
+
Resolves a `media` field with `multiple: true` to an array of URLs.
|
|
40
|
+
|
|
41
|
+
Resolution chain:
|
|
42
|
+
1. `data["{field}_medias"]` — injected `MediaItem[]` → extracts `.url` from each
|
|
43
|
+
2. `data["{field}_urls"]` — injected `string[]`
|
|
44
|
+
3. `data["{field}"]` — raw `string[]` or JSON-encoded `string[]`
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const urls = resolveMediaUrls('gallery', entry.data)
|
|
48
|
+
// → ['https://...', 'https://...']
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### `resolveImageDimensions(fieldName, data)`
|
|
52
|
+
|
|
53
|
+
Reads `width` and `height` from the `{field}_media` sidecar object. Returns `undefined` when the media object is absent or has no dimension data.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
const dims = resolveImageDimensions('cover', entry.data)
|
|
57
|
+
// → { width: 1200, height: 630 } | undefined
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Combine with `resolveMediaUrl` to pass explicit dimensions to `next/image` and avoid layout shift:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
const url = resolveMediaUrl('cover', entry.data)
|
|
64
|
+
const dims = resolveImageDimensions('cover', entry.data)
|
|
65
|
+
|
|
66
|
+
// In a Next.js page / generateMetadata:
|
|
67
|
+
return {
|
|
68
|
+
openGraph: { images: [{ url, ...dims }] },
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Or in a component:
|
|
72
|
+
<Image src={url} alt="cover" width={dims?.width ?? 800} height={dims?.height ?? 450} />
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### `resolveImageUrl` (alias)
|
|
76
|
+
|
|
77
|
+
Legacy alias for `resolveMediaUrl`. Prefer `resolveMediaUrl` for new `media`-typed fields.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Body / Rich-text
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import { parseMarkdown, parseText } from '@airdraft/content'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### `parseMarkdown(text)`
|
|
88
|
+
|
|
89
|
+
Parses a Markdown string to an HTML string via `marked`. Safe for use with `dangerouslySetInnerHTML` — content is CMS-authored, not user-supplied.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
const html = parseMarkdown(entry.data.body)
|
|
93
|
+
// → '<h1>Hello</h1><p>World</p>'
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### `parseText(text)`
|
|
97
|
+
|
|
98
|
+
Splits a plain `text` field into paragraphs (split on `\n\n`). Returns `string[]`. Useful when you want to render paragraphs manually without dangerouslySetInnerHTML.
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const paragraphs = parseText(entry.data.excerpt)
|
|
102
|
+
// → ['First paragraph.', 'Second paragraph.']
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Relations
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { resolveRelation, resolveRelations } from '@airdraft/content'
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### `resolveRelation(fieldName, data)`
|
|
114
|
+
|
|
115
|
+
Resolves the display label for a single `relation` field. Handles both expanded entry objects (returned when `expand=true`) and raw slug strings.
|
|
116
|
+
|
|
117
|
+
Label priority: `name` → `title` → `label` → `slug`.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
const label = resolveRelation('author', entry.data)
|
|
121
|
+
// → 'Jane Doe' | 'jane-doe' | null
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### `resolveRelations(fieldName, data)`
|
|
125
|
+
|
|
126
|
+
Same as `resolveRelation` but for `relations` (multi-relation) fields. Returns `string[]`.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
const labels = resolveRelations('authors', entry.data)
|
|
130
|
+
// → ['Jane Doe', 'John Smith']
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Notes
|
|
136
|
+
|
|
137
|
+
- All functions are synchronous and have no side effects.
|
|
138
|
+
- `resolveImageUrl` / `resolveMediaUrl` / `resolveMediaUrls` are used internally by `@airdraft/react-content` field components. Call them directly when you need the resolved value in logic rather than in JSX.
|
|
139
|
+
- `parseMarkdown` uses `marked` under the hood. To customise rendering (syntax highlighting, custom link targets, etc.) use the `render` prop on `<BodyField>` from `@airdraft/react-content` instead.
|
|
140
|
+
|
|
141
|
+
## Changelog
|
|
142
|
+
|
|
143
|
+
See [CHANGELOG.md](./CHANGELOG.md).
|
package/package.json
CHANGED