@dxup/nuxt 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -6
- package/dist/languages/named-layout-slots.cjs +78 -0
- package/dist/languages/named-layout-slots.d.cts +10 -0
- package/dist/module.d.mts +7 -3
- package/dist/module.mjs +148 -3
- package/dist/runtime/layouts.d.mts +35 -0
- package/dist/runtime/layouts.mjs +53 -0
- package/dist/typescript.cjs +2 -2
- package/package.json +15 -14
package/README.md
CHANGED
|
@@ -24,6 +24,12 @@ This is a TypeScript plugin that improves Nuxt DX.
|
|
|
24
24
|
experimental: {
|
|
25
25
|
typescriptPlugin: true,
|
|
26
26
|
},
|
|
27
|
+
dxup: {
|
|
28
|
+
features: {
|
|
29
|
+
// Enable opt-in features
|
|
30
|
+
namedLayoutSlots: true,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
27
33
|
});
|
|
28
34
|
```
|
|
29
35
|
|
|
@@ -50,7 +56,42 @@ import.meta.glob("~/assets/*.webp");
|
|
|
50
56
|
// ^^^^^^^^^^^^^^^^^
|
|
51
57
|
```
|
|
52
58
|
|
|
53
|
-
### 3.
|
|
59
|
+
### 3. namedLayoutSlots
|
|
60
|
+
|
|
61
|
+
**Default:** `false`
|
|
62
|
+
|
|
63
|
+
Write top-level named slots in your pages:
|
|
64
|
+
|
|
65
|
+
```vue
|
|
66
|
+
<!-- layouts/center.vue -->
|
|
67
|
+
<template>
|
|
68
|
+
<slot></slot>
|
|
69
|
+
<slot name="side" one="one"></slot>
|
|
70
|
+
</template>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```vue
|
|
74
|
+
<!-- pages/about.vue -->
|
|
75
|
+
<script lang="ts" setup>
|
|
76
|
+
definePageMeta({
|
|
77
|
+
layout: "center",
|
|
78
|
+
});
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<template>
|
|
82
|
+
<template #side="{ one }">
|
|
83
|
+
This "{{ one }}" comes from the layout slot.
|
|
84
|
+
<!-- ^^^ -->
|
|
85
|
+
</template>
|
|
86
|
+
<div>About Page</div>
|
|
87
|
+
</template>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
And them will be forwarded to the active layout automatically.
|
|
91
|
+
|
|
92
|
+
Due to design limitations, dynamic slots are currently not supported.
|
|
93
|
+
|
|
94
|
+
### 4. nitroRoutes
|
|
54
95
|
|
|
55
96
|
Go to definition for nitro routes in data fetching methods.
|
|
56
97
|
|
|
@@ -62,7 +103,7 @@ useFetch("/api/foo");
|
|
|
62
103
|
|
|
63
104
|
It will fallback to resolve the URL from your `public` directory when no nitro routes match.
|
|
64
105
|
|
|
65
|
-
###
|
|
106
|
+
### 5. pageMeta
|
|
66
107
|
|
|
67
108
|
Go to definition for page metadata.
|
|
68
109
|
|
|
@@ -75,7 +116,7 @@ definePageMeta({
|
|
|
75
116
|
});
|
|
76
117
|
```
|
|
77
118
|
|
|
78
|
-
###
|
|
119
|
+
### 6. runtimeConfig
|
|
79
120
|
|
|
80
121
|
Go to definition for runtime config.
|
|
81
122
|
|
|
@@ -86,7 +127,7 @@ Go to definition for runtime config.
|
|
|
86
127
|
</template>
|
|
87
128
|
```
|
|
88
129
|
|
|
89
|
-
###
|
|
130
|
+
### 7. typedPages
|
|
90
131
|
|
|
91
132
|
Go to definition for typed pages.
|
|
92
133
|
|
|
@@ -99,11 +140,11 @@ Go to definition for typed pages.
|
|
|
99
140
|
|
|
100
141
|
It can be triggered on the `name` property of an object literal constrained by the `RouteLocationRaw` type.
|
|
101
142
|
|
|
102
|
-
###
|
|
143
|
+
### 8. unimport
|
|
103
144
|
|
|
104
145
|
Please refer to the [@dxup/unimport](/packages/unimport) package for more details.
|
|
105
146
|
|
|
106
|
-
###
|
|
147
|
+
### 9. unofficial
|
|
107
148
|
|
|
108
149
|
Find references for SFC on `<template>`.
|
|
109
150
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require("@vue/compiler-dom");
|
|
2
|
+
let pathe = require("pathe");
|
|
3
|
+
//#region src/module/named-layout-slots/utils.ts
|
|
4
|
+
function isInDir(path, dir) {
|
|
5
|
+
const rel = (0, pathe.relative)(dir, path);
|
|
6
|
+
return rel !== ".." && !rel.startsWith("../") && !(0, pathe.isAbsolute)(rel);
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/module/named-layout-slots/language.ts
|
|
10
|
+
const resolvedAsts = /* @__PURE__ */ new WeakSet();
|
|
11
|
+
const plugin = ({ modules: { typescript: ts, "@vue/compiler-dom": CompilerDOM }, config: { options } }) => ({
|
|
12
|
+
version: 2.2,
|
|
13
|
+
order: -1,
|
|
14
|
+
resolveEmbeddedCode(fileName, sfc, embeddedCode) {
|
|
15
|
+
if (!embeddedCode.id.startsWith("script_")) return;
|
|
16
|
+
if (!options.dirs.some((dir) => isInDir(fileName, dir))) return;
|
|
17
|
+
if (!sfc.template?.ast || resolvedAsts.has(sfc.template.ast)) return;
|
|
18
|
+
resolvedAsts.add(sfc.template.ast);
|
|
19
|
+
let layoutName = "default";
|
|
20
|
+
if (sfc.scriptSetup) visit(sfc.scriptSetup.ast);
|
|
21
|
+
function visit(node) {
|
|
22
|
+
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "definePageMeta" && node.arguments.length && ts.isObjectLiteralExpression(node.arguments[0])) {
|
|
23
|
+
for (const prop of node.arguments[0].properties) if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text === "layout" && ts.isStringLiteral(prop.initializer)) {
|
|
24
|
+
layoutName = prop.initializer.text;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
} else ts.forEachChild(node, visit);
|
|
28
|
+
}
|
|
29
|
+
const expression = `\n// @ts-ignore\n{} as import("#build/dxup/layouts").Layouts["${layoutName}"]\n`;
|
|
30
|
+
const children = sfc.template.ast.children;
|
|
31
|
+
sfc.template.ast.children = [{
|
|
32
|
+
type: CompilerDOM.NodeTypes.ELEMENT,
|
|
33
|
+
ns: CompilerDOM.Namespaces.HTML,
|
|
34
|
+
tag: "component",
|
|
35
|
+
tagType: CompilerDOM.ElementTypes.COMPONENT,
|
|
36
|
+
loc: createVirtualLoc(),
|
|
37
|
+
props: [{
|
|
38
|
+
type: CompilerDOM.NodeTypes.DIRECTIVE,
|
|
39
|
+
name: "bind",
|
|
40
|
+
arg: {
|
|
41
|
+
type: CompilerDOM.NodeTypes.SIMPLE_EXPRESSION,
|
|
42
|
+
content: "is",
|
|
43
|
+
isStatic: true,
|
|
44
|
+
constType: CompilerDOM.ConstantTypes.CAN_STRINGIFY,
|
|
45
|
+
loc: createVirtualLoc("is")
|
|
46
|
+
},
|
|
47
|
+
exp: {
|
|
48
|
+
type: CompilerDOM.NodeTypes.SIMPLE_EXPRESSION,
|
|
49
|
+
content: expression,
|
|
50
|
+
isStatic: false,
|
|
51
|
+
constType: CompilerDOM.ConstantTypes.NOT_CONSTANT,
|
|
52
|
+
loc: createVirtualLoc(expression)
|
|
53
|
+
},
|
|
54
|
+
modifiers: [],
|
|
55
|
+
loc: createVirtualLoc(`:is="${expression}"`)
|
|
56
|
+
}],
|
|
57
|
+
children,
|
|
58
|
+
codegenNode: void 0
|
|
59
|
+
}];
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
function createVirtualLoc(source = "") {
|
|
63
|
+
return {
|
|
64
|
+
start: {
|
|
65
|
+
line: Number.MAX_VALUE,
|
|
66
|
+
column: Number.MAX_VALUE,
|
|
67
|
+
offset: Number.MAX_VALUE
|
|
68
|
+
},
|
|
69
|
+
end: {
|
|
70
|
+
line: Number.MAX_VALUE,
|
|
71
|
+
column: Number.MAX_VALUE,
|
|
72
|
+
offset: Number.MAX_VALUE
|
|
73
|
+
},
|
|
74
|
+
source
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
module.exports = plugin;
|
package/dist/module.d.mts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import * as _$_nuxt_schema0 from "@nuxt/schema";
|
|
2
|
-
|
|
3
1
|
//#region src/module/index.d.ts
|
|
4
2
|
interface ModuleOptions {
|
|
5
3
|
features?: {
|
|
@@ -13,6 +11,11 @@ interface ModuleOptions {
|
|
|
13
11
|
* @default true
|
|
14
12
|
*/
|
|
15
13
|
importGlob?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Whether to enable named layout slots support in the pages.
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
namedLayoutSlots?: boolean;
|
|
16
19
|
/**
|
|
17
20
|
* Whether to enable Go to Definition for nitro routes in data fetching methods.
|
|
18
21
|
* @default true
|
|
@@ -46,10 +49,11 @@ interface ModuleOptions {
|
|
|
46
49
|
unofficial?: boolean;
|
|
47
50
|
};
|
|
48
51
|
}
|
|
49
|
-
declare const _default:
|
|
52
|
+
declare const _default: import("@nuxt/schema").NuxtModule<ModuleOptions, {
|
|
50
53
|
features: {
|
|
51
54
|
components: true;
|
|
52
55
|
importGlob: true;
|
|
56
|
+
namedLayoutSlots: false;
|
|
53
57
|
nitroRoutes: true;
|
|
54
58
|
pageMeta: true;
|
|
55
59
|
runtimeConfig: true;
|
package/dist/module.mjs
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import { addTemplate, defineNuxtModule, useNitro } from "@nuxt/kit";
|
|
1
|
+
import { addBuildPlugin, addTemplate, addTypeTemplate, createResolver, defineNuxtModule, useNitro } from "@nuxt/kit";
|
|
2
2
|
import { Buffer } from "node:buffer";
|
|
3
3
|
import { EventEmitter } from "node:events";
|
|
4
4
|
import { mkdir, open, readFile, writeFile } from "node:fs/promises";
|
|
5
5
|
import { watch } from "chokidar";
|
|
6
|
-
import { dirname, join } from "pathe";
|
|
6
|
+
import { dirname, isAbsolute, join, relative } from "pathe";
|
|
7
|
+
import { genExport, genImport, genInlineTypeImport, genObjectKey } from "knitwork";
|
|
8
|
+
import { ElementTypes, NodeTypes, parse } from "@vue/compiler-dom";
|
|
9
|
+
import MagicString from "magic-string";
|
|
10
|
+
import { createUnplugin } from "unplugin";
|
|
11
|
+
import { parseAndWalk } from "oxc-walker";
|
|
7
12
|
//#region package.json
|
|
8
13
|
var name = "@dxup/nuxt";
|
|
9
14
|
//#endregion
|
|
@@ -59,6 +64,142 @@ async function onComponentsRename(nuxt, { fileName, references }) {
|
|
|
59
64
|
await Promise.all(tasks);
|
|
60
65
|
}
|
|
61
66
|
//#endregion
|
|
67
|
+
//#region src/module/named-layout-slots/utils.ts
|
|
68
|
+
const vueRE = /[?&]vue(?:&|$)/;
|
|
69
|
+
const typeRE = /[?&]type=[^&]*/;
|
|
70
|
+
function isVue(id) {
|
|
71
|
+
const index = id.indexOf("?");
|
|
72
|
+
const query = index !== -1 ? id.slice(index) : void 0;
|
|
73
|
+
if (query === void 0) return id.endsWith(".vue");
|
|
74
|
+
if (query === "?macro=true") return true;
|
|
75
|
+
if (!vueRE.test(query)) return false;
|
|
76
|
+
if (typeRE.test(query)) return false;
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
function isInDir(path, dir) {
|
|
80
|
+
const rel = relative(dir, path);
|
|
81
|
+
return rel !== ".." && !rel.startsWith("../") && !isAbsolute(rel);
|
|
82
|
+
}
|
|
83
|
+
function parseSFC(code) {
|
|
84
|
+
const sfc = parse(code, { parseMode: "sfc" });
|
|
85
|
+
let scriptSetup;
|
|
86
|
+
let template;
|
|
87
|
+
for (const node of sfc.children) {
|
|
88
|
+
if (node.type !== NodeTypes.ELEMENT) continue;
|
|
89
|
+
if (node.tag === "script" && node.props.some((prop) => prop.type === NodeTypes.ATTRIBUTE && (prop.name === "setup" || prop.name === "vapor"))) scriptSetup = node;
|
|
90
|
+
else if (node.tag === "template") template = node;
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
scriptSetup,
|
|
94
|
+
template
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/module/named-layout-slots/plugins/transform-layout.ts
|
|
99
|
+
const TransformLayoutPlugin = (options) => createUnplugin(() => ({
|
|
100
|
+
name: name + ":transform-layout",
|
|
101
|
+
enforce: "pre",
|
|
102
|
+
transformInclude: isVue,
|
|
103
|
+
transform: {
|
|
104
|
+
filter: { code: /<(?:nuxt-layout|NuxtLayout)/ },
|
|
105
|
+
handler(code) {
|
|
106
|
+
const { scriptSetup, template } = parseSFC(code);
|
|
107
|
+
const layout = template?.children.find((node) => node.type === NodeTypes.ELEMENT && (node.tag === "nuxt-layout" || node.tag === "NuxtLayout"));
|
|
108
|
+
if (!layout?.children.length) return;
|
|
109
|
+
const s = new MagicString(code);
|
|
110
|
+
const prefix = "\n" + genImport("#build/dxup/layouts.mjs", ["LayoutSlot", "provideLayoutSlots"]);
|
|
111
|
+
const suffix = `\nprovideLayoutSlots();\n`;
|
|
112
|
+
if (scriptSetup) {
|
|
113
|
+
s.appendLeft(scriptSetup.innerLoc.start.offset, prefix);
|
|
114
|
+
s.appendLeft(scriptSetup.innerLoc.end.offset, suffix);
|
|
115
|
+
} else s.prepend(`<script setup>${prefix + suffix}<\/script>\n\n`);
|
|
116
|
+
s.appendLeft(layout.children.at(-1).loc.end.offset, `
|
|
117
|
+
<template v-for="name in $route.meta.layoutSlots ?? []" :key="name" #[name]="props">
|
|
118
|
+
<LayoutSlot :name :props/>
|
|
119
|
+
</template>`);
|
|
120
|
+
return {
|
|
121
|
+
code: s.toString(),
|
|
122
|
+
map: options.sourcemap ? s.generateMap({ hires: true }) : void 0
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}));
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/module/named-layout-slots/plugins/transform-page.ts
|
|
129
|
+
const TransformPagePlugin = (options) => createUnplugin(() => ({
|
|
130
|
+
name: name + ":transform-page",
|
|
131
|
+
enforce: "pre",
|
|
132
|
+
transformInclude: isVue,
|
|
133
|
+
transform(code, id) {
|
|
134
|
+
if (!options.dirs.some((dir) => isInDir(id, dir))) return;
|
|
135
|
+
const { scriptSetup, template } = parseSFC(code);
|
|
136
|
+
if (!template) return;
|
|
137
|
+
const slots = [];
|
|
138
|
+
for (const node of template.children) {
|
|
139
|
+
if (node.type !== NodeTypes.ELEMENT || node.tagType !== ElementTypes.TEMPLATE) continue;
|
|
140
|
+
const dir = node.props.find((prop) => prop.type === NodeTypes.DIRECTIVE && prop.name === "slot");
|
|
141
|
+
if (dir?.arg?.type === NodeTypes.SIMPLE_EXPRESSION && dir.arg.isStatic && dir.arg.content !== "" && dir.arg.content !== "default") slots.push(dir.arg.content);
|
|
142
|
+
}
|
|
143
|
+
if (!slots.length) return;
|
|
144
|
+
const s = new MagicString(code);
|
|
145
|
+
const imports = genImport("#build/dxup/layouts.mjs", ["LayoutSlotsForward"]);
|
|
146
|
+
const expression = `layoutSlots: [${slots.map((slot) => JSON.stringify(slot)).join(", ")}],\n`;
|
|
147
|
+
if (scriptSetup) {
|
|
148
|
+
let meta;
|
|
149
|
+
parseAndWalk(scriptSetup.innerLoc.source, id, {
|
|
150
|
+
parseOptions: { lang: scriptSetup.props.find((prop) => prop.type === NodeTypes.ATTRIBUTE && prop.name === "lang")?.value?.content ?? "ts" },
|
|
151
|
+
enter(node) {
|
|
152
|
+
if (node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "definePageMeta" && node.arguments[0]?.type === "ObjectExpression") {
|
|
153
|
+
meta = node.arguments[0];
|
|
154
|
+
this.skip();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
const start = scriptSetup.innerLoc.start.offset;
|
|
159
|
+
s.appendLeft(start, `\n${imports}\n`);
|
|
160
|
+
if (meta) s.appendLeft(meta.properties[0].start + start, expression);
|
|
161
|
+
else s.appendLeft(scriptSetup.innerLoc.start.offset, `\ndefinePageMeta({\n${expression}});\n`);
|
|
162
|
+
} else s.prepend(`<script setup>\n${imports}\ndefinePageMeta({\n${expression}});\n<\/script>\n\n`);
|
|
163
|
+
s.appendLeft(template.innerLoc.start.offset, `<LayoutSlotsForward>`);
|
|
164
|
+
s.appendLeft(template.innerLoc.end.offset, "</LayoutSlotsForward>");
|
|
165
|
+
return {
|
|
166
|
+
code: s.toString(),
|
|
167
|
+
map: options.sourcemap ? s.generateMap({ hires: true }) : void 0
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}));
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region src/module/named-layout-slots/module.ts
|
|
173
|
+
function setup(nuxt, pluginsVue) {
|
|
174
|
+
const resolver = createResolver(import.meta.url);
|
|
175
|
+
const pageDirs = nuxt.options._layers.map((layer) => join(layer.config.srcDir, layer.config.dir?.pages ?? "pages"));
|
|
176
|
+
pluginsVue.push({
|
|
177
|
+
name: "@dxup/nuxt/languages/named-layout-slots.cjs",
|
|
178
|
+
options: { dirs: pageDirs }
|
|
179
|
+
});
|
|
180
|
+
addTemplate({
|
|
181
|
+
filename: "dxup/layouts.mjs",
|
|
182
|
+
getContents() {
|
|
183
|
+
return genExport(resolver.resolve("runtime/layouts.mjs"), "*");
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
addTypeTemplate({
|
|
187
|
+
filename: "dxup/layouts.d.ts",
|
|
188
|
+
getContents({ app }) {
|
|
189
|
+
return `
|
|
190
|
+
export interface Layouts {
|
|
191
|
+
${Object.values(app.layouts).map((layout) => ` ${genObjectKey(layout.name)}: ${genInlineTypeImport(layout.file)};`).join("\n")}
|
|
192
|
+
}
|
|
193
|
+
`.trimStart();
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
addBuildPlugin(TransformPagePlugin({
|
|
197
|
+
dirs: pageDirs,
|
|
198
|
+
sourcemap: !!nuxt.options.sourcemap.client
|
|
199
|
+
}));
|
|
200
|
+
addBuildPlugin(TransformLayoutPlugin({ sourcemap: !!nuxt.options.sourcemap.client }));
|
|
201
|
+
}
|
|
202
|
+
//#endregion
|
|
62
203
|
//#region src/module/index.ts
|
|
63
204
|
var module_default = defineNuxtModule().with({
|
|
64
205
|
meta: {
|
|
@@ -68,6 +209,7 @@ var module_default = defineNuxtModule().with({
|
|
|
68
209
|
defaults: { features: {
|
|
69
210
|
components: true,
|
|
70
211
|
importGlob: true,
|
|
212
|
+
namedLayoutSlots: false,
|
|
71
213
|
nitroRoutes: true,
|
|
72
214
|
pageMeta: true,
|
|
73
215
|
runtimeConfig: true,
|
|
@@ -77,11 +219,14 @@ var module_default = defineNuxtModule().with({
|
|
|
77
219
|
} },
|
|
78
220
|
async setup(options, nuxt) {
|
|
79
221
|
const pluginsTs = [{ name: "@dxup/nuxt" }];
|
|
80
|
-
|
|
222
|
+
const pluginsVue = [];
|
|
223
|
+
if (options.features.namedLayoutSlots) setup(nuxt, pluginsVue);
|
|
224
|
+
if (options.features.unimport) pluginsTs.unshift({ name: "@dxup/unimport" });
|
|
81
225
|
append(pluginsTs, nuxt.options, "typescript", "tsConfig", "compilerOptions");
|
|
82
226
|
append(pluginsTs, nuxt.options.nitro, "typescript", "tsConfig", "compilerOptions");
|
|
83
227
|
append(pluginsTs, nuxt.options, "typescript", "sharedTsConfig", "compilerOptions");
|
|
84
228
|
append(pluginsTs, nuxt.options, "typescript", "nodeTsConfig", "compilerOptions");
|
|
229
|
+
append(pluginsVue, nuxt.options, "typescript", "tsConfig", "vueCompilerOptions");
|
|
85
230
|
addTemplate({
|
|
86
231
|
filename: "dxup/data.json",
|
|
87
232
|
write: true,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ShallowRef, Slots } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/module/named-layout-slots/runtime/layouts.d.ts
|
|
4
|
+
interface LayoutSlotsRegistry {
|
|
5
|
+
slots: ShallowRef<Slots>;
|
|
6
|
+
set: (slots: Slots) => void;
|
|
7
|
+
waitFor: (name: string) => Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
declare function provideLayoutSlots(): LayoutSlotsRegistry;
|
|
10
|
+
declare const LayoutSlot: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
11
|
+
name: {
|
|
12
|
+
type: StringConstructor;
|
|
13
|
+
required: true;
|
|
14
|
+
};
|
|
15
|
+
props: {
|
|
16
|
+
type: ObjectConstructor;
|
|
17
|
+
default: () => {};
|
|
18
|
+
};
|
|
19
|
+
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
}>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
22
|
+
name: {
|
|
23
|
+
type: StringConstructor;
|
|
24
|
+
required: true;
|
|
25
|
+
};
|
|
26
|
+
props: {
|
|
27
|
+
type: ObjectConstructor;
|
|
28
|
+
default: () => {};
|
|
29
|
+
};
|
|
30
|
+
}>> & Readonly<{}>, {
|
|
31
|
+
props: Record<string, any>;
|
|
32
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
33
|
+
declare const LayoutSlotsForward: import("vue").DefineSetupFnComponent<Record<string, any>, {}, {}, Record<string, any> & {}, import("vue").PublicProps>;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { LayoutSlot, LayoutSlotsForward, provideLayoutSlots };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { defineComponent, inject, provide, shallowRef } from "vue";
|
|
2
|
+
//#region src/module/named-layout-slots/runtime/layouts.ts
|
|
3
|
+
const injectionKey = Symbol();
|
|
4
|
+
function provideLayoutSlots() {
|
|
5
|
+
const slots = shallowRef({});
|
|
6
|
+
const waiters = /* @__PURE__ */ new Map();
|
|
7
|
+
const registry = {
|
|
8
|
+
slots,
|
|
9
|
+
set(value) {
|
|
10
|
+
slots.value = value;
|
|
11
|
+
for (const name of Object.keys(value)) {
|
|
12
|
+
const resolves = waiters.get(name);
|
|
13
|
+
if (!resolves?.length) continue;
|
|
14
|
+
waiters.delete(name);
|
|
15
|
+
for (const resolve of resolves) resolve();
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
waitFor(name) {
|
|
19
|
+
if (slots.value[name]) return Promise.resolve();
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
let resolves = waiters.get(name);
|
|
22
|
+
if (!resolves) waiters.set(name, resolves = []);
|
|
23
|
+
resolves.push(resolve);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
provide(injectionKey, registry);
|
|
28
|
+
return registry;
|
|
29
|
+
}
|
|
30
|
+
const LayoutSlot = defineComponent({
|
|
31
|
+
props: {
|
|
32
|
+
name: {
|
|
33
|
+
type: String,
|
|
34
|
+
required: true
|
|
35
|
+
},
|
|
36
|
+
props: {
|
|
37
|
+
type: Object,
|
|
38
|
+
default: () => ({})
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
setup(props) {
|
|
42
|
+
const registry = inject(injectionKey);
|
|
43
|
+
const render = () => registry.slots.value[props.name]?.(props.props);
|
|
44
|
+
if (import.meta.server && !registry.slots.value[props.name]) return registry.waitFor(props.name).then(() => render);
|
|
45
|
+
return render;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const LayoutSlotsForward = defineComponent((props, ctx) => {
|
|
49
|
+
inject(injectionKey).set(ctx.slots);
|
|
50
|
+
return () => ctx.slots.default?.();
|
|
51
|
+
});
|
|
52
|
+
//#endregion
|
|
53
|
+
export { LayoutSlot, LayoutSlotsForward, provideLayoutSlots };
|
package/dist/typescript.cjs
CHANGED
|
@@ -172,12 +172,12 @@ var getDefinitionAndBoundSpan_exports = /* @__PURE__ */ __exportAll({
|
|
|
172
172
|
postprocess: () => postprocess,
|
|
173
173
|
preprocess: () => preprocess$1
|
|
174
174
|
});
|
|
175
|
-
const fetchFunctions = new Set([
|
|
175
|
+
const fetchFunctions = /* @__PURE__ */ new Set([
|
|
176
176
|
"$fetch",
|
|
177
177
|
"useFetch",
|
|
178
178
|
"useLazyFetch"
|
|
179
179
|
]);
|
|
180
|
-
const pageMetaKeys = new Set(["layout", "middleware"]);
|
|
180
|
+
const pageMetaKeys = /* @__PURE__ */ new Set(["layout", "middleware"]);
|
|
181
181
|
function postprocess(context, language, getDefinitionAndBoundSpan) {
|
|
182
182
|
const { ts } = context;
|
|
183
183
|
return (...args) => {
|
package/package.json
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxup/nuxt",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.1",
|
|
5
5
|
"description": "TypeScript plugin for Nuxt",
|
|
6
6
|
"author": "KazariEX",
|
|
7
7
|
"license": "MIT",
|
|
8
|
-
"repository":
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "KazariEX/dxup"
|
|
11
|
+
},
|
|
9
12
|
"exports": {
|
|
10
13
|
".": "./dist/module.mjs",
|
|
14
|
+
"./languages/*": "./dist/languages/*",
|
|
11
15
|
"./package.json": "./package.json"
|
|
12
16
|
},
|
|
13
17
|
"main": "./dist/typescript.cjs",
|
|
@@ -15,26 +19,23 @@
|
|
|
15
19
|
"files": [
|
|
16
20
|
"dist"
|
|
17
21
|
],
|
|
18
|
-
"peerDependencies": {
|
|
19
|
-
"typescript": "*"
|
|
20
|
-
},
|
|
21
|
-
"peerDependenciesMeta": {
|
|
22
|
-
"typescript": {
|
|
23
|
-
"optional": true
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
22
|
"dependencies": {
|
|
27
|
-
"@nuxt/kit": "^4.4.
|
|
23
|
+
"@nuxt/kit": "^4.4.8",
|
|
24
|
+
"@vue/compiler-dom": "^3.5.38",
|
|
28
25
|
"chokidar": "^5.0.0",
|
|
26
|
+
"knitwork": "^1.3.0",
|
|
27
|
+
"magic-string": "^0.30.21",
|
|
28
|
+
"oxc-walker": "^1.0.0",
|
|
29
29
|
"pathe": "^2.0.3",
|
|
30
|
-
"tinyglobby": "^0.2.
|
|
30
|
+
"tinyglobby": "^0.2.17",
|
|
31
|
+
"unplugin": "^3.0.0",
|
|
31
32
|
"@dxup/unimport": "^0.1.2"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"@volar/language-core": "^2.4.28",
|
|
35
36
|
"@volar/typescript": "^2.4.28",
|
|
36
|
-
"@vue/language-core": "^3.
|
|
37
|
-
"nuxt": "^4.4.
|
|
37
|
+
"@vue/language-core": "^3.3.5",
|
|
38
|
+
"nuxt": "^4.4.8",
|
|
38
39
|
"typescript": "^6.0.3",
|
|
39
40
|
"@dxup/shared": "0.0.0"
|
|
40
41
|
},
|