mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-19 08:02:55 +00:00
feat: add the uml generator
This commit is contained in:
@@ -21,6 +21,21 @@ build:
|
||||
paths:
|
||||
- lib
|
||||
|
||||
package:
|
||||
dependencies:
|
||||
- build
|
||||
tags:
|
||||
- secrecy
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "//registry.npmjs.org/:_authToken=$NPM_AUTH_TOKEN" > /root/.npmrc
|
||||
- npm publish
|
||||
only:
|
||||
- /^v[0-9]+.[0-9]+.[0-9]+$/
|
||||
artifacts:
|
||||
paths:
|
||||
- lib
|
||||
|
||||
test:
|
||||
tags:
|
||||
- docker
|
||||
@@ -71,6 +86,18 @@ package:
|
||||
paths:
|
||||
- lib
|
||||
|
||||
uml:
|
||||
cache: {}
|
||||
dependencies:
|
||||
- build
|
||||
stage: test
|
||||
image: node:10
|
||||
services:
|
||||
- name: registry.gitlab.com/openstapps/core-tools:latest
|
||||
alias: plantuml
|
||||
script:
|
||||
- node lib/cli.js plantuml test/model http://plantuml:8080 --showProperties --showOptionalProperties --showInheritedProperties --showEnumValues --showAssociations --showInheritance --excludeExternals
|
||||
|
||||
pages:
|
||||
stage: deploy
|
||||
script:
|
||||
|
||||
1
Dockerfile
Normal file
1
Dockerfile
Normal file
@@ -0,0 +1 @@
|
||||
FROM plantuml/plantuml-server:tomcat
|
||||
65
README.md
65
README.md
@@ -1,6 +1,6 @@
|
||||
# @openstapps/core-tools
|
||||
|
||||
[](https://gitlab.com/openstapps/core-tools/commits/master)
|
||||
[](https://gitlab.com/openstapps/core-tools/commits/master)
|
||||
[](https://npmjs.com/package/@openstapps/core-tools)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
[](https://openstapps.gitlab.io/core-tools)
|
||||
@@ -15,7 +15,7 @@ JSON schema files are needed for run-time validation of SC-type objects, as this
|
||||
|
||||
The StAppsCore Validator is a tool for run-time validation of objects (determining whether a JavaScript/JSON object is a valid object of the corresponding SC-type. It consumes JSON schema files from StAppsCore as the definitions of SC-types against which are validated concrete (actual) objects (as an example SCDish object in the example below).
|
||||
|
||||
## Installation
|
||||
## Installation
|
||||
|
||||
Installation of the npm package (using `npm install`) makes the tool available as an executable with the name `openstapps-core-tools`.
|
||||
|
||||
@@ -57,7 +57,7 @@ import {join} from 'path';
|
||||
|
||||
const objectToValidate: SCDish = {
|
||||
type: SCThingType.Dish,
|
||||
// more properties
|
||||
// more properties
|
||||
};
|
||||
|
||||
// instantiate a new validator
|
||||
@@ -127,7 +127,7 @@ Inside of a script in `package.json` or if the npm package is installed globally
|
||||
openstapps-core-tools validate lib/schema src/test/resources report.html
|
||||
```
|
||||
|
||||
## Generate documentation for routes
|
||||
## Generate documentation for routes
|
||||
|
||||
To generate a documentation for the routes use the following command.
|
||||
|
||||
@@ -142,3 +142,60 @@ To pack all the different files into two distribution files - one for definition
|
||||
```shell
|
||||
openstapps-core-tools pack
|
||||
```
|
||||
|
||||
## How to use the UML generator
|
||||
|
||||
The UML Generator generates PlantUML from the project reflection of the source files. By default it will include externals, which will take considerably longer to execute, you can disable this behaviour via an option. It can help you to visually explore the data model or document a specific part.
|
||||
|
||||
You can either use the public PlantUML-server or start your own local instance. To build the image and run, restart or stop the container use the scripts provided in the `package.json`.
|
||||
|
||||
### Generating from source-files
|
||||
|
||||
```shell
|
||||
openstapps-core-tools plantuml PATH/TO/SOURCEFILES http://PLANTUMLSERVER
|
||||
```
|
||||
|
||||
Executing this command will generate a `.svg` file in your current working directory.
|
||||
|
||||
Multiple options can be set to enhance the diagram. By default all additional information other than the definitions are disabled. You can use:
|
||||
|
||||
- `--showProperties` to show all mandatory attributes of the classes and interfaces.
|
||||
- `--showOptionalProperties` to show all mandatory attributes of the classes and interfaces. `--showProperties` must be set!
|
||||
- `--showEnumValues` to show all enumeration and type (enumeration-like) values
|
||||
- `--showInheritance` to show the hierarchy of the classes and interfaces. Inherited attributes will only be shown in their parent.
|
||||
- `--showAssociations` to show all references of classes and interfaces between one another
|
||||
- `--excludeExternals` to exclude external definitions
|
||||
- `--definitions <definitons>` to show only specific definitions to reduce the output of the diagram. `<definitions>` is a comma seperated list of definitions.
|
||||
|
||||
The best way to explore models is to enable `--showInheritance` and `--showAssociations`. Start with just one definition in your `--definition <definitions>`-list, generate the diagram, look at it, add a new definition that you have seen to your command and generate anew.
|
||||
|
||||
#### Examples
|
||||
|
||||
Show the class hierarchy of the whole project:
|
||||
|
||||
```shell
|
||||
openstapps-core-tools plantuml PATH/TO/SRCDIR http://PLANTUMLSERVER --showInheritance
|
||||
```
|
||||
|
||||
Show the dish-module:
|
||||
|
||||
```shell
|
||||
openstapps-core-tools plantuml ../core http://localhost:8080 --showProperties --showOptionalProperties --showInheritance --showAssociations --showEnumValues --definitions SCDish,SCThingThatCanBeOfferedOffer
|
||||
```
|
||||
|
||||
### Generating from existing file
|
||||
|
||||
The plantuml code is persisted inside the generated filea at the very bottom. You can tweak the model by using the function to generate UML from a PlantUML-file(simple text file). Extract the code (starting from `@startuml` to `@enduml`), edit it manually and execute the function.
|
||||
|
||||
```shell
|
||||
openstapps-core-tools plantuml-file /PATH/TO/Project.plantuml http://PLANTUMLSERVER
|
||||
```
|
||||
|
||||
Example-File-Content of Project.plantuml
|
||||
```
|
||||
@startuml
|
||||
interface MyClass{
|
||||
myProperty: string
|
||||
}
|
||||
@enduml
|
||||
```
|
||||
|
||||
334
package-lock.json
generated
334
package-lock.json
generated
@@ -75,6 +75,19 @@
|
||||
"nodemailer": "6.2.1"
|
||||
}
|
||||
},
|
||||
"@sindresorhus/is": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
|
||||
"integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ=="
|
||||
},
|
||||
"@szmarczak/http-timer": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
|
||||
"integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
|
||||
"requires": {
|
||||
"defer-to-connect": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"@types/chai": {
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz",
|
||||
@@ -104,6 +117,15 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/got": {
|
||||
"version": "9.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/got/-/got-9.4.4.tgz",
|
||||
"integrity": "sha512-IGAJokJRE9zNoBdY5csIwN4U5qQn+20HxC0kM+BbUdfTKIXa7bOX/pdhy23NnLBRP8Wvyhx7X5e6EHJs+4d8HA==",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/tough-cookie": "*"
|
||||
}
|
||||
},
|
||||
"@types/handlebars": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/handlebars/-/handlebars-4.1.0.tgz",
|
||||
@@ -143,6 +165,15 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz",
|
||||
"integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA=="
|
||||
},
|
||||
"@types/nock": {
|
||||
"version": "10.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/nock/-/nock-10.0.2.tgz",
|
||||
"integrity": "sha512-jOdoZ3zVLmPWZOoPJDoks+Zo6GsogdZuVBWs8/prWau993qno5PPtukVXKfc+WtS/ROgTPWpiru92z2K6KFYgQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "10.14.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.8.tgz",
|
||||
@@ -181,6 +212,11 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/tough-cookie": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz",
|
||||
"integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg=="
|
||||
},
|
||||
"@types/yaml": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/yaml/-/yaml-1.0.2.tgz",
|
||||
@@ -315,6 +351,30 @@
|
||||
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
|
||||
"dev": true
|
||||
},
|
||||
"cacheable-request": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.0.0.tgz",
|
||||
"integrity": "sha512-2N7AmszH/WPPpl5Z3XMw1HAP+8d+xugnKQAeKvxFZ/04dbT/CAznqwbl+7eSr3HkwdepNwtb2yx3CAMQWvG01Q==",
|
||||
"requires": {
|
||||
"clone-response": "^1.0.2",
|
||||
"get-stream": "^4.0.0",
|
||||
"http-cache-semantics": "^4.0.0",
|
||||
"keyv": "^3.0.0",
|
||||
"lowercase-keys": "^1.0.1",
|
||||
"normalize-url": "^3.1.0",
|
||||
"responselike": "^1.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
|
||||
"requires": {
|
||||
"pump": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
|
||||
@@ -371,6 +431,14 @@
|
||||
"wrap-ansi": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"clone-response": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
|
||||
"integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
|
||||
"requires": {
|
||||
"mimic-response": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
@@ -554,9 +622,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"conventional-changelog-writer": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.6.tgz",
|
||||
"integrity": "sha512-ou/sbrplJMM6KQpR5rKFYNVQYesFjN7WpNGdudQSWNi6X+RgyFUcSv871YBYkrUYV9EX8ijMohYVzn9RUb+4ag==",
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.5.tgz",
|
||||
"integrity": "sha512-g/Myp4MaJ1A+f7Ai+SnVhkcWtaHk6flw0SYN7A+vQ+MTu0+gSovQWs4Pg4NtcNUcIztYQ9YHsoxHP+GGQplI7Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"compare-func": "^1.3.1",
|
||||
@@ -566,7 +634,7 @@
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"lodash": "^4.2.1",
|
||||
"meow": "^4.0.0",
|
||||
"semver": "^6.0.0",
|
||||
"semver": "^5.5.0",
|
||||
"split": "^1.0.0",
|
||||
"through2": "^3.0.0"
|
||||
}
|
||||
@@ -582,13 +650,13 @@
|
||||
}
|
||||
},
|
||||
"conventional-commits-parser": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.3.tgz",
|
||||
"integrity": "sha512-KaA/2EeUkO4bKjinNfGUyqPTX/6w9JGshuQRik4r/wJz7rUw3+D3fDG6sZSEqJvKILzKXFQuFkpPLclcsAuZcg==",
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.2.tgz",
|
||||
"integrity": "sha512-y5eqgaKR0F6xsBNVSQ/5cI5qIF3MojddSUi1vKIggRkqUTbkqFKH9P5YX/AT1BVZp9DtSzBTIkvjyVLotLsVog==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"JSONStream": "^1.0.4",
|
||||
"is-text-path": "^2.0.0",
|
||||
"is-text-path": "^1.0.0",
|
||||
"lodash": "^4.2.1",
|
||||
"meow": "^4.0.0",
|
||||
"split2": "^2.0.0",
|
||||
@@ -688,6 +756,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
|
||||
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
|
||||
"requires": {
|
||||
"mimic-response": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"deep-eql": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
|
||||
@@ -696,6 +772,17 @@
|
||||
"type-detect": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"deep-equal": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
|
||||
"integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
|
||||
"dev": true
|
||||
},
|
||||
"defer-to-connect": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.0.2.tgz",
|
||||
"integrity": "sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw=="
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
||||
@@ -751,6 +838,11 @@
|
||||
"is-obj": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"duplexer3": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
|
||||
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||
@@ -761,7 +853,6 @@
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
@@ -1154,36 +1245,6 @@
|
||||
"through2": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
@@ -1273,6 +1334,34 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"got": {
|
||||
"version": "9.6.0",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
|
||||
"integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
|
||||
"requires": {
|
||||
"@sindresorhus/is": "^0.14.0",
|
||||
"@szmarczak/http-timer": "^1.1.2",
|
||||
"cacheable-request": "^6.0.0",
|
||||
"decompress-response": "^3.3.0",
|
||||
"duplexer3": "^0.1.4",
|
||||
"get-stream": "^4.1.0",
|
||||
"lowercase-keys": "^1.0.1",
|
||||
"mimic-response": "^1.0.1",
|
||||
"p-cancelable": "^1.0.0",
|
||||
"to-readable-stream": "^1.0.0",
|
||||
"url-parse-lax": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
|
||||
"requires": {
|
||||
"pump": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.1.15",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
|
||||
@@ -1332,6 +1421,11 @@
|
||||
"integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
|
||||
"dev": true
|
||||
},
|
||||
"http-cache-semantics": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz",
|
||||
"integrity": "sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew=="
|
||||
},
|
||||
"humanize-string": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/humanize-string/-/humanize-string-2.1.0.tgz",
|
||||
@@ -1516,6 +1610,11 @@
|
||||
"esprima": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"json-buffer": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
|
||||
"integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg="
|
||||
},
|
||||
"json-parse-better-errors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
||||
@@ -1565,6 +1664,14 @@
|
||||
"resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.4.tgz",
|
||||
"integrity": "sha512-lz1nOH69GbsVHeVgEdvyavc/33oymY1AZwtePMiMj4HZPMbP5OIKK3zT9INMWjwua/V4Z4yq7wSlBbSG+g4AEw=="
|
||||
},
|
||||
"keyv": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
|
||||
"integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
|
||||
"requires": {
|
||||
"json-buffer": "3.0.0"
|
||||
}
|
||||
},
|
||||
"lcid": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
|
||||
@@ -1659,6 +1766,11 @@
|
||||
"signal-exit": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lowercase-keys": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
|
||||
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
|
||||
@@ -1736,6 +1848,11 @@
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
||||
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
@@ -2051,6 +2168,34 @@
|
||||
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
|
||||
"dev": true
|
||||
},
|
||||
"nock": {
|
||||
"version": "10.0.6",
|
||||
"resolved": "https://registry.npmjs.org/nock/-/nock-10.0.6.tgz",
|
||||
"integrity": "sha512-b47OWj1qf/LqSQYnmokNWM8D88KvUl2y7jT0567NB3ZBAZFz2bWp2PC81Xn7u8F2/vJxzkzNZybnemeFa7AZ2w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chai": "^4.1.2",
|
||||
"debug": "^4.1.0",
|
||||
"deep-equal": "^1.0.0",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"lodash": "^4.17.5",
|
||||
"mkdirp": "^0.5.0",
|
||||
"propagate": "^1.0.0",
|
||||
"qs": "^6.5.1",
|
||||
"semver": "^5.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-environment-flags": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz",
|
||||
@@ -2094,6 +2239,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"normalize-url": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
|
||||
"integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg=="
|
||||
},
|
||||
"npm-run-path": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
|
||||
@@ -2176,6 +2326,11 @@
|
||||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||
"dev": true
|
||||
},
|
||||
"p-cancelable": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
|
||||
"integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw=="
|
||||
},
|
||||
"p-defer": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
|
||||
@@ -2223,6 +2378,11 @@
|
||||
"integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
|
||||
"dev": true
|
||||
},
|
||||
"pako": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.3.tgz",
|
||||
"integrity": "sha1-X1FbDGci4ZgpIK6ABerLC3ynPM8="
|
||||
},
|
||||
"parse-github-repo-url": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz",
|
||||
@@ -2306,6 +2466,15 @@
|
||||
"pinkie": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"plantuml-encoder": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/plantuml-encoder/-/plantuml-encoder-1.2.5.tgz",
|
||||
"integrity": "sha512-viV7Sz+BJNX/sC3iyebh2VfLyAZKuu3+JuBs2ISms8+zoTGwPqwk3/WEDw/zROmGAJ/xD4sNd8zsBw/YmTo7ng==",
|
||||
"requires": {
|
||||
"pako": "1.0.3",
|
||||
"utf8-bytes": "0.0.1"
|
||||
}
|
||||
},
|
||||
"prepend-file": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/prepend-file/-/prepend-file-1.3.1.tgz",
|
||||
@@ -2333,6 +2502,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"prepend-http": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
|
||||
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
@@ -2344,6 +2518,12 @@
|
||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
|
||||
},
|
||||
"propagate": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz",
|
||||
"integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=",
|
||||
"dev": true
|
||||
},
|
||||
"pseudomap": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||
@@ -2354,7 +2534,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
@@ -2371,6 +2550,12 @@
|
||||
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
|
||||
"dev": true
|
||||
},
|
||||
"quick-lru": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz",
|
||||
@@ -2462,6 +2647,14 @@
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"responselike": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
|
||||
"integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
|
||||
"requires": {
|
||||
"lowercase-keys": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
|
||||
@@ -2583,36 +2776,6 @@
|
||||
"through2": "^2.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
@@ -2642,9 +2805,9 @@
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
|
||||
"integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@@ -2731,6 +2894,11 @@
|
||||
"os-tmpdir": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"to-readable-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q=="
|
||||
},
|
||||
"toposort": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||
@@ -2757,13 +2925,6 @@
|
||||
"glob": "~7.1.4",
|
||||
"json-stable-stringify": "^1.0.1",
|
||||
"typescript": "~3.4.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"typescript": {
|
||||
"version": "3.4.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz",
|
||||
"integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
@@ -2926,6 +3087,19 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"url-parse-lax": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
|
||||
"integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
|
||||
"requires": {
|
||||
"prepend-http": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"utf8-bytes": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utf8-bytes/-/utf8-bytes-0.0.1.tgz",
|
||||
"integrity": "sha1-EWsCVEjJtQAIHN+/H01sbDfYg30="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
"check-configuration": "openstapps-configuration",
|
||||
"compile": "rimraf lib && tsc && prepend lib/cli.js '#!/usr/bin/env node\n'",
|
||||
"documentation": "typedoc --includeDeclarations --mode modules --out docs --readme README.md --listInvalidSymbolLinks src",
|
||||
"plantuml-build": "docker build -t openstapps/plantuml-server .",
|
||||
"plantuml-start": "docker run --name plantuml-server -d -p 8080:8080 openstapps/plantuml-server",
|
||||
"plantuml-restart": "docker restart plantuml-server",
|
||||
"plantuml-stop": "docker stop plantuml-server",
|
||||
"postversion": "npm run changelog",
|
||||
"prepublishOnly": "npm ci && npm run build",
|
||||
"preversion": "npm run prepublishOnly",
|
||||
@@ -44,6 +48,7 @@
|
||||
"@krlwlfrt/async-pool": "0.1.0",
|
||||
"@openstapps/logger": "0.3.1",
|
||||
"@types/glob": "7.1.1",
|
||||
"@types/got": "9.4.4",
|
||||
"@types/mustache": "0.8.32",
|
||||
"@types/node": "10.14.8",
|
||||
"ajv": "6.10.0",
|
||||
@@ -51,9 +56,11 @@
|
||||
"commander": "2.20.0",
|
||||
"del": "4.1.1",
|
||||
"glob": "7.1.4",
|
||||
"got": "9.6.0",
|
||||
"humanize-string": "2.1.0",
|
||||
"jsonschema": "1.2.4",
|
||||
"mustache": "3.0.1",
|
||||
"plantuml-encoder": "1.2.5",
|
||||
"toposort": "2.0.2",
|
||||
"ts-json-schema-generator": "0.42.0",
|
||||
"ts-node": "8.2.0",
|
||||
@@ -64,9 +71,11 @@
|
||||
"@types/chai": "4.1.7",
|
||||
"@types/mocha": "5.2.7",
|
||||
"@types/rimraf": "2.0.2",
|
||||
"@types/nock": "10.0.2",
|
||||
"conventional-changelog-cli": "2.0.21",
|
||||
"mocha": "6.1.4",
|
||||
"mocha-typescript": "1.1.17",
|
||||
"nock": "10.0.6",
|
||||
"prepend-file-cli": "1.0.6",
|
||||
"rimraf": "2.6.3",
|
||||
"tslint": "5.17.0",
|
||||
|
||||
104
src/cli.ts
104
src/cli.ts
@@ -16,10 +16,22 @@ import {Logger} from '@openstapps/logger';
|
||||
import * as commander from 'commander';
|
||||
import {existsSync, readFileSync, writeFileSync} from 'fs';
|
||||
import {join, resolve} from 'path';
|
||||
import {getProjectReflection, mkdirPromisified, readFilePromisified} from './common';
|
||||
import {
|
||||
getProjectReflection,
|
||||
mkdirPromisified,
|
||||
readFilePromisified,
|
||||
toArray,
|
||||
} from './common';
|
||||
import {pack} from './pack';
|
||||
import {gatherRouteInformation, generateDocumentationForRoute, getNodeMetaInformationMap} from './routes';
|
||||
import {
|
||||
gatherRouteInformation,
|
||||
generateDocumentationForRoute,
|
||||
getNodeMetaInformationMap,
|
||||
} from './routes';
|
||||
import {Converter, getValidatableTypesFromReflection} from './schema';
|
||||
import {createDiagram, createDiagramFromString} from './uml/createDiagram';
|
||||
import {readDefinitions} from './uml/readDefinitions';
|
||||
import {UMLConfig} from './uml/umlConfig';
|
||||
import {validateFiles, writeReport} from './validate';
|
||||
|
||||
// handle unhandled promise rejections
|
||||
@@ -53,7 +65,10 @@ commander
|
||||
|
||||
// generate documentation for all routes
|
||||
routes.forEach((routeWithMetaInformation) => {
|
||||
output += generateDocumentationForRoute(routeWithMetaInformation, getNodeMetaInformationMap(projectReflection));
|
||||
output += generateDocumentationForRoute(
|
||||
routeWithMetaInformation,
|
||||
getNodeMetaInformationMap(projectReflection),
|
||||
);
|
||||
});
|
||||
|
||||
// write documentation to file
|
||||
@@ -76,7 +91,9 @@ commander
|
||||
const projectReflection = getProjectReflection(srcPath);
|
||||
|
||||
// get validatable types
|
||||
const validatableTypes = getValidatableTypesFromReflection(projectReflection);
|
||||
const validatableTypes = getValidatableTypesFromReflection(
|
||||
projectReflection,
|
||||
);
|
||||
|
||||
Logger.info(`Found ${validatableTypes.length} type(s) to generate schemas for.`);
|
||||
|
||||
@@ -152,14 +169,85 @@ commander
|
||||
}
|
||||
});
|
||||
|
||||
commander.command('pack').action(async () => {
|
||||
await pack();
|
||||
});
|
||||
|
||||
commander
|
||||
.command('pack')
|
||||
.action(async () => {
|
||||
await pack();
|
||||
.command('plantuml <srcPath> <plantumlserver>')
|
||||
.option(
|
||||
'--definitions <definitions>',
|
||||
'Shows these specific definitions (class or enum)',
|
||||
toArray,
|
||||
)
|
||||
.option('--showAssociations', 'Shows associations of classes')
|
||||
.option(
|
||||
'--showInheritance',
|
||||
'Shows extensions and implementations of classes',
|
||||
)
|
||||
.option('--showEnumValues', 'Show enum values')
|
||||
.option('--showProperties', 'Show attributes')
|
||||
.option(
|
||||
'--showInheritedProperties',
|
||||
'Shows inherited attributes, needs --showProperties',
|
||||
)
|
||||
.option(
|
||||
'--showOptionalProperties',
|
||||
'Shows optional attributes and relations, needs --showProperties',
|
||||
)
|
||||
.option(
|
||||
'--excludeExternals',
|
||||
'Exclude external definitions',
|
||||
)
|
||||
.action(async (relativeSrcPath, plantumlserver, options) => {
|
||||
const plantUmlConfig: UMLConfig = {
|
||||
definitions:
|
||||
typeof options.definitions !== 'undefined' ? options.definitions : [],
|
||||
showAssociations:
|
||||
typeof options.showAssociations !== 'undefined'
|
||||
? options.showAssociations
|
||||
: false,
|
||||
showEnumValues:
|
||||
typeof options.showEnumValues !== 'undefined'
|
||||
? options.showEnumValues
|
||||
: false,
|
||||
showInheritance:
|
||||
typeof options.showInheritance !== 'undefined'
|
||||
? options.showInheritance
|
||||
: false,
|
||||
showInheritedProperties:
|
||||
typeof options.showInheritedProperties !== 'undefined'
|
||||
? options.showInheritedProperties
|
||||
: false,
|
||||
showOptionalProperties:
|
||||
typeof options.showOptionalProperties !== 'undefined'
|
||||
? options.showOptionalProperties
|
||||
: false,
|
||||
showProperties:
|
||||
typeof options.showProperties !== 'undefined'
|
||||
? options.showEnumValues
|
||||
: false,
|
||||
};
|
||||
|
||||
Logger.log(`PlantUML options: ${JSON.stringify(plantUmlConfig)}`);
|
||||
|
||||
const srcPath = resolve(relativeSrcPath);
|
||||
|
||||
const projectReflection = getProjectReflection(srcPath, !options.excludeExternals ? false : true);
|
||||
|
||||
const definitions = readDefinitions(projectReflection);
|
||||
|
||||
await createDiagram(definitions, plantUmlConfig, plantumlserver);
|
||||
});
|
||||
|
||||
commander
|
||||
.parse(process.argv);
|
||||
.command('plantuml-file <file> <plantumlserver>')
|
||||
.action(async (file: string, plantumlserver: string) => {
|
||||
const fileContent = readFileSync(resolve(file)).toString();
|
||||
await createDiagramFromString(fileContent, plantumlserver);
|
||||
});
|
||||
|
||||
commander.parse(process.argv);
|
||||
|
||||
if (commander.args.length < 1) {
|
||||
commander.outputHelp();
|
||||
|
||||
@@ -21,6 +21,7 @@ import {join, sep} from 'path';
|
||||
import {Definition} from 'ts-json-schema-generator';
|
||||
import {Application, ProjectReflection} from 'typedoc';
|
||||
import {promisify} from 'util';
|
||||
import {LightweightType} from './uml/model/LightweightType';
|
||||
|
||||
export const globPromisified = promisify(glob);
|
||||
export const mkdirPromisified = promisify(mkdir);
|
||||
@@ -142,14 +143,14 @@ export interface ExpectableValidationErrors {
|
||||
*
|
||||
* @param srcPath Path to get reflection from
|
||||
*/
|
||||
export function getProjectReflection(srcPath: PathLike): ProjectReflection {
|
||||
export function getProjectReflection(srcPath: PathLike, excludeExternals: boolean = true): ProjectReflection {
|
||||
Logger.info(`Generating project reflection for ${srcPath.toString()}.`);
|
||||
|
||||
const tsconfigPath = getTsconfigPath(srcPath.toString());
|
||||
|
||||
// initialize new Typedoc application
|
||||
const app = new Application({
|
||||
excludeExternals: true,
|
||||
excludeExternals: excludeExternals,
|
||||
includeDeclarations: true,
|
||||
module: 'commonjs',
|
||||
tsconfig: join(tsconfigPath, 'tsconfig.json'),
|
||||
@@ -178,7 +179,9 @@ export function getProjectReflection(srcPath: PathLike): ProjectReflection {
|
||||
*
|
||||
* @param schema Schema to check
|
||||
*/
|
||||
export function isSchemaWithDefinitions(schema: JSONSchema): schema is SchemaWithDefinitions {
|
||||
export function isSchemaWithDefinitions(
|
||||
schema: JSONSchema,
|
||||
): schema is SchemaWithDefinitions {
|
||||
return typeof schema.definitions !== 'undefined';
|
||||
}
|
||||
|
||||
@@ -212,7 +215,9 @@ export function getTsconfigPath(startPath: string): string {
|
||||
// repeat until a tsconfig.json is found
|
||||
while (!existsSync(join(tsconfigPath, 'tsconfig.json'))) {
|
||||
if (tsconfigPath === root) {
|
||||
throw new Error(`Reached file system root ${root} while searching for 'tsconfig.json' in ${startPath}!`);
|
||||
throw new Error(
|
||||
`Reached file system root ${root} while searching for 'tsconfig.json' in ${startPath}!`,
|
||||
);
|
||||
}
|
||||
|
||||
// pop last directory
|
||||
@@ -225,3 +230,51 @@ export function getTsconfigPath(startPath: string): string {
|
||||
|
||||
return tsconfigPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a comma seperated string into a string array
|
||||
*
|
||||
* @param val Comma seperated string
|
||||
*/
|
||||
export function toArray(val: string): string[] {
|
||||
return val.split(',');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the full name of a lightweight type recursivly
|
||||
*
|
||||
* @param type Type to get the full name of
|
||||
*/
|
||||
export function getFullTypeName(type: LightweightType): string {
|
||||
// init name
|
||||
let fullName: string = type.name;
|
||||
if (type.isTypeParameter) {
|
||||
// type parameters are a sink
|
||||
return fullName;
|
||||
}
|
||||
if (type.isLiteral) {
|
||||
// literals are a sink
|
||||
return "'" + fullName + "'";
|
||||
}
|
||||
if (type.isUnion && type.specificationTypes.length > 0) {
|
||||
const tempNames: string[] = [];
|
||||
for (const easyType of type.specificationTypes) {
|
||||
tempNames.push(getFullTypeName(easyType));
|
||||
}
|
||||
// since unions can't be applied to other types, it is a sink.
|
||||
return tempNames.join(' | ');
|
||||
}
|
||||
// check if type is generic and has a type attached
|
||||
if (type.isTyped && type.genericsTypes.length > 0) {
|
||||
const tempNames: string[] = [];
|
||||
for (const easyType of type.genericsTypes) {
|
||||
tempNames.push(getFullTypeName(easyType));
|
||||
}
|
||||
fullName += '<' + tempNames.join(', ') + '>';
|
||||
}
|
||||
// check if type is array
|
||||
if (type.isArray) {
|
||||
fullName += '[]';
|
||||
}
|
||||
return fullName;
|
||||
}
|
||||
|
||||
274
src/uml/createDiagram.ts
Normal file
274
src/uml/createDiagram.ts
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {Logger} from '@openstapps/logger';
|
||||
import {createWriteStream} from 'fs';
|
||||
import * as request from 'got';
|
||||
import {getFullTypeName} from '../common';
|
||||
import {LightweightClassDefinition} from './model/LightweightClassDefinition';
|
||||
import {LightweightDefinition} from './model/LightweightDefinition';
|
||||
import {LightweightEnumDefinition} from './model/LightweightEnumDefinition';
|
||||
import {LightweightProperty} from './model/LightweightProperty';
|
||||
import {LightweightType} from './model/LightweightType';
|
||||
import {UMLConfig} from './umlConfig';
|
||||
|
||||
/**
|
||||
* Converts the lightweight class/enum definitions according to the configuration,
|
||||
* to valid PlantUML Code, which will then be encoded, converted by the plantuml server
|
||||
* and saved as a .svg file in directory, in which this method was called
|
||||
*
|
||||
* @param definitions all type definitons of the project
|
||||
* @param config contains information on how the PlantUML should be generated
|
||||
* @param plantUmlBaseURL Hostname of the PlantUML-Server
|
||||
*/
|
||||
export async function createDiagram(
|
||||
definitions: LightweightDefinition[],
|
||||
config: UMLConfig,
|
||||
plantUmlBaseURL: string,
|
||||
): Promise<string> {
|
||||
|
||||
// when non definitions were specified use all
|
||||
if (config.definitions.length === 0) {
|
||||
config.definitions = [];
|
||||
definitions.forEach((definition) => {
|
||||
config.definitions.push(definition.name);
|
||||
});
|
||||
}
|
||||
|
||||
// when providing definitions and either showing associations or inheritance the
|
||||
// inherited definitions will be added automatically
|
||||
if (config.showInheritance) {
|
||||
const inheritedDefinitions = gatherTypeAssociations(
|
||||
definitions,
|
||||
config.definitions,
|
||||
);
|
||||
|
||||
config.definitions = config.definitions.concat(inheritedDefinitions);
|
||||
}
|
||||
|
||||
let modelPlantUMLCode: string = '';
|
||||
// creates a UML definition for every specified definition name
|
||||
// however if no definitions were provided all definitions will be transformed
|
||||
for (const definition of definitions) {
|
||||
if (
|
||||
config.definitions.length > 0 &&
|
||||
!config.definitions.includes(definition.name)
|
||||
) {
|
||||
// current definition not specified
|
||||
continue;
|
||||
}
|
||||
// either the definitions are empty or the definition was specified, proceed
|
||||
|
||||
let definitionPlantUMLCode: string = '';
|
||||
if (definition instanceof LightweightClassDefinition) {
|
||||
definitionPlantUMLCode = createPlantUMLCodeForClass(config, definition);
|
||||
} else if (definition instanceof LightweightEnumDefinition) {
|
||||
definitionPlantUMLCode = createPlantUMLCodeForEnum(config, definition);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
modelPlantUMLCode += definitionPlantUMLCode;
|
||||
}
|
||||
|
||||
return await createDiagramFromString(modelPlantUMLCode, plantUmlBaseURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will encode the plantuml code and post the code to the plantuml server
|
||||
* The server will then parse the code and create a corresponding diagram
|
||||
*
|
||||
* @param modelPlantUMLCode
|
||||
*/
|
||||
export async function createDiagramFromString(modelPlantUMLCode: string, plantUmlBaseURL: string) {
|
||||
const plantumlEncoder = require('plantuml-encoder');
|
||||
const plantUMLCode = plantumlEncoder.encode(modelPlantUMLCode);
|
||||
const url = `${plantUmlBaseURL}/svg/${plantUMLCode}`;
|
||||
let response;
|
||||
try {
|
||||
response = await request(url);
|
||||
if (response.statusCode !== 200) {
|
||||
Logger.error(`Plantuml Server responded with an error.\n${response.statusMessage}`);
|
||||
throw new Error('Response not okay');
|
||||
}
|
||||
} catch (e) {
|
||||
Logger.log(`Please try using the public plantuml server:\nhttp://www.plantuml.com/plantuml/svg/${plantUMLCode}`);
|
||||
throw e;
|
||||
}
|
||||
const fileName: string = `Diagram-${new Date().toISOString()}.svg`;
|
||||
try {
|
||||
createWriteStream(fileName).write(response.body);
|
||||
Logger.log(`Writen data to file: ${fileName}`);
|
||||
} catch (e) {
|
||||
throw new Error('Could not write file. Are you missing permissions?');
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursivly iterates over all types, to find implemented generic types and parents
|
||||
*
|
||||
* @param definitions all type definitons of the project
|
||||
* @param abstractionNames currently known string values of inherited classes
|
||||
*/
|
||||
function gatherTypeAssociations(
|
||||
definitions: LightweightDefinition[],
|
||||
abstractionNames: string[],
|
||||
): string[] {
|
||||
let abstractions: string[] = [];
|
||||
for (const name of abstractionNames) {
|
||||
const declaration = definitions.find(
|
||||
(definition) => definition.name === name,
|
||||
);
|
||||
if (declaration instanceof LightweightClassDefinition) {
|
||||
const currentAbstractions: string[] = declaration.extendedDefinitions.concat(
|
||||
declaration.implementedDefinitions,
|
||||
);
|
||||
|
||||
abstractions = abstractions.concat(currentAbstractions);
|
||||
abstractions = abstractions.concat(
|
||||
gatherTypeAssociations(definitions, currentAbstractions),
|
||||
);
|
||||
}
|
||||
}
|
||||
return abstractions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects all reference information of this type.
|
||||
*
|
||||
* Reference information is everything that is indirectly referencing a type or class by name.
|
||||
*
|
||||
* @param type Type with references to other types
|
||||
*/
|
||||
function getReferenceTypes(type: LightweightType): string[] {
|
||||
const types: string[] = [];
|
||||
if (type.isReference) {
|
||||
types.push(type.name);
|
||||
}
|
||||
if (type.isTyped && type.genericsTypes.length > 0) {
|
||||
for (const specificType of type.genericsTypes) {
|
||||
for (const value of getReferenceTypes(specificType)) {
|
||||
types.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
(type.isUnion && type.specificationTypes.length > 0) ||
|
||||
(type.isArray && type.specificationTypes.length > 0)
|
||||
) {
|
||||
for (const specificType of type.specificationTypes) {
|
||||
for (const value of getReferenceTypes(specificType)) {
|
||||
types.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Plant UML code according to the config for the provided class
|
||||
*
|
||||
* @param config Configuration for how the UML should be tweaked
|
||||
* @param readerClass Class or interface representation
|
||||
*/
|
||||
function createPlantUMLCodeForClass(
|
||||
config: UMLConfig,
|
||||
readerClass: LightweightClassDefinition,
|
||||
): string {
|
||||
// create the definition header, what type the definition is, it's name and it's inheritance
|
||||
let model: string = `${readerClass.type} ${readerClass.name}`;
|
||||
|
||||
if (readerClass.typeParameters.length > 0) {
|
||||
model += `<${readerClass.typeParameters.join(', ')}>`;
|
||||
}
|
||||
|
||||
if (config.showInheritance && readerClass.extendedDefinitions.length > 0) {
|
||||
// PlantUML will automatically create links, when using extends
|
||||
model += ` extends ${readerClass.extendedDefinitions.join(', ')}`;
|
||||
}
|
||||
if (config.showInheritance && readerClass.implementedDefinitions.length > 0) {
|
||||
// PlantUML will automatically create links, when using implenents
|
||||
model += ` implements ${readerClass.implementedDefinitions.join(', ')}`;
|
||||
}
|
||||
model += '{';
|
||||
|
||||
// add the properties to the definition body
|
||||
if (config.showProperties) {
|
||||
for (const property of readerClass.properties) {
|
||||
if (property.optional && !config.showOptionalProperties) {
|
||||
// don't show optional attributes
|
||||
continue;
|
||||
}
|
||||
if (property.inherited && !config.showInheritedProperties) {
|
||||
// don't show inherited properties
|
||||
continue;
|
||||
}
|
||||
model += `\n\t${createPropertyLine(property)}`;
|
||||
}
|
||||
}
|
||||
|
||||
// close the definition body
|
||||
model += '\n}\n';
|
||||
|
||||
// add associations from properties with references
|
||||
for (const property of readerClass.properties) {
|
||||
const types: string[] = getReferenceTypes(property.type);
|
||||
for (const type of types) {
|
||||
if ( config.showAssociations) {
|
||||
if (property.inherited && !config.showInheritedProperties) {
|
||||
continue;
|
||||
}
|
||||
model += `${readerClass.name} -up-> ${type} : ${property.name} >\n`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates PlantUML code according to the config for the provided enum/-like definition
|
||||
*
|
||||
* @param config Configuration for how the UML should be tweaked
|
||||
* @param readerEnum Enum/-like representation
|
||||
*/
|
||||
function createPlantUMLCodeForEnum(
|
||||
config: UMLConfig,
|
||||
readerEnum: LightweightEnumDefinition,
|
||||
): string {
|
||||
// create enum header
|
||||
let model: string = `enum ${readerEnum.name} {`;
|
||||
// add values
|
||||
if (config.showEnumValues) {
|
||||
for (const value of readerEnum.values) {
|
||||
model += `\n\t${value.toString()}`;
|
||||
}
|
||||
}
|
||||
model += '\n}\n';
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a property PlantUML Line
|
||||
*/
|
||||
function createPropertyLine(property: LightweightProperty): string {
|
||||
return (
|
||||
(property.inherited ? '/ ' : '') +
|
||||
(property.optional ? '?' : '') +
|
||||
property.name +
|
||||
' : ' +
|
||||
getFullTypeName(property.type)
|
||||
);
|
||||
}
|
||||
56
src/uml/model/LightweightClassDefinition.ts
Normal file
56
src/uml/model/LightweightClassDefinition.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {LightweightDefinition} from './LightweightDefinition';
|
||||
import {LightweightProperty} from './LightweightProperty';
|
||||
/**
|
||||
* Represents a class definition
|
||||
*/
|
||||
export class LightweightClassDefinition extends LightweightDefinition {
|
||||
/**
|
||||
* String values of the extended definitions
|
||||
*/
|
||||
public extendedDefinitions: string[];
|
||||
|
||||
/**
|
||||
* String values of the implemented definitions
|
||||
*/
|
||||
public implementedDefinitions: string[];
|
||||
|
||||
/**
|
||||
* Properties of the definition
|
||||
*/
|
||||
public properties: LightweightProperty[];
|
||||
|
||||
/**
|
||||
* The definition type
|
||||
* e.g. `interface`/[`abstract`] `class`
|
||||
*/
|
||||
public type: string;
|
||||
|
||||
/**
|
||||
* Generic type parameters of this class
|
||||
*/
|
||||
public typeParameters: string[];
|
||||
|
||||
constructor(name: string, type: string) {
|
||||
super(name);
|
||||
this.type = type;
|
||||
this.properties = [];
|
||||
this.extendedDefinitions = [];
|
||||
this.implementedDefinitions = [];
|
||||
this.typeParameters = [];
|
||||
}
|
||||
}
|
||||
28
src/uml/model/LightweightDefinition.ts
Normal file
28
src/uml/model/LightweightDefinition.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents any definition without specifics
|
||||
*/
|
||||
export abstract class LightweightDefinition {
|
||||
/**
|
||||
* Name of the definiton
|
||||
*/
|
||||
public name: string;
|
||||
|
||||
constructor(name: string) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
30
src/uml/model/LightweightEnumDefinition.ts
Normal file
30
src/uml/model/LightweightEnumDefinition.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {LightweightDefinition} from './LightweightDefinition';
|
||||
/**
|
||||
* Represents an enum definition
|
||||
*/
|
||||
export class LightweightEnumDefinition extends LightweightDefinition {
|
||||
/**
|
||||
* Enumeration or union values
|
||||
*/
|
||||
public values: string[];
|
||||
|
||||
constructor(name: string) {
|
||||
super(name);
|
||||
this.values = [];
|
||||
}
|
||||
}
|
||||
54
src/uml/model/LightweightProperty.ts
Normal file
54
src/uml/model/LightweightProperty.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {LightweightType} from './LightweightType';
|
||||
|
||||
/**
|
||||
* Represents a property definition
|
||||
*/
|
||||
export class LightweightProperty {
|
||||
/**
|
||||
* Is the property inherited from another definition
|
||||
*/
|
||||
public inherited: boolean;
|
||||
|
||||
/**
|
||||
* Name of the property
|
||||
*/
|
||||
public name: string;
|
||||
|
||||
/**
|
||||
* Is the property marked as optional
|
||||
*/
|
||||
public optional: boolean;
|
||||
|
||||
/**
|
||||
* Type of the property
|
||||
*/
|
||||
public type: LightweightType;
|
||||
|
||||
/**
|
||||
* Constructor for LightweightProperty
|
||||
*
|
||||
* @param name Name of the property
|
||||
* @param type Type of the property
|
||||
* @param optional Is the property optional
|
||||
*/
|
||||
constructor(name: string, type: LightweightType, optional: boolean = true) {
|
||||
this.name = name;
|
||||
this.optional = optional;
|
||||
this.inherited = false;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
85
src/uml/model/LightweightType.ts
Normal file
85
src/uml/model/LightweightType.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Describes an easy to use type definition.
|
||||
*/
|
||||
export class LightweightType {
|
||||
/**
|
||||
* Contains all types inside of <> brackets
|
||||
*/
|
||||
genericsTypes: LightweightType[];
|
||||
|
||||
/**
|
||||
* Does the type have generic-parameters
|
||||
*/
|
||||
hasTypeInformation: boolean = false;
|
||||
|
||||
/**
|
||||
* Does the type represent an array type
|
||||
*/
|
||||
isArray: boolean = false;
|
||||
|
||||
/**
|
||||
* Does the type represent a literal type
|
||||
*/
|
||||
isLiteral: boolean = false;
|
||||
|
||||
/**
|
||||
* Does the type represent a primitive type
|
||||
*/
|
||||
isPrimitive: boolean = false;
|
||||
|
||||
/**
|
||||
* Does the type contain a reference to
|
||||
*/
|
||||
isReference: boolean = false;
|
||||
|
||||
/**
|
||||
* Is the type a reflection and not avaiblabe at compile time
|
||||
*/
|
||||
isReflection: boolean = false;
|
||||
|
||||
/**
|
||||
* Does the type have type parameters
|
||||
*/
|
||||
isTyped: boolean = false;
|
||||
|
||||
/**
|
||||
* Is the type a typed parameter
|
||||
*/
|
||||
isTypeParameter: boolean = false;
|
||||
|
||||
/**
|
||||
* Is the type a union type
|
||||
*/
|
||||
isUnion: boolean = false;
|
||||
|
||||
/**
|
||||
* Name of the type
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Type specifications, if the type is combined by either an array, union or a typeOperator
|
||||
*/
|
||||
specificationTypes: LightweightType[];
|
||||
|
||||
constructor() {
|
||||
this.specificationTypes = [];
|
||||
this.genericsTypes = [];
|
||||
this.name = '';
|
||||
}
|
||||
}
|
||||
423
src/uml/readDefinitions.ts
Normal file
423
src/uml/readDefinitions.ts
Normal file
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {Logger} from '@openstapps/logger';
|
||||
import {
|
||||
ArrayType,
|
||||
DeclarationReflection,
|
||||
IntrinsicType,
|
||||
ProjectReflection,
|
||||
ReferenceType,
|
||||
ReflectionKind,
|
||||
ReflectionType,
|
||||
StringLiteralType,
|
||||
Type,
|
||||
TypeOperatorType,
|
||||
TypeParameterType,
|
||||
UnionType,
|
||||
} from 'typedoc/dist/lib/models';
|
||||
import {getFullTypeName} from '../common';
|
||||
import {LightweightClassDefinition} from './model/LightweightClassDefinition';
|
||||
import {LightweightDefinition} from './model/LightweightDefinition';
|
||||
import {LightweightEnumDefinition} from './model/LightweightEnumDefinition';
|
||||
import {LightweightProperty} from './model/LightweightProperty';
|
||||
import {LightweightType} from './model/LightweightType';
|
||||
|
||||
/**
|
||||
* Reads the reflection model from typedoc and converts it into a flatter, easier to handle model
|
||||
*
|
||||
* @param srcPath Path to source file directory
|
||||
*/
|
||||
export function readDefinitions(projectReflection: ProjectReflection): LightweightDefinition[] {
|
||||
|
||||
const definitions: LightweightDefinition[] = [];
|
||||
|
||||
// define known types and categorize them
|
||||
const enumLike: string[] = ['Type alias', 'Enumeration'];
|
||||
const classLike: string[] = ['Class', 'Interface'];
|
||||
const unused: string[] = ['Function', 'Object literal', 'Variable'];
|
||||
|
||||
// children need to be not undefined, if they are return empty
|
||||
if (typeof projectReflection.children === 'undefined') {
|
||||
return [];
|
||||
}
|
||||
|
||||
for (const module of projectReflection.children) {
|
||||
if (Array.isArray(module.children) && module.children.length > 0) {
|
||||
// iterate over class and enum declarations
|
||||
for (const type of module.children) {
|
||||
// only if kindString is set
|
||||
if (typeof type.kindString !== 'undefined') {
|
||||
// check if declaration is enum
|
||||
if (classLike.includes(type.kindString)) {
|
||||
definitions.push(readAsClassDefinition(type));
|
||||
} else if (enumLike.includes(type.kindString)) {
|
||||
definitions.push(readAsEnumDefinition(type));
|
||||
} else if (unused.includes(type.kindString)) {
|
||||
Logger.info(`Unconverted ${type.kindString} : ${type.name}`);
|
||||
} else {
|
||||
Logger.log(
|
||||
`Uncaught declaration type (${type.kindString}) : ${type.name}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return definitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the declaration into a `LightweightClassDefinition`
|
||||
*
|
||||
* @param declaration declaration
|
||||
*/
|
||||
export function readAsEnumDefinition(
|
||||
declaration: DeclarationReflection,
|
||||
): LightweightEnumDefinition {
|
||||
// init enum definition
|
||||
const enumDefinition: LightweightEnumDefinition = new LightweightEnumDefinition(
|
||||
declaration.name,
|
||||
);
|
||||
|
||||
// get enum values according to type
|
||||
if (declaration.kindString === 'Enumeration' && declaration.children) {
|
||||
// standard enumeration
|
||||
for (const child of declaration.children) {
|
||||
if (child.kindString === 'Enumeration member') {
|
||||
let value = child.name;
|
||||
if (typeof child.defaultValue !== 'undefined') {
|
||||
value = `${value} = ${child.defaultValue}`;
|
||||
}
|
||||
enumDefinition.values.push(value);
|
||||
} else {
|
||||
Logger.log(
|
||||
"Every enumeration member should be an 'EnumerationMemberType'",
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
declaration.kindString === 'Type alias' &&
|
||||
typeof declaration.type !== 'undefined'
|
||||
) {
|
||||
// enum like declaration
|
||||
try {
|
||||
const a = readTypeInformation(declaration.type);
|
||||
enumDefinition.values = enumDefinition.values.concat(
|
||||
getTypeInformation(a),
|
||||
);
|
||||
} catch (e) {
|
||||
Logger.warn(
|
||||
`Could not read the light type for ${declaration.name}. ${e}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return enumDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for enumrations to get the type value
|
||||
*/
|
||||
function getTypeInformation(type: LightweightType): string[] {
|
||||
const values: string[] = [];
|
||||
if (!type.hasTypeInformation) {
|
||||
for (const specificType of type.specificationTypes) {
|
||||
for (const value of getTypeInformation(specificType)) {
|
||||
values.push(value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
values.push(type.name);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the declaration into a `LightweightClassDefinition`
|
||||
*
|
||||
* @param declaration declaration
|
||||
*/
|
||||
export function readAsClassDefinition(
|
||||
declaration: DeclarationReflection,
|
||||
): LightweightClassDefinition {
|
||||
let type = declaration.kindString ? declaration.kindString.toLowerCase() : '';
|
||||
type = (declaration.flags.isAbstract ? 'abstract ' : '') + type;
|
||||
|
||||
const classDefinition: LightweightClassDefinition = new LightweightClassDefinition(
|
||||
declaration.name,
|
||||
type,
|
||||
);
|
||||
|
||||
// get generic types
|
||||
if (typeof declaration.typeParameters !== 'undefined') {
|
||||
const typeParameters: string[] = [];
|
||||
declaration.typeParameters.forEach((typeParameter) =>
|
||||
typeParameters.push(typeParameter.name),
|
||||
);
|
||||
classDefinition.typeParameters = typeParameters;
|
||||
}
|
||||
|
||||
// extracts extended types of the declaration
|
||||
if (typeof declaration.extendedTypes !== 'undefined') {
|
||||
for (const extType of declaration.extendedTypes) {
|
||||
classDefinition.extendedDefinitions.push((extType as ReferenceType).name);
|
||||
}
|
||||
}
|
||||
|
||||
// extracts implemented types of the declaration
|
||||
// HINT: typedoc automatically adds inherited interfaces to the declaration directly
|
||||
if (typeof declaration.implementedTypes !== 'undefined') {
|
||||
for (const implType of declaration.implementedTypes) {
|
||||
classDefinition.implementedDefinitions.push(
|
||||
(implType as ReferenceType).name,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof declaration.children !== 'undefined') {
|
||||
for (const child of declaration.getChildrenByKind(
|
||||
ReflectionKind.Property,
|
||||
)) {
|
||||
try {
|
||||
if (typeof child.type === 'undefined') {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
const myType: LightweightType = readTypeInformation(child.type);
|
||||
const property = new LightweightProperty(child.name, myType);
|
||||
|
||||
const flags = child.flags;
|
||||
if (flags.isOptional !== undefined) {
|
||||
property.optional = flags.isOptional as boolean;
|
||||
property.inherited = !(
|
||||
child.inheritedFrom === undefined || child.inheritedFrom === null
|
||||
);
|
||||
}
|
||||
classDefinition.properties.push(property);
|
||||
} catch (e) {
|
||||
Logger.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return classDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* The structure of reflection type has a huge overhead
|
||||
* This method and all submethods will convert these types in easier to process Types
|
||||
*
|
||||
* @param declarationType Type to be converted
|
||||
*/
|
||||
function readTypeInformation(declarationType: Type): LightweightType {
|
||||
if (declarationType instanceof ReflectionType) {
|
||||
return readAsReflectionType(declarationType);
|
||||
} else if (declarationType instanceof TypeOperatorType) {
|
||||
return readAsTypeOperatorType(declarationType);
|
||||
} else if (declarationType instanceof TypeParameterType) {
|
||||
return readAsTypeParameterType(declarationType);
|
||||
} else if (declarationType instanceof IntrinsicType) {
|
||||
return readAsIntrinsicType(declarationType);
|
||||
} else if (declarationType instanceof StringLiteralType) {
|
||||
return readAsStringLiteralType(declarationType);
|
||||
} else if (declarationType instanceof ReferenceType) {
|
||||
return readAsReferenceType(declarationType);
|
||||
} else if (declarationType instanceof ArrayType) {
|
||||
return readAsArrayType(declarationType);
|
||||
} else if (declarationType instanceof UnionType) {
|
||||
return readAsUnionType(declarationType);
|
||||
} else {
|
||||
throw new Error(`Could not read type ${declarationType.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion method for IntrinsicType's
|
||||
*
|
||||
* e.g. remainingAttendeeCapacity?: number;
|
||||
*
|
||||
* @param type Type to be converted
|
||||
*/
|
||||
function readAsIntrinsicType(type: IntrinsicType): LightweightType {
|
||||
const easyType: LightweightType = new LightweightType();
|
||||
easyType.name = type.name;
|
||||
easyType.isPrimitive = true;
|
||||
easyType.hasTypeInformation = true;
|
||||
return easyType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion method for StringLiteralType's
|
||||
*
|
||||
* e.g. inputType: 'multipleChoice';
|
||||
*
|
||||
* @param type Type to be converted
|
||||
*/
|
||||
function readAsStringLiteralType(type: StringLiteralType): LightweightType {
|
||||
const returnType: LightweightType = new LightweightType();
|
||||
returnType.name = type.value;
|
||||
returnType.isLiteral = true;
|
||||
returnType.hasTypeInformation = true;
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion method for ReferenceType's
|
||||
*
|
||||
* Everything that is a user or API designed definition and not a primitive type or core-language feature.
|
||||
*
|
||||
* e.g. publishers?: Array<SCPersonWithoutReferences | SCOrganizationWithoutReferences>;
|
||||
*
|
||||
* Array, SCPersonWithoutReferences and SCOrganizationWithoutReferences will be recognized as reference types!
|
||||
*
|
||||
* @param type Type to be converted
|
||||
*/
|
||||
function readAsReferenceType(type: ReferenceType): LightweightType {
|
||||
const returnType: LightweightType = new LightweightType();
|
||||
returnType.name = type.name;
|
||||
|
||||
if (type.typeArguments !== undefined && type.typeArguments.length > 0) {
|
||||
const typeArguments: LightweightType[] = [];
|
||||
|
||||
for (const value of type.typeArguments) {
|
||||
typeArguments.push(readTypeInformation(value));
|
||||
}
|
||||
|
||||
returnType.isTyped = true;
|
||||
returnType.genericsTypes = typeArguments;
|
||||
}
|
||||
|
||||
if (type.reflection !== undefined && type.reflection !== null) {
|
||||
const tempTypeReflection = type.reflection as DeclarationReflection;
|
||||
// interfaces and classes in a type are a sink, since their declaration are defined elsewhere
|
||||
if (
|
||||
tempTypeReflection.kindString &&
|
||||
['Interface', 'Class', 'Enumeration', 'Type alias'].indexOf(
|
||||
tempTypeReflection.kindString,
|
||||
) > -1
|
||||
) {
|
||||
returnType.isReference = true;
|
||||
}
|
||||
}
|
||||
|
||||
returnType.hasTypeInformation = true;
|
||||
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion method for ArrayType's
|
||||
*
|
||||
* The actual type of the array is stored in the first element of specificationTypes.
|
||||
*
|
||||
* e.g. articleBody?: string[];
|
||||
*
|
||||
* @param type Type to be converted
|
||||
*/
|
||||
function readAsArrayType(type: ArrayType): LightweightType {
|
||||
const returnType: LightweightType = new LightweightType();
|
||||
const typeOfArray: LightweightType = readTypeInformation(type.elementType);
|
||||
returnType.name = getFullTypeName(typeOfArray);
|
||||
returnType.specificationTypes = [typeOfArray];
|
||||
returnType.isArray = true;
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion method for UnionType's
|
||||
*
|
||||
* The Union-LightType store the single types of the union inside a
|
||||
* separate LightType inside specificationTypes.
|
||||
*
|
||||
* e.g. maintainer?: SCPerson | SCOrganization;
|
||||
*
|
||||
* @param type Type to be converted
|
||||
*/
|
||||
function readAsUnionType(type: UnionType): LightweightType {
|
||||
const returnType: LightweightType = new LightweightType();
|
||||
const typesOfUnion: LightweightType[] = [];
|
||||
for (const value of type.types) {
|
||||
typesOfUnion.push(readTypeInformation(value));
|
||||
}
|
||||
returnType.specificationTypes = typesOfUnion;
|
||||
returnType.name = getFullTypeName(returnType);
|
||||
returnType.isUnion = true;
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion method for ReflectionType's
|
||||
*
|
||||
* The explicit type is not contained in reflection!
|
||||
* It might be possible to get the structure of type by reading tempType.decoration.children,
|
||||
* but this structure is currently not supported in the data-model.
|
||||
*
|
||||
* e.g. categorySpecificValues?: { [s: string]: U };
|
||||
*
|
||||
* @param type Type to be converted
|
||||
*/
|
||||
function readAsReflectionType(type: ReflectionType): LightweightType {
|
||||
const returnType: LightweightType = new LightweightType();
|
||||
if (type.declaration.sources) {
|
||||
const src = type.declaration.sources[0];
|
||||
Logger.warn(
|
||||
`${src.line} : ${src.fileName}: Reflection Type not recognized. Refactoring to explicit class is advised.`,
|
||||
);
|
||||
}
|
||||
returnType.name = 'object';
|
||||
returnType.isReflection = true;
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion method for TypeOperatorType's
|
||||
*
|
||||
* This type is similar to reflection, that the actual type can only be evaluated at runtime.
|
||||
*
|
||||
* e.g. universityRole: keyof SCSportCoursePriceGroup;
|
||||
*
|
||||
* @param type Type to be converted
|
||||
*/
|
||||
function readAsTypeOperatorType(type: TypeOperatorType): LightweightType {
|
||||
const returnType: LightweightType = new LightweightType();
|
||||
const typeOf: LightweightType = readTypeInformation(type.target);
|
||||
returnType.name = `keyof ${getFullTypeName(typeOf)}`;
|
||||
returnType.specificationTypes = [typeOf];
|
||||
// can't be traced deeper! so might as well be a primitive
|
||||
returnType.isPrimitive = true;
|
||||
returnType.hasTypeInformation = true;
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion method for TypeParameterType's
|
||||
*
|
||||
* Should only be called in generic classes/interfaces, when a property is
|
||||
* referencing the generic-type.
|
||||
*
|
||||
* e.g. prices?: T;
|
||||
*
|
||||
* Does not match on Arrays of the generic type. Those will be matched with ArrayType.
|
||||
*
|
||||
* @param type Needs to be a TypeParameterType
|
||||
*/
|
||||
function readAsTypeParameterType(type: TypeParameterType): LightweightType {
|
||||
const returnType: LightweightType = new LightweightType();
|
||||
returnType.name = type.name;
|
||||
returnType.isTypeParameter = true;
|
||||
returnType.hasTypeInformation = true;
|
||||
return returnType;
|
||||
}
|
||||
54
src/uml/umlConfig.ts
Normal file
54
src/uml/umlConfig.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Holds configuration information of how the UML code should be build
|
||||
*/
|
||||
export interface UMLConfig {
|
||||
/**
|
||||
* Defines which definitions are shown
|
||||
*/
|
||||
definitions: string[];
|
||||
|
||||
/**
|
||||
* Should the associations between definitions be shown
|
||||
*/
|
||||
showAssociations: boolean;
|
||||
|
||||
/**
|
||||
* Should enum/-like values be shown
|
||||
*/
|
||||
showEnumValues: boolean;
|
||||
|
||||
/**
|
||||
* Should the inheritance be shown
|
||||
*/
|
||||
showInheritance: boolean;
|
||||
|
||||
/**
|
||||
* Should the inherited properties be shown
|
||||
*/
|
||||
showInheritedProperties: boolean;
|
||||
|
||||
/**
|
||||
* Should optional properties be shown
|
||||
*/
|
||||
showOptionalProperties: boolean;
|
||||
|
||||
/**
|
||||
* Should properties be shown
|
||||
*/
|
||||
showProperties: boolean;
|
||||
}
|
||||
@@ -29,4 +29,5 @@ export class CommonSpec {
|
||||
async getTsconfigPath() {
|
||||
expect(getTsconfigPath(__dirname)).to.be.equal(cwd());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
85
test/CreateDiagram.spec.ts
Normal file
85
test/CreateDiagram.spec.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {expect} from 'chai';
|
||||
import {resolve} from 'path';
|
||||
import {existsSync, unlinkSync} from 'fs';
|
||||
import {slow, suite, test, timeout} from 'mocha-typescript';
|
||||
import {getProjectReflection} from '../src/common';
|
||||
import {createDiagram, createDiagramFromString} from '../src/uml/createDiagram';
|
||||
import {UMLConfig} from './../lib/uml/umlConfig.d';
|
||||
import {readDefinitions} from '../src/uml/readDefinitions';
|
||||
import {LightweightDefinition} from '../src/uml/model/LightweightDefinition';
|
||||
import nock = require('nock');
|
||||
|
||||
@suite(timeout(15000), slow(5000))
|
||||
export class CreateDiagramSpec {
|
||||
plantUmlConfig: UMLConfig;
|
||||
definitions: LightweightDefinition[];
|
||||
|
||||
constructor() {
|
||||
this.plantUmlConfig = {
|
||||
definitions: [],
|
||||
showAssociations: true,
|
||||
showEnumValues: true,
|
||||
showInheritance: true,
|
||||
showInheritedProperties: true,
|
||||
showOptionalProperties: true,
|
||||
showProperties: true,
|
||||
};
|
||||
|
||||
const projectReflection = getProjectReflection('./test/model', true);
|
||||
this.definitions = readDefinitions(projectReflection);
|
||||
}
|
||||
|
||||
@test
|
||||
async shouldRefuseRequest() {
|
||||
const testPlantUmlCode: string = 'class Test{\n}';
|
||||
try {
|
||||
await createDiagramFromString(testPlantUmlCode, "http://plantuml:8080");
|
||||
} catch (e) {
|
||||
expect(e.message).to.equal(new Error('getaddrinfo ENOTFOUND plantuml plantuml:8080').message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This test will only test the functionality of the method
|
||||
* - Converting the definitions to plantuml code
|
||||
* - Sending the code to a server
|
||||
* - Writing the response to a file
|
||||
* This test will not check the file content
|
||||
*/
|
||||
@test
|
||||
async shouldCreateDiagrams() {
|
||||
nock('http://plantuml:8080')
|
||||
.persist()
|
||||
.get(() => true)
|
||||
.reply(200, 'This will be the file content')
|
||||
|
||||
let fileName = await createDiagram(this.definitions, this.plantUmlConfig, "http://plantuml:8080");
|
||||
let filePath = resolve(__dirname, '..', fileName);
|
||||
expect(await existsSync(filePath)).to.equal(true);
|
||||
await unlinkSync(fileName);
|
||||
|
||||
this.plantUmlConfig.showAssociations = false;
|
||||
this.plantUmlConfig.showInheritance = false;
|
||||
|
||||
fileName = await createDiagram(this.definitions, this.plantUmlConfig, "http://plantuml:8080");
|
||||
filePath = resolve(__dirname, '..', fileName);
|
||||
expect(await existsSync(filePath)).to.equal(true);
|
||||
await unlinkSync(fileName);
|
||||
|
||||
nock.cleanAll();
|
||||
}
|
||||
}
|
||||
29
test/ReadDefinitions.spec.ts
Normal file
29
test/ReadDefinitions.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {expect} from 'chai';
|
||||
import {slow, suite, test, timeout} from 'mocha-typescript';
|
||||
import {getProjectReflection} from '../src/common';
|
||||
import {readDefinitions} from '../src/uml/readDefinitions';
|
||||
import {generatedModel} from './model/generatedModel';
|
||||
|
||||
@suite(timeout(10000), slow(5000))
|
||||
export class ReadDefinitionsSpec {
|
||||
@test
|
||||
async testReadDefinitions() {
|
||||
const projectReflection = getProjectReflection('./test/model', true);
|
||||
const definitions = readDefinitions(projectReflection);
|
||||
expect(definitions).to.be.deep.equal(generatedModel);
|
||||
}
|
||||
}
|
||||
34
test/model/TestClass.ts
Normal file
34
test/model/TestClass.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {TestFirstUnion} from './TestUnion';
|
||||
|
||||
export class TestClass<T> {
|
||||
test2: T;
|
||||
test4: TestFirstUnion;
|
||||
|
||||
constructor(type: T) {
|
||||
this.test2 = type;
|
||||
this.test4 = 'test1';
|
||||
}
|
||||
|
||||
/**
|
||||
* Should not be processed at all
|
||||
*/
|
||||
testClassFunction(): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class TestSecondClass extends TestClass<string> {}
|
||||
25
test/model/TestEnum.ts
Normal file
25
test/model/TestEnum.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
export enum TestFirstEnum {
|
||||
TEST1,
|
||||
TEST2,
|
||||
TEST3,
|
||||
}
|
||||
|
||||
export enum TestSecondEnum {
|
||||
TEST1 = 'one',
|
||||
TEST2 = 'two',
|
||||
TEST3 = 'three',
|
||||
}
|
||||
17
test/model/TestFunction.ts
Normal file
17
test/model/TestFunction.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
export function testFunction(): boolean {
|
||||
return true;
|
||||
}
|
||||
34
test/model/TestInterface.ts
Normal file
34
test/model/TestInterface.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {TestClass, TestSecondClass} from './TestClass';
|
||||
import {TestFirstEnum} from './TestEnum';
|
||||
import {TestThirdUnion} from './TestUnion';
|
||||
|
||||
export interface TestInterface {
|
||||
articleBody: string[];
|
||||
categorySpecificValues?: { [s: string]: string };
|
||||
inputType: 'multipleChoice';
|
||||
maintainer: TestThirdUnion | TestFirstEnum;
|
||||
remainingAttendeeCapacity?: number;
|
||||
test1: Array<TestThirdUnion | typeof TestFirstEnum>;
|
||||
test2: TestClass<string>;
|
||||
test3: 'test1' | 'test2';
|
||||
test4: TestSecondClass;
|
||||
universityRole: keyof TestFirstEnum;
|
||||
}
|
||||
|
||||
export interface TestSecondInterface {
|
||||
[k: string]: string;
|
||||
}
|
||||
24
test/model/TestUnion.ts
Normal file
24
test/model/TestUnion.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export type TestFirstUnion = 'test1' | 'test2';
|
||||
|
||||
export type TestSecondUnion = 'test3';
|
||||
|
||||
export type TestThirdUnion = TestFirstUnion | TestSecondUnion;
|
||||
|
||||
export type TestFourthUnion<T extends TestFirstUnion> = T extends TestFirstUnion
|
||||
? TestFirstUnion
|
||||
: never;
|
||||
552
test/model/generatedModel.ts
Normal file
552
test/model/generatedModel.ts
Normal file
@@ -0,0 +1,552 @@
|
||||
/*
|
||||
* Copyright (C) 2019 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {LightweightClassDefinition} from '../../src/uml/model/LightweightClassDefinition';
|
||||
import {LightweightDefinition} from '../../src/uml/model/LightweightDefinition';
|
||||
import {LightweightEnumDefinition} from '../../src/uml/model/LightweightEnumDefinition';
|
||||
|
||||
export const generatedModel: Array<
|
||||
LightweightDefinition | LightweightClassDefinition | LightweightEnumDefinition
|
||||
> = [
|
||||
{
|
||||
name: 'TestClass',
|
||||
type: 'class',
|
||||
properties: [
|
||||
{
|
||||
name: 'test2',
|
||||
optional: false,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: true,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'T',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'test4',
|
||||
optional: false,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: true,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'TestFirstUnion',
|
||||
},
|
||||
},
|
||||
],
|
||||
extendedDefinitions: [],
|
||||
implementedDefinitions: [],
|
||||
typeParameters: ['T'],
|
||||
},
|
||||
{
|
||||
name: 'TestSecondClass',
|
||||
type: 'class',
|
||||
properties: [
|
||||
{
|
||||
name: 'test2',
|
||||
optional: false,
|
||||
inherited: true,
|
||||
type: {
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: true,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'test4',
|
||||
optional: false,
|
||||
inherited: true,
|
||||
type: {
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: true,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'TestFirstUnion',
|
||||
},
|
||||
},
|
||||
],
|
||||
extendedDefinitions: ['TestClass'],
|
||||
implementedDefinitions: [],
|
||||
typeParameters: [],
|
||||
},
|
||||
{
|
||||
name: 'TestFirstEnum',
|
||||
values: ['TEST1', 'TEST2', 'TEST3'],
|
||||
},
|
||||
{
|
||||
name: 'TestSecondEnum',
|
||||
values: ['TEST1 = "one"', 'TEST2 = "two"', 'TEST3 = "three"'],
|
||||
},
|
||||
{
|
||||
name: 'TestInterface',
|
||||
type: 'interface',
|
||||
properties: [
|
||||
{
|
||||
name: 'articleBody',
|
||||
optional: false,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: false,
|
||||
isArray: true,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: true,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'string',
|
||||
},
|
||||
],
|
||||
genericsTypes: [],
|
||||
name: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'categorySpecificValues',
|
||||
optional: true,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: false,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: true,
|
||||
specificationTypes: [
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: true,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'undefined',
|
||||
},
|
||||
{
|
||||
hasTypeInformation: false,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: true,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'object',
|
||||
},
|
||||
],
|
||||
genericsTypes: [],
|
||||
name: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'inputType',
|
||||
optional: false,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: true,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'multipleChoice',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'maintainer',
|
||||
optional: false,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: false,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: true,
|
||||
specificationTypes: [
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: true,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'TestThirdUnion',
|
||||
},
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: true,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'TestFirstEnum',
|
||||
},
|
||||
],
|
||||
genericsTypes: [],
|
||||
name: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'remainingAttendeeCapacity',
|
||||
optional: true,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: false,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: true,
|
||||
specificationTypes: [
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: true,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'undefined',
|
||||
},
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: true,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'number',
|
||||
},
|
||||
],
|
||||
genericsTypes: [],
|
||||
name: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'test1',
|
||||
optional: false,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: true,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [
|
||||
{
|
||||
hasTypeInformation: false,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: true,
|
||||
specificationTypes: [
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: true,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'TestThirdUnion',
|
||||
},
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: true,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'TestFirstEnum',
|
||||
},
|
||||
],
|
||||
genericsTypes: [],
|
||||
name: '',
|
||||
},
|
||||
],
|
||||
name: 'Array',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'test2',
|
||||
optional: false,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: true,
|
||||
isReflection: false,
|
||||
isTyped: true,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: true,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'string',
|
||||
},
|
||||
],
|
||||
name: 'TestClass',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'test3',
|
||||
optional: false,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: false,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: true,
|
||||
specificationTypes: [
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: true,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'test1',
|
||||
},
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: true,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'test2',
|
||||
},
|
||||
],
|
||||
genericsTypes: [],
|
||||
name: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'test4',
|
||||
optional: false,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: true,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'TestSecondClass',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'universityRole',
|
||||
optional: false,
|
||||
inherited: false,
|
||||
type: {
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: true,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [
|
||||
{
|
||||
hasTypeInformation: true,
|
||||
isArray: false,
|
||||
isLiteral: false,
|
||||
isPrimitive: false,
|
||||
isReference: false,
|
||||
isReflection: false,
|
||||
isTyped: false,
|
||||
isTypeParameter: false,
|
||||
isUnion: false,
|
||||
specificationTypes: [],
|
||||
genericsTypes: [],
|
||||
name: 'TestFirstEnum',
|
||||
},
|
||||
],
|
||||
genericsTypes: [],
|
||||
name: 'keyof TestFirstEnum',
|
||||
},
|
||||
},
|
||||
],
|
||||
extendedDefinitions: [],
|
||||
implementedDefinitions: [],
|
||||
typeParameters: [],
|
||||
},
|
||||
{
|
||||
name: 'TestSecondInterface',
|
||||
type: 'interface',
|
||||
properties: [],
|
||||
extendedDefinitions: [],
|
||||
implementedDefinitions: [],
|
||||
typeParameters: [],
|
||||
},
|
||||
{
|
||||
name: 'TestFirstUnion',
|
||||
values: ['test1', 'test2'],
|
||||
},
|
||||
{
|
||||
name: 'TestFourthUnion',
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
name: 'TestSecondUnion',
|
||||
values: ['test3'],
|
||||
},
|
||||
{
|
||||
name: 'TestThirdUnion',
|
||||
values: ['TestFirstUnion', 'TestSecondUnion'],
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user