hadars 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-TV37IMRB.js → chunk-2TMQUXFL.js} +10 -10
- package/dist/{chunk-2J2L2H3H.js → chunk-NYLXE7T7.js} +6 -6
- package/dist/{chunk-OS3V4CPN.js → chunk-OZUZS2PD.js} +4 -4
- package/dist/cli.js +462 -496
- package/dist/cloudflare.cjs +11 -11
- package/dist/cloudflare.js +3 -3
- package/dist/index.d.cts +8 -4
- package/dist/index.d.ts +8 -4
- package/dist/lambda.cjs +11 -11
- package/dist/lambda.js +7 -7
- package/dist/loader.cjs +90 -54
- package/dist/slim-react/index.cjs +13 -13
- package/dist/slim-react/index.js +2 -2
- package/dist/slim-react/jsx-runtime.cjs +2 -4
- package/dist/slim-react/jsx-runtime.js +1 -1
- package/dist/ssr-render-worker.js +174 -161
- package/dist/ssr-watch.js +40 -74
- package/package.json +8 -10
- package/cli-lib.ts +0 -676
- package/cli.ts +0 -36
- package/index.ts +0 -17
- package/src/build.ts +0 -805
- package/src/cloudflare.ts +0 -140
- package/src/index.tsx +0 -41
- package/src/lambda.ts +0 -287
- package/src/slim-react/context.ts +0 -55
- package/src/slim-react/dispatcher.ts +0 -87
- package/src/slim-react/hooks.ts +0 -137
- package/src/slim-react/index.ts +0 -232
- package/src/slim-react/jsx-runtime.ts +0 -7
- package/src/slim-react/jsx.ts +0 -53
- package/src/slim-react/render.ts +0 -1101
- package/src/slim-react/renderContext.ts +0 -294
- package/src/slim-react/types.ts +0 -33
- package/src/source/context.ts +0 -113
- package/src/source/graphiql.ts +0 -101
- package/src/source/inference.ts +0 -260
- package/src/source/runner.ts +0 -138
- package/src/source/store.ts +0 -50
- package/src/ssr-render-worker.ts +0 -116
- package/src/ssr-watch.ts +0 -62
- package/src/static.ts +0 -109
- package/src/types/global.d.ts +0 -5
- package/src/types/hadars.ts +0 -350
- package/src/utils/Head.tsx +0 -462
- package/src/utils/clientScript.tsx +0 -71
- package/src/utils/cookies.ts +0 -16
- package/src/utils/loader.ts +0 -335
- package/src/utils/proxyHandler.tsx +0 -104
- package/src/utils/request.tsx +0 -9
- package/src/utils/response.tsx +0 -141
- package/src/utils/rspack.ts +0 -467
- package/src/utils/runtime.ts +0 -19
- package/src/utils/serve.ts +0 -155
- package/src/utils/ssrHandler.ts +0 -239
- package/src/utils/staticFile.ts +0 -43
- package/src/utils/template.html +0 -11
- package/src/utils/upgradeRequest.tsx +0 -19
package/src/static.ts
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Static site export core — rendering and file I/O.
|
|
3
|
-
*
|
|
4
|
-
* Imported by cli-lib.ts (bundled into dist/cli.js via esbuild) and by tests.
|
|
5
|
-
* Has no dependency on the rspack build pipeline — only SSR utilities.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { cp, mkdir, writeFile } from 'node:fs/promises';
|
|
9
|
-
import { join, dirname, basename } from 'node:path';
|
|
10
|
-
import { parseRequest } from './utils/request';
|
|
11
|
-
import { getReactResponse, buildHeadHtml } from './utils/response';
|
|
12
|
-
import { buildSsrHtml, makePrecontentHtmlGetter } from './utils/ssrHandler';
|
|
13
|
-
import type { HadarsEntryModule, HadarsStaticContext, GraphQLExecutor } from './types/hadars';
|
|
14
|
-
|
|
15
|
-
export interface StaticRenderResult {
|
|
16
|
-
/** URL paths that were successfully rendered. */
|
|
17
|
-
rendered: string[];
|
|
18
|
-
/** Paths that failed, with the caught error. */
|
|
19
|
-
errors: Array<{ path: string; error: Error }>;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Pre-renders a list of URL paths to HTML files and copies static assets.
|
|
24
|
-
*
|
|
25
|
-
* Pages are rendered serially — `getReactResponse` writes to
|
|
26
|
-
* `globalThis.__hadarsUnsuspend / __hadarsContext` which are not re-entrant-safe.
|
|
27
|
-
*/
|
|
28
|
-
export async function renderStaticSite(opts: {
|
|
29
|
-
ssrModule: HadarsEntryModule<any>;
|
|
30
|
-
htmlSource: string;
|
|
31
|
-
staticSrc: string;
|
|
32
|
-
paths: string[];
|
|
33
|
-
outputDir: string;
|
|
34
|
-
graphql?: GraphQLExecutor;
|
|
35
|
-
}): Promise<StaticRenderResult> {
|
|
36
|
-
const { ssrModule, htmlSource, staticSrc, paths, outputDir } = opts;
|
|
37
|
-
|
|
38
|
-
const staticCtx: HadarsStaticContext = {
|
|
39
|
-
graphql: opts.graphql ?? (() => Promise.reject(
|
|
40
|
-
new Error('[hadars] No graphql executor configured. Add a `graphql` function to your hadars.config.'),
|
|
41
|
-
)),
|
|
42
|
-
};
|
|
43
|
-
const getPrecontentHtml = makePrecontentHtmlGetter(Promise.resolve(htmlSource));
|
|
44
|
-
|
|
45
|
-
await mkdir(outputDir, { recursive: true });
|
|
46
|
-
|
|
47
|
-
const rendered: string[] = [];
|
|
48
|
-
const errors: Array<{ path: string; error: Error }> = [];
|
|
49
|
-
|
|
50
|
-
for (const urlPath of paths) {
|
|
51
|
-
try {
|
|
52
|
-
const req = parseRequest(new Request('http://localhost' + urlPath));
|
|
53
|
-
|
|
54
|
-
// Expose the executor globally so useGraphQL() in components can reach it.
|
|
55
|
-
(globalThis as any).__hadarsGraphQL = staticCtx.graphql;
|
|
56
|
-
|
|
57
|
-
const { head, getAppBody, finalize } = await getReactResponse(req, {
|
|
58
|
-
document: {
|
|
59
|
-
body: ssrModule.default as any,
|
|
60
|
-
getInitProps: ssrModule.getInitProps,
|
|
61
|
-
getFinalProps: ssrModule.getFinalProps,
|
|
62
|
-
},
|
|
63
|
-
staticCtx,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const bodyHtml = await getAppBody();
|
|
67
|
-
const { clientProps } = await finalize();
|
|
68
|
-
const headHtml = buildHeadHtml(head);
|
|
69
|
-
// Inject a flag so the client knows it's a static export and should
|
|
70
|
-
// fetch index.json sidecars directly instead of hitting a live server.
|
|
71
|
-
const staticClientProps = { ...clientProps, __hadarsStatic: true };
|
|
72
|
-
const html = await buildSsrHtml(bodyHtml, staticClientProps, headHtml, getPrecontentHtml);
|
|
73
|
-
|
|
74
|
-
// '/' → <outputDir>/index.html
|
|
75
|
-
// '/about' → <outputDir>/about/index.html
|
|
76
|
-
const cleanPath = urlPath.replace(/\/$/, '');
|
|
77
|
-
const pageDir = cleanPath === '' ? outputDir : join(outputDir, cleanPath);
|
|
78
|
-
await mkdir(pageDir, { recursive: true });
|
|
79
|
-
await writeFile(join(pageDir, 'index.html'), html, 'utf-8');
|
|
80
|
-
|
|
81
|
-
// Write a JSON sidecar so useServerData can hydrate on client-side
|
|
82
|
-
// navigation without a live server. The format matches the live
|
|
83
|
-
// server's Accept: application/json response: { serverData: {...} }.
|
|
84
|
-
const serverData = (staticClientProps as any).__serverData ?? {};
|
|
85
|
-
await writeFile(
|
|
86
|
-
join(pageDir, 'index.json'),
|
|
87
|
-
JSON.stringify({ serverData }),
|
|
88
|
-
'utf-8',
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
rendered.push(urlPath);
|
|
92
|
-
} catch (err: any) {
|
|
93
|
-
errors.push({
|
|
94
|
-
path: urlPath,
|
|
95
|
-
error: err instanceof Error ? err : new Error(String(err)),
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Copy .hadars/static/ → <outputDir>/static/, excluding the SSR template.
|
|
101
|
-
const staticDest = join(outputDir, 'static');
|
|
102
|
-
await mkdir(staticDest, { recursive: true });
|
|
103
|
-
await cp(staticSrc, staticDest, {
|
|
104
|
-
recursive: true,
|
|
105
|
-
filter: (src: string) => basename(src) !== 'out.html',
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
return { rendered, errors };
|
|
109
|
-
}
|
package/src/types/global.d.ts
DELETED
package/src/types/hadars.ts
DELETED
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
import type { LinkHTMLAttributes, MetaHTMLAttributes, ScriptHTMLAttributes, StyleHTMLAttributes } from "react";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Minimal structural representation of a typed GraphQL document node.
|
|
5
|
-
*
|
|
6
|
-
* Compatible with `TypedDocumentNode` from `@graphql-typed-document-node/core`
|
|
7
|
-
* and the documents emitted by graphql-codegen's `client` preset — so passing
|
|
8
|
-
* a generated document object gives you fully-inferred result and variable types
|
|
9
|
-
* without writing explicit generics.
|
|
10
|
-
*
|
|
11
|
-
* hadars intentionally avoids importing from `graphql` or
|
|
12
|
-
* `@graphql-typed-document-node/core` so that neither is a required dependency.
|
|
13
|
-
*/
|
|
14
|
-
export interface HadarsDocumentNode<
|
|
15
|
-
TResult = Record<string, unknown>,
|
|
16
|
-
TVariables = Record<string, unknown>,
|
|
17
|
-
> {
|
|
18
|
-
/** @internal Used by TypeScript to carry the result type. */
|
|
19
|
-
readonly __apiType?: (variables: TVariables) => TResult;
|
|
20
|
-
/** At least one definition — ensures a plain string is not assignable. */
|
|
21
|
-
readonly definitions: ReadonlyArray<{ readonly kind: string }>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* In-process GraphQL executor passed to `getInitProps` and `paths` during
|
|
26
|
-
* `hadars export static`. Hadars is executor-agnostic — configure it in
|
|
27
|
-
* `hadars.config.ts` using any GraphQL library (e.g. `graphql-js`):
|
|
28
|
-
*
|
|
29
|
-
* ```ts
|
|
30
|
-
* import { graphql as gql, buildSchema } from 'graphql';
|
|
31
|
-
* const schema = buildSchema(`type Query { hello: String }`);
|
|
32
|
-
* const rootValue = { hello: () => 'world' };
|
|
33
|
-
*
|
|
34
|
-
* export default {
|
|
35
|
-
* graphql: (query, variables) =>
|
|
36
|
-
* gql({ schema, rootValue, source: query, variableValues: variables }),
|
|
37
|
-
* } satisfies HadarsOptions;
|
|
38
|
-
* ```
|
|
39
|
-
*
|
|
40
|
-
* The executor is generic — call it with explicit type parameters or pass a
|
|
41
|
-
* `TypedDocumentNode` / codegen-generated document to get inferred types:
|
|
42
|
-
*
|
|
43
|
-
* ```ts
|
|
44
|
-
* // Explicit generics:
|
|
45
|
-
* const { data } = await ctx.graphql<GetPostQuery, GetPostQueryVariables>(
|
|
46
|
-
* `query GetPost($slug: String) { blogPost(slug: $slug) { title } }`,
|
|
47
|
-
* { slug },
|
|
48
|
-
* );
|
|
49
|
-
*
|
|
50
|
-
* // Inferred via TypedDocumentNode (graphql-codegen client preset):
|
|
51
|
-
* import { GetPostDocument } from './gql';
|
|
52
|
-
* const { data } = await ctx.graphql(GetPostDocument, { slug });
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export type GraphQLExecutor = <
|
|
56
|
-
TData = any,
|
|
57
|
-
TVariables extends Record<string, unknown> = Record<string, unknown>,
|
|
58
|
-
>(
|
|
59
|
-
query: string | HadarsDocumentNode<TData, TVariables>,
|
|
60
|
-
variables?: TVariables,
|
|
61
|
-
) => Promise<{ data?: TData; errors?: ReadonlyArray<{ message: string }> }>;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Context passed as the second argument to `getInitProps` and `paths`
|
|
65
|
-
* during `hadars export static`. Not present in dev/run mode.
|
|
66
|
-
*/
|
|
67
|
-
export interface HadarsStaticContext {
|
|
68
|
-
graphql: GraphQLExecutor;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export type HadarsGetInitialProps<T extends {}> = (req: HadarsRequest, ctx?: HadarsStaticContext) => Promise<T> | T;
|
|
72
|
-
export type HadarsGetClientProps<T extends {}> = (props: T) => Promise<T> | T;
|
|
73
|
-
export type HadarsGetFinalProps<T extends {}> = (props: HadarsProps<T>) => Promise<T> | T;
|
|
74
|
-
export type HadarsApp<T extends {}> = React.FC<HadarsProps<T>>;
|
|
75
|
-
|
|
76
|
-
export type HadarsEntryModule<T extends {}> = {
|
|
77
|
-
default: HadarsApp<T>;
|
|
78
|
-
getInitProps?: HadarsGetInitialProps<T>;
|
|
79
|
-
getFinalProps?: HadarsGetFinalProps<T>;
|
|
80
|
-
getClientProps?: HadarsGetClientProps<T>;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export interface AppHead {
|
|
84
|
-
title: string;
|
|
85
|
-
status: number;
|
|
86
|
-
meta: Record<string, MetaProps>;
|
|
87
|
-
link: Record<string, LinkProps>;
|
|
88
|
-
style: Record<string, StyleProps>;
|
|
89
|
-
script: Record<string, ScriptProps>;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export type UnsuspendEntry =
|
|
93
|
-
| { status: 'pending'; promise: Promise<unknown> }
|
|
94
|
-
| { status: 'fulfilled'; value: unknown }
|
|
95
|
-
| { status: 'rejected'; reason: unknown };
|
|
96
|
-
|
|
97
|
-
/** @internal Populated by the framework's render loop — use useServerData() instead. */
|
|
98
|
-
export interface AppUnsuspend {
|
|
99
|
-
cache: Map<string, UnsuspendEntry>;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export interface AppContext {
|
|
103
|
-
path?: string;
|
|
104
|
-
head: AppHead;
|
|
105
|
-
/** @internal Framework use only — use the useServerData() hook instead. */
|
|
106
|
-
_unsuspend?: AppUnsuspend;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export type HadarsEntryBase = {
|
|
110
|
-
location: string;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export type HadarsProps<T extends {}> = T & HadarsEntryBase;
|
|
114
|
-
|
|
115
|
-
export type MetaProps = MetaHTMLAttributes<HTMLMetaElement>;
|
|
116
|
-
export type LinkProps = LinkHTMLAttributes<HTMLLinkElement>;
|
|
117
|
-
export type StyleProps = StyleHTMLAttributes<HTMLStyleElement>;
|
|
118
|
-
export type ScriptProps = ScriptHTMLAttributes<HTMLScriptElement>;
|
|
119
|
-
|
|
120
|
-
export interface HadarsOptions {
|
|
121
|
-
port?: number;
|
|
122
|
-
entry: string;
|
|
123
|
-
baseURL?: string;
|
|
124
|
-
// Optional SWC plugins to be applied to the swc-loader during compilation
|
|
125
|
-
swcPlugins?: SwcPluginList;
|
|
126
|
-
proxy?: Record<string, string> | ((req: HadarsRequest) => Promise<Response | null> | Response | null);
|
|
127
|
-
proxyCORS?: boolean;
|
|
128
|
-
define?: Record<string, string>;
|
|
129
|
-
/**
|
|
130
|
-
* Bun WebSocket handler passed directly to `Bun.serve()`.
|
|
131
|
-
* Ignored on Node.js and Deno — use `fetch` + a third-party WS library there.
|
|
132
|
-
* Pass a `Bun.WebSocketHandler` instance here when running on Bun.
|
|
133
|
-
*/
|
|
134
|
-
websocket?: unknown;
|
|
135
|
-
fetch?: (req: HadarsRequest) => Promise<Response | undefined> | Response | undefined;
|
|
136
|
-
wsPath?: string;
|
|
137
|
-
// Port for the rspack HMR dev server. Defaults to port + 1.
|
|
138
|
-
hmrPort?: number;
|
|
139
|
-
/**
|
|
140
|
-
* Parallelism level for `run()` mode (production server). Defaults to 1.
|
|
141
|
-
* Has no effect in `dev()` mode.
|
|
142
|
-
*
|
|
143
|
-
* **Node.js** — forks this many worker processes via `node:cluster`, each
|
|
144
|
-
* binding to the same port via OS round-robin. Set to `os.cpus().length`
|
|
145
|
-
* to saturate all CPU cores.
|
|
146
|
-
*
|
|
147
|
-
* **Bun / Deno** — creates a `node:worker_threads` render pool of this size.
|
|
148
|
-
* Each thread handles the synchronous `renderToString` step, freeing the
|
|
149
|
-
* main event loop for I/O.
|
|
150
|
-
*/
|
|
151
|
-
workers?: number;
|
|
152
|
-
/**
|
|
153
|
-
* Override or extend rspack's `optimization` config for production client builds.
|
|
154
|
-
* Merged on top of hadars defaults (splitChunks vendor splitting, deterministic moduleIds).
|
|
155
|
-
* Has no effect on the SSR bundle or dev mode.
|
|
156
|
-
*/
|
|
157
|
-
optimization?: Record<string, unknown>;
|
|
158
|
-
/**
|
|
159
|
-
* PostCSS plugins to pass to `postcss-loader`.
|
|
160
|
-
*
|
|
161
|
-
* When set, replaces the default `builtin:lightningcss-loader` with `postcss-loader`
|
|
162
|
-
* configured with these plugins, allowing full PostCSS transforms (e.g. Tailwind CSS v4).
|
|
163
|
-
*
|
|
164
|
-
* @example
|
|
165
|
-
* ```ts
|
|
166
|
-
* import tailwindcss from '@tailwindcss/postcss';
|
|
167
|
-
* export default { postcssPlugins: [tailwindcss()] } satisfies HadarsOptions;
|
|
168
|
-
* ```
|
|
169
|
-
*/
|
|
170
|
-
postcssPlugins?: any[];
|
|
171
|
-
/**
|
|
172
|
-
* Path to a custom HTML template file (relative to the project root).
|
|
173
|
-
* Replaces the built-in minimal template used to generate the HTML shell.
|
|
174
|
-
*
|
|
175
|
-
* The file must include two marker elements so hadars can inject the
|
|
176
|
-
* per-request head tags and the server-rendered body:
|
|
177
|
-
*
|
|
178
|
-
* ```html
|
|
179
|
-
* <meta name="HADARS_HEAD"> <!-- replaced with <title>, <meta>, <link>, <style> tags -->
|
|
180
|
-
* <meta name="HADARS_BODY"> <!-- replaced with the SSR-rendered React tree -->
|
|
181
|
-
* ```
|
|
182
|
-
*
|
|
183
|
-
* Any `<style>` blocks in the template are automatically processed through
|
|
184
|
-
* PostCSS (using the project's `postcss.config.js`) at build/dev startup time,
|
|
185
|
-
* so `@import "tailwindcss"` and other PostCSS directives work as expected.
|
|
186
|
-
* Note: inline styles are processed once at startup and are not live-reloaded.
|
|
187
|
-
*/
|
|
188
|
-
htmlTemplate?: string;
|
|
189
|
-
/**
|
|
190
|
-
* Force the React runtime mode independently of the build mode.
|
|
191
|
-
* Useful when you need production build optimizations (minification, tree-shaking)
|
|
192
|
-
* but want React's development build for debugging hydration mismatches or
|
|
193
|
-
* component stack traces.
|
|
194
|
-
*
|
|
195
|
-
* - `'development'` — forces `process.env.NODE_ENV = "development"` and enables
|
|
196
|
-
* JSX source info even in `hadars build`. React prints detailed hydration error
|
|
197
|
-
* messages and component stacks.
|
|
198
|
-
* - `'production'` — the default; React uses the optimised production bundle.
|
|
199
|
-
*
|
|
200
|
-
* Only affects the **client** bundle. The SSR bundle always uses slim-react.
|
|
201
|
-
*
|
|
202
|
-
* @example
|
|
203
|
-
* // hadars.config.ts — debug hydration errors in a production build
|
|
204
|
-
* reactMode: 'development'
|
|
205
|
-
*/
|
|
206
|
-
reactMode?: 'development' | 'production';
|
|
207
|
-
/**
|
|
208
|
-
* Additional rspack module rules appended to the built-in rule set.
|
|
209
|
-
* Applied to both the client and the SSR bundle.
|
|
210
|
-
*
|
|
211
|
-
* Useful for loaders not included by default, such as `@mdx-js/loader`,
|
|
212
|
-
* `less-loader`, `yaml-loader`, etc.
|
|
213
|
-
*
|
|
214
|
-
* @example
|
|
215
|
-
* moduleRules: [
|
|
216
|
-
* {
|
|
217
|
-
* test: /\.mdx?$/,
|
|
218
|
-
* use: [{ loader: '@mdx-js/loader' }],
|
|
219
|
-
* },
|
|
220
|
-
* ]
|
|
221
|
-
*/
|
|
222
|
-
moduleRules?: Record<string, any>[];
|
|
223
|
-
/**
|
|
224
|
-
* Additional rspack/webpack-compatible plugins applied to both the client
|
|
225
|
-
* and SSR bundles. Any object that implements the `apply(compiler)` method
|
|
226
|
-
* (the standard webpack/rspack plugin interface) is accepted.
|
|
227
|
-
*
|
|
228
|
-
* @example
|
|
229
|
-
* import { SubresourceIntegrityPlugin } from 'webpack-subresource-integrity';
|
|
230
|
-
* plugins: [new SubresourceIntegrityPlugin()]
|
|
231
|
-
*/
|
|
232
|
-
plugins?: Array<{ apply(compiler: any): void }>;
|
|
233
|
-
/**
|
|
234
|
-
* SSR response cache for `run()` mode. Has no effect in `dev()` mode.
|
|
235
|
-
*
|
|
236
|
-
* Receives the incoming request and should return `{ key, ttl? }` to cache
|
|
237
|
-
* the response, or `null`/`undefined` to skip caching for that request.
|
|
238
|
-
* `ttl` is the time-to-live in milliseconds; omit for entries that never expire.
|
|
239
|
-
* The function may be async.
|
|
240
|
-
*
|
|
241
|
-
* @example
|
|
242
|
-
* // Cache every page by pathname (no per-user personalisation):
|
|
243
|
-
* cache: (req) => ({ key: req.pathname })
|
|
244
|
-
*
|
|
245
|
-
* @example
|
|
246
|
-
* // Cache with a per-route TTL, skip authenticated requests:
|
|
247
|
-
* cache: (req) => req.cookies.session ? null : { key: req.pathname, ttl: 60_000 }
|
|
248
|
-
*/
|
|
249
|
-
cache?: (req: HadarsRequest) => { key: string; ttl?: number } | null | undefined
|
|
250
|
-
| Promise<{ key: string; ttl?: number } | null | undefined>;
|
|
251
|
-
/**
|
|
252
|
-
* Static export path list. Required for `hadars export static`.
|
|
253
|
-
*
|
|
254
|
-
* Return an array of URL paths (e.g. `['/', '/about', '/blog/hello']`) that
|
|
255
|
-
* should be pre-rendered to HTML files. May be async.
|
|
256
|
-
*
|
|
257
|
-
* @example
|
|
258
|
-
* paths: () => ['/', '/about', '/contact']
|
|
259
|
-
*
|
|
260
|
-
* @example
|
|
261
|
-
* paths: async () => {
|
|
262
|
-
* const posts = await fetchBlogPosts();
|
|
263
|
-
* return ['/', ...posts.map(p => `/blog/${p.slug}`)];
|
|
264
|
-
* }
|
|
265
|
-
*/
|
|
266
|
-
/**
|
|
267
|
-
* In-process GraphQL executor. Supply this to use the GraphQL data layer
|
|
268
|
-
* in `paths` and `getInitProps` during `hadars export static`.
|
|
269
|
-
* Has no effect in `dev` / `run` mode.
|
|
270
|
-
*/
|
|
271
|
-
graphql?: GraphQLExecutor;
|
|
272
|
-
paths?: (ctx: HadarsStaticContext) => Promise<string[]> | string[];
|
|
273
|
-
/**
|
|
274
|
-
* Gatsby-compatible source plugins to run before `hadars export static`.
|
|
275
|
-
*
|
|
276
|
-
* Each entry mirrors Gatsby's `gatsby-config.js` plugin object format:
|
|
277
|
-
* `{ resolve: 'gatsby-source-contentful', options: { spaceId: '...', accessToken: '...' } }`
|
|
278
|
-
*
|
|
279
|
-
* The plugin must export a `sourceNodes` function with the standard Gatsby API.
|
|
280
|
-
* Hadars provides a thin shim covering the most-used surface:
|
|
281
|
-
* `actions.createNode`, `createNodeId`, `createContentDigest`, `cache`, `reporter`,
|
|
282
|
-
* `getNode`, `getNodes`, `getNodesByType`.
|
|
283
|
-
*
|
|
284
|
-
* After all sources have run, hadars auto-generates a GraphQL schema from the
|
|
285
|
-
* collected nodes and makes it available via `config.graphql` in `getInitProps`
|
|
286
|
-
* and `paths`. Requires `graphql` to be installed in the project.
|
|
287
|
-
*
|
|
288
|
-
* @example
|
|
289
|
-
* sources: [
|
|
290
|
-
* {
|
|
291
|
-
* resolve: 'gatsby-source-filesystem',
|
|
292
|
-
* options: { name: 'posts', path: './content/posts' },
|
|
293
|
-
* },
|
|
294
|
-
* ]
|
|
295
|
-
*/
|
|
296
|
-
sources?: HadarsSourceEntry[];
|
|
297
|
-
/**
|
|
298
|
-
* Called whenever an SSR render error is caught, in both `dev()` and `run()` mode
|
|
299
|
-
* as well as the Lambda and Cloudflare adapters.
|
|
300
|
-
*
|
|
301
|
-
* Use this to forward errors to your monitoring service (Sentry, Datadog, etc.)
|
|
302
|
-
* without affecting the response sent to the browser.
|
|
303
|
-
* The handler may be async — hadars fires it and does not await the result,
|
|
304
|
-
* so it never delays the error response.
|
|
305
|
-
*
|
|
306
|
-
* @example
|
|
307
|
-
* import * as Sentry from '@sentry/node';
|
|
308
|
-
* onError: (err, req) => Sentry.captureException(err, { extra: { url: req.url } })
|
|
309
|
-
*
|
|
310
|
-
* @example
|
|
311
|
-
* onError: (err, req) => console.error('[myapp]', req.method, req.url, err)
|
|
312
|
-
*/
|
|
313
|
-
onError?: (err: Error, req: Request) => void | Promise<void>;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* A Gatsby-compatible source plugin entry, matching the format used in
|
|
318
|
-
* `gatsby-config.js` / `gatsby-config.ts`.
|
|
319
|
-
*/
|
|
320
|
-
export interface HadarsSourceEntry {
|
|
321
|
-
/**
|
|
322
|
-
* Package name (e.g. `'gatsby-source-contentful'`) or a pre-imported module
|
|
323
|
-
* object that exports `sourceNodes`. Using a module object lets you pass
|
|
324
|
-
* local source plugins without publishing them to npm.
|
|
325
|
-
*/
|
|
326
|
-
resolve: string | { sourceNodes?: (ctx: any, opts?: any) => Promise<void> | void };
|
|
327
|
-
/** Plugin options forwarded as the second argument to `sourceNodes`. */
|
|
328
|
-
options?: Record<string, unknown>;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
// SWC plugin typing — a pragmatic, ergonomic union that matches common usages:
|
|
333
|
-
// - a plugin package name (string)
|
|
334
|
-
// - a tuple [pluginName, options]
|
|
335
|
-
// - an object with a path and optional options
|
|
336
|
-
// - a direct function (for programmatic plugin instances)
|
|
337
|
-
export type SwcPluginItem =
|
|
338
|
-
| string
|
|
339
|
-
| [string, Record<string, unknown>]
|
|
340
|
-
| { path: string; options?: Record<string, unknown> }
|
|
341
|
-
| ((...args: any[]) => any);
|
|
342
|
-
|
|
343
|
-
export type SwcPluginList = SwcPluginItem[];
|
|
344
|
-
|
|
345
|
-
export interface HadarsRequest extends Request {
|
|
346
|
-
pathname: string;
|
|
347
|
-
search: string;
|
|
348
|
-
location: string;
|
|
349
|
-
cookies: Record<string, string>;
|
|
350
|
-
}
|