@dxup/nuxt 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/languages/named-layout-slots.cjs +8 -2
- package/dist/module.mjs +55 -78
- package/dist/runtime/layouts.d.mts +18 -0
- package/dist/runtime/layouts.mjs +38 -0
- package/dist/typescript.cjs +2 -2
- package/package.json +1 -3
- package/dist/components/forward.d.mts +0 -4
- package/dist/components/forward.mjs +0 -10
|
@@ -20,8 +20,14 @@ const plugin = ({ modules: { typescript: ts, "@vue/compiler-dom": CompilerDOM },
|
|
|
20
20
|
if (sfc.scriptSetup) visit(sfc.scriptSetup.ast);
|
|
21
21
|
function visit(node) {
|
|
22
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"
|
|
24
|
-
layoutName = prop.initializer.text;
|
|
23
|
+
for (const prop of node.arguments[0].properties) if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text === "layout") {
|
|
24
|
+
if (ts.isStringLiteralLike(prop.initializer)) layoutName = prop.initializer.text;
|
|
25
|
+
else if (ts.isObjectLiteralExpression(prop.initializer)) {
|
|
26
|
+
for (const sub of prop.initializer.properties) if (ts.isPropertyAssignment(sub) && ts.isIdentifier(sub.name) && sub.name.text === "name" && ts.isStringLiteralLike(sub.initializer)) {
|
|
27
|
+
layoutName = sub.initializer.text;
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
25
31
|
break;
|
|
26
32
|
}
|
|
27
33
|
} else ts.forEachChild(node, visit);
|
package/dist/module.mjs
CHANGED
|
@@ -8,7 +8,6 @@ import { genExport, genImport, genInlineTypeImport, genObjectKey } from "knitwor
|
|
|
8
8
|
import { ElementTypes, NodeTypes, parse } from "@vue/compiler-dom";
|
|
9
9
|
import MagicString from "magic-string";
|
|
10
10
|
import { createUnplugin } from "unplugin";
|
|
11
|
-
import { parseAndWalk } from "oxc-walker";
|
|
12
11
|
//#region package.json
|
|
13
12
|
var name = "@dxup/nuxt";
|
|
14
13
|
//#endregion
|
|
@@ -94,72 +93,52 @@ function parseSFC(code) {
|
|
|
94
93
|
template
|
|
95
94
|
};
|
|
96
95
|
}
|
|
96
|
+
function* forEachElementNode(node) {
|
|
97
|
+
if (node.type === NodeTypes.ROOT || node.type === NodeTypes.FOR || node.type === NodeTypes.IF_BRANCH) for (const child of node.children) yield* forEachElementNode(child);
|
|
98
|
+
else if (node.type === NodeTypes.ELEMENT) {
|
|
99
|
+
yield node;
|
|
100
|
+
for (const child of node.children) yield* forEachElementNode(child);
|
|
101
|
+
} else if (node.type === NodeTypes.IF) for (const branch of node.branches) yield* forEachElementNode(branch);
|
|
102
|
+
}
|
|
97
103
|
//#endregion
|
|
98
|
-
//#region src/module/named-layout-slots/
|
|
99
|
-
const
|
|
104
|
+
//#region src/module/named-layout-slots/transform.ts
|
|
105
|
+
const TransformPlugins = (options) => createUnplugin(() => [{
|
|
100
106
|
name: name + ":transform-layout",
|
|
101
107
|
enforce: "pre",
|
|
102
108
|
transformInclude: isVue,
|
|
103
|
-
transform
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
code: s.toString(),
|
|
122
|
-
map: options.sourcemap ? s.generateMap({ hires: true }) : void 0
|
|
123
|
-
};
|
|
124
|
-
}
|
|
109
|
+
transform(code, id) {
|
|
110
|
+
if (!options.layoutDirs.some((dir) => isInDir(id, dir))) return;
|
|
111
|
+
const { scriptSetup, template } = parseSFC(code);
|
|
112
|
+
if (!template) return;
|
|
113
|
+
const slots = [];
|
|
114
|
+
for (const node of forEachElementNode(template)) if (node.tagType === ElementTypes.SLOT && node.props.length && node.props.every((prop) => prop.name !== "name" || prop.type !== NodeTypes.ATTRIBUTE || prop.value && prop.value.content !== "default")) slots.push(node);
|
|
115
|
+
if (!slots.length) return;
|
|
116
|
+
const s = new MagicString(code);
|
|
117
|
+
const imports = genImport("#build/dxup/layouts.mjs", ["LayoutSlot"]);
|
|
118
|
+
if (scriptSetup) {
|
|
119
|
+
const start = scriptSetup.innerLoc.start.offset;
|
|
120
|
+
s.appendLeft(start, `\n${imports}\n`);
|
|
121
|
+
} else s.prepend(`<script setup>\n${imports}\n<\/script>\n\n`);
|
|
122
|
+
for (const slot of slots) for (const offset of /* @__PURE__ */ new Set([slot.loc.start.offset + slot.loc.source.indexOf("slot"), slot.loc.start.offset + slot.loc.source.lastIndexOf("slot")])) s.overwrite(offset, offset + 4, "LayoutSlot");
|
|
123
|
+
return {
|
|
124
|
+
code: s.toString(),
|
|
125
|
+
map: options.sourcemap ? s.generateMap({ hires: true }) : void 0
|
|
126
|
+
};
|
|
125
127
|
}
|
|
126
|
-
}
|
|
127
|
-
//#endregion
|
|
128
|
-
//#region src/module/named-layout-slots/plugins/transform-page.ts
|
|
129
|
-
const TransformPagePlugin = (options) => createUnplugin(() => ({
|
|
128
|
+
}, {
|
|
130
129
|
name: name + ":transform-page",
|
|
131
130
|
enforce: "pre",
|
|
132
131
|
transformInclude: isVue,
|
|
133
132
|
transform(code, id) {
|
|
134
|
-
if (!options.
|
|
133
|
+
if (!options.pageDirs.some((dir) => isInDir(id, dir))) return;
|
|
135
134
|
const { scriptSetup, template } = parseSFC(code);
|
|
136
135
|
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
136
|
const s = new MagicString(code);
|
|
145
137
|
const imports = genImport("#build/dxup/layouts.mjs", ["LayoutSlotsForward"]);
|
|
146
|
-
const expression = `layoutSlots: [${slots.map((slot) => JSON.stringify(slot)).join(", ")}],\n`;
|
|
147
138
|
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
139
|
const start = scriptSetup.innerLoc.start.offset;
|
|
159
140
|
s.appendLeft(start, `\n${imports}\n`);
|
|
160
|
-
|
|
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`);
|
|
141
|
+
} else s.prepend(`<script setup>\n${imports}\n<\/script>\n\n`);
|
|
163
142
|
s.appendLeft(template.innerLoc.start.offset, `<LayoutSlotsForward>`);
|
|
164
143
|
s.appendLeft(template.innerLoc.end.offset, "</LayoutSlotsForward>");
|
|
165
144
|
return {
|
|
@@ -167,56 +146,54 @@ const TransformPagePlugin = (options) => createUnplugin(() => ({
|
|
|
167
146
|
map: options.sourcemap ? s.generateMap({ hires: true }) : void 0
|
|
168
147
|
};
|
|
169
148
|
}
|
|
170
|
-
})
|
|
149
|
+
}]);
|
|
171
150
|
//#endregion
|
|
172
151
|
//#region src/module/named-layout-slots/module.ts
|
|
173
|
-
function setup(nuxt, pluginsVue) {
|
|
152
|
+
async function setup(nuxt, pluginsVue) {
|
|
174
153
|
const resolver = createResolver(import.meta.url);
|
|
154
|
+
const layoutDirs = nuxt.options._layers.map((layer) => join(layer.config.srcDir, layer.config.dir?.layouts ?? "layouts"));
|
|
175
155
|
const pageDirs = nuxt.options._layers.map((layer) => join(layer.config.srcDir, layer.config.dir?.pages ?? "pages"));
|
|
176
156
|
pluginsVue.push({
|
|
177
157
|
name: "@dxup/nuxt/languages/named-layout-slots.cjs",
|
|
178
158
|
options: { dirs: pageDirs }
|
|
179
159
|
});
|
|
160
|
+
nuxt.hook("components:extend", (components) => {
|
|
161
|
+
for (const comp of components) if (comp.pascalName === "NuxtLayout") {
|
|
162
|
+
comp.declarationPath = comp.filePath;
|
|
163
|
+
comp.filePath = join(nuxt.options.buildDir, "dxup/layouts.mjs");
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
const layoutPath = join(await resolver.resolvePath("nuxt", { cwd: nuxt.options.rootDir }), "../app/components/nuxt-layout.js");
|
|
180
168
|
addTemplate({
|
|
181
169
|
filename: "dxup/layouts.mjs",
|
|
182
170
|
getContents() {
|
|
183
|
-
return
|
|
184
|
-
|
|
185
|
-
"
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
as: "LayoutSlotsForward"
|
|
192
|
-
}])}
|
|
193
|
-
const injectionKey = Symbol();
|
|
194
|
-
export function provideLayoutSlots() {
|
|
195
|
-
const slots = shallowRef({});
|
|
196
|
-
provide(injectionKey, slots);
|
|
197
|
-
return slots;
|
|
198
|
-
}
|
|
199
|
-
export function injectLayoutSlots() {
|
|
200
|
-
return inject(injectionKey);
|
|
201
|
-
}
|
|
202
|
-
`.trimStart();
|
|
171
|
+
return [
|
|
172
|
+
genExport(resolver.resolve("runtime/layouts.mjs"), "*"),
|
|
173
|
+
genExport(resolver.resolve("runtime/layouts.mjs"), ["default"]),
|
|
174
|
+
genExport(layoutPath, [{
|
|
175
|
+
name: "default",
|
|
176
|
+
as: "NuxtLayout"
|
|
177
|
+
}])
|
|
178
|
+
].join("\n");
|
|
203
179
|
}
|
|
204
180
|
});
|
|
205
181
|
addTypeTemplate({
|
|
206
182
|
filename: "dxup/layouts.d.ts",
|
|
207
183
|
getContents({ app }) {
|
|
184
|
+
const currentDir = join(nuxt.options.buildDir, "dxup");
|
|
208
185
|
return `
|
|
209
186
|
export interface Layouts {
|
|
210
|
-
${Object.values(app.layouts).map((layout) => `
|
|
187
|
+
${Object.values(app.layouts).map((layout) => ` ${genObjectKey(layout.name)}: ${genInlineTypeImport(relative(currentDir, layout.file))};`).join("\n")}
|
|
211
188
|
}
|
|
212
189
|
`.trimStart();
|
|
213
190
|
}
|
|
214
191
|
});
|
|
215
|
-
addBuildPlugin(
|
|
216
|
-
|
|
192
|
+
addBuildPlugin(TransformPlugins({
|
|
193
|
+
layoutDirs,
|
|
194
|
+
pageDirs,
|
|
217
195
|
sourcemap: !!nuxt.options.sourcemap.client
|
|
218
196
|
}));
|
|
219
|
-
addBuildPlugin(TransformLayoutPlugin({ sourcemap: !!nuxt.options.sourcemap.client }));
|
|
220
197
|
}
|
|
221
198
|
//#endregion
|
|
222
199
|
//#region src/module/index.ts
|
|
@@ -239,7 +216,7 @@ var module_default = defineNuxtModule().with({
|
|
|
239
216
|
async setup(options, nuxt) {
|
|
240
217
|
const pluginsTs = [{ name: "@dxup/nuxt" }];
|
|
241
218
|
const pluginsVue = [];
|
|
242
|
-
if (options.features.namedLayoutSlots) setup(nuxt, pluginsVue);
|
|
219
|
+
if (options.features.namedLayoutSlots) await setup(nuxt, pluginsVue);
|
|
243
220
|
if (options.features.unimport) pluginsTs.unshift({ name: "@dxup/unimport" });
|
|
244
221
|
append(pluginsTs, nuxt.options, "typescript", "tsConfig", "compilerOptions");
|
|
245
222
|
append(pluginsTs, nuxt.options.nitro, "typescript", "tsConfig", "compilerOptions");
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/module/named-layout-slots/runtime/layouts.d.ts
|
|
2
|
+
declare const _default: import("vue").DefineSetupFnComponent<Record<string, any>, {}, {}, Record<string, any> & {}, import("vue").PublicProps>;
|
|
3
|
+
declare const LayoutSlot: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
+
name: {
|
|
5
|
+
type: StringConstructor;
|
|
6
|
+
required: true;
|
|
7
|
+
};
|
|
8
|
+
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
9
|
+
[key: string]: any;
|
|
10
|
+
}>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
11
|
+
name: {
|
|
12
|
+
type: StringConstructor;
|
|
13
|
+
required: true;
|
|
14
|
+
};
|
|
15
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
16
|
+
declare const LayoutSlotsForward: import("vue").DefineSetupFnComponent<Record<string, any>, {}, {}, Record<string, any> & {}, import("vue").PublicProps>;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { LayoutSlot, LayoutSlotsForward, _default as default };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { defineComponent, h, inject, provide, shallowRef } from "vue";
|
|
2
|
+
import { NuxtLayout } from "#build/dxup/layouts.mjs";
|
|
3
|
+
//#region src/module/named-layout-slots/runtime/layouts.ts
|
|
4
|
+
const injectionKey = Symbol();
|
|
5
|
+
var layouts_default = defineComponent((props, ctx) => {
|
|
6
|
+
const slots = shallowRef({});
|
|
7
|
+
let resolveReady;
|
|
8
|
+
provide(injectionKey, {
|
|
9
|
+
slots,
|
|
10
|
+
ready: new Promise((resolve) => {
|
|
11
|
+
resolveReady = resolve;
|
|
12
|
+
}),
|
|
13
|
+
set(value) {
|
|
14
|
+
slots.value = value;
|
|
15
|
+
resolveReady?.();
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return () => h(NuxtLayout, props, ctx.slots);
|
|
19
|
+
});
|
|
20
|
+
const LayoutSlot = defineComponent({
|
|
21
|
+
props: { name: {
|
|
22
|
+
type: String,
|
|
23
|
+
required: true
|
|
24
|
+
} },
|
|
25
|
+
setup(props, ctx) {
|
|
26
|
+
const { slots, ready } = inject(injectionKey);
|
|
27
|
+
const render = () => slots.value[props.name]?.(ctx.attrs);
|
|
28
|
+
if (import.meta.server && !slots.value[props.name]) return ready.then(() => render);
|
|
29
|
+
return render;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const LayoutSlotsForward = defineComponent((props, ctx) => {
|
|
33
|
+
const { set } = inject(injectionKey);
|
|
34
|
+
set(ctx.slots);
|
|
35
|
+
return () => ctx.slots.default?.();
|
|
36
|
+
});
|
|
37
|
+
//#endregion
|
|
38
|
+
export { LayoutSlot, LayoutSlotsForward, layouts_default as default };
|
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,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxup/nuxt",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.2",
|
|
5
5
|
"description": "TypeScript plugin for Nuxt",
|
|
6
6
|
"author": "KazariEX",
|
|
7
7
|
"license": "MIT",
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
},
|
|
12
12
|
"exports": {
|
|
13
13
|
".": "./dist/module.mjs",
|
|
14
|
-
"./components/*": "./dist/components/*",
|
|
15
14
|
"./languages/*": "./dist/languages/*",
|
|
16
15
|
"./package.json": "./package.json"
|
|
17
16
|
},
|
|
@@ -26,7 +25,6 @@
|
|
|
26
25
|
"chokidar": "^5.0.0",
|
|
27
26
|
"knitwork": "^1.3.0",
|
|
28
27
|
"magic-string": "^0.30.21",
|
|
29
|
-
"oxc-walker": "^1.0.0",
|
|
30
28
|
"pathe": "^2.0.3",
|
|
31
29
|
"tinyglobby": "^0.2.17",
|
|
32
30
|
"unplugin": "^3.0.0",
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { defineComponent } from "vue";
|
|
2
|
-
import { injectLayoutSlots } from "#build/dxup/layouts.mjs";
|
|
3
|
-
//#region src/module/named-layout-slots/components/forward.ts
|
|
4
|
-
var forward_default = defineComponent((props, ctx) => {
|
|
5
|
-
const slots = injectLayoutSlots();
|
|
6
|
-
slots.value = ctx.slots;
|
|
7
|
-
return () => ctx.slots.default?.();
|
|
8
|
-
});
|
|
9
|
-
//#endregion
|
|
10
|
-
export { forward_default as default };
|