yapi-to-ts

yapi to ts

  1. // ==UserScript==
  2. // @name yapi-to-ts
  3. // @namespace http://172.16.101.32:7700/project/*/interface/api/*
  4. // @version 0.3.3
  5. // @author monkey
  6. // @description yapi to ts
  7. // @license MIT
  8. // @icon https://vitejs.dev/logo.svg
  9. // @match http://172.16.101.32:7700/project/*/interface/api/*
  10. // @match http://172.16.101.32:7700/project/*/interface/api
  11. // @match https://yapi.doveaz.xyz:1443/project/*/interface/api
  12. // @match https://yapi.doveaz.xyz:1443/project/*/interface/api
  13. // @require https://cdn.jsdelivr.net/npm/json-schema-to-typescript-for-browser@11.0.3/dist/bundle.min.js
  14. // @require https://cdn.jsdelivr.net/npm/@highlightjs/cdn-assets@11.10.0/highlight.min.js
  15. // @require https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js
  16. // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js
  17. // @require https://cdn.jsdelivr.net/npm/vue@3.4.38/dist/vue.global.prod.js
  18. // @require data:application/javascript,%3Bwindow.Vue%3DVue%3B
  19. // @require https://cdn.jsdelivr.net/npm/element-plus@2.5.1/dist/index.full.min.js
  20. // @resource element-plus/dist/index.css https://cdn.jsdelivr.net/npm/element-plus@2.5.1/dist/index.css
  21. // @grant GM_addStyle
  22. // @grant GM_getResourceText
  23. // @grant GM_setClipboard
  24. // ==/UserScript==
  25.  
  26. (t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const e=document.createElement("style");e.textContent=t,document.head.append(e)})(" body .el-notification__content p{white-space:pre}body .el-notification{width:430px!important}body .interface-title{display:flex;align-items:center}body .component-label>div{display:flex;align-items:center;justify-content:space-between}body .interface-title+button+div>div{display:flex;align-items:center;justify-content:space-between}body .ant-layout-sider{position:sticky;top:30px}.settings[data-v-7a7beb5b]{display:flex;padding-left:15px}.settings[data-v-7a7beb5b]>*[data-v-7a7beb5b]{flex-shrink:0}.settings[data-v-7a7beb5b]>.el-input[data-v-7a7beb5b]{margin-left:15px} ");
  27.  
  28. (function (ElementPlus, vue) {
  29. 'use strict';
  30.  
  31. var _GM_addStyle = /* @__PURE__ */ (() => typeof GM_addStyle != "undefined" ? GM_addStyle : void 0)();
  32. var _GM_setClipboard = /* @__PURE__ */ (() => typeof GM_setClipboard != "undefined" ? GM_setClipboard : void 0)();
  33. const jsttCompileConfigOptions = {
  34. bannerComment: "",
  35. format: false,
  36. style: {
  37. bracketSpacing: false,
  38. printWidth: 120,
  39. semi: true,
  40. singleQuote: true,
  41. tabWidth: 2,
  42. trailingComma: "none",
  43. useTabs: false
  44. },
  45. strictIndexSignatures: true
  46. };
  47. function compileJSONSchema2TS(schema, name) {
  48. return jstt.compile(schema, name, jsttCompileConfigOptions).then((code) => formatComment2SingleLine(code)).catch((err) => console.error(err));
  49. }
  50. function formatComment2SingleLine(content = "") {
  51. return content.replace(
  52. /\/\*([^/]*)\*\//gm,
  53. (_2, p1) => `/** ${p1.replace(/[*\s\n]/gm, "")} */`
  54. ).replaceAll("string &", "");
  55. }
  56. const getDetail = (id) => {
  57. return fetch(`http://172.16.101.32:7700/api/interface/get?id=${id}`).then((res) => res.json()).then((res) => {
  58. return res.data;
  59. });
  60. };
  61. const fetchData = () => {
  62. if (!location.href.includes("api/cat_")) {
  63. return getDetail(location.href.match(/api\/(\d+)/)[1]);
  64. } else {
  65. return Promise.reject(new Error("请在接口详情页使用"));
  66. }
  67. };
  68. function copy(text) {
  69. text = text.replaceAll("number & string", "number");
  70. text = text.replaceAll("boolean & string", "boolean");
  71. ElementPlus.ElNotification({
  72. title: "复制成功",
  73. dangerouslyUseHTMLString: true,
  74. message: hljs.highlight(text, { language: "typescript" }).value,
  75. type: "success"
  76. });
  77. _GM_setClipboard(text);
  78. }
  79. function requestName(item) {
  80. return _.camelCase(
  81. item.path.replace(/\{(.*)\}$/, "_by_$1").replaceAll("/", "_").replace(/^_/, "").replace(/_$/, "")
  82. );
  83. }
  84. function paramsDto(item) {
  85. return _.upperFirst(requestName(item)) + "ParamsDto";
  86. }
  87. function dataDto(item) {
  88. return _.upperFirst(requestName(item)) + "DataDto";
  89. }
  90. function convertType(type) {
  91. return {
  92. int32: "number",
  93. int64: "number"
  94. }[type] || type || "any";
  95. }
  96. function isCate() {
  97. const matched = location.href.match(/cat_(\d+)$/);
  98. return !!matched;
  99. }
  100. function isAll() {
  101. const matched = location.href.match(/interface\/api$/);
  102. return !!matched;
  103. }
  104. async function copyRequest(item, noReturn = false) {
  105. const data = item || await fetchData();
  106. const name = requestName(data);
  107. let arg = "";
  108. let argType = "";
  109. if (_.size(data.req_query)) {
  110. arg = "params";
  111. argType = ": " + (settingsVm.anyType ? "any" : paramsDto(data));
  112. }
  113. if (_.size(data.req_body_other)) {
  114. arg = "data";
  115. argType = ": " + (settingsVm.anyType ? "any" : dataDto(data));
  116. }
  117. let pathArg = "";
  118. if (_.size(data.req_params)) {
  119. data.req_params.forEach((item2) => {
  120. pathArg += `${item2.name}: ${convertType(item2.type)},`;
  121. });
  122. }
  123. const responseDto = settingsVm.anyType || !data.res_body ? "any" : _.upperFirst(name) + "ResponseDto";
  124. let text = `
  125. // ${data.title} 作者: ${data.username} http://172.16.101.32:7700/project/${data.project_id}/interface/api/${data._id}
  126. `;
  127. const nativeAxios = localStorage.getItem(window.projectId + "-axios-native") === "true";
  128. const arrowFunction = localStorage.getItem(window.projectId + "-arrow-function") === "true";
  129. const requestFunctionName = localStorage.getItem(window.projectId + "-request-function-name") || "axiosRequest";
  130. const extractData = localStorage.getItem(window.projectId + "-extract-data") === "true";
  131. const extractDataString = extractData ? `['data']` : "";
  132. const functionDeclareText = arrowFunction ? `${name} : (${pathArg}${arg}${argType}): Promise<${responseDto}${extractDataString}> => ` : `export function ${name}(${pathArg}${arg}${argType}): Promise<${responseDto}${extractDataString}>`;
  133. const arrowPatternStart = !arrowFunction ? `{
  134. return` : "";
  135. const arrowPatternEnd = !arrowFunction ? `}` : "";
  136. if (nativeAxios) {
  137. text += `${functionDeclareText} ${arrowPatternStart} ${requestFunctionName}({
  138. url: \`${data.path.replaceAll("{", "${")}\`,
  139. method: '${_.toLower(data.method)}',
  140. ${arg}
  141. })
  142. ${arrowPatternEnd}`;
  143. } else {
  144. text += `${functionDeclareText} ${arrowPatternStart} ${requestFunctionName}.${_.toLower(data.method)}({
  145. url: \`${data.path.replaceAll("{", "${")}\`,
  146. ${arg}
  147. })
  148. ${arrowPatternEnd}`;
  149. }
  150. if (item) {
  151. return text;
  152. } else {
  153. copy(text);
  154. }
  155. }
  156. async function copyGroupRequest() {
  157. const arrowFunction = localStorage.getItem(window.projectId + "-arrow-function") === "true";
  158. const href = location.href;
  159. const matched = href.match(/cat_(\d+)$/);
  160. const id = matched == null ? void 0 : matched[1];
  161. const list = await fetch(
  162. id ? `http://172.16.101.32:7700/api/interface/list_cat?page=1&limit=9999&catid=${id}` : `http://172.16.101.32:7700/api/interface/list?page=1&limit=9999&project_id=${projectId}`
  163. ).then((res) => res.json()).then((res) => {
  164. return res.data.list;
  165. });
  166. let text = "";
  167. const resList = await Promise.all(list.map((item) => getDetail(item._id)));
  168. for (const data of resList) {
  169. text += await copyRequest(data) + (arrowFunction ? "," : "");
  170. }
  171. copy(text);
  172. }
  173. async function copyInterface(item) {
  174. const data = item || await fetchData();
  175. const name = requestName(data);
  176. const noExport = localStorage.getItem(window.projectId + "-no-export") === "true";
  177. let text = `// ${data.title} 作者: ${data.username} http://172.16.101.32:7700/project/${data.project_id}/interface/api/${data._id}`;
  178. let text1 = "";
  179. let text2 = "";
  180. if (data.req_query && data.req_query.length) {
  181. const interfaceString = data.req_query.map(
  182. (item2) => `/** ${item2.desc} **/
  183. ${item2.name}${item2.required === "1" ? "" : "?"}: string`
  184. ).join(";");
  185. text2 += `export interface ${paramsDto(data)} {
  186. ${interfaceString}
  187. }`;
  188. }
  189. if (data.req_body_other || data.req_body) {
  190. text2 += await compileJSONSchema2TS(
  191. JSON.parse(data.req_body_other || data.req_body),
  192. dataDto(data)
  193. );
  194. }
  195. let text3 = "";
  196. if (data.res_body) {
  197. text3 += await compileJSONSchema2TS(
  198. JSON.parse(data.res_body),
  199. `${_.upperFirst(name)}ResponseDto`
  200. );
  201. }
  202. text3 = text3.replaceAll("?: ", ": ");
  203. if (noExport) {
  204. text2 = text2.replace("export ", "");
  205. text3 = text3.replace("export ", "");
  206. }
  207. const result = _.compact([text, text1, text2, text3]).join("\n");
  208. if (item) {
  209. return result;
  210. } else {
  211. copy(result);
  212. }
  213. }
  214. async function copyGroupInterface(event) {
  215. const href = location.href;
  216. const matched = href.match(/cat_(\d+)$/);
  217. const id = matched == null ? void 0 : matched[1];
  218. const list = await fetch(
  219. id ? `http://172.16.101.32:7700/api/interface/list_cat?page=1&limit=9999&catid=${id}` : `http://172.16.101.32:7700/api/interface/list?page=1&limit=9999&project_id=${projectId}`
  220. ).then((res) => res.json()).then((res) => {
  221. return res.data.list;
  222. });
  223. let text = "";
  224. const resList = await Promise.all(list.map((item) => getDetail(item._id)));
  225. for (const data of resList) {
  226. text += await copyInterface(data);
  227. }
  228. copy(text);
  229. }
  230. async function copyResponseParameterInterface() {
  231. const data = await fetchData();
  232. const text = ``;
  233. const name = requestName(data);
  234. const noExport = localStorage.getItem(window.projectId + "-no-export") === "true";
  235. let content = await compileJSONSchema2TS(
  236. JSON.parse(data.res_body),
  237. _.upperFirst(name) + "ResponseDto"
  238. );
  239. content = content.replaceAll("?: ", ": ");
  240. if (noExport) {
  241. content = content.replace("export ", "");
  242. }
  243. copy(text + content);
  244. }
  245. async function copyBodyParameterInterface() {
  246. const data = await fetchData();
  247. const text = ``;
  248. requestName(data);
  249. const noExport = localStorage.getItem(window.projectId + "-no-export") === "true";
  250. let content = await compileJSONSchema2TS(
  251. JSON.parse(data.req_body_other),
  252. dataDto(data)
  253. );
  254. if (noExport) {
  255. content = content.replace("export ", "");
  256. }
  257. copy(text + content);
  258. }
  259. const cssLoader = (e) => {
  260. const t = GM_getResourceText(e);
  261. return GM_addStyle(t), t;
  262. };
  263. cssLoader("element-plus/dist/index.css");
  264. function tryOnScopeDispose(fn) {
  265. if (vue.getCurrentScope()) {
  266. vue.onScopeDispose(fn);
  267. return true;
  268. }
  269. return false;
  270. }
  271. function toValue(r) {
  272. return typeof r === "function" ? r() : vue.unref(r);
  273. }
  274. const isClient = typeof window !== "undefined" && typeof document !== "undefined";
  275. typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
  276. const toString = Object.prototype.toString;
  277. const isObject = (val) => toString.call(val) === "[object Object]";
  278. const noop = () => {
  279. };
  280. function createFilterWrapper(filter, fn) {
  281. function wrapper(...args) {
  282. return new Promise((resolve, reject) => {
  283. Promise.resolve(filter(() => fn.apply(this, args), { fn, thisArg: this, args })).then(resolve).catch(reject);
  284. });
  285. }
  286. return wrapper;
  287. }
  288. const bypassFilter = (invoke) => {
  289. return invoke();
  290. };
  291. function pausableFilter(extendFilter = bypassFilter) {
  292. const isActive = vue.ref(true);
  293. function pause() {
  294. isActive.value = false;
  295. }
  296. function resume() {
  297. isActive.value = true;
  298. }
  299. const eventFilter = (...args) => {
  300. if (isActive.value)
  301. extendFilter(...args);
  302. };
  303. return { isActive: vue.readonly(isActive), pause, resume, eventFilter };
  304. }
  305. function getLifeCycleTarget(target) {
  306. return target || vue.getCurrentInstance();
  307. }
  308. function watchWithFilter(source, cb, options = {}) {
  309. const {
  310. eventFilter = bypassFilter,
  311. ...watchOptions
  312. } = options;
  313. return vue.watch(
  314. source,
  315. createFilterWrapper(
  316. eventFilter,
  317. cb
  318. ),
  319. watchOptions
  320. );
  321. }
  322. function watchPausable(source, cb, options = {}) {
  323. const {
  324. eventFilter: filter,
  325. ...watchOptions
  326. } = options;
  327. const { eventFilter, pause, resume, isActive } = pausableFilter(filter);
  328. const stop = watchWithFilter(
  329. source,
  330. cb,
  331. {
  332. ...watchOptions,
  333. eventFilter
  334. }
  335. );
  336. return { stop, pause, resume, isActive };
  337. }
  338. function tryOnMounted(fn, sync = true, target) {
  339. const instance = getLifeCycleTarget();
  340. if (instance)
  341. vue.onMounted(fn, target);
  342. else if (sync)
  343. fn();
  344. else
  345. vue.nextTick(fn);
  346. }
  347. function unrefElement(elRef) {
  348. var _a;
  349. const plain = toValue(elRef);
  350. return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain;
  351. }
  352. const defaultWindow = isClient ? window : void 0;
  353. function useEventListener(...args) {
  354. let target;
  355. let events;
  356. let listeners;
  357. let options;
  358. if (typeof args[0] === "string" || Array.isArray(args[0])) {
  359. [events, listeners, options] = args;
  360. target = defaultWindow;
  361. } else {
  362. [target, events, listeners, options] = args;
  363. }
  364. if (!target)
  365. return noop;
  366. if (!Array.isArray(events))
  367. events = [events];
  368. if (!Array.isArray(listeners))
  369. listeners = [listeners];
  370. const cleanups = [];
  371. const cleanup = () => {
  372. cleanups.forEach((fn) => fn());
  373. cleanups.length = 0;
  374. };
  375. const register = (el, event, listener, options2) => {
  376. el.addEventListener(event, listener, options2);
  377. return () => el.removeEventListener(event, listener, options2);
  378. };
  379. const stopWatch = vue.watch(
  380. () => [unrefElement(target), toValue(options)],
  381. ([el, options2]) => {
  382. cleanup();
  383. if (!el)
  384. return;
  385. const optionsClone = isObject(options2) ? { ...options2 } : options2;
  386. cleanups.push(
  387. ...events.flatMap((event) => {
  388. return listeners.map((listener) => register(el, event, listener, optionsClone));
  389. })
  390. );
  391. },
  392. { immediate: true, flush: "post" }
  393. );
  394. const stop = () => {
  395. stopWatch();
  396. cleanup();
  397. };
  398. tryOnScopeDispose(stop);
  399. return stop;
  400. }
  401. const _global = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
  402. const globalKey = "__vueuse_ssr_handlers__";
  403. const handlers = /* @__PURE__ */ getHandlers();
  404. function getHandlers() {
  405. if (!(globalKey in _global))
  406. _global[globalKey] = _global[globalKey] || {};
  407. return _global[globalKey];
  408. }
  409. function getSSRHandler(key, fallback) {
  410. return handlers[key] || fallback;
  411. }
  412. function guessSerializerType(rawInit) {
  413. return rawInit == null ? "any" : rawInit instanceof Set ? "set" : rawInit instanceof Map ? "map" : rawInit instanceof Date ? "date" : typeof rawInit === "boolean" ? "boolean" : typeof rawInit === "string" ? "string" : typeof rawInit === "object" ? "object" : !Number.isNaN(rawInit) ? "number" : "any";
  414. }
  415. const StorageSerializers = {
  416. boolean: {
  417. read: (v) => v === "true",
  418. write: (v) => String(v)
  419. },
  420. object: {
  421. read: (v) => JSON.parse(v),
  422. write: (v) => JSON.stringify(v)
  423. },
  424. number: {
  425. read: (v) => Number.parseFloat(v),
  426. write: (v) => String(v)
  427. },
  428. any: {
  429. read: (v) => v,
  430. write: (v) => String(v)
  431. },
  432. string: {
  433. read: (v) => v,
  434. write: (v) => String(v)
  435. },
  436. map: {
  437. read: (v) => new Map(JSON.parse(v)),
  438. write: (v) => JSON.stringify(Array.from(v.entries()))
  439. },
  440. set: {
  441. read: (v) => new Set(JSON.parse(v)),
  442. write: (v) => JSON.stringify(Array.from(v))
  443. },
  444. date: {
  445. read: (v) => new Date(v),
  446. write: (v) => v.toISOString()
  447. }
  448. };
  449. const customStorageEventName = "vueuse-storage";
  450. function useStorage(key, defaults, storage, options = {}) {
  451. var _a;
  452. const {
  453. flush = "pre",
  454. deep = true,
  455. listenToStorageChanges = true,
  456. writeDefaults = true,
  457. mergeDefaults = false,
  458. shallow,
  459. window: window2 = defaultWindow,
  460. eventFilter,
  461. onError = (e) => {
  462. console.error(e);
  463. },
  464. initOnMounted
  465. } = options;
  466. const data = (shallow ? vue.shallowRef : vue.ref)(typeof defaults === "function" ? defaults() : defaults);
  467. if (!storage) {
  468. try {
  469. storage = getSSRHandler("getDefaultStorage", () => {
  470. var _a2;
  471. return (_a2 = defaultWindow) == null ? void 0 : _a2.localStorage;
  472. })();
  473. } catch (e) {
  474. onError(e);
  475. }
  476. }
  477. if (!storage)
  478. return data;
  479. const rawInit = toValue(defaults);
  480. const type = guessSerializerType(rawInit);
  481. const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type];
  482. const { pause: pauseWatch, resume: resumeWatch } = watchPausable(
  483. data,
  484. () => write(data.value),
  485. { flush, deep, eventFilter }
  486. );
  487. if (window2 && listenToStorageChanges) {
  488. tryOnMounted(() => {
  489. if (storage instanceof Storage)
  490. useEventListener(window2, "storage", update);
  491. else
  492. useEventListener(window2, customStorageEventName, updateFromCustomEvent);
  493. if (initOnMounted)
  494. update();
  495. });
  496. }
  497. if (!initOnMounted)
  498. update();
  499. function dispatchWriteEvent(oldValue, newValue) {
  500. if (window2) {
  501. const payload = {
  502. key,
  503. oldValue,
  504. newValue,
  505. storageArea: storage
  506. };
  507. window2.dispatchEvent(storage instanceof Storage ? new StorageEvent("storage", payload) : new CustomEvent(customStorageEventName, {
  508. detail: payload
  509. }));
  510. }
  511. }
  512. function write(v) {
  513. try {
  514. const oldValue = storage.getItem(key);
  515. if (v == null) {
  516. dispatchWriteEvent(oldValue, null);
  517. storage.removeItem(key);
  518. } else {
  519. const serialized = serializer.write(v);
  520. if (oldValue !== serialized) {
  521. storage.setItem(key, serialized);
  522. dispatchWriteEvent(oldValue, serialized);
  523. }
  524. }
  525. } catch (e) {
  526. onError(e);
  527. }
  528. }
  529. function read(event) {
  530. const rawValue = event ? event.newValue : storage.getItem(key);
  531. if (rawValue == null) {
  532. if (writeDefaults && rawInit != null)
  533. storage.setItem(key, serializer.write(rawInit));
  534. return rawInit;
  535. } else if (!event && mergeDefaults) {
  536. const value = serializer.read(rawValue);
  537. if (typeof mergeDefaults === "function")
  538. return mergeDefaults(value, rawInit);
  539. else if (type === "object" && !Array.isArray(value))
  540. return { ...rawInit, ...value };
  541. return value;
  542. } else if (typeof rawValue !== "string") {
  543. return rawValue;
  544. } else {
  545. return serializer.read(rawValue);
  546. }
  547. }
  548. function update(event) {
  549. if (event && event.storageArea !== storage)
  550. return;
  551. if (event && event.key == null) {
  552. data.value = rawInit;
  553. return;
  554. }
  555. if (event && event.key !== key)
  556. return;
  557. pauseWatch();
  558. try {
  559. if ((event == null ? void 0 : event.newValue) !== serializer.write(data.value))
  560. data.value = read(event);
  561. } catch (e) {
  562. onError(e);
  563. } finally {
  564. if (event)
  565. vue.nextTick(resumeWatch);
  566. else
  567. resumeWatch();
  568. }
  569. }
  570. function updateFromCustomEvent(event) {
  571. update(event.detail);
  572. }
  573. return data;
  574. }
  575. const _export_sfc = (sfc, props) => {
  576. const target = sfc.__vccOpts || sfc;
  577. for (const [key, val] of props) {
  578. target[key] = val;
  579. }
  580. return target;
  581. };
  582. const _hoisted_1 = { class: "settings" };
  583. const _sfc_main = {
  584. __name: "App",
  585. setup(__props) {
  586. const nativeAxios = useStorage(window.projectId + "-axios-native", false);
  587. const arrowFunction = useStorage(window.projectId + "-arrow-function", false);
  588. const noExport = useStorage(window.projectId + "-no-export", false);
  589. const extractData = useStorage(window.projectId + "-extract-data", false);
  590. const requestFunctionName = useStorage(
  591. window.projectId + "-request-function-name",
  592. "axiosRequest"
  593. );
  594. return (_ctx, _cache) => {
  595. const _component_el_checkbox = vue.resolveComponent("el-checkbox");
  596. const _component_el_input = vue.resolveComponent("el-input");
  597. return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
  598. vue.createVNode(_component_el_checkbox, {
  599. modelValue: vue.unref(nativeAxios),
  600. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.isRef(nativeAxios) ? nativeAxios.value = $event : null),
  601. title: "use axios({...}) replace axios.post(...)"
  602. }, {
  603. default: vue.withCtx(() => [
  604. vue.createTextVNode("native axios")
  605. ]),
  606. _: 1
  607. }, 8, ["modelValue"]),
  608. vue.createVNode(_component_el_checkbox, {
  609. modelValue: vue.unref(arrowFunction),
  610. "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vue.isRef(arrowFunction) ? arrowFunction.value = $event : null)
  611. }, {
  612. default: vue.withCtx(() => [
  613. vue.createTextVNode("arrow function")
  614. ]),
  615. _: 1
  616. }, 8, ["modelValue"]),
  617. vue.createVNode(_component_el_checkbox, {
  618. modelValue: vue.unref(noExport),
  619. "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => vue.isRef(noExport) ? noExport.value = $event : null)
  620. }, {
  621. default: vue.withCtx(() => [
  622. vue.createTextVNode("no export")
  623. ]),
  624. _: 1
  625. }, 8, ["modelValue"]),
  626. vue.createVNode(_component_el_checkbox, {
  627. modelValue: vue.unref(extractData),
  628. "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => vue.isRef(extractData) ? extractData.value = $event : null)
  629. }, {
  630. default: vue.withCtx(() => [
  631. vue.createTextVNode("extract data")
  632. ]),
  633. _: 1
  634. }, 8, ["modelValue"]),
  635. vue.createVNode(_component_el_input, {
  636. modelValue: vue.unref(requestFunctionName),
  637. "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => vue.isRef(requestFunctionName) ? requestFunctionName.value = $event : null),
  638. modelModifiers: { trim: true },
  639. style: { "width": "120px" },
  640. placeholder: "request function name"
  641. }, null, 8, ["modelValue"])
  642. ]);
  643. };
  644. }
  645. };
  646. const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-7a7beb5b"]]);
  647. _GM_addStyle(
  648. "@import url('https://cdn.jsdelivr.net/npm/@highlightjs/cdn-assets@11.10.0/styles/atom-one-dark.min.css');"
  649. );
  650. _GM_addStyle(
  651. "@import url('https://cdn.jsdelivr.net/npm/element-plus@2.8.0/dist/index.min.css');"
  652. );
  653. window.settingsVm = {};
  654. function insertButton() {
  655. if (document.querySelector(".copy-request")) {
  656. return;
  657. }
  658. if (!document.querySelector(".interface-title")) {
  659. return;
  660. }
  661. const requestParams = $(".interface-title:contains('基本信息')");
  662. if (requestParams.length) {
  663. requestParams.append(
  664. '<button class="copy-request ant-btn ant-btn-primary ant-btn-md" style="margin-left:10px;">req</button>'
  665. );
  666. requestParams.append(
  667. '<button class="copy-interface ant-btn ant-btn-primary ant-btn-md" style="margin-left:10px;">ts</button>'
  668. );
  669. requestParams.append('<div id="yapi-app-vue"></div>');
  670. addSettingsButton("#yapi-app-vue");
  671. document.querySelector(".copy-request").addEventListener("click", () => copyRequest());
  672. document.querySelector(".copy-interface").addEventListener("click", () => copyInterface());
  673. }
  674. const bodyParameter = $(".col-title:contains('Body:')");
  675. if (bodyParameter.length) {
  676. bodyParameter.append(
  677. '<button class="body-parameter-copy-request ant-btn ant-btn-primary ant-btn-md" style="margin-left:10px;">ts</button>'
  678. );
  679. document.querySelector(".body-parameter-copy-request").addEventListener("click", copyBodyParameterInterface);
  680. }
  681. const responseParameter = $(".interface-title:contains('返回数据')");
  682. if (responseParameter.length) {
  683. responseParameter.append(
  684. '<button class="response-parameter-copy-request ant-btn ant-btn-primary ant-btn-md" style="margin-left:10px;">ts</button>'
  685. );
  686. document.querySelector(".response-parameter-copy-request").addEventListener("click", copyResponseParameterInterface);
  687. }
  688. }
  689. function insertGroupButton() {
  690. if (document.querySelector(".group-copy-request")) {
  691. return;
  692. }
  693. if (document.querySelector(".group-copy-interface")) {
  694. return;
  695. }
  696. const title = $(".interface-title").next().next().children();
  697. if (isAll()) {
  698. title.append(`<div></div>`);
  699. }
  700. title.append(`“
  701. <div style="display: flex;gap: 12px;">
  702. <div id="yapi-app-vue-group"></div>
  703. <button class="group-copy-request ant-btn ant-btn-primary ant-btn-md" style="padding: 1px 6px;font-size: 12px;width: 60px">req</button>
  704. <button class="group-copy-interface ant-btn ant-btn-primary ant-btn-md" style="padding: 1px 6px;font-size: 12px;width: 60px">ts</button>
  705. </div>
  706. `);
  707. addSettingsButton("#yapi-app-vue-group");
  708. $(".group-copy-request").on("click", copyGroupRequest);
  709. $(".group-copy-interface").on("click", copyGroupInterface);
  710. }
  711. function insertPathName() {
  712. $(".copy-request-func").remove();
  713. const funcName = requestName({
  714. path: $(".interface-url-icon").prev().text()
  715. });
  716. $(".interface-url-icon").parent().append(
  717. `<button class="copy-request-func ant-btn ant-btn-primary ant-btn-md" style="margin-left:10px;">${funcName}</button>`
  718. );
  719. document.querySelector(".copy-request-func").addEventListener("click", () => copy(funcName));
  720. }
  721. const path = vue.ref("");
  722. setInterval(() => {
  723. path.value = location.pathname;
  724. }, 100);
  725. vue.watch(path, async (val) => {
  726. var _a;
  727. window.projectId = (_a = location.href.match(/project\/(\d+)/)) == null ? void 0 : _a[1];
  728. if (isCate() || isAll()) {
  729. setTimeout(() => {
  730. insertGroupButton();
  731. }, 100);
  732. } else {
  733. setTimeout(() => {
  734. insertButton();
  735. insertPathName();
  736. }, 100);
  737. }
  738. });
  739. function addSettingsButton(el) {
  740. const app = vue.createApp(App);
  741. app.use(ElementPlus);
  742. app.mount(el);
  743. }
  744.  
  745. })(ElementPlus, Vue);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址