@lupinum/ginko 0.4.0 → 0.6.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 (90) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/README.md +2 -2
  3. package/dist/basics.d.mts +492 -0
  4. package/dist/basics.d.ts +492 -0
  5. package/dist/basics.mjs +416 -0
  6. package/dist/cli/index.mjs +59 -56
  7. package/dist/index.d.mts +5 -4
  8. package/dist/index.d.ts +5 -4
  9. package/dist/index.mjs +3 -3
  10. package/dist/internal/search.mjs +6 -3
  11. package/dist/internal.d.mts +387 -41
  12. package/dist/internal.d.ts +387 -41
  13. package/dist/internal.mjs +267 -101
  14. package/dist/nuxt/module.d.mts +2 -2
  15. package/dist/nuxt/module.d.ts +2 -2
  16. package/dist/nuxt/module.mjs +108 -15
  17. package/dist/nuxt/runtime/GinkoImage.d.mts +1 -1
  18. package/dist/nuxt/runtime/GinkoMarkdown.mjs +2 -2
  19. package/dist/nuxt/runtime/composables.d.mts +4 -3
  20. package/dist/nuxt/runtime/composables.mjs +19 -15
  21. package/dist/nuxt/runtime/fetch.d.mts +3 -1
  22. package/dist/nuxt/runtime/fetch.mjs +12 -6
  23. package/dist/nuxt/runtime/markdown.d.mts +3 -0
  24. package/dist/nuxt/runtime/markdown.mjs +15 -3
  25. package/dist/nuxt/runtime/plugin.mjs +6 -35
  26. package/dist/nuxt/runtime/preview-listener.d.mts +13 -0
  27. package/dist/nuxt/runtime/preview-listener.mjs +37 -0
  28. package/dist/nuxt/runtime/preview.vue +3 -1
  29. package/dist/nuxt/runtime/schema.d.ts +6 -0
  30. package/dist/nuxt/runtime/server/bundles.d.ts +4 -0
  31. package/dist/nuxt/runtime/server/files-md.d.ts +2 -0
  32. package/dist/nuxt/runtime/server/files.d.ts +2 -0
  33. package/dist/nuxt/runtime/server/headers.d.ts +2 -0
  34. package/dist/nuxt/runtime/server/items.d.mts +12 -0
  35. package/dist/nuxt/runtime/server/items.d.ts +12 -0
  36. package/dist/nuxt/runtime/server/items.mjs +17 -0
  37. package/dist/nuxt/runtime/server/llms-full.d.ts +2 -0
  38. package/dist/nuxt/runtime/server/llms.d.ts +2 -0
  39. package/dist/nuxt/runtime/server/markdown-trees.d.ts +2 -0
  40. package/dist/nuxt/runtime/server/markdown.d.ts +2 -0
  41. package/dist/nuxt/runtime/server/markdown.mjs +1 -1
  42. package/dist/nuxt/runtime/server/platform-md.d.mts +3 -0
  43. package/dist/nuxt/runtime/server/platform-md.d.ts +3 -0
  44. package/dist/nuxt/runtime/server/platform-md.mjs +71 -0
  45. package/dist/nuxt/runtime/server/redirects.d.ts +2 -0
  46. package/dist/nuxt/runtime/server/robots.d.ts +2 -0
  47. package/dist/nuxt/runtime/server/search.d.ts +2 -0
  48. package/dist/nuxt/runtime/server/site-config.d.ts +14 -0
  49. package/dist/nuxt/runtime/server/sitemap-source.d.ts +2 -0
  50. package/dist/nuxt/runtime/server/sitemap-xml.d.ts +24 -0
  51. package/dist/nuxt/runtime/server/sitemap.d.ts +2 -0
  52. package/dist/nuxt/runtime/shared.d.mts +10 -3
  53. package/dist/nuxt/runtime/shared.mjs +2 -2
  54. package/dist/shared/{ginko.BBkZW2nW.d.ts → ginko.6cI8KXZP.d.mts} +2 -2
  55. package/dist/shared/{ginko.CrNRBkS5.mjs → ginko.B1-DoOea.mjs} +253 -309
  56. package/dist/shared/ginko.BNVC-g9n.mjs +10389 -0
  57. package/dist/shared/{ginko.Bwan3BB-.d.mts → ginko.B_pACpVU.d.ts} +2 -2
  58. package/dist/shared/ginko.BaFweQcB.d.mts +91 -0
  59. package/dist/shared/ginko.BiDXgjLy.d.ts +91 -0
  60. package/dist/shared/ginko.C-oz8wwI.mjs +95 -0
  61. package/dist/shared/{ginko.BDF3bW0C.d.ts → ginko.CLzVaDi4.d.ts} +56 -5
  62. package/dist/shared/ginko.C_nq6vk7.d.mts +1622 -0
  63. package/dist/shared/ginko.CjWB8N7f.d.ts +128 -0
  64. package/dist/shared/ginko.D1PeQ3ds.mjs +36 -0
  65. package/dist/shared/ginko.D2oht0Kx.d.ts +1622 -0
  66. package/dist/shared/ginko.DCHGkQ7P.mjs +116 -0
  67. package/dist/shared/ginko.DIl7l-75.mjs +26 -0
  68. package/dist/shared/{ginko.akHewCGt.d.mts → ginko.DkIc0ZZk.d.mts} +56 -5
  69. package/dist/shared/{ginko.D-fNojn9.d.mts → ginko.DrkUeYFP.d.mts} +824 -10
  70. package/dist/shared/{ginko.D-fNojn9.d.ts → ginko.DrkUeYFP.d.ts} +824 -10
  71. package/dist/shared/ginko.WAfoMhv1.mjs +601 -0
  72. package/dist/shared/ginko.o1yIKlgj.d.mts +128 -0
  73. package/dist/shared/{ginko.Dht0xxE5.mjs → ginko.raCzOPYC.mjs} +1 -2
  74. package/dist/shared/{ginko.C90fPpMP.mjs → ginko.t-gbwzxh.mjs} +128 -101
  75. package/dist/shared/ginko.yKMIjJ68.mjs +84 -0
  76. package/dist/vue.d.mts +5 -4
  77. package/dist/vue.d.ts +5 -4
  78. package/dist/vue.mjs +1 -1
  79. package/i18n/ar.json +212 -0
  80. package/i18n/de.json +9 -1
  81. package/i18n/en.json +9 -1
  82. package/i18n/es.json +12 -4
  83. package/i18n/fr.json +212 -0
  84. package/i18n/it.json +212 -0
  85. package/package.json +7 -3
  86. package/dist/shared/ginko.BTUfZCfa.d.mts +0 -172
  87. package/dist/shared/ginko.C-QjDn3O.mjs +0 -4944
  88. package/dist/shared/ginko.CQvxhyez.mjs +0 -40
  89. package/dist/shared/ginko.Dc0oNcDv.d.ts +0 -172
  90. package/dist/shared/ginko.Mn30dmlm.mjs +0 -20
