@cancia/astro 0.7.0 → 0.9.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-L2VKQJPY.js → chunk-2NVZWZPE.js} +62 -33
- package/dist/{chunk-22DJVJBR.js → chunk-DIV2FFYX.js} +1 -1
- package/dist/{chunk-UR5WC3RA.js → chunk-GBTFXQEA.js} +20 -6
- package/dist/chunk-GJIX7MWC.js +55 -0
- package/dist/{chunk-VFMOVGMC.js → chunk-HQIGNRIU.js} +2 -2
- package/dist/{chunk-BOIQNZAO.js → chunk-KHCFVVYV.js} +53 -1
- package/dist/{chunk-AGNPUTKS.js → chunk-LJSSPOSW.js} +2 -2
- package/dist/{chunk-GNWD7EL2.js → chunk-MXVOJRAM.js} +22 -39
- package/dist/{chunk-NG5GJME5.js → chunk-VL6FO446.js} +8 -1
- package/dist/{chunk-UMCBQXB6.js → chunk-WVHTCFE6.js} +17 -1
- package/dist/content.d.ts +24 -2
- package/dist/content.js +47 -4
- package/dist/endpoints/auth.js +7 -48
- package/dist/endpoints/lists.js +2 -2
- package/dist/endpoints/schemas.js +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +285 -71
- package/dist/loader/index.d.ts +24 -0
- package/dist/loader/index.js +4 -2
- package/dist/{portable-text-BikSqS9T.d.ts → portable-text-D74aIuHn.d.ts} +25 -1
- package/dist/richtext/CanciaRichRegion.astro +57 -0
- package/dist/richtext/index.d.ts +2 -2
- package/dist/richtext/index.js +7 -3
- package/dist/runtime.js +3 -3
- package/dist/schema/index.d.ts +47 -2
- package/dist/schema/index.js +9 -3
- package/dist/schema/loader.d.ts +23 -0
- package/dist/schema/loader.js +12 -0
- package/dist/storage/index.js +2 -2
- package/dist/transform/text-helper.d.ts +47 -0
- package/dist/transform/text-helper.js +64 -0
- package/package.json +10 -4
package/dist/richtext/index.js
CHANGED
|
@@ -3,9 +3,11 @@ import {
|
|
|
3
3
|
PT_LIST_ITEMS,
|
|
4
4
|
PT_STYLES,
|
|
5
5
|
isSafeHref,
|
|
6
|
+
parseRichValue,
|
|
6
7
|
portableTextSubsetSchema,
|
|
7
|
-
ptBlockSchema
|
|
8
|
-
|
|
8
|
+
ptBlockSchema,
|
|
9
|
+
serializeRichValue
|
|
10
|
+
} from "../chunk-KHCFVVYV.js";
|
|
9
11
|
|
|
10
12
|
// src/richtext/markdown.ts
|
|
11
13
|
function keyGen(prefix) {
|
|
@@ -134,9 +136,11 @@ export {
|
|
|
134
136
|
PT_STYLES,
|
|
135
137
|
blockToRow,
|
|
136
138
|
isSafeHref,
|
|
139
|
+
parseRichValue,
|
|
137
140
|
portableTextSubsetSchema,
|
|
138
141
|
portableTextToRows,
|
|
139
142
|
ptBlockSchema,
|
|
140
143
|
rowToBlock,
|
|
141
|
-
rowsToPortableText
|
|
144
|
+
rowsToPortableText,
|
|
145
|
+
serializeRichValue
|
|
142
146
|
};
|
package/dist/runtime.js
CHANGED
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
getCanciaRuntime,
|
|
4
4
|
setBakedConfig,
|
|
5
5
|
setCanciaRuntime
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-LJSSPOSW.js";
|
|
7
7
|
import "./chunk-5IPHDIC6.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-MXVOJRAM.js";
|
|
9
9
|
import "./chunk-U7V53JX7.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-2NVZWZPE.js";
|
|
11
11
|
import "./chunk-7IA5B5CF.js";
|
|
12
12
|
export {
|
|
13
13
|
__resetRuntimeForTests,
|
package/dist/schema/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export { z } from 'zod';
|
|
3
|
-
export { P as PT_DECORATORS, a as PT_LIST_ITEMS, b as PT_STYLES, c as PortableTextValue, d as PtBlock, e as PtDecorator, f as PtLinkMarkDef, g as PtListItem, h as PtSpan, i as PtStyle, j as isSafeHref, p as
|
|
3
|
+
export { P as PT_DECORATORS, a as PT_LIST_ITEMS, b as PT_STYLES, c as PortableTextValue, d as PtBlock, e as PtDecorator, f as PtLinkMarkDef, g as PtListItem, h as PtSpan, i as PtStyle, j as isSafeHref, p as parseRichValue, k as portableTextSubsetSchema, l as ptBlockSchema, s as serializeRichValue } from '../portable-text-D74aIuHn.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Widget hint the modal form uses to pick an input element. The Zod type
|
|
@@ -82,6 +82,21 @@ interface ListSchemaOptions<TFields extends Record<string, z.ZodTypeAny>> {
|
|
|
82
82
|
* Defaults to the entry ID. The server validates slug uniqueness on save.
|
|
83
83
|
*/
|
|
84
84
|
slugField?: keyof TFields & string;
|
|
85
|
+
/**
|
|
86
|
+
* Field name holding the entry's draft flag. When set, `canciaLoader`
|
|
87
|
+
* omits entries whose value is truthy from the content collection, so a
|
|
88
|
+
* draft never reaches the built site.
|
|
89
|
+
*
|
|
90
|
+
* The field MUST be a boolean with a default (`defineField.draft()` gives
|
|
91
|
+
* you exactly that) — an `undefined` draft flag reads as published, which
|
|
92
|
+
* is the safe direction for the pre-existing entries of a list that adds
|
|
93
|
+
* `draftField` later.
|
|
94
|
+
*
|
|
95
|
+
* Draft is deliberately per-list opt-in rather than an implicit field on
|
|
96
|
+
* every list: a list of office locations or nav links has no meaningful
|
|
97
|
+
* draft state, and a phantom "Draft" checkbox on every form is noise.
|
|
98
|
+
*/
|
|
99
|
+
draftField?: keyof TFields & string;
|
|
85
100
|
/** Field definitions. */
|
|
86
101
|
fields: TFields;
|
|
87
102
|
}
|
|
@@ -91,10 +106,26 @@ interface ListSchema<TFields extends Record<string, z.ZodTypeAny> = Record<strin
|
|
|
91
106
|
titleField: string;
|
|
92
107
|
bodyField: string | undefined;
|
|
93
108
|
slugField: string | undefined;
|
|
109
|
+
draftField: string | undefined;
|
|
94
110
|
fields: TFields;
|
|
95
111
|
/** Zod object schema combining all fields, for one-shot validation. */
|
|
96
112
|
validator: z.ZodObject<TFields>;
|
|
97
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* True when `entry.data` is a draft under `schema.draftField`.
|
|
116
|
+
*
|
|
117
|
+
* The single source of truth for "is this entry a draft" — the loader, the
|
|
118
|
+
* toolbar preview rows and any user-side filter all call THIS, so a draft is
|
|
119
|
+
* decided identically everywhere. Vite-free and dependency-free by design.
|
|
120
|
+
*
|
|
121
|
+
* Reads as published (`false`) when the list declares no draftField, when the
|
|
122
|
+
* field is absent, or when it is `undefined` — every ambiguous case resolves
|
|
123
|
+
* to "published", matching the field's own default and keeping entries that
|
|
124
|
+
* predate the draftField visible.
|
|
125
|
+
*/
|
|
126
|
+
declare function isDraft(schema: {
|
|
127
|
+
draftField?: string;
|
|
128
|
+
}, data: Record<string, unknown>): boolean;
|
|
98
129
|
declare function defineList<TFields extends Record<string, z.ZodTypeAny>>(opts: ListSchemaOptions<TFields>): ListSchema<TFields>;
|
|
99
130
|
/**
|
|
100
131
|
* One field as seen by the modal form. Plain JSON, no Zod refs.
|
|
@@ -154,6 +185,15 @@ declare const defineField: {
|
|
|
154
185
|
email: (o?: PlainFieldOptions) => z.ZodString;
|
|
155
186
|
datetime: (o?: PlainFieldOptions) => z.ZodString;
|
|
156
187
|
checkbox: (o?: PlainFieldOptions) => z.ZodBoolean;
|
|
188
|
+
/**
|
|
189
|
+
* The draft flag for a list's `draftField`. A checkbox that DEFAULTS to
|
|
190
|
+
* false, which is what makes it safe to add to an existing list: every
|
|
191
|
+
* stored entry that predates the field validates and reads as published
|
|
192
|
+
* rather than vanishing from the built site.
|
|
193
|
+
*
|
|
194
|
+
* Label defaults to "Draft" so the affordance reads the same on every list.
|
|
195
|
+
*/
|
|
196
|
+
draft: (o?: PlainFieldOptions) => z.ZodDefault<z.ZodBoolean>;
|
|
157
197
|
number: (o?: PlainFieldOptions & {
|
|
158
198
|
min?: number;
|
|
159
199
|
max?: number;
|
|
@@ -266,6 +306,11 @@ interface ListDescription {
|
|
|
266
306
|
titleField: string;
|
|
267
307
|
bodyField?: string;
|
|
268
308
|
slugField?: string;
|
|
309
|
+
/**
|
|
310
|
+
* Field holding the draft flag, when the list opts in. The toolbar uses it
|
|
311
|
+
* to badge unpublished rows; the loader uses it to omit them from the build.
|
|
312
|
+
*/
|
|
313
|
+
draftField?: string;
|
|
269
314
|
fields: FieldDescription[];
|
|
270
315
|
}
|
|
271
316
|
/**
|
|
@@ -317,4 +362,4 @@ declare function isExternalHref(href: string): boolean;
|
|
|
317
362
|
/** Map of list name → schema. What users export from src/cms/schemas.ts. */
|
|
318
363
|
type SchemasModule = Record<string, ListSchema>;
|
|
319
364
|
|
|
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 };
|
|
365
|
+
export { type FieldDescription, type FieldMeta, type FieldMetaBase, type FieldWidget, type LinkValue, type ListDescription, type ListSchema, type ListSchemaOptions, type SchemasModule, defineField, defineList, describeList, isDraft, isExternalHref, parseLinkValue, serializeLinkValue, slugify };
|
package/dist/schema/index.js
CHANGED
|
@@ -2,20 +2,23 @@ import {
|
|
|
2
2
|
defineField,
|
|
3
3
|
defineList,
|
|
4
4
|
describeList,
|
|
5
|
+
isDraft,
|
|
5
6
|
isExternalHref,
|
|
6
7
|
parseLinkValue,
|
|
7
8
|
serializeLinkValue,
|
|
8
9
|
slugify,
|
|
9
10
|
z
|
|
10
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-WVHTCFE6.js";
|
|
11
12
|
import {
|
|
12
13
|
PT_DECORATORS,
|
|
13
14
|
PT_LIST_ITEMS,
|
|
14
15
|
PT_STYLES,
|
|
15
16
|
isSafeHref,
|
|
17
|
+
parseRichValue,
|
|
16
18
|
portableTextSubsetSchema,
|
|
17
|
-
ptBlockSchema
|
|
18
|
-
|
|
19
|
+
ptBlockSchema,
|
|
20
|
+
serializeRichValue
|
|
21
|
+
} from "../chunk-KHCFVVYV.js";
|
|
19
22
|
export {
|
|
20
23
|
PT_DECORATORS,
|
|
21
24
|
PT_LIST_ITEMS,
|
|
@@ -23,12 +26,15 @@ export {
|
|
|
23
26
|
defineField,
|
|
24
27
|
defineList,
|
|
25
28
|
describeList,
|
|
29
|
+
isDraft,
|
|
26
30
|
isExternalHref,
|
|
27
31
|
isSafeHref,
|
|
28
32
|
parseLinkValue,
|
|
33
|
+
parseRichValue,
|
|
29
34
|
portableTextSubsetSchema,
|
|
30
35
|
ptBlockSchema,
|
|
31
36
|
serializeLinkValue,
|
|
37
|
+
serializeRichValue,
|
|
32
38
|
slugify,
|
|
33
39
|
z
|
|
34
40
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ListSchema, SchemasModule } from './index.js';
|
|
2
|
+
import 'zod';
|
|
3
|
+
import '../portable-text-D74aIuHn.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the absolute path to the user's schemas.ts. Returns null if no
|
|
7
|
+
* file exists at the expected location.
|
|
8
|
+
*/
|
|
9
|
+
declare function resolveSchemasPath(projectRoot: string, overridePath?: string): string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Load (and cache) the user's schemas module. Returns an empty map if no
|
|
12
|
+
* schemas.ts exists — the inline editor still works for KV edits without
|
|
13
|
+
* any lists defined.
|
|
14
|
+
*/
|
|
15
|
+
declare function loadSchemas(projectRoot: string, overridePath?: string): Promise<SchemasModule>;
|
|
16
|
+
/**
|
|
17
|
+
* Get a single list schema, or null if it doesn't exist.
|
|
18
|
+
*/
|
|
19
|
+
declare function loadListSchema(projectRoot: string, listName: string, overridePath?: string): Promise<ListSchema | null>;
|
|
20
|
+
/** For tests — drop the in-memory cache. */
|
|
21
|
+
declare function clearSchemaCache(): void;
|
|
22
|
+
|
|
23
|
+
export { clearSchemaCache, loadListSchema, loadSchemas, resolveSchemasPath };
|
package/dist/storage/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
closeSqliteAdapterV2,
|
|
7
7
|
createGitBackedAdapter,
|
|
8
8
|
createSqliteAdapterV2
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-MXVOJRAM.js";
|
|
10
10
|
import {
|
|
11
11
|
createGitHubClient
|
|
12
12
|
} from "../chunk-U7V53JX7.js";
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
createJsonFileAdapter,
|
|
16
16
|
createJsonFileAdapterV2,
|
|
17
17
|
hashRev
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-2NVZWZPE.js";
|
|
19
19
|
import {
|
|
20
20
|
RevConflictError
|
|
21
21
|
} from "../chunk-7IA5B5CF.js";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ContentMap } from '../content.js';
|
|
2
|
+
|
|
3
|
+
/** Test/dev hook — a content change must not be served from a stale cache. */
|
|
4
|
+
declare function clearTextCache(): void;
|
|
5
|
+
interface TextHelperConfig {
|
|
6
|
+
site: string;
|
|
7
|
+
lang: string;
|
|
8
|
+
/** Reads the whole content map. Injected so this module imports no adapter. */
|
|
9
|
+
read: () => Promise<ContentMap>;
|
|
10
|
+
}
|
|
11
|
+
declare function configureTextHelper(next: TextHelperConfig): void;
|
|
12
|
+
/**
|
|
13
|
+
* Load the content map. Awaited once per page, in frontmatter.
|
|
14
|
+
*
|
|
15
|
+
* NEVER throws or rejects. A content read must not break a build — the same rule
|
|
16
|
+
* createContentReader holds — so every failure resolves to an empty map, and
|
|
17
|
+
* every call site then falls back to the text authored in the page. A site whose
|
|
18
|
+
* database is unreachable renders exactly as its source says.
|
|
19
|
+
*/
|
|
20
|
+
declare function __canciaContent(): Promise<ContentMap>;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve one annotated element's text.
|
|
23
|
+
*
|
|
24
|
+
* `??` is load-bearing, not style: a stored "" means DELIBERATELY EMPTY (the
|
|
25
|
+
* client removed this text on purpose) and must NOT fall through to the authored
|
|
26
|
+
* fallback, or deleted content reappears on every build.
|
|
27
|
+
*/
|
|
28
|
+
declare function __canciaText(cms: ContentMap, key: string, fallback: string): string;
|
|
29
|
+
interface LinkValue {
|
|
30
|
+
label: string;
|
|
31
|
+
href: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Resolve a link field — label AND href from one stored value.
|
|
35
|
+
*
|
|
36
|
+
* A link stores `{label, href}` as JSON so a new label can never be saved
|
|
37
|
+
* against a stale href. Both halves have an authored fallback (the text, and the
|
|
38
|
+
* `href=` already in the markup), which is why a link needs no t() call either.
|
|
39
|
+
*
|
|
40
|
+
* An unsafe href is DROPPED on read, falling back to the authored one — the same
|
|
41
|
+
* rule parseLinkValue holds, and for the same reason: validation guards the
|
|
42
|
+
* write path, but a value can reach a renderer from an older row or a
|
|
43
|
+
* hand-edited DB, so the read is where the guarantee has to hold.
|
|
44
|
+
*/
|
|
45
|
+
declare function __canciaLink(cms: ContentMap, key: string, labelFallback: string, hrefFallback: string): LinkValue;
|
|
46
|
+
|
|
47
|
+
export { type LinkValue, type TextHelperConfig, __canciaContent, __canciaLink, __canciaText, clearTextCache, configureTextHelper };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// src/transform/text-helper.ts
|
|
2
|
+
var contentPromise = null;
|
|
3
|
+
function clearTextCache() {
|
|
4
|
+
contentPromise = null;
|
|
5
|
+
}
|
|
6
|
+
var config = null;
|
|
7
|
+
function configureTextHelper(next) {
|
|
8
|
+
config = next;
|
|
9
|
+
contentPromise = null;
|
|
10
|
+
}
|
|
11
|
+
async function __canciaContent() {
|
|
12
|
+
if (!config) return {};
|
|
13
|
+
try {
|
|
14
|
+
if (!contentPromise) contentPromise = config.read();
|
|
15
|
+
return await contentPromise;
|
|
16
|
+
} catch {
|
|
17
|
+
contentPromise = null;
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function lang() {
|
|
22
|
+
return config?.lang ?? "en";
|
|
23
|
+
}
|
|
24
|
+
function __canciaText(cms, key, fallback) {
|
|
25
|
+
return cms[`${key}.${lang()}`] ?? fallback;
|
|
26
|
+
}
|
|
27
|
+
function isSafeHref(href) {
|
|
28
|
+
const trimmed = href.trim();
|
|
29
|
+
if (trimmed === "") return true;
|
|
30
|
+
if (/^(https?:|mailto:|tel:)/i.test(trimmed)) return true;
|
|
31
|
+
const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(trimmed);
|
|
32
|
+
if (scheme) {
|
|
33
|
+
const firstSep = trimmed.search(/[/?#]/);
|
|
34
|
+
if (firstSep === -1 || scheme[1].length < firstSep) return false;
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
function __canciaLink(cms, key, labelFallback, hrefFallback) {
|
|
39
|
+
const fallback = { label: labelFallback, href: hrefFallback };
|
|
40
|
+
const raw = cms[`${key}.${lang()}`];
|
|
41
|
+
if (raw === void 0) return fallback;
|
|
42
|
+
if (raw === "") return { label: "", href: "" };
|
|
43
|
+
const trimmed = raw.trim();
|
|
44
|
+
if (trimmed.startsWith("{")) {
|
|
45
|
+
try {
|
|
46
|
+
const parsed = JSON.parse(trimmed);
|
|
47
|
+
const href = String(parsed.href ?? "");
|
|
48
|
+
return {
|
|
49
|
+
label: String(parsed.label ?? "") || labelFallback,
|
|
50
|
+
href: href && isSafeHref(href) ? href : hrefFallback
|
|
51
|
+
};
|
|
52
|
+
} catch {
|
|
53
|
+
return fallback;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return { label: raw, href: hrefFallback };
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
__canciaContent,
|
|
60
|
+
__canciaLink,
|
|
61
|
+
__canciaText,
|
|
62
|
+
clearTextCache,
|
|
63
|
+
configureTextHelper
|
|
64
|
+
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cancia/astro",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Astro integration for Cancia CMS — inline editing with zero separate server",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/ninuzdellalb/cancia",
|
|
8
|
+
"url": "git+https://github.com/ninuzdellalb/cancia.git",
|
|
9
9
|
"directory": "packages/astro"
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"types": "./dist/schema/index.d.ts",
|
|
21
21
|
"import": "./dist/schema/index.js"
|
|
22
22
|
},
|
|
23
|
+
"./schema-loader": {
|
|
24
|
+
"types": "./dist/schema/loader.d.ts",
|
|
25
|
+
"import": "./dist/schema/loader.js"
|
|
26
|
+
},
|
|
23
27
|
"./loader": {
|
|
24
28
|
"types": "./dist/loader/index.d.ts",
|
|
25
29
|
"import": "./dist/loader/index.js"
|
|
@@ -40,7 +44,8 @@
|
|
|
40
44
|
"types": "./dist/richtext/index.d.ts",
|
|
41
45
|
"import": "./dist/richtext/index.js"
|
|
42
46
|
},
|
|
43
|
-
"./richtext/CanciaRichText.astro": "./dist/richtext/CanciaRichText.astro"
|
|
47
|
+
"./richtext/CanciaRichText.astro": "./dist/richtext/CanciaRichText.astro",
|
|
48
|
+
"./richtext/CanciaRichRegion.astro": "./dist/richtext/CanciaRichRegion.astro"
|
|
44
49
|
},
|
|
45
50
|
"files": [
|
|
46
51
|
"dist"
|
|
@@ -68,7 +73,8 @@
|
|
|
68
73
|
},
|
|
69
74
|
"dependencies": {
|
|
70
75
|
"astro-portabletext": "^0.13.0",
|
|
71
|
-
"zod": "^4.4.3"
|
|
76
|
+
"zod": "^4.4.3",
|
|
77
|
+
"@astrojs/compiler": "^2.10.0"
|
|
72
78
|
},
|
|
73
79
|
"scripts": {
|
|
74
80
|
"build": "tsup",
|