@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.
- package/CHANGELOG.md +161 -0
- package/README.md +2 -2
- package/dist/basics.d.mts +492 -0
- package/dist/basics.d.ts +492 -0
- package/dist/basics.mjs +416 -0
- package/dist/cli/index.mjs +59 -56
- package/dist/index.d.mts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.mjs +3 -3
- package/dist/internal/search.mjs +6 -3
- package/dist/internal.d.mts +387 -41
- package/dist/internal.d.ts +387 -41
- package/dist/internal.mjs +267 -101
- package/dist/nuxt/module.d.mts +2 -2
- package/dist/nuxt/module.d.ts +2 -2
- package/dist/nuxt/module.mjs +108 -15
- package/dist/nuxt/runtime/GinkoImage.d.mts +1 -1
- package/dist/nuxt/runtime/GinkoMarkdown.mjs +2 -2
- package/dist/nuxt/runtime/composables.d.mts +4 -3
- package/dist/nuxt/runtime/composables.mjs +19 -15
- package/dist/nuxt/runtime/fetch.d.mts +3 -1
- package/dist/nuxt/runtime/fetch.mjs +12 -6
- package/dist/nuxt/runtime/markdown.d.mts +3 -0
- package/dist/nuxt/runtime/markdown.mjs +15 -3
- package/dist/nuxt/runtime/plugin.mjs +6 -35
- package/dist/nuxt/runtime/preview-listener.d.mts +13 -0
- package/dist/nuxt/runtime/preview-listener.mjs +37 -0
- package/dist/nuxt/runtime/preview.vue +3 -1
- package/dist/nuxt/runtime/schema.d.ts +6 -0
- package/dist/nuxt/runtime/server/bundles.d.ts +4 -0
- package/dist/nuxt/runtime/server/files-md.d.ts +2 -0
- package/dist/nuxt/runtime/server/files.d.ts +2 -0
- package/dist/nuxt/runtime/server/headers.d.ts +2 -0
- package/dist/nuxt/runtime/server/items.d.mts +12 -0
- package/dist/nuxt/runtime/server/items.d.ts +12 -0
- package/dist/nuxt/runtime/server/items.mjs +17 -0
- package/dist/nuxt/runtime/server/llms-full.d.ts +2 -0
- package/dist/nuxt/runtime/server/llms.d.ts +2 -0
- package/dist/nuxt/runtime/server/markdown-trees.d.ts +2 -0
- package/dist/nuxt/runtime/server/markdown.d.ts +2 -0
- package/dist/nuxt/runtime/server/markdown.mjs +1 -1
- package/dist/nuxt/runtime/server/platform-md.d.mts +3 -0
- package/dist/nuxt/runtime/server/platform-md.d.ts +3 -0
- package/dist/nuxt/runtime/server/platform-md.mjs +71 -0
- package/dist/nuxt/runtime/server/redirects.d.ts +2 -0
- package/dist/nuxt/runtime/server/robots.d.ts +2 -0
- package/dist/nuxt/runtime/server/search.d.ts +2 -0
- package/dist/nuxt/runtime/server/site-config.d.ts +14 -0
- package/dist/nuxt/runtime/server/sitemap-source.d.ts +2 -0
- package/dist/nuxt/runtime/server/sitemap-xml.d.ts +24 -0
- package/dist/nuxt/runtime/server/sitemap.d.ts +2 -0
- package/dist/nuxt/runtime/shared.d.mts +10 -3
- package/dist/nuxt/runtime/shared.mjs +2 -2
- package/dist/shared/{ginko.BBkZW2nW.d.ts → ginko.6cI8KXZP.d.mts} +2 -2
- package/dist/shared/{ginko.CrNRBkS5.mjs → ginko.B1-DoOea.mjs} +253 -309
- package/dist/shared/ginko.BNVC-g9n.mjs +10389 -0
- package/dist/shared/{ginko.Bwan3BB-.d.mts → ginko.B_pACpVU.d.ts} +2 -2
- package/dist/shared/ginko.BaFweQcB.d.mts +91 -0
- package/dist/shared/ginko.BiDXgjLy.d.ts +91 -0
- package/dist/shared/ginko.C-oz8wwI.mjs +95 -0
- package/dist/shared/{ginko.BDF3bW0C.d.ts → ginko.CLzVaDi4.d.ts} +56 -5
- package/dist/shared/ginko.C_nq6vk7.d.mts +1622 -0
- package/dist/shared/ginko.CjWB8N7f.d.ts +128 -0
- package/dist/shared/ginko.D1PeQ3ds.mjs +36 -0
- package/dist/shared/ginko.D2oht0Kx.d.ts +1622 -0
- package/dist/shared/ginko.DCHGkQ7P.mjs +116 -0
- package/dist/shared/ginko.DIl7l-75.mjs +26 -0
- package/dist/shared/{ginko.akHewCGt.d.mts → ginko.DkIc0ZZk.d.mts} +56 -5
- package/dist/shared/{ginko.D-fNojn9.d.mts → ginko.DrkUeYFP.d.mts} +824 -10
- package/dist/shared/{ginko.D-fNojn9.d.ts → ginko.DrkUeYFP.d.ts} +824 -10
- package/dist/shared/ginko.WAfoMhv1.mjs +601 -0
- package/dist/shared/ginko.o1yIKlgj.d.mts +128 -0
- package/dist/shared/{ginko.Dht0xxE5.mjs → ginko.raCzOPYC.mjs} +1 -2
- package/dist/shared/{ginko.C90fPpMP.mjs → ginko.t-gbwzxh.mjs} +128 -101
- package/dist/shared/ginko.yKMIjJ68.mjs +84 -0
- package/dist/vue.d.mts +5 -4
- package/dist/vue.d.ts +5 -4
- package/dist/vue.mjs +1 -1
- package/i18n/ar.json +212 -0
- package/i18n/de.json +9 -1
- package/i18n/en.json +9 -1
- package/i18n/es.json +12 -4
- package/i18n/fr.json +212 -0
- package/i18n/it.json +212 -0
- package/package.json +7 -3
- package/dist/shared/ginko.BTUfZCfa.d.mts +0 -172
- package/dist/shared/ginko.C-QjDn3O.mjs +0 -4944
- package/dist/shared/ginko.CQvxhyez.mjs +0 -40
- package/dist/shared/ginko.Dc0oNcDv.d.ts +0 -172
- 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.
|
|
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
|
|
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 {
|
|
2
|
-
import { B as Bundle } from './ginko.
|
|
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,
|
|
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 };
|