@ynode/squirrellyify 1.5.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/plugin.js +57 -19
package/package.json
CHANGED
package/src/plugin.js
CHANGED
|
@@ -38,7 +38,12 @@ import {
|
|
|
38
38
|
resolveUseCache,
|
|
39
39
|
validatePluginOptions,
|
|
40
40
|
} from "./config.js";
|
|
41
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
buildTemplateSearchDirs,
|
|
43
|
+
collectViewScope,
|
|
44
|
+
createTemplateResolver,
|
|
45
|
+
preloadPartials,
|
|
46
|
+
} from "./resolver.js";
|
|
42
47
|
import { createRuntimeApi } from "./runtime-api.js";
|
|
43
48
|
import { assertSafeName } from "./safety.js";
|
|
44
49
|
|
|
@@ -75,7 +80,9 @@ async function squirrellyify(fastify, options = {}) {
|
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
const log =
|
|
78
|
-
typeof fastify.log?.child === "function"
|
|
83
|
+
typeof fastify.log?.child === "function"
|
|
84
|
+
? fastify.log.child({ name: "@ynode/squirrellyify" })
|
|
85
|
+
: fastify.log;
|
|
79
86
|
|
|
80
87
|
const initialTemplatesDirs = resolveInitialTemplateDirs(options);
|
|
81
88
|
const initialPartialsDirs = resolveInitialPartialsDirs(options);
|
|
@@ -83,11 +90,17 @@ async function squirrellyify(fastify, options = {}) {
|
|
|
83
90
|
const { extensionWithDot } = resolveExtension(options);
|
|
84
91
|
const useCache = resolveUseCache(options);
|
|
85
92
|
const { sqrlScope, sqrlConfig } = resolveSqrlConfig(options);
|
|
86
|
-
const {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
const {
|
|
94
|
+
defineSqrlHelper,
|
|
95
|
+
defineSqrlFilter,
|
|
96
|
+
defineSqrlTemplate,
|
|
97
|
+
viewHelpers,
|
|
98
|
+
viewFilters,
|
|
99
|
+
viewPartials,
|
|
100
|
+
} = createRuntimeApi({
|
|
101
|
+
sqrlScope,
|
|
102
|
+
sqrlConfig,
|
|
103
|
+
});
|
|
91
104
|
|
|
92
105
|
if (options.sqrl?.helpers) {
|
|
93
106
|
Object.entries(options.sqrl.helpers).forEach(([name, fn]) => {
|
|
@@ -110,12 +123,13 @@ async function squirrellyify(fastify, options = {}) {
|
|
|
110
123
|
sqrlConfig,
|
|
111
124
|
});
|
|
112
125
|
|
|
113
|
-
const { findTemplatePath, getTemplate, hasLayoutTag, clearCaches, cacheStats } =
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
126
|
+
const { findTemplatePath, getTemplate, hasLayoutTag, clearCaches, cacheStats } =
|
|
127
|
+
createTemplateResolver({
|
|
128
|
+
fastify,
|
|
129
|
+
extensionWithDot,
|
|
130
|
+
useCache,
|
|
131
|
+
sqrlConfig,
|
|
132
|
+
});
|
|
119
133
|
|
|
120
134
|
/**
|
|
121
135
|
* Renders a Squirrelly template and sends it as an HTML response.
|
|
@@ -126,7 +140,8 @@ async function squirrellyify(fastify, options = {}) {
|
|
|
126
140
|
async function view(template, data = {}) {
|
|
127
141
|
try {
|
|
128
142
|
const requestData = data && typeof data === "object" ? data : {};
|
|
129
|
-
const replyContext =
|
|
143
|
+
const replyContext =
|
|
144
|
+
this.context && typeof this.context === "object" ? this.context : {};
|
|
130
145
|
const replyLocals = this.locals && typeof this.locals === "object" ? this.locals : {};
|
|
131
146
|
const mergedData = {
|
|
132
147
|
...replyContext,
|
|
@@ -141,12 +156,17 @@ async function squirrellyify(fastify, options = {}) {
|
|
|
141
156
|
|
|
142
157
|
const instance = this.request.server;
|
|
143
158
|
const { aggregatedTemplatesDirs, scopedLayout } = collectViewScope(instance);
|
|
144
|
-
const templateSearchDirs = buildTemplateSearchDirs(
|
|
159
|
+
const templateSearchDirs = buildTemplateSearchDirs(
|
|
160
|
+
aggregatedTemplatesDirs,
|
|
161
|
+
initialTemplatesDirs,
|
|
162
|
+
);
|
|
145
163
|
|
|
146
164
|
// 1. Find and render the page template
|
|
147
165
|
const pagePath = await findTemplatePath(template, templateSearchDirs);
|
|
148
166
|
if (!pagePath) {
|
|
149
|
-
throw new Error(
|
|
167
|
+
throw new Error(
|
|
168
|
+
`Template "${template}" not found in [${templateSearchDirs.join(", ")}]`,
|
|
169
|
+
);
|
|
150
170
|
}
|
|
151
171
|
|
|
152
172
|
const pageTemplate = await getTemplate(pagePath);
|
|
@@ -154,7 +174,8 @@ async function squirrellyify(fastify, options = {}) {
|
|
|
154
174
|
|
|
155
175
|
// 2. Determine which layout to use
|
|
156
176
|
const currentLayout = scopedLayout !== null ? scopedLayout : initialLayout;
|
|
157
|
-
const layoutFile =
|
|
177
|
+
const layoutFile =
|
|
178
|
+
mergedData.layout === false ? null : mergedData.layout || currentLayout;
|
|
158
179
|
|
|
159
180
|
if (!layoutFile) {
|
|
160
181
|
return this.type("text/html").send(pageHtml);
|
|
@@ -167,12 +188,16 @@ async function squirrellyify(fastify, options = {}) {
|
|
|
167
188
|
// 3. Find and render the layout, injecting the page content
|
|
168
189
|
const layoutPath = await findTemplatePath(layoutFile, templateSearchDirs);
|
|
169
190
|
if (!layoutPath) {
|
|
170
|
-
throw new Error(
|
|
191
|
+
throw new Error(
|
|
192
|
+
`Layout "${layoutFile}" not found in [${templateSearchDirs.join(", ")}]`,
|
|
193
|
+
);
|
|
171
194
|
}
|
|
172
195
|
|
|
173
196
|
const layoutTemplate = await getTemplate(layoutPath);
|
|
174
197
|
const layoutPayload =
|
|
175
|
-
mergedData.layoutData && typeof mergedData.layoutData === "object"
|
|
198
|
+
mergedData.layoutData && typeof mergedData.layoutData === "object"
|
|
199
|
+
? mergedData.layoutData
|
|
200
|
+
: {};
|
|
176
201
|
const layoutData = { ...mergedData, ...layoutPayload, body: pageHtml };
|
|
177
202
|
const finalHtml = await layoutTemplate(layoutData, sqrlConfig);
|
|
178
203
|
|
|
@@ -189,6 +214,19 @@ async function squirrellyify(fastify, options = {}) {
|
|
|
189
214
|
}
|
|
190
215
|
}
|
|
191
216
|
|
|
217
|
+
// Pre-decorate context for V8 optimization performance in consumers
|
|
218
|
+
try {
|
|
219
|
+
fastify.decorateReply("context", null);
|
|
220
|
+
} catch (err) {
|
|
221
|
+
if (err.code !== "FST_ERR_DEC_ALREADY_PRESENT") {
|
|
222
|
+
throw err;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
fastify.addHook("onRequest", async (request, reply) => {
|
|
227
|
+
reply.context = {};
|
|
228
|
+
});
|
|
229
|
+
|
|
192
230
|
// Decorate the reply object with the main view function
|
|
193
231
|
fastify.decorateReply("view", view);
|
|
194
232
|
|