dtwo 2.17.0 → 3.0.0-rc.14

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.
Files changed (118) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +2 -41
  3. package/app.d.ts +1 -0
  4. package/bin/dtwo.mjs +2 -0
  5. package/config.cjs +7 -0
  6. package/config.d.ts +4 -0
  7. package/config.mjs +5 -0
  8. package/dist/app/compat/capi.d.ts +4 -0
  9. package/dist/app/compat/capi.mjs +19 -0
  10. package/dist/app/compat/kdu-demi.d.ts +4 -0
  11. package/dist/app/compat/kdu-demi.mjs +4 -0
  12. package/dist/app/components/client-only.d.mts +22 -0
  13. package/dist/app/components/client-only.mjs +75 -0
  14. package/dist/app/components/dev-only.d.mts +4 -0
  15. package/dist/app/components/dev-only.mjs +11 -0
  16. package/dist/app/components/dtwo-error-boundary.d.ts +8 -0
  17. package/dist/app/components/dtwo-error-boundary.mjs +21 -0
  18. package/dist/app/components/dtwo-error-page.kdu +46 -0
  19. package/dist/app/components/dtwo-link.d.ts +33 -0
  20. package/dist/app/components/dtwo-link.mjs +248 -0
  21. package/dist/app/components/dtwo-loading-indicator.d.ts +43 -0
  22. package/dist/app/components/dtwo-loading-indicator.mjs +107 -0
  23. package/dist/app/components/dtwo-root.kdu +35 -0
  24. package/dist/app/components/index.d.ts +2 -0
  25. package/dist/app/components/index.mjs +1 -0
  26. package/dist/app/components/layout.d.ts +17 -0
  27. package/dist/app/components/layout.mjs +66 -0
  28. package/dist/app/components/server-placeholder.d.ts +2 -0
  29. package/dist/app/components/server-placeholder.mjs +7 -0
  30. package/dist/app/components/utils.d.ts +11 -0
  31. package/dist/app/components/utils.mjs +9 -0
  32. package/dist/app/composables/asyncData.d.ts +40 -0
  33. package/dist/app/composables/asyncData.mjs +169 -0
  34. package/dist/app/composables/component.d.ts +3 -0
  35. package/dist/app/composables/component.mjs +46 -0
  36. package/dist/app/composables/cookie.d.ts +12 -0
  37. package/dist/app/composables/cookie.mjs +58 -0
  38. package/dist/app/composables/error.d.ts +17 -0
  39. package/dist/app/composables/error.mjs +31 -0
  40. package/dist/app/composables/fetch.d.ts +15 -0
  41. package/dist/app/composables/fetch.mjs +66 -0
  42. package/dist/app/composables/hydrate.d.ts +8 -0
  43. package/dist/app/composables/hydrate.mjs +14 -0
  44. package/dist/app/composables/index.d.ts +16 -0
  45. package/dist/app/composables/index.mjs +11 -0
  46. package/dist/app/composables/payload.d.ts +8 -0
  47. package/dist/app/composables/payload.mjs +58 -0
  48. package/dist/app/composables/preload.d.ts +17 -0
  49. package/dist/app/composables/preload.mjs +41 -0
  50. package/dist/app/composables/router.d.ts +28 -0
  51. package/dist/app/composables/router.mjs +111 -0
  52. package/dist/app/composables/ssr.d.ts +6 -0
  53. package/dist/app/composables/ssr.mjs +23 -0
  54. package/dist/app/composables/state.d.ts +9 -0
  55. package/dist/app/composables/state.mjs +27 -0
  56. package/dist/app/config.d.ts +13 -0
  57. package/dist/app/config.mjs +56 -0
  58. package/dist/app/dtwo.d.ts +122 -0
  59. package/dist/app/dtwo.mjs +168 -0
  60. package/dist/app/entry.async.d.ts +2 -0
  61. package/dist/app/entry.async.mjs +5 -0
  62. package/dist/app/entry.d.ts +3 -0
  63. package/dist/app/entry.mjs +59 -0
  64. package/dist/app/index.d.ts +10 -0
  65. package/dist/app/index.mjs +7 -0
  66. package/dist/app/plugins/cross-origin-prefetch.client.d.ts +2 -0
  67. package/dist/app/plugins/cross-origin-prefetch.client.mjs +28 -0
  68. package/dist/app/plugins/debug.d.ts +2 -0
  69. package/dist/app/plugins/debug.mjs +5 -0
  70. package/dist/app/plugins/payload.client.d.ts +2 -0
  71. package/dist/app/plugins/payload.client.mjs +22 -0
  72. package/dist/app/plugins/preload.server.d.ts +2 -0
  73. package/dist/app/plugins/preload.server.mjs +10 -0
  74. package/dist/app/plugins/router.d.ts +53 -0
  75. package/dist/app/plugins/router.mjs +176 -0
  76. package/dist/app/types/augments.d.ts +28 -0
  77. package/dist/core/runtime/hole/error.d.ts +3 -0
  78. package/dist/core/runtime/hole/error.mjs +58 -0
  79. package/dist/core/runtime/hole/paths.d.ts +4 -0
  80. package/dist/core/runtime/hole/paths.mjs +15 -0
  81. package/dist/core/runtime/hole/renderer.d.ts +16 -0
  82. package/dist/core/runtime/hole/renderer.mjs +219 -0
  83. package/dist/head/runtime/components.d.ts +796 -0
  84. package/dist/head/runtime/components.mjs +209 -0
  85. package/dist/head/runtime/composables.d.ts +10 -0
  86. package/dist/head/runtime/composables.mjs +4 -0
  87. package/dist/head/runtime/index.d.ts +4 -0
  88. package/dist/head/runtime/index.mjs +1 -0
  89. package/dist/head/runtime/lib/kdu-meta.plugin.d.ts +2 -0
  90. package/dist/head/runtime/lib/kdu-meta.plugin.mjs +31 -0
  91. package/dist/head/runtime/lib/kduse-head.plugin.d.ts +2 -0
  92. package/dist/head/runtime/lib/kduse-head.plugin.mjs +35 -0
  93. package/dist/head/runtime/types.d.ts +7 -0
  94. package/dist/head/runtime/types.mjs +0 -0
  95. package/dist/index.d.ts +9 -0
  96. package/dist/index.mjs +2274 -0
  97. package/dist/pages/runtime/app.kdu +5 -0
  98. package/dist/pages/runtime/composables.d.ts +42 -0
  99. package/dist/pages/runtime/composables.mjs +8 -0
  100. package/dist/pages/runtime/index.d.ts +1 -0
  101. package/dist/pages/runtime/index.mjs +1 -0
  102. package/dist/pages/runtime/page-placeholder.d.ts +4 -0
  103. package/dist/pages/runtime/page-placeholder.mjs +10 -0
  104. package/dist/pages/runtime/page.d.ts +15 -0
  105. package/dist/pages/runtime/page.mjs +107 -0
  106. package/dist/pages/runtime/router.d.ts +8 -0
  107. package/dist/pages/runtime/router.mjs +152 -0
  108. package/dist/pages/runtime/router.options.d.ts +2 -0
  109. package/dist/pages/runtime/router.options.mjs +51 -0
  110. package/dist/pages/runtime/utils.d.ts +9 -0
  111. package/dist/pages/runtime/utils.mjs +12 -0
  112. package/dist/pages/runtime/validate.d.ts +2 -0
  113. package/dist/pages/runtime/validate.mjs +11 -0
  114. package/package.json +79 -42
  115. package/types.d.ts +15 -0
  116. package/bin/dtwo.js +0 -10
  117. package/dist/dtwo.js +0 -37
  118. package/webpack.config.js +0 -4
