zuby 1.0.48 → 1.0.49
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/config.js +56 -1
- package/context/index.d.ts +3 -0
- package/context/index.js +9 -0
- package/context/types.d.ts +17 -0
- package/package.json +1 -1
- package/pageContext/index.d.ts +32 -0
- package/pageContext/index.js +52 -0
- package/plugins/contextPlugin/index.js +4 -1
- package/server/index.js +65 -0
- package/server/zubyRenderer.js +2 -0
- package/templates/index.d.ts +6 -1
- package/templates/index.js +38 -18
- package/templates/types.d.ts +5 -0
- package/templates/types.js +0 -1
- package/types.d.ts +30 -1
package/config.js
CHANGED
|
@@ -12,6 +12,7 @@ import manifestPlugin from './plugins/manifestPlugin/index.js';
|
|
|
12
12
|
import prerenderPlugin from './plugins/prerenderPlugin/index.js';
|
|
13
13
|
import standaloneBuildPlugin from './plugins/dependenciesPlugin/index.js';
|
|
14
14
|
import preloadPlugin from './plugins/preloadPlugin/index.js';
|
|
15
|
+
import { TEMPLATES } from './templates/types.js';
|
|
15
16
|
let zubyInternalConfig;
|
|
16
17
|
/**
|
|
17
18
|
* Returns the path to the ZubyConfig file.
|
|
@@ -57,8 +58,57 @@ export const getZubyInternalConfig = async (configFilePath, cache = true) => {
|
|
|
57
58
|
return zubyInternalConfig;
|
|
58
59
|
const zubyConfig = await getZubyConfig(configFilePath);
|
|
59
60
|
zubyConfig.configFilePath = configFilePath;
|
|
61
|
+
zubyConfig.templateFiles = zubyConfig.templateFiles || [];
|
|
62
|
+
zubyConfig.headElements = zubyConfig.headElements || [];
|
|
60
63
|
// Run config setup hook
|
|
61
|
-
await executePlugins(zubyConfig, PLUGIN_HOOKS.ZubyConfigSetup
|
|
64
|
+
await executePlugins(zubyConfig, PLUGIN_HOOKS.ZubyConfigSetup, {
|
|
65
|
+
addEntryTemplate: (filename) => zubyConfig.templateFiles?.push({
|
|
66
|
+
filename,
|
|
67
|
+
path: '/:path*',
|
|
68
|
+
templateType: TEMPLATES.entry,
|
|
69
|
+
}),
|
|
70
|
+
addAppTemplate: (filename, path = '/:path*') => zubyConfig.templateFiles?.push({
|
|
71
|
+
filename,
|
|
72
|
+
path,
|
|
73
|
+
templateType: TEMPLATES.app,
|
|
74
|
+
}),
|
|
75
|
+
addLayoutTemplate: (filename, path = '/:path*') => zubyConfig.templateFiles?.push({
|
|
76
|
+
filename,
|
|
77
|
+
path,
|
|
78
|
+
templateType: TEMPLATES.layout,
|
|
79
|
+
}),
|
|
80
|
+
addInnerLayoutTemplate: (filename, path = '/:path*') => zubyConfig.templateFiles?.push({
|
|
81
|
+
filename,
|
|
82
|
+
path,
|
|
83
|
+
templateType: TEMPLATES.innerLayout,
|
|
84
|
+
}),
|
|
85
|
+
addPageTemplate: (filename, path = '/:path*') => zubyConfig.templateFiles?.push({
|
|
86
|
+
filename,
|
|
87
|
+
path,
|
|
88
|
+
templateType: TEMPLATES.page,
|
|
89
|
+
}),
|
|
90
|
+
addErrorTemplate: (filename, path = '/:path*') => zubyConfig.templateFiles?.push({
|
|
91
|
+
filename,
|
|
92
|
+
path,
|
|
93
|
+
templateType: TEMPLATES.error,
|
|
94
|
+
}),
|
|
95
|
+
addLoaderTemplate: (filename, path = '/:path*') => zubyConfig.templateFiles?.push({
|
|
96
|
+
filename,
|
|
97
|
+
path,
|
|
98
|
+
templateType: TEMPLATES.loader,
|
|
99
|
+
}),
|
|
100
|
+
addPage: (filename, path = '/:path*') => zubyConfig.templateFiles?.push({
|
|
101
|
+
filename,
|
|
102
|
+
path,
|
|
103
|
+
templateType: TEMPLATES.page,
|
|
104
|
+
}),
|
|
105
|
+
addHandler: (filename, path = '/:path*') => zubyConfig.templateFiles?.push({
|
|
106
|
+
filename,
|
|
107
|
+
path,
|
|
108
|
+
templateType: TEMPLATES.handler,
|
|
109
|
+
}),
|
|
110
|
+
addToHead: (element) => zubyConfig.headElements?.push(element),
|
|
111
|
+
});
|
|
62
112
|
validateConfig(zubyConfig);
|
|
63
113
|
zubyInternalConfig = await mergeDefaultConfig(zubyConfig);
|
|
64
114
|
// Run config done hook
|
|
@@ -106,6 +156,11 @@ export const mergeDefaultConfig = async (config) => {
|
|
|
106
156
|
config.minifyJS = config.minifyJS ?? true;
|
|
107
157
|
// Build ID generator
|
|
108
158
|
config.generateBuildId = config.generateBuildId ?? generateDefaultBuildId;
|
|
159
|
+
// Global props
|
|
160
|
+
config.props = config.props ?? {};
|
|
161
|
+
config.serverProps = config.serverProps ?? {};
|
|
162
|
+
// Head elements
|
|
163
|
+
config.headElements = config.headElements ?? [];
|
|
109
164
|
// Add logger
|
|
110
165
|
config.customLogger =
|
|
111
166
|
config.customLogger ??
|
package/context/index.d.ts
CHANGED
|
@@ -21,5 +21,8 @@ export declare class ZubyContext {
|
|
|
21
21
|
defaultLocale: string;
|
|
22
22
|
} | undefined;
|
|
23
23
|
get buildId(): string | undefined;
|
|
24
|
+
get props(): Record<string, any> | undefined;
|
|
25
|
+
get serverProps(): Record<string, any> | undefined;
|
|
26
|
+
get headElements(): string[] | undefined;
|
|
24
27
|
}
|
|
25
28
|
export declare const getContext: () => ZubyContext;
|
package/context/index.js
CHANGED
|
@@ -26,6 +26,15 @@ export class ZubyContext {
|
|
|
26
26
|
get buildId() {
|
|
27
27
|
return this.rawContext.buildId;
|
|
28
28
|
}
|
|
29
|
+
get props() {
|
|
30
|
+
return this.rawContext.props;
|
|
31
|
+
}
|
|
32
|
+
get serverProps() {
|
|
33
|
+
return this.rawContext.serverProps;
|
|
34
|
+
}
|
|
35
|
+
get headElements() {
|
|
36
|
+
return this.rawContext.headElements;
|
|
37
|
+
}
|
|
29
38
|
}
|
|
30
39
|
const getRawContext = () => {
|
|
31
40
|
return globalThis.ZubyRawContext;
|
package/context/types.d.ts
CHANGED
|
@@ -50,4 +50,21 @@ export interface ZubyRawContext {
|
|
|
50
50
|
locales: string[];
|
|
51
51
|
defaultLocale: string;
|
|
52
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* The global props for the site
|
|
55
|
+
* that will be passed to all pages
|
|
56
|
+
* on both client and server side.
|
|
57
|
+
*/
|
|
58
|
+
props?: Record<string, any>;
|
|
59
|
+
/**
|
|
60
|
+
* The global server props for the site
|
|
61
|
+
* that will be passed to all pages
|
|
62
|
+
* only on server side.
|
|
63
|
+
*/
|
|
64
|
+
serverProps?: Record<string, any>;
|
|
65
|
+
/**
|
|
66
|
+
* Additional elements that should be added
|
|
67
|
+
* to the head of the page.
|
|
68
|
+
*/
|
|
69
|
+
headElements?: string[];
|
|
53
70
|
}
|
package/package.json
CHANGED
package/pageContext/index.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export declare class ZubyPageContext {
|
|
|
10
10
|
protected _headers: Headers;
|
|
11
11
|
protected _cache: number;
|
|
12
12
|
protected _props: Record<string, any>;
|
|
13
|
+
protected _serverProps: Record<string, any>;
|
|
14
|
+
protected _headElements: (string | (() => any))[];
|
|
13
15
|
protected _zubyContext: ZubyContext;
|
|
14
16
|
constructor(options: {
|
|
15
17
|
url?: URL;
|
|
@@ -94,6 +96,24 @@ export declare class ZubyPageContext {
|
|
|
94
96
|
*/
|
|
95
97
|
get props(): Record<string, any>;
|
|
96
98
|
set props(value: Record<string, any>);
|
|
99
|
+
/**
|
|
100
|
+
* The server props that are available only in server-side
|
|
101
|
+
* environment and are not shared with the client.
|
|
102
|
+
* You can use this property to pass data from handler to layout template.
|
|
103
|
+
* Hint: You should not read them in page because the hydration would fail,
|
|
104
|
+
* but you can write them on page and read them in layout.
|
|
105
|
+
* @example { my: 'secret-value' }
|
|
106
|
+
*/
|
|
107
|
+
get serverProps(): Record<string, any>;
|
|
108
|
+
set serverProps(value: Record<string, any>);
|
|
109
|
+
/**
|
|
110
|
+
* The global props from the ZubyConfig
|
|
111
|
+
*/
|
|
112
|
+
get globalProps(): Record<string, any> | undefined;
|
|
113
|
+
/**
|
|
114
|
+
* The global server props from the ZubyConfig
|
|
115
|
+
*/
|
|
116
|
+
get globalServerProps(): Record<string, any> | undefined;
|
|
97
117
|
/**
|
|
98
118
|
* The current status code that will be returned to the client.
|
|
99
119
|
* This property has only effect in server-side.
|
|
@@ -177,4 +197,16 @@ export declare class ZubyPageContext {
|
|
|
177
197
|
* @example ecdf1a94cc9b4f4c
|
|
178
198
|
*/
|
|
179
199
|
get buildId(): string | undefined;
|
|
200
|
+
/**
|
|
201
|
+
* Adds the given HTML string
|
|
202
|
+
* or Jsx Component to the head of the page
|
|
203
|
+
* when it's rendered on the server.
|
|
204
|
+
*/
|
|
205
|
+
addToHead(element: string | (() => any)): void;
|
|
206
|
+
/**
|
|
207
|
+
* Returns array of all elements as string
|
|
208
|
+
* that should be added to the head of the page.
|
|
209
|
+
* @private
|
|
210
|
+
*/
|
|
211
|
+
getHeadElements(): Promise<string[]>;
|
|
180
212
|
}
|
package/pageContext/index.js
CHANGED
|
@@ -9,9 +9,11 @@ export class ZubyPageContext {
|
|
|
9
9
|
this._clientAddress = options?.clientAddress;
|
|
10
10
|
this._statusCode = options?.statusCode || 200;
|
|
11
11
|
this._props = options?.props || {};
|
|
12
|
+
this._serverProps = {};
|
|
12
13
|
this._cache = 0;
|
|
13
14
|
this._headers = options?.headers || new Headers();
|
|
14
15
|
this._zubyContext = options?.zubyContext || getContext();
|
|
16
|
+
this._headElements = [...(this._zubyContext.headElements || [])];
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
19
|
* The current URL of the page.
|
|
@@ -114,6 +116,35 @@ export class ZubyPageContext {
|
|
|
114
116
|
set props(value) {
|
|
115
117
|
this._props = value || {};
|
|
116
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* The server props that are available only in server-side
|
|
121
|
+
* environment and are not shared with the client.
|
|
122
|
+
* You can use this property to pass data from handler to layout template.
|
|
123
|
+
* Hint: You should not read them in page because the hydration would fail,
|
|
124
|
+
* but you can write them on page and read them in layout.
|
|
125
|
+
* @example { my: 'secret-value' }
|
|
126
|
+
*/
|
|
127
|
+
get serverProps() {
|
|
128
|
+
return {
|
|
129
|
+
...(this._zubyContext.serverProps || {}),
|
|
130
|
+
...(this._serverProps || {}),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
set serverProps(value) {
|
|
134
|
+
this._serverProps = value || {};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* The global props from the ZubyConfig
|
|
138
|
+
*/
|
|
139
|
+
get globalProps() {
|
|
140
|
+
return this._zubyContext.props;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The global server props from the ZubyConfig
|
|
144
|
+
*/
|
|
145
|
+
get globalServerProps() {
|
|
146
|
+
return this._zubyContext.serverProps;
|
|
147
|
+
}
|
|
117
148
|
/**
|
|
118
149
|
* The current status code that will be returned to the client.
|
|
119
150
|
* This property has only effect in server-side.
|
|
@@ -232,4 +263,25 @@ export class ZubyPageContext {
|
|
|
232
263
|
get buildId() {
|
|
233
264
|
return this._zubyContext.buildId;
|
|
234
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* Adds the given HTML string
|
|
268
|
+
* or Jsx Component to the head of the page
|
|
269
|
+
* when it's rendered on the server.
|
|
270
|
+
*/
|
|
271
|
+
addToHead(element) {
|
|
272
|
+
this._headElements.push(element);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Returns array of all elements as string
|
|
276
|
+
* that should be added to the head of the page.
|
|
277
|
+
* @private
|
|
278
|
+
*/
|
|
279
|
+
async getHeadElements() {
|
|
280
|
+
return Promise.all(this._headElements.map(element => {
|
|
281
|
+
if (typeof element === 'function') {
|
|
282
|
+
return this._zubyContext?.renderToString?.(element()) || '';
|
|
283
|
+
}
|
|
284
|
+
return element;
|
|
285
|
+
}));
|
|
286
|
+
}
|
|
235
287
|
}
|
|
@@ -25,7 +25,7 @@ export default function index() {
|
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
export async function generateCompileTimeContextCode(ssr) {
|
|
28
|
-
const { site, i18n, buildId } = await getZubyInternalConfig();
|
|
28
|
+
const { site, i18n, buildId, props, serverProps, headElements } = await getZubyInternalConfig();
|
|
29
29
|
const { version } = await getZubyPackageConfig();
|
|
30
30
|
return `globalThis.ZubyRawContext = {
|
|
31
31
|
...(globalThis.ZubyRawContext || {}),
|
|
@@ -35,6 +35,9 @@ export async function generateCompileTimeContextCode(ssr) {
|
|
|
35
35
|
generator: 'Zuby.js ${version}',
|
|
36
36
|
version: '${version}',
|
|
37
37
|
buildId: '${buildId}',
|
|
38
|
+
props: ${JSON.stringify(props)},
|
|
39
|
+
serverProps: ${JSON.stringify(ssr ? serverProps : {})},
|
|
40
|
+
headElements: ${JSON.stringify(ssr ? headElements : [])},
|
|
38
41
|
i18n: ${JSON.stringify(i18n)},
|
|
39
42
|
};`;
|
|
40
43
|
}
|
package/server/index.js
CHANGED
|
@@ -2091,6 +2091,15 @@ var ZubyContext = class {
|
|
|
2091
2091
|
get buildId() {
|
|
2092
2092
|
return this.rawContext.buildId;
|
|
2093
2093
|
}
|
|
2094
|
+
get props() {
|
|
2095
|
+
return this.rawContext.props;
|
|
2096
|
+
}
|
|
2097
|
+
get serverProps() {
|
|
2098
|
+
return this.rawContext.serverProps;
|
|
2099
|
+
}
|
|
2100
|
+
get headElements() {
|
|
2101
|
+
return this.rawContext.headElements;
|
|
2102
|
+
}
|
|
2094
2103
|
};
|
|
2095
2104
|
var getRawContext = () => {
|
|
2096
2105
|
return globalThis.ZubyRawContext;
|
|
@@ -2113,9 +2122,11 @@ var ZubyPageContext = class {
|
|
|
2113
2122
|
this._clientAddress = options?.clientAddress;
|
|
2114
2123
|
this._statusCode = options?.statusCode || 200;
|
|
2115
2124
|
this._props = options?.props || {};
|
|
2125
|
+
this._serverProps = {};
|
|
2116
2126
|
this._cache = 0;
|
|
2117
2127
|
this._headers = options?.headers || new Headers();
|
|
2118
2128
|
this._zubyContext = options?.zubyContext || getContext();
|
|
2129
|
+
this._headElements = [...this._zubyContext.headElements || []];
|
|
2119
2130
|
}
|
|
2120
2131
|
/**
|
|
2121
2132
|
* The current URL of the page.
|
|
@@ -2218,6 +2229,35 @@ var ZubyPageContext = class {
|
|
|
2218
2229
|
set props(value) {
|
|
2219
2230
|
this._props = value || {};
|
|
2220
2231
|
}
|
|
2232
|
+
/**
|
|
2233
|
+
* The server props that are available only in server-side
|
|
2234
|
+
* environment and are not shared with the client.
|
|
2235
|
+
* You can use this property to pass data from handler to layout template.
|
|
2236
|
+
* Hint: You should not read them in page because the hydration would fail,
|
|
2237
|
+
* but you can write them on page and read them in layout.
|
|
2238
|
+
* @example { my: 'secret-value' }
|
|
2239
|
+
*/
|
|
2240
|
+
get serverProps() {
|
|
2241
|
+
return {
|
|
2242
|
+
...this._zubyContext.serverProps || {},
|
|
2243
|
+
...this._serverProps || {}
|
|
2244
|
+
};
|
|
2245
|
+
}
|
|
2246
|
+
set serverProps(value) {
|
|
2247
|
+
this._serverProps = value || {};
|
|
2248
|
+
}
|
|
2249
|
+
/**
|
|
2250
|
+
* The global props from the ZubyConfig
|
|
2251
|
+
*/
|
|
2252
|
+
get globalProps() {
|
|
2253
|
+
return this._zubyContext.props;
|
|
2254
|
+
}
|
|
2255
|
+
/**
|
|
2256
|
+
* The global server props from the ZubyConfig
|
|
2257
|
+
*/
|
|
2258
|
+
get globalServerProps() {
|
|
2259
|
+
return this._zubyContext.serverProps;
|
|
2260
|
+
}
|
|
2221
2261
|
/**
|
|
2222
2262
|
* The current status code that will be returned to the client.
|
|
2223
2263
|
* This property has only effect in server-side.
|
|
@@ -2336,6 +2376,29 @@ var ZubyPageContext = class {
|
|
|
2336
2376
|
get buildId() {
|
|
2337
2377
|
return this._zubyContext.buildId;
|
|
2338
2378
|
}
|
|
2379
|
+
/**
|
|
2380
|
+
* Adds the given HTML string
|
|
2381
|
+
* or Jsx Component to the head of the page
|
|
2382
|
+
* when it's rendered on the server.
|
|
2383
|
+
*/
|
|
2384
|
+
addToHead(element) {
|
|
2385
|
+
this._headElements.push(element);
|
|
2386
|
+
}
|
|
2387
|
+
/**
|
|
2388
|
+
* Returns array of all elements as string
|
|
2389
|
+
* that should be added to the head of the page.
|
|
2390
|
+
* @private
|
|
2391
|
+
*/
|
|
2392
|
+
async getHeadElements() {
|
|
2393
|
+
return Promise.all(
|
|
2394
|
+
this._headElements.map((element) => {
|
|
2395
|
+
if (typeof element === "function") {
|
|
2396
|
+
return this._zubyContext?.renderToString?.(element()) || "";
|
|
2397
|
+
}
|
|
2398
|
+
return element;
|
|
2399
|
+
})
|
|
2400
|
+
);
|
|
2401
|
+
}
|
|
2339
2402
|
};
|
|
2340
2403
|
|
|
2341
2404
|
// src/server/zubyRenderer.ts
|
|
@@ -8721,6 +8784,8 @@ var ZubyRenderer = class {
|
|
|
8721
8784
|
jsImports.forEach((imp) => {
|
|
8722
8785
|
html = html.replace(/(<\/head>)/, `<script type="module" src="${imp}" defer></script>$1`);
|
|
8723
8786
|
});
|
|
8787
|
+
const headElements = await pageContext.getHeadElements();
|
|
8788
|
+
html = html.replace(/(<\/head>)/, headElements.join("") + "$1");
|
|
8724
8789
|
return this.injectHeaders(
|
|
8725
8790
|
new Response(html, {
|
|
8726
8791
|
status: pageContext.statusCode || 200,
|
package/server/zubyRenderer.js
CHANGED
|
@@ -149,6 +149,8 @@ export default class ZubyRenderer {
|
|
|
149
149
|
jsImports.forEach((imp) => {
|
|
150
150
|
html = html.replace(/(<\/head>)/, `<script type="module" src="${imp}" defer></script>$1`);
|
|
151
151
|
});
|
|
152
|
+
const headElements = await pageContext.getHeadElements();
|
|
153
|
+
html = html.replace(/(<\/head>)/, headElements.join('') + '$1');
|
|
152
154
|
return this.injectHeaders(new Response(html, {
|
|
153
155
|
status: pageContext.statusCode || 200,
|
|
154
156
|
headers: {
|
package/templates/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Template, TemplateType } from './types.js';
|
|
1
|
+
import { Template, TemplateFile, TemplateType } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Returns the array of pages with static path.
|
|
4
4
|
*/
|
|
@@ -42,6 +42,11 @@ export declare function getDefaultTemplate(filename: string, templateType: Templ
|
|
|
42
42
|
* If i18n config is defined, the pages will be localized and duplicated for each locale.
|
|
43
43
|
*/
|
|
44
44
|
export declare function getTemplates(cache?: boolean): Promise<Template[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Collects all template files from the pages directory and the templateFiles config
|
|
47
|
+
* and returns them as an array of TemplateFile objects.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getTemplateFiles(): Promise<TemplateFile[]>;
|
|
45
50
|
/**
|
|
46
51
|
* Calculates the weight of each template
|
|
47
52
|
* and sorts them from the least dynamic path to the most dynamic.
|
package/templates/index.js
CHANGED
|
@@ -103,26 +103,12 @@ export function getDefaultTemplate(filename, templateType) {
|
|
|
103
103
|
export async function getTemplates(cache = true) {
|
|
104
104
|
if (cache && templatesCache)
|
|
105
105
|
return templatesCache;
|
|
106
|
-
const {
|
|
107
|
-
const pagesDir = normalizePath(join(srcDir, 'pages'));
|
|
108
|
-
const files = await glob(`${pagesDir}/**/*.{${templateExtensions.join(',')}}`);
|
|
106
|
+
const { i18n } = await getZubyInternalConfig();
|
|
109
107
|
const locales = (i18n?.locales || []).filter(locale => locale !== i18n?.defaultLocale);
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
filename = normalizePath(filename);
|
|
108
|
+
const templateFiles = await getTemplateFiles();
|
|
109
|
+
const templates = templateFiles
|
|
110
|
+
.map(({ path, filename, templateType }) => {
|
|
114
111
|
const fileNameWithoutExtension = basename(filename).replace(/\.(.+)$/, '');
|
|
115
|
-
const templateType = getTemplateType(filename);
|
|
116
|
-
// Remove the pagesDir prefix from the filename
|
|
117
|
-
// and transform it to a valid wouter path
|
|
118
|
-
let path = toPath(filename.replace(pagesDir, ''));
|
|
119
|
-
// Create matching path for base templates
|
|
120
|
-
if (Object.values(BASE_TEMPLATES).includes(templateType)) {
|
|
121
|
-
path = `${path}/:path*`.replace(/\/+/g, '/');
|
|
122
|
-
}
|
|
123
|
-
// Calculate the relative path from
|
|
124
|
-
// the ZubyRouter component file to the page file
|
|
125
|
-
filename = normalizePath(resolve(filename));
|
|
126
112
|
return {
|
|
127
113
|
filename,
|
|
128
114
|
path,
|
|
@@ -148,6 +134,40 @@ export async function getTemplates(cache = true) {
|
|
|
148
134
|
}));
|
|
149
135
|
return (templatesCache = sortTemplates(templates));
|
|
150
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Collects all template files from the pages directory and the templateFiles config
|
|
139
|
+
* and returns them as an array of TemplateFile objects.
|
|
140
|
+
*/
|
|
141
|
+
export async function getTemplateFiles() {
|
|
142
|
+
const { srcDir, templateExtensions, templateFiles } = await getZubyInternalConfig();
|
|
143
|
+
const pagesDir = normalizePath(join(srcDir, 'pages'));
|
|
144
|
+
const files = await glob(`${pagesDir}/**/*.{${templateExtensions.join(',')}}`);
|
|
145
|
+
const configTemplateFiles = templateFiles.map(({ templateType, filename, path }) => {
|
|
146
|
+
return {
|
|
147
|
+
filename: normalizePath(resolve(filename)),
|
|
148
|
+
path: toPath(path),
|
|
149
|
+
templateType,
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
const folderTemplateFiles = files.map(filename => {
|
|
153
|
+
// Normalize the path and slashes to unix style (needed for windows)
|
|
154
|
+
filename = normalizePath(filename);
|
|
155
|
+
const templateType = getTemplateType(filename);
|
|
156
|
+
// Remove the pagesDir prefix from the filename
|
|
157
|
+
// and transform it to a valid wouter path
|
|
158
|
+
let path = toPath(filename.replace(pagesDir, ''));
|
|
159
|
+
// Create matching path for base templates
|
|
160
|
+
if (Object.values(BASE_TEMPLATES).includes(templateType)) {
|
|
161
|
+
path = `${path}/:path*`.replace(/\/+/g, '/');
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
filename: normalizePath(resolve(filename)),
|
|
165
|
+
path,
|
|
166
|
+
templateType,
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
return [...configTemplateFiles, ...folderTemplateFiles];
|
|
170
|
+
}
|
|
151
171
|
/**
|
|
152
172
|
* Calculates the weight of each template
|
|
153
173
|
* and sorts them from the least dynamic path to the most dynamic.
|
package/templates/types.d.ts
CHANGED
package/templates/types.js
CHANGED
package/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { UserConfig as ViteUserConfig, InlineConfig as ViteInlineConfig, PluginOption as VitePluginOption, Plugin as VitePlugin } from 'vite';
|
|
3
3
|
import { ZubyLogger } from './logger/types.js';
|
|
4
4
|
import ReadableStream = NodeJS.ReadableStream;
|
|
5
|
-
import { PathParamsType, Template } from './templates/types.js';
|
|
5
|
+
import { PathParamsType, Template, TemplateFile } from './templates/types.js';
|
|
6
6
|
import ZubyDevServer from './server/zubyDevServer.js';
|
|
7
7
|
export interface ZubyConfig {
|
|
8
8
|
/**
|
|
@@ -127,6 +127,34 @@ export interface ZubyConfig {
|
|
|
127
127
|
* you can use this option to generate consistent build IDs.
|
|
128
128
|
*/
|
|
129
129
|
generateBuildId?: () => string | Promise<string>;
|
|
130
|
+
/**
|
|
131
|
+
* Template files that are used to
|
|
132
|
+
* create the templates during the build process.
|
|
133
|
+
* @private
|
|
134
|
+
*/
|
|
135
|
+
templateFiles?: TemplateFile[];
|
|
136
|
+
/**
|
|
137
|
+
* The global props for the site
|
|
138
|
+
* that will be passed to all pages, handlers etc...
|
|
139
|
+
* on both client and server side.
|
|
140
|
+
* They can be retrieved using PageContext.globalProps method.
|
|
141
|
+
* @default {}
|
|
142
|
+
*/
|
|
143
|
+
props?: Record<string, any>;
|
|
144
|
+
/**
|
|
145
|
+
* The global server props for the site
|
|
146
|
+
* that will be passed to all pages, handlers etc...
|
|
147
|
+
* only on server side.
|
|
148
|
+
* They can be retrieved using PageContext.globalServerProps method.
|
|
149
|
+
* @default {}
|
|
150
|
+
*/
|
|
151
|
+
serverProps?: Record<string, any>;
|
|
152
|
+
/**
|
|
153
|
+
* Additional HTML elements
|
|
154
|
+
* that will be injected into the head of the page.
|
|
155
|
+
* @default []
|
|
156
|
+
*/
|
|
157
|
+
headElements?: string[];
|
|
130
158
|
}
|
|
131
159
|
export interface ZubyInternalConfig extends Required<ZubyConfig> {
|
|
132
160
|
/**
|
|
@@ -321,6 +349,7 @@ export interface ZubyConfigSetupHookParams {
|
|
|
321
349
|
addLoaderTemplate: (loaderFile: string, path?: string) => void;
|
|
322
350
|
addPage: (pageFile: string, path?: string) => void;
|
|
323
351
|
addHandler: (handlerFile: string, path?: string) => void;
|
|
352
|
+
addToHead: (element: string) => void;
|
|
324
353
|
}
|
|
325
354
|
export interface ZubyConfigDoneHookParams extends ZubyConfigSetupHookParams {
|
|
326
355
|
config: ZubyInternalConfig;
|