Skip to content
This repository was archived by the owner on Jan 24, 2023. It is now read-only.

Commit 5bbd00f

Browse files
committed
feat(scaffold): Populate correctly swagger.json
1 parent 63bb7f3 commit 5bbd00f

10 files changed

Lines changed: 309 additions & 17 deletions

File tree

packages/@simpli/cli-scaffold/generator/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ module.exports = (api, options) => {
2929
'normalize-scss': '^7.0.1',
3030
'register-service-worker': '^1.1.1',
3131
'simple-line-icons': '^2.4.1',
32-
'simpli-ts-vue': '^1.1.0',
32+
'simpli-ts-vue': '^1.1.3',
3333
'vue': '^2.5.16',
3434
'vue-chartjs': '^3.2.1',
3535
'vue-chartkick': '^0.2.1',

packages/@simpli/cli-scaffold/generator/template/src/scss/base.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ section {
4242
/* Track */
4343
::-webkit-scrollbar-track {
4444
background: lighten($accent-color, 40%);
45-
border-radius: 0 0 5px 5px;
45+
border-radius: 5px;
4646
}
4747

4848
/* Handle */
4949
::-webkit-scrollbar-thumb {
5050
background: $accent-color;
51-
border-radius: 0 0 5px 5px;
51+
border-radius: 5px;
5252
}
5353

5454
/* Handle on hover */

packages/@simpli/cli-scaffold/generator/template/vue.config.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,17 @@ module.exports = {
1818

1919
// tweak internal webpack configuration.
2020
// see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
21-
chainWebpack: () => {},
21+
chainWebpack: config => {
22+
if (process.env.NODE_ENV === 'production') {
23+
config
24+
.plugin('uglify')
25+
.tap(args => {
26+
args[0].uglifyOptions.keep_classnames = true
27+
args[0].uglifyOptions.keep_fnames = true
28+
return args
29+
})
30+
}
31+
},
2232
configureWebpack: {
2333
resolve: {
2434
alias: {

packages/@simpli/cli/lib/create.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const path = require('path')
33
const chalk = require('chalk')
44
const rimraf = require('rimraf')
55
const inquirer = require('inquirer')
6-
const Scaffold = require('./Scaffold')
6+
const Scaffold = require('./scaffold/Scaffold')
77
const clearConsole = require('./util/clearConsole')
88
const { error, stopSpinner } = require('@vue/cli-shared-utils')
99

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
module.exports = class Attr {
2+
constructor (name, belongsTo, prop) {
3+
this.name = name || ''
4+
this.belongsTo = belongsTo
5+
this.default = prop.default !== undefined ? prop.default : null
6+
this.type = prop.type
7+
this.isArray = false
8+
this.isObject = false
9+
this.isRequired = false
10+
11+
this.setType(prop)
12+
}
13+
14+
setType (entry) {
15+
if (this.name.match(/^(id)\w+(Pk)$/)) {
16+
this.type = 'ID'
17+
} else if (this.name.match(/^(id)\w+(Fk)$/)) {
18+
this.type = 'foreign'
19+
} else if (this.isTAG() && !entry.$ref) {
20+
this.type = 'TAG'
21+
} else if (this.isEmail() && !entry.$ref) {
22+
this.type = 'email'
23+
} else if (this.isPassword() && !entry.$ref) {
24+
this.type = 'password'
25+
} else if (entry.type === 'number') {
26+
if (entry.format === 'double') this.type = 'double'
27+
else this.type = 'integer'
28+
} else if (entry.type === 'string') {
29+
if (entry.format === 'date-time') this.type = 'datetime'
30+
} else if (entry.type === 'array') {
31+
this.isArray = true
32+
this.isObject = false
33+
this.type = entry.items && entry.items.$ref && entry.items.$ref.match(/[^\/]+(?=\/$|$)/)[0]
34+
} else if (entry.type === 'object' || entry.$ref) {
35+
this.isArray = false
36+
this.isObject = true
37+
this.type = entry.$ref && entry.$ref.match(/[^\/]+(?=\/$|$)/)[0]
38+
}
39+
}
40+
41+
// Type Primary
42+
isID () { return this.isPrimaryOrigin() && this.type === 'id' }
43+
isForeign () { return this.isPrimaryOrigin() && this.type === 'foreign' }
44+
isString () { return this.isPrimaryOrigin() && this.type === 'string' }
45+
isInteger () { return this.isPrimaryOrigin() && this.type === 'integer' }
46+
isDouble () { return this.isPrimaryOrigin() && this.type === 'double' }
47+
isBoolean () { return this.isPrimaryOrigin() && this.type === 'boolean' }
48+
isDate () { return this.isPrimaryOrigin() && this.type === 'date' }
49+
isDatetime () { return this.isPrimaryOrigin() && this.type === 'datetime' }
50+
51+
// Type Origin
52+
isPrimaryOrigin () { return this.typeOrigin() === 'primary' }
53+
isArrayOrigin () { return this.typeOrigin() === 'array' }
54+
isObjectOrigin () { return this.typeOrigin() === 'object' }
55+
56+
typeOrigin () {
57+
if (!this.isArray && !this.isObject) {
58+
return 'primary'
59+
} else if (this.isArray && !this.isObject) {
60+
return 'array'
61+
} else if (!this.isArray && this.isObject) {
62+
return 'object'
63+
}
64+
throw new Error(`The attribute '${this.name}' in '${this.belongsTo}' is both array and object`)
65+
}
66+
67+
isTAG () {
68+
const reservedWords = [
69+
'tag',
70+
'label',
71+
'title',
72+
'name',
73+
'titulo',
74+
'nome'
75+
]
76+
return !!reservedWords.find((word) => word === this.name)
77+
}
78+
79+
isEmail () {
80+
const reservedWords = [
81+
'email',
82+
'e-mail',
83+
'mail'
84+
]
85+
return !!reservedWords.find((word) => word === this.name)
86+
}
87+
88+
isPassword () {
89+
const reservedWords = [
90+
'password',
91+
'senha'
92+
]
93+
return !!reservedWords.find((word) => word === this.name)
94+
}
95+
96+
validations () {
97+
const result = []
98+
99+
if (this.isRequired) {
100+
result.push({
101+
title: 'ValidationRequired',
102+
attr: []
103+
})
104+
}
105+
106+
if (this.isString()) {
107+
result.push({
108+
title: 'MaxLength',
109+
attr: [255]
110+
})
111+
}
112+
113+
if (this.isEmail()) {
114+
result.push({
115+
title: 'ValidationEmail',
116+
attr: []
117+
})
118+
}
119+
120+
if (this.isPassword()) {
121+
result.push({
122+
title: 'ValidationPasswordLength',
123+
attr: [6, 31]
124+
})
125+
result.push({
126+
title: 'ResponseHidden',
127+
attr: []
128+
})
129+
}
130+
131+
return result
132+
}
133+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
const map = require('lodash.map')
2+
const Attr = require('./Attr')
3+
4+
module.exports = class Resource {
5+
constructor (name, definition, path) {
6+
this.name = name || ''
7+
this.endpoint = null
8+
this.endpointParams = []
9+
this.keyID = null
10+
this.keyTAG = null
11+
this.isResponse = null
12+
this.isPagedResponse = null
13+
this.child = null
14+
this.attrs = []
15+
16+
this.setAttr(name, definition.properties, definition.required)
17+
this.setResponse()
18+
this.setEndpoint(path)
19+
this.setKey()
20+
}
21+
22+
onlyObjects () {
23+
return this.attrs.filter((resource) => resource.isObject)
24+
}
25+
26+
onlyArrays () {
27+
return this.attrs.filter((resource) => resource.isArray)
28+
}
29+
30+
onlyRequired () {
31+
return this.attrs.filter((resource) => resource.isRequired)
32+
}
33+
34+
setAttr (belongsTo, property = {}, required = []) {
35+
const attrs = map(property, (prop, name) => new Attr(name, belongsTo, prop)) || []
36+
37+
required.forEach((name) => {
38+
const attr = attrs.find((attr) => attr.name === name)
39+
attr.isRequired = true
40+
})
41+
42+
this.attrs = attrs
43+
}
44+
45+
setEndpoint (path) {
46+
// Get WS endpoint
47+
const wsEndpoint = Object.keys(path).find((endpoint) => {
48+
const regex = new RegExp(`^\/\\w+\/(?:${this.child || this.name})(?:\/\{\\w+\})+$`, 'g')
49+
return endpoint.match(regex)
50+
}) || ''
51+
52+
// Populate endpointParams
53+
const params = /{([^}]+)}/g
54+
let matchParams
55+
do {
56+
matchParams = params.exec(wsEndpoint)
57+
if (matchParams) this.endpointParams.push(matchParams[1])
58+
} while (matchParams)
59+
60+
// Set endpoint
61+
const dir = /\/\w+[^\/]/g
62+
let matchDir
63+
do {
64+
matchDir = dir.exec(wsEndpoint)
65+
if (matchDir) {
66+
if (!this.endpoint) this.endpoint = ''
67+
this.endpoint += matchDir[0]
68+
}
69+
} while (matchDir)
70+
71+
this.endpointParams.forEach((params) => {
72+
this.endpoint += `{/${params}}`
73+
})
74+
}
75+
76+
setResponse () {
77+
this.isResponse = false
78+
this.isPagedResponse = false
79+
80+
if (this.name.match(/^\w+(Resp)$/)) {
81+
this.isResponse = true
82+
this.isPagedResponse = false
83+
} if (this.name.match(/^(PagedResp)\w+$/)) {
84+
this.isResponse = false
85+
this.isPagedResponse = true
86+
}
87+
88+
if (this.isResponse && this.onlyObjects()[0]) {
89+
this.child = this.onlyObjects()[0].type
90+
}
91+
}
92+
93+
setKey () {
94+
if (!this.child) {
95+
const keyID = this.attrs.find((attr) => attr.type === 'ID')
96+
const keyTAG = this.attrs.find((attr) => attr.type === 'TAG')
97+
98+
this.keyID = keyID ? keyID.name : null
99+
this.keyTAG = keyTAG ? keyTAG.name : null
100+
} else if (this.onlyObjects()[0]) {
101+
this.keyID = `${this.onlyObjects()[0].name}.$id`
102+
this.keyTAG = `${this.onlyObjects()[0].name}.$tag`
103+
}
104+
}
105+
}

packages/@simpli/cli/lib/Scaffold.js renamed to packages/@simpli/cli/lib/scaffold/Scaffold.js

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ const debug = require('debug')
44
const execa = require('execa')
55
const resolve = require('resolve')
66
const inquirer = require('inquirer')
7-
const Generator = require('./Generator')
7+
const Generator = require('../Generator')
8+
const SwaggerSetup = require('./SwaggerSetup')
89
const cloneDeep = require('lodash.clonedeep')
9-
const sortObject = require('./util/sortObject')
10-
const getVersions = require('./util/getVersions')
11-
const { installDeps } = require('./util/installDeps')
12-
const clearConsole = require('./util/clearConsole')
13-
const PromptModuleAPI = require('./PromptModuleAPI')
14-
const writeFileTree = require('./util/writeFileTree')
15-
const formatFeatures = require('./util/formatFeatures')
16-
const fetchRemotePreset = require('./util/fetchRemotePreset')
17-
const request = require('./util/request.js')
10+
const sortObject = require('../util/sortObject')
11+
const getVersions = require('../util/getVersions')
12+
const { installDeps } = require('../util/installDeps')
13+
const clearConsole = require('../util/clearConsole')
14+
const PromptModuleAPI = require('../PromptModuleAPI')
15+
const writeFileTree = require('../util/writeFileTree')
16+
const formatFeatures = require('../util/formatFeatures')
17+
const fetchRemotePreset = require('../util/fetchRemotePreset')
18+
const request = require('../util/request.js')
1819

1920
const {
2021
log,
@@ -31,7 +32,8 @@ module.exports = class Scaffold {
3132
constructor (name, context, promptModules) {
3233
this.name = name
3334
this.context = process.env.SIMPLI_CLI_CONTEXT = context
34-
this.swaggerSetup = {}
35+
this.swaggerJSON = {}
36+
this.swaggerSetup = new SwaggerSetup()
3537
const { presetPrompt, featurePrompt } = this.resolveIntroPrompts()
3638
this.presetPrompt = presetPrompt
3739
this.featurePrompt = featurePrompt
@@ -55,7 +57,18 @@ module.exports = class Scaffold {
5557

5658
try {
5759
const resp = await request.get(url)
58-
this.swaggerSetup = resp.body
60+
this.swaggerJSON = resp.body
61+
62+
const { swagger, info, paths, definitions } = this.swaggerJSON
63+
64+
if (!swagger) {
65+
throw new Error('This file is not a valid Swagger')
66+
}
67+
68+
// Remove last directory of the URL
69+
this.swaggerSetup.apiUrl = url.replace(/\/([^\/]+)\/?$/, '/')
70+
this.swaggerSetup.title = info && info.title
71+
this.swaggerSetup.setResources(definitions, paths)
5972
} catch (e) {
6073
error(e.message)
6174
process.exit(1)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const map = require('lodash.map')
2+
const Resource = require('./Resource')
3+
4+
module.exports = class SwaggerSetup {
5+
constructor () {
6+
this.title = null
7+
this.apiUrl = null
8+
this.resources = []
9+
}
10+
11+
nonResponses () {
12+
return this.resources.filter((resource) => !resource.isResponse && !resource.isPagedResponse)
13+
}
14+
15+
onlyResourceResponses () {
16+
return this.resources.filter((resource) => resource.isResponse)
17+
}
18+
19+
onlyPagedResponses () {
20+
return this.resources.filter((resource) => resource.isPagedResponse)
21+
}
22+
23+
setResources (definition = {}, path = {}) {
24+
this.resources = map(definition, (def, name) => new Resource(name, def, path)) || []
25+
}
26+
}

packages/@simpli/cli/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"javascript-stringify": "^1.6.0",
3535
"js-yaml": "^3.10.0",
3636
"klaw-sync": "^3.0.2",
37+
"lodash.map": "^4.5.0",
3738
"lodash.clonedeep": "^4.5.0",
3839
"minimist": "^1.2.0",
3940
"mkdirp": "^0.5.1",

yarn.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3399,6 +3399,10 @@ lodash.clonedeep@^4.5.0:
33993399
version "4.5.0"
34003400
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
34013401

3402+
lodash.map@^4.5.0:
3403+
version "4.6.0"
3404+
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
3405+
34023406
lodash.sortby@^4.7.0:
34033407
version "4.7.0"
34043408
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"

0 commit comments

Comments
 (0)