@getstrata/core 2.2.12 → 2.2.13
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
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# @getstrata/core changelog
|
|
2
2
|
|
|
3
|
+
## 2.2.13
|
|
4
|
+
|
|
5
|
+
- Improve view rendering and better htmx support
|
|
6
|
+
|
|
3
7
|
## 2.2.12
|
|
4
8
|
|
|
5
9
|
- Require Bun >=1.4.3; align CI, generated/existing example runtime pins and Docker stages to 1.4.3, with bun-types >=1.4.3 behind the official @types/bun shim.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
export type { LayoutDataResolver } from "./etaViewEngine";
|
|
1
|
+
export type { LayoutDataResolver, RenderOptions } from "./etaViewEngine";
|
|
2
2
|
export { DEFAULT_VIEWS_DIRECTORY, EtaViewEngine } from "./etaViewEngine";
|
|
3
3
|
export { htmlResponse, isHtmxRequest, redirectResponse, rssResponse, textResponse, xmlResponse, } from "./htmlResponse";
|
|
4
4
|
export type { ViewEngine } from "./viewEngine";
|
|
5
|
+
export type { HtmxViewResponseOptions, ViewResponseOptions } from "./viewRenderer";
|
|
6
|
+
export { CORE_VIEW_RENDERER_TOKEN, ViewRenderer } from "./viewRenderer";
|
|
5
7
|
export type { WebErrorViewInput, WebErrorViewOptions } from "./webErrorView";
|
|
6
8
|
export { configureWebErrorView, errorTemplateName, htmlErrorResponse, notFoundHtmlResponse, renderKernelErrorChrome, renderWebErrorHtml, } from "./webErrorView";
|
|
7
9
|
export type { WebLayoutAuthUser, WebLayoutData, WebLayoutDataOptions, WebLayoutUserKey, } from "./webLayoutData";
|
|
8
|
-
export { configureWebLayoutData, resolveWebLayoutData } from "./webLayoutData";
|
|
10
|
+
export { configureWebLayoutData, createWebLayoutDataResolver, resolveWebLayoutData, } from "./webLayoutData";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ViewEngine } from "./viewEngine";
|
|
2
|
+
interface ViewResponseOptions {
|
|
3
|
+
layout?: string | false;
|
|
4
|
+
request?: Request;
|
|
5
|
+
status?: number;
|
|
6
|
+
statusText?: string;
|
|
7
|
+
headers?: ConstructorParameters<typeof Headers>[0];
|
|
8
|
+
}
|
|
9
|
+
interface HtmxViewResponseOptions extends ViewResponseOptions {
|
|
10
|
+
/** Optional fragment template; otherwise render the page template without its layout. */
|
|
11
|
+
fragment?: string;
|
|
12
|
+
}
|
|
13
|
+
/** App-owned renderer; request data stays in the engine's async resolver. */
|
|
14
|
+
declare class ViewRenderer {
|
|
15
|
+
private readonly engine;
|
|
16
|
+
private readonly defaultLayout?;
|
|
17
|
+
constructor(engine: ViewEngine, defaultLayout?: string | false | undefined);
|
|
18
|
+
render(name: string, data?: Record<string, unknown>, options?: ViewResponseOptions): Promise<Response>;
|
|
19
|
+
/** Opt-in representation selection; auth/CSRF/tenancy remain the route's responsibility. */
|
|
20
|
+
renderHtmx(name: string, data?: Record<string, unknown>, options?: HtmxViewResponseOptions): Promise<Response>;
|
|
21
|
+
}
|
|
22
|
+
declare const CORE_VIEW_RENDERER_TOKEN: import("../contracts/container").ServiceToken<ViewRenderer>;
|
|
23
|
+
export type { HtmxViewResponseOptions, ViewResponseOptions };
|
|
24
|
+
export { CORE_VIEW_RENDERER_TOKEN, ViewRenderer };
|
|
@@ -24,5 +24,7 @@ interface WebLayoutDataOptions {
|
|
|
24
24
|
declare function configureWebLayoutData(options: WebLayoutDataOptions): void;
|
|
25
25
|
declare function resetWebLayoutDataConfigForTests(): void;
|
|
26
26
|
declare function resolveWebLayoutData(container: ServiceContainerLike, request?: Request, options?: WebLayoutDataOptions): Promise<Record<string, unknown>>;
|
|
27
|
+
/** Isolated configuration for one app; does not read legacy global defaults. */
|
|
28
|
+
declare function createWebLayoutDataResolver(container: ServiceContainerLike, options?: WebLayoutDataOptions): (request?: Request) => Promise<Record<string, unknown>>;
|
|
27
29
|
export type { WebLayoutAuthUser, WebLayoutData, WebLayoutDataOptions, WebLayoutUserKey };
|
|
28
|
-
export { configureWebLayoutData, resetWebLayoutDataConfigForTests, resolveWebLayoutData };
|
|
30
|
+
export { configureWebLayoutData, createWebLayoutDataResolver, resetWebLayoutDataConfigForTests, resolveWebLayoutData, };
|
|
@@ -169,6 +169,7 @@ export type { TracingOptions, TracingRuntime } from "../core/tracing/tracingMidd
|
|
|
169
169
|
export { acquireTracingRuntime, createTracingMiddleware, createTracingRuntime, getTracingRuntime, } from "../core/tracing/tracingMiddleware.ts";
|
|
170
170
|
export type { ValidationRule, ValidationSchema } from "../core/validation/rules.ts";
|
|
171
171
|
export { emailRule, maxLength, minLength, required, stringRule, validateObject, } from "../core/validation/rules.ts";
|
|
172
|
-
export { configureWebErrorView, configureWebLayoutData, DEFAULT_VIEWS_DIRECTORY, EtaViewEngine, errorTemplateName, htmlErrorResponse, htmlResponse, isHtmxRequest, notFoundHtmlResponse, redirectResponse, renderKernelErrorChrome, renderWebErrorHtml, resolveWebLayoutData, rssResponse, textResponse, xmlResponse, } from "../core/view/index.ts";
|
|
172
|
+
export { CORE_VIEW_RENDERER_TOKEN, configureWebErrorView, configureWebLayoutData, createWebLayoutDataResolver, DEFAULT_VIEWS_DIRECTORY, EtaViewEngine, errorTemplateName, htmlErrorResponse, htmlResponse, isHtmxRequest, notFoundHtmlResponse, redirectResponse, renderKernelErrorChrome, renderWebErrorHtml, resolveWebLayoutData, rssResponse, textResponse, ViewRenderer, xmlResponse, } from "../core/view/index.ts";
|
|
173
173
|
export type { ViewEngine } from "../core/view/viewEngine.ts";
|
|
174
|
+
export type { HtmxViewResponseOptions, ViewResponseOptions } from "../core/view/viewRenderer.ts";
|
|
174
175
|
export type { WebLayoutAuthUser, WebLayoutData, WebLayoutDataOptions, WebLayoutUserKey, } from "../core/view/webLayoutData.ts";
|
package/dist/index.js
CHANGED
|
@@ -16118,6 +16118,56 @@ class EtaViewEngine {
|
|
|
16118
16118
|
});
|
|
16119
16119
|
}
|
|
16120
16120
|
}
|
|
16121
|
+
// ../../src/core/view/viewRenderer.ts
|
|
16122
|
+
var HTMX_VARY_HEADERS = ["HX-Request", "HX-Boosted", "HX-History-Restore-Request"];
|
|
16123
|
+
function varyByHtmx(headers) {
|
|
16124
|
+
const existing = (headers.get("Vary") ?? "").split(",").map((field) => field.trim());
|
|
16125
|
+
if (existing.includes("*"))
|
|
16126
|
+
return;
|
|
16127
|
+
const fields = new Map;
|
|
16128
|
+
for (const field of [...existing, ...HTMX_VARY_HEADERS]) {
|
|
16129
|
+
if (field)
|
|
16130
|
+
fields.set(field.toLowerCase(), field);
|
|
16131
|
+
}
|
|
16132
|
+
headers.set("Vary", [...fields.values()].join(", "));
|
|
16133
|
+
}
|
|
16134
|
+
|
|
16135
|
+
class ViewRenderer {
|
|
16136
|
+
engine;
|
|
16137
|
+
defaultLayout;
|
|
16138
|
+
constructor(engine, defaultLayout) {
|
|
16139
|
+
this.engine = engine;
|
|
16140
|
+
this.defaultLayout = defaultLayout;
|
|
16141
|
+
}
|
|
16142
|
+
async render(name, data = {}, options = {}) {
|
|
16143
|
+
const html = await this.engine.render(name, data, {
|
|
16144
|
+
request: options.request,
|
|
16145
|
+
layout: options.layout ?? this.defaultLayout
|
|
16146
|
+
});
|
|
16147
|
+
const headers = new Headers(options.headers);
|
|
16148
|
+
headers.set("Content-Type", "text/html; charset=utf-8");
|
|
16149
|
+
return new Response(html, {
|
|
16150
|
+
status: options.status ?? 200,
|
|
16151
|
+
statusText: options.statusText,
|
|
16152
|
+
headers
|
|
16153
|
+
});
|
|
16154
|
+
}
|
|
16155
|
+
async renderHtmx(name, data = {}, options = {}) {
|
|
16156
|
+
const request = options.request ?? currentRequestMeta().request;
|
|
16157
|
+
if (!request)
|
|
16158
|
+
throw new Error("HTMX view rendering requires a request.");
|
|
16159
|
+
const fragment = request.headers.get("HX-Request") === "true" && request.headers.get("HX-Boosted") !== "true" && request.headers.get("HX-History-Restore-Request") !== "true";
|
|
16160
|
+
const headers = new Headers(options.headers);
|
|
16161
|
+
varyByHtmx(headers);
|
|
16162
|
+
return this.render(fragment ? options.fragment ?? name : name, data, {
|
|
16163
|
+
...options,
|
|
16164
|
+
request,
|
|
16165
|
+
headers,
|
|
16166
|
+
layout: fragment ? false : options.layout
|
|
16167
|
+
});
|
|
16168
|
+
}
|
|
16169
|
+
}
|
|
16170
|
+
var CORE_VIEW_RENDERER_TOKEN = createServiceToken("core.viewRenderer");
|
|
16121
16171
|
// ../../src/core/view/webLayoutData.ts
|
|
16122
16172
|
var configuredLayoutOptions = {};
|
|
16123
16173
|
function configureWebLayoutData(options) {
|
|
@@ -16156,6 +16206,16 @@ async function defaultLoadLayoutUser(container, _request) {
|
|
|
16156
16206
|
}
|
|
16157
16207
|
async function resolveWebLayoutData(container, request, options = {}) {
|
|
16158
16208
|
const resolved = { ...configuredLayoutOptions, ...options };
|
|
16209
|
+
return loadWebLayoutData(container, request, resolved);
|
|
16210
|
+
}
|
|
16211
|
+
function createWebLayoutDataResolver(container, options = {}) {
|
|
16212
|
+
const scoped = {
|
|
16213
|
+
...options,
|
|
16214
|
+
extra: typeof options.extra === "function" ? options.extra : { ...options.extra }
|
|
16215
|
+
};
|
|
16216
|
+
return (request) => loadWebLayoutData(container, request, scoped);
|
|
16217
|
+
}
|
|
16218
|
+
async function loadWebLayoutData(container, request, resolved) {
|
|
16159
16219
|
const csrfToken = request ? resolveCsrfTokenForRequest(request) : "";
|
|
16160
16220
|
const flash = request ? currentRequestMeta().flash ?? pullFlash(request) : null;
|
|
16161
16221
|
const userKey = layoutUserKey(resolved);
|
|
@@ -16183,6 +16243,7 @@ export {
|
|
|
16183
16243
|
BelongsToRelationQuery,
|
|
16184
16244
|
Blueprint,
|
|
16185
16245
|
CACHE_TAGS,
|
|
16246
|
+
CORE_VIEW_RENDERER_TOKEN,
|
|
16186
16247
|
repository_default as CacheRepository,
|
|
16187
16248
|
ColumnDefinition,
|
|
16188
16249
|
CompositeGuard,
|
|
@@ -16256,6 +16317,7 @@ export {
|
|
|
16256
16317
|
UnprocessableEntityError,
|
|
16257
16318
|
UnsupportedSchemaFeatureError,
|
|
16258
16319
|
ValidationError,
|
|
16320
|
+
ViewRenderer,
|
|
16259
16321
|
WebFormRequest,
|
|
16260
16322
|
WhereBuilder,
|
|
16261
16323
|
absoluteTemporarySignedUrl,
|
|
@@ -16374,6 +16436,7 @@ export {
|
|
|
16374
16436
|
createTrackedJob,
|
|
16375
16437
|
createTransactionAcquisitionMetrics,
|
|
16376
16438
|
createValidateSignatureMiddleware,
|
|
16439
|
+
createWebLayoutDataResolver,
|
|
16377
16440
|
createdResponse,
|
|
16378
16441
|
currentAuthUser,
|
|
16379
16442
|
currentCredentialSource,
|