@shaferllc/keel 0.66.0 → 0.74.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/AGENTS.md +169 -0
- package/README.md +44 -6
- package/bin/keel-mcp.mjs +9 -0
- package/dist/api/api.config.stub +9 -0
- package/dist/api/config.d.ts +13 -0
- package/dist/api/config.js +14 -0
- package/dist/api/index.d.ts +16 -0
- package/dist/api/index.js +13 -0
- package/dist/api/provider.d.ts +10 -0
- package/dist/api/provider.js +17 -0
- package/dist/api/query.d.ts +35 -0
- package/dist/api/query.js +42 -0
- package/dist/api/resource.d.ts +91 -0
- package/dist/api/resource.js +188 -0
- package/dist/core/application.d.ts +5 -5
- package/dist/core/application.js +8 -2
- package/dist/core/cache.d.ts +81 -5
- package/dist/core/cache.js +188 -23
- package/dist/core/cli/stubs.d.ts +26 -0
- package/dist/core/cli/stubs.js +225 -0
- package/dist/core/console-prompt.d.ts +79 -0
- package/dist/core/console-prompt.js +239 -0
- package/dist/core/console-ui.d.ts +96 -0
- package/dist/core/console-ui.js +187 -0
- package/dist/core/console.d.ts +188 -0
- package/dist/core/console.js +395 -0
- package/dist/core/database.d.ts +70 -1
- package/dist/core/database.js +174 -15
- package/dist/core/env.d.ts +96 -0
- package/dist/core/env.js +140 -0
- package/dist/core/events.d.ts +129 -5
- package/dist/core/events.js +165 -7
- package/dist/core/health.d.ts +141 -0
- package/dist/core/health.js +226 -0
- package/dist/core/helpers.d.ts +9 -3
- package/dist/core/helpers.js +11 -3
- package/dist/core/http/kernel.d.ts +2 -0
- package/dist/core/http/kernel.js +48 -0
- package/dist/core/http/router.d.ts +5 -5
- package/dist/core/http/router.js +5 -5
- package/dist/core/i18n.d.ts +162 -0
- package/dist/core/i18n.js +472 -0
- package/dist/core/index.d.ts +39 -13
- package/dist/core/index.js +19 -6
- package/dist/core/instrumentation.d.ts +113 -0
- package/dist/core/instrumentation.js +52 -0
- package/dist/core/lock.d.ts +139 -0
- package/dist/core/lock.js +215 -0
- package/dist/core/logger.d.ts +89 -4
- package/dist/core/logger.js +167 -22
- package/dist/core/mail.d.ts +128 -7
- package/dist/core/mail.js +264 -16
- package/dist/core/notification.js +10 -1
- package/dist/core/package.d.ts +120 -0
- package/dist/core/package.js +169 -0
- package/dist/core/pages.d.ts +108 -0
- package/dist/core/pages.js +199 -0
- package/dist/core/queue.d.ts +134 -9
- package/dist/core/queue.js +325 -14
- package/dist/core/repl.d.ts +33 -0
- package/dist/core/repl.js +88 -0
- package/dist/core/scheduler.js +6 -0
- package/dist/core/social.d.ts +4 -4
- package/dist/core/social.js +4 -4
- package/dist/core/storage.d.ts +159 -6
- package/dist/core/storage.js +299 -7
- package/dist/core/telemetry.d.ts +208 -0
- package/dist/core/telemetry.js +383 -0
- package/dist/core/template.d.ts +2 -3
- package/dist/core/template.js +2 -3
- package/dist/core/testing.d.ts +170 -1
- package/dist/core/testing.js +504 -2
- package/dist/db/d1.js +13 -0
- package/dist/db/pg.d.ts +13 -0
- package/dist/db/pg.js +46 -4
- package/dist/mcp/server.d.ts +19 -0
- package/dist/mcp/server.js +355 -0
- package/dist/openapi/config.d.ts +28 -0
- package/dist/openapi/config.js +25 -0
- package/dist/openapi/doc.d.ts +40 -0
- package/dist/openapi/doc.js +20 -0
- package/dist/openapi/export.d.ts +8 -0
- package/dist/openapi/export.js +19 -0
- package/dist/openapi/gate.d.ts +15 -0
- package/dist/openapi/gate.js +27 -0
- package/dist/openapi/index.d.ts +19 -0
- package/dist/openapi/index.js +15 -0
- package/dist/openapi/openapi.config.stub +29 -0
- package/dist/openapi/provider.d.ts +18 -0
- package/dist/openapi/provider.js +35 -0
- package/dist/openapi/routes.d.ts +9 -0
- package/dist/openapi/routes.js +23 -0
- package/dist/openapi/spec.d.ts +23 -0
- package/dist/openapi/spec.js +132 -0
- package/dist/openapi/ui.d.ts +8 -0
- package/dist/openapi/ui.js +31 -0
- package/dist/openapi/zod.d.ts +12 -0
- package/dist/openapi/zod.js +46 -0
- package/dist/watch/config.d.ts +33 -0
- package/dist/watch/config.js +38 -0
- package/dist/watch/entry.d.ts +53 -0
- package/dist/watch/entry.js +105 -0
- package/dist/watch/gate.d.ts +20 -0
- package/dist/watch/gate.js +32 -0
- package/dist/watch/index.d.ts +21 -0
- package/dist/watch/index.js +17 -0
- package/dist/watch/migration.d.ts +7 -0
- package/dist/watch/migration.js +20 -0
- package/dist/watch/provider.d.ts +22 -0
- package/dist/watch/provider.js +58 -0
- package/dist/watch/prune.d.ts +11 -0
- package/dist/watch/prune.js +20 -0
- package/dist/watch/recorder.d.ts +24 -0
- package/dist/watch/recorder.js +39 -0
- package/dist/watch/routes.d.ts +13 -0
- package/dist/watch/routes.js +55 -0
- package/dist/watch/store.d.ts +54 -0
- package/dist/watch/store.js +158 -0
- package/dist/watch/ui/dist/watch.css +1 -0
- package/dist/watch/ui/dist/watch.js +555 -0
- package/dist/watch/ui-shell.d.ts +12 -0
- package/dist/watch/ui-shell.js +24 -0
- package/dist/watch/watch.config.stub +47 -0
- package/dist/watch/watchers.d.ts +12 -0
- package/dist/watch/watchers.js +156 -0
- package/docs/ai-manifest.json +3206 -0
- package/docs/ai.md +128 -0
- package/docs/api-resources.md +118 -0
- package/docs/architecture.md +331 -0
- package/docs/authentication.md +453 -0
- package/docs/authorization.md +167 -0
- package/docs/broadcasting.md +137 -0
- package/docs/broker.md +500 -0
- package/docs/cache.md +558 -0
- package/docs/configuration.md +385 -0
- package/docs/console.md +536 -0
- package/docs/container.md +467 -0
- package/docs/controllers.md +265 -0
- package/docs/cors.md +51 -0
- package/docs/database.md +631 -0
- package/docs/debugging.md +129 -0
- package/docs/decorators.md +127 -0
- package/docs/errors.md +395 -0
- package/docs/events.md +496 -0
- package/docs/examples/architecture-app.ts +27 -0
- package/docs/examples/authentication.ts +61 -0
- package/docs/examples/authorization.ts +79 -0
- package/docs/examples/broadcasting.ts +60 -0
- package/docs/examples/broker-cache-validate.ts +34 -0
- package/docs/examples/broker-fault-tolerance.ts +29 -0
- package/docs/examples/broker-middleware.ts +27 -0
- package/docs/examples/broker.ts +203 -0
- package/docs/examples/cache.ts +222 -0
- package/docs/examples/configuration.ts +121 -0
- package/docs/examples/console.ts +134 -0
- package/docs/examples/container.ts +134 -0
- package/docs/examples/controllers.ts +86 -0
- package/docs/examples/database.ts +208 -0
- package/docs/examples/debugging.ts +41 -0
- package/docs/examples/decorators.ts +40 -0
- package/docs/examples/errors.ts +121 -0
- package/docs/examples/events.ts +204 -0
- package/docs/examples/factories.ts +84 -0
- package/docs/examples/hashing.ts +71 -0
- package/docs/examples/health.ts +94 -0
- package/docs/examples/helpers.ts +171 -0
- package/docs/examples/hooks.ts +54 -0
- package/docs/examples/i18n.ts +117 -0
- package/docs/examples/inertia.ts +81 -0
- package/docs/examples/locks.ts +120 -0
- package/docs/examples/logger.ts +166 -0
- package/docs/examples/mail.ts +263 -0
- package/docs/examples/middleware.ts +119 -0
- package/docs/examples/migrations.ts +126 -0
- package/docs/examples/models.ts +239 -0
- package/docs/examples/notification.ts +124 -0
- package/docs/examples/pages.ts +82 -0
- package/docs/examples/providers.ts +123 -0
- package/docs/examples/queues.ts +254 -0
- package/docs/examples/rate-limiting.ts +42 -0
- package/docs/examples/redis.ts +99 -0
- package/docs/examples/request-response.ts +197 -0
- package/docs/examples/routing.ts +186 -0
- package/docs/examples/scheduling.ts +62 -0
- package/docs/examples/sessions.ts +102 -0
- package/docs/examples/static-files.ts +63 -0
- package/docs/examples/storage.ts +132 -0
- package/docs/examples/telemetry.ts +127 -0
- package/docs/examples/templates.ts +58 -0
- package/docs/examples/testing.ts +215 -0
- package/docs/examples/transformer.ts +141 -0
- package/docs/examples/transformers.ts +49 -0
- package/docs/examples/url-builder.ts +86 -0
- package/docs/examples/validation.ts +102 -0
- package/docs/examples/views.tsx +62 -0
- package/docs/examples/vite.ts +106 -0
- package/docs/factories.md +166 -0
- package/docs/getting-started.md +290 -0
- package/docs/hashing.md +259 -0
- package/docs/health.md +225 -0
- package/docs/helpers.md +347 -0
- package/docs/hono.md +186 -0
- package/docs/hooks.md +118 -0
- package/docs/i18n.md +302 -0
- package/docs/inertia.md +241 -0
- package/docs/locks.md +323 -0
- package/docs/logger.md +436 -0
- package/docs/mail.md +751 -0
- package/docs/middleware.md +425 -0
- package/docs/migrations.md +476 -0
- package/docs/models.md +810 -0
- package/docs/notifications.md +474 -0
- package/docs/openapi.md +111 -0
- package/docs/packages.md +118 -0
- package/docs/pages.md +217 -0
- package/docs/providers.md +363 -0
- package/docs/queues.md +679 -0
- package/docs/rate-limiting.md +155 -0
- package/docs/redis.md +178 -0
- package/docs/request-response.md +953 -0
- package/docs/routing.md +804 -0
- package/docs/scheduling.md +110 -0
- package/docs/security.md +85 -0
- package/docs/sessions.md +354 -0
- package/docs/social-auth.md +174 -0
- package/docs/static-files.md +211 -0
- package/docs/storage.md +452 -0
- package/docs/telemetry.md +263 -0
- package/docs/templates.md +314 -0
- package/docs/testing.md +376 -0
- package/docs/transformers.md +381 -0
- package/docs/url-builder.md +295 -0
- package/docs/validation.md +288 -0
- package/docs/views.md +267 -0
- package/docs/vite.md +434 -0
- package/docs/watch.md +118 -0
- package/llms-full.txt +19816 -0
- package/llms.txt +127 -0
- package/package.json +42 -7
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internationalization — translations with ICU message formatting, and the
|
|
3
|
+
* `Intl` formatters that go with them.
|
|
4
|
+
*
|
|
5
|
+
* setTranslations({
|
|
6
|
+
* en: { "cart.items": "{count, plural, =0 {Your cart is empty} one {# item} other {# items}}" },
|
|
7
|
+
* fr: { "cart.items": "{count, plural, =0 {Panier vide} one {# article} other {# articles}}" },
|
|
8
|
+
* });
|
|
9
|
+
*
|
|
10
|
+
* t("cart.items", { count: 3 }); // "3 items" (the request's locale)
|
|
11
|
+
* i18n("fr").t("cart.items", { count: 3 }); // "3 articles"
|
|
12
|
+
*
|
|
13
|
+
* There is **no dependency** here, and there doesn't need to be: `Intl` ships with
|
|
14
|
+
* every modern runtime — Node and Workers both carry the full ICU data — so
|
|
15
|
+
* plurals, currencies, dates, and relative times are the platform's job. What Keel
|
|
16
|
+
* adds is the message parser on top, which is the part `Intl` doesn't do.
|
|
17
|
+
*
|
|
18
|
+
* The supported ICU subset is the part people actually use: interpolation,
|
|
19
|
+
* `plural`, `selectordinal`, `select`, `number`, `date`, and `time` — nested
|
|
20
|
+
* arbitrarily deep. See the i18n guide for the grammar.
|
|
21
|
+
*/
|
|
22
|
+
import { getContext } from "hono/context-storage";
|
|
23
|
+
import { hasApplication, emit } from "./helpers.js";
|
|
24
|
+
/**
|
|
25
|
+
* Flatten nested translations to dot paths, so `{ cart: { items: "…" } }` and
|
|
26
|
+
* `{ "cart.items": "…" }` are the same thing and can be mixed freely.
|
|
27
|
+
*/
|
|
28
|
+
function flatten(input, prefix = "", out = {}) {
|
|
29
|
+
for (const [key, value] of Object.entries(input)) {
|
|
30
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
31
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
32
|
+
flatten(value, path, out);
|
|
33
|
+
}
|
|
34
|
+
else if (value != null) {
|
|
35
|
+
out[path] = String(value);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
/* ---------------------------- the ICU formatter --------------------------- */
|
|
41
|
+
/**
|
|
42
|
+
* Find the index of the `}` matching the `{` at `open`. Brace-counting, because a
|
|
43
|
+
* plural branch contains whole sub-messages that have braces of their own.
|
|
44
|
+
*/
|
|
45
|
+
function matchBrace(message, open) {
|
|
46
|
+
let depth = 0;
|
|
47
|
+
for (let i = open; i < message.length; i++) {
|
|
48
|
+
const char = message[i];
|
|
49
|
+
if (char === "{")
|
|
50
|
+
depth++;
|
|
51
|
+
else if (char === "}") {
|
|
52
|
+
depth--;
|
|
53
|
+
if (depth === 0)
|
|
54
|
+
return i;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
throw new Error(`i18n: unbalanced braces in message: ${message}`);
|
|
58
|
+
}
|
|
59
|
+
/** Split `one {# item} other {# items}` into its branches. */
|
|
60
|
+
function parseBranches(style) {
|
|
61
|
+
const branches = {};
|
|
62
|
+
let i = 0;
|
|
63
|
+
while (i < style.length) {
|
|
64
|
+
// The branch key: everything up to the next `{`.
|
|
65
|
+
while (i < style.length && /\s/.test(style[i]))
|
|
66
|
+
i++;
|
|
67
|
+
const open = style.indexOf("{", i);
|
|
68
|
+
if (open === -1)
|
|
69
|
+
break;
|
|
70
|
+
const key = style.slice(i, open).trim();
|
|
71
|
+
const close = matchBrace(style, open);
|
|
72
|
+
if (key)
|
|
73
|
+
branches[key] = style.slice(open + 1, close);
|
|
74
|
+
i = close + 1;
|
|
75
|
+
}
|
|
76
|
+
return branches;
|
|
77
|
+
}
|
|
78
|
+
/** Split an argument's innards into `name`, `type`, and the raw `style`. */
|
|
79
|
+
function parseArg(inner) {
|
|
80
|
+
const firstComma = inner.indexOf(",");
|
|
81
|
+
if (firstComma === -1)
|
|
82
|
+
return { name: inner.trim() };
|
|
83
|
+
const name = inner.slice(0, firstComma).trim();
|
|
84
|
+
const rest = inner.slice(firstComma + 1);
|
|
85
|
+
const secondComma = rest.indexOf(",");
|
|
86
|
+
if (secondComma === -1)
|
|
87
|
+
return { name, type: rest.trim() };
|
|
88
|
+
return {
|
|
89
|
+
name,
|
|
90
|
+
type: rest.slice(0, secondComma).trim(),
|
|
91
|
+
style: rest.slice(secondComma + 1).trim(),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function numberFormat(locale, style) {
|
|
95
|
+
if (!style)
|
|
96
|
+
return {};
|
|
97
|
+
if (style === "percent")
|
|
98
|
+
return { style: "percent" };
|
|
99
|
+
if (style === "integer")
|
|
100
|
+
return { maximumFractionDigits: 0 };
|
|
101
|
+
// The ICU skeleton for currency: `::currency/USD`.
|
|
102
|
+
const currency = /^::currency\/([A-Z]{3})$/.exec(style);
|
|
103
|
+
if (currency)
|
|
104
|
+
return { style: "currency", currency: currency[1] };
|
|
105
|
+
return {};
|
|
106
|
+
}
|
|
107
|
+
const DATE_STYLES = new Set(["full", "long", "medium", "short"]);
|
|
108
|
+
function dateStyleOf(style, key) {
|
|
109
|
+
const value = style && DATE_STYLES.has(style) ? style : "medium";
|
|
110
|
+
return { [key]: value };
|
|
111
|
+
}
|
|
112
|
+
function toDate(value) {
|
|
113
|
+
if (value instanceof Date)
|
|
114
|
+
return value;
|
|
115
|
+
if (typeof value === "number" || typeof value === "string")
|
|
116
|
+
return new Date(value);
|
|
117
|
+
throw new Error(`i18n: expected a date, got ${typeof value}`);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Format an ICU message. The grammar we support:
|
|
121
|
+
*
|
|
122
|
+
* {name} interpolation
|
|
123
|
+
* {n, number} {n, number, percent} {n, number, ::currency/USD}
|
|
124
|
+
* {d, date, medium} {d, time, short}
|
|
125
|
+
* {c, plural, =0 {none} one {# item} other {# items}}
|
|
126
|
+
* {c, selectordinal, one {#st} two {#nd} few {#rd} other {#th}}
|
|
127
|
+
* {g, select, male {He} female {She} other {They}}
|
|
128
|
+
*
|
|
129
|
+
* `#` inside a plural branch becomes the formatted number. Branches are
|
|
130
|
+
* themselves messages, so they nest. `'{'` and `'}'` are literal braces.
|
|
131
|
+
*/
|
|
132
|
+
export function formatMessage(message, data = {}, locale = "en") {
|
|
133
|
+
let out = "";
|
|
134
|
+
let i = 0;
|
|
135
|
+
while (i < message.length) {
|
|
136
|
+
const char = message[i];
|
|
137
|
+
// ICU escaping: '{' and '}' are literal braces.
|
|
138
|
+
if (char === "'" && (message[i + 1] === "{" || message[i + 1] === "}")) {
|
|
139
|
+
const end = message.indexOf("'", i + 1);
|
|
140
|
+
if (end === -1) {
|
|
141
|
+
out += message.slice(i + 1);
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
out += message.slice(i + 1, end);
|
|
145
|
+
i = end + 1;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (char !== "{") {
|
|
149
|
+
out += char;
|
|
150
|
+
i++;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const close = matchBrace(message, i);
|
|
154
|
+
const { name, type, style } = parseArg(message.slice(i + 1, close));
|
|
155
|
+
const value = data[name];
|
|
156
|
+
i = close + 1;
|
|
157
|
+
if (!type) {
|
|
158
|
+
out += value == null ? "" : String(value);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
switch (type) {
|
|
162
|
+
case "number":
|
|
163
|
+
out += new Intl.NumberFormat(locale, numberFormat(locale, style)).format(Number(value));
|
|
164
|
+
break;
|
|
165
|
+
case "date":
|
|
166
|
+
out += new Intl.DateTimeFormat(locale, dateStyleOf(style, "dateStyle")).format(toDate(value));
|
|
167
|
+
break;
|
|
168
|
+
case "time":
|
|
169
|
+
out += new Intl.DateTimeFormat(locale, dateStyleOf(style, "timeStyle")).format(toDate(value));
|
|
170
|
+
break;
|
|
171
|
+
case "plural":
|
|
172
|
+
case "selectordinal": {
|
|
173
|
+
const count = Number(value);
|
|
174
|
+
const branches = parseBranches(style ?? "");
|
|
175
|
+
// An exact `=N` match wins over the plural category — that's what lets
|
|
176
|
+
// "=0 {Your cart is empty}" say something other than "0 items".
|
|
177
|
+
const category = new Intl.PluralRules(locale, {
|
|
178
|
+
type: type === "plural" ? "cardinal" : "ordinal",
|
|
179
|
+
}).select(count);
|
|
180
|
+
const branch = branches[`=${count}`] ?? branches[category] ?? branches.other ?? "";
|
|
181
|
+
const formatted = new Intl.NumberFormat(locale).format(count);
|
|
182
|
+
// `#` is the count. Recurse first, then substitute, so a nested message
|
|
183
|
+
// can't accidentally eat the marker.
|
|
184
|
+
out += formatMessage(branch, data, locale).replaceAll("#", formatted);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
case "select": {
|
|
188
|
+
const branches = parseBranches(style ?? "");
|
|
189
|
+
const branch = branches[String(value)] ?? branches.other ?? "";
|
|
190
|
+
out += formatMessage(branch, data, locale);
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
default:
|
|
194
|
+
// An unknown type: fall back to interpolation rather than throwing.
|
|
195
|
+
out += value == null ? "" : String(value);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return out;
|
|
199
|
+
}
|
|
200
|
+
/* --------------------------------- locales -------------------------------- */
|
|
201
|
+
/**
|
|
202
|
+
* Pick the best locale for an `Accept-Language` header.
|
|
203
|
+
*
|
|
204
|
+
* negotiateLocale("fr-CA,fr;q=0.9,en;q=0.8", ["en", "fr"], "en") // "fr"
|
|
205
|
+
*
|
|
206
|
+
* Exact matches win, then the language part (`fr-CA` → `fr`), in the client's
|
|
207
|
+
* order of preference. Falls back to `defaultLocale` when nothing matches.
|
|
208
|
+
*/
|
|
209
|
+
export function negotiateLocale(header, supported, defaultLocale) {
|
|
210
|
+
if (!header)
|
|
211
|
+
return defaultLocale;
|
|
212
|
+
const wanted = header
|
|
213
|
+
.split(",")
|
|
214
|
+
.map((part) => {
|
|
215
|
+
const [tag, ...params] = part.trim().split(";");
|
|
216
|
+
const q = params.find((p) => p.trim().startsWith("q="));
|
|
217
|
+
return { tag: (tag ?? "").trim().toLowerCase(), q: q ? Number(q.split("=")[1]) : 1 };
|
|
218
|
+
})
|
|
219
|
+
.filter((entry) => entry.tag && !Number.isNaN(entry.q))
|
|
220
|
+
.sort((a, b) => b.q - a.q);
|
|
221
|
+
const lower = new Map(supported.map((locale) => [locale.toLowerCase(), locale]));
|
|
222
|
+
for (const { tag } of wanted) {
|
|
223
|
+
const exact = lower.get(tag);
|
|
224
|
+
if (exact)
|
|
225
|
+
return exact;
|
|
226
|
+
// `fr-CA` should match a supported `fr`.
|
|
227
|
+
const language = tag.split("-")[0];
|
|
228
|
+
const partial = lower.get(language);
|
|
229
|
+
if (partial)
|
|
230
|
+
return partial;
|
|
231
|
+
}
|
|
232
|
+
return defaultLocale;
|
|
233
|
+
}
|
|
234
|
+
/* ---------------------------------- i18n ---------------------------------- */
|
|
235
|
+
/** One locale, bound to its messages. Get one with `i18n(locale)`. */
|
|
236
|
+
export class I18n {
|
|
237
|
+
locale;
|
|
238
|
+
messages;
|
|
239
|
+
manager;
|
|
240
|
+
constructor(locale, messages, manager) {
|
|
241
|
+
this.locale = locale;
|
|
242
|
+
this.messages = messages;
|
|
243
|
+
this.manager = manager;
|
|
244
|
+
}
|
|
245
|
+
/** Whether a key resolves in this locale (or its fallbacks). */
|
|
246
|
+
has(key) {
|
|
247
|
+
return this.messages[key] !== undefined;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Translate a key, formatting its ICU message with `data`.
|
|
251
|
+
*
|
|
252
|
+
* t("cart.items", { count: 3 }); // "3 items"
|
|
253
|
+
*
|
|
254
|
+
* A missing key doesn't throw — it goes through the configured `missing`
|
|
255
|
+
* handler (which returns the key itself by default, so the page still renders
|
|
256
|
+
* and the gap is obvious) and fires an `i18n.missing` event.
|
|
257
|
+
*/
|
|
258
|
+
t(key, data) {
|
|
259
|
+
const message = this.messages[key];
|
|
260
|
+
if (message === undefined)
|
|
261
|
+
return this.manager.missing(key, this.locale);
|
|
262
|
+
return formatMessage(message, data, this.locale);
|
|
263
|
+
}
|
|
264
|
+
formatNumber(value, options) {
|
|
265
|
+
return new Intl.NumberFormat(this.locale, options).format(value);
|
|
266
|
+
}
|
|
267
|
+
formatCurrency(value, currency, options) {
|
|
268
|
+
return new Intl.NumberFormat(this.locale, { ...options, style: "currency", currency }).format(value);
|
|
269
|
+
}
|
|
270
|
+
formatDate(value, options) {
|
|
271
|
+
return new Intl.DateTimeFormat(this.locale, options ?? { dateStyle: "medium" }).format(toDate(value));
|
|
272
|
+
}
|
|
273
|
+
formatTime(value, options) {
|
|
274
|
+
return new Intl.DateTimeFormat(this.locale, options ?? { timeStyle: "medium" }).format(toDate(value));
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* "3 days ago", "in 2 hours". With no unit, the best one is picked from the
|
|
278
|
+
* distance between `value` and now.
|
|
279
|
+
*/
|
|
280
|
+
formatRelativeTime(value, unit, options) {
|
|
281
|
+
const formatter = new Intl.RelativeTimeFormat(this.locale, { numeric: "auto", ...options });
|
|
282
|
+
const deltaMs = toDate(value).getTime() - Date.now();
|
|
283
|
+
if (unit)
|
|
284
|
+
return formatter.format(Math.round(deltaMs / MS[unit]), unit);
|
|
285
|
+
// Walk from the coarsest unit down; the first one the delta clears wins.
|
|
286
|
+
for (const candidate of AUTO_UNITS) {
|
|
287
|
+
const size = MS[candidate];
|
|
288
|
+
if (Math.abs(deltaMs) >= size || candidate === "second") {
|
|
289
|
+
return formatter.format(Math.round(deltaMs / size), candidate);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return formatter.format(0, "second");
|
|
293
|
+
}
|
|
294
|
+
/** "a, b, and c" — or "a, b, or c" with `{ type: "disjunction" }`. */
|
|
295
|
+
formatList(items, options) {
|
|
296
|
+
return new Intl.ListFormat(this.locale, options).format(items);
|
|
297
|
+
}
|
|
298
|
+
/** The plural category for a count: "one", "other", … */
|
|
299
|
+
formatPlural(count, options) {
|
|
300
|
+
return new Intl.PluralRules(this.locale, options).select(count);
|
|
301
|
+
}
|
|
302
|
+
/** A language/region/currency code as its display name: "fr" → "French". */
|
|
303
|
+
formatDisplayName(code, type = "language") {
|
|
304
|
+
return new Intl.DisplayNames([this.locale], { type }).of(code) ?? code;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
const MS = {
|
|
308
|
+
year: 31_536_000_000,
|
|
309
|
+
quarter: 7_884_000_000,
|
|
310
|
+
month: 2_628_000_000,
|
|
311
|
+
week: 604_800_000,
|
|
312
|
+
day: 86_400_000,
|
|
313
|
+
hour: 3_600_000,
|
|
314
|
+
minute: 60_000,
|
|
315
|
+
second: 1_000,
|
|
316
|
+
};
|
|
317
|
+
const AUTO_UNITS = [
|
|
318
|
+
"year",
|
|
319
|
+
"month",
|
|
320
|
+
"week",
|
|
321
|
+
"day",
|
|
322
|
+
"hour",
|
|
323
|
+
"minute",
|
|
324
|
+
"second",
|
|
325
|
+
];
|
|
326
|
+
export class I18nManager {
|
|
327
|
+
translations = new Map();
|
|
328
|
+
options;
|
|
329
|
+
constructor(options = {}) {
|
|
330
|
+
this.options = {
|
|
331
|
+
defaultLocale: options.defaultLocale ?? "en",
|
|
332
|
+
fallbackLocales: options.fallbackLocales ?? {},
|
|
333
|
+
missing: options.missing ?? ((key) => key),
|
|
334
|
+
supportedLocales: options.supportedLocales,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
get defaultLocale() {
|
|
338
|
+
return this.options.defaultLocale;
|
|
339
|
+
}
|
|
340
|
+
/** Add translations, merging into whatever is already loaded. */
|
|
341
|
+
add(data) {
|
|
342
|
+
for (const [locale, messages] of Object.entries(data)) {
|
|
343
|
+
const existing = this.translations.get(locale) ?? {};
|
|
344
|
+
this.translations.set(locale, { ...existing, ...flatten(messages) });
|
|
345
|
+
}
|
|
346
|
+
return this;
|
|
347
|
+
}
|
|
348
|
+
/** Load from one or more loaders. */
|
|
349
|
+
async load(...loaders) {
|
|
350
|
+
for (const loader of loaders)
|
|
351
|
+
this.add(await loader.load());
|
|
352
|
+
return this;
|
|
353
|
+
}
|
|
354
|
+
/** The locales this app serves. */
|
|
355
|
+
supported() {
|
|
356
|
+
return this.options.supportedLocales ?? [...this.translations.keys()];
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* The chain to try for a locale: itself, its configured fallback, its language
|
|
360
|
+
* prefix (`es-MX` → `es`), then the default. That's what makes a regional
|
|
361
|
+
* locale usable with only the base language translated.
|
|
362
|
+
*/
|
|
363
|
+
chain(locale) {
|
|
364
|
+
const chain = [locale];
|
|
365
|
+
const configured = this.options.fallbackLocales[locale];
|
|
366
|
+
if (configured)
|
|
367
|
+
chain.push(configured);
|
|
368
|
+
const language = locale.split("-")[0];
|
|
369
|
+
if (language !== locale)
|
|
370
|
+
chain.push(language);
|
|
371
|
+
chain.push(this.options.defaultLocale);
|
|
372
|
+
return [...new Set(chain)];
|
|
373
|
+
}
|
|
374
|
+
/** An `I18n` for a locale, with its fallback chain already flattened in. */
|
|
375
|
+
locale(code) {
|
|
376
|
+
const locale = code ?? this.options.defaultLocale;
|
|
377
|
+
// Later entries in the chain fill only the gaps the earlier ones leave.
|
|
378
|
+
const merged = {};
|
|
379
|
+
for (const candidate of this.chain(locale).reverse()) {
|
|
380
|
+
Object.assign(merged, this.translations.get(candidate) ?? {});
|
|
381
|
+
}
|
|
382
|
+
return new I18n(locale, merged, this);
|
|
383
|
+
}
|
|
384
|
+
/** What to render for a missing key — and a chance to notice it. */
|
|
385
|
+
missing(key, locale) {
|
|
386
|
+
if (hasApplication())
|
|
387
|
+
void emit("i18n.missing", { key, locale });
|
|
388
|
+
return this.options.missing(key, locale);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/* --------------------------------- global --------------------------------- */
|
|
392
|
+
let manager = new I18nManager();
|
|
393
|
+
/** Replace the i18n manager (options and all). */
|
|
394
|
+
export function setI18n(next) {
|
|
395
|
+
manager = next;
|
|
396
|
+
return manager;
|
|
397
|
+
}
|
|
398
|
+
/** The active i18n manager. */
|
|
399
|
+
export function getI18n() {
|
|
400
|
+
return manager;
|
|
401
|
+
}
|
|
402
|
+
/** Register translations on the active manager. */
|
|
403
|
+
export function setTranslations(data) {
|
|
404
|
+
return manager.add(data);
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* An `I18n` for a locale — or, with no argument, the **current request's** locale
|
|
408
|
+
* (set by `detectLocale()`), falling back to the default outside a request.
|
|
409
|
+
*/
|
|
410
|
+
export function i18n(locale) {
|
|
411
|
+
return manager.locale(locale ?? currentLocale());
|
|
412
|
+
}
|
|
413
|
+
/** Translate a key in the current request's locale. */
|
|
414
|
+
export function t(key, data) {
|
|
415
|
+
return i18n().t(key, data);
|
|
416
|
+
}
|
|
417
|
+
/** Translations from a plain object — the simplest loader. */
|
|
418
|
+
export function objectLoader(data) {
|
|
419
|
+
return { load: () => data };
|
|
420
|
+
}
|
|
421
|
+
/* ------------------------------- the request ------------------------------ */
|
|
422
|
+
/**
|
|
423
|
+
* The locale `detectLocale()` stored on this request, if we're in one. Outside a
|
|
424
|
+
* request — a CLI command, a queue worker — there's no context, and that's fine:
|
|
425
|
+
* `i18n()` falls back to the default locale.
|
|
426
|
+
*/
|
|
427
|
+
function currentLocale() {
|
|
428
|
+
try {
|
|
429
|
+
return getContext().get("locale");
|
|
430
|
+
}
|
|
431
|
+
catch {
|
|
432
|
+
return undefined;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Work out the request's locale and stash it, so `t()` and `i18n()` pick it up
|
|
437
|
+
* anywhere in the request without threading it through.
|
|
438
|
+
*
|
|
439
|
+
* this.use(detectLocale()); // Accept-Language
|
|
440
|
+
* this.use(detectLocale({ query: "lang" })); // ?lang=fr wins
|
|
441
|
+
*
|
|
442
|
+
* Precedence: `resolve` → query → cookie → `Accept-Language` → the default. Only
|
|
443
|
+
* **supported** locales are honored, so `?lang=xx` can't put the app into a locale
|
|
444
|
+
* you have no translations for.
|
|
445
|
+
*/
|
|
446
|
+
export function detectLocale(options = {}) {
|
|
447
|
+
return async (c, next) => {
|
|
448
|
+
const supported = manager.supported();
|
|
449
|
+
const isSupported = (value) => value !== undefined && supported.includes(value);
|
|
450
|
+
let locale;
|
|
451
|
+
const custom = options.resolve?.(c);
|
|
452
|
+
if (isSupported(custom))
|
|
453
|
+
locale = custom;
|
|
454
|
+
if (!locale && options.query) {
|
|
455
|
+
const value = new URL(c.req.url).searchParams.get(options.query) ?? undefined;
|
|
456
|
+
if (isSupported(value))
|
|
457
|
+
locale = value;
|
|
458
|
+
}
|
|
459
|
+
if (!locale && options.cookie) {
|
|
460
|
+
const cookies = c.req.header("Cookie") ?? "";
|
|
461
|
+
const match = new RegExp(`(?:^|;\\s*)${options.cookie}=([^;]+)`).exec(cookies);
|
|
462
|
+
const value = match?.[1];
|
|
463
|
+
if (isSupported(value))
|
|
464
|
+
locale = value;
|
|
465
|
+
}
|
|
466
|
+
if (!locale && options.header !== false) {
|
|
467
|
+
locale = negotiateLocale(c.req.header("Accept-Language"), supported, manager.defaultLocale);
|
|
468
|
+
}
|
|
469
|
+
c.set("locale", locale ?? manager.defaultLocale);
|
|
470
|
+
await next();
|
|
471
|
+
};
|
|
472
|
+
}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -4,19 +4,28 @@ export type { Token, Constructor, Factory } from "./container.js";
|
|
|
4
4
|
export { Application } from "./application.js";
|
|
5
5
|
export type { BootOptions, LifecycleHook, Configurator } from "./application.js";
|
|
6
6
|
export { Config, env } from "./config.js";
|
|
7
|
+
export { defineEnv, envVar, EnvValidationError } from "./env.js";
|
|
8
|
+
export type { EnvRule, EnvSchema, EnvValues, EnvType, DefineEnvOptions } from "./env.js";
|
|
7
9
|
export { app, config, view, bind, singleton, instance, make, bound, alias, swap, restore, events, emit, listen, cache, logger, onReady, onShutdown, terminate, } from "./helpers.js";
|
|
8
10
|
export { Logger } from "./logger.js";
|
|
9
|
-
export
|
|
11
|
+
export { consoleSink, MemorySink, setLogger, namedLogger, tapLogs } from "./logger.js";
|
|
12
|
+
export type { LogLevel, LoggerOptions, LogRecord, Sink, RedactOptions } from "./logger.js";
|
|
10
13
|
export { requestLogger, requestLog } from "./request-logger.js";
|
|
11
14
|
export type { RequestLoggerOptions } from "./request-logger.js";
|
|
12
|
-
export { Events } from "./events.js";
|
|
13
|
-
export type { Listener } from "./events.js";
|
|
15
|
+
export { Events, EventBuffer } from "./events.js";
|
|
16
|
+
export type { Listener, AnyListener, ErrorHandler, EventsList, EventName, PayloadOf, RecordedEvent, } from "./events.js";
|
|
14
17
|
export { Cache, MemoryStore } from "./cache.js";
|
|
15
|
-
export type { CacheStore } from "./cache.js";
|
|
18
|
+
export type { CacheStore, RememberOptions, PutOptions } from "./cache.js";
|
|
16
19
|
export { serveStatic } from "./static.js";
|
|
17
20
|
export type { StaticOptions } from "./static.js";
|
|
18
|
-
export {
|
|
19
|
-
export type {
|
|
21
|
+
export { i18n, t, getI18n, setI18n, setTranslations, objectLoader, detectLocale, negotiateLocale, formatMessage, I18n, I18nManager, } from "./i18n.js";
|
|
22
|
+
export type { Translations, TranslationsByLocale, TranslationLoader, I18nOptions, DetectLocaleOptions, } from "./i18n.js";
|
|
23
|
+
export { lock, restoreLock, setLockStore, getLockStore, Lock, MemoryLockStore, LockNotHeldError, } from "./lock.js";
|
|
24
|
+
export type { LockStore, AcquireOptions } from "./lock.js";
|
|
25
|
+
export { health, healthCheck, check, Result, BaseCheck, HealthChecks, DatabaseCheck, RedisCheck, CacheCheck, } from "./health.js";
|
|
26
|
+
export type { HealthStatus, HealthReport, CheckReport, HealthCheckOptions, } from "./health.js";
|
|
27
|
+
export { Storage, FakeStorage, MemoryDisk, storage, setDisk, fakeDisk, restoreDisk, serveStorage, signStorageUrl, verifyStorageUrl, contentTypeFor, } from "./storage.js";
|
|
28
|
+
export type { Disk, Contents, FileVisibility, WriteOptions, FileMetadata, SignedFileOptions, SignedUploadOptions, ServeStorageOptions, } from "./storage.js";
|
|
20
29
|
export { dump, dd } from "./debug.js";
|
|
21
30
|
export { hash, encryption, jwt } from "./crypto.js";
|
|
22
31
|
export type { JwtPayload, JwtSignOptions, JwtVerifyOptions, EncryptOptions } from "./crypto.js";
|
|
@@ -28,17 +37,17 @@ export { securityHeaders } from "./shield.js";
|
|
|
28
37
|
export type { SecurityHeadersOptions, HstsOptions } from "./shield.js";
|
|
29
38
|
export { csrf, csrfToken, csrfField } from "./csrf.js";
|
|
30
39
|
export type { CsrfOptions } from "./csrf.js";
|
|
31
|
-
export { db, connection, setConnection, addConnection, setDefaultConnection, connectionNames, clearConnections, QueryBuilder, } from "./database.js";
|
|
32
|
-
export type { Connection, ConnectionHandle, WriteResult, Row, Dialect, Operator, Paginated } from "./database.js";
|
|
40
|
+
export { db, connection, getConnection, setConnection, addConnection, setDefaultConnection, connectionNames, clearConnections, transaction, inTransaction, QueryBuilder, } from "./database.js";
|
|
41
|
+
export type { Connection, TransactionConnection, TransactionHandle, ConnectionHandle, WriteResult, Row, Dialect, Operator, Paginated, } from "./database.js";
|
|
33
42
|
export { Model } from "./model.js";
|
|
34
43
|
export type { CastType, Casts } from "./casts.js";
|
|
35
44
|
export { Relation, HasOne, HasMany, BelongsTo, BelongsToMany } from "./relations.js";
|
|
36
45
|
export { Faker, Factory as ModelFactory, factory, Seeder, seed } from "./factory.js";
|
|
37
46
|
export type { Definition } from "./factory.js";
|
|
38
|
-
export { Mailer, PendingMail, ArrayTransport, LogTransport, fetchTransport, mail, setMailer, getMailer, } from "./mail.js";
|
|
39
|
-
export type { Message, Transport, MailerOptions, FetchTransportOptions } from "./mail.js";
|
|
40
|
-
export { Job, Queue, SyncDriver, MemoryDriver, dispatch, work, setQueue, getQueue, } from "./queue.js";
|
|
41
|
-
export type { Dispatchable, JobOptions, QueueDriver, Drainable, QueuedJob } from "./queue.js";
|
|
47
|
+
export { Mailer, FakeMailer, PendingMail, BaseMail, SendMailJob, ArrayTransport, LogTransport, fetchTransport, mail, mailer, send, sendLater, setMailer, getMailer, fakeMail, restoreMail, } from "./mail.js";
|
|
48
|
+
export type { Message, Transport, MailerOptions, FetchTransportOptions, Attachment, RecordedMail, } from "./mail.js";
|
|
49
|
+
export { Job, Queue, FakeQueue, SyncDriver, MemoryDriver, dispatch, work, setQueue, getQueue, fakeQueue, restoreQueue, exponentialBackoff, linearBackoff, fixedBackoff, noBackoff, } from "./queue.js";
|
|
50
|
+
export type { Dispatchable, JobOptions, JobContext, JobClass, QueueDriver, Drainable, QueuedJob, FailedJob, Backoff, } from "./queue.js";
|
|
42
51
|
export { Scheduler, ScheduledTask, scheduler, setScheduler, schedule, cronMatches } from "./scheduler.js";
|
|
43
52
|
export { MemoryBroadcaster, broadcast, setBroadcaster, getBroadcaster, channelAuth, authorizeChannel, clearChannels, } from "./broadcasting.js";
|
|
44
53
|
export type { Broadcaster, Subscriber, ChannelAuthorizer } from "./broadcasting.js";
|
|
@@ -58,12 +67,29 @@ export { TemplateEngine, escapeHtml, templates, setTemplateEngine, render, } fro
|
|
|
58
67
|
export type { Filter, RenderContext } from "./template.js";
|
|
59
68
|
export { ServiceProvider } from "./provider.js";
|
|
60
69
|
export type { ProviderClass } from "./provider.js";
|
|
70
|
+
export { PackageProvider, MigrationRegistry, CommandRegistry, PublishRegistry, } from "./package.js";
|
|
71
|
+
export type { PackageCommand, PublishEntry, PackageRouteOptions, PackageAssetOptions, PackageMiddleware, } from "./package.js";
|
|
72
|
+
export { instrument, runRequest, currentRequestId, newRequestId, } from "./instrumentation.js";
|
|
73
|
+
export type { QueryEvent, RequestEvent, ExceptionEvent, JobEvent, CacheEvent, NotificationEvent, ScheduleEvent, InstrumentEvent, } from "./instrumentation.js";
|
|
61
74
|
export { Router, Route, RouteGroup, RouteResource, matchers } from "./http/router.js";
|
|
62
75
|
export type { Ctx, RouteHandler, RouteDefinition, Method, Matcher, MiddlewareRef, UrlOptions, SignedUrlOptions, } from "./http/router.js";
|
|
63
76
|
export { Inertia, inertia, inertiaPageAttr } from "./inertia.js";
|
|
64
77
|
export type { InertiaPage, InertiaOptions } from "./inertia.js";
|
|
65
78
|
export { HttpKernel } from "./http/kernel.js";
|
|
66
|
-
export {
|
|
79
|
+
export { defineCommand, arg, flag, ConsoleKernel, ConsoleError, parseArgv } from "./console.js";
|
|
80
|
+
export type { CommandDefinition, CommandContext, AnyCommand, ArgSpec, FlagSpec, ArgsSpec, FlagsSpec, ConsoleKernelOptions, } from "./console.js";
|
|
81
|
+
export { createUi, stripAnsi } from "./console-ui.js";
|
|
82
|
+
export type { Ui, UiOptions, Colors, ColorName, Table, Tasks, TaskHandle } from "./console-ui.js";
|
|
83
|
+
export { createPrompt } from "./console-prompt.js";
|
|
84
|
+
export type { Prompt, PromptOptions, ChoiceOptions, Choice, Trap } from "./console-prompt.js";
|
|
85
|
+
export { startRepl } from "./repl.js";
|
|
86
|
+
export type { ReplHelper, ReplOptions } from "./repl.js";
|
|
87
|
+
export { pages, definePages, routePattern, routeName } from "./pages.js";
|
|
88
|
+
export type { PageProps, PageModule, PagesOptions, RegisteredPage, PageMiddleware } from "./pages.js";
|
|
89
|
+
export { TestClient, TestResponse, CommandResult, testClient, runCommand, resetState, freezeTime, timeTravel, restoreTime, timeIsFrozen, spy, spyOn, restoreSpies, truncate, assertDatabaseHas, assertDatabaseMissing, assertDatabaseCount, assertDatabaseEmpty, } from "./testing.js";
|
|
90
|
+
export type { Spy } from "./testing.js";
|
|
91
|
+
export { Tracer, Span, MemoryExporter, otlpExporter, consoleExporter, telemetry, setTelemetry, trace, currentSpan, setAttributes, addEvent, traceIds, flushTelemetry, tracing, parseTraceparent, traceparent, injectTraceContext, } from "./telemetry.js";
|
|
92
|
+
export type { SpanContext, SpanData, SpanEvent, SpanKind, SpanStatus, SpanOptions, SpanExporter, SpanAttributes, SpanAttributeValue, TracerOptions, TracingOptions, OtlpOptions, } from "./telemetry.js";
|
|
67
93
|
export { HttpException, BadRequestException, UnauthorizedException, PaymentRequiredException, ForbiddenException, NotFoundException, MethodNotAllowedException, NotAcceptableException, RequestTimeoutException, ConflictException, LengthRequiredException, ValidationException, TooManyRequestsException, ServerErrorException, NotImplementedException, BadGatewayException, ServiceUnavailableException, createError, STATUS_TEXT, } from "./exceptions.js";
|
|
68
94
|
export { validate, validateRequest, validated } from "./validation.js";
|
|
69
95
|
export type { Schema, RequestSchemas } from "./validation.js";
|
package/dist/core/index.js
CHANGED
|
@@ -2,25 +2,30 @@
|
|
|
2
2
|
export { Container } from "./container.js";
|
|
3
3
|
export { Application } from "./application.js";
|
|
4
4
|
export { Config, env } from "./config.js";
|
|
5
|
+
export { defineEnv, envVar, EnvValidationError } from "./env.js";
|
|
5
6
|
export { app, config, view, bind, singleton, instance, make, bound, alias, swap, restore, events, emit, listen, cache, logger, onReady, onShutdown, terminate, } from "./helpers.js";
|
|
6
7
|
export { Logger } from "./logger.js";
|
|
8
|
+
export { consoleSink, MemorySink, setLogger, namedLogger, tapLogs } from "./logger.js";
|
|
7
9
|
export { requestLogger, requestLog } from "./request-logger.js";
|
|
8
|
-
export { Events } from "./events.js";
|
|
10
|
+
export { Events, EventBuffer } from "./events.js";
|
|
9
11
|
export { Cache, MemoryStore } from "./cache.js";
|
|
10
12
|
export { serveStatic } from "./static.js";
|
|
11
|
-
export {
|
|
13
|
+
export { i18n, t, getI18n, setI18n, setTranslations, objectLoader, detectLocale, negotiateLocale, formatMessage, I18n, I18nManager, } from "./i18n.js";
|
|
14
|
+
export { lock, restoreLock, setLockStore, getLockStore, Lock, MemoryLockStore, LockNotHeldError, } from "./lock.js";
|
|
15
|
+
export { health, healthCheck, check, Result, BaseCheck, HealthChecks, DatabaseCheck, RedisCheck, CacheCheck, } from "./health.js";
|
|
16
|
+
export { Storage, FakeStorage, MemoryDisk, storage, setDisk, fakeDisk, restoreDisk, serveStorage, signStorageUrl, verifyStorageUrl, contentTypeFor, } from "./storage.js";
|
|
12
17
|
export { dump, dd } from "./debug.js";
|
|
13
18
|
export { hash, encryption, jwt } from "./crypto.js";
|
|
14
19
|
export { rateLimiter } from "./rate-limit.js";
|
|
15
20
|
export { cors } from "./cors.js";
|
|
16
21
|
export { securityHeaders } from "./shield.js";
|
|
17
22
|
export { csrf, csrfToken, csrfField } from "./csrf.js";
|
|
18
|
-
export { db, connection, setConnection, addConnection, setDefaultConnection, connectionNames, clearConnections, QueryBuilder, } from "./database.js";
|
|
23
|
+
export { db, connection, getConnection, setConnection, addConnection, setDefaultConnection, connectionNames, clearConnections, transaction, inTransaction, QueryBuilder, } from "./database.js";
|
|
19
24
|
export { Model } from "./model.js";
|
|
20
25
|
export { Relation, HasOne, HasMany, BelongsTo, BelongsToMany } from "./relations.js";
|
|
21
26
|
export { Faker, Factory as ModelFactory, factory, Seeder, seed } from "./factory.js";
|
|
22
|
-
export { Mailer, PendingMail, ArrayTransport, LogTransport, fetchTransport, mail, setMailer, getMailer, } from "./mail.js";
|
|
23
|
-
export { Job, Queue, SyncDriver, MemoryDriver, dispatch, work, setQueue, getQueue, } from "./queue.js";
|
|
27
|
+
export { Mailer, FakeMailer, PendingMail, BaseMail, SendMailJob, ArrayTransport, LogTransport, fetchTransport, mail, mailer, send, sendLater, setMailer, getMailer, fakeMail, restoreMail, } from "./mail.js";
|
|
28
|
+
export { Job, Queue, FakeQueue, SyncDriver, MemoryDriver, dispatch, work, setQueue, getQueue, fakeQueue, restoreQueue, exponentialBackoff, linearBackoff, fixedBackoff, noBackoff, } from "./queue.js";
|
|
24
29
|
export { Scheduler, ScheduledTask, scheduler, setScheduler, schedule, cronMatches } from "./scheduler.js";
|
|
25
30
|
export { MemoryBroadcaster, broadcast, setBroadcaster, getBroadcaster, channelAuth, authorizeChannel, clearChannels, } from "./broadcasting.js";
|
|
26
31
|
export { Redis, MemoryRedis, redis, setRedis, redisStore } from "./redis.js";
|
|
@@ -31,10 +36,18 @@ export { decorateRequest, hasRequestDecorator, decorated, setRequestValue, clear
|
|
|
31
36
|
export { View } from "./view.js";
|
|
32
37
|
export { TemplateEngine, escapeHtml, templates, setTemplateEngine, render, } from "./template.js";
|
|
33
38
|
export { ServiceProvider } from "./provider.js";
|
|
39
|
+
export { PackageProvider, MigrationRegistry, CommandRegistry, PublishRegistry, } from "./package.js";
|
|
40
|
+
export { instrument, runRequest, currentRequestId, newRequestId, } from "./instrumentation.js";
|
|
34
41
|
export { Router, Route, RouteGroup, RouteResource, matchers } from "./http/router.js";
|
|
35
42
|
export { Inertia, inertia, inertiaPageAttr } from "./inertia.js";
|
|
36
43
|
export { HttpKernel } from "./http/kernel.js";
|
|
37
|
-
export {
|
|
44
|
+
export { defineCommand, arg, flag, ConsoleKernel, ConsoleError, parseArgv } from "./console.js";
|
|
45
|
+
export { createUi, stripAnsi } from "./console-ui.js";
|
|
46
|
+
export { createPrompt } from "./console-prompt.js";
|
|
47
|
+
export { startRepl } from "./repl.js";
|
|
48
|
+
export { pages, definePages, routePattern, routeName } from "./pages.js";
|
|
49
|
+
export { TestClient, TestResponse, CommandResult, testClient, runCommand, resetState, freezeTime, timeTravel, restoreTime, timeIsFrozen, spy, spyOn, restoreSpies, truncate, assertDatabaseHas, assertDatabaseMissing, assertDatabaseCount, assertDatabaseEmpty, } from "./testing.js";
|
|
50
|
+
export { Tracer, Span, MemoryExporter, otlpExporter, consoleExporter, telemetry, setTelemetry, trace, currentSpan, setAttributes, addEvent, traceIds, flushTelemetry, tracing, parseTraceparent, traceparent, injectTraceContext, } from "./telemetry.js";
|
|
38
51
|
export { HttpException, BadRequestException, UnauthorizedException, PaymentRequiredException, ForbiddenException, NotFoundException, MethodNotAllowedException, NotAcceptableException, RequestTimeoutException, ConflictException, LengthRequiredException, ValidationException, TooManyRequestsException, ServerErrorException, NotImplementedException, BadGatewayException, ServiceUnavailableException, createError, STATUS_TEXT, } from "./exceptions.js";
|
|
39
52
|
export { validate, validateRequest, validated } from "./validation.js";
|
|
40
53
|
export { Session, session, sessionMiddleware } from "./session.js";
|