@cancia/astro 0.5.1 → 0.7.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-FOSOWSXV.js +0 -0
- package/dist/{chunk-MCHQV6Y7.js → chunk-UMCBQXB6.js} +58 -1
- package/dist/{chunk-IIGDU5SV.js → chunk-VFMOVGMC.js} +1 -1
- package/dist/content.d.ts +74 -0
- package/dist/content.js +84 -0
- package/dist/endpoints/lists.js +5 -5
- package/dist/endpoints/schemas.js +2 -2
- package/dist/index.js +2 -2
- package/dist/schema/index.d.ts +59 -2
- package/dist/schema/index.js +7 -1
- package/dist/storage/index.js +1 -0
- package/package.json +5 -1
|
File without changes
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
isSafeHref,
|
|
2
3
|
portableTextSubsetSchema
|
|
3
4
|
} from "./chunk-BOIQNZAO.js";
|
|
4
5
|
|
|
@@ -56,6 +57,30 @@ var defineField = {
|
|
|
56
57
|
* related: f.array(f.reference({ list: "posts" }), { label: "Related" }),
|
|
57
58
|
*/
|
|
58
59
|
reference: (o) => z.string().meta({ widget: "reference", ...o }),
|
|
60
|
+
/**
|
|
61
|
+
* A link: label + href as ONE unit.
|
|
62
|
+
*
|
|
63
|
+
* A button/CTA is two values that must stay together — saving a new label
|
|
64
|
+
* against a stale href produces a broken call-to-action, so they are stored
|
|
65
|
+
* as a single object rather than two flat keys that could drift.
|
|
66
|
+
*
|
|
67
|
+
* cta: f.link({ label: "Primary CTA" }),
|
|
68
|
+
*
|
|
69
|
+
* `href` is NOT z.url(): a relative href ("/start", "#programmes") and a
|
|
70
|
+
* mailto:/tel: are all legitimate and z.url() rejects the relative forms.
|
|
71
|
+
* It IS constrained by `isSafeHref` — the SAME guard richtext link marks
|
|
72
|
+
* use — so a stored value can never carry a javascript:/data: XSS payload.
|
|
73
|
+
* Without this, the link widget would be a hole around a protection
|
|
74
|
+
* richtext already enforces.
|
|
75
|
+
*
|
|
76
|
+
* Whether to open in a new tab is derived from the href at render time
|
|
77
|
+
* (see `isExternalHref`) instead of being stored — one less thing that can
|
|
78
|
+
* fall out of sync with the URL it describes.
|
|
79
|
+
*/
|
|
80
|
+
link: (o) => z.object({
|
|
81
|
+
label: z.string(),
|
|
82
|
+
href: z.string().refine(isSafeHref, "unsafe or unsupported URL scheme")
|
|
83
|
+
}).meta({ widget: "link", ...o }),
|
|
59
84
|
/**
|
|
60
85
|
* A constrained rich-text body. Stored as a Portable-Text SUBSET array (D4):
|
|
61
86
|
* block styles normal/h2/h3/blockquote, bullet/number lists, strong/em marks,
|
|
@@ -145,11 +170,43 @@ function describeList(name, schema) {
|
|
|
145
170
|
fields
|
|
146
171
|
};
|
|
147
172
|
}
|
|
173
|
+
function parseLinkValue(raw) {
|
|
174
|
+
const safe = (href) => isSafeHref(href) ? href : "";
|
|
175
|
+
if (raw && typeof raw === "object") {
|
|
176
|
+
const o = raw;
|
|
177
|
+
return { label: String(o.label ?? ""), href: safe(String(o.href ?? "")) };
|
|
178
|
+
}
|
|
179
|
+
if (typeof raw !== "string" || raw === "") return { label: "", href: "" };
|
|
180
|
+
const trimmed = raw.trim();
|
|
181
|
+
if (trimmed.startsWith("{")) {
|
|
182
|
+
try {
|
|
183
|
+
const parsed = JSON.parse(trimmed);
|
|
184
|
+
if (parsed && typeof parsed === "object") {
|
|
185
|
+
return {
|
|
186
|
+
label: String(parsed.label ?? ""),
|
|
187
|
+
href: safe(String(parsed.href ?? ""))
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
} catch {
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return { label: raw, href: "" };
|
|
194
|
+
}
|
|
195
|
+
function serializeLinkValue(value) {
|
|
196
|
+
return JSON.stringify({ label: value.label ?? "", href: value.href ?? "" });
|
|
197
|
+
}
|
|
198
|
+
function isExternalHref(href) {
|
|
199
|
+
if (!href) return false;
|
|
200
|
+
return /^https?:\/\//i.test(href);
|
|
201
|
+
}
|
|
148
202
|
|
|
149
203
|
export {
|
|
150
204
|
z,
|
|
151
205
|
defineList,
|
|
152
206
|
defineField,
|
|
153
207
|
slugify,
|
|
154
|
-
describeList
|
|
208
|
+
describeList,
|
|
209
|
+
parseLinkValue,
|
|
210
|
+
serializeLinkValue,
|
|
211
|
+
isExternalHref
|
|
155
212
|
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/** Flat content map as returned by /api/cancia/content and kv.getAll: "key.lang" → value. */
|
|
2
|
+
type ContentMap = Record<string, string>;
|
|
3
|
+
/** A translator: `(key, fallback) => cms[`${key}.${lang}`] ?? fallback`. */
|
|
4
|
+
type Translate = (key: string, fallback: string) => string;
|
|
5
|
+
/** The value behind a `link` field: a label and where it points. */
|
|
6
|
+
interface LinkValue {
|
|
7
|
+
label: string;
|
|
8
|
+
href: string;
|
|
9
|
+
}
|
|
10
|
+
/** Resolve a link field, falling back to the values authored in the page. */
|
|
11
|
+
type TranslateLink = (key: string, fallback: LinkValue) => LinkValue;
|
|
12
|
+
interface ContentReaderOptions {
|
|
13
|
+
/** Site id (the `?site=` query param and the storage `site` column). */
|
|
14
|
+
site: string;
|
|
15
|
+
/**
|
|
16
|
+
* Build-time content API base. Default: `process.env.CANCIA_CONTENT_URL`.
|
|
17
|
+
* When set (non-empty), `getCMS()` FETCHES from
|
|
18
|
+
* `${url}/api/cancia/content?site=<site>` instead of reading the DB directly.
|
|
19
|
+
* This is how a static build on a runtime-only volume gets live content.
|
|
20
|
+
*/
|
|
21
|
+
url?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Bearer token for the fetch. Default: `process.env.CANCIA_TOKEN`. Required by
|
|
24
|
+
* a non-public site (036 fail-closed) — without it the fetch 401s and the
|
|
25
|
+
* reader falls back to the direct DB read.
|
|
26
|
+
*/
|
|
27
|
+
token?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Direct-DB fallback path. Default:
|
|
30
|
+
* `process.env.CANCIA_DB_PATH ?? "<cwd>/cancia.db"`.
|
|
31
|
+
* Ignored when a `readDb` override is supplied.
|
|
32
|
+
*/
|
|
33
|
+
dbPath?: string;
|
|
34
|
+
/** Default language for `makeT`/`get`. Default: `"en"`. */
|
|
35
|
+
lang?: string;
|
|
36
|
+
/** Injectable fetch (tests). Default: global `fetch`. */
|
|
37
|
+
fetch?: typeof fetch;
|
|
38
|
+
/**
|
|
39
|
+
* Optional DB-read override. Lets a non-sqlite project (e.g. json-file
|
|
40
|
+
* storage) supply its own fallback WITHOUT this reader importing every
|
|
41
|
+
* adapter. Default: read via `createSqliteAdapterV2({ dbPath })` (the
|
|
42
|
+
* recommended backend).
|
|
43
|
+
*/
|
|
44
|
+
readDb?: () => Promise<ContentMap>;
|
|
45
|
+
}
|
|
46
|
+
interface ContentReader {
|
|
47
|
+
/**
|
|
48
|
+
* Read all content for the site as a flat `"key.lang" → value` map.
|
|
49
|
+
* Chain: fetch (when `url` set) → direct DB read → `{}`. NEVER throws.
|
|
50
|
+
*/
|
|
51
|
+
getCMS(): Promise<ContentMap>;
|
|
52
|
+
/** Build a translator over a content map for the reader's `lang`. */
|
|
53
|
+
makeT(cms: ContentMap): Translate;
|
|
54
|
+
/**
|
|
55
|
+
* Build a link resolver over a content map. A link field stores
|
|
56
|
+
* `{label, href}` as JSON; this parses it and falls back to the values
|
|
57
|
+
* authored in the page. Never throws; drops an unsafe href.
|
|
58
|
+
*/
|
|
59
|
+
makeTLink(cms: ContentMap): TranslateLink;
|
|
60
|
+
/** Sugar: `const { t, tLink, cms } = await reader.get()` in frontmatter. */
|
|
61
|
+
get(): Promise<{
|
|
62
|
+
t: Translate;
|
|
63
|
+
tLink: TranslateLink;
|
|
64
|
+
cms: ContentMap;
|
|
65
|
+
}>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Create a content reader. Reads are transport-agnostic (network OR local file)
|
|
69
|
+
* and never throw — a static build reads content the same way whether it's a
|
|
70
|
+
* local DB, the site's own API, or a future hosted Cancia DB.
|
|
71
|
+
*/
|
|
72
|
+
declare function createContentReader(opts: ContentReaderOptions): ContentReader;
|
|
73
|
+
|
|
74
|
+
export { type ContentMap, type ContentReader, type ContentReaderOptions, type LinkValue, type Translate, type TranslateLink, createContentReader };
|
package/dist/content.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import "./chunk-FOSOWSXV.js";
|
|
2
|
+
import "./chunk-CJDIVWO3.js";
|
|
3
|
+
import {
|
|
4
|
+
createSqliteAdapterV2
|
|
5
|
+
} from "./chunk-GNWD7EL2.js";
|
|
6
|
+
import "./chunk-U7V53JX7.js";
|
|
7
|
+
import "./chunk-L2VKQJPY.js";
|
|
8
|
+
import "./chunk-7IA5B5CF.js";
|
|
9
|
+
|
|
10
|
+
// src/content.ts
|
|
11
|
+
function isSafeHref(href) {
|
|
12
|
+
const trimmed = href.trim();
|
|
13
|
+
if (trimmed === "") return false;
|
|
14
|
+
if (/^(https?:|mailto:|tel:)/i.test(trimmed)) return true;
|
|
15
|
+
const schemeMatch = /^([a-z][a-z0-9+.-]*):/i.exec(trimmed);
|
|
16
|
+
if (schemeMatch) {
|
|
17
|
+
const firstSep = trimmed.search(/[/?#]/);
|
|
18
|
+
if (firstSep === -1 || schemeMatch[1].length < firstSep) return false;
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
function parseLink(raw, fallback) {
|
|
23
|
+
if (!raw) return fallback;
|
|
24
|
+
const trimmed = raw.trim();
|
|
25
|
+
if (trimmed.startsWith("{")) {
|
|
26
|
+
try {
|
|
27
|
+
const p = JSON.parse(trimmed);
|
|
28
|
+
if (p && typeof p === "object") {
|
|
29
|
+
const href = String(p.href ?? "");
|
|
30
|
+
return {
|
|
31
|
+
label: String(p.label ?? "") || fallback.label,
|
|
32
|
+
href: href && isSafeHref(href) ? href : fallback.href
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { label: raw, href: fallback.href };
|
|
39
|
+
}
|
|
40
|
+
function createContentReader(opts) {
|
|
41
|
+
const site = opts.site;
|
|
42
|
+
const lang = opts.lang ?? "en";
|
|
43
|
+
const url = opts.url ?? process.env.CANCIA_CONTENT_URL;
|
|
44
|
+
const token = opts.token ?? process.env.CANCIA_TOKEN;
|
|
45
|
+
const fetchImpl = opts.fetch ?? globalThis.fetch;
|
|
46
|
+
function readDb() {
|
|
47
|
+
if (opts.readDb) return opts.readDb();
|
|
48
|
+
const dbPath = opts.dbPath ?? process.env.CANCIA_DB_PATH ?? `${process.cwd()}/cancia.db`;
|
|
49
|
+
return createSqliteAdapterV2({ dbPath }).kv.getAll(site);
|
|
50
|
+
}
|
|
51
|
+
async function fetchFromApi(base) {
|
|
52
|
+
const endpoint = `${base.replace(/\/+$/, "")}/api/cancia/content?site=${encodeURIComponent(site)}`;
|
|
53
|
+
const res = await fetchImpl(endpoint, {
|
|
54
|
+
headers: token ? { Authorization: `Bearer ${token}` } : {}
|
|
55
|
+
});
|
|
56
|
+
if (!res.ok) throw new Error(`Content fetch failed: ${res.status}`);
|
|
57
|
+
return await res.json();
|
|
58
|
+
}
|
|
59
|
+
async function getCMS() {
|
|
60
|
+
try {
|
|
61
|
+
return url ? await fetchFromApi(url) : await readDb();
|
|
62
|
+
} catch {
|
|
63
|
+
try {
|
|
64
|
+
return await readDb();
|
|
65
|
+
} catch {
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function makeT(cms) {
|
|
71
|
+
return (key, fallback) => cms[`${key}.${lang}`] ?? fallback;
|
|
72
|
+
}
|
|
73
|
+
function makeTLink(cms) {
|
|
74
|
+
return (key, fallback) => parseLink(cms[`${key}.${lang}`], fallback);
|
|
75
|
+
}
|
|
76
|
+
async function get() {
|
|
77
|
+
const cms = await getCMS();
|
|
78
|
+
return { t: makeT(cms), tLink: makeTLink(cms), cms };
|
|
79
|
+
}
|
|
80
|
+
return { getCMS, makeT, makeTLink, get };
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
createContentReader
|
|
84
|
+
};
|
package/dist/endpoints/lists.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
makeListsRoutes
|
|
3
|
-
} from "../chunk-22DJVJBR.js";
|
|
4
|
-
import "../chunk-NG5GJME5.js";
|
|
5
|
-
import "../chunk-7IA5B5CF.js";
|
|
6
1
|
import {
|
|
7
2
|
extractRoute,
|
|
8
3
|
invalidateOnSave
|
|
9
4
|
} from "../chunk-VGRG5DN7.js";
|
|
5
|
+
import {
|
|
6
|
+
makeListsRoutes
|
|
7
|
+
} from "../chunk-22DJVJBR.js";
|
|
8
|
+
import "../chunk-NG5GJME5.js";
|
|
10
9
|
import "../chunk-X6ZFFGIA.js";
|
|
10
|
+
import "../chunk-7IA5B5CF.js";
|
|
11
11
|
|
|
12
12
|
// src/endpoints/lists.ts
|
|
13
13
|
import { getCanciaRuntime } from "virtual:cancia/runtime";
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-22DJVJBR.js";
|
|
7
7
|
import {
|
|
8
8
|
makeSchemasRoute
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-VFMOVGMC.js";
|
|
10
10
|
import "./chunk-NG5GJME5.js";
|
|
11
11
|
import {
|
|
12
12
|
makeLocalUploadHandler,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
defineList,
|
|
21
21
|
describeList,
|
|
22
22
|
z
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-UMCBQXB6.js";
|
|
24
24
|
import {
|
|
25
25
|
canciaLoader
|
|
26
26
|
} from "./chunk-UR5WC3RA.js";
|
package/dist/schema/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export { P as PT_DECORATORS, a as PT_LIST_ITEMS, b as PT_STYLES, c as PortableTe
|
|
|
16
16
|
* z.boolean() → "checkbox"
|
|
17
17
|
* z.enum([...]) → "select"
|
|
18
18
|
*/
|
|
19
|
-
type FieldWidget = "text" | "textarea" | "url" | "email" | "datetime" | "number" | "checkbox" | "select" | "image" | "slug" | "array" | "object" | "reference" | "richtext";
|
|
19
|
+
type FieldWidget = "text" | "textarea" | "url" | "email" | "datetime" | "number" | "checkbox" | "select" | "image" | "slug" | "array" | "object" | "reference" | "richtext" | "link";
|
|
20
20
|
/**
|
|
21
21
|
* Fields common to every widget's metadata. All optional.
|
|
22
22
|
*/
|
|
@@ -61,6 +61,8 @@ type FieldMeta = (FieldMetaBase & {
|
|
|
61
61
|
list: string;
|
|
62
62
|
}) | (FieldMetaBase & {
|
|
63
63
|
widget: "richtext";
|
|
64
|
+
}) | (FieldMetaBase & {
|
|
65
|
+
widget: "link";
|
|
64
66
|
});
|
|
65
67
|
interface ListSchemaOptions<TFields extends Record<string, z.ZodTypeAny>> {
|
|
66
68
|
/** Display label for the list (e.g. "Blog Posts"). */
|
|
@@ -194,6 +196,30 @@ declare const defineField: {
|
|
|
194
196
|
reference: (o: FieldMetaBase & {
|
|
195
197
|
list: string;
|
|
196
198
|
}) => z.ZodString;
|
|
199
|
+
/**
|
|
200
|
+
* A link: label + href as ONE unit.
|
|
201
|
+
*
|
|
202
|
+
* A button/CTA is two values that must stay together — saving a new label
|
|
203
|
+
* against a stale href produces a broken call-to-action, so they are stored
|
|
204
|
+
* as a single object rather than two flat keys that could drift.
|
|
205
|
+
*
|
|
206
|
+
* cta: f.link({ label: "Primary CTA" }),
|
|
207
|
+
*
|
|
208
|
+
* `href` is NOT z.url(): a relative href ("/start", "#programmes") and a
|
|
209
|
+
* mailto:/tel: are all legitimate and z.url() rejects the relative forms.
|
|
210
|
+
* It IS constrained by `isSafeHref` — the SAME guard richtext link marks
|
|
211
|
+
* use — so a stored value can never carry a javascript:/data: XSS payload.
|
|
212
|
+
* Without this, the link widget would be a hole around a protection
|
|
213
|
+
* richtext already enforces.
|
|
214
|
+
*
|
|
215
|
+
* Whether to open in a new tab is derived from the href at render time
|
|
216
|
+
* (see `isExternalHref`) instead of being stored — one less thing that can
|
|
217
|
+
* fall out of sync with the URL it describes.
|
|
218
|
+
*/
|
|
219
|
+
link: (o?: FieldMetaBase) => z.ZodObject<{
|
|
220
|
+
label: z.ZodString;
|
|
221
|
+
href: z.ZodString;
|
|
222
|
+
}, z.core.$strip>;
|
|
197
223
|
/**
|
|
198
224
|
* A constrained rich-text body. Stored as a Portable-Text SUBSET array (D4):
|
|
199
225
|
* block styles normal/h2/h3/blockquote, bullet/number lists, strong/em marks,
|
|
@@ -257,7 +283,38 @@ interface ListDescription {
|
|
|
257
283
|
*/
|
|
258
284
|
declare function slugify(input: string): string;
|
|
259
285
|
declare function describeList(name: string, schema: ListSchema): ListDescription;
|
|
286
|
+
/** The value behind a `link` widget: a label and where it points. */
|
|
287
|
+
interface LinkValue {
|
|
288
|
+
label: string;
|
|
289
|
+
href: string;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Parse a stored link value. NEVER throws.
|
|
293
|
+
*
|
|
294
|
+
* The KV surface stores every value as a string, so a link round-trips as
|
|
295
|
+
* JSON. Three cases must all degrade gracefully rather than break a render:
|
|
296
|
+
*
|
|
297
|
+
* - proper JSON object → used as-is (missing halves coerced to "")
|
|
298
|
+
* - a bare string → treated as the LABEL with an empty href. This is
|
|
299
|
+
* the migration path for a field that used to be
|
|
300
|
+
* `text`, and for a fallback authored in markup.
|
|
301
|
+
* - empty / malformed → `{ label: "", href: "" }`
|
|
302
|
+
*
|
|
303
|
+
* A content read must never throw (same rule as createContentReader).
|
|
304
|
+
*/
|
|
305
|
+
declare function parseLinkValue(raw: unknown): LinkValue;
|
|
306
|
+
/** Serialize a link value for storage. The inverse of `parseLinkValue`. */
|
|
307
|
+
declare function serializeLinkValue(value: LinkValue): string;
|
|
308
|
+
/**
|
|
309
|
+
* Should this href open in a new tab? Derived, never stored.
|
|
310
|
+
*
|
|
311
|
+
* External = has a scheme+host that isn't the current origin. Relative hrefs
|
|
312
|
+
* ("/start", "#programmes") and mailto:/tel: are NOT external — mailto/tel
|
|
313
|
+
* hand off to another app, and forcing target=_blank on them leaves a blank
|
|
314
|
+
* tab behind.
|
|
315
|
+
*/
|
|
316
|
+
declare function isExternalHref(href: string): boolean;
|
|
260
317
|
/** Map of list name → schema. What users export from src/cms/schemas.ts. */
|
|
261
318
|
type SchemasModule = Record<string, ListSchema>;
|
|
262
319
|
|
|
263
|
-
export { type FieldDescription, type FieldMeta, type FieldMetaBase, type FieldWidget, type ListDescription, type ListSchema, type ListSchemaOptions, type SchemasModule, defineField, defineList, describeList, slugify };
|
|
320
|
+
export { type FieldDescription, type FieldMeta, type FieldMetaBase, type FieldWidget, type LinkValue, type ListDescription, type ListSchema, type ListSchemaOptions, type SchemasModule, defineField, defineList, describeList, isExternalHref, parseLinkValue, serializeLinkValue, slugify };
|
package/dist/schema/index.js
CHANGED
|
@@ -2,9 +2,12 @@ import {
|
|
|
2
2
|
defineField,
|
|
3
3
|
defineList,
|
|
4
4
|
describeList,
|
|
5
|
+
isExternalHref,
|
|
6
|
+
parseLinkValue,
|
|
7
|
+
serializeLinkValue,
|
|
5
8
|
slugify,
|
|
6
9
|
z
|
|
7
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-UMCBQXB6.js";
|
|
8
11
|
import {
|
|
9
12
|
PT_DECORATORS,
|
|
10
13
|
PT_LIST_ITEMS,
|
|
@@ -20,9 +23,12 @@ export {
|
|
|
20
23
|
defineField,
|
|
21
24
|
defineList,
|
|
22
25
|
describeList,
|
|
26
|
+
isExternalHref,
|
|
23
27
|
isSafeHref,
|
|
28
|
+
parseLinkValue,
|
|
24
29
|
portableTextSubsetSchema,
|
|
25
30
|
ptBlockSchema,
|
|
31
|
+
serializeLinkValue,
|
|
26
32
|
slugify,
|
|
27
33
|
z
|
|
28
34
|
};
|
package/dist/storage/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cancia/astro",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Astro integration for Cancia CMS — inline editing with zero separate server",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
"types": "./dist/cache.d.ts",
|
|
33
33
|
"import": "./dist/cache.js"
|
|
34
34
|
},
|
|
35
|
+
"./content": {
|
|
36
|
+
"types": "./dist/content.d.ts",
|
|
37
|
+
"import": "./dist/content.js"
|
|
38
|
+
},
|
|
35
39
|
"./richtext": {
|
|
36
40
|
"types": "./dist/richtext/index.d.ts",
|
|
37
41
|
"import": "./dist/richtext/index.js"
|