package/dist/index.mjs ADDED
@@ -0,0 +1,2274 @@
1
+ import { dirname, resolve, basename, extname, relative, normalize, isAbsolute, join } from 'pathe';
2
+ import { createHooks, createDebugger } from 'hookable';
3
+ import { useDtwo, resolveFiles, defineDtwoModule, addPlugin, addTemplate, addComponent, updateTemplates, addWitePlugin, addWebpackPlugin, findPath, isIgnored, resolveAlias, addPluginTemplate, logger, resolvePath, dtwoCtx, tryResolveModule, installModule, loadDtwoConfig, normalizeTemplate, compileTemplate, normalizePlugin, templateUtils, importModule } from '@dtwo/kit';
4
+ import escapeRE from 'escape-string-regexp';
5
+ import fse from 'fs-extra';
6
+ import { encodePath, parseURL, stringifyQuery, parseQuery, joinURL, withTrailingSlash, withoutLeadingSlash } from 'ufo';
7
+ import { existsSync, readdirSync, statSync, promises } from 'node:fs';
8
+ import { genArrayFromRaw, genSafeVariableName, genImport, genDynamicImport, genObjectFromRawEntries, genString, genExport } from 'knitwork';
9
+ import { fileURLToPath, pathToFileURL } from 'node:url';
10
+ import { kebabCase, splitByCase, pascalCase, camelCase } from 'scule';
11
+ import { createUnplugin } from '@dtwo/unplugin';
12
+ import { findStaticImports, findExports, parseStaticImport, resolvePath as resolvePath$1 } from 'mlly';
13
+ import { walk } from 'estree-walker';
14
+ import MagicString from 'magic-string';
15
+ import { globby } from 'globby';
16
+ import { hyphenate } from '@kdujs/shared';
17
+ import { parse, walk as walk$1, ELEMENT_NODE } from 'ultrahtml';
18
+ import { defineKdimportPreset, createKdimport, toImports, scanDirExports } from 'kdimport';
19
+ import { createRequire } from 'node:module';
20
+ import { createTransformer } from 'unctx/transform';
21
+ import { stripLiteral } from 'strip-literal';
22
+ import { createHole, scanHandlers, writeTypes, build as build$1, prepare, copyPublicAssets, prerender, createDevServer } from 'holepack';
23
+ import defu from 'defu';
24
+ import { dynamicEventHandler } from 'h3';
25
+ import { createHeadCore } from 'kdhead';
26
+ import { renderSSRHead } from '@kdhead/ssr';
27
+ import chokidar from 'chokidar';
28
+ import { debounce } from 'perfect-debounce';
29
+ import { generateTypes, resolveSchema } from 'untyped';
30
+ import { hash } from 'ohash';
31
+
32
+ let _distDir = dirname(fileURLToPath(import.meta.url));
33
+ if (_distDir.match(/(chunks|shared)$/)) {
34
+ _distDir = dirname(_distDir);
35
+ }
36
+ const distDir = _distDir;
37
+ const pkgDir = resolve(distDir, "..");
38
+ resolve(distDir, "runtime");
39
+
40
+ function getNameFromPath(path) {
41
+ return kebabCase(basename(path).replace(extname(path), "")).replace(/["']/g, "");
42
+ }
43
+ function uniqueBy(arr, key) {
44
+ const res = [];
45
+ const seen = /* @__PURE__ */ new Set();
46
+ for (const item of arr) {
47
+ if (seen.has(item[key])) {
48
+ continue;
49
+ }
50
+ seen.add(item[key]);
51
+ res.push(item);
52
+ }
53
+ return res;
54
+ }
55
+ function hasSuffix(path, suffix) {
56
+ return basename(path).replace(extname(path), "").endsWith(suffix);
57
+ }
58
+
59
+ async function resolvePagesRoutes() {
60
+ const dtwo = useDtwo();
61
+ const pagesDirs = dtwo.options._layers.map(
62
+ (layer) => resolve(layer.config.srcDir, layer.config.dir?.pages || "pages")
63
+ );
64
+ const allRoutes = (await Promise.all(
65
+ pagesDirs.map(async (dir) => {
66
+ const files = await resolveFiles(dir, `**/*{${dtwo.options.extensions.join(",")}}`);
67
+ files.sort();
68
+ return generateRoutesFromFiles(files, dir);
69
+ })
70
+ )).flat();
71
+ return uniqueBy(allRoutes, "path");
72
+ }
73
+ function generateRoutesFromFiles(files, pagesDir) {
74
+ const routes = [];
75
+ for (const file of files) {
76
+ const segments = relative(pagesDir, file).replace(new RegExp(`${escapeRE(extname(file))}$`), "").split("/");
77
+ const route = {
78
+ name: "",
79
+ path: "",
80
+ file,
81
+ children: []
82
+ };
83
+ let parent = routes;
84
+ for (let i = 0; i < segments.length; i++) {
85
+ const segment = segments[i];
86
+ const tokens = parseSegment(segment);
87
+ const segmentName = tokens.map(({ value }) => value).join("");
88
+ route.name += (route.name && "-") + segmentName;
89
+ const child = parent.find((parentRoute) => parentRoute.name === route.name && !parentRoute.path.endsWith("(.*)*"));
90
+ if (child && child.children) {
91
+ parent = child.children;
92
+ route.path = "";
93
+ } else if (segmentName === "index" && !route.path) {
94
+ route.path += "/";
95
+ } else if (segmentName !== "index") {
96
+ route.path += getRoutePath(tokens);
97
+ }
98
+ }
99
+ parent.push(route);
100
+ }
101
+ return prepareRoutes(routes);
102
+ }
103
+ function getRoutePath(tokens) {
104
+ return tokens.reduce((path, token) => {
105
+ return path + (token.type === 2 /* optional */ ? `:${token.value}?` : token.type === 1 /* dynamic */ ? `:${token.value}` : token.type === 3 /* catchall */ ? `:${token.value}(.*)*` : encodePath(token.value));
106
+ }, "/");
107
+ }
108
+ const PARAM_CHAR_RE = /[\w\d_.]/;
109
+ function parseSegment(segment) {
110
+ let state = 0 /* initial */;
111
+ let i = 0;
112
+ let buffer = "";
113
+ const tokens = [];
114
+ function consumeBuffer() {
115
+ if (!buffer) {
116
+ return;
117
+ }
118
+ if (state === 0 /* initial */) {
119
+ throw new Error("wrong state");
120
+ }
121
+ tokens.push({
122
+ type: state === 1 /* static */ ? 0 /* static */ : state === 2 /* dynamic */ ? 1 /* dynamic */ : state === 3 /* optional */ ? 2 /* optional */ : 3 /* catchall */,
123
+ value: buffer
124
+ });
125
+ buffer = "";
126
+ }
127
+ while (i < segment.length) {
128
+ const c = segment[i];
129
+ switch (state) {
130
+ case 0 /* initial */:
131
+ buffer = "";
132
+ if (c === "[") {
133
+ state = 2 /* dynamic */;
134
+ } else {
135
+ i--;
136
+ state = 1 /* static */;
137
+ }
138
+ break;
139
+ case 1 /* static */:
140
+ if (c === "[") {
141
+ consumeBuffer();
142
+ state = 2 /* dynamic */;
143
+ } else {
144
+ buffer += c;
145
+ }
146
+ break;
147
+ case 4 /* catchall */:
148
+ case 2 /* dynamic */:
149
+ case 3 /* optional */:
150
+ if (buffer === "...") {
151
+ buffer = "";
152
+ state = 4 /* catchall */;
153
+ }
154
+ if (c === "[" && state === 2 /* dynamic */) {
155
+ state = 3 /* optional */;
156
+ }
157
+ if (c === "]" && (state !== 3 /* optional */ || buffer[buffer.length - 1] === "]")) {
158
+ if (!buffer) {
159
+ throw new Error("Empty param");
160
+ } else {
161
+ consumeBuffer();
162
+ }
163
+ state = 0 /* initial */;
164
+ } else if (PARAM_CHAR_RE.test(c)) {
165
+ buffer += c;
166
+ } else ;
167
+ break;
168
+ }
169
+ i++;
170
+ }
171
+ if (state === 2 /* dynamic */) {
172
+ throw new Error(`Unfinished param "${buffer}"`);
173
+ }
174
+ consumeBuffer();
175
+ return tokens;
176
+ }
177
+ function prepareRoutes(routes, parent) {
178
+ for (const route of routes) {
179
+ if (route.name) {
180
+ route.name = route.name.replace(/-index$/, "");
181
+ }
182
+ if (parent && route.path.startsWith("/")) {
183
+ route.path = route.path.slice(1);
184
+ }
185
+ if (route.children?.length) {
186
+ route.children = prepareRoutes(route.children, route);
187
+ }
188
+ if (route.children?.find((childRoute) => childRoute.path === "")) {
189
+ delete route.name;
190
+ }
191
+ }
192
+ return routes;
193
+ }
194
+ function normalizeRoutes(routes, metaImports = /* @__PURE__ */ new Set()) {
195
+ return {
196
+ imports: metaImports,
197
+ routes: genArrayFromRaw(routes.map((route) => {
198
+ const file = normalize(route.file);
199
+ const metaImportName = genSafeVariableName(file) + "Meta";
200
+ metaImports.add(genImport(`${file}?macro=true`, [{ name: "default", as: metaImportName }]));
201
+ let aliasCode = `${metaImportName}?.alias || []`;
202
+ if (Array.isArray(route.alias) && route.alias.length) {
203
+ aliasCode = `${JSON.stringify(route.alias)}.concat(${aliasCode})`;
204
+ }
205
+ return {
206
+ ...Object.fromEntries(Object.entries(route).map(([key, value]) => [key, JSON.stringify(value)])),
207
+ name: `${metaImportName}?.name ?? ${route.name ? JSON.stringify(route.name) : "undefined"}`,
208
+ path: `${metaImportName}?.path ?? ${JSON.stringify(route.path)}`,
209
+ children: route.children ? normalizeRoutes(route.children, metaImports).routes : [],
210
+ meta: route.meta ? `{...(${metaImportName} || {}), ...${JSON.stringify(route.meta)}}` : metaImportName,
211
+ alias: aliasCode,
212
+ redirect: route.redirect ? JSON.stringify(route.redirect) : `${metaImportName}?.redirect || undefined`,
213
+ component: genDynamicImport(file, { interopDefault: true })
214
+ };
215
+ }))
216
+ };
217
+ }
218
+
219
+ const CODE_EMPTY = `
220
+ const __dtwo_page_meta = {}
221
+ export default __dtwo_page_meta
222
+ `;
223
+ const CODE_HMR = `
224
+ // Wite
225
+ if (import.meta.hot) {
226
+ import.meta.hot.accept(mod => {
227
+ Object.assign(__dtwo_page_meta, mod)
228
+ })
229
+ }
230
+ // Webpack
231
+ if (import.meta.webpackHot) {
232
+ import.meta.webpackHot.accept((err) => {
233
+ if (err) { window.location = window.location.href }
234
+ })
235
+ }`;
236
+ const PageMetaPlugin = createUnplugin((options) => {
237
+ return {
238
+ name: "dtwo:pages-macros-transform",
239
+ enforce: "post",
240
+ transformInclude(id) {
241
+ const query = parseMacroQuery(id);
242
+ id = normalize(id);
243
+ const isPagesDir = options.dirs.some((dir) => typeof dir === "string" ? id.startsWith(dir) : dir.test(id));
244
+ if (!isPagesDir && !query.macro) {
245
+ return false;
246
+ }
247
+ const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href));
248
+ return /\.(m?[jt]sx?|kdu)/.test(pathname);
249
+ },
250
+ transform(code, id) {
251
+ const query = parseMacroQuery(id);
252
+ if (query.type && query.type !== "script") {
253
+ return;
254
+ }
255
+ const s = new MagicString(code);
256
+ function result() {
257
+ if (s.hasChanged()) {
258
+ return {
259
+ code: s.toString(),
260
+ map: options.sourcemap ? s.generateMap({ source: id, includeContent: true }) : void 0
261
+ };
262
+ }
263
+ }
264
+ const hasMacro = code.match(/\bdefinePageMeta\s*\(\s*/);
265
+ if (!query.macro) {
266
+ if (hasMacro) {
267
+ walk(this.parse(code, {
268
+ sourceType: "module",
269
+ ecmaVersion: "latest"
270
+ }), {
271
+ enter(_node) {
272
+ if (_node.type !== "CallExpression" || _node.callee.type !== "Identifier") {
273
+ return;
274
+ }
275
+ const node = _node;
276
+ const name = "name" in node.callee && node.callee.name;
277
+ if (name === "definePageMeta") {
278
+ s.overwrite(node.start, node.end, "false && {}");
279
+ }
280
+ }
281
+ });
282
+ }
283
+ return result();
284
+ }
285
+ const imports = findStaticImports(code);
286
+ const scriptImport = imports.find((i) => parseMacroQuery(i.specifier).type === "script");
287
+ if (scriptImport) {
288
+ const specifier = rewriteQuery(scriptImport.specifier);
289
+ s.overwrite(0, code.length, `export { default } from ${JSON.stringify(specifier)}`);
290
+ return result();
291
+ }
292
+ const currentExports = findExports(code);
293
+ for (const match of currentExports) {
294
+ if (match.type !== "default" || !match.specifier) {
295
+ continue;
296
+ }
297
+ const specifier = rewriteQuery(match.specifier);
298
+ s.overwrite(0, code.length, `export { default } from ${JSON.stringify(specifier)}`);
299
+ return result();
300
+ }
301
+ if (!hasMacro && !code.includes("export { default }") && !code.includes("__dtwo_page_meta")) {
302
+ s.overwrite(0, code.length, CODE_EMPTY + (options.dev ? CODE_HMR : ""));
303
+ return result();
304
+ }
305
+ const importMap = /* @__PURE__ */ new Map();
306
+ const addedImports = /* @__PURE__ */ new Set();
307
+ for (const i of imports) {
308
+ const parsed = parseStaticImport(i);
309
+ for (const name of [
310
+ parsed.defaultImport,
311
+ ...Object.keys(parsed.namedImports || {}),
312
+ parsed.namespacedImport
313
+ ].filter(Boolean)) {
314
+ importMap.set(name, i);
315
+ }
316
+ }
317
+ walk(this.parse(code, {
318
+ sourceType: "module",
319
+ ecmaVersion: "latest"
320
+ }), {
321
+ enter(_node) {
322
+ if (_node.type !== "CallExpression" || _node.callee.type !== "Identifier") {
323
+ return;
324
+ }
325
+ const node = _node;
326
+ const name = "name" in node.callee && node.callee.name;
327
+ if (name !== "definePageMeta") {
328
+ return;
329
+ }
330
+ const meta = node.arguments[0];
331
+ let contents = `const __dtwo_page_meta = ${code.slice(meta.start, meta.end) || "{}"}
332
+ export default __dtwo_page_meta` + (options.dev ? CODE_HMR : "");
333
+ function addImport(name2) {
334
+ if (name2 && importMap.has(name2)) {
335
+ const importValue = importMap.get(name2).code;
336
+ if (!addedImports.has(importValue)) {
337
+ contents = importMap.get(name2).code + "\n" + contents;
338
+ addedImports.add(importValue);
339
+ }
340
+ }
341
+ }
342
+ walk(meta, {
343
+ enter(_node2) {
344
+ if (_node2.type === "CallExpression") {
345
+ const node2 = _node2;
346
+ addImport("name" in node2.callee && node2.callee.name);
347
+ }
348
+ if (_node2.type === "Identifier") {
349
+ const node2 = _node2;
350
+ addImport(node2.name);
351
+ }
352
+ }
353
+ });
354
+ s.overwrite(0, code.length, contents);
355
+ }
356
+ });
357
+ if (!s.hasChanged() && !code.includes("__dtwo_page_meta")) {
358
+ s.overwrite(0, code.length, CODE_EMPTY + (options.dev ? CODE_HMR : ""));
359
+ }
360
+ return result();
361
+ },
362
+ wite: {
363
+ handleHotUpdate: {
364
+ order: "pre",
365
+ handler: ({ modules }) => {
366
+ const index = modules.findIndex((i) => i.id?.includes("?macro=true"));
367
+ if (index !== -1) {
368
+ modules.splice(index, 1);
369
+ }
370
+ }
371
+ }
372
+ }
373
+ };
374
+ });
375
+ function rewriteQuery(id) {
376
+ const query = stringifyQuery({ macro: "true", ...parseMacroQuery(id) });
377
+ return id.replace(/\?.+$/, "?" + query);
378
+ }
379
+ function parseMacroQuery(id) {
380
+ const { search } = parseURL(decodeURIComponent(isAbsolute(id) ? pathToFileURL(id).href : id).replace(/\?macro=true$/, ""));
381
+ const query = parseQuery(search);
382
+ if (id.includes("?macro=true")) {
383
+ return { macro: "true", ...query };
384
+ }
385
+ return query;
386
+ }
387
+
388
+ const pagesModule = defineDtwoModule({
389
+ meta: {
390
+ name: "pages"
391
+ },
392
+ setup(_options, dtwo) {
393
+ const pagesDirs = dtwo.options._layers.map(
394
+ (layer) => resolve(layer.config.srcDir, layer.config.dir?.pages || "pages")
395
+ );
396
+ const isNonEmptyDir = (dir) => existsSync(dir) && readdirSync(dir).length;
397
+ const isPagesEnabled = () => {
398
+ if (typeof dtwo.options.pages === "boolean") {
399
+ return dtwo.options.pages;
400
+ }
401
+ if (dtwo.options._layers.some((layer) => existsSync(resolve(layer.config.srcDir, "app/router.options.ts")))) {
402
+ return true;
403
+ }
404
+ if (pagesDirs.some((dir) => isNonEmptyDir(dir))) {
405
+ return true;
406
+ }
407
+ return false;
408
+ };
409
+ dtwo.options.pages = isPagesEnabled();
410
+ if (!dtwo.options.pages) {
411
+ addPlugin(resolve(distDir, "app/plugins/router"));
412
+ addTemplate({
413
+ filename: "pages.mjs",
414
+ getContents: () => "export { useRoute } from '#app'"
415
+ });
416
+ addComponent({
417
+ name: "DtwoPage",
418
+ filePath: resolve(distDir, "pages/runtime/page-placeholder")
419
+ });
420
+ return;
421
+ }
422
+ const runtimeDir = resolve(distDir, "pages/runtime");
423
+ dtwo.hook("prepare:types", ({ references }) => {
424
+ references.push({ types: "kdu-router" });
425
+ });
426
+ dtwo.hook("imports:sources", (sources) => {
427
+ const routerImports = sources.find((s) => s.from === "#app" && s.imports.includes("onBeforeRouteLeave"));
428
+ if (routerImports) {
429
+ routerImports.from = "kdu-router";
430
+ }
431
+ });
432
+ dtwo.hook("builder:watch", async (event, path) => {
433
+ const dirs = [
434
+ dtwo.options.dir.pages,
435
+ dtwo.options.dir.layouts,
436
+ dtwo.options.dir.middleware
437
+ ].filter(Boolean);
438
+ const pathPattern = new RegExp(`(^|\\/)(${dirs.map(escapeRE).join("|")})/`);
439
+ if (event !== "change" && path.match(pathPattern)) {
440
+ await updateTemplates({
441
+ filter: (template) => template.filename === "routes.mjs"
442
+ });
443
+ }
444
+ });
445
+ dtwo.hook("app:resolve", (app) => {
446
+ if (app.mainComponent.includes("@dtwo/ui-templates")) {
447
+ app.mainComponent = resolve(runtimeDir, "app.kdu");
448
+ }
449
+ app.middleware.unshift({
450
+ name: "validate",
451
+ path: resolve(runtimeDir, "validate"),
452
+ global: true
453
+ });
454
+ });
455
+ if (!dtwo.options.dev && dtwo.options._generate) {
456
+ const prerenderRoutes = /* @__PURE__ */ new Set();
457
+ dtwo.hook("modules:done", () => {
458
+ dtwo.hook("pages:extend", (pages) => {
459
+ prerenderRoutes.clear();
460
+ const processPages = (pages2, currentPath = "/") => {
461
+ for (const page of pages2) {
462
+ if (page.path.match(/^\/?:.*(\?|\(\.\*\)\*)$/) && !page.children?.length) {
463
+ prerenderRoutes.add(currentPath);
464
+ }
465
+ if (page.path.includes(":")) {
466
+ continue;
467
+ }
468
+ const route = joinURL(currentPath, page.path);
469
+ prerenderRoutes.add(route);
470
+ if (page.children) {
471
+ processPages(page.children, route);
472
+ }
473
+ }
474
+ };
475
+ processPages(pages);
476
+ });
477
+ });
478
+ dtwo.hook("hole:build:before", (hole) => {
479
+ for (const route of hole.options.prerender.routes || []) {
480
+ if (route === "/") {
481
+ continue;
482
+ }
483
+ prerenderRoutes.add(route);
484
+ }
485
+ hole.options.prerender.routes = Array.from(prerenderRoutes);
486
+ });
487
+ }
488
+ dtwo.hook("imports:extend", (imports) => {
489
+ imports.push(
490
+ { name: "definePageMeta", as: "definePageMeta", from: resolve(runtimeDir, "composables") },
491
+ { name: "useLink", as: "useLink", from: "kdu-router" }
492
+ );
493
+ });
494
+ const pageMetaOptions = {
495
+ dev: dtwo.options.dev,
496
+ sourcemap: dtwo.options.sourcemap.server || dtwo.options.sourcemap.client,
497
+ dirs: dtwo.options._layers.map(
498
+ (layer) => resolve(layer.config.srcDir, layer.config.dir?.pages || "pages")
499
+ )
500
+ };
501
+ addWitePlugin(PageMetaPlugin.wite(pageMetaOptions));
502
+ addWebpackPlugin(PageMetaPlugin.webpack(pageMetaOptions));
503
+ addPlugin(resolve(runtimeDir, "router"));
504
+ const getSources = (pages) => pages.flatMap(
505
+ (p) => [relative(dtwo.options.srcDir, p.file), ...getSources(p.children || [])]
506
+ );
507
+ dtwo.hook("build:manifest", async (manifest) => {
508
+ const pages = await resolvePagesRoutes();
509
+ await dtwo.callHook("pages:extend", pages);
510
+ const sourceFiles = getSources(pages);
511
+ for (const key in manifest) {
512
+ if (manifest[key].isEntry) {
513
+ manifest[key].dynamicImports = manifest[key].dynamicImports?.filter((i) => !sourceFiles.includes(i));
514
+ }
515
+ }
516
+ });
517
+ addTemplate({
518
+ filename: "routes.mjs",
519
+ async getContents() {
520
+ const pages = await resolvePagesRoutes();
521
+ await dtwo.callHook("pages:extend", pages);
522
+ const { routes, imports } = normalizeRoutes(pages);
523
+ return [...imports, `export default ${routes}`].join("\n");
524
+ }
525
+ });
526
+ addTemplate({
527
+ filename: "pages.mjs",
528
+ getContents: () => "export { useRoute } from 'kdu-router'"
529
+ });
530
+ dtwo.options.wite.optimizeDeps = dtwo.options.wite.optimizeDeps || {};
531
+ dtwo.options.wite.optimizeDeps.include = dtwo.options.wite.optimizeDeps.include || [];
532
+ dtwo.options.wite.optimizeDeps.include.push("kdu-router");
533
+ addTemplate({
534
+ filename: "router.options.mjs",
535
+ getContents: async () => {
536
+ const routerOptionsFiles = (await Promise.all(dtwo.options._layers.map(
537
+ async (layer) => await findPath(resolve(layer.config.srcDir, "app/router.options"))
538
+ ))).filter(Boolean);
539
+ routerOptionsFiles.push(resolve(runtimeDir, "router.options"));
540
+ const configRouterOptions = genObjectFromRawEntries(Object.entries(dtwo.options.router.options).map(([key, value]) => [key, genString(value)]));
541
+ return [
542
+ ...routerOptionsFiles.map((file, index) => genImport(file, `routerOptions${index}`)),
543
+ `const configRouterOptions = ${configRouterOptions}`,
544
+ "export default {",
545
+ "...configRouterOptions,",
546
+ ...routerOptionsFiles.map((_, index) => `...routerOptions${index},`).reverse(),
547
+ "}"
548
+ ].join("\n");
549
+ }
550
+ });
551
+ addTemplate({
552
+ filename: "types/middleware.d.ts",
553
+ getContents: ({ app }) => {
554
+ const composablesFile = resolve(runtimeDir, "composables");
555
+ const namedMiddleware = app.middleware.filter((mw) => !mw.global);
556
+ return [
557
+ "import type { NavigationGuard } from 'kdu-router'",
558
+ `export type MiddlewareKey = ${namedMiddleware.map((mw) => genString(mw.name)).join(" | ") || "string"}`,
559
+ `declare module ${genString(composablesFile)} {`,
560
+ " interface PageMeta {",
561
+ " middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>",
562
+ " }",
563
+ "}"
564
+ ].join("\n");
565
+ }
566
+ });
567
+ addTemplate({
568
+ filename: "types/layouts.d.ts",
569
+ getContents: ({ app }) => {
570
+ const composablesFile = resolve(runtimeDir, "composables");
571
+ return [
572
+ "import { ComputedRef, Ref } from 'kdu'",
573
+ `export type LayoutKey = ${Object.keys(app.layouts).map((name) => genString(name)).join(" | ") || "string"}`,
574
+ `declare module ${genString(composablesFile)} {`,
575
+ " interface PageMeta {",
576
+ " layout?: false | LayoutKey | Ref<LayoutKey> | ComputedRef<LayoutKey>",
577
+ " }",
578
+ "}"
579
+ ].join("\n");
580
+ }
581
+ });
582
+ addComponent({
583
+ name: "DtwoPage",
584
+ filePath: resolve(distDir, "pages/runtime/page")
585
+ });
586
+ dtwo.hook("prepare:types", ({ references }) => {
587
+ references.push({ path: resolve(dtwo.options.buildDir, "types/middleware.d.ts") });
588
+ references.push({ path: resolve(dtwo.options.buildDir, "types/layouts.d.ts") });
589
+ });
590
+ }
591
+ });
592
+
593
+ const components = ["NoScript", "Link", "Base", "Title", "Meta", "Style", "Head", "Html", "Body"];
594
+ const metaModule = defineDtwoModule({
595
+ meta: {
596
+ name: "meta"
597
+ },
598
+ setup(options, dtwo) {
599
+ const runtimeDir = dtwo.options.alias["#head"] || resolve(distDir, "head/runtime");
600
+ dtwo.options.build.transpile.push("@kduse/head");
601
+ dtwo.options.alias["#head"] = runtimeDir;
602
+ const componentsPath = resolve(runtimeDir, "components");
603
+ for (const componentName of components) {
604
+ addComponent({
605
+ name: componentName,
606
+ filePath: componentsPath,
607
+ export: componentName,
608
+ kebabName: componentName
609
+ });
610
+ }
611
+ addPlugin({ src: resolve(runtimeDir, "lib/kduse-head.plugin") });
612
+ }
613
+ });
614
+
615
+ const createImportMagicComments = (options) => {
616
+ const { chunkName, prefetch, preload } = options;
617
+ return [
618
+ `webpackChunkName: "${chunkName}"`,
619
+ prefetch === true || typeof prefetch === "number" ? `webpackPrefetch: ${prefetch}` : false,
620
+ preload === true || typeof preload === "number" ? `webpackPreload: ${preload}` : false
621
+ ].filter(Boolean).join(", ");
622
+ };
623
+ const componentsPluginTemplate = {
624
+ filename: "components.plugin.mjs",
625
+ getContents({ options }) {
626
+ const globalComponents = options.getComponents().filter((c) => c.global === true);
627
+ return `import { defineAsyncComponent } from 'kdu'
628
+ import { defineDtwoPlugin } from '#app'
629
+
630
+ const components = ${genObjectFromRawEntries(globalComponents.map((c) => {
631
+ const exp = c.export === "default" ? "c.default || c" : `c['${c.export}']`;
632
+ const comment = createImportMagicComments(c);
633
+ return [c.pascalName, `defineAsyncComponent(${genDynamicImport(c.filePath, { comment })}.then(c => ${exp}))`];
634
+ }))}
635
+
636
+ export default defineDtwoPlugin(dtwoApp => {
637
+ for (const name in components) {
638
+ dtwoApp.kduApp.component(name, components[name])
639
+ dtwoApp.kduApp.component('Lazy' + name, components[name])
640
+ }
641
+ })
642
+ `;
643
+ }
644
+ };
645
+ const componentsTemplate = {
646
+ getContents({ options }) {
647
+ const imports = /* @__PURE__ */ new Set();
648
+ imports.add("import { defineAsyncComponent } from 'kdu'");
649
+ let num = 0;
650
+ const components = options.getComponents(options.mode).flatMap((c) => {
651
+ const exp = c.export === "default" ? "c.default || c" : `c['${c.export}']`;
652
+ const comment = createImportMagicComments(c);
653
+ const isClient = c.mode === "client";
654
+ const definitions = [];
655
+ if (isClient) {
656
+ num++;
657
+ const identifier = `__dtwo_component_${num}`;
658
+ imports.add(genImport("#app/components/client-only", [{ name: "createClientOnly" }]));
659
+ imports.add(genImport(c.filePath, [{ name: c.export, as: identifier }]));
660
+ definitions.push(`export const ${c.pascalName} = /*#__PURE__*/ createClientOnly(${identifier})`);
661
+ } else {
662
+ definitions.push(genExport(c.filePath, [{ name: c.export, as: c.pascalName }]));
663
+ }
664
+ definitions.push(`export const Lazy${c.pascalName} = defineAsyncComponent(${genDynamicImport(c.filePath, { comment })}.then(c => ${isClient ? `createClientOnly(${exp})` : exp}))`);
665
+ return definitions;
666
+ });
667
+ return [
668
+ ...imports,
669
+ ...components,
670
+ `export const componentNames = ${JSON.stringify(options.getComponents().map((c) => c.pascalName))}`
671
+ ].join("\n");
672
+ }
673
+ };
674
+ const componentsTypeTemplate = {
675
+ filename: "components.d.ts",
676
+ getContents: ({ options, dtwo }) => {
677
+ const buildDir = dtwo.options.buildDir;
678
+ const componentTypes = options.getComponents().map((c) => [
679
+ c.pascalName,
680
+ `typeof ${genDynamicImport(isAbsolute(c.filePath) ? relative(buildDir, c.filePath).replace(/(?<=\w)\.(?!kdu)\w+$/g, "") : c.filePath.replace(/(?<=\w)\.(?!kdu)\w+$/g, ""), { wrapper: false })}['${c.export}']`
681
+ ]);
682
+ return `// Generated by components discovery
683
+ declare module '@kdujs/runtime-core' {
684
+ export interface GlobalComponents {
685
+ ${componentTypes.map(([pascalName, type]) => ` '${pascalName}': ${type}`).join("\n")}
686
+ ${componentTypes.map(([pascalName, type]) => ` 'Lazy${pascalName}': ${type}`).join("\n")}
687
+ }
688
+ }
689
+
690
+ ${componentTypes.map(([pascalName, type]) => `export const ${pascalName}: ${type}`).join("\n")}
691
+ ${componentTypes.map(([pascalName, type]) => `export const Lazy${pascalName}: ${type}`).join("\n")}
692
+
693
+ export const componentNames: string[]
694
+ `;
695
+ }
696
+ };
697
+
698
+ async function scanComponents(dirs, srcDir) {
699
+ const components = [];
700
+ const filePaths = /* @__PURE__ */ new Set();
701
+ const scannedPaths = [];
702
+ for (const dir of dirs) {
703
+ const resolvedNames = /* @__PURE__ */ new Map();
704
+ const files = (await globby(dir.pattern, { cwd: dir.path, ignore: dir.ignore })).sort();
705
+ for (const _file of files) {
706
+ const filePath = join(dir.path, _file);
707
+ if (scannedPaths.find((d) => filePath.startsWith(withTrailingSlash(d))) || isIgnored(filePath)) {
708
+ continue;
709
+ }
710
+ if (filePaths.has(filePath)) {
711
+ continue;
712
+ }
713
+ filePaths.add(filePath);
714
+ const prefixParts = [].concat(
715
+ dir.prefix ? splitByCase(dir.prefix) : [],
716
+ dir.pathPrefix !== false ? splitByCase(relative(dir.path, dirname(filePath))) : []
717
+ );
718
+ let fileName = basename(filePath, extname(filePath));
719
+ const global = /\.(global)$/.test(fileName) || dir.global;
720
+ const mode = fileName.match(/(?<=\.)(client|server)(\.global)?$/)?.[1] || "all";
721
+ fileName = fileName.replace(/(\.(client|server))?(\.global)?$/, "");
722
+ if (fileName.toLowerCase() === "index") {
723
+ fileName = dir.pathPrefix === false ? basename(dirname(filePath)) : "";
724
+ }
725
+ const fileNameParts = splitByCase(fileName);
726
+ const componentNameParts = [];
727
+ while (prefixParts.length && (prefixParts[0] || "").toLowerCase() !== (fileNameParts[0] || "").toLowerCase()) {
728
+ componentNameParts.push(prefixParts.shift());
729
+ }
730
+ const componentName = pascalCase(componentNameParts) + pascalCase(fileNameParts);
731
+ const suffix = mode !== "all" ? `-${mode}` : "";
732
+ if (resolvedNames.has(componentName + suffix) || resolvedNames.has(componentName)) {
733
+ console.warn(
734
+ `Two component files resolving to the same name \`${componentName}\`:
735
+
736
+ - ${filePath}
737
+ - ${resolvedNames.get(componentName)}`
738
+ );
739
+ continue;
740
+ }
741
+ resolvedNames.set(componentName + suffix, filePath);
742
+ const pascalName = pascalCase(componentName).replace(/["']/g, "");
743
+ const kebabName = hyphenate(componentName);
744
+ const shortPath = relative(srcDir, filePath);
745
+ const chunkName = "components/" + kebabName + suffix;
746
+ let component = {
747
+ mode,
748
+ global,
749
+ prefetch: Boolean(dir.prefetch),
750
+ preload: Boolean(dir.preload),
751
+ filePath,
752
+ pascalName,
753
+ kebabName,
754
+ chunkName,
755
+ shortPath,
756
+ export: "default"
757
+ };
758
+ if (typeof dir.extendComponent === "function") {
759
+ component = await dir.extendComponent(component) || component;
760
+ }
761
+ if (!components.some((c) => c.pascalName === component.pascalName && ["all", component.mode].includes(c.mode))) {
762
+ components.push(component);
763
+ }
764
+ }
765
+ scannedPaths.push(dir.path);
766
+ }
767
+ return components;
768
+ }
769
+
770
+ function isKduTemplate(id) {
771
+ if (id.endsWith(".kdu")) {
772
+ return true;
773
+ }
774
+ const { search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
775
+ if (!search) {
776
+ return false;
777
+ }
778
+ const query = parseQuery(search);
779
+ if (query.macro) {
780
+ return true;
781
+ }
782
+ if (!("kdu" in query) || query.type === "style") {
783
+ return false;
784
+ }
785
+ return true;
786
+ }
787
+ const loaderPlugin = createUnplugin((options) => {
788
+ const exclude = options.transform?.exclude || [];
789
+ const include = options.transform?.include || [];
790
+ return {
791
+ name: "dtwo:components-loader",
792
+ enforce: "post",
793
+ transformInclude(id) {
794
+ if (exclude.some((pattern) => id.match(pattern))) {
795
+ return false;
796
+ }
797
+ if (include.some((pattern) => id.match(pattern))) {
798
+ return true;
799
+ }
800
+ return isKduTemplate(id);
801
+ },
802
+ transform(code, id) {
803
+ const components = options.getComponents();
804
+ let num = 0;
805
+ const imports = /* @__PURE__ */ new Set();
806
+ const map = /* @__PURE__ */ new Map();
807
+ const s = new MagicString(code);
808
+ s.replace(/(?<=[ (])_?resolveComponent\(\s*["'](lazy-|Lazy)?([^'"]*?)["'][\s,]*[^)]*\)/g, (full, lazy, name) => {
809
+ const component = findComponent(components, name, options.mode);
810
+ if (component) {
811
+ let identifier = map.get(component) || `__dtwo_component_${num++}`;
812
+ map.set(component, identifier);
813
+ const isClientOnly = component.mode === "client";
814
+ if (isClientOnly) {
815
+ imports.add(genImport("#app/components/client-only", [{ name: "createClientOnly" }]));
816
+ identifier += "_client";
817
+ }
818
+ if (lazy) {
819
+ imports.add(genImport("kdu", [{ name: "defineAsyncComponent", as: "__defineAsyncComponent" }]));
820
+ identifier += "_lazy";
821
+ imports.add(`const ${identifier} = /*#__PURE__*/ __defineAsyncComponent(${genDynamicImport(component.filePath, { interopDefault: true })}${isClientOnly ? ".then(c => createClientOnly(c))" : ""})`);
822
+ } else {
823
+ imports.add(genImport(component.filePath, [{ name: component.export, as: identifier }]));
824
+ if (isClientOnly) {
825
+ imports.add(`const ${identifier}_wrapped = /*#__PURE__*/ createClientOnly(${identifier})`);
826
+ identifier += "_wrapped";
827
+ }
828
+ }
829
+ return identifier;
830
+ }
831
+ return full;
832
+ });
833
+ if (imports.size) {
834
+ s.prepend([...imports, ""].join("\n"));
835
+ }
836
+ if (s.hasChanged()) {
837
+ return {
838
+ code: s.toString(),
839
+ map: options.sourcemap ? s.generateMap({ source: id, includeContent: true }) : void 0
840
+ };
841
+ }
842
+ }
843
+ };
844
+ });
845
+ function findComponent(components, name, mode) {
846
+ const id = pascalCase(name).replace(/["']/g, "");
847
+ const component = components.find((component2) => id === component2.pascalName && ["all", mode, void 0].includes(component2.mode));
848
+ if (!component && components.some((component2) => id === component2.pascalName)) {
849
+ return components.find((component2) => component2.pascalName === "ServerPlaceholder");
850
+ }
851
+ return component;
852
+ }
853
+
854
+ const PLACEHOLDER_RE = /^(k-slot|#)(fallback|placeholder)/;
855
+ const TreeShakeTemplatePlugin = createUnplugin((options) => {
856
+ const regexpMap = /* @__PURE__ */ new WeakMap();
857
+ return {
858
+ name: "dtwo:tree-shake-template",
859
+ enforce: "pre",
860
+ transformInclude(id) {
861
+ const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href));
862
+ return pathname.endsWith(".kdu");
863
+ },
864
+ async transform(code, id) {
865
+ const template = code.match(/<template>([\s\S]*)<\/template>/);
866
+ if (!template) {
867
+ return;
868
+ }
869
+ const components = options.getComponents();
870
+ if (!regexpMap.has(components)) {
871
+ const clientOnlyComponents2 = components.filter((c) => c.mode === "client" && !components.some((other) => other.mode !== "client" && other.pascalName === c.pascalName)).flatMap((c) => [c.pascalName, c.kebabName]).concat(["ClientOnly", "client-only"]);
872
+ const tags = clientOnlyComponents2.map((component) => `<(${component})[^>]*>[\\s\\S]*?<\\/(${component})>`);
873
+ regexpMap.set(components, [new RegExp(`(${tags.join("|")})`, "g"), clientOnlyComponents2]);
874
+ }
875
+ const [COMPONENTS_RE, clientOnlyComponents] = regexpMap.get(components);
876
+ if (!COMPONENTS_RE.test(code)) {
877
+ return;
878
+ }
879
+ const s = new MagicString(code);
880
+ const ast = parse(template[0]);
881
+ await walk$1(ast, (node) => {
882
+ if (node.type !== ELEMENT_NODE || !clientOnlyComponents.includes(node.name) || !node.children?.length) {
883
+ return;
884
+ }
885
+ const fallback = node.children.find(
886
+ (n) => n.name === "template" && Object.entries(n.attributes)?.flat().some((attr) => PLACEHOLDER_RE.test(attr))
887
+ );
888
+ try {
889
+ const text = fallback ? code.slice(template.index + fallback.loc[0].start, template.index + fallback.loc[fallback.loc.length - 1].end) : "";
890
+ s.overwrite(template.index + node.loc[0].end, template.index + node.loc[node.loc.length - 1].start, text);
891
+ } catch (err) {
892
+ }
893
+ });
894
+ if (s.hasChanged()) {
895
+ return {
896
+ code: s.toString(),
897
+ map: options.sourcemap ? s.generateMap({ source: id, includeContent: true }) : void 0
898
+ };
899
+ }
900
+ }
901
+ };
902
+ });
903
+
904
+ const isPureObjectOrString = (val) => !Array.isArray(val) && typeof val === "object" || typeof val === "string";
905
+ const isDirectory = (p) => {
906
+ try {
907
+ return statSync(p).isDirectory();
908
+ } catch (_e) {
909
+ return false;
910
+ }
911
+ };
912
+ function compareDirByPathLength({ path: pathA }, { path: pathB }) {
913
+ return pathB.split(/[\\/]/).filter(Boolean).length - pathA.split(/[\\/]/).filter(Boolean).length;
914
+ }
915
+ const DEFAULT_COMPONENTS_DIRS_RE = /\/components$|\/components\/global$/;
916
+ const componentsModule = defineDtwoModule({
917
+ meta: {
918
+ name: "components",
919
+ configKey: "components"
920
+ },
921
+ defaults: {
922
+ dirs: []
923
+ },
924
+ setup(componentOptions, dtwo) {
925
+ let componentDirs = [];
926
+ const context = {
927
+ components: []
928
+ };
929
+ const getComponents = (mode) => {
930
+ return mode && mode !== "all" ? context.components.filter((c) => c.mode === mode || c.mode === "all") : context.components;
931
+ };
932
+ const normalizeDirs = (dir, cwd) => {
933
+ if (Array.isArray(dir)) {
934
+ return dir.map((dir2) => normalizeDirs(dir2, cwd)).flat().sort(compareDirByPathLength);
935
+ }
936
+ if (dir === true || dir === void 0) {
937
+ return [
938
+ { path: resolve(cwd, "components/global"), global: true },
939
+ { path: resolve(cwd, "components") }
940
+ ];
941
+ }
942
+ if (typeof dir === "string") {
943
+ return [
944
+ { path: resolve(cwd, resolveAlias(dir)) }
945
+ ];
946
+ }
947
+ if (!dir) {
948
+ return [];
949
+ }
950
+ const dirs = (dir.dirs || [dir]).map((dir2) => typeof dir2 === "string" ? { path: dir2 } : dir2).filter((_dir) => _dir.path);
951
+ return dirs.map((_dir) => ({
952
+ ..._dir,
953
+ path: resolve(cwd, resolveAlias(_dir.path))
954
+ }));
955
+ };
956
+ dtwo.hook("app:resolve", async () => {
957
+ const allDirs = dtwo.options._layers.map((layer) => normalizeDirs(layer.config.components, layer.config.srcDir)).flat();
958
+ await dtwo.callHook("components:dirs", allDirs);
959
+ componentDirs = allDirs.filter(isPureObjectOrString).map((dir) => {
960
+ const dirOptions = typeof dir === "object" ? dir : { path: dir };
961
+ const dirPath = resolveAlias(dirOptions.path);
962
+ const transpile = typeof dirOptions.transpile === "boolean" ? dirOptions.transpile : "auto";
963
+ const extensions = (dirOptions.extensions || dtwo.options.extensions).map((e) => e.replace(/^\./g, ""));
964
+ const present = isDirectory(dirPath);
965
+ if (!present && !DEFAULT_COMPONENTS_DIRS_RE.test(dirOptions.path)) {
966
+ console.warn("Components directory not found: `" + dirPath + "`");
967
+ }
968
+ return {
969
+ global: componentOptions.global,
970
+ ...dirOptions,
971
+ enabled: true,
972
+ path: dirPath,
973
+ extensions,
974
+ pattern: dirOptions.pattern || `**/*.{${extensions.join(",")},}`,
975
+ ignore: [
976
+ "**/*{M,.m,-m}ixin.{js,ts,jsx,tsx}",
977
+ "**/*.d.ts",
978
+ ...dirOptions.ignore || []
979
+ ],
980
+ transpile: transpile === "auto" ? dirPath.includes("node_modules") : transpile
981
+ };
982
+ }).filter((d) => d.enabled);
983
+ componentDirs = [
984
+ ...componentDirs.filter((dir) => !dir.path.includes("node_modules")),
985
+ ...componentDirs.filter((dir) => dir.path.includes("node_modules"))
986
+ ];
987
+ dtwo.options.build.transpile.push(...componentDirs.filter((dir) => dir.transpile).map((dir) => dir.path));
988
+ });
989
+ addTemplate({ ...componentsTypeTemplate, options: { getComponents } });
990
+ addPluginTemplate({ ...componentsPluginTemplate, options: { getComponents } });
991
+ addTemplate({ ...componentsTemplate, filename: "components.server.mjs", options: { getComponents, mode: "server" } });
992
+ addTemplate({ ...componentsTemplate, filename: "components.client.mjs", options: { getComponents, mode: "client" } });
993
+ dtwo.hook("wite:extendConfig", (config, { isClient }) => {
994
+ const mode = isClient ? "client" : "server";
995
+ config.resolve.alias["#components"] = resolve(dtwo.options.buildDir, `components.${mode}.mjs`);
996
+ });
997
+ dtwo.hook("webpack:config", (configs) => {
998
+ for (const config of configs) {
999
+ const mode = config.name === "server" ? "server" : "client";
1000
+ config.resolve.alias["#components"] = resolve(dtwo.options.buildDir, `components.${mode}.mjs`);
1001
+ }
1002
+ });
1003
+ dtwo.hook("build:manifest", (manifest) => {
1004
+ const sourceFiles = getComponents().filter((c) => c.global).map((c) => relative(dtwo.options.srcDir, c.filePath));
1005
+ for (const key in manifest) {
1006
+ if (manifest[key].isEntry) {
1007
+ manifest[key].dynamicImports = manifest[key].dynamicImports?.filter((i) => !sourceFiles.includes(i));
1008
+ }
1009
+ }
1010
+ });
1011
+ dtwo.hook("app:templates", async () => {
1012
+ const newComponents = await scanComponents(componentDirs, dtwo.options.srcDir);
1013
+ await dtwo.callHook("components:extend", newComponents);
1014
+ for (const component of newComponents) {
1015
+ if (component.mode === "client" && !newComponents.some((c) => c.pascalName === component.pascalName && c.mode === "server")) {
1016
+ newComponents.push({
1017
+ ...component,
1018
+ mode: "server",
1019
+ filePath: resolve(distDir, "app/components/server-placeholder"),
1020
+ chunkName: "components/" + component.kebabName
1021
+ });
1022
+ }
1023
+ }
1024
+ context.components = newComponents;
1025
+ });
1026
+ dtwo.hook("prepare:types", ({ references, tsConfig }) => {
1027
+ tsConfig.compilerOptions.paths["#components"] = [relative(dtwo.options.rootDir, resolve(dtwo.options.buildDir, "components"))];
1028
+ references.push({ path: resolve(dtwo.options.buildDir, "components.d.ts") });
1029
+ });
1030
+ dtwo.hook("builder:watch", async (event, path) => {
1031
+ if (!["add", "unlink"].includes(event)) {
1032
+ return;
1033
+ }
1034
+ const fPath = resolve(dtwo.options.srcDir, path);
1035
+ if (componentDirs.find((dir) => fPath.startsWith(dir.path))) {
1036
+ await updateTemplates({
1037
+ filter: (template) => [
1038
+ "components.plugin.mjs",
1039
+ "components.d.ts",
1040
+ "components.server.mjs",
1041
+ "components.client.mjs"
1042
+ ].includes(template.filename)
1043
+ });
1044
+ }
1045
+ });
1046
+ dtwo.hook("wite:extendConfig", (config, { isClient, isServer }) => {
1047
+ const mode = isClient ? "client" : "server";
1048
+ config.plugins = config.plugins || [];
1049
+ config.plugins.push(loaderPlugin.wite({
1050
+ sourcemap: dtwo.options.sourcemap[mode],
1051
+ getComponents,
1052
+ mode
1053
+ }));
1054
+ if (dtwo.options.experimental.treeshakeClientOnly && isServer) {
1055
+ config.plugins.push(TreeShakeTemplatePlugin.wite({
1056
+ sourcemap: dtwo.options.sourcemap[mode],
1057
+ getComponents
1058
+ }));
1059
+ }
1060
+ });
1061
+ dtwo.hook("webpack:config", (configs) => {
1062
+ configs.forEach((config) => {
1063
+ const mode = config.name === "client" ? "client" : "server";
1064
+ config.plugins = config.plugins || [];
1065
+ config.plugins.push(loaderPlugin.webpack({
1066
+ sourcemap: dtwo.options.sourcemap[mode],
1067
+ getComponents,
1068
+ mode
1069
+ }));
1070
+ if (dtwo.options.experimental.treeshakeClientOnly && mode === "server") {
1071
+ config.plugins.push(TreeShakeTemplatePlugin.webpack({
1072
+ sourcemap: dtwo.options.sourcemap[mode],
1073
+ getComponents
1074
+ }));
1075
+ }
1076
+ });
1077
+ });
1078
+ }
1079
+ });
1080
+
1081
+ const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }) => {
1082
+ return {
1083
+ name: "dtwo:imports-transform",
1084
+ enforce: "post",
1085
+ transformInclude(id) {
1086
+ const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
1087
+ const query = parseQuery(search);
1088
+ if (options.transform?.include?.some((pattern) => id.match(pattern))) {
1089
+ return true;
1090
+ }
1091
+ if (options.transform?.exclude?.some((pattern) => id.match(pattern))) {
1092
+ return false;
1093
+ }
1094
+ if (id.endsWith(".kdu") || "macro" in query || "kdu" in query && (query.type === "template" || query.type === "script" || "setup" in query)) {
1095
+ return true;
1096
+ }
1097
+ if (pathname.match(/\.((c|m)?j|t)sx?$/g)) {
1098
+ return true;
1099
+ }
1100
+ },
1101
+ async transform(code, id) {
1102
+ id = normalize(id);
1103
+ const isNodeModule = id.match(/[\\/]node_modules[\\/]/) && !options.transform?.include?.some((pattern) => id.match(pattern));
1104
+ if (isNodeModule && !code.match(/(['"])#imports\1/)) {
1105
+ return;
1106
+ }
1107
+ const { s } = await ctx.injectImports(code, id, { autoImport: options.autoImport && !isNodeModule });
1108
+ if (s.hasChanged()) {
1109
+ return {
1110
+ code: s.toString(),
1111
+ map: sourcemap ? s.generateMap({ source: id, includeContent: true }) : void 0
1112
+ };
1113
+ }
1114
+ }
1115
+ };
1116
+ });
1117
+
1118
+ const commonPresets = [
1119
+ defineKdimportPreset({
1120
+ from: "#head",
1121
+ imports: [
1122
+ "useHead"
1123
+ ]
1124
+ }),
1125
+ defineKdimportPreset({
1126
+ from: "kdu-demi",
1127
+ imports: [
1128
+ "isKdu2",
1129
+ "isKdu3"
1130
+ ]
1131
+ })
1132
+ ];
1133
+ const appPreset = defineKdimportPreset({
1134
+ from: "#app",
1135
+ imports: [
1136
+ "useAsyncData",
1137
+ "useLazyAsyncData",
1138
+ "refreshDtwoData",
1139
+ "clearDtwoData",
1140
+ "defineDtwoComponent",
1141
+ "useDtwoApp",
1142
+ "defineDtwoPlugin",
1143
+ "useRuntimeConfig",
1144
+ "useState",
1145
+ "useFetch",
1146
+ "useLazyFetch",
1147
+ "useCookie",
1148
+ "useRequestHeaders",
1149
+ "useRequestEvent",
1150
+ "setResponseStatus",
1151
+ "setPageLayout",
1152
+ "useRouter",
1153
+ "useRoute",
1154
+ "useActiveRoute",
1155
+ "defineDtwoRouteMiddleware",
1156
+ "navigateTo",
1157
+ "abortNavigation",
1158
+ "addRouteMiddleware",
1159
+ "throwError",
1160
+ "showError",
1161
+ "clearError",
1162
+ "isDtwoError",
1163
+ "useError",
1164
+ "createError",
1165
+ "defineDtwoLink",
1166
+ "useAppConfig",
1167
+ "updateAppConfig",
1168
+ "defineAppConfig",
1169
+ "preloadComponents",
1170
+ "preloadRouteComponents",
1171
+ "prefetchComponents",
1172
+ "loadPayload",
1173
+ "preloadPayload",
1174
+ "isPrerendered"
1175
+ ]
1176
+ });
1177
+ const routerPreset = defineKdimportPreset({
1178
+ from: "#app",
1179
+ imports: [
1180
+ "onBeforeRouteLeave",
1181
+ "onBeforeRouteUpdate"
1182
+ ]
1183
+ });
1184
+ const kduPreset = defineKdimportPreset({
1185
+ from: "kdu",
1186
+ imports: [
1187
+ "withCtx",
1188
+ "withDirectives",
1189
+ "withKeys",
1190
+ "withMemo",
1191
+ "withModifiers",
1192
+ "withScopeId",
1193
+ "onActivated",
1194
+ "onBeforeMount",
1195
+ "onBeforeUnmount",
1196
+ "onBeforeUpdate",
1197
+ "onDeactivated",
1198
+ "onErrorCaptured",
1199
+ "onMounted",
1200
+ "onRenderTracked",
1201
+ "onRenderTriggered",
1202
+ "onServerPrefetch",
1203
+ "onUnmounted",
1204
+ "onUpdated",
1205
+ "computed",
1206
+ "customRef",
1207
+ "isProxy",
1208
+ "isReactive",
1209
+ "isReadonly",
1210
+ "isRef",
1211
+ "markRaw",
1212
+ "proxyRefs",
1213
+ "reactive",
1214
+ "readonly",
1215
+ "ref",
1216
+ "shallowReactive",
1217
+ "shallowReadonly",
1218
+ "shallowRef",
1219
+ "toRaw",
1220
+ "toRef",
1221
+ "toRefs",
1222
+ "triggerRef",
1223
+ "unref",
1224
+ "watch",
1225
+ "watchEffect",
1226
+ "isShallow",
1227
+ "effect",
1228
+ "effectScope",
1229
+ "getCurrentScope",
1230
+ "onScopeDispose",
1231
+ "defineComponent",
1232
+ "defineAsyncComponent",
1233
+ "resolveComponent",
1234
+ "getCurrentInstance",
1235
+ "h",
1236
+ "inject",
1237
+ "nextTick",
1238
+ "provide",
1239
+ "useAttrs",
1240
+ "useCssModule",
1241
+ "useCssVars",
1242
+ "useSlots",
1243
+ "useTransitionState"
1244
+ ]
1245
+ });
1246
+ const defaultPresets = [
1247
+ ...commonPresets,
1248
+ appPreset,
1249
+ routerPreset,
1250
+ kduPreset
1251
+ ];
1252
+
1253
+ const importsModule = defineDtwoModule({
1254
+ meta: {
1255
+ name: "imports",
1256
+ configKey: "imports"
1257
+ },
1258
+ defaults: {
1259
+ autoImport: true,
1260
+ presets: defaultPresets,
1261
+ global: false,
1262
+ imports: [],
1263
+ dirs: [],
1264
+ transform: {
1265
+ include: [],
1266
+ exclude: void 0
1267
+ }
1268
+ },
1269
+ async setup(options, dtwo) {
1270
+ const presets = JSON.parse(JSON.stringify(options.presets));
1271
+ await dtwo.callHook("imports:sources", presets);
1272
+ const ctx = createKdimport({
1273
+ presets,
1274
+ imports: options.imports,
1275
+ virtualImports: ["#imports"],
1276
+ addons: {
1277
+ kduTemplate: options.autoImport
1278
+ }
1279
+ });
1280
+ let composablesDirs = [];
1281
+ for (const layer of dtwo.options._layers) {
1282
+ composablesDirs.push(resolve(layer.config.srcDir, "composables"));
1283
+ composablesDirs.push(resolve(layer.config.srcDir, "utils"));
1284
+ for (const dir of layer.config.imports?.dirs ?? []) {
1285
+ if (!dir) {
1286
+ continue;
1287
+ }
1288
+ composablesDirs.push(resolve(layer.config.srcDir, dir));
1289
+ }
1290
+ }
1291
+ await dtwo.callHook("imports:dirs", composablesDirs);
1292
+ composablesDirs = composablesDirs.map((dir) => normalize(dir));
1293
+ addTemplate({
1294
+ filename: "imports.mjs",
1295
+ getContents: async () => await ctx.toExports() + '\nif (process.dev) { console.warn("[dtwo] `#imports` should be transformed with real imports. There seems to be something wrong with the imports plugin.") }'
1296
+ });
1297
+ dtwo.options.alias["#imports"] = join(dtwo.options.buildDir, "imports");
1298
+ if (dtwo.options.dev && options.global) {
1299
+ addPluginTemplate({
1300
+ filename: "imports.mjs",
1301
+ getContents: async () => {
1302
+ const imports = await ctx.getImports();
1303
+ const importStatement = toImports(imports);
1304
+ const globalThisSet = imports.map((i) => `globalThis.${i.as} = ${i.as};`).join("\n");
1305
+ return `${importStatement}
1306
+
1307
+ ${globalThisSet}
1308
+
1309
+ export default () => {};`;
1310
+ }
1311
+ });
1312
+ } else {
1313
+ addWitePlugin(TransformPlugin.wite({ ctx, options, sourcemap: dtwo.options.sourcemap.server || dtwo.options.sourcemap.client }));
1314
+ addWebpackPlugin(TransformPlugin.webpack({ ctx, options, sourcemap: dtwo.options.sourcemap.server || dtwo.options.sourcemap.client }));
1315
+ }
1316
+ const regenerateImports = async () => {
1317
+ ctx.clearDynamicImports();
1318
+ await ctx.modifyDynamicImports(async (imports) => {
1319
+ imports.push(...await scanDirExports(composablesDirs));
1320
+ await dtwo.callHook("imports:extend", imports);
1321
+ });
1322
+ };
1323
+ await regenerateImports();
1324
+ addDeclarationTemplates(ctx, options);
1325
+ dtwo.hook("prepare:types", ({ references }) => {
1326
+ references.push({ path: resolve(dtwo.options.buildDir, "types/imports.d.ts") });
1327
+ references.push({ path: resolve(dtwo.options.buildDir, "imports.d.ts") });
1328
+ });
1329
+ const templates = [
1330
+ "types/imports.d.ts",
1331
+ "imports.d.ts",
1332
+ "imports.mjs"
1333
+ ];
1334
+ dtwo.hook("builder:watch", async (_, path) => {
1335
+ const _resolved = resolve(dtwo.options.srcDir, path);
1336
+ if (composablesDirs.find((dir) => _resolved.startsWith(dir))) {
1337
+ await updateTemplates({
1338
+ filter: (template) => templates.includes(template.filename)
1339
+ });
1340
+ }
1341
+ });
1342
+ dtwo.hook("builder:generateApp", async () => {
1343
+ await regenerateImports();
1344
+ });
1345
+ }
1346
+ });
1347
+ function addDeclarationTemplates(ctx, options) {
1348
+ const dtwo = useDtwo();
1349
+ const stripExtension = (path) => path.replace(/\.[a-z]+$/, "");
1350
+ const resolved = {};
1351
+ const r = ({ from }) => {
1352
+ if (resolved[from]) {
1353
+ return resolved[from];
1354
+ }
1355
+ let path = resolveAlias(from);
1356
+ if (isAbsolute(path)) {
1357
+ path = relative(join(dtwo.options.buildDir, "types"), path);
1358
+ }
1359
+ path = stripExtension(path);
1360
+ resolved[from] = path;
1361
+ return path;
1362
+ };
1363
+ addTemplate({
1364
+ filename: "imports.d.ts",
1365
+ getContents: () => ctx.toExports(dtwo.options.buildDir)
1366
+ });
1367
+ addTemplate({
1368
+ filename: "types/imports.d.ts",
1369
+ getContents: async () => "// Generated by auto imports\n" + (options.autoImport ? await ctx.generateTypeDeclarations({ resolvePath: r }) : "// Implicit auto importing is disabled, you can use explicitly import from `#imports` instead.")
1370
+ });
1371
+ }
1372
+
1373
+ const version = "3.0.0-rc.14";
1374
+
1375
+ const _require = createRequire(import.meta.url);
1376
+ const kduAppPatterns = (dtwo) => [
1377
+ [/^(dtwo3|dtwo)$/, "`dtwo3`/`dtwo` cannot be imported directly. Instead, import runtime Dtwo composables from `#app` or `#imports`."],
1378
+ [/^((|~|~~|@|@@)\/)?dtwo\.config(\.|$)/, "Importing directly from a `dtwo.config` file is not allowed. Instead, use runtime config or a module."],
1379
+ [/(^|node_modules\/)@kdujs\/composition-api/],
1380
+ ...dtwo.options.modules.filter((m) => typeof m === "string").map((m) => [new RegExp(`^${escapeRE(m)}$`), "Importing directly from module entry points is not allowed."]),
1381
+ ...[/(^|node_modules\/)@dtwo\/kit/, /^holepack/].map((i) => [i, "This module cannot be imported in the Kdu part of your app."]),
1382
+ [new RegExp(escapeRE(join(dtwo.options.srcDir, dtwo.options.dir.server || "server")) + "\\/(api|routes|middleware|plugins)\\/"), "Importing from server is not allowed in the Kdu part of your app."]
1383
+ ];
1384
+ const ImportProtectionPlugin = createUnplugin(function(options) {
1385
+ const cache = {};
1386
+ const importersToExclude = options?.exclude || [];
1387
+ return {
1388
+ name: "dtwo:import-protection",
1389
+ enforce: "pre",
1390
+ resolveId(id, importer) {
1391
+ if (!importer) {
1392
+ return;
1393
+ }
1394
+ if (id.startsWith(".")) {
1395
+ id = join(importer, "..", id);
1396
+ }
1397
+ if (isAbsolute(id)) {
1398
+ id = relative(options.rootDir, id);
1399
+ }
1400
+ if (importersToExclude.some((p) => typeof p === "string" ? importer === p : p.test(importer))) {
1401
+ return;
1402
+ }
1403
+ const invalidImports = options.patterns.filter(([pattern]) => pattern instanceof RegExp ? pattern.test(id) : pattern === id);
1404
+ let matched = false;
1405
+ for (const match of invalidImports) {
1406
+ cache[id] = cache[id] || /* @__PURE__ */ new Map();
1407
+ const [pattern, warning] = match;
1408
+ if (cache[id].has(pattern)) {
1409
+ continue;
1410
+ }
1411
+ const relativeImporter = isAbsolute(importer) ? relative(options.rootDir, importer) : importer;
1412
+ logger.error(warning || "Invalid import", `[importing \`${id}\` from \`${relativeImporter}\`]`);
1413
+ cache[id].set(pattern, true);
1414
+ matched = true;
1415
+ }
1416
+ if (matched) {
1417
+ return _require.resolve("unenv/runtime/mock/proxy");
1418
+ }
1419
+ return null;
1420
+ }
1421
+ };
1422
+ });
1423
+
1424
+ const UnctxTransformPlugin = (dtwo) => {
1425
+ const transformer = createTransformer({
1426
+ asyncFunctions: ["defineDtwoPlugin", "defineDtwoRouteMiddleware"]
1427
+ });
1428
+ let app;
1429
+ dtwo.hook("app:resolve", (_app) => {
1430
+ app = _app;
1431
+ });
1432
+ return createUnplugin((options = {}) => ({
1433
+ name: "unctx:transfrom",
1434
+ enforce: "post",
1435
+ transformInclude(id) {
1436
+ id = normalize(id).replace(/\?.*$/, "");
1437
+ return app?.plugins.some((i) => i.src === id) || app?.middleware.some((m) => m.path === id);
1438
+ },
1439
+ transform(code, id) {
1440
+ const result = transformer.transform(code);
1441
+ if (result) {
1442
+ return {
1443
+ code: result.code,
1444
+ map: options.sourcemap ? result.magicString.generateMap({ source: id, includeContent: true }) : void 0
1445
+ };
1446
+ }
1447
+ }
1448
+ }));
1449
+ };
1450
+
1451
+ const TreeShakePlugin = createUnplugin((options) => {
1452
+ const COMPOSABLE_RE = new RegExp(`($\\s+)(${options.treeShake.join("|")})(?=\\()`, "gm");
1453
+ return {
1454
+ name: "dtwo:server-treeshake:transfrom",
1455
+ enforce: "post",
1456
+ transformInclude(id) {
1457
+ const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
1458
+ const { type } = parseQuery(search);
1459
+ if (pathname.endsWith(".kdu") && (type === "script" || !search)) {
1460
+ return true;
1461
+ }
1462
+ if (pathname.match(/\.((c|m)?j|t)sx?$/g)) {
1463
+ return true;
1464
+ }
1465
+ },
1466
+ transform(code, id) {
1467
+ if (!code.match(COMPOSABLE_RE)) {
1468
+ return;
1469
+ }
1470
+ const s = new MagicString(code);
1471
+ const strippedCode = stripLiteral(code);
1472
+ for (const match of strippedCode.matchAll(COMPOSABLE_RE) || []) {
1473
+ s.overwrite(match.index, match.index + match[0].length, `${match[1]} /*#__PURE__*/ false && ${match[2]}`);
1474
+ }
1475
+ if (s.hasChanged()) {
1476
+ return {
1477
+ code: s.toString(),
1478
+ map: options.sourcemap ? s.generateMap({ source: id, includeContent: true }) : void 0
1479
+ };
1480
+ }
1481
+ }
1482
+ };
1483
+ });
1484
+
1485
+ const DevOnlyPlugin = createUnplugin((options) => {
1486
+ const DEVONLY_COMP_RE = /<dev-?only>(:?[\s\S]*)<\/dev-?only>/gmi;
1487
+ return {
1488
+ name: "dtwo:server-devonly:transfrom",
1489
+ enforce: "pre",
1490
+ transformInclude(id) {
1491
+ const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
1492
+ const { type } = parseQuery(search);
1493
+ if (pathname.endsWith(".kdu") && (type === "template" || !search)) {
1494
+ return true;
1495
+ }
1496
+ },
1497
+ transform(code, id) {
1498
+ if (!code.match(DEVONLY_COMP_RE)) {
1499
+ return;
1500
+ }
1501
+ const s = new MagicString(code);
1502
+ const strippedCode = stripLiteral(code);
1503
+ for (const match of strippedCode.matchAll(DEVONLY_COMP_RE) || []) {
1504
+ s.remove(match.index, match.index + match[0].length);
1505
+ }
1506
+ if (s.hasChanged()) {
1507
+ return {
1508
+ code: s.toString(),
1509
+ map: options.sourcemap ? s.generateMap({ source: id, includeContent: true }) : void 0
1510
+ };
1511
+ }
1512
+ }
1513
+ };
1514
+ });
1515
+
1516
+ const addModuleTranspiles = (opts = {}) => {
1517
+ const dtwo = useDtwo();
1518
+ const modules = [
1519
+ ...opts.additionalModules || [],
1520
+ ...dtwo.options.modules,
1521
+ ...dtwo.options._modules
1522
+ ].map((m) => typeof m === "string" ? m : Array.isArray(m) ? m[0] : m.src).filter((m) => typeof m === "string").map((m) => m.split("node_modules/").pop());
1523
+ dtwo.options.build.transpile = dtwo.options.build.transpile.map((m) => typeof m === "string" ? m.split("node_modules/").pop() : m).filter((x) => !!x);
1524
+ function isTranspilePresent(mod) {
1525
+ return dtwo.options.build.transpile.some((t) => !(t instanceof Function) && (t instanceof RegExp ? t.test(mod) : new RegExp(t).test(mod)));
1526
+ }
1527
+ for (const module of modules) {
1528
+ if (!isTranspilePresent(module)) {
1529
+ dtwo.options.build.transpile.push(module);
1530
+ }
1531
+ }
1532
+ };
1533
+
1534
+ async function initHole(dtwo) {
1535
+ const _holeConfig = dtwo.options.hole || {};
1536
+ const holeConfig = defu(_holeConfig, {
1537
+ debug: dtwo.options.debug,
1538
+ rootDir: dtwo.options.rootDir,
1539
+ workspaceDir: dtwo.options.workspaceDir,
1540
+ srcDir: dtwo.options.serverDir,
1541
+ dev: dtwo.options.dev,
1542
+ buildDir: dtwo.options.buildDir,
1543
+ esbuild: {
1544
+ options: {
1545
+ exclude: [
1546
+ new RegExp(`node_modules\\/(?!${dtwo.options._layers.map((l) => l.cwd.match(/(?<=\/)node_modules\/(.+)$/)?.[1]).filter(Boolean).map((dir) => escapeRE(dir)).join("|")})`)
1547
+ ]
1548
+ }
1549
+ },
1550
+ analyze: dtwo.options.build.analyze && {
1551
+ template: "treemap",
1552
+ projectRoot: dtwo.options.rootDir,
1553
+ filename: join(dtwo.options.rootDir, ".dtwo/stats", "{name}.html")
1554
+ },
1555
+ scanDirs: dtwo.options._layers.map((layer) => (layer.config.serverDir || layer.config.srcDir) && resolve(layer.cwd, layer.config.serverDir || resolve(layer.config.srcDir, "server"))).filter(Boolean),
1556
+ renderer: resolve(distDir, "core/runtime/hole/renderer"),
1557
+ errorHandler: resolve(distDir, "core/runtime/hole/error"),
1558
+ nodeModulesDirs: dtwo.options.modulesDir,
1559
+ handlers: dtwo.options.serverHandlers,
1560
+ devHandlers: [],
1561
+ baseURL: dtwo.options.app.baseURL,
1562
+ virtual: {
1563
+ "#internal/dtwo.config.mjs": () => dtwo.vfs["#build/dtwo.config"]
1564
+ },
1565
+ routeRules: {
1566
+ "/__dtwo_error": { cache: false }
1567
+ },
1568
+ runtimeConfig: {
1569
+ ...dtwo.options.runtimeConfig,
1570
+ hole: {
1571
+ envPrefix: "DTWO_",
1572
+ ...dtwo.options.runtimeConfig.hole
1573
+ }
1574
+ },
1575
+ typescript: {
1576
+ generateTsConfig: false
1577
+ },
1578
+ publicAssets: [
1579
+ { dir: resolve(dtwo.options.buildDir, "dist/client") },
1580
+ ...dtwo.options._layers.map((layer) => join(layer.config.srcDir, layer.config.dir?.public || "public")).filter((dir) => existsSync(dir)).map((dir) => ({ dir }))
1581
+ ],
1582
+ prerender: {
1583
+ crawlLinks: dtwo.options._generate ?? void 0,
1584
+ routes: [].concat(dtwo.options.generate.routes).concat(dtwo.options._generate ? [dtwo.options.ssr ? "/" : "/index.html", "/200.html", "/404.html"] : [])
1585
+ },
1586
+ sourceMap: dtwo.options.sourcemap.server,
1587
+ externals: {
1588
+ inline: [
1589
+ ...dtwo.options.dev ? [] : [
1590
+ ...dtwo.options.experimental.externalKdu ? [] : ["kdu", "@kdujs/"],
1591
+ "@dtwo/",
1592
+ dtwo.options.buildDir
1593
+ ],
1594
+ "dtwo/dist",
1595
+ "dtwo3/dist",
1596
+ distDir
1597
+ ]
1598
+ },
1599
+ alias: {
1600
+ ...dtwo.options.experimental.externalKdu ? {} : {
1601
+ "kdu/compiler-sfc": "kdu/compiler-sfc",
1602
+ "kdu/server-renderer": "kdu/server-renderer",
1603
+ kdu: await resolvePath(`kdu/dist/kdu.cjs${dtwo.options.dev ? "" : ".prod"}.js`)
1604
+ },
1605
+ "estree-walker": "unenv/runtime/mock/proxy",
1606
+ "@babel/parser": "unenv/runtime/mock/proxy",
1607
+ "@kdujs/compiler-core": "unenv/runtime/mock/proxy",
1608
+ "@kdujs/compiler-dom": "unenv/runtime/mock/proxy",
1609
+ "@kdujs/compiler-ssr": "unenv/runtime/mock/proxy",
1610
+ "@kdujs/devtools-api": "kdu-devtools-stub",
1611
+ "#paths": resolve(distDir, "core/runtime/hole/paths"),
1612
+ ...dtwo.options.alias
1613
+ },
1614
+ replace: {
1615
+ "process.env.DTWO_NO_SSR": dtwo.options.ssr === false,
1616
+ "process.env.DTWO_EARLY_HINTS": dtwo.options.experimental.writeEarlyHints !== false,
1617
+ "process.env.DTWO_NO_SCRIPTS": !!dtwo.options.experimental.noScripts && !dtwo.options.dev,
1618
+ "process.env.DTWO_INLINE_STYLES": !!dtwo.options.experimental.inlineSSRStyles,
1619
+ "process.env.DTWO_PAYLOAD_EXTRACTION": !!dtwo.options.experimental.payloadExtraction,
1620
+ "process.dev": dtwo.options.dev,
1621
+ __KDU_PROD_DEVTOOLS__: false
1622
+ },
1623
+ rollupConfig: {
1624
+ plugins: []
1625
+ }
1626
+ });
1627
+ const head = createHeadCore();
1628
+ head.push(dtwo.options.app.head);
1629
+ const headChunk = await renderSSRHead(head);
1630
+ holeConfig.virtual["#head-static"] = `export default ${JSON.stringify(headChunk)}`;
1631
+ if (!dtwo.options.ssr) {
1632
+ holeConfig.virtual["#build/dist/server/server.mjs"] = "export default () => {}";
1633
+ }
1634
+ if (!dtwo.options.experimental.inlineSSRStyles) {
1635
+ holeConfig.virtual["#build/dist/server/styles.mjs"] = "export default {}";
1636
+ }
1637
+ holeConfig.rollupConfig.plugins.push(
1638
+ ImportProtectionPlugin.rollup({
1639
+ rootDir: dtwo.options.rootDir,
1640
+ patterns: [
1641
+ ...["#app", /^#build(\/|$)/].map((p) => [p, "Kdu app aliases are not allowed in server routes."])
1642
+ ],
1643
+ exclude: [/core[\\/]runtime[\\/]hole[\\/]renderer/]
1644
+ })
1645
+ );
1646
+ await dtwo.callHook("hole:config", holeConfig);
1647
+ const hole = await createHole(holeConfig);
1648
+ dtwo._hole = hole;
1649
+ await dtwo.callHook("hole:init", hole);
1650
+ hole.vfs = dtwo.vfs = hole.vfs || dtwo.vfs || {};
1651
+ dtwo.hook("close", () => hole.hooks.callHook("close"));
1652
+ hole.hooks.hook("prerender:routes", (routes) => {
1653
+ dtwo.callHook("prerender:routes", { routes });
1654
+ });
1655
+ const devMiddlewareHandler = dynamicEventHandler();
1656
+ hole.options.devHandlers.unshift({ handler: devMiddlewareHandler });
1657
+ hole.options.devHandlers.push(...dtwo.options.devServerHandlers);
1658
+ hole.options.handlers.unshift({
1659
+ route: "/__dtwo_error",
1660
+ lazy: true,
1661
+ handler: resolve(distDir, "core/runtime/hole/renderer")
1662
+ });
1663
+ dtwo.hook("prepare:types", async (opts) => {
1664
+ if (!dtwo.options.dev) {
1665
+ await scanHandlers(hole);
1666
+ await writeTypes(hole);
1667
+ }
1668
+ opts.references.push({ path: resolve(dtwo.options.buildDir, "types/hole.d.ts") });
1669
+ });
1670
+ dtwo.hook("build:done", async () => {
1671
+ await dtwo.callHook("hole:build:before", hole);
1672
+ if (dtwo.options.dev) {
1673
+ await build$1(hole);
1674
+ } else {
1675
+ await prepare(hole);
1676
+ await copyPublicAssets(hole);
1677
+ await prerender(hole);
1678
+ if (!dtwo.options._generate) {
1679
+ await build$1(hole);
1680
+ } else {
1681
+ const distDir2 = resolve(dtwo.options.rootDir, "dist");
1682
+ if (!existsSync(distDir2)) {
1683
+ await promises.symlink(hole.options.output.publicDir, distDir2, "junction").catch(() => {
1684
+ });
1685
+ }
1686
+ }
1687
+ }
1688
+ });
1689
+ if (dtwo.options.dev) {
1690
+ dtwo.hook("webpack:compile", ({ compiler }) => {
1691
+ compiler.outputFileSystem = { ...fse, join };
1692
+ });
1693
+ dtwo.hook("webpack:compiled", () => {
1694
+ dtwo.server.reload();
1695
+ });
1696
+ dtwo.hook("wite:compiled", () => {
1697
+ dtwo.server.reload();
1698
+ });
1699
+ dtwo.hook("server:devHandler", (h) => {
1700
+ devMiddlewareHandler.set(h);
1701
+ });
1702
+ dtwo.server = createDevServer(hole);
1703
+ const waitUntilCompile = new Promise((resolve2) => hole.hooks.hook("compiled", () => resolve2()));
1704
+ dtwo.hook("build:done", () => waitUntilCompile);
1705
+ }
1706
+ }
1707
+
1708
+ function createDtwo(options) {
1709
+ const hooks = createHooks();
1710
+ const dtwo = {
1711
+ _version: version,
1712
+ options,
1713
+ hooks,
1714
+ callHook: hooks.callHook,
1715
+ addHooks: hooks.addHooks,
1716
+ hook: hooks.hook,
1717
+ ready: () => initDtwo(dtwo),
1718
+ close: () => Promise.resolve(hooks.callHook("close", dtwo)),
1719
+ vfs: {}
1720
+ };
1721
+ return dtwo;
1722
+ }
1723
+ async function initDtwo(dtwo) {
1724
+ dtwo.hooks.addHooks(dtwo.options.hooks);
1725
+ dtwoCtx.set(dtwo);
1726
+ dtwo.hook("close", () => dtwoCtx.unset());
1727
+ dtwo.hook("prepare:types", (opts) => {
1728
+ opts.references.push({ types: "dtwo" });
1729
+ opts.references.push({ path: resolve(dtwo.options.buildDir, "types/plugins.d.ts") });
1730
+ if (dtwo.options.typescript.shim) {
1731
+ opts.references.push({ path: resolve(dtwo.options.buildDir, "types/kdu-shim.d.ts") });
1732
+ }
1733
+ opts.references.push({ path: resolve(dtwo.options.buildDir, "types/schema.d.ts") });
1734
+ opts.references.push({ path: resolve(dtwo.options.buildDir, "types/app.config.d.ts") });
1735
+ for (const layer of dtwo.options._layers) {
1736
+ const declaration = join(layer.cwd, "index.d.ts");
1737
+ if (fse.existsSync(declaration)) {
1738
+ opts.references.push({ path: declaration });
1739
+ }
1740
+ }
1741
+ });
1742
+ const config = {
1743
+ rootDir: dtwo.options.rootDir,
1744
+ exclude: [join(dtwo.options.rootDir, "index.html")],
1745
+ patterns: kduAppPatterns(dtwo)
1746
+ };
1747
+ addWitePlugin(ImportProtectionPlugin.wite(config));
1748
+ addWebpackPlugin(ImportProtectionPlugin.webpack(config));
1749
+ addWitePlugin(UnctxTransformPlugin(dtwo).wite({ sourcemap: dtwo.options.sourcemap.server || dtwo.options.sourcemap.client }));
1750
+ addWebpackPlugin(UnctxTransformPlugin(dtwo).webpack({ sourcemap: dtwo.options.sourcemap.server || dtwo.options.sourcemap.client }));
1751
+ if (!dtwo.options.dev) {
1752
+ const removeFromServer = ["onBeforeMount", "onMounted", "onBeforeUpdate", "onRenderTracked", "onRenderTriggered", "onActivated", "onDeactivated", "onBeforeUnmount"];
1753
+ const removeFromClient = ["onServerPrefetch", "onRenderTracked", "onRenderTriggered"];
1754
+ addWitePlugin(TreeShakePlugin.wite({ sourcemap: dtwo.options.sourcemap.server, treeShake: removeFromServer }), { client: false });
1755
+ addWitePlugin(TreeShakePlugin.wite({ sourcemap: dtwo.options.sourcemap.client, treeShake: removeFromClient }), { server: false });
1756
+ addWebpackPlugin(TreeShakePlugin.webpack({ sourcemap: dtwo.options.sourcemap.server, treeShake: removeFromServer }), { client: false });
1757
+ addWebpackPlugin(TreeShakePlugin.webpack({ sourcemap: dtwo.options.sourcemap.client, treeShake: removeFromClient }), { server: false });
1758
+ addWitePlugin(DevOnlyPlugin.wite({ sourcemap: dtwo.options.sourcemap.server || dtwo.options.sourcemap.client }));
1759
+ addWebpackPlugin(DevOnlyPlugin.webpack({ sourcemap: dtwo.options.sourcemap.server || dtwo.options.sourcemap.client }));
1760
+ }
1761
+ if (dtwo.options.experimental.noScripts && !dtwo.options.dev) {
1762
+ dtwo.hook("build:manifest", async (manifest) => {
1763
+ for (const file in manifest) {
1764
+ if (manifest[file].resourceType === "script") {
1765
+ await fse.rm(resolve(dtwo.options.buildDir, "dist/client", withoutLeadingSlash(dtwo.options.app.buildAssetsDir), manifest[file].file), { force: true });
1766
+ manifest[file].file = "";
1767
+ }
1768
+ }
1769
+ });
1770
+ }
1771
+ dtwo.options.build.transpile.push(
1772
+ ...dtwo.options._layers.filter((i) => i.cwd.includes("node_modules")).map((i) => i.cwd)
1773
+ );
1774
+ await dtwo.callHook("modules:before");
1775
+ const modulesToInstall = [
1776
+ ...dtwo.options.modules,
1777
+ ...dtwo.options._modules
1778
+ ];
1779
+ addComponent({
1780
+ name: "DtwoWelcome",
1781
+ filePath: tryResolveModule("@dtwo/ui-templates/templates/welcome.kdu")
1782
+ });
1783
+ addComponent({
1784
+ name: "DtwoLayout",
1785
+ filePath: resolve(dtwo.options.appDir, "components/layout")
1786
+ });
1787
+ addComponent({
1788
+ name: "DtwoErrorBoundary",
1789
+ filePath: resolve(dtwo.options.appDir, "components/dtwo-error-boundary")
1790
+ });
1791
+ addComponent({
1792
+ name: "ClientOnly",
1793
+ filePath: resolve(dtwo.options.appDir, "components/client-only")
1794
+ });
1795
+ addComponent({
1796
+ name: "DevOnly",
1797
+ filePath: resolve(dtwo.options.appDir, "components/dev-only")
1798
+ });
1799
+ addComponent({
1800
+ name: "ServerPlaceholder",
1801
+ filePath: resolve(dtwo.options.appDir, "components/server-placeholder")
1802
+ });
1803
+ addComponent({
1804
+ name: "DtwoLink",
1805
+ filePath: resolve(dtwo.options.appDir, "components/dtwo-link")
1806
+ });
1807
+ addComponent({
1808
+ name: "DtwoLoadingIndicator",
1809
+ filePath: resolve(dtwo.options.appDir, "components/dtwo-loading-indicator")
1810
+ });
1811
+ if (!dtwo.options.dev && dtwo.options.experimental.payloadExtraction) {
1812
+ addPlugin(resolve(dtwo.options.appDir, "plugins/payload.client"));
1813
+ }
1814
+ if (dtwo.options.experimental.crossOriginPrefetch) {
1815
+ addPlugin(resolve(dtwo.options.appDir, "plugins/cross-origin-prefetch.client"));
1816
+ }
1817
+ if (dtwo.options.builder === "@dtwo/webpack-builder") {
1818
+ addPlugin(resolve(dtwo.options.appDir, "plugins/preload.server"));
1819
+ }
1820
+ if (dtwo.options.debug) {
1821
+ addPlugin(resolve(dtwo.options.appDir, "plugins/debug"));
1822
+ }
1823
+ for (const m of modulesToInstall) {
1824
+ if (Array.isArray(m)) {
1825
+ await installModule(m[0], m[1]);
1826
+ } else {
1827
+ await installModule(m, {});
1828
+ }
1829
+ }
1830
+ await dtwo.callHook("modules:done");
1831
+ dtwo.options.build.transpile = dtwo.options.build.transpile.map((t) => typeof t === "string" ? normalize(t) : t);
1832
+ addModuleTranspiles();
1833
+ await initHole(dtwo);
1834
+ await dtwo.callHook("ready", dtwo);
1835
+ }
1836
+ async function loadDtwo(opts) {
1837
+ const options = await loadDtwoConfig(opts);
1838
+ options.appDir = options.alias["#app"] = resolve(distDir, "app");
1839
+ options._majorVersion = 3;
1840
+ options._modules.push(pagesModule, metaModule, componentsModule);
1841
+ options._modules.push([importsModule, {
1842
+ transform: {
1843
+ include: options._layers.filter((i) => i.cwd && i.cwd.includes("node_modules")).map((i) => new RegExp(`(^|\\/)${escapeRE(i.cwd.split("node_modules/").pop())}(\\/|$)(?!node_modules\\/)`))
1844
+ }
1845
+ }]);
1846
+ options.modulesDir.push(resolve(options.workspaceDir, "node_modules"));
1847
+ options.modulesDir.push(resolve(pkgDir, "node_modules"));
1848
+ options.build.transpile.push("@dtwo/ui-templates");
1849
+ options.alias["kdu-demi"] = resolve(options.appDir, "compat/kdu-demi");
1850
+ options.alias["@kdujs/composition-api"] = resolve(options.appDir, "compat/capi");
1851
+ if (options.telemetry !== false && !process.env.DTWO_TELEMETRY_DISABLED) {
1852
+ options._modules.push("@dtwo/telemetry");
1853
+ }
1854
+ const dtwo = createDtwo(options);
1855
+ if (dtwo.options.debug) {
1856
+ createDebugger(dtwo.hooks, { tag: "dtwo" });
1857
+ }
1858
+ if (opts.ready !== false) {
1859
+ await dtwo.ready();
1860
+ }
1861
+ return dtwo;
1862
+ }
1863
+
1864
+ const kduShim = {
1865
+ filename: "types/kdu-shim.d.ts",
1866
+ getContents: () => [
1867
+ "declare module '*.kdu' {",
1868
+ " import { DefineComponent } from '@kdujs/runtime-core'",
1869
+ " const component: DefineComponent<{}, {}, any>",
1870
+ " export default component",
1871
+ "}"
1872
+ ].join("\n")
1873
+ };
1874
+ const appComponentTemplate = {
1875
+ filename: "app-component.mjs",
1876
+ getContents: (ctx) => genExport(ctx.app.mainComponent, ["default"])
1877
+ };
1878
+ const rootComponentTemplate = {
1879
+ filename: "root-component.mjs",
1880
+ getContents: (ctx) => genExport(ctx.app.rootComponent, ["default"])
1881
+ };
1882
+ const errorComponentTemplate = {
1883
+ filename: "error-component.mjs",
1884
+ getContents: (ctx) => genExport(ctx.app.errorComponent, ["default"])
1885
+ };
1886
+ const cssTemplate = {
1887
+ filename: "css.mjs",
1888
+ getContents: (ctx) => ctx.dtwo.options.css.map((i) => genImport(i)).join("\n")
1889
+ };
1890
+ const clientPluginTemplate = {
1891
+ filename: "plugins/client.mjs",
1892
+ getContents(ctx) {
1893
+ const clientPlugins = ctx.app.plugins.filter((p) => !p.mode || p.mode !== "server");
1894
+ const exports = [];
1895
+ const imports = [];
1896
+ for (const plugin of clientPlugins) {
1897
+ const path = relative(ctx.dtwo.options.rootDir, plugin.src);
1898
+ const variable = genSafeVariableName(path).replace(/_(45|46|47)/g, "_") + "_" + hash(path);
1899
+ exports.push(variable);
1900
+ imports.push(genImport(plugin.src, variable));
1901
+ }
1902
+ return [
1903
+ ...imports,
1904
+ `export default ${genArrayFromRaw(exports)}`
1905
+ ].join("\n");
1906
+ }
1907
+ };
1908
+ const serverPluginTemplate = {
1909
+ filename: "plugins/server.mjs",
1910
+ getContents(ctx) {
1911
+ const serverPlugins = ctx.app.plugins.filter((p) => !p.mode || p.mode !== "client");
1912
+ const exports = [];
1913
+ const imports = [];
1914
+ for (const plugin of serverPlugins) {
1915
+ const path = relative(ctx.dtwo.options.rootDir, plugin.src);
1916
+ const variable = genSafeVariableName(path).replace(/_(45|46|47)/g, "_") + "_" + hash(path);
1917
+ exports.push(variable);
1918
+ imports.push(genImport(plugin.src, variable));
1919
+ }
1920
+ return [
1921
+ ...imports,
1922
+ `export default ${genArrayFromRaw(exports)}`
1923
+ ].join("\n");
1924
+ }
1925
+ };
1926
+ const pluginsDeclaration = {
1927
+ filename: "types/plugins.d.ts",
1928
+ getContents: (ctx) => {
1929
+ const EXTENSION_RE = new RegExp(`(?<=\\w)(${ctx.dtwo.options.extensions.map((e) => escapeRE(e)).join("|")})$`, "g");
1930
+ const tsImports = ctx.app.plugins.map((p) => (isAbsolute(p.src) ? relative(join(ctx.dtwo.options.buildDir, "types"), p.src) : p.src).replace(EXTENSION_RE, ""));
1931
+ return `// Generated by Dtwo'
1932
+ import type { Plugin } from '#app'
1933
+
1934
+ type Decorate<T extends Record<string, any>> = { [K in keyof T as K extends string ? \`$\${K}\` : never]: T[K] }
1935
+
1936
+ type InjectionType<A extends Plugin> = A extends Plugin<infer T> ? Decorate<T> : unknown
1937
+
1938
+ type DtwoAppInjections =
1939
+ ${tsImports.map((p) => `InjectionType<typeof ${genDynamicImport(p, { wrapper: false })}.default>`).join(" &\n ")}
1940
+
1941
+ declare module '#app' {
1942
+ interface DtwoApp extends DtwoAppInjections { }
1943
+ }
1944
+
1945
+ declare module '@kdujs/runtime-core' {
1946
+ interface ComponentCustomProperties extends DtwoAppInjections { }
1947
+ }
1948
+
1949
+ export { }
1950
+ `;
1951
+ }
1952
+ };
1953
+ const adHocModules = ["router", "pages", "imports", "meta", "components"];
1954
+ const schemaTemplate = {
1955
+ filename: "types/schema.d.ts",
1956
+ getContents: async ({ dtwo }) => {
1957
+ const moduleInfo = dtwo.options._installedModules.map((m) => ({
1958
+ ...m.meta || {},
1959
+ importName: m.entryPath || m.meta?.name
1960
+ })).filter((m) => m.configKey && m.name && !adHocModules.includes(m.name));
1961
+ const relativeRoot = relative(resolve(dtwo.options.buildDir, "types"), dtwo.options.rootDir);
1962
+ return [
1963
+ "import { DtwoModule } from '@dtwo/schema'",
1964
+ "declare module '@dtwo/schema' {",
1965
+ " interface DtwoConfig {",
1966
+ ...moduleInfo.filter(Boolean).map(
1967
+ (meta) => ` [${genString(meta.configKey)}]?: typeof ${genDynamicImport(meta.importName.startsWith(".") ? "./" + join(relativeRoot, meta.importName) : meta.importName, { wrapper: false })}.default extends DtwoModule<infer O> ? Partial<O> : Record<string, any>`
1968
+ ),
1969
+ " }",
1970
+ generateTypes(
1971
+ await resolveSchema(Object.fromEntries(Object.entries(dtwo.options.runtimeConfig).filter(([key]) => key !== "public"))),
1972
+ {
1973
+ interfaceName: "RuntimeConfig",
1974
+ addExport: false,
1975
+ addDefaults: false,
1976
+ allowExtraKeys: false,
1977
+ indentation: 2
1978
+ }
1979
+ ),
1980
+ generateTypes(
1981
+ await resolveSchema(dtwo.options.runtimeConfig.public),
1982
+ {
1983
+ interfaceName: "PublicRuntimeConfig",
1984
+ addExport: false,
1985
+ addDefaults: false,
1986
+ allowExtraKeys: false,
1987
+ indentation: 2
1988
+ }
1989
+ ),
1990
+ "}"
1991
+ ].join("\n");
1992
+ }
1993
+ };
1994
+ const layoutTemplate = {
1995
+ filename: "layouts.mjs",
1996
+ getContents({ app }) {
1997
+ const layoutsObject = genObjectFromRawEntries(Object.values(app.layouts).map(({ name, file }) => {
1998
+ return [name, genDynamicImport(file, { interopDefault: true })];
1999
+ }));
2000
+ return [
2001
+ `export default ${layoutsObject}`
2002
+ ].join("\n");
2003
+ }
2004
+ };
2005
+ const middlewareTemplate = {
2006
+ filename: "middleware.mjs",
2007
+ getContents({ app }) {
2008
+ const globalMiddleware = app.middleware.filter((mw) => mw.global);
2009
+ const namedMiddleware = app.middleware.filter((mw) => !mw.global);
2010
+ const namedMiddlewareObject = genObjectFromRawEntries(namedMiddleware.map((mw) => [mw.name, genDynamicImport(mw.path)]));
2011
+ return [
2012
+ ...globalMiddleware.map((mw) => genImport(mw.path, genSafeVariableName(mw.name))),
2013
+ `export const globalMiddleware = ${genArrayFromRaw(globalMiddleware.map((mw) => genSafeVariableName(mw.name)))}`,
2014
+ `export const namedMiddleware = ${namedMiddlewareObject}`
2015
+ ].join("\n");
2016
+ }
2017
+ };
2018
+ const clientConfigTemplate = {
2019
+ filename: "hole.client.mjs",
2020
+ getContents: () => `
2021
+ export const useRuntimeConfig = () => window?.__DTWO__?.config || {}
2022
+ `
2023
+ };
2024
+ const appConfigDeclarationTemplate = {
2025
+ filename: "types/app.config.d.ts",
2026
+ getContents: ({ app, dtwo }) => {
2027
+ return `
2028
+ import type { Defu } from 'defu'
2029
+ ${app.configs.map((id, index) => `import ${`cfg${index}`} from ${JSON.stringify(id.replace(/(?<=\w)\.\w+$/g, ""))}`).join("\n")}
2030
+
2031
+ declare const inlineConfig = ${JSON.stringify(dtwo.options.appConfig, null, 2)}
2032
+ type ResolvedAppConfig = Defu<typeof inlineConfig, [${app.configs.map((_id, index) => `typeof cfg${index}`).join(", ")}]>
2033
+
2034
+ declare module '@dtwo/schema' {
2035
+ interface AppConfig extends ResolvedAppConfig { }
2036
+ }
2037
+ `;
2038
+ }
2039
+ };
2040
+ const appConfigTemplate = {
2041
+ filename: "app.config.mjs",
2042
+ write: true,
2043
+ getContents: async ({ app, dtwo }) => {
2044
+ return `
2045
+ import { defuFn } from '${await _resolveId("defu")}'
2046
+
2047
+ const inlineConfig = ${JSON.stringify(dtwo.options.appConfig, null, 2)}
2048
+
2049
+ ${app.configs.map((id, index) => `import ${`cfg${index}`} from ${JSON.stringify(id)}`).join("\n")}
2050
+
2051
+ export default defuFn(${app.configs.map((_id, index) => `cfg${index}`).concat(["inlineConfig"]).join(", ")})
2052
+ `;
2053
+ }
2054
+ };
2055
+ const publicPathTemplate = {
2056
+ filename: "paths.mjs",
2057
+ async getContents({ dtwo }) {
2058
+ return [
2059
+ `import { joinURL } from '${await _resolveId("ufo")}'`,
2060
+ !dtwo.options.dev && "import { useRuntimeConfig } from '#internal/hole'",
2061
+ dtwo.options.dev ? `const appConfig = ${JSON.stringify(dtwo.options.app)}` : "const appConfig = useRuntimeConfig().app",
2062
+ "export const baseURL = () => appConfig.baseURL",
2063
+ "export const buildAssetsDir = () => appConfig.buildAssetsDir",
2064
+ "export const buildAssetsURL = (...path) => joinURL(publicAssetsURL(), buildAssetsDir(), ...path)",
2065
+ "export const publicAssetsURL = (...path) => {",
2066
+ " const publicBase = appConfig.cdnURL || appConfig.baseURL",
2067
+ " return path.length ? joinURL(publicBase, ...path) : publicBase",
2068
+ "}",
2069
+ "if (process.client) {",
2070
+ " globalThis.__buildAssetsURL = buildAssetsURL",
2071
+ " globalThis.__publicAssetsURL = publicAssetsURL",
2072
+ "}"
2073
+ ].filter(Boolean).join("\n");
2074
+ }
2075
+ };
2076
+ const dtwoConfigTemplate = {
2077
+ filename: "dtwo.config.mjs",
2078
+ getContents: (ctx) => {
2079
+ return Object.entries(ctx.dtwo.options.app).map(([k, v]) => `export const ${camelCase("app-" + k)} = ${JSON.stringify(v)}`).join("\n\n");
2080
+ }
2081
+ };
2082
+ function _resolveId(id) {
2083
+ return resolvePath$1(id, {
2084
+ url: [
2085
+ global.__DTWO_PREPATHS__,
2086
+ import.meta.url,
2087
+ process.cwd(),
2088
+ global.__DTWO_PATHS__
2089
+ ]
2090
+ });
2091
+ }
2092
+
2093
+ const defaultTemplates = {
2094
+ __proto__: null,
2095
+ kduShim: kduShim,
2096
+ appComponentTemplate: appComponentTemplate,
2097
+ rootComponentTemplate: rootComponentTemplate,
2098
+ errorComponentTemplate: errorComponentTemplate,
2099
+ cssTemplate: cssTemplate,
2100
+ clientPluginTemplate: clientPluginTemplate,
2101
+ serverPluginTemplate: serverPluginTemplate,
2102
+ pluginsDeclaration: pluginsDeclaration,
2103
+ schemaTemplate: schemaTemplate,
2104
+ layoutTemplate: layoutTemplate,
2105
+ middlewareTemplate: middlewareTemplate,
2106
+ clientConfigTemplate: clientConfigTemplate,
2107
+ appConfigDeclarationTemplate: appConfigDeclarationTemplate,
2108
+ appConfigTemplate: appConfigTemplate,
2109
+ publicPathTemplate: publicPathTemplate,
2110
+ dtwoConfigTemplate: dtwoConfigTemplate
2111
+ };
2112
+
2113
+ function createApp(dtwo, options = {}) {
2114
+ return defu(options, {
2115
+ dir: dtwo.options.srcDir,
2116
+ extensions: dtwo.options.extensions,
2117
+ plugins: [],
2118
+ templates: []
2119
+ });
2120
+ }
2121
+ async function generateApp(dtwo, app, options = {}) {
2122
+ await resolveApp(dtwo, app);
2123
+ app.templates = Object.values(defaultTemplates).concat(dtwo.options.build.templates);
2124
+ await dtwo.callHook("app:templates", app);
2125
+ app.templates = app.templates.map((tmpl) => normalizeTemplate(tmpl));
2126
+ const templateContext = { utils: templateUtils, dtwo, app };
2127
+ await Promise.all(app.templates.filter((template) => !options.filter || options.filter(template)).map(async (template) => {
2128
+ const contents = await compileTemplate(template, templateContext);
2129
+ const fullPath = template.dst || resolve(dtwo.options.buildDir, template.filename);
2130
+ dtwo.vfs[fullPath] = contents;
2131
+ const aliasPath = "#build/" + template.filename.replace(/\.\w+$/, "");
2132
+ dtwo.vfs[aliasPath] = contents;
2133
+ if (process.platform === "win32") {
2134
+ dtwo.vfs[fullPath.replace(/\//g, "\\")] = contents;
2135
+ }
2136
+ if (template.write) {
2137
+ await promises.mkdir(dirname(fullPath), { recursive: true });
2138
+ await promises.writeFile(fullPath, contents, "utf8");
2139
+ }
2140
+ }));
2141
+ await dtwo.callHook("app:templatesGenerated", app);
2142
+ }
2143
+ async function resolveApp(dtwo, app) {
2144
+ if (!app.mainComponent) {
2145
+ app.mainComponent = await findPath(
2146
+ dtwo.options._layers.flatMap((layer) => [`${layer.config.srcDir}/App`, `${layer.config.srcDir}/app`])
2147
+ );
2148
+ }
2149
+ if (!app.mainComponent) {
2150
+ app.mainComponent = tryResolveModule("@dtwo/ui-templates/templates/welcome.kdu");
2151
+ }
2152
+ if (!app.rootComponent) {
2153
+ app.rootComponent = await findPath(["~/app.root", resolve(dtwo.options.appDir, "components/dtwo-root.kdu")]);
2154
+ }
2155
+ if (!app.errorComponent) {
2156
+ app.errorComponent = await findPath(["~/error"]) || resolve(dtwo.options.appDir, "components/dtwo-error-page.kdu");
2157
+ }
2158
+ app.layouts = {};
2159
+ for (const config of dtwo.options._layers.map((layer) => layer.config)) {
2160
+ const layoutFiles = await resolveFiles(config.srcDir, `${config.dir?.layouts || "layouts"}/*{${dtwo.options.extensions.join(",")}}`);
2161
+ for (const file of layoutFiles) {
2162
+ const name = getNameFromPath(file);
2163
+ app.layouts[name] = app.layouts[name] || { name, file };
2164
+ }
2165
+ }
2166
+ app.middleware = [];
2167
+ for (const config of dtwo.options._layers.map((layer) => layer.config)) {
2168
+ const middlewareFiles = await resolveFiles(config.srcDir, `${config.dir?.middleware || "middleware"}/*{${dtwo.options.extensions.join(",")}}`);
2169
+ app.middleware.push(...middlewareFiles.map((file) => {
2170
+ const name = getNameFromPath(file);
2171
+ return { name, path: file, global: hasSuffix(file, ".global") };
2172
+ }));
2173
+ }
2174
+ app.plugins = [
2175
+ ...dtwo.options.plugins.map(normalizePlugin)
2176
+ ];
2177
+ for (const config of dtwo.options._layers.map((layer) => layer.config)) {
2178
+ app.plugins.push(...[
2179
+ ...config.plugins || [],
2180
+ ...config.srcDir ? await resolveFiles(config.srcDir, [
2181
+ `${config.dir?.plugins || "plugins"}/*.{ts,js,mjs,cjs,mts,cts}`,
2182
+ `${config.dir?.plugins || "plugins"}/*/index.*{ts,js,mjs,cjs,mts,cts}`
2183
+ ]) : []
2184
+ ].map((plugin) => normalizePlugin(plugin)));
2185
+ }
2186
+ app.middleware = uniqueBy(await resolvePaths(app.middleware, "path"), "name");
2187
+ app.plugins = uniqueBy(await resolvePaths(app.plugins, "src"), "src");
2188
+ app.configs = [];
2189
+ for (const config of dtwo.options._layers.map((layer) => layer.config)) {
2190
+ const appConfigPath = await findPath(resolve(config.srcDir, "app.config"));
2191
+ if (appConfigPath) {
2192
+ app.configs.push(appConfigPath);
2193
+ }
2194
+ }
2195
+ await dtwo.callHook("app:resolve", app);
2196
+ app.middleware = uniqueBy(await resolvePaths(app.middleware, "path"), "name");
2197
+ app.plugins = uniqueBy(await resolvePaths(app.plugins, "src"), "src");
2198
+ }
2199
+ function resolvePaths(items, key) {
2200
+ return Promise.all(items.map(async (item) => {
2201
+ if (!item[key]) {
2202
+ return item;
2203
+ }
2204
+ return {
2205
+ ...item,
2206
+ [key]: await resolvePath(resolveAlias(item[key]))
2207
+ };
2208
+ }));
2209
+ }
2210
+
2211
+ async function build(dtwo) {
2212
+ const app = createApp(dtwo);
2213
+ const generateApp$1 = debounce(() => generateApp(dtwo, app), void 0, { leading: true });
2214
+ await generateApp$1();
2215
+ if (dtwo.options.dev) {
2216
+ watch(dtwo);
2217
+ dtwo.hook("builder:watch", async (event, path) => {
2218
+ if (event !== "change" && /^(app\.|error\.|plugins\/|middleware\/|layouts\/)/i.test(path)) {
2219
+ if (path.startsWith("app")) {
2220
+ app.mainComponent = void 0;
2221
+ }
2222
+ if (path.startsWith("error")) {
2223
+ app.errorComponent = void 0;
2224
+ }
2225
+ await generateApp$1();
2226
+ }
2227
+ });
2228
+ dtwo.hook("builder:generateApp", (options) => {
2229
+ if (options) {
2230
+ return generateApp(dtwo, app, options);
2231
+ }
2232
+ return generateApp$1();
2233
+ });
2234
+ }
2235
+ await dtwo.callHook("build:before");
2236
+ if (!dtwo.options._prepare) {
2237
+ await bundle(dtwo);
2238
+ await dtwo.callHook("build:done");
2239
+ }
2240
+ if (!dtwo.options.dev) {
2241
+ await dtwo.callHook("close", dtwo);
2242
+ }
2243
+ }
2244
+ function watch(dtwo) {
2245
+ const watcher = chokidar.watch(dtwo.options._layers.map((i) => i.config.srcDir).filter(Boolean), {
2246
+ ...dtwo.options.watchers.chokidar,
2247
+ cwd: dtwo.options.srcDir,
2248
+ ignoreInitial: true,
2249
+ ignored: [
2250
+ isIgnored,
2251
+ ".dtwo",
2252
+ "node_modules"
2253
+ ]
2254
+ });
2255
+ watcher.on("all", (event, path) => dtwo.callHook("builder:watch", event, normalize(path)));
2256
+ dtwo.hook("close", () => watcher.close());
2257
+ return watcher;
2258
+ }
2259
+ async function bundle(dtwo) {
2260
+ try {
2261
+ const { bundle: bundle2 } = typeof dtwo.options.builder === "string" ? await importModule(dtwo.options.builder, { paths: dtwo.options.rootDir }) : dtwo.options.builder;
2262
+ return bundle2(dtwo);
2263
+ } catch (error) {
2264
+ await dtwo.callHook("build:error", error);
2265
+ if (error.toString().includes("Cannot find module '@dtwo/webpack-builder'")) {
2266
+ throw new Error([
2267
+ "Could not load `@dtwo/webpack-builder`. You may need to add it to your project dependencies."
2268
+ ].join("\n"));
2269
+ }
2270
+ throw error;
2271
+ }
2272
+ }
2273
+
2274
+ export { build, createDtwo, loadDtwo };