mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-22 04:06:18 +00:00
chore: Jest Testing structure (#2707)
* deps: add jest deps * chore: mock * feat: use mocinggoose * feat: jest * chore: remove babel.config.js
This commit is contained in:
49
scripts/openapi/index.js
Normal file
49
scripts/openapi/index.js
Normal file
@@ -0,0 +1,49 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var utils_1 = require("./utils");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var openapi_1 = require("./openapi");
|
||||
var rootPath = 'projects/app/src/pages/api';
|
||||
var exclude = ['/admin', '/proApi'];
|
||||
function getAllFiles(dir) {
|
||||
var files = [];
|
||||
var stat = fs.statSync(dir);
|
||||
if (stat.isDirectory()) {
|
||||
var list = fs.readdirSync(dir);
|
||||
list.forEach(function (item) {
|
||||
var fullPath = path.join(dir, item);
|
||||
if (!exclude.some(function (excluded) { return fullPath.includes(excluded); })) {
|
||||
files = files.concat(getAllFiles(fullPath));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
files.push(dir);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
var searchPath = process.env.SEARCH_PATH || '';
|
||||
var files = getAllFiles(path.join(rootPath, searchPath));
|
||||
// console.log(files)
|
||||
var apis = files.map(function (file) {
|
||||
return (0, utils_1.parseAPI)({ path: file, rootPath: rootPath });
|
||||
});
|
||||
var openapi = (0, openapi_1.convertOpenApi)({
|
||||
apis: apis,
|
||||
openapi: '3.0.0',
|
||||
info: {
|
||||
title: 'FastGPT OpenAPI',
|
||||
version: '1.0.0',
|
||||
author: 'FastGPT'
|
||||
},
|
||||
servers: [
|
||||
{
|
||||
url: 'http://localhost:4000'
|
||||
}
|
||||
]
|
||||
});
|
||||
var json = JSON.stringify(openapi, null, 2);
|
||||
fs.writeFileSync('./scripts/openapi/openapi.json', json);
|
||||
fs.writeFileSync('./scripts/openapi/openapi.out', JSON.stringify(apis, null, 2));
|
||||
console.log('Total APIs:', files.length);
|
145
scripts/openapi/openapi.js
Normal file
145
scripts/openapi/openapi.js
Normal file
@@ -0,0 +1,145 @@
|
||||
"use strict";
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.convertPath = convertPath;
|
||||
exports.convertOpenApi = convertOpenApi;
|
||||
function convertPath(api) {
|
||||
var _a;
|
||||
var _b;
|
||||
var method = api.method.toLowerCase();
|
||||
var parameters = [];
|
||||
if (api.query) {
|
||||
if (Array.isArray(api.query)) {
|
||||
api.query.forEach(function (item) {
|
||||
parameters.push({
|
||||
name: item.key,
|
||||
description: item.comment,
|
||||
in: 'query',
|
||||
required: item.required,
|
||||
schema: {
|
||||
type: item.type
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
parameters.push({
|
||||
description: api.query.comment,
|
||||
name: api.query.key,
|
||||
in: 'query',
|
||||
required: api.query.required,
|
||||
schema: {
|
||||
type: api.query.type
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (api.body) {
|
||||
if (Array.isArray(api.body)) {
|
||||
api.body.forEach(function (item) {
|
||||
parameters.push({
|
||||
description: item.comment,
|
||||
name: item.key,
|
||||
in: 'body',
|
||||
required: item.required,
|
||||
schema: {
|
||||
type: item.type
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
var responses = (function () {
|
||||
var _a, _b, _c;
|
||||
if (api.response) {
|
||||
if (Array.isArray(api.response)) {
|
||||
var properties_1 = {};
|
||||
api.response.forEach(function (item) {
|
||||
var _a;
|
||||
properties_1[item.type] = {
|
||||
type: (_a = item.key) !== null && _a !== void 0 ? _a : item.type,
|
||||
description: item.comment
|
||||
};
|
||||
});
|
||||
var res = {
|
||||
'200': {
|
||||
description: (_a = api.description) !== null && _a !== void 0 ? _a : '',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: properties_1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return res;
|
||||
}
|
||||
else {
|
||||
return {
|
||||
'200': {
|
||||
description: (_b = api.response.comment) !== null && _b !== void 0 ? _b : '',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: api.response.type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
return {
|
||||
'200': {
|
||||
description: (_c = api.description) !== null && _c !== void 0 ? _c : '',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
return _a = {},
|
||||
_a[method] = {
|
||||
description: (_b = api.description) !== null && _b !== void 0 ? _b : '',
|
||||
parameters: parameters,
|
||||
responses: responses
|
||||
},
|
||||
_a;
|
||||
}
|
||||
function convertOpenApi(_a) {
|
||||
var apis = _a.apis, rest = __rest(_a, ["apis"]);
|
||||
var paths = {};
|
||||
apis.forEach(function (api) {
|
||||
paths[api.url] = convertPath(api);
|
||||
});
|
||||
return __assign({ paths: paths }, rest);
|
||||
}
|
2756
scripts/openapi/openapi.json
Normal file
2756
scripts/openapi/openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
1284
scripts/openapi/openapi.out
Normal file
1284
scripts/openapi/openapi.out
Normal file
File diff suppressed because it is too large
Load Diff
229
scripts/openapi/utils.js
Normal file
229
scripts/openapi/utils.js
Normal file
@@ -0,0 +1,229 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseAPI = parseAPI;
|
||||
var parser_1 = require("@babel/parser");
|
||||
var traverse_1 = require("@babel/traverse");
|
||||
var fs = require("fs");
|
||||
function getMetadata(path) {
|
||||
var _a, _b, _c;
|
||||
var metadata = {
|
||||
name: '',
|
||||
author: '',
|
||||
version: '',
|
||||
method: ''
|
||||
};
|
||||
if (path.isExportNamedDeclaration() && // get metadata
|
||||
((_a = path.node.declaration) === null || _a === void 0 ? void 0 : _a.type) === 'VariableDeclaration' &&
|
||||
((_b = path.node.declaration.declarations[0]) === null || _b === void 0 ? void 0 : _b.id.type) === 'Identifier' &&
|
||||
path.node.declaration.declarations[0].id.name === 'ApiMetadata' &&
|
||||
((_c = path.node.declaration.declarations[0].init) === null || _c === void 0 ? void 0 : _c.type) === 'ObjectExpression') {
|
||||
path.node.declaration.declarations[0].init.properties.forEach(function (item) {
|
||||
if (item.type === 'ObjectProperty') {
|
||||
var key = item.key.type === 'Identifier' ? item.key.name : item.key.type;
|
||||
if (key === 'name') {
|
||||
metadata.name = item.value.type === 'StringLiteral' ? item.value.value : item.value.type;
|
||||
}
|
||||
if (key === 'author') {
|
||||
metadata.author =
|
||||
item.value.type === 'StringLiteral' ? item.value.value : item.value.type;
|
||||
}
|
||||
if (key === 'version') {
|
||||
metadata.version =
|
||||
item.value.type === 'StringLiteral' ? item.value.value : item.value.type;
|
||||
}
|
||||
else if (key === 'method') {
|
||||
metadata.method =
|
||||
item.value.type === 'StringLiteral' ? item.value.value : item.value.type;
|
||||
metadata.method = metadata.method.toUpperCase();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (metadata.name && metadata.author && metadata.version) {
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
function getDescription(path) {
|
||||
var _a, _b;
|
||||
if (path.isFunctionDeclaration() && ((_a = path.node.id) === null || _a === void 0 ? void 0 : _a.name) === 'handler') {
|
||||
var comments = (_b = path.node.leadingComments) === null || _b === void 0 ? void 0 : _b.map(function (item) { return item.value.trim(); }).join('\n');
|
||||
return comments;
|
||||
}
|
||||
}
|
||||
function parseType(type) {
|
||||
if (!type) {
|
||||
return '';
|
||||
}
|
||||
if (type.type === 'TSTypeReference') {
|
||||
return type.typeName.type === 'Identifier' ? type.typeName.name : type.typeName.type;
|
||||
}
|
||||
else if (type.type === 'TSArrayType') {
|
||||
return "".concat(parseType(type.elementType), "[]");
|
||||
}
|
||||
else if (type.type === 'TSUnionType') {
|
||||
return type.types.map(function (item) { return parseType(item); }).join(' | ');
|
||||
}
|
||||
else if (type.type === 'TSIntersectionType') {
|
||||
return type.types.map(function (item) { return parseType(item); }).join(' & ');
|
||||
}
|
||||
else if (type.type === 'TSLiteralType') {
|
||||
return type.literal.type === 'StringLiteral' ? type.literal.value : type.literal.type;
|
||||
// } else if (type.type === 'TSTypeLiteral') {
|
||||
// return parseTypeLiteral(type);
|
||||
}
|
||||
else if (type.type === 'TSStringKeyword') {
|
||||
return 'string';
|
||||
}
|
||||
else if (type.type === 'TSNumberKeyword') {
|
||||
return 'number';
|
||||
}
|
||||
else if (type.type === 'TSBooleanKeyword') {
|
||||
return 'boolean';
|
||||
}
|
||||
else {
|
||||
return type.type;
|
||||
}
|
||||
}
|
||||
function parseTypeLiteral(type) {
|
||||
var items = [];
|
||||
type.members.forEach(function (item) {
|
||||
var _a, _b, _c;
|
||||
if (item.type === 'TSPropertySignature') {
|
||||
var key = item.key.type === 'Identifier' ? item.key.name : item.key.type;
|
||||
var value = parseType((_a = item.typeAnnotation) === null || _a === void 0 ? void 0 : _a.typeAnnotation);
|
||||
var comments = [
|
||||
(_b = item.leadingComments) === null || _b === void 0 ? void 0 : _b.map(function (item) { return item.value.trim(); }).join('\n'),
|
||||
(_c = item.trailingComments) === null || _c === void 0 ? void 0 : _c.map(function (item) { return item.value.trim(); }).join('\n')
|
||||
].join('\n');
|
||||
var required = item.optional ? false : true;
|
||||
items.push({
|
||||
type: value,
|
||||
comment: comments,
|
||||
key: key,
|
||||
required: required
|
||||
});
|
||||
}
|
||||
});
|
||||
return items;
|
||||
}
|
||||
function getData(path) {
|
||||
var _a, _b, _c;
|
||||
var type = {};
|
||||
if (path.isExportNamedDeclaration()) {
|
||||
var comments = [
|
||||
(_a = path.node.leadingComments) === null || _a === void 0 ? void 0 : _a.map(function (item) { return item.value.trim(); }).join('\n'),
|
||||
(_b = path.node.trailingComments) === null || _b === void 0 ? void 0 : _b.map(function (item) { return item.value.trim(); }).join('\n')
|
||||
].join('\n');
|
||||
if (comments) {
|
||||
type.comment = comments;
|
||||
}
|
||||
if (((_c = path.node.declaration) === null || _c === void 0 ? void 0 : _c.type) === 'TSTypeAliasDeclaration') {
|
||||
if (path.node.declaration.id.type === 'Identifier') {
|
||||
if (path.node.declaration.id.name.endsWith('Query')) {
|
||||
type.type = 'query';
|
||||
var queryType = path.node.declaration.typeAnnotation;
|
||||
if (queryType) {
|
||||
if (queryType.type === 'TSTypeLiteral') {
|
||||
type.items = parseTypeLiteral(queryType);
|
||||
}
|
||||
else {
|
||||
type.dataType = parseType(queryType);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (path.node.declaration.id.name.endsWith('Body')) {
|
||||
type.type = 'body';
|
||||
if (path.node.declaration.typeAnnotation) {
|
||||
if (path.node.declaration.typeAnnotation.type === 'TSTypeLiteral') {
|
||||
type.items = parseTypeLiteral(path.node.declaration.typeAnnotation);
|
||||
}
|
||||
else {
|
||||
type.dataType = parseType(path.node.declaration.typeAnnotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (path.node.declaration.id.name.endsWith('Response')) {
|
||||
type.type = 'response';
|
||||
if (path.node.declaration.typeAnnotation) {
|
||||
if (path.node.declaration.typeAnnotation.type === 'TSTypeLiteral') {
|
||||
type.items = parseTypeLiteral(path.node.declaration.typeAnnotation);
|
||||
}
|
||||
else {
|
||||
type.dataType = parseType(path.node.declaration.typeAnnotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
function parseCode(code) {
|
||||
var ast = (0, parser_1.parse)(code, {
|
||||
sourceType: 'module',
|
||||
plugins: ['typescript', 'jsx']
|
||||
});
|
||||
var api = {};
|
||||
(0, traverse_1.default)(ast, {
|
||||
enter: function (path) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
||||
var metadata = getMetadata(path);
|
||||
var description = getDescription(path);
|
||||
var data = getData(path);
|
||||
if (metadata) {
|
||||
api.name = metadata.name;
|
||||
api.author = metadata.author;
|
||||
api.version = metadata.version;
|
||||
}
|
||||
if (description) {
|
||||
api.description = description;
|
||||
}
|
||||
if (data) {
|
||||
if (data.type === 'query') {
|
||||
api.query = (_a = data.items) !== null && _a !== void 0 ? _a : {
|
||||
type: (_b = data.dataType) !== null && _b !== void 0 ? _b : '',
|
||||
comment: (_c = data.comment) !== null && _c !== void 0 ? _c : ''
|
||||
};
|
||||
}
|
||||
else if (data.type === 'body') {
|
||||
api.body = (_d = data.items) !== null && _d !== void 0 ? _d : {
|
||||
type: (_e = data.dataType) !== null && _e !== void 0 ? _e : '',
|
||||
comment: (_f = data.comment) !== null && _f !== void 0 ? _f : ''
|
||||
};
|
||||
}
|
||||
else if (data.type === 'response') {
|
||||
api.response = (_g = data.items) !== null && _g !== void 0 ? _g : {
|
||||
type: (_h = data.dataType) !== null && _h !== void 0 ? _h : '',
|
||||
comment: (_j = data.comment) !== null && _j !== void 0 ? _j : ''
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return api;
|
||||
}
|
||||
function getMethod(api) {
|
||||
if (api.query && !(Array.isArray(api.query) && api.query.length === 0)) {
|
||||
return 'GET';
|
||||
}
|
||||
else if (api.body && !(Array.isArray(api.body) && api.body.length === 0)) {
|
||||
return 'POST';
|
||||
}
|
||||
else {
|
||||
return 'GET';
|
||||
}
|
||||
}
|
||||
function parseAPI(_a) {
|
||||
var path = _a.path, rootPath = _a.rootPath;
|
||||
var code = fs.readFileSync(path, 'utf-8');
|
||||
var api = parseCode(code);
|
||||
api.url = path.replace('.ts', '').replace(rootPath, '');
|
||||
api.path = path;
|
||||
if (api.method === undefined) {
|
||||
api.method = getMethod(api);
|
||||
}
|
||||
return api;
|
||||
}
|
Reference in New Issue
Block a user