sumor 2.0.0 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # Sumor Cloud Application Framework
package/package.json CHANGED
@@ -1,11 +1,19 @@
1
1
  {
2
2
  "name": "sumor",
3
- "version": "2.0.0",
3
+ "version": "2.0.3",
4
4
  "main": "src/index.js",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "sumor": "src/cli.js"
8
8
  },
9
+ "files": [
10
+ "i18n/",
11
+ "i18nExt/",
12
+ "modules/",
13
+ "src/",
14
+ "LICENSE",
15
+ "README.md"
16
+ ],
9
17
  "scripts": {
10
18
  "demo": "cd demo && npm run start",
11
19
  "check": "npm run autofix && npm run coverage",
@@ -26,10 +34,18 @@
26
34
  "publish-release-minor": "npm version minor && npm run push-tag",
27
35
  "publish-release-major": "npm version major && npm run push-tag"
28
36
  },
29
- "keywords": [],
30
- "author": "",
31
- "license": "UNLICENSED",
32
- "description": "",
37
+ "keywords": [
38
+ "sumor",
39
+ "openapi",
40
+ "swagger",
41
+ "rest",
42
+ "api",
43
+ "express",
44
+ "yaml"
45
+ ],
46
+ "author": "Sumor Cloud",
47
+ "license": "MIT",
48
+ "description": "It generates a REST API from a YAML file using OpenAPI 3.0 and Express.js.",
33
49
  "dependencies": {
34
50
  "axios": "^1.8.4",
35
51
  "body-parser": "^2.2.0",
package/.eslintignore DELETED
@@ -1,6 +0,0 @@
1
- coverage
2
- node_modules
3
- web/public
4
- static
5
- tmp
6
- apiExplorer
package/.eslintrc.yml DELETED
@@ -1,4 +0,0 @@
1
- root: true
2
- extends:
3
- - standard
4
- - plugin:prettier/recommended
package/.gitattributes DELETED
@@ -1 +0,0 @@
1
- * text=auto eol=lf
@@ -1,22 +0,0 @@
1
- name: Audit
2
- on:
3
- schedule:
4
- - cron: '0 * * * *'
5
- jobs:
6
- audit:
7
- name: Audit
8
- runs-on: ubuntu-latest
9
- steps:
10
- - name: Checkout code
11
- uses: actions/checkout@v4
12
- - name: Use Node.js
13
- uses: actions/setup-node@v4
14
- with:
15
- node-version: '20.x'
16
- registry-url: 'https://registry.npmjs.org'
17
- - name: Install NPM dependencies
18
- run: npm ci
19
- - name: Check dependencies size
20
- run: du -sh node_modules
21
- - name: Run NPM audit
22
- run: npm audit
@@ -1,22 +0,0 @@
1
- name: Available
2
- on:
3
- schedule:
4
- - cron: '*/1 * * * *'
5
- jobs:
6
- install:
7
- name: NPM Installation Test
8
- runs-on: ubuntu-latest
9
- steps:
10
- - name: Use Node.js
11
- uses: actions/setup-node@v4
12
- with:
13
- node-version: '20.x'
14
- registry-url: 'https://registry.npmjs.org'
15
- - name: Install NPM dependencies
16
- run: npm i sumor
17
- - name: Check dependencies size
18
- run: du -sh node_modules
19
- - name: Dependency Check
20
- run: npm ls
21
- - name: Audit
22
- run: npm audit
@@ -1,45 +0,0 @@
1
- name: CI
2
- on:
3
- push:
4
- branches:
5
- - main
6
- jobs:
7
- check:
8
- name: Code Quality Check
9
- runs-on: ubuntu-latest
10
- steps:
11
- - name: Checkout code
12
- uses: actions/checkout@v4
13
- - name: Use Node.js
14
- uses: actions/setup-node@v4
15
- with:
16
- node-version: '20.x'
17
- registry-url: 'https://registry.npmjs.org'
18
- - name: Install NPM dependencies
19
- run: npm ci
20
- - name: Check dependencies size
21
- run: du -sh node_modules
22
- - name: Syntax specification checking using ESLint
23
- run: npm run lint
24
- - name: Run NPM audit
25
- run: npm audit
26
- test:
27
- name: Unit Test
28
- needs: check
29
- runs-on: ubuntu-latest
30
- strategy:
31
- matrix:
32
- node-version: [18.x, 20.x, 22.x]
33
- steps:
34
- - name: Checkout code
35
- uses: actions/checkout@v4
36
- - name: Use Node.js ${{ matrix.node-version }}
37
- uses: actions/setup-node@v4
38
- with:
39
- node-version: ${{ matrix.node-version }}
40
- - name: Install NPM dependencies
41
- run: npm ci
42
- - name: Check dependencies size
43
- run: du -sh node_modules
44
- - name: Unit test using Jest
45
- run: npm test
@@ -1,23 +0,0 @@
1
- name: Coverage
2
- on:
3
- push:
4
- branches:
5
- - main
6
- jobs:
7
- test:
8
- name: Unit Test
9
- runs-on: ubuntu-latest
10
- steps:
11
- - name: Checkout code
12
- uses: actions/checkout@v4
13
- - name: Use Node.js
14
- uses: actions/setup-node@v4
15
- with:
16
- node-version: '20.x'
17
- registry-url: 'https://registry.npmjs.org'
18
- - name: Install NPM dependencies
19
- run: npm ci
20
- - name: Check dependencies size
21
- run: du -sh node_modules
22
- - name: Unit test with coverage using Jest
23
- run: npm run coverage
@@ -1,31 +0,0 @@
1
- name: Publish
2
- on:
3
- push:
4
- tags:
5
- - '*'
6
- jobs:
7
- publish:
8
- name: Publish to NPM
9
- runs-on: ubuntu-latest
10
- steps:
11
- - name: Checkout code
12
- uses: actions/checkout@v4
13
- - name: Use Node.js
14
- uses: actions/setup-node@v4
15
- with:
16
- node-version: '20.x'
17
- registry-url: 'https://registry.npmjs.org'
18
- - name: Install NPM dependencies
19
- run: npm ci
20
- - name: Check dependencies size
21
- run: du -sh node_modules
22
- - name: Syntax specification checking using ESLint
23
- run: npm run lint
24
- - name: Run NPM audit
25
- run: npm audit
26
- - name: Unit test with coverage using Jest
27
- run: npm test
28
- - name: Publish to NPM
29
- run: npm publish --access public
30
- env:
31
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -1,24 +0,0 @@
1
- name: Test
2
- on:
3
- schedule:
4
- - cron: '0 * * * *'
5
- jobs:
6
- test:
7
- name: Unit test for latest dependencies
8
- runs-on: ubuntu-latest
9
- steps:
10
- - name: Checkout code
11
- uses: actions/checkout@v4
12
- - name: Use Node.js
13
- uses: actions/setup-node@v4
14
- with:
15
- node-version: '20.x'
16
- registry-url: 'https://registry.npmjs.org'
17
- - name: Remove package-lock.json
18
- run: rm -f package-lock.json
19
- - name: Install NPM dependencies
20
- run: npm i
21
- - name: Check dependencies size
22
- run: du -sh node_modules
23
- - name: Unit test using Jest
24
- run: npm run test
package/.husky/pre-commit DELETED
@@ -1,10 +0,0 @@
1
- #!/bin/sh
2
- #
3
- # 在运行 pre-commit 脚本之前打印消息
4
- echo "正在运行 pre-commit 脚本..."
5
-
6
- # 运行 pre-commit 命令
7
- npm run pre-commit
8
-
9
- # 在运行 pre-commit 脚本之后打印消息
10
- echo "pre-commit 脚本运行完成。"
package/.husky/pre-push DELETED
@@ -1,10 +0,0 @@
1
- #!/bin/sh
2
-
3
- # 在运行 pre-push 脚本之前打印消息
4
- echo "正在运行 pre-push 脚本..."
5
-
6
- # 运行 pre-push 命令
7
- npm run pre-push
8
-
9
- # 在运行 pre-push 脚本之后打印消息
10
- echo "pre-push 脚本运行完成。"
package/.prettierrc.yml DELETED
@@ -1,7 +0,0 @@
1
- singleQuote: true
2
- semi: false
3
- tabWidth: 2
4
- printWidth: 100
5
- trailingComma: none
6
- arrowParens: avoid
7
- endOfLine: lf
package/demo/api/error.js DELETED
@@ -1,3 +0,0 @@
1
- export default (req, res) => {
2
- throw new Error('This is an error')
3
- }
package/demo/api/file.js DELETED
@@ -1,4 +0,0 @@
1
- export default (req, res) => {
2
- // const file = req.data.file
3
- return req.data
4
- }
@@ -1,11 +0,0 @@
1
- name: File
2
- methods:
3
- - POST
4
- - GET
5
- parameters:
6
- file:
7
- name: 文件
8
- type: file
9
- required: true
10
- id:
11
- name: 上传请求号
package/demo/api/hello.js DELETED
@@ -1,4 +0,0 @@
1
- export default (req, res) => {
2
- const name = req.data.name
3
- return `Hello ${name}!`
4
- }
@@ -1,13 +0,0 @@
1
- name: Hello
2
- path:
3
- - /hello
4
- - /hello/:name
5
- parameters:
6
- name:
7
- name: 姓名
8
- type: string
9
- required: true
10
- rules:
11
- CHARACTER_LIMIT:
12
- expression: '^[a-zA-Z][a-zA-Z0-9_]{0,19}$'
13
- message: '姓名只能包含字母、数字和下划线,且不能以数字开头,长度在1-20个字符之间'
package/demo/api/login.js DELETED
@@ -1,4 +0,0 @@
1
- export default (req, res, next) => {
2
- req.token.id = 'DEMO_TOKEN'
3
- req.token.user = 'DEMO_USER'
4
- }
@@ -1,4 +0,0 @@
1
- export default (req, res, next) => {
2
- req.token.id = 'DEMO_TOKEN'
3
- req.token.user = 'DEMO_USER'
4
- }
package/demo/api/long.js DELETED
@@ -1,9 +0,0 @@
1
- export default (req, res) => {
2
- const times = 100
3
- let result = ''
4
- for (let i = 0; i < times; i++) {
5
- result += 'Hello!'
6
- }
7
-
8
- return result
9
- }
@@ -1,2 +0,0 @@
1
- methods:
2
- - GET
@@ -1,12 +0,0 @@
1
- export default async (req, res) => {
2
- const { token } = req
3
-
4
- token.id = 'DEMO_TOKEN'
5
- token.user = 'DEMO_USER'
6
-
7
- token.check('ADMIN')
8
-
9
- return {
10
- name: 'John Doe'
11
- }
12
- }
@@ -1,8 +0,0 @@
1
- export default async (req, res) => {
2
- const { token } = req
3
- token.check()
4
-
5
- return {
6
- name: 'John Doe'
7
- }
8
- }
@@ -1,2 +0,0 @@
1
- name: demo
2
- desc: 示例应用,用于测试和演示
@@ -1 +0,0 @@
1
- name: 测试
package/demo/package.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "type": "module",
3
- "scripts": {
4
- "start": "../src/cli.js start"
5
- }
6
- }
package/jest.config.json DELETED
@@ -1,26 +0,0 @@
1
- {
2
- "maxWorkers": 10,
3
- "reporters": [
4
- "default",
5
- [
6
- "jest-html-reporter",
7
- {
8
- "pageTitle": "Test Report",
9
- "outputPath": "./output/unit/index.html"
10
- }
11
- ]
12
- ],
13
- "coverageThreshold": {
14
- "global": {
15
- "branches": 80,
16
- "functions": 80,
17
- "lines": 80,
18
- "statements": 80
19
- }
20
- },
21
- "coverageDirectory": "output/test/all/coverage",
22
- "coverageReporters": ["json", "lcov", "text", "clover"],
23
- "collectCoverageFrom": ["modules/**/*.js"],
24
- "testPathIgnorePatterns": ["node_modules", "output", "static", "dist", "tmp"],
25
- "coveragePathIgnorePatterns": ["node_modules", "output", "static", "dist", "tmp"]
26
- }
@@ -1,4 +0,0 @@
1
- # 代码测试器
2
-
3
- 代码测试不指定文件的情况下,会自动测试当前目录下的所有代码文件。这消耗太多时间,而指定文件名又很麻烦。
4
- 该工具将通过命令行交互,查找当前目录下的所有测试文件,让用户选择要测试的文件,然后执行测试。
@@ -1,47 +0,0 @@
1
- /* 当浏览器设置为dark模式时生效 */
2
- a {
3
- color: #2196f3;
4
- }
5
-
6
- @media (prefers-color-scheme: dark) {
7
- body {
8
- background: #000;
9
- color: #fff;
10
- }
11
- .quiet {
12
- color: rgba(255, 255, 255, 0.5);
13
- }
14
- .low {
15
- background: rgba(255, 87, 34, 0.5);
16
- }
17
- .high {
18
- background: rgba(255, 255, 255, 0.1);
19
- }
20
- .medium {
21
- background: rgba(255, 87, 34, 0.3);
22
- }
23
-
24
- .status-line.medium,
25
- .medium .cover-fill {
26
- background: rgb(255, 87, 34);
27
- }
28
- a {
29
- color: #a9d9ff;
30
- }
31
- .coverage-summary th {
32
- background: rgba(255, 255, 255, 0.3);
33
- }
34
- thead tr {
35
- border: 1px solid #bbb;
36
- }
37
- pre {
38
- background: rgba(255, 255, 255, 1);
39
- color: #000;
40
- .quiet {
41
- color: rgba(0, 0, 0, 0.7);
42
- }
43
- }
44
- pre a {
45
- color: #2196f3;
46
- }
47
- }
@@ -1,80 +0,0 @@
1
- import inquirer from 'inquirer'
2
- import path from 'path'
3
- import fse from 'fs-extra'
4
- import getTestFiles from './utils/getTestFiles.js'
5
- import runTests from './utils/runTests.js'
6
- import startServer from './utils/startServer.js'
7
- const LAST_TEST_FILE_PATH = path.join(process.cwd(), 'tmp', 'tools', 'codeTest', 'lastTestFile.txt')
8
-
9
- // 主函数
10
- const executeCodeTest = async () => {
11
- const testFiles = getTestFiles(path.join(process.cwd(), 'modules'))
12
- if (testFiles.length === 0) {
13
- console.log('未找到测试文件。')
14
- return
15
- }
16
-
17
- // const sortedTestFiles = testFiles.sort((a, b) => {
18
- // if (a.endsWith('/index.test.js') && !b.endsWith('/index.test.js')) return -1
19
- // if (!a.endsWith('/index.test.js') && b.endsWith('/index.test.js')) return 1
20
- // return a.localeCompare(b)
21
- // })
22
-
23
- let displayTestFiles = testFiles.map(file => {
24
- if (file.endsWith('/index.test.js'))
25
- return {
26
- name: file.replace('/index.test.js', ''),
27
- value: file
28
- }
29
- return {
30
- name: file.replace('.test.js', ''),
31
- value: file
32
- }
33
- })
34
- displayTestFiles = displayTestFiles.sort((a, b) => {
35
- if (b.name > a.name) return -1
36
- else return 1
37
- })
38
-
39
- let lastTestFile = ''
40
- if (await fse.exists(LAST_TEST_FILE_PATH)) {
41
- lastTestFile = await fse.readFile(LAST_TEST_FILE_PATH, 'utf-8')
42
- }
43
-
44
- const answers = await inquirer.prompt([
45
- {
46
- type: 'list',
47
- name: 'file',
48
- message: `选择要运行的测试文件:(共${displayTestFiles.length - 1}个)`,
49
- choices: [{ name: `全部`, value: '' }, ...displayTestFiles],
50
- default: lastTestFile
51
- }
52
- ])
53
-
54
- let selectedFile = answers.file
55
- selectedFile = selectedFile || ''
56
- const report = await runTests(LAST_TEST_FILE_PATH, selectedFile)
57
-
58
- const unitPath = path.join(report, 'unit')
59
-
60
- const generatedUnitPath = path.join(process.cwd(), 'output', 'unit')
61
- await fse.move(generatedUnitPath, path.join(process.cwd(), unitPath))
62
-
63
- const unitPort = await startServer(path.join(process.cwd(), unitPath))
64
- console.log(`单元测试报告请访问 http://localhost:${unitPort}`)
65
- // console.log(` - 报告目录:${unitPath}`)
66
-
67
- const coveragePath = path.join(report, 'coverage', 'lcov-report')
68
-
69
- // 将custom.css的内容追加到base.css文件中
70
- const customCssPath = path.join(new URL('.', import.meta.url).pathname, 'custom.css')
71
- const baseCssPath = path.join(coveragePath, 'base.css')
72
- const customCss = await fse.readFile(customCssPath, 'utf-8')
73
- await fse.appendFile(baseCssPath, customCss)
74
-
75
- const coveragePort = await startServer(path.join(process.cwd(), coveragePath))
76
- console.log(`覆盖率报告请访问 http://localhost:${coveragePort}`)
77
- // console.log(` - 报告目录:${coveragePath}`)
78
- }
79
-
80
- executeCodeTest()
@@ -1,55 +0,0 @@
1
- export function calculateCoverage(coverageJSON) {
2
- const results = {}
3
- let totalStatements = 0
4
- let totalFunctions = 0
5
- let totalBranches = 0
6
- let totalStatementCoverage = 0
7
- let totalFunctionCoverage = 0
8
- let totalBranchCoverage = 0
9
-
10
- for (const filePath in coverageJSON) {
11
- const fileCoverage = coverageJSON[filePath]
12
- const statements = Object.keys(fileCoverage.s).length
13
- const functions = Object.keys(fileCoverage.f).length
14
- const branches = Object.keys(fileCoverage.b).length
15
- const statementCoverage =
16
- (Object.values(fileCoverage.s).filter(v => v > 0).length / statements) * 100
17
- const functionCoverage =
18
- (Object.values(fileCoverage.f).filter(v => v > 0).length / functions) * 100
19
- const branchCoverage =
20
- (Object.values(fileCoverage.b).filter(v => v.every(b => b > 0)).length / branches) * 100
21
-
22
- results[filePath] = {
23
- statements,
24
- functions,
25
- branches,
26
- statementCoverage,
27
- functionCoverage,
28
- branchCoverage
29
- }
30
-
31
- totalStatements += statements
32
- totalFunctions += functions
33
- totalBranches += branches
34
- if (statements > 0) {
35
- totalStatementCoverage += statementCoverage * statements
36
- }
37
- if (functions > 0) {
38
- totalFunctionCoverage += functionCoverage * functions
39
- }
40
- if (branches > 0) {
41
- totalBranchCoverage += branchCoverage * branches
42
- }
43
- }
44
-
45
- const total = {
46
- statements: totalStatements,
47
- functions: totalFunctions,
48
- branches: totalBranches,
49
- statementCoverage: totalStatementCoverage / totalStatements,
50
- functionCoverage: totalFunctionCoverage / totalFunctions,
51
- branchCoverage: totalBranchCoverage / totalBranches
52
- }
53
-
54
- return { results, total }
55
- }
@@ -1,20 +0,0 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
-
4
- // 获取当前目录下的所有测试文件的函数
5
- const getTestFiles = testFolder => {
6
- let testFiles = []
7
- const files = fs.readdirSync(testFolder)
8
- files.forEach(file => {
9
- const filePath = path.join(testFolder, file)
10
- const stat = fs.statSync(filePath)
11
- if (stat.isDirectory()) {
12
- testFiles = testFiles.concat(getTestFiles(filePath))
13
- } else if (file.endsWith('.test.js')) {
14
- testFiles.push(filePath.replace(process.cwd() + path.sep, ''))
15
- }
16
- })
17
- return testFiles
18
- }
19
-
20
- export default getTestFiles
@@ -1,38 +0,0 @@
1
- import { execSync } from 'child_process'
2
- import fse from 'fs-extra'
3
- import path from 'path'
4
-
5
- // 替换 .test.ts 为 .test.js
6
- const runTests = async (config, file) => {
7
- await fse.remove(path.join(process.cwd(), 'tmp', 'test'))
8
-
9
- await fse.ensureFile(config)
10
- await fse.writeFile(config, file, 'utf-8')
11
-
12
- let folder = 'all'
13
- if (file !== '') {
14
- folder = file.replace('.test.js', '').replace(/\/|\\/g, '.').replace('.index', '')
15
- }
16
- const root = `./output/test/${folder}`
17
- await fse.remove(path.join(process.cwd(), root))
18
-
19
- try {
20
- const cmdArr = [
21
- 'node --experimental-vm-modules node_modules/jest/bin/jest.js',
22
- file.replace(/\\/g, '/'),
23
- '--coverage',
24
- '--coverageDirectory=' + root + '/coverage'
25
- ]
26
- console.log(cmdArr.join(' '))
27
- execSync(cmdArr.join(' '), {
28
- stdio: 'inherit'
29
- })
30
- } catch (e) {
31
- if (e) {
32
- console.log('\n单元测试失败,调试请查看上述日志')
33
- }
34
- }
35
- return root
36
- }
37
-
38
- export default runTests
@@ -1,23 +0,0 @@
1
- import express from 'express'
2
- import { getPortPromise } from 'portfinder'
3
-
4
- // 启动网页服务显示覆盖率
5
- const startServer = async dir => {
6
- const app = express()
7
- app.use(express.static(dir))
8
- const port = await getPortPromise({ port: 16100, stopPort: 16199 })
9
- const server = await new Promise(resolve => {
10
- const server = app.listen(port, () => {
11
- resolve(server)
12
- })
13
- })
14
- process.on('SIGINT', () => {
15
- server.close(() => {
16
- process.exit(0)
17
- })
18
- })
19
-
20
- return port
21
- }
22
-
23
- export default startServer
package/test-utils/tmp.js DELETED
@@ -1,15 +0,0 @@
1
- import fse from 'fs-extra'
2
- import path from 'path'
3
-
4
- // await fse.remove(path.join(process.cwd(), 'tmp', 'test'))
5
-
6
- export default async namespace => {
7
- namespace = namespace || 'unknown'
8
- const random = Math.random().toString(36).substring(7)
9
- const folderName = namespace + '-' + random
10
- const tmpDir = path.join(process.cwd(), 'tmp', 'test', folderName)
11
-
12
- await fse.ensureDir(tmpDir)
13
-
14
- return tmpDir
15
- }