@@ -1,11 +1,11 @@
1
- import { L as Locale, C as Currency, M as MarkdownTree, S as Schema, F as Fields, J as Json } from './ginko.D-fNojn9.mjs';
1
+ import { L as Locale, C as Currency, M as MarkdownTree, S as Schema, F as Fields, J as Json } from './ginko.DrkUeYFP.js';
2
2
 
3
3
  /** 3: text fields carry comark trees; collection items carry `updatedAt` and, for file entries, `source`. Other formats are refused. */
4
4
  declare const BUNDLE_FORMAT = 3;
5
5
  interface BundleItem {
6
6
  id: string;
7
7
  data: Record<string, unknown>;
8
- /** Leaves delivered in the main language because the requested translation is missing or outdated. */
8
+ /** Leaves delivered in the main language because the requested translation is missing. */
9
9
  fallback: string[];
10
10
  /** Only for collections with `route`, only visible entries, only locales where the entry exists. */
11
11
  urls?: Partial<Record<Locale, string>>;
@@ -0,0 +1,91 @@
1
+ import './ginko.DkIc0ZZk.mjs';
2
+ import { af as Money, F as Fields } from './ginko.DrkUeYFP.mjs';
3
+ import './ginko.o1yIKlgj.mjs';
4
+ import { a as BundleItem, B as Bundle } from './ginko.6cI8KXZP.mjs';
5
+
6
+ /** http(s), mailto, tel, a same-site path or fragment, or a `$` route link. Everything else (javascript:, data:, //host) is unsafe. */
7
+ declare function isSafeHref(href: string): boolean;
8
+ /** The link or image URL when it is safe (see `isSafeHref`), else undefined: for `href`/`src` from content. */
9
+ declare function safeHref(href: string | undefined): string | undefined;
10
+
11
+ /**
12
+ * Money is stored as an integer count of the currency's minor units (cents for EUR, whole yen for JPY).
13
+ * `minorDigits` says how many decimals one unit has: 2 for EUR, 0 for JPY, 3 for KWD.
14
+ */
15
+ declare function minorDigits(currency: string): number;
16
+ /** Options of `formatMoney`. */
17
+ interface FormatMoneyOptions {
18
+ /** A whole amount without its minor units: `€390` instead of `€390.00`; `€12.50` stays as it is. Default false. */
19
+ wholeWithoutMinor?: boolean;
20
+ }
21
+ /**
22
+ * The amount in the notation of `language`, a BCP 47 tag such as `de-AT` (use `useI18n().language`, not the URL
23
+ * code): `12,50 €` in de, `€ 12,50` in de-AT, `€12.50` in en, `¥1,250` for JPY.
24
+ * Every space is a no-break space: Node and browsers ship different ICU data (one uses a plain
25
+ * space), so a server-rendered price would otherwise differ from the hydrated one, and a price never breaks in two.
26
+ */
27
+ declare function formatMoney(money: Money, language: string, options?: FormatMoneyOptions): string;
28
+
29
+ type Data = Record<string, unknown>;
30
+ /** What a condition compares a value with: one element of a list value, money by `amount`, a daterange by its start date. */
31
+ type Comparable<V> = V extends readonly (infer E)[] ? E : V extends Money ? Pick<Money, 'amount'> : V extends {
32
+ from: string;
33
+ } ? string : V;
34
+ /**
35
+ * A test on one field. `eq`/`ne`: equal or not (for a list value: one element is). `gt`, `gte`, `lt`, `lte`: compare.
36
+ * `in`: equal to one of these. `contains`: a text contains this text (case-insensitive), a list contains this element.
37
+ */
38
+ interface Condition<V = unknown> {
39
+ eq?: Comparable<V> | null;
40
+ ne?: Comparable<V> | null;
41
+ gt?: Comparable<V>;
42
+ gte?: Comparable<V>;
43
+ lt?: Comparable<V>;
44
+ lte?: Comparable<V>;
45
+ in?: readonly Comparable<V>[];
46
+ contains?: Comparable<V>;
47
+ }
48
+ /** A sort order: the text `'price desc, name'` (`asc` is the default) or `{ field, dir? }` like a brick's `order`. */
49
+ type QueryOrder<D = Data> = string | {
50
+ field: keyof D & string;
51
+ dir?: 'asc' | 'desc';
52
+ };
53
+ /** `D` is the data of the brick's entries; `useGinkoQuery` sets it, so field names and values are checked. */
54
+ interface Query<D = Data> {
55
+ /** Per field a value (equal to it) or a `Condition`; every field must match. */
56
+ where?: {
57
+ [K in keyof D]?: Comparable<D[K]> | null | Condition<D[K]>;
58
+ };
59
+ /** Default: the bundle's item order. */
60
+ order?: QueryOrder<D>;
61
+ /** At least 1; without it, every matching entry. */
62
+ limit?: number;
63
+ /** 1-based. */
64
+ page?: number;
65
+ fields?: (keyof D & string)[];
66
+ facets?: (keyof D & string)[];
67
+ include?: (keyof D & string)[];
68
+ }
69
+ interface QueryResult {
70
+ items: BundleItem[];
71
+ total: number;
72
+ page: number;
73
+ pages: number;
74
+ facets?: Record<string, Record<string, number>>;
75
+ }
76
+ /** What `query` reads of the schema: the fields of each brick (a full `Schema` fits). */
77
+ interface QuerySchema {
78
+ bricks: Record<string, {
79
+ fields: Fields;
80
+ }>;
81
+ }
82
+ /** Filter, order, page, project and enrich the items of one collection brick. Pure; throws on a field the brick does not have. */
83
+ declare function query(bundle: Bundle, brick: string, q?: Query, schema?: QuerySchema): QueryResult;
84
+ /** The items before and after `id` in the given (or default) order. Both are missing for an unknown id. */
85
+ declare function neighbors(bundle: Bundle, brick: string, id: string, order?: QueryOrder): {
86
+ prev?: BundleItem;
87
+ next?: BundleItem;
88
+ };
89
+
90
+ export { formatMoney as f, isSafeHref as i, minorDigits as m, neighbors as n, query as q, safeHref as s };
91
+ export type { Condition as C, FormatMoneyOptions as F, Query as Q, QueryOrder as a, QueryResult as b, QuerySchema as c };
@@ -0,0 +1,91 @@
1
+ import './ginko.CLzVaDi4.js';
2
+ import { af as Money, F as Fields } from './ginko.DrkUeYFP.js';
3
+ import './ginko.CjWB8N7f.js';
4
+ import { a as BundleItem, B as Bundle } from './ginko.B_pACpVU.js';
5
+
6
+ /** http(s), mailto, tel, a same-site path or fragment, or a `$` route link. Everything else (javascript:, data:, //host) is unsafe. */
7
+ declare function isSafeHref(href: string): boolean;
8
+ /** The link or image URL when it is safe (see `isSafeHref`), else undefined: for `href`/`src` from content. */
9
+ declare function safeHref(href: string | undefined): string | undefined;
10
+
11
+ /**
12
+ * Money is stored as an integer count of the currency's minor units (cents for EUR, whole yen for JPY).
13
+ * `minorDigits` says how many decimals one unit has: 2 for EUR, 0 for JPY, 3 for KWD.
14
+ */
15
+ declare function minorDigits(currency: string): number;
16
+ /** Options of `formatMoney`. */
17
+ interface FormatMoneyOptions {
18
+ /** A whole amount without its minor units: `€390` instead of `€390.00`; `€12.50` stays as it is. Default false. */
19
+ wholeWithoutMinor?: boolean;
20
+ }
21
+ /**
22
+ * The amount in the notation of `language`, a BCP 47 tag such as `de-AT` (use `useI18n().language`, not the URL
23
+ * code): `12,50 €` in de, `€ 12,50` in de-AT, `€12.50` in en, `¥1,250` for JPY.
24
+ * Every space is a no-break space: Node and browsers ship different ICU data (one uses a plain
25
+ * space), so a server-rendered price would otherwise differ from the hydrated one, and a price never breaks in two.
26
+ */
27
+ declare function formatMoney(money: Money, language: string, options?: FormatMoneyOptions): string;
28
+
29
+ type Data = Record<string, unknown>;
30
+ /** What a condition compares a value with: one element of a list value, money by `amount`, a daterange by its start date. */
31
+ type Comparable<V> = V extends readonly (infer E)[] ? E : V extends Money ? Pick<Money, 'amount'> : V extends {
32
+ from: string;
33
+ } ? string : V;
34
+ /**
35
+ * A test on one field. `eq`/`ne`: equal or not (for a list value: one element is). `gt`, `gte`, `lt`, `lte`: compare.
36
+ * `in`: equal to one of these. `contains`: a text contains this text (case-insensitive), a list contains this element.
37
+ */
38
+ interface Condition<V = unknown> {
39
+ eq?: Comparable<V> | null;
40
+ ne?: Comparable<V> | null;
41
+ gt?: Comparable<V>;
42
+ gte?: Comparable<V>;
43
+ lt?: Comparable<V>;
44
+ lte?: Comparable<V>;
45
+ in?: readonly Comparable<V>[];
46
+ contains?: Comparable<V>;
47
+ }
48
+ /** A sort order: the text `'price desc, name'` (`asc` is the default) or `{ field, dir? }` like a brick's `order`. */
49
+ type QueryOrder<D = Data> = string | {
50
+ field: keyof D & string;
51
+ dir?: 'asc' | 'desc';
52
+ };
53
+ /** `D` is the data of the brick's entries; `useGinkoQuery` sets it, so field names and values are checked. */
54
+ interface Query<D = Data> {
55
+ /** Per field a value (equal to it) or a `Condition`; every field must match. */
56
+ where?: {
57
+ [K in keyof D]?: Comparable<D[K]> | null | Condition<D[K]>;
58
+ };
59
+ /** Default: the bundle's item order. */
60
+ order?: QueryOrder<D>;
61
+ /** At least 1; without it, every matching entry. */
62
+ limit?: number;
63
+ /** 1-based. */
64
+ page?: number;
65
+ fields?: (keyof D & string)[];
66
+ facets?: (keyof D & string)[];
67
+ include?: (keyof D & string)[];
68
+ }
69
+ interface QueryResult {
70
+ items: BundleItem[];
71
+ total: number;
72
+ page: number;
73
+ pages: number;
74
+ facets?: Record<string, Record<string, number>>;
75
+ }
76
+ /** What `query` reads of the schema: the fields of each brick (a full `Schema` fits). */
77
+ interface QuerySchema {
78
+ bricks: Record<string, {
79
+ fields: Fields;
80
+ }>;
81
+ }
82
+ /** Filter, order, page, project and enrich the items of one collection brick. Pure; throws on a field the brick does not have. */
83
+ declare function query(bundle: Bundle, brick: string, q?: Query, schema?: QuerySchema): QueryResult;
84
+ /** The items before and after `id` in the given (or default) order. Both are missing for an unknown id. */
85
+ declare function neighbors(bundle: Bundle, brick: string, id: string, order?: QueryOrder): {
86
+ prev?: BundleItem;
87
+ next?: BundleItem;
88
+ };
89
+
90
+ export { formatMoney as f, isSafeHref as i, minorDigits as m, neighbors as n, query as q, safeHref as s };
91
+ export type { Condition as C, FormatMoneyOptions as F, Query as Q, QueryOrder as a, QueryResult as b, QuerySchema as c };
@@ -0,0 +1,95 @@
1
+ function defineSite(site) {
2
+ return site;
3
+ }
4
+ function withoutFiles(site) {
5
+ const bricks = Object.fromEntries(Object.entries(site.bricks).map(([key, { source: _, ...brick }]) => [key, brick]));
6
+ return { ...site, bricks };
7
+ }
8
+ function siteForContent(site, content) {
9
+ if (!content) return site;
10
+ if (content === "platform") {
11
+ const bricks = Object.fromEntries(Object.entries(site.bricks).map(([key, brick]) => {
12
+ const copy = { ...brick };
13
+ delete copy.source;
14
+ return [key, copy];
15
+ }));
16
+ return { ...site, bricks };
17
+ }
18
+ throw new Error(`GINKO_CONTENT must be "platform" or unset, not "${content}".`);
19
+ }
20
+ function single(input) {
21
+ return { kind: "single", ...input, tasks: input.tasks };
22
+ }
23
+ function collection(input) {
24
+ return { kind: "collection", ...input, tasks: input.tasks };
25
+ }
26
+
27
+ function todayIn(timeZone, now = /* @__PURE__ */ new Date()) {
28
+ const parts = new Intl.DateTimeFormat("en-CA", { timeZone, year: "numeric", month: "2-digit", day: "2-digit" }).formatToParts(now);
29
+ const get = (t) => parts.find((p) => p.type === t)?.value ?? "";
30
+ return `${get("year")}-${get("month")}-${get("day")}`;
31
+ }
32
+ const readers = /* @__PURE__ */ new Map();
33
+ function zoneOffset(timeZone, ms) {
34
+ let reader = readers.get(timeZone);
35
+ if (!reader) readers.set(timeZone, reader = new Intl.DateTimeFormat("en-US", {
36
+ timeZone,
37
+ hourCycle: "h23",
38
+ year: "numeric",
39
+ month: "2-digit",
40
+ day: "2-digit",
41
+ hour: "2-digit",
42
+ minute: "2-digit",
43
+ second: "2-digit"
44
+ }));
45
+ const parts = reader.formatToParts(ms);
46
+ const get = (t) => Number(parts.find((p) => p.type === t)?.value ?? 0);
47
+ const local = Date.UTC(get("year"), get("month") - 1, get("day"), get("hour"), get("minute"), get("second"));
48
+ return local - Math.floor(ms / 1e3) * 1e3;
49
+ }
50
+ function zonedDateTime(date, time, timeZone) {
51
+ const naive = Date.parse(`${date}T${time}:00Z`);
52
+ const minutes = Math.round(zoneOffset(timeZone, naive - zoneOffset(timeZone, naive)) / 6e4);
53
+ const sign = minutes < 0 ? "-" : "+";
54
+ const abs = Math.abs(minutes);
55
+ return `${date}T${time}:00${sign}${String(Math.floor(abs / 60)).padStart(2, "0")}:${String(abs % 60).padStart(2, "0")}`;
56
+ }
57
+ function addDays(date, days) {
58
+ const d = /* @__PURE__ */ new Date(`${date}T00:00:00Z`);
59
+ d.setUTCDate(d.getUTCDate() + days);
60
+ return d.toISOString().slice(0, 10);
61
+ }
62
+ const DEFAULT_WEEK = { firstDay: 1, weekend: [6, 7] };
63
+ function weekInfoOf(language, firstDayOfWeek) {
64
+ let info = DEFAULT_WEEK;
65
+ try {
66
+ const locale = new Intl.Locale(language);
67
+ const found = locale.getWeekInfo?.() ?? locale.weekInfo;
68
+ if (found?.firstDay && Array.isArray(found.weekend)) info = { firstDay: found.firstDay, weekend: [...found.weekend] };
69
+ } catch {
70
+ }
71
+ return { firstDay: firstDayOfWeek ?? info.firstDay, weekend: info.weekend };
72
+ }
73
+ const isoDay = (date) => (/* @__PURE__ */ new Date(`${date}T00:00:00Z`)).getUTCDay() || 7;
74
+ const placeInWeek = (day, week) => (day - week.firstDay + 7) % 7;
75
+ function startOfWeek(date, week) {
76
+ return addDays(date, -placeInWeek(isoDay(date), week));
77
+ }
78
+ function workWeekOf(date, week) {
79
+ const lastWorkday = Math.max(-1, ...[1, 2, 3, 4, 5, 6, 7].filter((d) => !week.weekend.includes(d)).map((d) => placeInWeek(d, week)));
80
+ const own = startOfWeek(date, week);
81
+ return placeInWeek(isoDay(date), week) > lastWorkday ? addDays(own, 7) : own;
82
+ }
83
+ function firstDayShown(weekStart, week) {
84
+ for (let day = addDays(weekStart, -6); day < weekStart; day = addDays(day, 1)) if (workWeekOf(day, week) === weekStart) return day;
85
+ return weekStart;
86
+ }
87
+ function resolveToken(token, timeZone, week, now = /* @__PURE__ */ new Date()) {
88
+ const today = todayIn(timeZone, now);
89
+ if (token === "@today") return today;
90
+ if (token === "@workWeek") return workWeekOf(today, week);
91
+ if (token === "@nextWorkWeek") return addDays(workWeekOf(today, week), 7);
92
+ return void 0;
93
+ }
94
+
95
+ export { DEFAULT_WEEK as D, startOfWeek as a, addDays as b, collection as c, defineSite as d, weekInfoOf as e, firstDayShown as f, siteForContent as g, withoutFiles as h, zoneOffset as i, resolveToken as r, single as s, todayIn as t, workWeekOf as w, zonedDateTime as z };
@@ -1,5 +1,5 @@
1
- import { b as Msg, S as Schema, F as Fields, J as Json, L as Locale, C as Currency, B as Brick, a as ComponentRegistry, R as RetiredRule, c as Label, d as BrickSource, T as Task, V as Visibility, e as CollectionBrick, f as SingleBrick } from './ginko.D-fNojn9.js';
2
- import { B as Bundle } from './ginko.BBkZW2nW.js';
1
+ import { a as Msg, S as Schema, F as Fields, J as Json, L as Locale, C as Currency, H as HolidaysOption, B as Brick, b as ComponentRegistry, R as RetiredRule, c as Label, d as BrickSource, T as Task, V as Visibility, e as CollectionStatus, f as CollectionBrick, g as SingleStatus, h as SingleBrick } from './ginko.DrkUeYFP.js';
2
+ import { B as Bundle } from './ginko.B_pACpVU.js';
3
3
 
4
4
  interface Redirect {
5
5
  from: string;
@@ -59,10 +59,12 @@ type Pages = Pick<Schema, 'pages' | 'bricks'>;
59
59
  /**
60
60
  * The bundle with `$…` links turned into paths and `::snippet` components replaced by their text.
61
61
  * `$page.<key>` is a page of `schema.pages`; `$<brick>.<slug-or-id>` is an entry's URL; a `#anchor` is kept.
62
+ * `main` is the main-language bundle (from `buildBundle`, links unresolved): an entry left out of this locale because
63
+ * it is not translated (`untranslated: 'hide'`) is found there, and the link goes to its main-language page.
62
64
  * What cannot be resolved stays as it is and gets `data-broken: true`. A snippet is the `body` of the entry
63
65
  * `snippets/<name>` of the collection `snippets`; a snippet inside a snippet stays as it is. No mutation.
64
66
  */
65
- declare function resolveRouteLinks(bundle: Bundle, schema: Pages): Bundle;
67
+ declare function resolveRouteLinks(bundle: Bundle, schema: Pages, main?: Bundle): Bundle;
66
68
  /**
67
69
  * Link check over bundles (one per locale) before any HTML exists. Errors: route links and snippets that
68
70
  * `resolveRouteLinks` could not resolve, and `/…` paths that match no entry URL, no page and no public file.
@@ -117,6 +119,16 @@ interface SiteInput {
117
119
  */
118
120
  firstDayOfWeek?: 1 | 2 | 3 | 4 | 5 | 6 | 7;
119
121
  currency: Currency;
122
+ /**
123
+ * The country of the site (ISO 3166-1 alpha-2, e.g. `AT`). It picks the public-holiday calendar (`calendar`) and is
124
+ * the default `addressCountry` of JSON-LD. A country Ginko has no calendar for keeps no public holidays (`ginko check` warns).
125
+ */
126
+ country?: string;
127
+ /**
128
+ * Which public holidays count for opening hours: `AT`, `DE` (nationwide only), `SG`, `none`, or your own function
129
+ * `(year) => Holiday[]`. Default: the calendar of `country`. Stored in the schema as `holidays` (a function as `custom`).
130
+ */
131
+ calendar?: HolidaysOption;
120
132
  /**
121
133
  * Static pages by key: `{ menu: { de: '/speisekarte', en: '/en/menu' } }`. A plain path is the page in
122
134
  * the main locale only. The home page is the page whose main-locale path is `/`. The sitemap pairs a page's locales by key.
@@ -136,6 +148,7 @@ interface SiteInput {
136
148
  image?: string;
137
149
  /** The brand colour, `#rrggbb` or `#rgb`: the background of generated share cards (nuxt-og-image). */
138
150
  color?: string;
151
+ /** The home page's Organization JSON-LD. A page with its own (`siteJsonLd` of `@lupinum/ginko/basics`) gets none from here. */
139
152
  organization?: {
140
153
  logo?: string;
141
154
  sameAs?: string[];
@@ -170,12 +183,40 @@ type RetiredInput<S extends SiteInput> = {
170
183
  declare function defineSite<const S extends SiteInput>(site: S & {
171
184
  retired?: RetiredInput<S>;
172
185
  }): S;
186
+ /**
187
+ * `site` as it runs on the platform: every brick without `source`, so the owner edits it in the Studio. A template
188
+ * that reads its content from files and this twin must both pass `checkSite`; tools and tests use it to prove that a
189
+ * files site can move to the platform without changing its bricks.
190
+ */
191
+ declare function withoutFiles<const S extends SiteInput>(site: S): WithoutFiles<S>;
192
+ /**
193
+ * The site for the content source `GINKO_CONTENT` names: unset or empty keeps the config as it is, `platform` is
194
+ * `withoutFiles(site)`. A files site deployed with `GINKO_CONTENT=platform` reads the Studio without a code change
195
+ * (the hosted template demos); the Nuxt module and the CLI both read it, so the build and `ginko release` agree.
196
+ */
197
+ declare function siteForContent(site: SiteInput, content: string | undefined): SiteInput;
198
+ /** `S` with no `source` on any brick. */
199
+ type WithoutFiles<S extends SiteInput> = Omit<S, 'bricks'> & {
200
+ bricks: {
201
+ [K in keyof S['bricks']]: Omit<S['bricks'][K], 'source'>;
202
+ };
203
+ };
173
204
  /** The names of the fields in `F` whose type is one of `T`. */
174
205
  type FieldsOfType<F, T extends string> = {
175
206
  [K in keyof F]: F[K] extends {
176
207
  type: T;
177
208
  } ? K : never;
178
209
  }[keyof F] & string;
210
+ /**
211
+ * A planned change of one field (`planned`): from the date in the date field `from` on, `next` replaces `field`. `next`
212
+ * and `from` are optional and set together; every edit task that changes `field` lists them too. Field names only:
213
+ * a factory with generic fields could not name its date field otherwise, so `ginko check` reports the other rules.
214
+ */
215
+ type Planned<F> = {
216
+ field: keyof F & string;
217
+ next: keyof F & string;
218
+ from: keyof F & string;
219
+ };
179
220
  /** A collection's detail page per locale: a path with `[slug]` where the entry's slug goes, e.g. `/blog/[slug]`. */
180
221
  type RouteTemplate = `/${string}[slug]${string}`;
181
222
  declare function single<const F extends Fields>(input: {
@@ -185,6 +226,8 @@ declare function single<const F extends Fields>(input: {
185
226
  fields: F;
186
227
  layout?: 'sections' | 'tabs';
187
228
  tasks?: readonly Task<F>[];
229
+ planned?: Planned<F>;
230
+ status?: SingleStatus;
188
231
  }): SingleBrick<F>;
189
232
  declare function collection<const F extends Fields, const R extends Record<Locale, RouteTemplate> | undefined = undefined>(input: {
190
233
  label: Label;
@@ -193,6 +236,8 @@ declare function collection<const F extends Fields, const R extends Record<Local
193
236
  fields: F;
194
237
  layout?: 'sections' | 'tabs';
195
238
  tasks?: readonly Task<F>[];
239
+ /** A planned change of one field: from the date in `from` on, `next` replaces `field`. */
240
+ planned?: Planned<F>;
196
241
  max: number;
197
242
  order: 'manual' | {
198
243
  field: keyof F & string;
@@ -200,6 +245,10 @@ declare function collection<const F extends Fields, const R extends Record<Local
200
245
  };
201
246
  route?: R;
202
247
  visible?: Visibility<FieldsOfType<F, 'date' | 'daterange'>>;
248
+ /**
249
+ * A required translatable field is missing in a language: `'hide'` (default with a `route`) leaves the entry out
250
+ * there; `'fallback'` (default without) shows the main language and links to the main-language page.
251
+ */
203
252
  untranslated?: 'fallback' | 'hide';
204
253
  /** Entries plan weeks of the single brick `brick`; `field` (a date field of this collection) holds the first day of the week (`firstDayOfWeek`). */
205
254
  plans?: {
@@ -207,7 +256,9 @@ declare function collection<const F extends Fields, const R extends Record<Local
207
256
  field: FieldsOfType<F, 'date'>;
208
257
  };
209
258
  drafts?: boolean;
259
+ /** The status line on the Studio's Today page (see `CollectionStatus`). */
260
+ status?: CollectionStatus<FieldsOfType<F, 'date' | 'daterange'>, keyof F & string>;
210
261
  }): CollectionBrick<F, R>;
211
262
 
212
- export { checkLinks as d, collection as e, defineSite as f, entryRedirects as g, externalLinks as h, findRedirect as i, resolveRouteLinks as j, linkTargets as l, matchRedirect as m, redirectProblems as r, single as s };
213
- export type { CheckLinksOptions as C, ExternalLink as E, LinkConfig as L, Migration as M, Redirect as R, SiteInput as S, LinkIssue as a, MigrationContext as b, RouteTemplate as c };
263
+ export { checkLinks as d, collection as e, defineSite as f, entryRedirects as g, externalLinks as h, findRedirect as i, resolveRouteLinks as j, siteForContent as k, linkTargets as l, matchRedirect as m, redirectProblems as r, single as s, withoutFiles as w };
264
+ export type { CheckLinksOptions as C, ExternalLink as E, LinkConfig as L, Migration as M, RouteTemplate as R, SiteInput as S, WithoutFiles as W, LinkIssue as a, MigrationContext as b, Redirect as c };