refactor: build system

This commit is contained in:
2023-03-22 11:45:30 +01:00
parent 4df19e8c20
commit 8cb9285462
427 changed files with 3978 additions and 9810 deletions

View File

@@ -1,15 +0,0 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

View File

@@ -1,2 +0,0 @@
resources
openapi

View File

@@ -1,3 +0,0 @@
{
"extends": "@openstapps"
}

View File

@@ -1,6 +1,5 @@
image: registry.gitlab.com/openstapps/projectmanagement/node
before_script:
- npm ci

View File

@@ -2,35 +2,29 @@
(Summarize the bug encountered concisely)
## Steps to reproduce
(How one can reproduce the issue - this is very important)
## Example Project
(If possible, please create an example project here on GitLab.com that exhibits the problematic behaviour, and link to it here in the bug report)
(If you are using an older version of GitLab, this will also determine whether the bug has been fixed in a more recent version)
## What is the current bug behavior?
(What actually happens)
## What is the expected correct behavior?
(What you should see instead)
## Relevant logs and/or screenshots
(Paste any relevant logs - please use code blocks (```) to format console output,
logs, and code as it's very hard to read otherwise.)
## Possible fixes
(If you can, link to the line of code that might be responsible for the problem)

View File

@@ -2,15 +2,12 @@
(Describe the feature that you're requesting concisely)
## Explanation
(Explain why the feature is necessary)
## Dependencies, issues to be resolved beforehand
(List issues or dependencies that need to be resolved before this feature can be implemented)
/label ~meeting

View File

@@ -1,353 +1,228 @@
# [0.34.0](https://gitlab.com/openstapps/core-tools/compare/v0.33.0...v0.34.0) (2023-01-30)
# [0.33.0](https://gitlab.com/openstapps/core-tools/compare/v0.32.0...v0.33.0) (2023-01-12)
### Bug Fixes
* convert schema glob path to posix path ([c3d66b3](https://gitlab.com/openstapps/core-tools/commit/c3d66b36c8b4bdf84b3e23cd0ab8318d3fd068f9))
- convert schema glob path to posix path ([c3d66b3](https://gitlab.com/openstapps/core-tools/commit/c3d66b36c8b4bdf84b3e23cd0ab8318d3fd068f9))
# [0.32.0](https://gitlab.com/openstapps/core-tools/compare/v0.31.0...v0.32.0) (2022-08-17)
### Bug Fixes
* documentation not beeing generated ([51ae246](https://gitlab.com/openstapps/core-tools/commit/51ae246a0fd10144cf6af348bc7ded88e6dab27a))
- documentation not beeing generated ([51ae246](https://gitlab.com/openstapps/core-tools/commit/51ae246a0fd10144cf6af348bc7ded88e6dab27a))
# [0.31.0](https://gitlab.com/openstapps/core-tools/compare/v0.30.1...v0.31.0) (2022-06-27)
## [0.30.1](https://gitlab.com/openstapps/core-tools/compare/v0.30.0...v0.30.1) (2022-05-27)
# [0.30.0](https://gitlab.com/openstapps/core-tools/compare/v0.29.1...v0.30.0) (2022-04-04)
## [0.29.1](https://gitlab.com/openstapps/core-tools/compare/v0.29.0...v0.29.1) (2022-03-21)
# [0.29.0](https://gitlab.com/openstapps/core-tools/compare/v0.28.0...v0.29.0) (2022-01-25)
# [0.28.0](https://gitlab.com/openstapps/core-tools/compare/v0.27.0...v0.28.0) (2021-12-17)
### Bug Fixes
* ajv related tranistive build errors ([e82f4e9](https://gitlab.com/openstapps/core-tools/commit/e82f4e92099359baed5ea89f64bd7204700c2785))
- ajv related tranistive build errors ([e82f4e9](https://gitlab.com/openstapps/core-tools/commit/e82f4e92099359baed5ea89f64bd7204700c2785))
# [0.27.0](https://gitlab.com/openstapps/core-tools/compare/v0.26.0...v0.27.0) (2021-12-15)
# [0.26.0](https://gitlab.com/openstapps/core-tools/compare/v0.25.0...v0.26.0) (2021-12-15)
# [0.25.0](https://gitlab.com/openstapps/core-tools/compare/v0.24.3...v0.25.0) (2021-08-31)
### Bug Fixes
* generate schemas for type aliases ([96e3acf](https://gitlab.com/openstapps/core-tools/commit/96e3acf9ba330c3414eb1e38b347ca9e597fee88))
- generate schemas for type aliases ([96e3acf](https://gitlab.com/openstapps/core-tools/commit/96e3acf9ba330c3414eb1e38b347ca9e597fee88))
## [0.24.3](https://gitlab.com/openstapps/core-tools/compare/v0.24.2...v0.24.3) (2021-08-27)
### Bug Fixes
* add cruical Converter ceation option ([f82b465](https://gitlab.com/openstapps/core-tools/commit/f82b4652637808abf68f1e72b1de0c76b228457a))
- add cruical Converter ceation option ([f82b465](https://gitlab.com/openstapps/core-tools/commit/f82b4652637808abf68f1e72b1de0c76b228457a))
## [0.24.2](https://gitlab.com/openstapps/core-tools/compare/v0.24.1...v0.24.2) (2021-08-25)
## [0.24.1](https://gitlab.com/openstapps/core-tools/compare/v0.24.0...v0.24.1) (2021-08-25)
# [0.24.0](https://gitlab.com/openstapps/core-tools/compare/v0.23.2...v0.24.0) (2021-08-25)
### Features
* modernize core-tools ([fe59204](https://gitlab.com/openstapps/core-tools/commit/fe59204b4210831b15445fa9aa7dbc20de75e96d))
- modernize core-tools ([fe59204](https://gitlab.com/openstapps/core-tools/commit/fe59204b4210831b15445fa9aa7dbc20de75e96d))
## [0.23.2](https://gitlab.com/openstapps/core-tools/compare/v0.23.0...v0.23.2) (2021-08-02)
### Bug Fixes
* rollback ajv version to 6.12.6 ([7a5d2bb](https://gitlab.com/openstapps/core-tools/commit/7a5d2bb1e98b41d1143fbfe21b29e3aef2133c8f))
- rollback ajv version to 6.12.6 ([7a5d2bb](https://gitlab.com/openstapps/core-tools/commit/7a5d2bb1e98b41d1143fbfe21b29e3aef2133c8f))
# [0.23.0](https://gitlab.com/openstapps/core-tools/compare/v0.22.0...v0.23.0) (2021-07-21)
### Features
* replace route markdown with openapi ([f4bf7ab](https://gitlab.com/openstapps/core-tools/commit/f4bf7abc895f87a57fa34b2269311809f2a9413d))
- replace route markdown with openapi ([f4bf7ab](https://gitlab.com/openstapps/core-tools/commit/f4bf7abc895f87a57fa34b2269311809f2a9413d))
# [0.22.0](https://gitlab.com/openstapps/core-tools/compare/v0.21.0...v0.22.0) (2021-07-07)
### Bug Fixes
* fix inherited properties not working correctly ([f20038c](https://gitlab.com/openstapps/core-tools/commit/f20038c8f9a37424fd7a95484e744e0c672f5cfb))
- fix inherited properties not working correctly ([f20038c](https://gitlab.com/openstapps/core-tools/commit/f20038c8f9a37424fd7a95484e744e0c672f5cfb))
# [0.21.0](https://gitlab.com/openstapps/core-tools/compare/v0.20.0...v0.21.0) (2021-05-12)
### Features
* add support for non-external premaps ([7429806](https://gitlab.com/openstapps/core-tools/commit/74298065e0386c8e4646e565e5e383b5ae08dfaa))
- add support for non-external premaps ([7429806](https://gitlab.com/openstapps/core-tools/commit/74298065e0386c8e4646e565e5e383b5ae08dfaa))
# [0.20.0](https://gitlab.com/openstapps/core-tools/compare/v0.19.0...v0.20.0) (2021-04-26)
### Features
* add filterable annotation option for integer ([7ba8233](https://gitlab.com/openstapps/core-tools/commit/7ba8233f5b81f4ab3c3aeec2c8a47a7bad3ae502))
- add filterable annotation option for integer ([7ba8233](https://gitlab.com/openstapps/core-tools/commit/7ba8233f5b81f4ab3c3aeec2c8a47a7bad3ae502))
# [0.19.0](https://gitlab.com/openstapps/core-tools/compare/v0.18.0...v0.19.0) (2021-04-06)
# [0.18.0](https://gitlab.com/openstapps/core-tools/compare/v0.17.0...v0.18.0) (2021-03-24)
### Features
* make Point type sortable in Elasticsearch ([724a686](https://gitlab.com/openstapps/core-tools/commit/724a6866c80a544dec4ce11d70d648bd724f9aba))
- make Point type sortable in Elasticsearch ([724a686](https://gitlab.com/openstapps/core-tools/commit/724a6866c80a544dec4ce11d70d648bd724f9aba))
# [0.17.0](https://gitlab.com/openstapps/core-tools/compare/v0.16.0...v0.17.0) (2020-12-02)
### Features
* add support for [@inherit](https://gitlab.com/inherit)Tags ([485430b](https://gitlab.com/openstapps/core-tools/commit/485430b7f27fb9c751a6f5697e74eb5531ac7889))
* add support for date mapping ([a09be1d](https://gitlab.com/openstapps/core-tools/commit/a09be1d941df88826ccaa8aa468680ece29d35a5))
- add support for [@inherit](https://gitlab.com/inherit)Tags ([485430b](https://gitlab.com/openstapps/core-tools/commit/485430b7f27fb9c751a6f5697e74eb5531ac7889))
- add support for date mapping ([a09be1d](https://gitlab.com/openstapps/core-tools/commit/a09be1d941df88826ccaa8aa468680ece29d35a5))
# [0.16.0](https://gitlab.com/openstapps/core-tools/compare/v0.15.0...v0.16.0) (2020-10-28)
### Bug Fixes
* use value type in IndexSignature type instead of key type ([b7cdb6a](https://gitlab.com/openstapps/core-tools/commit/b7cdb6a9ad2bdb1fc09d0f535daf4ec778501fec))
- use value type in IndexSignature type instead of key type ([b7cdb6a](https://gitlab.com/openstapps/core-tools/commit/b7cdb6a9ad2bdb1fc09d0f535daf4ec778501fec))
# [0.15.0](https://gitlab.com/openstapps/core-tools/compare/v0.14.0...v0.15.0) (2020-10-05)
### Bug Fixes
* array tags did not propagate ([e5511d0](https://gitlab.com/openstapps/core-tools/commit/e5511d07386e93b032b5dbefa3e6cc46c07219ed))
- array tags did not propagate ([e5511d0](https://gitlab.com/openstapps/core-tools/commit/e5511d07386e93b032b5dbefa3e6cc46c07219ed))
# [0.14.0](https://gitlab.com/openstapps/core-tools/compare/v0.13.0...v0.14.0) (2020-02-11)
# [0.13.0](https://gitlab.com/openstapps/core-tools/compare/v0.12.0...v0.13.0) (2020-01-28)
# [0.12.0](https://gitlab.com/openstapps/core-tools/compare/v0.11.0...v0.12.0) (2019-12-03)
### Bug Fixes
* make fields with index signatures a dynamic mapping ([8f5570e](https://gitlab.com/openstapps/core-tools/commit/8f5570e2e2d350d6153b34f940f4cd5c407b5bc9))
- make fields with index signatures a dynamic mapping ([8f5570e](https://gitlab.com/openstapps/core-tools/commit/8f5570e2e2d350d6153b34f940f4cd5c407b5bc9))
# [0.11.0](https://gitlab.com/openstapps/core-tools/compare/v0.10.0...v0.11.0) (2019-11-12)
### Bug Fixes
* use .raw field for aggregations ([4c1a374](https://gitlab.com/openstapps/core-tools/commit/4c1a374a9ee266884bd33e8a3b3f52fcef8f4019))
- use .raw field for aggregations ([4c1a374](https://gitlab.com/openstapps/core-tools/commit/4c1a374a9ee266884bd33e8a3b3f52fcef8f4019))
# [0.10.0](https://gitlab.com/openstapps/core-tools/compare/v0.9.0...v0.10.0) (2019-11-08)
### Bug Fixes
* make mapping of generics work correctly ([8f7201e](https://gitlab.com/openstapps/core-tools/commit/8f7201e2cf010ed9ef457d9cf938167a4e970963)), closes [#27](https://gitlab.com/openstapps/core-tools/issues/27)
* make mapping tags work for overwritten values ([47361d4](https://gitlab.com/openstapps/core-tools/commit/47361d412a92ae34dc1b81298402d6b441b4f4ba))
- make mapping of generics work correctly ([8f7201e](https://gitlab.com/openstapps/core-tools/commit/8f7201e2cf010ed9ef457d9cf938167a4e970963)), closes [#27](https://gitlab.com/openstapps/core-tools/issues/27)
- make mapping tags work for overwritten values ([47361d4](https://gitlab.com/openstapps/core-tools/commit/47361d412a92ae34dc1b81298402d6b441b4f4ba))
### Features
* generate aggreations from annotations in the core ([18ad651](https://gitlab.com/openstapps/core-tools/commit/18ad651286bafcbc929e14ee9429c7b852d86f3b))
- generate aggreations from annotations in the core ([18ad651](https://gitlab.com/openstapps/core-tools/commit/18ad651286bafcbc929e14ee9429c7b852d86f3b))
# [0.9.0](https://gitlab.com/openstapps/core-tools/compare/v0.8.0...v0.9.0) (2019-09-10)
### Bug Fixes
* read type tags correctly after the first time ([77e4914](https://gitlab.com/openstapps/core-tools/commit/77e49146c0619566919815bd5d63ddf34dc19387))
- read type tags correctly after the first time ([77e4914](https://gitlab.com/openstapps/core-tools/commit/77e49146c0619566919815bd5d63ddf34dc19387))
### Features
* add support for [@filterable](https://gitlab.com/filterable) tag ([36bf17e](https://gitlab.com/openstapps/core-tools/commit/36bf17e3236a555e6d1193466141be880b280db9))
- add support for [@filterable](https://gitlab.com/filterable) tag ([36bf17e](https://gitlab.com/openstapps/core-tools/commit/36bf17e3236a555e6d1193466141be880b280db9))
# [0.8.0](https://gitlab.com/openstapps/core-tools/compare/v0.7.0...v0.8.0) (2019-07-25)
### Bug Fixes
* apply stricter tslint rules ([967f946](https://gitlab.com/openstapps/core-tools/commit/967f94652723d8589b7f272454185449233ac838))
* emend the imports in the test files ([53e8047](https://gitlab.com/openstapps/core-tools/commit/53e80476c85027194cf406ad87fe8950d6c2f3a8))
* remove duplicate job ([af904a7](https://gitlab.com/openstapps/core-tools/commit/af904a7a05de56cdef6aea136a7e3bb237c4beb2))
* update the uml job to use our node image ([a478715](https://gitlab.com/openstapps/core-tools/commit/a478715d8045dd26cd345ba3cbb469fda651b84f))
- apply stricter tslint rules ([967f946](https://gitlab.com/openstapps/core-tools/commit/967f94652723d8589b7f272454185449233ac838))
- emend the imports in the test files ([53e8047](https://gitlab.com/openstapps/core-tools/commit/53e80476c85027194cf406ad87fe8950d6c2f3a8))
- remove duplicate job ([af904a7](https://gitlab.com/openstapps/core-tools/commit/af904a7a05de56cdef6aea136a7e3bb237c4beb2))
- update the uml job to use our node image ([a478715](https://gitlab.com/openstapps/core-tools/commit/a478715d8045dd26cd345ba3cbb469fda651b84f))
### Features
* add automatic mapping generation ([7b198f9](https://gitlab.com/openstapps/core-tools/commit/7b198f95ce7bbd75454247e70757d34af462cefc)), closes [#6](https://gitlab.com/openstapps/core-tools/issues/6)
* add the uml generator ([0f21da4](https://gitlab.com/openstapps/core-tools/commit/0f21da4a92b4e0ef11a5f274468d3679fc9784ee))
* added output file name for uml generation ([843e598](https://gitlab.com/openstapps/core-tools/commit/843e59811a5a104df1c746627aa668d26fdc9f60))
- add automatic mapping generation ([7b198f9](https://gitlab.com/openstapps/core-tools/commit/7b198f95ce7bbd75454247e70757d34af462cefc)), closes [#6](https://gitlab.com/openstapps/core-tools/issues/6)
- add the uml generator ([0f21da4](https://gitlab.com/openstapps/core-tools/commit/0f21da4a92b4e0ef11a5f274468d3679fc9784ee))
- added output file name for uml generation ([843e598](https://gitlab.com/openstapps/core-tools/commit/843e59811a5a104df1c746627aa668d26fdc9f60))
# [0.7.0](https://gitlab.com/openstapps/core-tools/compare/v0.6.0...v0.7.0) (2019-06-24)
# [0.6.0](https://gitlab.com/openstapps/core-tools/compare/v0.5.1...v0.6.0) (2019-04-16)
## [0.5.1](https://gitlab.com/openstapps/core-tools/compare/v0.5.0...v0.5.1) (2019-04-09)
# [0.5.0](https://gitlab.com/openstapps/core-tools/compare/v0.4.0...v0.5.0) (2019-04-09)
# [0.4.0](https://gitlab.com/openstapps/core-tools/compare/v0.3.0...v0.4.0) (2019-04-03)
### Features
* add feature to validate schemas directly ([1022150](https://gitlab.com/openstapps/core-tools/commit/1022150ca3d2af846b819e0e0e46ead71134d5f8))
* adjust generation of route documentation ([d3ce936](https://gitlab.com/openstapps/core-tools/commit/d3ce936626751f24f20081403271d77e2c346e03)), closes [#12](https://gitlab.com/openstapps/core-tools/issues/12)
- add feature to validate schemas directly ([1022150](https://gitlab.com/openstapps/core-tools/commit/1022150ca3d2af846b819e0e0e46ead71134d5f8))
- adjust generation of route documentation ([d3ce936](https://gitlab.com/openstapps/core-tools/commit/d3ce936626751f24f20081403271d77e2c346e03)), closes [#12](https://gitlab.com/openstapps/core-tools/issues/12)
# [0.3.0](https://gitlab.com/openstapps/core-tools/compare/v0.2.1...v0.3.0) (2019-02-06)
### Features
* ensure correct path for input files ([1c74432](https://gitlab.com/openstapps/core-tools/commit/1c744328eb03dc8019fe6dc3a309f68260210146))
- ensure correct path for input files ([1c74432](https://gitlab.com/openstapps/core-tools/commit/1c744328eb03dc8019fe6dc3a309f68260210146))
## [0.2.1](https://gitlab.com/openstapps/core-tools/compare/v0.2.0...v0.2.1) (2019-01-30)
### Bug Fixes
* add SC prefix to the camel cased type of the instance ([e559234](https://gitlab.com/openstapps/core-tools/commit/e559234cea9ef245733f8117ab4a27e83db54e14))
* use tsconfig.json of project for schema generation ([6b1a420](https://gitlab.com/openstapps/core-tools/commit/6b1a4202f92759c9ef36d32d0960faf4f56cc8db)), closes [#10](https://gitlab.com/openstapps/core-tools/issues/10)
- add SC prefix to the camel cased type of the instance ([e559234](https://gitlab.com/openstapps/core-tools/commit/e559234cea9ef245733f8117ab4a27e83db54e14))
- use tsconfig.json of project for schema generation ([6b1a420](https://gitlab.com/openstapps/core-tools/commit/6b1a4202f92759c9ef36d32d0960faf4f56cc8db)), closes [#10](https://gitlab.com/openstapps/core-tools/issues/10)
### Features
* add function to find tsconfig.json ([aa645a2](https://gitlab.com/openstapps/core-tools/commit/aa645a2cc4661c58c6050196ee1944dfd9e5eea8))
- add function to find tsconfig.json ([aa645a2](https://gitlab.com/openstapps/core-tools/commit/aa645a2cc4661c58c6050196ee1944dfd9e5eea8))
# [0.2.0](https://gitlab.com/openstapps/core-tools/compare/v0.1.1...v0.2.0) (2019-01-21)
### Features
* add pack script ([7438465](https://gitlab.com/openstapps/core-tools/commit/7438465149b591ebf1583a8bd6b9da56aa9c9f57)), closes [#4](https://gitlab.com/openstapps/core-tools/issues/4)
- add pack script ([7438465](https://gitlab.com/openstapps/core-tools/commit/7438465149b591ebf1583a8bd6b9da56aa9c9f57)), closes [#4](https://gitlab.com/openstapps/core-tools/issues/4)
## [0.1.1](https://gitlab.com/openstapps/core-tools/compare/v0.1.0...v0.1.1) (2019-01-14)
### Bug Fixes
* add missing dependency typedoc ([b248d1b](https://gitlab.com/openstapps/core-tools/commit/b248d1b5e0306247ce35e5c9d45637b0f3f83cac)), closes [#5](https://gitlab.com/openstapps/core-tools/issues/5)
- add missing dependency typedoc ([b248d1b](https://gitlab.com/openstapps/core-tools/commit/b248d1b5e0306247ce35e5c9d45637b0f3f83cac)), closes [#5](https://gitlab.com/openstapps/core-tools/issues/5)
# [0.1.0](https://gitlab.com/openstapps/core-tools/compare/v0.0.3...v0.1.0) (2019-01-08)
### Features
* validate generated schemas ([7b7299d](https://gitlab.com/openstapps/core-tools/commit/7b7299d9c475105f9d2387c9dc31974139997483)), closes [#1](https://gitlab.com/openstapps/core-tools/issues/1)
- validate generated schemas ([7b7299d](https://gitlab.com/openstapps/core-tools/commit/7b7299d9c475105f9d2387c9dc31974139997483)), closes [#1](https://gitlab.com/openstapps/core-tools/issues/1)
## [0.0.3](https://gitlab.com/openstapps/core-tools/compare/v0.0.2...v0.0.3) (2018-12-18)
### Bug Fixes
* do not ignore resources ([6502bcf](https://gitlab.com/openstapps/core-tools/commit/6502bcf2b517ab98909626a7b8baa08e7cdcdc3e))
- do not ignore resources ([6502bcf](https://gitlab.com/openstapps/core-tools/commit/6502bcf2b517ab98909626a7b8baa08e7cdcdc3e))
## [0.0.2](https://gitlab.com/openstapps/core-tools/compare/v0.0.1...v0.0.2) (2018-12-18)
## [0.0.1](https://gitlab.com/openstapps/core-tools/compare/1ac90ef6330bcfd0ea362505a11db66453f3386f...v0.0.1) (2018-12-18)
### Features
* add core tools ([1ac90ef](https://gitlab.com/openstapps/core-tools/commit/1ac90ef6330bcfd0ea362505a11db66453f3386f))
- add core tools ([1ac90ef](https://gitlab.com/openstapps/core-tools/commit/1ac90ef6330bcfd0ea362505a11db66453f3386f))

View File

@@ -30,6 +30,7 @@ openstapps-core-tools schema <srcPath> <schemaPath>
```
where:
- `<srcPath>` is path to the project (where used `*.ts` files are, e.g. `src/core`,
- `<schemaPath>` is directory to save output files to, e.g. `lib/schema`.
@@ -45,14 +46,6 @@ Inside of a script in `package.json` or if the npm package is installed globally
openstapps-core-tools schema src/core lib/schema
```
## What is Easy AST?
Easy [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) is a "wrapper" around the TypeScript Compiler API. The TS Compiler API is built for many
much more complex things than just accessing type declarations, and thus comes with a ton of
bloat that makes it really difficult to work with.
This is why we built the Easy AST, which converts the TS representation to a really easy and
lightweight structure, that removes a lot of the stuff you wouldn't really need.
## How to use the validator?
@@ -65,7 +58,7 @@ import {ValidatorResult} from 'jsonschema';
import {join} from 'path';
const objectToValidate: SCDish = {
type: SCThingType.Dish,
type: SCThingType.Dish,
// more properties
};
@@ -95,6 +88,7 @@ Your basic JSON object:
```
JSON for validateFiles:
```json
{
"errorNames": [],
@@ -120,6 +114,7 @@ openstapps-core-tools validate <schemaPath> <testPath> [reportPath]
```
where:
- `<schemaPath>` is a directory where JSON schema files are, e.g. `lib/schema`,
- `<testPath>` is a directory where test files are, e.g. `src/test/resources`,
- `[reportPath]` is a file where the HTML report of the validation will be saved to, e.g. `report.html` (optional argument - if it's not provided no report will be written).
@@ -144,14 +139,6 @@ To generate a openapi JSON file that represents the routes according to openapi
openstapps-core-tools openapi PATH/TO/CORE/lib PATH/TO/PUT/FILES/TO
```
## Pack definitions and implementations
To pack all the different files into two distribution files - one for definitions/one for implementations - use the following command:
```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.
@@ -202,7 +189,8 @@ The plantuml code is persisted inside the generated file at the very bottom. You
openstapps-core-tools plantuml-file /PATH/TO/Project.plantuml http://PLANTUMLSERVER OptionalCustomFileName
```
Example-File-Content of Project.plantuml
Example-File-Content of Project.plantuml
```
@startuml
interface MyClass{

View File

@@ -1,2 +1,2 @@
#!/usr/bin/env node
import './lib/cli.js'
import './lib/app.js';

View File

@@ -13,41 +13,43 @@
"Rainer Killinger <mail-openstapps@killinger.co>",
"Thea Schöbl <dev@theaninova.de>"
],
"prettier": "@openstapps",
"keywords": [
"StApps",
"StAppsCore",
"converter",
"core",
"validator"
],
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"bin": {
"openstapps-core-tools": "app.js"
},
"scripts": {
"build": "rimraf lib && tsc",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md",
"check-configuration": "openstapps-configuration",
"documentation": "typedoc --out docs --readme README.md --includeVersion --validation.invalidLink true --entryPointStrategy expand src",
"lint": "eslint -c .eslintrc.json --ignore-path .eslintignore --ext .ts src/",
"lint:fix": "eslint --fix -c .eslintrc.json --ignore-path .eslintignore --ext .ts src/",
"build": "tsup --dts",
"format": "prettier .",
"format:fix": "prettier --write .",
"lint": "eslint --ext .ts src/",
"lint:fix": "eslint --fix --ext .ts src/",
"plantuml-restart": "docker restart plantuml-server",
"plantuml-start": "docker run --name plantuml-server -d -p 8080:8080 registry.gitlab.com/openstapps/core-tools:latest",
"plantuml-stop": "docker stop plantuml-server",
"prepublishOnly": "npm ci && npm run build",
"preversion": "npm run prepublishOnly",
"push": "git push && git push origin \"v$npm_package_version\"",
"test": "mocha --require ts-node/register test/*.spec.ts",
"version": "npm run changelog"
"test": "nyc mocha 'test/**/*.spec.ts'"
},
"dependencies": {
"@openstapps/collection-utils": "workspace:*",
"@openstapps/logger": "workspace:*",
"@openstapps/easy-ast": "workspace:*",
"ajv": "8.12.0",
"better-ajv-errors": "1.2.0",
"chai": "4.3.7",
"commander": "10.0.0",
"deepmerge": "4.3.0",
"deepmerge": "4.3.1",
"del": "6.1.1",
"eslint": "8.33.0",
"flatted": "3.2.7",
"fs-extra": "10.1.0",
"glob": "8.1.0",
"glob": "10.2.1",
"got": "12.6.0",
"humanize-string": "3.0.0",
"json-schema": "0.4.0",
@@ -61,9 +63,10 @@
"typescript": "4.8.4"
},
"devDependencies": {
"@openstapps/configuration": "workspace:*",
"@openstapps/eslint-config": "workspace:*",
"@openstapps/nyc-config": "workspace:*",
"@openstapps/prettier-config": "workspace:*",
"@openstapps/tsconfig": "workspace:*",
"@testdeck/mocha": "0.3.3",
"@types/chai": "4.3.4",
"@types/fs-extra": "9.0.13",
@@ -72,25 +75,32 @@
"@types/mocha": "10.0.1",
"@types/mustache": "4.2.2",
"@types/node": "18.15.3",
"@types/rimraf": "3.0.2",
"@typescript-eslint/eslint-plugin": "5.49.0",
"@typescript-eslint/parser": "5.49.0",
"conventional-changelog-cli": "2.2.2",
"eslint-config-prettier": "8.6.0",
"eslint-plugin-jsdoc": "39.7.4",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-unicorn": "45.0.2",
"mocha": "10.2.0",
"nock": "13.3.0",
"prettier": "2.8.3",
"rimraf": "4.4.0",
"typedoc": "0.23.26"
"tsup": "6.7.0",
"typedoc": "0.23.28"
},
"keywords": [
"StApps",
"StAppsCore",
"converter",
"core",
"validator"
]
"tsup": {
"entry": [
"src/app.ts",
"src/index.ts"
],
"sourcemap": true,
"clean": true,
"format": "esm",
"outDir": "lib"
},
"prettier": "@openstapps/prettier-config",
"eslintConfig": {
"extends": [
"@openstapps"
]
},
"eslintIgnore": [
"resources",
"openapi"
],
"nyc": {
"extends": "@openstapps/nyc-config"
}
}

View File

@@ -18,8 +18,7 @@ import {existsSync, readFileSync, writeFileSync} from 'fs';
import {copy} from 'fs-extra';
import path from 'path';
import {mkdirPromisified, readFilePromisified} from './common.js';
import {lightweightDefinitionsFromPath, lightweightProjectFromPath} from './easy-ast/easy-ast.js';
import {pack} from './pack.js';
import {lightweightDefinitionsFromPath, lightweightProjectFromPath} from '@openstapps/easy-ast';
import {openapi3Template} from './resources/openapi-303-template.js';
import {gatherRouteInformation, generateOpenAPIForRoute} from './routes.js';
import {Converter, getValidatableTypesInPath} from './schema.js';
@@ -27,7 +26,7 @@ import {createDiagram, createDiagramFromString} from './uml/create-diagram.js';
import {UMLConfig} from './uml/uml-config.js';
import {capitalize} from './util/string.js';
import {validateFiles, writeReport} from './validate.js';
import {fileURLToPath} from "url";
import {fileURLToPath} from 'url';
// handle unhandled promise rejections
process.on('unhandledRejection', async (reason: unknown) => {
@@ -41,7 +40,11 @@ process.on('unhandledRejection', async (reason: unknown) => {
const commander = new Command('openstapps-core-tools');
// eslint-disable-next-line unicorn/prefer-module
commander.version(JSON.parse(readFileSync(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'package.json')).toString()).version);
commander.version(
JSON.parse(
readFileSync(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'package.json')).toString(),
).version,
);
commander.command('prototype <srcBundle> <out>').action(async (sourcePath, out) => {
const files = lightweightProjectFromPath(sourcePath);
@@ -201,10 +204,6 @@ commander
}
});
commander.command('pack').action(async () => {
await pack();
});
commander
.command('plantuml <srcPath> <plantumlserver>')
.option('--definitions <definitions>', 'Shows these specific definitions (class, interface or enum)', it =>

View File

@@ -1,10 +1,10 @@
declare module 'better-ajv-errors' {
import type { ErrorObject } from 'ajv';
import type {ErrorObject} from 'ajv';
export interface IOutputError {
start: { line: number; column: number; offset: number };
start: {line: number; column: number; offset: number};
// Optional for required
end?: { line: number; column: number; offset: number };
end?: {line: number; column: number; offset: number};
error: string;
suggestion?: string;
}
@@ -21,6 +21,6 @@ declare module 'better-ajv-errors' {
schema: S,
data: T,
errors: Array<ErrorObject>,
options?: Options
): Options extends { format: 'js' } ? Array<IOutputError> : string;
options?: Options,
): Options extends {format: 'js'} ? Array<IOutputError> : string;
}

View File

@@ -1,117 +0,0 @@
/*
* Copyright (C) 2021 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 * as ts from 'typescript';
import {cleanupEmpty} from '../util/collections.js';
import {LightweightComment} from './types/lightweight-comment.js';
/** @internal */
export function extractComment(node: ts.Node): LightweightComment | undefined {
const jsDocuments =
// @ts-expect-error jsDoc exists in reality
node.jsDoc as
| Array<{
comment?: string;
tags?: Array<{comment?: string; tagName?: {escapedText?: string}}>;
}>
| undefined;
const jsDocument = jsDocuments?.[jsDocuments.length - 1]
const comment = jsDocument?.comment?.split('\n\n');
return jsDocument === undefined
? undefined
: cleanupEmpty({
shortSummary: comment?.[0],
description: comment?.[comment.length - 1],
tags: jsDocument?.tags?.map(tag =>
cleanupEmpty({
name: tag.tagName?.escapedText ?? 'UNRESOLVED_NAME',
parameters: tag.comment?.split(' '),
}),
),
});
}
/** @internal */
export function isProperty(
node: ts.ClassElement | ts.TypeElement,
): node is ts.PropertyDeclaration | ts.PropertySignature {
return ts.isPropertyDeclaration(node) || ts.isPropertySignature(node);
}
/** @internal */
export function filterNodeTo<T extends ts.Node, S extends T>(
node: ts.NodeArray<T>,
check: (node: T) => node is S,
): S[] {
return node.filter(check);
}
/** @internal */
export function filterChildrenTo<T extends ts.Node>(node: ts.Node, check: (node: ts.Node) => node is T): T[] {
const out: T[] = [];
node.forEachChild(child => {
if (check(child)) {
out.push(child);
}
});
return out;
}
/** @internal */
export function getModifiers(text: string, kind: string): string[] {
return [
...text
.split(kind)[0]
.split(/\s+/)
.filter(it => it !== ''),
kind,
];
}
/** @internal */
export function resolvePropertyName(name?: ts.PropertyName): string | undefined {
return name === undefined
? undefined
: ts.isComputedPropertyName(name)
? 'UNSUPPORTED_IDENTIFIER_TYPE'
: name.getText();
}
/** @internal */
export function resolveTypeName(type?: ts.TypeNode): string | undefined {
// @ts-expect-error typeName exists in reality
return type?.typeName?.escapedText ?? type?.typeName?.right?.escapedText;
}
/** @internal */
export function isArrayLikeType(typeNode?: ts.TypeNode): typeNode is ts.ArrayTypeNode | ts.TypeReferenceNode {
return typeNode !== undefined && (ts.isArrayTypeNode(typeNode) || isArrayReference(typeNode));
}
/** @internal */
export function isArrayReference(typeNode: ts.TypeNode): boolean {
return ts.isTypeReferenceNode(typeNode) && (typeNode.typeName as ts.Identifier).escapedText === 'Array';
}
/** @internal */
export function isClassLikeNode(node: ts.Node): node is ts.ClassDeclaration | ts.InterfaceDeclaration {
return ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node);
}
/** @internal */
export function isEnumLikeNode(node: ts.Node): node is ts.EnumDeclaration | ts.TypeAliasDeclaration {
return ts.isEnumDeclaration(node) || ts.isTypeAliasDeclaration(node);
}

View File

@@ -1,83 +0,0 @@
/* eslint-disable jsdoc/require-jsdoc */
/*
* Copyright (C) 2021 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 ts from 'typescript';
import {LightweightAliasDefinition} from './types/lightweight-alias-definition.js';
import {LightweightClassDefinition} from './types/lightweight-class-definition.js';
import {LightweightDefinition} from './types/lightweight-definition.js';
import {LightweightDefinitionKind} from './types/lightweight-definition-kind.js';
import {LightweightProject} from './types/lightweight-project.js';
import {LightweightType} from './types/lightweight-type.js';
import {keyBy} from "@openstapps/collection-utils/lib/key-by.js";
/**
* Creates a printable name of a type
*/
export function expandTypeValue(type: LightweightType): string | undefined {
if (type.isArray) {
return `${type.value}[]`;
}
if (isStringLiteralType(type)) {
return `'${type.value}'`;
}
if (isUnionOrIntersectionType(type)) {
return type.specificationTypes?.map(expandTypeValue).join(isUnionType(type) ? ' | ' : ' & ');
}
if (type.genericsTypes?.length === 0) {
return `${type.value}<${type.genericsTypes?.map(expandTypeValue).join(', ')}>`;
}
return type.value?.toString();
}
export function definitionsOf(project: LightweightProject): Record<string, LightweightDefinition> {
return keyBy(Object.values(project).flatMap(Object.values), it => it.name);
}
export function isPrimitiveType(type: { flags: ts.TypeFlags }): boolean {
return (type.flags & ts.TypeFlags.NonPrimitive) === 0;
}
export function isLiteralType(type: { flags: ts.TypeFlags }): boolean {
return (type.flags & ts.TypeFlags.Literal) !== 0;
}
export function isEnumLiteralType(type: { flags: ts.TypeFlags }): boolean {
return (type.flags & ts.TypeFlags.EnumLiteral) !== 0;
}
export function isStringLiteralType(type: { flags: ts.TypeFlags }): boolean {
return (type.flags & ts.TypeFlags.StringLiteral) !== 0;
}
export function isUnionOrIntersectionType(type: { flags: ts.TypeFlags }): boolean {
return (type.flags & ts.TypeFlags.UnionOrIntersection) !== 0;
}
export function isUnionType(type: { flags: ts.TypeFlags }): boolean {
return (type.flags & ts.TypeFlags.Union) !== 0;
}
export function isLightweightClass(node?: LightweightDefinition): node is LightweightClassDefinition {
return node?.kind === LightweightDefinitionKind.CLASS_LIKE;
}
export function isLightweightEnum(node?: LightweightDefinition): node is LightweightAliasDefinition {
return node?.kind === LightweightDefinitionKind.ALIAS_LIKE;
}
export function isTypeVariable(type: { flags: ts.TypeFlags }): boolean {
return (type.flags & ts.TypeFlags.TypeVariable) !== 0;
}

View File

@@ -1,251 +0,0 @@
/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */
/*
* Copyright (C) 2021 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 ts from 'typescript';
import {cleanupEmpty, mapNotNil, rejectNil} from '../util/collections.js';
import {expandPathToFilesSync} from '../util/io.js';
import {
extractComment,
filterChildrenTo,
filterNodeTo,
getModifiers,
isArrayLikeType,
isClassLikeNode,
isEnumLikeNode,
isProperty,
resolvePropertyName,
resolveTypeName,
} from './ast-internal-util.js';
import {isEnumLiteralType, isTypeVariable} from './ast-util.js';
import {LightweightAliasDefinition} from './types/lightweight-alias-definition.js';
import {LightweightClassDefinition} from './types/lightweight-class-definition.js';
import {LightweightDefinition} from './types/lightweight-definition.js';
import {LightweightDefinitionKind} from './types/lightweight-definition-kind.js';
import {LightweightProject} from './types/lightweight-project.js';
import {LightweightType} from './types/lightweight-type.js';
import path from 'path';
import {LightweightProperty} from './types/lightweight-property.js';
import {mapValues} from "@openstapps/collection-utils/lib/map-values.js";
import {groupBy} from "@openstapps/collection-utils/lib/group-by.js";
import {keyBy} from "@openstapps/collection-utils/lib/key-by.js";
/**
* Convert a TypeScript project to a lightweight Type-AST representation of the project
*
* @param sourcePath either a directory or a set of input files
* @param includeComments if comments should be included (default true)
*/
export function lightweightProjectFromPath(
sourcePath: string | string[],
includeComments = true,
): LightweightProject {
return new LightweightDefinitionBuilder(sourcePath, includeComments).convert();
}
/**
* Convert a TypeScript project to a set of lightweight definition ASTs
*
* @param sourcePath either a directory or a set of input files
* @param includeComments if comments should be included (default true)
*/
export function lightweightDefinitionsFromPath(
sourcePath: string | string[],
includeComments = true,
): LightweightDefinition[] {
return rejectNil(new LightweightDefinitionBuilder(sourcePath, includeComments).convertToList());
}
/**
* Reads the reflection model and converts it into a flatter, easier to handle model
*/
class LightweightDefinitionBuilder {
readonly program: ts.Program;
readonly sourceFiles: readonly ts.SourceFile[];
readonly typeChecker: ts.TypeChecker;
constructor(sourcePath: string | string[], readonly includeComments: boolean) {
const rootNames = Array.isArray(sourcePath)
? sourcePath
: expandPathToFilesSync(path.resolve(sourcePath), file => file.endsWith('ts'));
this.program = ts.createProgram({
rootNames: rootNames,
options: {
alwaysStrict: true,
charset: 'utf8',
declaration: true,
esModuleInterop: true,
experimentalDecorators: true,
inlineSourceMap: true,
module: ts.ModuleKind.CommonJS,
strict: true,
target: ts.ScriptTarget.ES2015,
},
});
this.typeChecker = this.program.getTypeChecker();
this.sourceFiles = mapNotNil(this.program.getRootFileNames(), it => this.program.getSourceFile(it));
}
private convertAliasLike(enumLike: ts.EnumDeclaration | ts.TypeAliasDeclaration): LightweightAliasDefinition {
return cleanupEmpty({
comment: this.includeComments ? extractComment(enumLike) : undefined,
name: enumLike.name.getText() ?? 'ERROR',
kind: LightweightDefinitionKind.ALIAS_LIKE,
modifiers: getModifiers(enumLike.getText(), ts.isEnumDeclaration(enumLike) ? 'enum' : 'type'),
type: ts.isEnumDeclaration(enumLike)
? enumLike.members.length > 0
? {
flags: 1_048_576,
specificationTypes: enumLike.members.map(it => this.lightweightTypeAtNode(it)),
}
: undefined
: this.lightweightTypeFromType(this.typeChecker.getTypeFromTypeNode(enumLike.type), enumLike.type),
});
}
private convertClassLike(classLike: ts.ClassDeclaration | ts.InterfaceDeclaration): LightweightClassDefinition {
const heritages = mapValues(
groupBy([...(classLike.heritageClauses!)], it => it.token.toString()),
heritages => heritages.flatMap(it => it.types),
);
return cleanupEmpty({
comment: this.includeComments ? extractComment(classLike) : undefined,
name: classLike.name?.escapedText ?? 'ERROR',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: getModifiers(classLike.getText(), ts.isClassDeclaration(classLike) ? 'class' : 'interface'),
extendedDefinitions: heritages[ts.SyntaxKind.ExtendsKeyword]?.map(it => this.lightweightTypeAtNode(it)),
implementedDefinitions: heritages[ts.SyntaxKind.ImplementsKeyword]?.map(it =>
this.lightweightTypeAtNode(it),
),
indexSignatures: keyBy(
filterNodeTo(
classLike.members as ts.NodeArray<ts.ClassElement | ts.TypeElement>,
ts.isIndexSignatureDeclaration,
).map(indexSignature =>
cleanupEmpty({
name:
this.typeChecker.getSignatureFromDeclaration(indexSignature)?.parameters?.[0]?.escapedName ??
'UNRESOLVED_INDEX_SIGNATURE',
type: this.lightweightTypeFromType(
this.typeChecker.getTypeFromTypeNode(indexSignature.type),
indexSignature.type,
),
indexSignatureType: this.lightweightTypeFromType(
this.typeChecker.getTypeFromTypeNode(indexSignature.parameters[0].type!),
indexSignature.parameters[0].type!,
),
}),
),
it => it.name,
),
typeParameters: classLike.typeParameters?.map(it => it.name.getText()),
properties: this.collectProperties(classLike.members),
});
}
collectProperties(members: ts.NodeArray<ts.ClassElement | ts.TypeElement>): Record<string, LightweightProperty> {
return keyBy(
filterNodeTo(members as ts.NodeArray<ts.ClassElement | ts.TypeElement>, isProperty).map(property =>
cleanupEmpty({
comment: this.includeComments ? extractComment(property) : undefined,
name: resolvePropertyName(property.name) ?? property.getText(),
type: this.lightweightTypeAtNode(property),
properties: this.collectProperties((property.type as ts.TypeLiteralNode)?.members),
optional: ts.isPropertyDeclaration(property)
? property.questionToken === undefined
? undefined
: true
: undefined,
}),
),
it => it.name,
);
}
private lightweightTypeAtNode(node: ts.Node): LightweightType {
const type = this.typeChecker.getTypeAtLocation(node);
return this.lightweightTypeFromType(type, this.typeChecker.typeToTypeNode(type, node, undefined));
}
private lightweightTypeFromType(type: ts.Type, typeNode?: ts.TypeNode): LightweightType {
if (typeNode?.kind === ts.SyntaxKind.ConditionalType) {
return {value: 'UNSUPPORTED_CONDITIONAL_TYPE', flags: ts.TypeFlags.Unknown};
}
if (isArrayLikeType(typeNode)) {
const elementType = ts.isArrayTypeNode(typeNode) ? typeNode.elementType : typeNode.typeArguments?.[0]!;
const out = this.lightweightTypeFromType(
this.typeChecker.getTypeFromTypeNode(elementType),
elementType,
);
out.isArray = true;
return out;
}
const isReference = typeNode !== undefined && ts.isTypeReferenceNode(typeNode) && !isEnumLiteralType(type);
const isTypeLiteral = typeNode !== undefined && ts.isTypeLiteralNode(typeNode);
// @ts-expect-error intrinsic name & value exist
const intrinsicName = (type.intrinsicName ?? type.value) as string | undefined;
return cleanupEmpty({
value: intrinsicName,
referenceName: isTypeLiteral
? undefined
: resolveTypeName(typeNode) ?? (type.symbol?.escapedName as string | undefined),
flags: type.flags,
genericsTypes: isTypeVariable(type)
? undefined
: this.typeChecker
.getApparentType(type)
// @ts-expect-error resolvedTypeArguments exits
?.resolvedTypeArguments?.filter(it => !it.isThisType)
?.map((it: ts.Type) => this.lightweightTypeFromType(it)),
specificationTypes:
type.isUnionOrIntersection() && !isReference
? type.types.map(it =>
this.lightweightTypeFromType(it, this.typeChecker.typeToTypeNode(it, undefined, undefined)),
)
: undefined,
});
}
/**
* Start the conversion process
*/
convert(): LightweightProject {
return mapValues(
keyBy([...this.sourceFiles], it => it.fileName),
file =>
keyBy(
[
...filterChildrenTo(file, isClassLikeNode).map(it => this.convertClassLike(it)),
...filterChildrenTo(file, isEnumLikeNode).map(it => this.convertAliasLike(it)),
],
it => it.name,
),
);
}
/**
* Same as conversion, but generates a simple list of all definitions.
*/
convertToList(): LightweightDefinition[] {
return Object.values(this.convert()).flatMap(it => it.values);
}
}

View File

@@ -1,32 +0,0 @@
/*
* Copyright (C) 2021 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 {LightweightDefinitionBase} from './lightweight-definition.js';
import {LightweightDefinitionKind} from './lightweight-definition-kind.js';
import {LightweightType} from './lightweight-type.js';
/**
* Represents an enum definition
*/
export interface LightweightAliasDefinition extends LightweightDefinitionBase {
/**
* Kind
*/
kind: LightweightDefinitionKind.ALIAS_LIKE;
/**
* Enumeration or union values
*/
type?: LightweightType;
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) 2021 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 {LightweightDefinitionBase} from './lightweight-definition.js';
import {LightweightDefinitionKind} from './lightweight-definition-kind.js';
import {LightweightIndexSignature, LightweightProperty} from './lightweight-property.js';
import {LightweightType} from './lightweight-type.js';
/**
* Represents a class definition
*/
export interface LightweightClassDefinition extends LightweightDefinitionBase {
/**
* String values of the extended definitions
*/
extendedDefinitions?: LightweightType[];
/**
* String values of the implemented definitions
*/
implementedDefinitions?: LightweightType[];
/**
* Index signatures
*/
indexSignatures?: Record<string, LightweightIndexSignature>;
/**
* Kind
*/
kind: LightweightDefinitionKind.CLASS_LIKE;
/**
* Properties of the definition
*/
properties?: Record<string, LightweightProperty>;
/**
* Generic type parameters of this class
*/
typeParameters?: string[];
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright (C) 2021 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 a Comment
*/
export interface LightweightComment {
/**
* Description of the comment
*/
description?: string;
/**
* Short summary of the comment
*/
shortSummary?: string;
/**
* Tags of the comment
*/
tags?: LightweightCommentTag[];
}
/**
* Lightweight comment tag
*/
export interface LightweightCommentTag {
/**
* The name of the tag
*/
name: string;
/**
* The parameters of the tag
*/
parameters?: string[];
}

View File

@@ -1,19 +0,0 @@
/*
* Copyright (C) 2021 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 LightweightDefinitionKind {
CLASS_LIKE = 'class-like',
ALIAS_LIKE = 'alias-like',
}

View File

@@ -1,46 +0,0 @@
/*
* Copyright (C) 2021 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 {LightweightDefinitionKind} from './lightweight-definition-kind.js';
import {LightweightComment} from './lightweight-comment.js';
import {LightweightClassDefinition} from './lightweight-class-definition.js';
import {LightweightAliasDefinition} from './lightweight-alias-definition.js';
export type LightweightDefinition = LightweightClassDefinition | LightweightAliasDefinition;
/**
* Represents any definition without specifics
*/
export interface LightweightDefinitionBase {
/**
* The comment of the definition
*/
comment?: LightweightComment;
/**
* Kind of the definition
*/
kind: LightweightDefinitionKind;
/**
* The definition type
* e.g. [`abstract`, `class`] or [`enum`] or [`export`, `type`]
*/
modifiers?: string[];
/**
* Name of the definition
*/
name: string;
}

View File

@@ -1,99 +0,0 @@
/*
* Copyright (C) 2021 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 {mapNotNil} from '../../util/collections.js';
import {definitionsOf, isLightweightClass} from '../ast-util.js';
import {lightweightProjectFromPath} from '../easy-ast.js';
import {LightweightClassDefinition} from './lightweight-class-definition.js';
import {LightweightDefinition} from './lightweight-definition.js';
/**
* Build an index for a lightweight project
*/
function buildIndex(project: LightweightProject): Record<string, string> {
return Object.fromEntries(
Object.values(project).flatMap((definitions, file) => Object.keys(definitions).map(definition => [definition, file.toString()]))
);
}
/**
* A lightweight definition class for more advanced use cases
*/
export class LightweightProjectWithIndex {
/**
* All definitions
*/
readonly definitions: Record<string, LightweightDefinition>;
/**
* Project
*/
readonly files: LightweightProject;
/**
* Index of all definitions to their respective files
*/
readonly index: {
[definitionName: string]: string;
};
constructor(project: LightweightProject | string) {
this.files = typeof project === 'string' ? lightweightProjectFromPath(project) : project;
this.index = buildIndex(this.files);
this.definitions = definitionsOf(this.files);
}
/**
* Apply inherited classes; default deeply
*/
applyInheritance(classLike: LightweightClassDefinition, deep?: boolean): LightweightDefinition {
return Object.assign(
mapNotNil(
[...(classLike.implementedDefinitions ?? []), ...(classLike.extendedDefinitions ?? [])],
extension => {
const object = this.definitions[extension.referenceName ?? ''];
return (deep ?? true) && isLightweightClass(object)
? this.applyInheritance(object)
: JSON.parse(JSON.stringify(object));
},
),
JSON.parse(JSON.stringify(classLike)),
);
}
/**
* Instantiate a definition
*
* Requires the program to be run with `--require ts-node/register`
*/
async instantiateDefinitionByName<T>(name: string, findCompiledModule = true): Promise<T | undefined> {
const fsPath = this.index[name];
if (fsPath === undefined) {
return undefined;
}
const module = await import(findCompiledModule ? `${fsPath.replace(/\.d\.ts$/, '')}.js` : fsPath);
return new module[name]() as T;
}
}
export interface LightweightFile {
[definitionName: string]: LightweightDefinition;
}
export interface LightweightProject {
[sourcePath: string]: LightweightFile;
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) 2021 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 {LightweightComment} from './lightweight-comment.js';
import {LightweightType} from './lightweight-type.js';
/**
* Represents a property definition
*/
export interface LightweightProperty {
/**
* The comment of the property
*/
comment?: LightweightComment;
/**
* Name of the property
*/
name: string;
/**
* Is the property marked as optional
*/
optional?: true;
/**
* A record of properties if the property happens to be a type literal
*/
properties?: Record<string, LightweightProperty>;
/**
* Type of the property
*/
type: LightweightType;
}
export interface LightweightIndexSignature extends LightweightProperty {
/**
* Type of the index signature, if it is an index signature
*/
indexSignatureType: LightweightType;
}

View File

@@ -1,58 +0,0 @@
/*
* Copyright (C) 2021 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 {TypeFlags} from 'typescript';
/**
* Describes an easy to use type definition.
*/
export interface LightweightType {
/**
* Type Flags
*/
flags: TypeFlags;
/**
* Contains all types inside of <> brackets
*/
genericsTypes?: LightweightType[];
/**
* If it is an array(-like) type
*/
isArray?: true;
/**
* If it is a type parameter
*/
isTypeParameter?: true;
/**
* The name of the type that is referenced. Enum members have reference names that lead no where.
*/
referenceName?: string;
/**
* Type specifications, if the type is combined by either an array, union or a typeOperator
*/
specificationTypes?: LightweightType[];
/**
* Value of the type
*
* Literal types have their value here, non-literals their type name (for example 'string')
*/
value?: string | number | boolean;
}

View File

@@ -0,0 +1,11 @@
export * from './validate.js'
export * from './types/validator.js'
export * from './uml/uml-config.js'
export * from './uml/create-diagram.js'
export * from './routes.js'
export * from './types/routes.js'
export * from './schema.js'
export * from './types/schema.js'

View File

@@ -1,465 +0,0 @@
/* eslint-disable unicorn/error-message */
/*
* Copyright (C) 2021 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 del from 'del';
import {existsSync} from 'fs';
import {cwd} from 'process';
import {globPromisified, readFilePromisified, unlinkPromisified, writeFilePromisified} from './common.js';
import {JavaScriptModule} from './types/pack.js';
import path from 'path';
const PACK_IDENTIFIER = '/* PACKED BY @openstapps/pack */';
const posixCwd = cwd().replaceAll(path.win32.sep, path.posix.sep)
/**
* Pack cli.js
*
* This finds all internal requires and replaces the paths with `./index` or internal requires if it has been
* required already.
*
* Furthermore it checks that no shebang line is present and that it does not export anything.
*/
async function packCliJs(): Promise<void> {
const cliPath = path.join(cwd(), 'lib', 'cli.js');
if (!existsSync(cliPath)) {
return;
}
Logger.info('Adjusting JavaScript CLI...');
const buffer = await readFilePromisified(cliPath);
const content = buffer.toString();
if (content.indexOf('#!/') === 0) {
throw new Error('`cli.js` must not contain a shebang line! It is added by this script.');
}
let internalRequire: string | undefined;
const adjustedContent = content
.split('\n')
.map((line, lineNumber) => {
// check for exports (cli.js is not allowed to export anything)
if (Array.isArray(line.match(/^\s*((exports)|(module\.exports))/))) {
throw new TypeError(
`Line '${lineNumber}' in 'cli.js' exports something. cli.js is not for exporting. Line was:\n${line}`,
);
}
// replace lines with internal requires
// extract module name from line
const match = line.match(/^(\s*)(const|var) ([a-z0-9_]*) = require\(("[^"]+"|'[^']+')\);$/i);
if (match !== null) {
const importedName = match[3];
// eslint-disable-next-line unicorn/prefer-string-slice
const moduleName = match[4].substring(1, match[4].length - 1);
// if it begins with '.' and not ends with json
if (/^[.]{1,2}\/(?!.*\.json$).*$/i.test(moduleName)) {
// is the first internal require
if (internalRequire) {
return `const ${importedName} = ${internalRequire};`;
}
// only the first import needs a require
internalRequire = importedName;
return `const ${importedName} = require("./index");`;
}
}
return line;
})
.join('\n');
return writeFilePromisified(cliPath, `#!/usr/bin/env node\n\n${adjustedContent}`);
}
/**
* Get a list containing the contents of all type definition files
*/
async function getAllTypeDefinitions(): Promise<string[]> {
const fileNames = await globPromisified(path.posix.join(posixCwd, '*(lib|src)', '**', '*.d.ts'), {
ignore: [
path.posix.join(posixCwd, 'lib', 'doc', '**', '*.d.ts'),
path.posix.join(posixCwd, 'lib', 'test', '**', '*.d.ts'),
path.posix.join(posixCwd, 'lib', 'cli.d.ts'),
],
});
const promises = fileNames.map(async (fileName: string) => {
return readFilePromisified(fileName, 'utf8');
});
return Promise.all(promises);
}
/**
* Pack a list of type definitions into one file
*/
async function packTypeDefinitions(): Promise<void> {
Logger.info('Packing TypeScript definition files...');
const indexPath = path.join(cwd(), 'lib', 'index.d.ts');
await deleteFileIfExistingAndPacked(indexPath);
const typeDefinitions = await getAllTypeDefinitions();
// pack TypeScript definition files
const imports: {[k: string]: string[]} = {};
const referenceLines: string[] = [];
let allDefinitions = typeDefinitions
// concat them separated by new lines
.join('\n\n\n\n\n')
// split all lines
.split('\n')
.map(line => {
if (line.includes('export =')) {
throw new Error('`export =` is not allowed by pack. Use named imports instead.');
}
if (line.indexOf('/// <reference') === 0) {
referenceLines.push(line);
return '// moved referenced line';
}
// match import lines
const match = line.match(/^import\s+{\s*([^}].*)\s*}\s+from\s+['"]([^'"].*)['"];$/);
if (match !== null) {
const module = match[2];
// extract imported objects
const importedObjects = match[1].split(',').map(object => {
return object.trim();
});
// add list of already imported objects for module
if (imports[module] === undefined) {
imports[module] = [];
}
// count already imported objects and objects to import now
const objectsToImport: string[] = [];
for (const object of importedObjects) {
if (!imports[module].includes(object)) {
imports[module].push(object);
objectsToImport.push(object);
}
}
// replace import line
if (objectsToImport.length === 0) {
return '// extraneous removed import';
}
return `import {${objectsToImport.join(', ')}} from '${module}';`;
}
return line;
})
// filter lines which contain "local" imports
.filter(line => {
return line.match(/^import .* from '\./) === null;
})
// concat all lines separated by new lines
.join('\n');
if (allDefinitions.length > 0) {
if (referenceLines.length > 0) {
allDefinitions = `${referenceLines.join('\n')}
${allDefinitions}`;
}
// write packed TypeScript definition files
return writeFilePromisified(
indexPath,
`${PACK_IDENTIFIER}
${allDefinitions}`,
);
}
}
/**
* Get all JavaScript modules
*/
async function getAllJavaScriptModules(): Promise<JavaScriptModule[]> {
const fileNames = await globPromisified(path.posix.join(posixCwd, 'lib', '**', '*.js'), {
ignore: [
path.posix.join(posixCwd, 'lib', 'doc', '**', '*.js'),
path.posix.join(posixCwd, 'lib', 'test', '*.js'),
path.posix.join(posixCwd, 'lib', 'cli.js'),
],
});
const promises = fileNames.map(async (fileName: string) => {
const fileContent = await readFilePromisified(fileName, 'utf8');
const directory = path.dirname(fileName).replace(new RegExp(`^${path.join(cwd(), 'lib')}`), '');
return {
content: `(function() {
${fileContent}
})();
`,
dependencies: getAllInternalDependencies(fileContent),
directory: directory,
name: path.basename(fileName, '.js'),
};
});
return Promise.all(promises);
}
/**
* Pack all javascript files
*/
async function packJavaScriptFiles(): Promise<void> {
const indexPath = path.join(cwd(), 'lib', 'index.js');
Logger.info('Packing JavaScript files...');
await deleteFileIfExistingAndPacked(indexPath);
// topologically sort the modules (sort by dependencies)
const jsModules = topologicalSort(await getAllJavaScriptModules());
let wholeCode = jsModules
// convert modules to strings
.map(module => {
module.content = module.content
.split('\n')
.map(line => {
const match = line.match(
/^(\s*)(const|var) ([a-z0-9_]*) = ((require\("([^"]+)"\))|(require\('([^']+)'\)));$/i,
);
// replace lines with internal requires
if (match !== null) {
if (match[6] === undefined) {
match[6] = match[8];
}
const whiteSpace = typeof match[1] === 'string' && match[1].length > 0 ? match[1] : '';
const importedName = match[3];
const modulePath = match[6];
// leave line unchanged if it is a "global" import
if (modulePath.match(/^[.]{1,2}\//) === null) {
return line;
}
// replace internal requires with `module.exports`
if (existsSync(path.join(cwd(), 'lib', module.directory, `${modulePath}.js`))) {
return `${whiteSpace}const ${importedName} = module.exports;`;
}
if (existsSync(path.join(cwd(), 'src', module.directory, modulePath))) {
return `${whiteSpace} const ${importedName} = require(../src/${modulePath});`;
}
Logger.warn(`Import ${importedName} could not be found in module.directory ${modulePath}.`);
}
return line;
})
.join('\n');
return `// Module: ${module.name}
${module.content}`;
})
// concat them separated by new lines
.join('\n\n\n\n\n')
// split all lines
.split('\n')
// filter lines
.filter(line => {
// remove strict usage
if (line === '"use strict";') {
return false;
}
// remove esModule property
if (line === 'Object.defineProperty(exports, "__esModule", { value: true });') {
return false;
}
// remove source map references
if (line.indexOf('//# sourceMappingURL=') === 0) {
return false;
}
// keep all other lines
return true;
})
// concat all lines separated by new lines
.join('\n');
if (wholeCode.length > 0) {
// add meta lines to the file
wholeCode = `"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
${wholeCode}`;
// write packed JavaScript files
return writeFilePromisified(
indexPath,
`${PACK_IDENTIFIER}
${wholeCode}`,
);
}
}
/**
* Delete file if it exists and is packed by this script
*
* @param path Path to file to check/delete
*/
async function deleteFileIfExistingAndPacked(path: string): Promise<void> {
try {
const buffer = await readFilePromisified(path);
const content = buffer.toString();
// check if packed by this script
if (content.indexOf(PACK_IDENTIFIER) === 0) {
Logger.log(`Found '${path}' which is packed by this script. Deleting it...`);
return unlinkPromisified(path);
}
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
return;
}
}
}
/**
* Get all internal dependencies from the content of a module
*
* @param moduleContent Module content to analyze
*/
function getAllInternalDependencies(moduleContent: string): string[] {
// match all const <name> = require(<moduleName>);
const requireLines = moduleContent.match(
/^\s*(const|var) [a-z0-9_]* = require\("([^"]+)"\)|require\('([^']+)'\);$/gim,
);
if (Array.isArray(requireLines)) {
return requireLines
.map(requireLine => {
const matches = requireLine.match(/require\("([^"]+)"\)|require\('([^']+)'\);$/i);
// previously matched require line does not contain a require?!
if (matches === null) {
throw new Error();
}
// return only the moduleName
return matches[1];
})
.filter(moduleName => {
// filter out internal modules beginning with './' and not ending with '.json'
return /^[.]{1,2}\/(?!.*\.json$).*$/i.test(moduleName);
})
.map(internalModuleName => {
// cut './' from the name
return internalModuleName.slice('./'.length);
});
}
return [];
}
/**
* Sort modules by their dependencies
*
* @param modules Modules to sort
*/
function topologicalSort(modules: JavaScriptModule[]): JavaScriptModule[] {
// eslint-disable-next-line unicorn/prefer-module,@typescript-eslint/no-var-requires
const topoSort = require('toposort');
// vertices are modules, an edge from a to b means that b depends on a
const edges: string[][] = [];
const nodes: string[] = [];
// add all edges
for (const module of modules) {
for (const dependencyPath of module.dependencies) {
// add edge from dependency to our module
edges.push([path.basename(dependencyPath), module.name]);
}
nodes.push(module.name);
}
// sort graph and return as an array of sorted modules
return topoSort.array(nodes, edges).map((moduleName: string) => {
return modules.find(module => {
return module.name === moduleName;
});
});
}
/**
* Pack
*/
export async function pack() {
Logger.log(`Packing project in ${process.cwd()}...`);
// run all tasks in parallel
const promises: Array<Promise<void>> = [packCliJs(), packTypeDefinitions(), packJavaScriptFiles()];
await Promise.all(promises);
// clean up afterwards
Logger.info('Deleting extraneous files...');
await del([
// delete all transpiled files
'lib/*',
// keep packed files
'!lib/index.d.ts',
'!lib/index.js',
// keep converted schema files
'!lib/schema',
'!lib/schema/*.json',
// keep documentation
'!lib/doc',
'!lib/doc/*',
'!lib/doc/**/*',
// keep cli
'!lib/cli.js',
// keep tests
'!lib/test',
'!lib/test/*',
'!lib/test/**/*',
]);
}

View File

@@ -15,27 +15,27 @@
import {OpenAPIV3} from 'openapi-types';
export const openapi3Template: OpenAPIV3.Document = {
openapi: '3.0.3',
info: {
title: 'Openstapps Backend',
description: `# Introduction
openapi: '3.0.3',
info: {
title: 'Openstapps Backend',
description: `# Introduction
This is a human readable documentation of the backend OpenAPI representation.`,
contact: {
name: 'Openstapps Team',
url: 'https://gitlab.com/openstapps/backend',
email: 'app@uni-frankfurt.de',
},
license: {
name: 'AGPL 3.0',
url: 'https://www.gnu.org/licenses/agpl-3.0.en.html',
},
version: '2.0.0',
contact: {
name: 'Openstapps Team',
url: 'https://gitlab.com/openstapps/backend',
email: 'app@uni-frankfurt.de',
},
servers: [
{
url: 'https://mobile.server.uni-frankfurt.de:3000',
description: 'Production server',
},
],
paths: {},
};
license: {
name: 'AGPL 3.0',
url: 'https://www.gnu.org/licenses/agpl-3.0.en.html',
},
version: '2.0.0',
},
servers: [
{
url: 'https://mobile.server.uni-frankfurt.de:3000',
description: 'Production server',
},
],
paths: {},
};

View File

@@ -13,13 +13,11 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {OpenAPIV3} from 'openapi-types';
import {isLightweightClass} from './easy-ast/ast-util.js';
import {LightweightProjectWithIndex} from './easy-ast/types/lightweight-project.js';
import {isLightweightClass, lightweightProjectFromPath, LightweightProjectWithIndex} from '@openstapps/easy-ast';
import {RouteInstanceWithMeta, RouteWithMetaInformation} from './types/routes.js';
import {rejectNil} from './util/collections.js';
import {capitalize} from './util/string.js';
import path from 'path';
import {lightweightProjectFromPath} from './easy-ast/easy-ast.js';
/**
* Gather relevant information of routes
@@ -33,38 +31,42 @@ export async function gatherRouteInformation(path: string): Promise<RouteWithMet
// find all classes that implement the SCAbstractRoute
return rejectNil(
await Promise.all(
Object.values(project.definitions).filter(isLightweightClass).map(async node => {
if (!node.extendedDefinitions?.some(it => it.referenceName === 'SCAbstractRoute')) {
return undefined;
}
Object.values(project.definitions)
.filter(isLightweightClass)
.map(async node => {
if (!node.extendedDefinitions?.some(it => it.referenceName === 'SCAbstractRoute')) {
return undefined;
}
const instantiatedRoute = (await project.instantiateDefinitionByName(
node.name,
)) as RouteInstanceWithMeta;
// instantiate all errors
instantiatedRoute.errors = await Promise.all(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
instantiatedRoute.errorNames.map(async (error: any) =>
// eslint-disable-next-line @typescript-eslint/ban-types
Object.assign((await project.instantiateDefinitionByName(error.name)) as object, {name: error.name}),
),
);
instantiatedRoute.responseBodyDescription =
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
project.definitions[instantiatedRoute.responseBodyName]?.comment?.shortSummary!;
instantiatedRoute.requestBodyDescription =
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
project.definitions[instantiatedRoute.requestBodyName]?.comment?.shortSummary!;
const instantiatedRoute = (await project.instantiateDefinitionByName(
node.name,
)) as RouteInstanceWithMeta;
// instantiate all errors
instantiatedRoute.errors = await Promise.all(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
instantiatedRoute.errorNames.map(async (error: any) =>
// eslint-disable-next-line @typescript-eslint/ban-types
Object.assign((await project.instantiateDefinitionByName(error.name)) as object, {
name: error.name,
}),
),
);
instantiatedRoute.responseBodyDescription =
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
project.definitions[instantiatedRoute.responseBodyName]?.comment?.shortSummary!;
instantiatedRoute.requestBodyDescription =
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
project.definitions[instantiatedRoute.requestBodyName]?.comment?.shortSummary!;
return {
description: {
shortText: node.comment?.shortSummary,
text: node.comment?.description,
},
name: node.name!,
route: instantiatedRoute,
};
}),
return {
description: {
shortText: node.comment?.shortSummary,
text: node.comment?.description,
},
name: node.name!,
route: instantiatedRoute,
};
}),
),
);
}

View File

@@ -19,8 +19,7 @@ import {createFormatter} from 'ts-json-schema-generator';
import {createParser} from 'ts-json-schema-generator';
import {createProgram} from 'ts-json-schema-generator';
import {getTsconfigPath} from './common.js';
import {definitionsOf} from './easy-ast/ast-util.js';
import {lightweightProjectFromPath} from './easy-ast/easy-ast.js';
import {definitionsOf, lightweightProjectFromPath} from '@openstapps/easy-ast';
import {isSchemaWithDefinitions} from './util/guards.js';
import path from 'path';
import re2 from './types/re2.js';
@@ -111,5 +110,5 @@ export class Converter {
export function getValidatableTypesInPath(path: string): string[] {
return Object.values(definitionsOf(lightweightProjectFromPath(path)))
.filter(type => !!type.comment?.tags?.find(it => it.name === 'validatable'))
.map(type => type.name)
.map(type => type.name);
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright (C) 2018-2021 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/>.
*/
/**
* A JavaScript module representation to sort a list of them by dependencies
*/
export interface JavaScriptModule {
/**
* Content of the module
*/
content: string;
/**
* List of names of dependencies
*/
dependencies: string[];
/**
* Directory the module is in
*/
directory: string;
/**
* The name of the module
*/
name: string;
}

View File

@@ -15,12 +15,15 @@
import {Logger} from '@openstapps/logger';
import {createWriteStream} from 'fs';
import * as request from 'got';
import {expandTypeValue, isLightweightClass} from '../easy-ast/ast-util.js';
import {LightweightAliasDefinition} from '../easy-ast/types/lightweight-alias-definition.js';
import {LightweightClassDefinition} from '../easy-ast/types/lightweight-class-definition.js';
import {LightweightDefinition} from '../easy-ast/types/lightweight-definition.js';
import {LightweightProperty} from '../easy-ast/types/lightweight-property.js';
import {LightweightType} from '../easy-ast/types/lightweight-type.js';
import {
expandTypeValue,
isLightweightClass,
LightweightAliasDefinition,
LightweightClassDefinition,
LightweightDefinition,
LightweightProperty,
LightweightType
} from '@openstapps/easy-ast';
import {UMLConfig} from './uml-config.js';
/**
@@ -59,7 +62,8 @@ export async function createDiagram(
isLightweightClass(definition)
? createPlantUMLCodeForClass(config, definition)
: createPlantUMLCodeForEnum(config, definition),
).join('');
)
.join('');
return createDiagramFromString(modelPlantUMLCode, plantUmlBaseURL, config.outputFileName);
}

View File

@@ -34,10 +34,10 @@ export function mapNotNil<T, S>(array: readonly T[], transform: (element: T) =>
export function cleanupEmpty<T extends object>(object: T): T {
const out = {} as T;
for (const key in object) {
const value = object[key]
const value = object[key];
// eslint-disable-next-line unicorn/no-null
if (value != null && (typeof value !== 'object' || Object.values(value).length > 0)) {
out[key] = value
out[key] = value;
}
}
return out;

View File

@@ -25,7 +25,7 @@ export function expandPathToFilesSync(sourcePath: string, accept: (fileName: str
return directory.isDirectory()
? readdirSync(fullPath).flatMap(fragment =>
expandPathToFilesSync(path.resolve(sourcePath, fragment), accept),
)
)
: [fullPath].filter(accept);
}

View File

@@ -18,9 +18,8 @@ import {existsSync, unlinkSync} from 'fs';
import {slow, suite, test, timeout} from '@testdeck/mocha';
import {createDiagram, createDiagramFromString} from '../src/uml/create-diagram.js';
import {UMLConfig} from '../src/uml/uml-config.js';
import {LightweightDefinition} from '../src/easy-ast/types/lightweight-definition.js';
import {LightweightDefinition, lightweightDefinitionsFromPath} from '@openstapps/easy-ast';
import nock = require('nock');
import {lightweightDefinitionsFromPath} from '../src/easy-ast/easy-ast.js';
import path from 'path';
@suite(timeout(15_000), slow(5000))

View File

@@ -1,36 +0,0 @@
/*
* Copyright (C) 2021 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 {expandPathToFilesSync, toUnixPath} from '../src/util/io.js';
import {EasyAstSpecType} from './easy-ast/easy-ast-spec-type.js';
import {lightweightProjectFromPath} from '../src/easy-ast/easy-ast.js';
import {expect} from 'chai';
import {omitBy} from 'lodash';
describe('Easy AST', async () => {
const project = lightweightProjectFromPath('./test/easy-ast', true);
for (const file of expandPathToFilesSync('./test/easy-ast', file => file.endsWith('ast-test.ts'))) {
try {
const test = (await import(file))['testConfig'] as EasyAstSpecType;
it(test.testName, () => {
expect(omitBy(project[toUnixPath(file)], (_value, key) => key.startsWith('$'))).to.be.deep.equal(
test.expected,
);
});
} catch (error) {
console.error(error);
}
}
});

View File

@@ -1,68 +0,0 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
type TestTypeAlias = number | string;
enum TestEnum {
Foo,
Bar,
}
export const testConfig: EasyAstSpecType = {
testName: `should resolve alias-likes`,
expected: {
TestTypeAlias: {
name: 'TestTypeAlias',
kind: LightweightDefinitionKind.ALIAS_LIKE,
modifiers: ['type'],
type: {
flags: 1_048_576,
specificationTypes: [
{
value: 'string',
flags: 4,
},
{
value: 'number',
flags: 8,
},
],
},
},
TestEnum: {
name: 'TestEnum',
kind: LightweightDefinitionKind.ALIAS_LIKE,
modifiers: ['enum'],
type: {
flags: 1_048_576,
specificationTypes: [
{
referenceName: 'Foo',
value: 0,
flags: 1280,
},
{
referenceName: 'Bar',
value: 1,
flags: 1280,
},
],
},
},
},
};

View File

@@ -1,75 +0,0 @@
/* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-interface */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
interface Random {}
type TestArrayGeneric = Array<string>;
type TestArrayLiteral = number[];
type TestArrayReferenceGeneric = Array<Random>;
type TestArrayReferenceLiteral = Random[];
export const testConfig: EasyAstSpecType = {
testName: `should resolve array-likes`,
expected: {
TestArrayGeneric: {
name: 'TestArrayGeneric',
kind: LightweightDefinitionKind.ALIAS_LIKE,
modifiers: ['type'],
type: {
value: 'string',
flags: 4,
isArray: true,
},
},
TestArrayLiteral: {
name: 'TestArrayLiteral',
kind: LightweightDefinitionKind.ALIAS_LIKE,
modifiers: ['type'],
type: {
value: 'number',
flags: 8,
isArray: true,
},
},
TestArrayReferenceGeneric: {
name: 'TestArrayReferenceGeneric',
kind: LightweightDefinitionKind.ALIAS_LIKE,
modifiers: ['type'],
type: {
referenceName: 'Random',
flags: 524_288,
isArray: true,
},
},
TestArrayReferenceLiteral: {
name: 'TestArrayReferenceLiteral',
kind: LightweightDefinitionKind.ALIAS_LIKE,
modifiers: ['type'],
type: {
referenceName: 'Random',
flags: 524_288,
isArray: true,
},
},
Random: {
name: 'Random',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
},
},
};

View File

@@ -1,59 +0,0 @@
/* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/no-inferrable-types */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
interface TestInterface {
foo: number;
}
class TestClass {
bar: string = 'test';
}
export const testConfig: EasyAstSpecType = {
testName: `should resolve class-likes`,
expected: {
TestInterface: {
name: 'TestInterface',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
properties: {
foo: {
name: 'foo',
type: {
value: 'number',
flags: 8,
},
},
},
},
TestClass: {
name: 'TestClass',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['class'],
properties: {
bar: {
name: 'bar',
type: {
value: 'string',
flags: 4,
},
},
},
},
},
};

View File

@@ -1,161 +0,0 @@
/* eslint-disable @typescript-eslint/no-unused-vars,jsdoc/check-tag-names */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
/**
* Class comment
*
* Class description
*
* More description
*
* @classTag classParameter1 classParameter2
*/
interface TestInterface {
/**
* Property comment
*
* Property description
*
* More description
*
* @propertyTag propertyParameter1 propertyParameter2
*/
foo: string;
}
/**
* Class comment
*
* Class description
*
* More description
*
* @classTag classParameter1 classParameter2
*/
class TestClass {
/**
* Property comment
*
* Property description
*
* More description
*
* @propertyTag propertyParameter1 propertyParameter2
*/
foo = 1;
}
/**
* Enum comment
*
* Enum description
*
* More description
*
* @enumTag enumParameter1
*/
enum TestAlias {}
export const testConfig: EasyAstSpecType = {
testName: `should resolve comments`,
expected: {
TestInterface: {
comment: {
shortSummary: 'Class comment',
description: 'Class description\n\nMore description',
tags: [
{
name: 'classTag',
parameters: ['classParameter1', 'classParameter2'],
},
],
},
name: 'TestInterface',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
properties: {
foo: {
comment: {
shortSummary: 'Property comment',
description: 'Property description\n\nMore description',
tags: [
{
name: 'propertyTag',
parameters: ['propertyParameter1', 'propertyParameter2'],
},
],
},
name: 'foo',
type: {
value: 'string',
flags: 4,
},
},
},
},
TestClass: {
comment: {
shortSummary: 'Class comment',
description: 'Class description\n\nMore description',
tags: [
{
name: 'classTag',
parameters: ['classParameter1', 'classParameter2'],
},
],
},
name: 'TestClass',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['class'],
properties: {
foo: {
comment: {
shortSummary: 'Property comment',
description: 'Property description\n\nMore description',
tags: [
{
name: 'propertyTag',
parameters: ['propertyParameter1', 'propertyParameter2'],
},
],
},
name: 'foo',
type: {
value: 'number',
flags: 8,
},
},
},
},
TestAlias: {
comment: {
shortSummary: 'Enum comment',
description: 'Enum description\n\nMore description',
tags: [
{
name: 'enumTag',
parameters: ['enumParameter1'],
},
],
},
name: 'TestAlias',
kind: LightweightDefinitionKind.ALIAS_LIKE,
modifiers: ['enum'],
},
},
};

View File

@@ -1,66 +0,0 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
interface Test1<T = number> {
foo: T;
}
interface Test2 {
bar: Test1;
}
export const testConfig: EasyAstSpecType = {
testName: `should resolve default generics`,
expected: {
Test1: {
name: 'Test1',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
typeParameters: ['T'],
properties: {
foo: {
name: 'foo',
type: {
referenceName: 'T',
flags: 262_144,
},
},
},
},
Test2: {
name: 'Test2',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
properties: {
bar: {
name: 'bar',
type: {
referenceName: 'Test1',
flags: 524_288,
genericsTypes: [
{
value: 'number',
flags: 8,
},
],
},
},
},
},
},
};

View File

@@ -1,20 +0,0 @@
/*
* Copyright (C) 2021 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 {LightweightFile} from '../../src/easy-ast/types/lightweight-project.js';
export interface EasyAstSpecType {
testName: string;
expected: LightweightFile;
}

View File

@@ -1,73 +0,0 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
enum TestAuto {
Foo,
Bar,
}
enum TestSpecified {
YES = 'yes',
NO = 'no',
}
export const testConfig: EasyAstSpecType = {
testName: `should resolve auto and specified enums`,
expected: {
TestAuto: {
name: 'TestAuto',
kind: LightweightDefinitionKind.ALIAS_LIKE,
modifiers: ['enum'],
type: {
flags: 1_048_576,
specificationTypes: [
{
referenceName: 'Foo',
value: 0,
flags: 1280,
},
{
referenceName: 'Bar',
value: 1,
flags: 1280,
},
],
},
},
TestSpecified: {
name: 'TestSpecified',
kind: LightweightDefinitionKind.ALIAS_LIKE,
modifiers: ['enum'],
type: {
flags: 1_048_576,
specificationTypes: [
{
referenceName: 'YES',
value: 'yes',
flags: 1152,
},
{
referenceName: 'NO',
value: 'no',
flags: 1152,
},
],
},
},
},
};

View File

@@ -1,80 +0,0 @@
/* eslint-disable @typescript-eslint/no-empty-interface,@typescript-eslint/no-unused-vars */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
interface $Random {}
interface Generics {
baz: Foo<number, $Random>;
}
interface Foo<T, S> {
foo: T;
bar: S;
}
export const testConfig: EasyAstSpecType = {
testName: `should resolve generics`,
expected: {
Generics: {
name: 'Generics',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
properties: {
baz: {
name: 'baz',
type: {
referenceName: 'Foo',
flags: 524_288,
genericsTypes: [
{
value: 'number',
flags: 8,
},
{
referenceName: '$Random',
flags: 524_288,
},
],
},
},
},
},
Foo: {
name: 'Foo',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
typeParameters: ['T', 'S'],
properties: {
foo: {
name: 'foo',
type: {
referenceName: 'T',
flags: 262_144,
},
},
bar: {
name: 'bar',
type: {
referenceName: 'S',
flags: 262_144,
},
},
},
},
},
};

View File

@@ -1,69 +0,0 @@
/* eslint-disable @typescript-eslint/no-empty-interface,@typescript-eslint/no-unused-vars */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
interface $Random {}
interface IndexSignatureObject {
[key: string]: $Random;
}
interface IndexSignaturePrimitive {
[key: string]: number;
}
export const testConfig: EasyAstSpecType = {
testName: `should resolve index signatures`,
expected: {
IndexSignatureObject: {
name: 'IndexSignatureObject',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
indexSignatures: {
key: {
name: 'key',
indexSignatureType: {
value: 'string',
flags: 4,
},
type: {
referenceName: '$Random',
flags: 524_288,
},
},
},
},
IndexSignaturePrimitive: {
name: 'IndexSignaturePrimitive',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
indexSignatures: {
key: {
name: 'key',
indexSignatureType: {
value: 'string',
flags: 4,
},
type: {
value: 'number',
flags: 8,
},
},
},
},
},
};

View File

@@ -1,82 +0,0 @@
/* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/no-inferrable-types */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
interface $BaseInterface<T> {
foo: T;
}
interface $BaseInterface2 {
bar: string;
}
class $BaseClass {}
class InheritingClass extends $BaseClass implements $BaseInterface<number>, $BaseInterface2 {
bar: string = '';
foo: number = 1;
}
export const testConfig: EasyAstSpecType = {
testName: `inheritance`,
expected: {
InheritingClass: {
name: 'InheritingClass',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['class'],
implementedDefinitions: [
{
referenceName: '$BaseInterface',
genericsTypes: [
{
value: 'number',
flags: 8,
},
],
flags: 524_288,
},
{
referenceName: '$BaseInterface2',
flags: 524_288,
},
],
extendedDefinitions: [
{
referenceName: '$BaseClass',
flags: 524_288,
},
],
properties: {
foo: {
name: 'foo',
type: {
value: 'number',
flags: 8,
},
},
bar: {
name: 'bar',
type: {
value: 'string',
flags: 4,
},
},
},
},
},
};

View File

@@ -1,61 +0,0 @@
/* eslint-disable @typescript-eslint/no-empty-interface,@typescript-eslint/no-unused-vars */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
interface NestedObject {
nested: {
deeplyNested: {
aNumber: number;
};
};
}
export const testConfig: EasyAstSpecType = {
testName: `should handle nested/type literals`,
expected: {
NestedObject: {
name: 'NestedObject',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
properties: {
nested: {
name: 'nested',
type: {
flags: 524_288,
},
properties: {
deeplyNested: {
name: 'deeplyNested',
type: {
flags: 524_288,
},
properties: {
aNumber: {
name: 'aNumber',
type: {
flags: 8,
value: 'number',
},
},
},
},
},
},
},
},
},
};

View File

@@ -1,99 +0,0 @@
/* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/no-explicit-any */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
interface Test {
number_type: number;
string_type: string;
boolean_type: boolean;
any_type: any;
unknown_type: unknown;
null_type: null;
undefined_type: undefined;
}
export const testConfig: EasyAstSpecType = {
testName: `should interpret primitive types correctly`,
expected: {
Test: {
name: 'Test',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
properties: {
number_type: {
name: 'number_type',
type: {
value: 'number',
flags: 8,
},
},
string_type: {
name: 'string_type',
type: {
value: 'string',
flags: 4,
},
},
boolean_type: {
name: 'boolean_type',
type: {
value: 'boolean',
flags: 1_048_592,
specificationTypes: [
{
value: 'false',
flags: 512,
},
{
value: 'true',
flags: 512,
},
],
},
},
any_type: {
name: 'any_type',
type: {
value: 'any',
flags: 1,
},
},
unknown_type: {
name: 'unknown_type',
type: {
value: 'unknown',
flags: 2,
},
},
null_type: {
name: 'null_type',
type: {
value: 'null',
flags: 65_536,
},
},
undefined_type: {
name: 'undefined_type',
type: {
value: 'undefined',
flags: 32_768,
},
},
},
},
},
};

View File

@@ -1,61 +0,0 @@
/* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/no-explicit-any */
/*
* Copyright (C) 2021 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 {EasyAstSpecType} from './easy-ast-spec-type.js';
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
interface Foo<T extends Bar<string>> {
bar: T;
}
interface Bar<T> {
foo: T;
}
export const testConfig: EasyAstSpecType = {
testName: `should ignore type constraints`,
expected: {
Foo: {
name: 'Foo',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
typeParameters: ['T'],
properties: {
bar: {
name: 'bar',
type: {
referenceName: 'T',
flags: 262_144,
},
},
},
},
Bar: {
name: 'Bar',
kind: LightweightDefinitionKind.CLASS_LIKE,
modifiers: ['interface'],
typeParameters: ['T'],
properties: {
foo: {
name: 'foo',
type: {
referenceName: 'T',
flags: 262_144,
},
},
},
},
},
};

View File

@@ -1,5 +1,5 @@
{
"extends": "./node_modules/@openstapps/configuration/tsconfig.json",
"extends": "@openstapps/tsconfig",
"compilerOptions": {
"noUnusedLocals": false,
"stripInternal": true