@eycraf/permission-kit-vite-plugin 0.0.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/dist/index.cjs +591 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +179 -0
- package/dist/index.d.ts +179 -0
- package/dist/index.js +560 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
default: () => permissionPlugin
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
var import_vite3 = require("vite");
|
|
37
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
38
|
+
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
39
|
+
|
|
40
|
+
// src/options.ts
|
|
41
|
+
var import_zod = require("zod");
|
|
42
|
+
var FilterPatternSchema = import_zod.z.custom();
|
|
43
|
+
var GlobPatternSchema = import_zod.z.union([import_zod.z.string(), import_zod.z.array(import_zod.z.string())]);
|
|
44
|
+
var PluginOptionsSchema = import_zod.z.object({
|
|
45
|
+
framework: import_zod.z.enum(["react", "vue"]).default("react"),
|
|
46
|
+
componentName: import_zod.z.string().default("Can"),
|
|
47
|
+
importFrom: import_zod.z.string().default("@eycraf/permission-kit-react"),
|
|
48
|
+
/**
|
|
49
|
+
* 全局 include/exclude。
|
|
50
|
+
* transform/rewrite 没单独配置时,会回退使用这里。
|
|
51
|
+
*/
|
|
52
|
+
include: FilterPatternSchema.optional(),
|
|
53
|
+
exclude: FilterPatternSchema.optional(),
|
|
54
|
+
transform: import_zod.z.object({
|
|
55
|
+
enabled: import_zod.z.boolean().default(true),
|
|
56
|
+
include: FilterPatternSchema.optional(),
|
|
57
|
+
exclude: FilterPatternSchema.optional(),
|
|
58
|
+
attributes: import_zod.z.array(import_zod.z.string()).default(["permission"]),
|
|
59
|
+
modeAttribute: import_zod.z.string().default("permissionMode"),
|
|
60
|
+
strategyAttribute: import_zod.z.string().default("permissionStrategy"),
|
|
61
|
+
allowNested: import_zod.z.boolean().default(false)
|
|
62
|
+
}).default({}),
|
|
63
|
+
rewrite: import_zod.z.object({
|
|
64
|
+
enabled: import_zod.z.boolean().default(false),
|
|
65
|
+
/**
|
|
66
|
+
* false = dry-run,只打印会修改哪些文件
|
|
67
|
+
* true = 真实写回源文件
|
|
68
|
+
*/
|
|
69
|
+
write: import_zod.z.boolean().default(false),
|
|
70
|
+
include: GlobPatternSchema.optional(),
|
|
71
|
+
exclude: GlobPatternSchema.optional(),
|
|
72
|
+
/**
|
|
73
|
+
* rewrite 只在 serve/build 启动时跑一次。
|
|
74
|
+
* 默认 true,避免 HMR 时反复改文件。
|
|
75
|
+
*/
|
|
76
|
+
once: import_zod.z.boolean().default(true)
|
|
77
|
+
}).default({}),
|
|
78
|
+
manifest: import_zod.z.object({
|
|
79
|
+
enabled: import_zod.z.boolean().default(true),
|
|
80
|
+
output: import_zod.z.string().default("src/generated/permission-manifest.json")
|
|
81
|
+
}).default({}),
|
|
82
|
+
dts: import_zod.z.object({
|
|
83
|
+
enabled: import_zod.z.boolean().default(true),
|
|
84
|
+
output: import_zod.z.string().default("src/generated/permission.d.ts"),
|
|
85
|
+
typeName: import_zod.z.string().default("PermissionKey")
|
|
86
|
+
}).default({}),
|
|
87
|
+
validate: import_zod.z.object({
|
|
88
|
+
enabled: import_zod.z.boolean().default(false),
|
|
89
|
+
permissions: import_zod.z.array(import_zod.z.string()).default([]),
|
|
90
|
+
unknownPermission: import_zod.z.enum(["off", "warn", "error"]).default("warn")
|
|
91
|
+
}).default({})
|
|
92
|
+
});
|
|
93
|
+
function resolveOptions(options) {
|
|
94
|
+
return PluginOptionsSchema.parse(options);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// src/state.ts
|
|
98
|
+
var PermissionState = class {
|
|
99
|
+
constructor() {
|
|
100
|
+
this.fileUsageMap = /* @__PURE__ */ new Map();
|
|
101
|
+
}
|
|
102
|
+
clear() {
|
|
103
|
+
this.fileUsageMap.clear();
|
|
104
|
+
}
|
|
105
|
+
setFileUsage(file, usages) {
|
|
106
|
+
this.fileUsageMap.set(file, usages);
|
|
107
|
+
}
|
|
108
|
+
removeFile(file) {
|
|
109
|
+
this.fileUsageMap.delete(file);
|
|
110
|
+
}
|
|
111
|
+
getAllUsages() {
|
|
112
|
+
return [...this.fileUsageMap.values()].flat();
|
|
113
|
+
}
|
|
114
|
+
getUsedPermissions() {
|
|
115
|
+
return [...new Set(this.getAllUsages().map((item) => item.permission))].sort();
|
|
116
|
+
}
|
|
117
|
+
toManifest() {
|
|
118
|
+
var _a;
|
|
119
|
+
const result = {};
|
|
120
|
+
for (const usage of this.getAllUsages()) {
|
|
121
|
+
const items = result[_a = usage.permission] ?? (result[_a] = []);
|
|
122
|
+
const entry = {
|
|
123
|
+
file: usage.file
|
|
124
|
+
};
|
|
125
|
+
if (usage.line !== void 0) {
|
|
126
|
+
entry.line = usage.line;
|
|
127
|
+
}
|
|
128
|
+
if (usage.column !== void 0) {
|
|
129
|
+
entry.column = usage.column;
|
|
130
|
+
}
|
|
131
|
+
items.push(entry);
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// src/transformReact.ts
|
|
138
|
+
var import_parser = require("@babel/parser");
|
|
139
|
+
var import_traverse = __toESM(require("@babel/traverse"), 1);
|
|
140
|
+
var import_magic_string = __toESM(require("magic-string"), 1);
|
|
141
|
+
function transformReactPermission(code, id, options) {
|
|
142
|
+
if (!/\.[jt]sx$/.test(id)) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const attrs = options.transform.attributes;
|
|
146
|
+
const modeAttrName = options.transform.modeAttribute;
|
|
147
|
+
const componentName = options.componentName;
|
|
148
|
+
const ast = (0, import_parser.parse)(code, {
|
|
149
|
+
sourceType: "module",
|
|
150
|
+
plugins: ["jsx", "typescript"],
|
|
151
|
+
errorRecovery: true
|
|
152
|
+
});
|
|
153
|
+
const ms = new import_magic_string.default(code);
|
|
154
|
+
const wraps = [];
|
|
155
|
+
const usages = [];
|
|
156
|
+
const removes = [];
|
|
157
|
+
let hasCanImport = false;
|
|
158
|
+
let lastImportEnd = 0;
|
|
159
|
+
(0, import_traverse.default)(ast, {
|
|
160
|
+
ImportDeclaration(path4) {
|
|
161
|
+
lastImportEnd = Math.max(lastImportEnd, path4.node.end ?? 0);
|
|
162
|
+
if (path4.node.source.value === options.importFrom) {
|
|
163
|
+
for (const specifier of path4.node.specifiers) {
|
|
164
|
+
if (specifier.type === "ImportSpecifier" && specifier.local.name === componentName) {
|
|
165
|
+
hasCanImport = true;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
JSXElement(path4) {
|
|
171
|
+
const node = path4.node;
|
|
172
|
+
const openingName = node.openingElement.name;
|
|
173
|
+
if (openingName.type === "JSXIdentifier" && openingName.name === componentName) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const attributes = node.openingElement.attributes;
|
|
177
|
+
const permissionAttr = attributes.find((attr) => {
|
|
178
|
+
return attr.type === "JSXAttribute" && attr.name.type === "JSXIdentifier" && attrs.includes(attr.name.name);
|
|
179
|
+
});
|
|
180
|
+
if (!permissionAttr) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const modeAttr = attributes.find((attr) => {
|
|
184
|
+
return attr.type === "JSXAttribute" && attr.name.type === "JSXIdentifier" && attr.name.name === modeAttrName;
|
|
185
|
+
});
|
|
186
|
+
const permissionCode = getJSXAttributeValueCode(code, permissionAttr);
|
|
187
|
+
if (!permissionCode) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const modeCode = modeAttr ? getJSXAttributeValueCode(code, modeAttr) : void 0;
|
|
191
|
+
const permissionLiteral = getStaticStringValue(permissionAttr);
|
|
192
|
+
if (permissionLiteral) {
|
|
193
|
+
const usage = {
|
|
194
|
+
permission: permissionLiteral,
|
|
195
|
+
file: id
|
|
196
|
+
};
|
|
197
|
+
if (permissionAttr.loc?.start.line !== void 0) {
|
|
198
|
+
usage.line = permissionAttr.loc.start.line;
|
|
199
|
+
}
|
|
200
|
+
if (permissionAttr.loc?.start.column !== void 0) {
|
|
201
|
+
usage.column = permissionAttr.loc.start.column;
|
|
202
|
+
}
|
|
203
|
+
usages.push(usage);
|
|
204
|
+
}
|
|
205
|
+
const attrsToRemove = modeAttr ? [permissionAttr, modeAttr] : [permissionAttr];
|
|
206
|
+
if (isInsideCanElement(path4, componentName)) {
|
|
207
|
+
removes.push(...attrsToRemove);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const resolvedModeCode = modeCode ?? void 0;
|
|
211
|
+
wraps.push({
|
|
212
|
+
node,
|
|
213
|
+
permissionCode,
|
|
214
|
+
modeCode: resolvedModeCode,
|
|
215
|
+
attrsToRemove: modeAttr ? [permissionAttr, modeAttr] : [permissionAttr]
|
|
216
|
+
});
|
|
217
|
+
if (!options.transform.allowNested) {
|
|
218
|
+
path4.skip();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
if (removes.length) {
|
|
223
|
+
removes.sort((a, b) => (b.start ?? 0) - (a.start ?? 0)).forEach((attr) => {
|
|
224
|
+
removeJSXAttribute(ms, code, attr);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
if (wraps.length === 0) {
|
|
228
|
+
if (removes.length === 0) {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
code: ms.toString(),
|
|
233
|
+
map: ms.generateMap({
|
|
234
|
+
source: id,
|
|
235
|
+
includeContent: true,
|
|
236
|
+
hires: true
|
|
237
|
+
}),
|
|
238
|
+
usages
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
wraps.sort((a, b) => (b.node.start ?? 0) - (a.node.start ?? 0)).forEach((item) => {
|
|
242
|
+
for (const attr of item.attrsToRemove) {
|
|
243
|
+
removeJSXAttribute(ms, code, attr);
|
|
244
|
+
}
|
|
245
|
+
const start = item.node.start;
|
|
246
|
+
const end = item.node.end;
|
|
247
|
+
if (start == null || end == null) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const modePart = item.modeCode ? ` mode={${item.modeCode}}` : "";
|
|
251
|
+
ms.prependLeft(start, `<${componentName} permission={${item.permissionCode}}${modePart}>`);
|
|
252
|
+
ms.appendRight(end, `</${componentName}>`);
|
|
253
|
+
});
|
|
254
|
+
if (!hasCanImport) {
|
|
255
|
+
const importCode = `import { ${componentName} } from '${options.importFrom}'
|
|
256
|
+
`;
|
|
257
|
+
if (lastImportEnd > 0) {
|
|
258
|
+
ms.appendRight(lastImportEnd, `
|
|
259
|
+
${importCode}`);
|
|
260
|
+
} else {
|
|
261
|
+
ms.prepend(importCode);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return {
|
|
265
|
+
code: ms.toString(),
|
|
266
|
+
map: ms.generateMap({
|
|
267
|
+
source: id,
|
|
268
|
+
includeContent: true,
|
|
269
|
+
hires: true
|
|
270
|
+
}),
|
|
271
|
+
usages
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function getJSXAttributeValueCode(code, attr) {
|
|
275
|
+
const value = attr.value;
|
|
276
|
+
if (!value) {
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
if (value.type === "StringLiteral") {
|
|
280
|
+
return JSON.stringify(value.value);
|
|
281
|
+
}
|
|
282
|
+
if (value.type === "JSXExpressionContainer") {
|
|
283
|
+
const expr = value.expression;
|
|
284
|
+
if (expr.type === "JSXEmptyExpression" || expr.start == null || expr.end == null) {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
return code.slice(expr.start, expr.end);
|
|
288
|
+
}
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
function getStaticStringValue(attr) {
|
|
292
|
+
const value = attr.value;
|
|
293
|
+
if (!value) {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
if (value.type === "StringLiteral") {
|
|
297
|
+
return value.value;
|
|
298
|
+
}
|
|
299
|
+
if (value.type === "JSXExpressionContainer" && value.expression.type === "StringLiteral") {
|
|
300
|
+
return value.expression.value;
|
|
301
|
+
}
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
function removeJSXAttribute(ms, code, attr) {
|
|
305
|
+
if (attr.start == null || attr.end == null) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
let start = attr.start;
|
|
309
|
+
let end = attr.end;
|
|
310
|
+
while (start > 0 && /\s/.test(code.charAt(start - 1))) {
|
|
311
|
+
start--;
|
|
312
|
+
}
|
|
313
|
+
ms.remove(start, end);
|
|
314
|
+
}
|
|
315
|
+
function getJSXName(name) {
|
|
316
|
+
if (name.type === "JSXIdentifier") {
|
|
317
|
+
return name.name;
|
|
318
|
+
}
|
|
319
|
+
if (name.type === "JSXMemberExpression") {
|
|
320
|
+
return `${getJSXName(name.object)}.${getJSXName(name.property)}`;
|
|
321
|
+
}
|
|
322
|
+
return `${name.namespace.name}:${name.name.name}`;
|
|
323
|
+
}
|
|
324
|
+
function isCanElement(node, componentName) {
|
|
325
|
+
const name = getJSXName(node.openingElement.name);
|
|
326
|
+
return name === componentName;
|
|
327
|
+
}
|
|
328
|
+
function isInsideCanElement(path4, componentName) {
|
|
329
|
+
return Boolean(
|
|
330
|
+
path4.findParent((parentPath) => {
|
|
331
|
+
if (!parentPath.isJSXElement()) {
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
return isCanElement(parentPath.node, componentName);
|
|
335
|
+
})
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// src/manifest.ts
|
|
340
|
+
function createManifestJson(state) {
|
|
341
|
+
return JSON.stringify(
|
|
342
|
+
{
|
|
343
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
344
|
+
permissions: state.toManifest()
|
|
345
|
+
},
|
|
346
|
+
null,
|
|
347
|
+
2
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// src/dts.ts
|
|
352
|
+
function createDts(permissions, typeName = "PermissionKey") {
|
|
353
|
+
if (permissions.length === 0) {
|
|
354
|
+
return `export type ${typeName} = string
|
|
355
|
+
`;
|
|
356
|
+
}
|
|
357
|
+
const union = permissions.map((item) => ` | ${JSON.stringify(item)}`).join("\n");
|
|
358
|
+
return [
|
|
359
|
+
"/* eslint-disable */",
|
|
360
|
+
"// This file is generated by vite-plugin-permission.",
|
|
361
|
+
"// Do not edit manually.",
|
|
362
|
+
"",
|
|
363
|
+
`export type ${typeName} =`,
|
|
364
|
+
union,
|
|
365
|
+
""
|
|
366
|
+
].join("\n");
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// src/filter.ts
|
|
370
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
371
|
+
var import_vite = require("vite");
|
|
372
|
+
function createRootFilter(root, include, exclude) {
|
|
373
|
+
return (0, import_vite.createFilter)(normalizePatterns(root, include), normalizePatterns(root, exclude));
|
|
374
|
+
}
|
|
375
|
+
function normalizePatterns(root, patterns) {
|
|
376
|
+
if (!patterns) {
|
|
377
|
+
return void 0;
|
|
378
|
+
}
|
|
379
|
+
const list = Array.isArray(patterns) ? patterns : [patterns];
|
|
380
|
+
return list.map((item) => {
|
|
381
|
+
if (item instanceof RegExp) {
|
|
382
|
+
return item;
|
|
383
|
+
}
|
|
384
|
+
if (import_node_path.default.isAbsolute(item)) {
|
|
385
|
+
return (0, import_vite.normalizePath)(item);
|
|
386
|
+
}
|
|
387
|
+
return (0, import_vite.normalizePath)(import_node_path.default.resolve(root, item));
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// src/rewrite.ts
|
|
392
|
+
var import_promises = __toESM(require("fs/promises"), 1);
|
|
393
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
394
|
+
var import_fast_glob = __toESM(require("fast-glob"), 1);
|
|
395
|
+
var import_vite2 = require("vite");
|
|
396
|
+
async function rewriteSourceFiles(root, options, context) {
|
|
397
|
+
const include = toArray(options.rewrite.include ?? ["src/**/*.{tsx,jsx}"]);
|
|
398
|
+
const exclude = toArray(
|
|
399
|
+
options.rewrite.exclude ?? [
|
|
400
|
+
"**/node_modules/**",
|
|
401
|
+
"**/dist/**",
|
|
402
|
+
"**/.vite/**",
|
|
403
|
+
"**/.turbo/**",
|
|
404
|
+
"**/*.test.*",
|
|
405
|
+
"**/*.spec.*",
|
|
406
|
+
"**/*.stories.*"
|
|
407
|
+
]
|
|
408
|
+
);
|
|
409
|
+
const files = await (0, import_fast_glob.default)(include, {
|
|
410
|
+
cwd: root,
|
|
411
|
+
absolute: true,
|
|
412
|
+
onlyFiles: true,
|
|
413
|
+
ignore: exclude
|
|
414
|
+
});
|
|
415
|
+
let changed = 0;
|
|
416
|
+
const changedFiles = [];
|
|
417
|
+
for (const file of files) {
|
|
418
|
+
const id = (0, import_vite2.normalizePath)(file);
|
|
419
|
+
const code = await import_promises.default.readFile(file, "utf-8");
|
|
420
|
+
if (options.framework !== "react") {
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
const result = transformReactPermission(code, id, options);
|
|
424
|
+
if (!result || result.code === code) {
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
changed++;
|
|
428
|
+
changedFiles.push(import_node_path2.default.relative(root, file));
|
|
429
|
+
if (options.rewrite.write) {
|
|
430
|
+
await import_promises.default.writeFile(file, result.code, "utf-8");
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
const mode = options.rewrite.write ? "write" : "dry-run";
|
|
434
|
+
if (changedFiles.length > 0) {
|
|
435
|
+
context.warn(
|
|
436
|
+
[
|
|
437
|
+
`[vite-plugin-permission] rewrite ${mode}: ${changed} file(s) would change`,
|
|
438
|
+
...changedFiles.map((file) => ` - ${file}`)
|
|
439
|
+
].join("\n")
|
|
440
|
+
);
|
|
441
|
+
} else {
|
|
442
|
+
context.warn(`[vite-plugin-permission] rewrite ${mode}: no files changed`);
|
|
443
|
+
}
|
|
444
|
+
return {
|
|
445
|
+
checked: files.length,
|
|
446
|
+
changed,
|
|
447
|
+
files: changedFiles
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
function toArray(value) {
|
|
451
|
+
return Array.isArray(value) ? value : [value];
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// src/index.ts
|
|
455
|
+
var VIRTUAL_ID = "virtual:permission-manifest";
|
|
456
|
+
var RESOLVED_VIRTUAL_ID = "\0" + VIRTUAL_ID;
|
|
457
|
+
function permissionPlugin(userOptions = {}) {
|
|
458
|
+
const options = resolveOptions(userOptions);
|
|
459
|
+
let config;
|
|
460
|
+
let server;
|
|
461
|
+
let rewriteExecuted = false;
|
|
462
|
+
let transformContext;
|
|
463
|
+
let transformFilter;
|
|
464
|
+
const state = new PermissionState();
|
|
465
|
+
const filter = (0, import_vite3.createFilter)(
|
|
466
|
+
options.include ?? [/\.tsx$/, /\.jsx$/, /\.vue$/],
|
|
467
|
+
options.exclude ?? [/node_modules/, /\.git/]
|
|
468
|
+
);
|
|
469
|
+
return {
|
|
470
|
+
name: "vite-plugin-permission",
|
|
471
|
+
enforce: "pre",
|
|
472
|
+
configResolved(resolvedConfig) {
|
|
473
|
+
config = resolvedConfig;
|
|
474
|
+
transformFilter = createRootFilter(
|
|
475
|
+
config.root,
|
|
476
|
+
options.transform.include ?? options.include ?? ["src/**/*.{tsx,jsx}"],
|
|
477
|
+
options.transform.exclude ?? options.exclude ?? [
|
|
478
|
+
"**/node_modules/**",
|
|
479
|
+
"**/dist/**",
|
|
480
|
+
"**/.vite/**",
|
|
481
|
+
"**/.turbo/**",
|
|
482
|
+
"**/*.test.*",
|
|
483
|
+
"**/*.spec.*",
|
|
484
|
+
"**/*.stories.*"
|
|
485
|
+
]
|
|
486
|
+
);
|
|
487
|
+
},
|
|
488
|
+
async buildStart() {
|
|
489
|
+
state.clear?.();
|
|
490
|
+
if (!options.rewrite.enabled) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
if (options.rewrite.once && rewriteExecuted) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
rewriteExecuted = true;
|
|
497
|
+
await rewriteSourceFiles(config.root, options, this);
|
|
498
|
+
},
|
|
499
|
+
resolveId(id) {
|
|
500
|
+
if (id === VIRTUAL_ID) {
|
|
501
|
+
return RESOLVED_VIRTUAL_ID;
|
|
502
|
+
}
|
|
503
|
+
return null;
|
|
504
|
+
},
|
|
505
|
+
load(id) {
|
|
506
|
+
if (id === RESOLVED_VIRTUAL_ID) {
|
|
507
|
+
return `export default ${JSON.stringify(state.toManifest(), null, 2)}`;
|
|
508
|
+
}
|
|
509
|
+
return null;
|
|
510
|
+
},
|
|
511
|
+
async transform(code, id) {
|
|
512
|
+
transformContext = this;
|
|
513
|
+
if (!filter(id) || !transformFilter?.(id)) {
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
516
|
+
if (!options.transform.enabled) {
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
if (options.framework === "react") {
|
|
520
|
+
const result = transformReactPermission(code, id, options);
|
|
521
|
+
if (!result) {
|
|
522
|
+
state.removeFile(id);
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
state.setFileUsage(id, result.usages);
|
|
526
|
+
validatePermissions(result.usages.map((item) => item.permission));
|
|
527
|
+
return {
|
|
528
|
+
code: result.code,
|
|
529
|
+
map: result.map
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
return null;
|
|
533
|
+
},
|
|
534
|
+
async generateBundle() {
|
|
535
|
+
await emitManifestAndDts(config.root, options, state);
|
|
536
|
+
},
|
|
537
|
+
configureServer(_server) {
|
|
538
|
+
server = _server;
|
|
539
|
+
server.middlewares.use("/__permission/manifest", async (_req, res) => {
|
|
540
|
+
res.setHeader("Content-Type", "application/json");
|
|
541
|
+
res.end(JSON.stringify(state.toManifest(), null, 2));
|
|
542
|
+
});
|
|
543
|
+
},
|
|
544
|
+
async handleHotUpdate(ctx) {
|
|
545
|
+
if (!filter(ctx.file)) {
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
state.removeFile(ctx.file);
|
|
549
|
+
ctx.server.ws.send({
|
|
550
|
+
type: "custom",
|
|
551
|
+
event: "permission-manifest-update",
|
|
552
|
+
data: state.toManifest()
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
function validatePermissions(usedPermissions) {
|
|
557
|
+
if (!options.validate.enabled) {
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
if (options.validate.unknownPermission === "off") {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
const knownSet = new Set(options.validate.permissions);
|
|
564
|
+
const unknown = usedPermissions.filter((item) => !knownSet.has(item));
|
|
565
|
+
if (unknown.length === 0) {
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
const message = `[vite-plugin-permission] Unknown permissions: ${unknown.join(", ")}`;
|
|
569
|
+
if (options.validate.unknownPermission === "error") {
|
|
570
|
+
throw new Error(message);
|
|
571
|
+
}
|
|
572
|
+
transformContext?.warn(message);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
async function emitManifestAndDts(root, options, state) {
|
|
576
|
+
if (options.manifest.enabled) {
|
|
577
|
+
const manifestPath = import_node_path3.default.resolve(root, options.manifest.output);
|
|
578
|
+
await import_promises2.default.mkdir(import_node_path3.default.dirname(manifestPath), { recursive: true });
|
|
579
|
+
await import_promises2.default.writeFile(manifestPath, createManifestJson(state), "utf-8");
|
|
580
|
+
}
|
|
581
|
+
if (options.dts.enabled) {
|
|
582
|
+
const dtsPath = import_node_path3.default.resolve(root, options.dts.output);
|
|
583
|
+
await import_promises2.default.mkdir(import_node_path3.default.dirname(dtsPath), { recursive: true });
|
|
584
|
+
await import_promises2.default.writeFile(
|
|
585
|
+
dtsPath,
|
|
586
|
+
createDts(state.getUsedPermissions(), options.dts.typeName),
|
|
587
|
+
"utf-8"
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/options.ts","../src/state.ts","../src/transformReact.ts","../src/manifest.ts","../src/dts.ts","../src/filter.ts","../src/rewrite.ts"],"sourcesContent":["// src/index.ts\nimport type { Plugin, ResolvedConfig, ViteDevServer } from 'vite'\nimport { createFilter } from 'vite'\nimport path from 'node:path'\nimport fs from 'node:fs/promises'\nimport { resolveOptions, type PermissionPluginOptions } from './options'\nimport { PermissionState } from './state'\nimport { transformReactPermission } from './transformReact'\nimport { createManifestJson } from './manifest'\nimport { createDts } from './dts'\nimport { createRootFilter } from './filter'\nimport { rewriteSourceFiles } from './rewrite'\n\nconst VIRTUAL_ID = 'virtual:permission-manifest'\nconst RESOLVED_VIRTUAL_ID = '\\0' + VIRTUAL_ID\n\nexport default function permissionPlugin(userOptions: PermissionPluginOptions = {}): Plugin {\n const options = resolveOptions(userOptions)\n\n let config: ResolvedConfig\n let server: ViteDevServer | undefined\n let rewriteExecuted = false\n let transformContext: { warn: (message: string) => void } | undefined\n let transformFilter: ReturnType<typeof createRootFilter> | undefined\n const state = new PermissionState()\n\n const filter = createFilter(\n options.include ?? [/\\.tsx$/, /\\.jsx$/, /\\.vue$/],\n options.exclude ?? [/node_modules/, /\\.git/]\n )\n return {\n name: 'vite-plugin-permission',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n\n transformFilter = createRootFilter(\n config.root,\n options.transform.include ?? options.include ?? ['src/**/*.{tsx,jsx}'],\n options.transform.exclude ??\n options.exclude ?? [\n '**/node_modules/**',\n '**/dist/**',\n '**/.vite/**',\n '**/.turbo/**',\n '**/*.test.*',\n '**/*.spec.*',\n '**/*.stories.*'\n ]\n )\n },\n\n async buildStart() {\n state.clear?.()\n if (!options.rewrite.enabled) {\n return\n }\n\n if (options.rewrite.once && rewriteExecuted) {\n return\n }\n\n rewriteExecuted = true\n\n await rewriteSourceFiles(config.root, options, this)\n },\n\n resolveId(id) {\n if (id === VIRTUAL_ID) {\n return RESOLVED_VIRTUAL_ID\n }\n\n return null\n },\n\n load(id) {\n if (id === RESOLVED_VIRTUAL_ID) {\n return `export default ${JSON.stringify(state.toManifest(), null, 2)}`\n }\n\n return null\n },\n\n async transform(code, id) {\n transformContext = this\n\n if (!filter(id) || !transformFilter?.(id)) {\n return null\n }\n\n if (!options.transform.enabled) {\n return null\n }\n\n if (options.framework === 'react') {\n const result = transformReactPermission(code, id, options)\n\n if (!result) {\n state.removeFile(id)\n return null\n }\n\n state.setFileUsage(id, result.usages)\n\n validatePermissions(result.usages.map((item) => item.permission))\n\n return {\n code: result.code,\n map: result.map\n }\n }\n\n // Vue MVP 阶段建议只扫描,不强行 template 改写\n return null\n },\n\n async generateBundle() {\n await emitManifestAndDts(config.root, options, state)\n },\n\n configureServer(_server) {\n server = _server\n\n server.middlewares.use('/__permission/manifest', async (_req, res) => {\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify(state.toManifest(), null, 2))\n })\n },\n\n async handleHotUpdate(ctx) {\n if (!filter(ctx.file)) {\n return\n }\n\n // 文件变化后,先删除旧记录,等待下一次 transform 写入新记录\n state.removeFile(ctx.file)\n\n // 通知前端或 devtools 权限 manifest 变了\n ctx.server.ws.send({\n type: 'custom',\n event: 'permission-manifest-update',\n data: state.toManifest()\n })\n }\n }\n\n function validatePermissions(usedPermissions: string[]) {\n if (!options.validate.enabled) {\n return\n }\n\n if (options.validate.unknownPermission === 'off') {\n return\n }\n\n const knownSet = new Set(options.validate.permissions)\n\n const unknown = usedPermissions.filter((item) => !knownSet.has(item))\n\n if (unknown.length === 0) {\n return\n }\n\n const message = `[vite-plugin-permission] Unknown permissions: ${unknown.join(', ')}`\n\n if (options.validate.unknownPermission === 'error') {\n throw new Error(message)\n }\n\n transformContext?.warn(message)\n }\n}\n\nasync function emitManifestAndDts(\n root: string,\n options: ReturnType<typeof resolveOptions>,\n state: PermissionState\n) {\n if (options.manifest.enabled) {\n const manifestPath = path.resolve(root, options.manifest.output)\n await fs.mkdir(path.dirname(manifestPath), { recursive: true })\n await fs.writeFile(manifestPath, createManifestJson(state), 'utf-8')\n }\n\n if (options.dts.enabled) {\n const dtsPath = path.resolve(root, options.dts.output)\n await fs.mkdir(path.dirname(dtsPath), { recursive: true })\n await fs.writeFile(\n dtsPath,\n createDts(state.getUsedPermissions(), options.dts.typeName),\n 'utf-8'\n )\n }\n}\n","// src/options.ts\nimport { z } from 'zod'\n\nconst FilterPatternSchema = z.custom<string | RegExp | Array<string | RegExp>>()\n\nconst GlobPatternSchema = z.union([z.string(), z.array(z.string())])\n\nexport const PluginOptionsSchema = z.object({\n framework: z.enum(['react', 'vue']).default('react'),\n\n componentName: z.string().default('Can'),\n\n importFrom: z.string().default('@eycraf/permission-kit-react'),\n\n /**\n * 全局 include/exclude。\n * transform/rewrite 没单独配置时,会回退使用这里。\n */\n include: FilterPatternSchema.optional(),\n exclude: FilterPatternSchema.optional(),\n\n transform: z\n .object({\n enabled: z.boolean().default(true),\n include: FilterPatternSchema.optional(),\n exclude: FilterPatternSchema.optional(),\n attributes: z.array(z.string()).default(['permission']),\n modeAttribute: z.string().default('permissionMode'),\n strategyAttribute: z.string().default('permissionStrategy'),\n allowNested: z.boolean().default(false)\n })\n .default({}),\n\n rewrite: z\n .object({\n enabled: z.boolean().default(false),\n\n /**\n * false = dry-run,只打印会修改哪些文件\n * true = 真实写回源文件\n */\n write: z.boolean().default(false),\n\n include: GlobPatternSchema.optional(),\n exclude: GlobPatternSchema.optional(),\n\n /**\n * rewrite 只在 serve/build 启动时跑一次。\n * 默认 true,避免 HMR 时反复改文件。\n */\n once: z.boolean().default(true)\n })\n .default({}),\n\n manifest: z\n .object({\n enabled: z.boolean().default(true),\n output: z.string().default('src/generated/permission-manifest.json')\n })\n .default({}),\n\n dts: z\n .object({\n enabled: z.boolean().default(true),\n output: z.string().default('src/generated/permission.d.ts'),\n typeName: z.string().default('PermissionKey')\n })\n .default({}),\n\n validate: z\n .object({\n enabled: z.boolean().default(false),\n permissions: z.array(z.string()).default([]),\n unknownPermission: z.enum(['off', 'warn', 'error']).default('warn')\n })\n .default({})\n})\n\nexport type PermissionPluginOptions = z.input<typeof PluginOptionsSchema>\nexport type NormalizedPermissionPluginOptions = z.output<typeof PluginOptionsSchema>\n\nexport function resolveOptions(options: PermissionPluginOptions) {\n return PluginOptionsSchema.parse(options)\n}\n","// src/state.ts\nexport type PermissionUsage = {\n permission: string\n file: string\n line?: number\n column?: number\n}\n\nexport class PermissionState {\n private fileUsageMap = new Map<string, PermissionUsage[]>()\n\n clear() {\n this.fileUsageMap.clear()\n }\n\n setFileUsage(file: string, usages: PermissionUsage[]) {\n this.fileUsageMap.set(file, usages)\n }\n\n removeFile(file: string) {\n this.fileUsageMap.delete(file)\n }\n\n getAllUsages() {\n return [...this.fileUsageMap.values()].flat()\n }\n\n getUsedPermissions() {\n return [...new Set(this.getAllUsages().map((item) => item.permission))].sort()\n }\n\n toManifest() {\n const result: Record<\n string,\n Array<{\n file: string\n line?: number\n column?: number\n }>\n > = {}\n\n for (const usage of this.getAllUsages()) {\n const items = (result[usage.permission] ??= [])\n const entry: {\n file: string\n line?: number\n column?: number\n } = {\n file: usage.file\n }\n\n if (usage.line !== undefined) {\n entry.line = usage.line\n }\n\n if (usage.column !== undefined) {\n entry.column = usage.column\n }\n\n items.push(entry)\n }\n\n return result\n }\n}\n","// src/transformReact.ts\nimport { parse } from '@babel/parser'\nimport traverse, { type NodePath } from '@babel/traverse'\nimport type {\n JSXAttribute,\n JSXElement,\n JSXIdentifier,\n JSXMemberExpression,\n JSXNamespacedName\n} from '@babel/types'\nimport MagicString from 'magic-string'\nimport type { NormalizedPermissionPluginOptions } from './options'\nimport type { PermissionUsage } from './state'\n\ntype TransformResult = {\n code: string\n map: ReturnType<MagicString['generateMap']>\n usages: PermissionUsage[]\n}\n\ntype PendingWrap = {\n node: JSXElement\n permissionCode: string\n modeCode: string | undefined\n attrsToRemove: JSXAttribute[]\n}\n\nexport function transformReactPermission(\n code: string,\n id: string,\n options: NormalizedPermissionPluginOptions\n): TransformResult | null {\n if (!/\\.[jt]sx$/.test(id)) {\n return null\n }\n\n const attrs = options.transform.attributes\n const modeAttrName = options.transform.modeAttribute\n const componentName = options.componentName\n const ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n errorRecovery: true\n })\n\n const ms = new MagicString(code)\n const wraps: PendingWrap[] = []\n const usages: PermissionUsage[] = []\n const removes: JSXAttribute[] = []\n\n let hasCanImport = false\n let lastImportEnd = 0\n\n traverse(ast, {\n ImportDeclaration(path) {\n lastImportEnd = Math.max(lastImportEnd, path.node.end ?? 0)\n\n if (path.node.source.value === options.importFrom) {\n for (const specifier of path.node.specifiers) {\n if (specifier.type === 'ImportSpecifier' && specifier.local.name === componentName) {\n hasCanImport = true\n }\n }\n }\n },\n\n JSXElement(path) {\n const node = path.node\n\n // 避免 <Can permission=\"x\"> 被再次包裹\n const openingName = node.openingElement.name\n if (openingName.type === 'JSXIdentifier' && openingName.name === componentName) {\n return\n }\n\n const attributes = node.openingElement.attributes\n const permissionAttr = attributes.find((attr): attr is JSXAttribute => {\n return (\n attr.type === 'JSXAttribute' &&\n attr.name.type === 'JSXIdentifier' &&\n attrs.includes(attr.name.name)\n )\n })\n\n if (!permissionAttr) {\n return\n }\n\n const modeAttr = attributes.find((attr): attr is JSXAttribute => {\n return (\n attr.type === 'JSXAttribute' &&\n attr.name.type === 'JSXIdentifier' &&\n attr.name.name === modeAttrName\n )\n })\n\n const permissionCode = getJSXAttributeValueCode(code, permissionAttr)\n if (!permissionCode) {\n return\n }\n\n const modeCode = modeAttr ? getJSXAttributeValueCode(code, modeAttr) : undefined\n\n const permissionLiteral = getStaticStringValue(permissionAttr)\n if (permissionLiteral) {\n const usage: PermissionUsage = {\n permission: permissionLiteral,\n file: id\n }\n\n if (permissionAttr.loc?.start.line !== undefined) {\n usage.line = permissionAttr.loc.start.line\n }\n\n if (permissionAttr.loc?.start.column !== undefined) {\n usage.column = permissionAttr.loc.start.column\n }\n\n usages.push(usage)\n }\n\n const attrsToRemove = modeAttr ? [permissionAttr, modeAttr] : [permissionAttr]\n\n // 2. 已经在 <Can> 内部:只删除 permission 属性,不再包裹\n if (isInsideCanElement(path, componentName)) {\n removes.push(...attrsToRemove)\n return\n }\n\n const resolvedModeCode = modeCode ?? undefined\n\n wraps.push({\n node,\n permissionCode,\n modeCode: resolvedModeCode,\n attrsToRemove: modeAttr ? [permissionAttr, modeAttr] : [permissionAttr]\n })\n\n // 4. 可选:如果当前元素已经要被包裹,可以跳过它的子节点\n // 这样可以避免父子都有 permission 时产生嵌套。\n if (!options.transform.allowNested) {\n path.skip()\n }\n }\n })\n\n if (removes.length) {\n // 先删除在 <Can> 内部的冗余 permission 属性\n removes\n .sort((a, b) => (b.start ?? 0) - (a.start ?? 0))\n .forEach((attr) => {\n removeJSXAttribute(ms, code, attr)\n })\n }\n\n if (wraps.length === 0) {\n if (removes.length === 0) {\n return null\n }\n\n return {\n code: ms.toString(),\n map: ms.generateMap({\n source: id,\n includeContent: true,\n hires: true\n }),\n usages\n }\n }\n\n // 倒序修改,避免位置偏移\n wraps\n .sort((a, b) => (b.node.start ?? 0) - (a.node.start ?? 0))\n .forEach((item) => {\n for (const attr of item.attrsToRemove) {\n removeJSXAttribute(ms, code, attr)\n }\n\n const start = item.node.start\n const end = item.node.end\n\n if (start == null || end == null) {\n return\n }\n\n const modePart = item.modeCode ? ` mode={${item.modeCode}}` : ''\n\n ms.prependLeft(start, `<${componentName} permission={${item.permissionCode}}${modePart}>`)\n\n ms.appendRight(end, `</${componentName}>`)\n })\n\n if (!hasCanImport) {\n const importCode = `import { ${componentName} } from '${options.importFrom}'\\n`\n\n if (lastImportEnd > 0) {\n ms.appendRight(lastImportEnd, `\\n${importCode}`)\n } else {\n ms.prepend(importCode)\n }\n }\n\n return {\n code: ms.toString(),\n map: ms.generateMap({\n source: id,\n includeContent: true,\n hires: true\n }),\n usages\n }\n}\n\nfunction getJSXAttributeValueCode(code: string, attr: JSXAttribute): string | null {\n const value = attr.value\n\n if (!value) {\n return null\n }\n\n if (value.type === 'StringLiteral') {\n return JSON.stringify(value.value)\n }\n\n if (value.type === 'JSXExpressionContainer') {\n const expr = value.expression\n\n if (expr.type === 'JSXEmptyExpression' || expr.start == null || expr.end == null) {\n return null\n }\n\n return code.slice(expr.start, expr.end)\n }\n\n return null\n}\n\nfunction getStaticStringValue(attr: JSXAttribute): string | null {\n const value = attr.value\n\n if (!value) {\n return null\n }\n\n if (value.type === 'StringLiteral') {\n return value.value\n }\n\n if (value.type === 'JSXExpressionContainer' && value.expression.type === 'StringLiteral') {\n return value.expression.value\n }\n\n return null\n}\n\nfunction removeJSXAttribute(ms: MagicString, code: string, attr: JSXAttribute) {\n if (attr.start == null || attr.end == null) {\n return\n }\n\n let start = attr.start\n let end = attr.end\n\n // 顺手删除属性前面的空格,避免留下多余空白\n while (start > 0 && /\\s/.test(code.charAt(start - 1))) {\n start--\n }\n\n ms.remove(start, end)\n}\n\nfunction getJSXName(name: JSXIdentifier | JSXMemberExpression | JSXNamespacedName): string {\n if (name.type === 'JSXIdentifier') {\n return name.name\n }\n\n if (name.type === 'JSXMemberExpression') {\n return `${getJSXName(name.object)}.${getJSXName(name.property)}`\n }\n\n return `${name.namespace.name}:${name.name.name}`\n}\n\nfunction isCanElement(node: JSXElement, componentName: string) {\n const name = getJSXName(node.openingElement.name)\n\n return name === componentName\n}\n\nfunction isInsideCanElement(path: NodePath<JSXElement>, componentName: string) {\n return Boolean(\n path.findParent((parentPath) => {\n if (!parentPath.isJSXElement()) {\n return false\n }\n\n return isCanElement(parentPath.node, componentName)\n })\n )\n}\n","// src/manifest.ts\nimport type { PermissionState } from './state'\n\nexport function createManifestJson(state: PermissionState) {\n return JSON.stringify(\n {\n generatedAt: new Date().toISOString(),\n permissions: state.toManifest()\n },\n null,\n 2\n )\n}\n","// src/dts.ts\nexport function createDts(permissions: string[], typeName = 'PermissionKey') {\n if (permissions.length === 0) {\n return `export type ${typeName} = string\\n`\n }\n\n const union = permissions.map((item) => ` | ${JSON.stringify(item)}`).join('\\n')\n\n return [\n '/* eslint-disable */',\n '// This file is generated by vite-plugin-permission.',\n '// Do not edit manually.',\n '',\n `export type ${typeName} =`,\n union,\n ''\n ].join('\\n')\n}\n","// packages/vite-plugin/src/filter.ts\nimport path from 'node:path'\nimport { createFilter, normalizePath } from 'vite'\n\ntype Pattern = string | RegExp | Array<string | RegExp> | undefined\n\nexport function createRootFilter(root: string, include: Pattern, exclude: Pattern) {\n return createFilter(normalizePatterns(root, include), normalizePatterns(root, exclude))\n}\n\nfunction normalizePatterns(root: string, patterns: Pattern) {\n if (!patterns) {\n return undefined\n }\n\n const list = Array.isArray(patterns) ? patterns : [patterns]\n\n return list.map((item) => {\n if (item instanceof RegExp) {\n return item\n }\n\n // 绝对路径 glob:只做 POSIX 规范化\n if (path.isAbsolute(item)) {\n return normalizePath(item)\n }\n\n // 相对路径 glob:基于 Vite root 转绝对\n return normalizePath(path.resolve(root, item))\n })\n}\n\nexport function cleanId(id: string) {\n return normalizePath(id.split('?')[0] ?? id)\n}\n","// packages/vite-plugin/src/rewrite.ts\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport fg from 'fast-glob'\nimport { normalizePath } from 'vite'\nimport type { NormalizedPermissionPluginOptions } from './options'\nimport { transformReactPermission } from './transformReact'\n\ntype LoggerLike = {\n warn(message: string): void\n}\n\nexport type RewriteResult = {\n checked: number\n changed: number\n files: string[]\n}\n\nexport async function rewriteSourceFiles(\n root: string,\n options: NormalizedPermissionPluginOptions,\n context: LoggerLike\n): Promise<RewriteResult> {\n const include = toArray(options.rewrite.include ?? ['src/**/*.{tsx,jsx}'])\n\n const exclude = toArray(\n options.rewrite.exclude ?? [\n '**/node_modules/**',\n '**/dist/**',\n '**/.vite/**',\n '**/.turbo/**',\n '**/*.test.*',\n '**/*.spec.*',\n '**/*.stories.*'\n ]\n )\n\n const files = await fg(include, {\n cwd: root,\n absolute: true,\n onlyFiles: true,\n ignore: exclude\n })\n\n let changed = 0\n const changedFiles: string[] = []\n\n for (const file of files) {\n const id = normalizePath(file)\n const code = await fs.readFile(file, 'utf-8')\n\n if (options.framework !== 'react') {\n continue\n }\n\n const result = transformReactPermission(code, id, options)\n\n if (!result || result.code === code) {\n continue\n }\n\n changed++\n changedFiles.push(path.relative(root, file))\n\n if (options.rewrite.write) {\n await fs.writeFile(file, result.code, 'utf-8')\n }\n }\n\n const mode = options.rewrite.write ? 'write' : 'dry-run'\n\n if (changedFiles.length > 0) {\n context.warn(\n [\n `[vite-plugin-permission] rewrite ${mode}: ${changed} file(s) would change`,\n ...changedFiles.map((file) => ` - ${file}`)\n ].join('\\n')\n )\n } else {\n context.warn(`[vite-plugin-permission] rewrite ${mode}: no files changed`)\n }\n\n return {\n checked: files.length,\n changed,\n files: changedFiles\n }\n}\n\nfunction toArray<T>(value: T | T[]): T[] {\n return Array.isArray(value) ? value : [value]\n}\n"],"mappings":"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","names":["import_vite","import_node_path","import_promises","MagicString","traverse","path","path","import_node_path","import_vite","fg","fs","path","path","fs"]}
|