ing
This commit is contained in:
commit
06967e23c9
45
.gitignore
vendored
Normal file
45
.gitignore
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/dist-server
|
||||
/tmp
|
||||
/out-tsc
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# e2e
|
||||
/e2e/*.js
|
||||
/e2e/*.map
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
yarn.lock
|
3
.npmignore
Normal file
3
.npmignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
tsconfig.json
|
||||
tslint.json
|
||||
src
|
489
package-lock.json
generated
Normal file
489
package-lock.json
generated
Normal file
|
@ -0,0 +1,489 @@
|
|||
{
|
||||
"name": "@loafer/core",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "8.0.58",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/node/-/node-8.0.58.tgz",
|
||||
"integrity": "sha512-V746iUU7eHNdzQipoACuguDlVhC7IHK8CES1jSkuFt352wwA84BCWPXaGekBd7R5XdNK5ReHONDVKxlL9IreAw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/strip-bom": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/strip-bom/-/strip-bom-3.0.0.tgz",
|
||||
"integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=",
|
||||
"dev": true
|
||||
},
|
||||
"@types/strip-json-comments": {
|
||||
"version": "0.0.30",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz",
|
||||
"integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "1.9.1"
|
||||
}
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"sprintf-js": "1.0.3"
|
||||
}
|
||||
},
|
||||
"arrify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/arrify/-/arrify-1.0.1.tgz",
|
||||
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
||||
"dev": true
|
||||
},
|
||||
"babel-code-frame": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "1.1.3",
|
||||
"esutils": "2.0.2",
|
||||
"js-tokens": "3.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "2.2.1",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"has-ansi": "2.0.0",
|
||||
"strip-ansi": "3.0.1",
|
||||
"supports-color": "2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/buffer-from/-/buffer-from-1.0.0.tgz",
|
||||
"integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==",
|
||||
"dev": true
|
||||
},
|
||||
"builtin-modules": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/builtin-modules/-/builtin-modules-1.1.1.tgz",
|
||||
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/chalk/-/chalk-2.4.1.tgz",
|
||||
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "3.2.1",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"supports-color": "5.4.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/color-convert/-/color-convert-1.9.1.tgz",
|
||||
"integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.15.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/commander/-/commander-2.15.1.tgz",
|
||||
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/diff/-/diff-3.5.0.tgz",
|
||||
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
|
||||
"dev": true
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/esprima/-/esprima-4.0.0.tgz",
|
||||
"integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
|
||||
"dev": true
|
||||
},
|
||||
"esutils": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/esutils/-/esutils-2.0.2.tgz",
|
||||
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
|
||||
"dev": true
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "1.0.0",
|
||||
"inflight": "1.0.6",
|
||||
"inherits": "2.0.3",
|
||||
"minimatch": "3.0.4",
|
||||
"once": "1.4.0",
|
||||
"path-is-absolute": "1.0.1"
|
||||
}
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "2.1.1"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
},
|
||||
"homedir-polyfill": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
|
||||
"integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"parse-passwd": "1.0.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "1.4.0",
|
||||
"wrappy": "1.0.2"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"dev": true
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/js-tokens/-/js-tokens-3.0.2.tgz",
|
||||
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
|
||||
"dev": true
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.11.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/js-yaml/-/js-yaml-3.11.0.tgz",
|
||||
"integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "1.0.10",
|
||||
"esprima": "4.0.0"
|
||||
}
|
||||
},
|
||||
"make-error": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/make-error/-/make-error-1.3.4.tgz",
|
||||
"integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==",
|
||||
"dev": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "1.1.11"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1.0.2"
|
||||
}
|
||||
},
|
||||
"parse-passwd": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/parse-passwd/-/parse-passwd-1.0.0.tgz",
|
||||
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
|
||||
"dev": true
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/path-parse/-/path-parse-1.0.5.tgz",
|
||||
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
|
||||
"dev": true
|
||||
},
|
||||
"reflect-metadata": {
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/reflect-metadata/-/reflect-metadata-0.1.12.tgz",
|
||||
"integrity": "sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A=="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/resolve/-/resolve-1.7.1.tgz",
|
||||
"integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-parse": "1.0.5"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/semver/-/semver-5.5.0.tgz",
|
||||
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/source-map-support/-/source-map-support-0.5.6.tgz",
|
||||
"integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-from": "1.0.0",
|
||||
"source-map": "0.6.1"
|
||||
}
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "2.1.1"
|
||||
}
|
||||
},
|
||||
"strip-bom": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/strip-bom/-/strip-bom-3.0.0.tgz",
|
||||
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
||||
"dev": true
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/supports-color/-/supports-color-5.4.0.tgz",
|
||||
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "3.0.0"
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/ts-node/-/ts-node-4.0.2.tgz",
|
||||
"integrity": "sha512-mg7l6ON8asjnfzkTi1LFWKaOGHl5Jf1+5ij0MQ502YfC6+4FBgh/idJgw9aN9kei1Rf4/pmFpNuFE1YbcQdOTA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arrify": "1.0.1",
|
||||
"chalk": "2.4.1",
|
||||
"diff": "3.5.0",
|
||||
"make-error": "1.3.4",
|
||||
"minimist": "1.2.0",
|
||||
"mkdirp": "0.5.1",
|
||||
"source-map-support": "0.5.6",
|
||||
"tsconfig": "7.0.0",
|
||||
"v8flags": "3.1.0",
|
||||
"yn": "2.0.0"
|
||||
}
|
||||
},
|
||||
"tsconfig": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/tsconfig/-/tsconfig-7.0.0.tgz",
|
||||
"integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/strip-bom": "3.0.0",
|
||||
"@types/strip-json-comments": "0.0.30",
|
||||
"strip-bom": "3.0.0",
|
||||
"strip-json-comments": "2.0.1"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/tslib/-/tslib-1.9.0.tgz",
|
||||
"integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==",
|
||||
"dev": true
|
||||
},
|
||||
"tslint": {
|
||||
"version": "5.9.1",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/tslint/-/tslint-5.9.1.tgz",
|
||||
"integrity": "sha1-ElX4ej/1frCw4fDmEKi0dIBGya4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-code-frame": "6.26.0",
|
||||
"builtin-modules": "1.1.1",
|
||||
"chalk": "2.4.1",
|
||||
"commander": "2.15.1",
|
||||
"diff": "3.5.0",
|
||||
"glob": "7.1.2",
|
||||
"js-yaml": "3.11.0",
|
||||
"minimatch": "3.0.4",
|
||||
"resolve": "1.7.1",
|
||||
"semver": "5.5.0",
|
||||
"tslib": "1.9.0",
|
||||
"tsutils": "2.27.0"
|
||||
}
|
||||
},
|
||||
"tsutils": {
|
||||
"version": "2.27.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/tsutils/-/tsutils-2.27.0.tgz",
|
||||
"integrity": "sha512-JcyX25oM9pFcb3zh60OqG1St8p/uSqC5Bgipdo3ieacB/Ao4dPhm7hAtKT9NrEu23CyYrrgJPV3CqYfo+/+T4w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "1.9.0"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/typescript/-/typescript-2.5.3.tgz",
|
||||
"integrity": "sha512-ptLSQs2S4QuS6/OD1eAKG+S5G8QQtrU5RT32JULdZQtM1L3WTi34Wsu48Yndzi8xsObRAB9RPt/KhA9wlpEF6w==",
|
||||
"dev": true
|
||||
},
|
||||
"v8flags": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/v8flags/-/v8flags-3.1.0.tgz",
|
||||
"integrity": "sha512-0m69VIK2dudEf2Ub0xwLQhZkDZu85OmiOpTw+UGDt56ibviYICHziM/3aE+oVg7IjGPp0c83w3eSVqa+lYZ9UQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"homedir-polyfill": "1.0.1"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
},
|
||||
"yn": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://nexus.loafle.net/repository/npm-all/yn/-/yn-2.0.0.tgz",
|
||||
"integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
30
package.json
Normal file
30
package.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "@loafer/core",
|
||||
"description": "Core module of loafer",
|
||||
"version": "0.0.3",
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.loafle.net/loafer/typescript/core.git"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://nexus.loafle.net/repository/npm-loafle/"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Loafle <loafer@loafle.com>",
|
||||
"scripts": {
|
||||
"compile": "npm run clean && tsc -p .",
|
||||
"watch": "tsc -w -p .",
|
||||
"clean": "rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"reflect-metadata": "^0.1.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "~8.0.0",
|
||||
"ts-node": "~4.0.1",
|
||||
"tslint": "~5.9.1",
|
||||
"typescript": "~2.5.3"
|
||||
}
|
||||
}
|
6
src/error.ts
Normal file
6
src/error.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export class IllegalArgumentError extends Error {
|
||||
public constructor(message?: string) {
|
||||
super(message);
|
||||
Object.setPrototypeOf(this, new.target.prototype);
|
||||
}
|
||||
}
|
2
src/index.ts
Normal file
2
src/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from './error';
|
||||
export * from './type';
|
64
src/reflect/AccessibleObject.ts
Normal file
64
src/reflect/AccessibleObject.ts
Normal file
|
@ -0,0 +1,64 @@
|
|||
import {
|
||||
Type,
|
||||
} from '../type';
|
||||
|
||||
import {
|
||||
TypeUtil,
|
||||
} from '../util/TypeUtil';
|
||||
|
||||
import { AnnotatedElement } from './AnnotatedElement';
|
||||
import { Annotation } from './Annotation';
|
||||
|
||||
export abstract class AccessibleObject implements AnnotatedElement {
|
||||
private _annotations: Map<Type<any>, Annotation>;
|
||||
|
||||
protected constructor() {
|
||||
this._annotations = new Map();
|
||||
}
|
||||
|
||||
public _addAnnotation<AnnotationType extends Annotation>(annotation: AnnotationType): void {
|
||||
this._annotations.set(TypeUtil.getType(annotation), annotation);
|
||||
}
|
||||
|
||||
public isAnnotationPresent<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>): boolean {
|
||||
return null !== this.getAnnotation(annotationClass);
|
||||
}
|
||||
|
||||
public getOwnAnnotation<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>): AnnotationType | undefined {
|
||||
return <AnnotationType>this._annotations.get(annotationClass);
|
||||
}
|
||||
|
||||
public getOwnAnnotations(): Map<Type<any>, Annotation> {
|
||||
return this._annotations;
|
||||
}
|
||||
|
||||
public getOwnAnnotationsByType<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>)
|
||||
: AnnotationType[] | undefined {
|
||||
if (0 === this._annotations.size) {
|
||||
return undefined;
|
||||
}
|
||||
const results: AnnotationType[] = [];
|
||||
for (const classType of Array.from(this._annotations.keys())) {
|
||||
if (classType === annotationClass) {
|
||||
results.push(<AnnotationType>this._annotations.get(classType));
|
||||
}
|
||||
}
|
||||
if (0 === results.length) {
|
||||
return undefined;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public getAnnotation<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>): AnnotationType | undefined {
|
||||
return this.getOwnAnnotation(annotationClass);
|
||||
}
|
||||
|
||||
public getAnnotations(): Map<Type<any>, Annotation> {
|
||||
return this.getOwnAnnotations();
|
||||
}
|
||||
|
||||
public getAnnotationsByType<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>)
|
||||
: AnnotationType[] | undefined {
|
||||
return this.getOwnAnnotationsByType(annotationClass);
|
||||
}
|
||||
}
|
17
src/reflect/AnnotatedElement.ts
Normal file
17
src/reflect/AnnotatedElement.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import {
|
||||
Type,
|
||||
} from '../type';
|
||||
|
||||
import { Annotation } from './Annotation';
|
||||
|
||||
export interface AnnotatedElement {
|
||||
_addAnnotation<AnnotationType extends Annotation>(annotation: AnnotationType): void;
|
||||
|
||||
isAnnotationPresent<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>): boolean;
|
||||
getOwnAnnotation<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>): AnnotationType | undefined;
|
||||
getOwnAnnotations(): Map<Type<any>, Annotation>;
|
||||
getOwnAnnotationsByType<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>): AnnotationType[] | undefined;
|
||||
getAnnotation<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>): AnnotationType | undefined;
|
||||
getAnnotations(): Map<Type<any>, Annotation>;
|
||||
getAnnotationsByType<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>): AnnotationType[] | undefined;
|
||||
}
|
7
src/reflect/Annotation.ts
Normal file
7
src/reflect/Annotation.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export abstract class Annotation<Attribute = {}> {
|
||||
public readonly attribute: Attribute;
|
||||
|
||||
public constructor(attribute?: Attribute) {
|
||||
this.attribute = attribute;
|
||||
}
|
||||
}
|
228
src/reflect/Class.ts
Normal file
228
src/reflect/Class.ts
Normal file
|
@ -0,0 +1,228 @@
|
|||
import {
|
||||
Type,
|
||||
PropertyKeyType,
|
||||
} from '../type';
|
||||
|
||||
import {
|
||||
TypeUtil,
|
||||
} from '../util/TypeUtil';
|
||||
|
||||
import { AccessibleObject } from './AccessibleObject';
|
||||
import { Annotation } from './Annotation';
|
||||
import { SystemClassRegistry } from './ClassRegistry';
|
||||
import { Constructor } from './Constructor';
|
||||
import { Field } from './Field';
|
||||
import { Method } from './Method';
|
||||
import { Metadata } from './Metadata';
|
||||
|
||||
|
||||
|
||||
export class Class extends AccessibleObject {
|
||||
private _type: Type<any>;
|
||||
private _constructor: Constructor;
|
||||
private _fields: Map<PropertyKeyType, Field>;
|
||||
private _methods: Map<PropertyKeyType, Method>;
|
||||
|
||||
/**
|
||||
* forClass
|
||||
*/
|
||||
public static forType(type: Type<any>): Class | undefined {
|
||||
return SystemClassRegistry.get(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* _defineClass
|
||||
*/
|
||||
public static _defineClass(type: Type<any>): Class {
|
||||
let clazz: Class = Class.forType(type);
|
||||
if (undefined === clazz) {
|
||||
clazz = new Class(type);
|
||||
SystemClassRegistry.set(type, clazz);
|
||||
}
|
||||
|
||||
if (null === clazz._constructor) {
|
||||
const parameterTypes = Metadata.getOwnParamTypes(type);
|
||||
if (undefined !== parameterTypes) {
|
||||
clazz._constructor = new Constructor(clazz, parameterTypes);
|
||||
}
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
private constructor(type: Type<any>) {
|
||||
super();
|
||||
this._type = type;
|
||||
this._fields = new Map();
|
||||
this._methods = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
* _defineField
|
||||
*/
|
||||
public _defineConstructor(parameterTypes: any[]): Constructor {
|
||||
let cons: Constructor = this._constructor;
|
||||
if (undefined === cons) {
|
||||
cons = new Constructor(this, parameterTypes);
|
||||
this._constructor = cons;
|
||||
}
|
||||
return cons;
|
||||
}
|
||||
|
||||
/**
|
||||
* _defineField
|
||||
*/
|
||||
public _defineField(propertyKey: PropertyKeyType, propertyType: any): Field {
|
||||
let field: Field = this._fields.get(propertyKey);
|
||||
if (undefined === field) {
|
||||
field = new Field(this, propertyKey, propertyType);
|
||||
this._fields.set(propertyKey, field);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* _defineMethod
|
||||
*/
|
||||
public _defineMethod(propertyKey: PropertyKeyType, parameterTypes: any[], returnType: any): Method {
|
||||
let method: Method = this._methods.get(propertyKey);
|
||||
if (undefined === method) {
|
||||
method = new Method(this, propertyKey, parameterTypes, returnType);
|
||||
this._methods.set(propertyKey, method);
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
public getType(): Type<any> {
|
||||
return this._type;
|
||||
}
|
||||
|
||||
public getConstructor(): Constructor {
|
||||
if (undefined === this._constructor) {
|
||||
this._constructor = new Constructor(this, undefined);
|
||||
}
|
||||
return this._constructor;
|
||||
}
|
||||
|
||||
public getOwnField(propertyKey: PropertyKeyType): Field | undefined {
|
||||
return this._fields.get(propertyKey);
|
||||
}
|
||||
|
||||
public getOwnFields(): Map<PropertyKeyType, Field> {
|
||||
return this._fields;
|
||||
}
|
||||
|
||||
public getField(propertyKey: PropertyKeyType): Field | undefined {
|
||||
const fields = this.getFields();
|
||||
|
||||
return fields.get(propertyKey);
|
||||
}
|
||||
|
||||
public getFields(): Map<PropertyKeyType, Field> {
|
||||
const fields: Map<PropertyKeyType, Field> = new Map();
|
||||
|
||||
const types = TypeUtil.ancestorsOf(this._type);
|
||||
if (null === types || 0 === types.length) {
|
||||
return fields;
|
||||
}
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
const tType = types[i];
|
||||
const tClazz = Class.forType(tType);
|
||||
if (undefined === tClazz) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tClazz.getOwnFields().forEach((value: Field, key: PropertyKeyType): void => {
|
||||
fields.set(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
public getOwnMethod(propertyKey: PropertyKeyType): Method | undefined {
|
||||
return this._methods.get(propertyKey);
|
||||
}
|
||||
|
||||
public getOwnMethods(): Map<PropertyKeyType, Method> {
|
||||
return this._methods;
|
||||
}
|
||||
|
||||
public getMethod(propertyKey: PropertyKeyType): Method | undefined {
|
||||
const methods = this.getMethods();
|
||||
|
||||
return methods.get(propertyKey);
|
||||
}
|
||||
|
||||
public getMethods(): Map<PropertyKeyType, Method> {
|
||||
const methods: Map<PropertyKeyType, Method> = new Map();
|
||||
|
||||
const types = TypeUtil.ancestorsOf(this._type);
|
||||
if (null === types || 0 === types.length) {
|
||||
return methods;
|
||||
}
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
const tClazzType = types[i];
|
||||
const tClazz = Class.forType(tClazzType);
|
||||
if (undefined === tClazz) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tClazz.getOwnMethods().forEach((value: Method, key: PropertyKeyType): void => {
|
||||
methods.set(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
public getAnnotation<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>): AnnotationType | undefined {
|
||||
const annotations = this.getAnnotations();
|
||||
|
||||
return <AnnotationType>annotations.get(annotationClass);
|
||||
}
|
||||
|
||||
public getAnnotations(): Map<Type<any>, Annotation> {
|
||||
const annotations: Map<Type<any>, Annotation> = new Map();
|
||||
|
||||
const types = TypeUtil.ancestorsOf(this._type);
|
||||
if (null === types || 0 === types.length) {
|
||||
return annotations;
|
||||
}
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
const tClazzType = types[i];
|
||||
const tClazz = Class.forType(tClazzType);
|
||||
if (undefined === tClazz) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tClazz.getOwnAnnotations().forEach((value: Annotation, key: Type<any>): void => {
|
||||
annotations.set(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
return annotations;
|
||||
}
|
||||
|
||||
public getAnnotationsByType<AnnotationType extends Annotation>(annotationClass: Type<AnnotationType>)
|
||||
: AnnotationType[] | undefined {
|
||||
const annotations = this.getAnnotations();
|
||||
if (0 === annotations.size) {
|
||||
return undefined;
|
||||
}
|
||||
const results: AnnotationType[] = [];
|
||||
for (const classType of Array.from(annotations.keys())) {
|
||||
if (classType === annotationClass) {
|
||||
results.push(<AnnotationType>annotations.get(classType));
|
||||
}
|
||||
}
|
||||
if (0 === results.length) {
|
||||
return undefined;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public getName(): string {
|
||||
return this._type.name;
|
||||
}
|
||||
}
|
12
src/reflect/ClassRegistry.ts
Normal file
12
src/reflect/ClassRegistry.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { Type } from '../type';
|
||||
import { Registry } from '../util/Registry';
|
||||
|
||||
import { Class } from './Class';
|
||||
|
||||
export class ClassRegistry extends Registry<Type<any>, Class> {
|
||||
public constructor(parent?: ClassRegistry) {
|
||||
super(parent);
|
||||
}
|
||||
}
|
||||
|
||||
export const SystemClassRegistry = new ClassRegistry();
|
22
src/reflect/Constructor.ts
Normal file
22
src/reflect/Constructor.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import {
|
||||
TypeUtil,
|
||||
} from '../util/TypeUtil';
|
||||
|
||||
import { Class } from './Class';
|
||||
import { Executable } from './Executable';
|
||||
|
||||
export class Constructor extends Executable {
|
||||
private _rawConstructor: Function;
|
||||
|
||||
public constructor(declaringClazz: Class, parameterTypes?: any[]) {
|
||||
super(declaringClazz, CONSTRUCTOR_NAME, parameterTypes);
|
||||
this._rawConstructor = TypeUtil.getPrototype(declaringClazz.getType())[CONSTRUCTOR_NAME];
|
||||
}
|
||||
|
||||
public newInstance(...args: any[]): any {
|
||||
const ctor = this.getDeclaringClass().getType();
|
||||
return new (ctor.bind.apply(ctor, [null].concat(args)))();
|
||||
}
|
||||
}
|
||||
|
||||
const CONSTRUCTOR_NAME = 'constructor';
|
75
src/reflect/Executable.ts
Normal file
75
src/reflect/Executable.ts
Normal file
|
@ -0,0 +1,75 @@
|
|||
import {
|
||||
PropertyKeyType,
|
||||
} from '../type';
|
||||
|
||||
import {
|
||||
TypeUtil,
|
||||
} from '../util/TypeUtil';
|
||||
|
||||
import { AccessibleObject } from './AccessibleObject';
|
||||
import { Class } from './Class';
|
||||
import { Member } from './Member';
|
||||
import { Parameter } from './Parameter';
|
||||
|
||||
export abstract class Executable extends AccessibleObject implements Member {
|
||||
private _clazz: Class;
|
||||
private _name: PropertyKeyType;
|
||||
private _parameters: Parameter[];
|
||||
|
||||
protected constructor(declaringClazz: Class, name: PropertyKeyType, parameterTypes?: any[]) {
|
||||
super();
|
||||
|
||||
this._clazz = declaringClazz;
|
||||
this._name = name;
|
||||
|
||||
if (undefined === parameterTypes) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parameterNames = TypeUtil.getParameterNames(declaringClazz.getType(), name);
|
||||
this._parameters = [];
|
||||
|
||||
for (let i = 0; i < parameterTypes.length; i++) {
|
||||
const parameterType = parameterTypes[i];
|
||||
const parameterName = parameterNames[i];
|
||||
const parameter: Parameter = new Parameter(this, parameterType, parameterName, i);
|
||||
this._parameters.push(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
public getDeclaringClass(): Class {
|
||||
return this._clazz;
|
||||
}
|
||||
|
||||
public getName(): PropertyKeyType {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
/**
|
||||
* getParameterCount
|
||||
*/
|
||||
public getParameterCount(): number {
|
||||
if (null === this._parameters) {
|
||||
return 0;
|
||||
}
|
||||
return this._parameters.length;
|
||||
}
|
||||
/**
|
||||
* getParameters
|
||||
*/
|
||||
public getParameters(): Parameter[] | undefined {
|
||||
return this._parameters;
|
||||
}
|
||||
/**
|
||||
* getParameter
|
||||
*/
|
||||
public getParameter(index: number): Parameter | undefined {
|
||||
if (null === this._parameters) {
|
||||
return undefined;
|
||||
}
|
||||
if (0 > index || this._parameters.length <= index) {
|
||||
return undefined;
|
||||
}
|
||||
return this._parameters[index];
|
||||
}
|
||||
}
|
33
src/reflect/Field.ts
Normal file
33
src/reflect/Field.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import {
|
||||
PropertyKeyType,
|
||||
} from '../type';
|
||||
|
||||
import { AccessibleObject } from './AccessibleObject';
|
||||
import { Class } from './Class';
|
||||
import { Member } from './Member';
|
||||
|
||||
export class Field extends AccessibleObject implements Member {
|
||||
private _clazz: Class;
|
||||
private _name: PropertyKeyType;
|
||||
private _type: any;
|
||||
|
||||
public constructor(declaringClazz: Class, name: PropertyKeyType, fieldType: any) {
|
||||
super();
|
||||
this._clazz = declaringClazz;
|
||||
this._name = name;
|
||||
this._type = fieldType;
|
||||
}
|
||||
|
||||
public getDeclaringClass(): Class {
|
||||
return this._clazz;
|
||||
}
|
||||
|
||||
public getName(): PropertyKeyType {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public getType(): any {
|
||||
return this._type;
|
||||
}
|
||||
|
||||
}
|
10
src/reflect/Member.ts
Normal file
10
src/reflect/Member.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import {
|
||||
PropertyKeyType,
|
||||
} from '../type';
|
||||
|
||||
import { Class } from './Class';
|
||||
|
||||
export interface Member {
|
||||
getDeclaringClass(): Class;
|
||||
getName(): PropertyKeyType;
|
||||
}
|
521
src/reflect/Metadata.ts
Normal file
521
src/reflect/Metadata.ts
Normal file
|
@ -0,0 +1,521 @@
|
|||
import {
|
||||
MetadataKeyType,
|
||||
PropertyKeyType,
|
||||
} from '../type';
|
||||
|
||||
import { TypeUtil } from '../util/TypeUtil';
|
||||
|
||||
|
||||
export class Metadata {
|
||||
/**
|
||||
* Gets the metadata value for the provided metadata key on the target object or its prototype chain.
|
||||
* @param key A key used to store and retrieve metadata.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @returns The metadata value for the metadata key if found; otherwise, `undefined`.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // constructor
|
||||
* result = Metadata.get("custom:annotation", Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.get("custom:annotation", Example, "staticProperty");
|
||||
*
|
||||
* // property (on prototype)
|
||||
* result = Metadata.get("custom:annotation", Example.prototype, "property");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.get("custom:annotation", Example, "staticMethod");
|
||||
*
|
||||
* // method (on prototype)
|
||||
* result = Metadata.get("custom:annotation", Example.prototype, "method");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static get(key: MetadataKeyType, target: any, propertyKey?: PropertyKeyType): any {
|
||||
return Reflect.getMetadata(key, TypeUtil.getType(target), propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata value for the provided metadata key on the target object or its prototype chain.
|
||||
* @param key A key used to store and retrieve metadata.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @returns The metadata value for the metadata key if found; otherwise, `undefined`.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // constructor
|
||||
* result = Metadata.getOwn("custom:annotation", Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.getOwn("custom:annotation", Example, "staticProperty");
|
||||
*
|
||||
* // property (on prototype)
|
||||
* result = Metadata.getOwn("custom:annotation", Example.prototype, "property");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.getOwn("custom:annotation", Example, "staticMethod");
|
||||
*
|
||||
* // method (on prototype)
|
||||
* result = Metadata.getOwn("custom:annotation", Example.prototype, "method");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static getOwn(key: MetadataKeyType, target: any, propertyKey?: PropertyKeyType): any {
|
||||
return Reflect.getOwnMetadata(key, TypeUtil.getType(target), propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata value for the provided metadata DESIGN_TYPE on the target object or its prototype chain.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @returns The metadata value for the metadata key if found; otherwise, `undefined`.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // on contructor
|
||||
* result = Metadata.getType(Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.getType(Example, "staticProperty");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.getType(Example, "staticMethod");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static getType(target: any, propertyKey?: PropertyKeyType): any {
|
||||
return Reflect.getMetadata(DESIGN_TYPE, target, propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata value for the provided metadata DESIGN_TYPE on the target object or its prototype chain.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @returns The metadata value for the metadata key if found; otherwise, `undefined`.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // on contructor
|
||||
* result = Metadata.getOwnType(Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.getOwnType(Example, "staticProperty");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.getOwnType(Example, "staticMethod");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static getOwnType(target: any, propertyKey?: PropertyKeyType): any {
|
||||
return Reflect.getMetadata(DESIGN_TYPE, target, propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata value for the provided metadata DESIGN_RETURN_TYPE on the target object or its prototype chain.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @returns The metadata value for the metadata key if found; otherwise, `undefined`.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // on contructor
|
||||
* result = Metadata.getReturnType(Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.getReturnType(Example, "staticProperty");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.getReturnType(Example, "staticMethod");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static getReturnType(target: any, propertyKey?: PropertyKeyType): any {
|
||||
return Reflect.getMetadata(DESIGN_RETURN_TYPE, target, propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata value for the provided metadata DESIGN_RETURN_TYPE on the target object or its prototype chain.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @returns The metadata value for the metadata key if found; otherwise, `undefined`.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // on contructor
|
||||
* result = Metadata.getOwnReturnType(Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.getOwnReturnType(Example, "staticProperty");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.getOwnReturnType(Example, "staticMethod");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static getOwnReturnType(target: any, propertyKey?: PropertyKeyType): any {
|
||||
return Reflect.getOwnMetadata(DESIGN_RETURN_TYPE, target, propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether the target object or its prototype chain has the provided metadata key defined.
|
||||
* @param key A key used to store and retrieve metadata.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @returns `true` if the metadata key was defined on the target object or its prototype chain; otherwise, `false`.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // constructor
|
||||
* result = Metadata.has("custom:annotation", Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.has("custom:annotation", Example, "staticProperty");
|
||||
*
|
||||
* // property (on prototype)
|
||||
* result = Metadata.has("custom:annotation", Example.prototype, "property");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.has("custom:annotation", Example, "staticMethod");
|
||||
*
|
||||
* // method (on prototype)
|
||||
* result = Metadata.has("custom:annotation", Example.prototype, "method");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static has(key: MetadataKeyType, target: any, propertyKey?: PropertyKeyType): boolean {
|
||||
return Reflect.hasMetadata(key, TypeUtil.getType(target), propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether the target object or its prototype chain has the provided metadata key defined.
|
||||
* @param key A key used to store and retrieve metadata.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @returns `true` if the metadata key was defined on the target object or its prototype chain; otherwise, `false`.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // constructor
|
||||
* result = Metadata.has("custom:annotation", Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.hasOwn("custom:annotation", Example, "staticProperty");
|
||||
*
|
||||
* // property (on prototype)
|
||||
* result = Metadata.hasOwn("custom:annotation", Example.prototype, "property");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.hasOwn("custom:annotation", Example, "staticMethod");
|
||||
*
|
||||
* // method (on prototype)
|
||||
* result = Metadata.hasOwn("custom:annotation", Example.prototype, "method");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static hasOwn(key: MetadataKeyType, target: any, propertyKey?: PropertyKeyType): boolean {
|
||||
return Reflect.hasOwnMetadata(key, TypeUtil.getType(target), propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the metadata entry from the target object with the provided key.
|
||||
* @param key A key used to store and retrieve metadata.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @returns `true` if the metadata entry was found and deleted; otherwise, false.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // constructor
|
||||
* result = Metadata.delete("custom:annotation", Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.delete("custom:annotation", Example, "staticProperty");
|
||||
*
|
||||
* // property (on prototype)
|
||||
* result = Metadata.delete("custom:annotation", Example.prototype, "property");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.delete("custom:annotation", Example, "staticMethod");
|
||||
*
|
||||
* // method (on prototype)
|
||||
* result = Metadata.delete("custom:annotation", Example.prototype, "method");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static delete(key: MetadataKeyType, target: any, propertyKey?: PropertyKeyType): boolean {
|
||||
return Reflect.deleteMetadata(key, TypeUtil.getType(target), propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the metadata value for the provided metadata DESIGN_PARAM_TYPES on the target object or its prototype chain.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @param value A value that contains attached metadata.
|
||||
* @returns The metadata value for the metadata key if found; otherwise, `undefined`.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // on contructor
|
||||
* result = Metadata.setParamTypes(Example, undefined, [Object]);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.setParamTypes(Example, "staticProperty", [Object]);
|
||||
*
|
||||
* // property (on prototype)
|
||||
* result = Metadata.setParamTypes(Example.prototype, "property", [Object]);
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.setParamTypes(Example, "staticMethod", [Object]);
|
||||
*
|
||||
* // method (on prototype)
|
||||
* result = Metadata.setParamTypes(Example.prototype, "method", [Object]);
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static setParamTypes(target: any, propertyKey: PropertyKeyType, value: any): void {
|
||||
return this.set(DESIGN_PARAM_TYPES, value, target.prototype, propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all metadata for a metadataKey.
|
||||
* @param metadataKey
|
||||
*/
|
||||
public static getTargetsFromPropertyKey = (metadataKey: MetadataKeyType): any[] =>
|
||||
PROPERTIES.has(metadataKey) ? PROPERTIES.get(metadataKey) || [] : []
|
||||
|
||||
/**
|
||||
* Define a unique metadata entry on the target.
|
||||
* @param key A key used to store and retrieve metadata.
|
||||
* @param value A value that contains attached metadata.
|
||||
* @param target The target object on which to define metadata.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // constructor
|
||||
* Reflect.defineMetadata("custom:annotation", options, Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* Reflect.defineMetadata("custom:annotation", Number, Example, "staticProperty");
|
||||
*
|
||||
* // property (on prototype)
|
||||
* Reflect.defineMetadata("custom:annotation", Number, Example.prototype, "property");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* Reflect.defineMetadata("custom:annotation", Number, Example, "staticMethod");
|
||||
*
|
||||
* // method (on prototype)
|
||||
* Reflect.defineMetadata("custom:annotation", Number, Example.prototype, "method");
|
||||
*
|
||||
* // decorator factory as metadata-producing annotation.
|
||||
* function MyAnnotation(options): PropertyDecorator {
|
||||
* return (target, key) => Reflect.defineMetadata("custom:annotation", options, target, key);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static set(key: MetadataKeyType, value: any, target: any, propertyKey?: PropertyKeyType): void {
|
||||
|
||||
const targets: any[] = PROPERTIES.has(key) ? PROPERTIES.get(key) || [] : [];
|
||||
const classConstructor = TypeUtil.getType(target);
|
||||
|
||||
if (targets.indexOf(classConstructor) === -1) {
|
||||
targets.push(classConstructor);
|
||||
PROPERTIES.set(key, targets);
|
||||
}
|
||||
|
||||
Reflect.defineMetadata(key, value, TypeUtil.getType(target), propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata value for the provided metadata DESIGN_PARAM_TYPES on the target object or its prototype chain.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @returns The metadata value for the metadata key if found; otherwise, `undefined`.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // on contructor
|
||||
* result = Metadata.getParamTypes(Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.getParamTypes(Example, "staticProperty");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.getParamTypes(Example, "staticMethod");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static getParamTypes(target: any, propertyKey?: PropertyKeyType): any[] {
|
||||
return Reflect.getMetadata(DESIGN_PARAM_TYPES, target, propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata value for the provided metadata DESIGN_PARAM_TYPES on the target object or its prototype chain.
|
||||
* @param target The target object on which the metadata is defined.
|
||||
* @param propertyKey The property key for the target.
|
||||
* @returns The metadata value for the metadata key if found; otherwise, `undefined`.
|
||||
* @example
|
||||
*
|
||||
* ```typescript
|
||||
* class Example {
|
||||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||||
* // static staticProperty;
|
||||
* // property;
|
||||
*
|
||||
* static staticMethod(p) { }
|
||||
* method(p) { }
|
||||
* }
|
||||
*
|
||||
* // on contructor
|
||||
* result = Metadata.getParamTypes(Example);
|
||||
*
|
||||
* // property (on constructor)
|
||||
* result = Metadata.getParamTypes(Example, "staticProperty");
|
||||
*
|
||||
* // method (on constructor)
|
||||
* result = Metadata.getParamTypes(Example, "staticMethod");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
public static getOwnParamTypes(target: any, propertyKey?: PropertyKeyType): any[] {
|
||||
return Reflect.getOwnMetadata(DESIGN_PARAM_TYPES, target, propertyKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Metadata key
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
const DESIGN_PARAM_TYPES = 'design:paramtypes';
|
||||
/**
|
||||
* Metadata key
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
const DESIGN_TYPE = 'design:type';
|
||||
/**
|
||||
* Metadata key
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
const DESIGN_RETURN_TYPE = 'design:returntype';
|
||||
/**
|
||||
* Properties collections
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
const PROPERTIES: Map<MetadataKeyType, any[]> = new Map<MetadataKeyType, any[]>();
|
29
src/reflect/Method.ts
Normal file
29
src/reflect/Method.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import {
|
||||
PropertyKeyType,
|
||||
} from '../type';
|
||||
|
||||
import {
|
||||
TypeUtil,
|
||||
} from '../util/TypeUtil';
|
||||
|
||||
import { Class } from './Class';
|
||||
import { Executable } from './Executable';
|
||||
|
||||
export class Method extends Executable {
|
||||
private _returnType: any;
|
||||
private _rawMethod: Function;
|
||||
|
||||
public constructor(declaringClazz: Class, name: PropertyKeyType, parameterTypes: any[], returnType: any) {
|
||||
super(declaringClazz, name, parameterTypes);
|
||||
this._returnType = returnType;
|
||||
this._rawMethod = TypeUtil.getPrototype(declaringClazz.getType())[name];
|
||||
}
|
||||
|
||||
public getReturnType(): any {
|
||||
return this._returnType;
|
||||
}
|
||||
|
||||
public invoke(instance: Object, ...args: any[]): any {
|
||||
return this._rawMethod.apply(instance, args);
|
||||
}
|
||||
}
|
33
src/reflect/Parameter.ts
Normal file
33
src/reflect/Parameter.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { AccessibleObject } from './AccessibleObject';
|
||||
import { Executable } from './Executable';
|
||||
|
||||
export class Parameter extends AccessibleObject {
|
||||
private _executable: Executable;
|
||||
private _type: any;
|
||||
private _index: number;
|
||||
private _name: string;
|
||||
|
||||
public constructor(executable: Executable, parameterType: any, name: string, index: number) {
|
||||
super();
|
||||
this._executable = executable;
|
||||
this._type = parameterType;
|
||||
this._name = name;
|
||||
this._index = index;
|
||||
}
|
||||
|
||||
public getDeclaringExecutable(): Executable {
|
||||
return this._executable;
|
||||
}
|
||||
|
||||
public getType(): any {
|
||||
return this._type;
|
||||
}
|
||||
|
||||
public getName(): string {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public getIndex(): number {
|
||||
return this._index;
|
||||
}
|
||||
}
|
12
src/reflect/index.ts
Normal file
12
src/reflect/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
export * from './AccessibleObject';
|
||||
export * from './AnnotatedElement';
|
||||
export * from './Annotation';
|
||||
export * from './Class';
|
||||
export * from './Constructor';
|
||||
|
||||
export * from './Executable';
|
||||
export * from './Field';
|
||||
export * from './Member';
|
||||
export * from './Metadata';
|
||||
export * from './Method';
|
||||
export * from './Parameter';
|
16
src/type.ts
Normal file
16
src/type.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
export declare const Type: FunctionConstructor;
|
||||
export declare function isType(v: any): v is Type<any>;
|
||||
export interface Type<T> extends Function {
|
||||
new (...args: any[]): T;
|
||||
}
|
||||
|
||||
export declare type IdentityType<T> = T | symbol;
|
||||
export declare type PropertyKeyType = IdentityType<string>;
|
||||
export declare type MetadataKeyType = IdentityType<string>;
|
||||
|
||||
export enum PrimitiveType {
|
||||
ANY = 'any',
|
||||
STRING = 'string',
|
||||
NUMBER = 'number',
|
||||
BOOLEAN = 'boolean',
|
||||
}
|
39
src/util/AnnotationUtil.ts
Normal file
39
src/util/AnnotationUtil.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { Class, Annotation } from '../reflect';
|
||||
import { Type } from '../type';
|
||||
|
||||
export abstract class AnnotationUtils {
|
||||
public static hasAnnotation<T extends Annotation>(type: Type<any>, annotationClass: Type<T>): boolean {
|
||||
const annotation = AnnotationUtils.getAnnotation(type, annotationClass);
|
||||
if (undefined !== annotation) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static getAnnotation<T extends Annotation>(type: Type<any>, annotationClass: Type<T>): T | undefined {
|
||||
const clazz = Class.forType(type);
|
||||
if (undefined === clazz) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const annotations = clazz.getAnnotations();
|
||||
if (0 === annotations.size) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
for (const annonClassType of Array.from(annotations.keys())) {
|
||||
if (annonClassType === annotationClass) {
|
||||
return <T>annotations.get(annonClassType);
|
||||
}
|
||||
const annotation = AnnotationUtils.getAnnotation(annonClassType, annotationClass);
|
||||
if (undefined !== annotation) {
|
||||
return annotation;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
66
src/util/Registry.ts
Normal file
66
src/util/Registry.ts
Normal file
|
@ -0,0 +1,66 @@
|
|||
export abstract class Registry<K, V> {
|
||||
private _parent: Registry<K, V>;
|
||||
private _map: Map<K, V>;
|
||||
|
||||
protected constructor(parent?: Registry<K, V>) {
|
||||
this._parent = parent;
|
||||
this._map = new Map<K, V>();
|
||||
}
|
||||
|
||||
public get parent(): Registry<K, V> | undefined {
|
||||
return this._parent;
|
||||
}
|
||||
|
||||
public get size(): number {
|
||||
return this._map.size;
|
||||
}
|
||||
|
||||
public get(key: K): V | undefined {
|
||||
let v = this._map.get(key);
|
||||
if (undefined === v && undefined !== this._parent) {
|
||||
v = this._parent.get(key);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public has(key: K): boolean {
|
||||
let exist = this._map.has(key);
|
||||
if (!exist && undefined !== this._parent) {
|
||||
exist = this._parent.has(key);
|
||||
}
|
||||
return exist;
|
||||
}
|
||||
|
||||
public set(key: K, value: V): void {
|
||||
this._map.set(key, value);
|
||||
}
|
||||
|
||||
public entries(): IterableIterator<[K, V]> {
|
||||
return this._map.entries();
|
||||
}
|
||||
|
||||
public keys(): IterableIterator<K> {
|
||||
return this._map.keys();
|
||||
}
|
||||
|
||||
public values(): IterableIterator<V> {
|
||||
return this._map.values();
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this._map.clear();
|
||||
}
|
||||
|
||||
public delete(key: K): boolean {
|
||||
let result = this._map.delete(key);
|
||||
if (!result && undefined !== this._parent) {
|
||||
result = this._parent.delete(key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public forEach(callback: (vlaue: V, key: K, map: Map<K, V>) => void, thisArg?: any): void {
|
||||
this._map.forEach(callback, thisArg);
|
||||
}
|
||||
}
|
407
src/util/TypeUtil.ts
Normal file
407
src/util/TypeUtil.ts
Normal file
|
@ -0,0 +1,407 @@
|
|||
import {
|
||||
Type,
|
||||
PrimitiveType,
|
||||
PropertyKeyType,
|
||||
} from '../type';
|
||||
|
||||
|
||||
export class TypeUtil {
|
||||
/**
|
||||
* Get the provide constructor.
|
||||
* @param target
|
||||
*/
|
||||
public static getContructor<T>(target: any): Type<T> {
|
||||
return typeof target === 'function' ? target : target.constructor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the provide constructor if target is an instance.
|
||||
* @param target
|
||||
* @returns {*}
|
||||
*/
|
||||
public static getType<T>(target: any): Type<T> {
|
||||
return target.prototype ? target : target.constructor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the provide prototype if target is an instance.
|
||||
* @param target
|
||||
* @returns {*}
|
||||
*/
|
||||
public static getPrototype(target: any): Object {
|
||||
return typeof target === 'function' ? target.prototype : target;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {symbol}
|
||||
*/
|
||||
public static getTypeOrSymbol(target: any): any {
|
||||
return typeof target === 'symbol' ? target : TypeUtil.getType(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given obj is a primitive.
|
||||
* @param target
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isPrimitiveOrPrimitiveType(target: any): boolean {
|
||||
return TypeUtil.isString(target)
|
||||
|| TypeUtil.isNumber(target)
|
||||
|| TypeUtil.isBoolean(target);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {PrimitiveType}
|
||||
*/
|
||||
public static primitiveOf(target: any): PrimitiveType {
|
||||
if (TypeUtil.isString(target)) {
|
||||
return PrimitiveType.STRING;
|
||||
}
|
||||
if (TypeUtil.isNumber(target)) {
|
||||
return PrimitiveType.NUMBER;
|
||||
}
|
||||
if (TypeUtil.isBoolean(target)) {
|
||||
return PrimitiveType.BOOLEAN;
|
||||
}
|
||||
return PrimitiveType.ANY;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isString(target: any): boolean {
|
||||
return typeof target === 'string' || target instanceof String || target === String;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isNumber(target: any): boolean {
|
||||
return typeof target === 'number' || target instanceof Number || target === Number;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isBoolean(target: any): boolean {
|
||||
return typeof target === 'boolean' || target instanceof Boolean || target === Boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
public static isArray(target: any): boolean {
|
||||
return Array.isArray(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the clazz is an array.
|
||||
* @param target
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isArrayOrArrayType(target: any): boolean {
|
||||
if (target === Array) {
|
||||
return true;
|
||||
}
|
||||
return TypeUtil.isArray(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the target.
|
||||
* @param target
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isCollection(target: any): boolean {
|
||||
return TypeUtil.isArrayOrArrayType(target)
|
||||
|| target === Map
|
||||
|| target instanceof Map
|
||||
|| target === Set
|
||||
|| target instanceof Set
|
||||
|| target === WeakMap
|
||||
|| target instanceof WeakMap
|
||||
|| target === WeakSet
|
||||
|| target instanceof WeakSet;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isDate(target: any): boolean {
|
||||
return target === Date || target instanceof Date;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isMethod(target: any, propertyKey: PropertyKeyType): boolean {
|
||||
if (typeof(target[propertyKey]) === undefined) {
|
||||
return false;
|
||||
}
|
||||
return typeof target[propertyKey] === 'function';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isObject(target: any): boolean {
|
||||
return target === Object;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isType(target: any): boolean {
|
||||
return !TypeUtil.isPrimitiveOrPrimitiveType(target)
|
||||
&& !TypeUtil.isObject(target)
|
||||
&& !TypeUtil.isDate(target)
|
||||
&& target !== undefined
|
||||
&& !TypeUtil.isPromise(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the value is an empty string, null or undefined.
|
||||
* @param value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isEmpty(value: any): boolean {
|
||||
return value === '' || value === null || value === undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object name
|
||||
*/
|
||||
public static nameOf(obj: any): string {
|
||||
switch (typeof obj) {
|
||||
default:
|
||||
return '' + obj;
|
||||
case 'symbol':
|
||||
return TypeUtil.nameOfSymbol(obj);
|
||||
case 'function':
|
||||
return TypeUtil.nameOfType(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the provide name.
|
||||
* @param target
|
||||
*/
|
||||
public static nameOfType(target: any): string {
|
||||
return typeof target === 'function'
|
||||
? target.name
|
||||
: target.constructor.name;
|
||||
}
|
||||
/**
|
||||
* Get symbol name.
|
||||
* @param sym
|
||||
*/
|
||||
public static nameOfSymbol(sym: symbol): string {
|
||||
return sym.toString().replace('Symbol(', '').replace(')', '');
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param out
|
||||
* @param obj
|
||||
* @param {{[p: string]: (collection: any[], value: any) => any}} reducers
|
||||
* @returns {any}
|
||||
*/
|
||||
public static deepExtends(out: any, obj: any, reducers: { [key: string]: (collection: any[], value: any) => any } = {}): any {
|
||||
|
||||
if (obj === undefined || obj === null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (TypeUtil.isPrimitiveOrPrimitiveType(obj) || typeof obj === 'symbol' || typeof obj === 'function') {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (TypeUtil.isArrayOrArrayType(obj)) {
|
||||
out = out || [];
|
||||
} else {
|
||||
out = out || {};
|
||||
}
|
||||
|
||||
const defaultReducer = reducers.default ? reducers.default : (collection: any[], value: any) => {
|
||||
collection.push(value);
|
||||
return collection;
|
||||
};
|
||||
const set = (key: string | number, value: any) => {
|
||||
if (TypeUtil.isArrayOrArrayType(obj)) {
|
||||
out.push(value);
|
||||
} else {
|
||||
out[key] = value;
|
||||
}
|
||||
};
|
||||
|
||||
Object.keys(obj).forEach(key => {
|
||||
let value = obj[key];
|
||||
|
||||
if (value === undefined || value === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value === '' && out[key] !== '') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TypeUtil.isPrimitiveOrPrimitiveType(value) || typeof value === 'function') {
|
||||
set(key, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TypeUtil.isArrayOrArrayType(value)) {
|
||||
|
||||
value = value.map((v: any) => TypeUtil.deepExtends(undefined, v));
|
||||
|
||||
set(key, []
|
||||
.concat(out[key] || [], value)
|
||||
.reduce((collection: any[], v: any) =>
|
||||
reducers[key] ? reducers[key](collection, v) : defaultReducer(collection, v),
|
||||
[]));
|
||||
return;
|
||||
}
|
||||
|
||||
// Object
|
||||
if (TypeUtil.isArrayOrArrayType(obj)) {
|
||||
set(key, TypeUtil.deepExtends(undefined, value, reducers));
|
||||
} else {
|
||||
set(key, TypeUtil.deepExtends(out[key], value, reducers));
|
||||
}
|
||||
});
|
||||
|
||||
if (TypeUtil.isArrayOrArrayType(out)) {
|
||||
out.reduce((collection: any[], value: any) => defaultReducer(collection, value), []);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isPromise(target: any): boolean {
|
||||
return target === Promise || target instanceof Promise;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {any}
|
||||
*/
|
||||
public static getInheritedType(target: Type<any>): Type<any> {
|
||||
return Object.getPrototypeOf(target);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @param {PropertyKeyType} propertyKey
|
||||
* @returns {PropertyDescriptor}
|
||||
*/
|
||||
public static descriptorOf(target: any, propertyKey: PropertyKeyType): PropertyDescriptor {
|
||||
return Object.getOwnPropertyDescriptor(target && target.prototype || target, propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @param {PropertyKeyType} propertyKey
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public static getParameterNames(target: any, propertyKey: PropertyKeyType): string[] {
|
||||
const rawType = TypeUtil.getPrototype(target);
|
||||
const fn: Function = rawType[propertyKey];
|
||||
|
||||
const code = fn.toString()
|
||||
.replace(COMMENTS, '')
|
||||
.replace(FAT_ARROWS, '')
|
||||
.replace(DEFAULT_PARAMS, '');
|
||||
|
||||
const result = code.slice(code.indexOf('(') + 1, code.indexOf(')')).match(/([^\s,]+)/g);
|
||||
|
||||
return result === null
|
||||
? []
|
||||
: result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @returns {Array}
|
||||
*/
|
||||
public static ancestorsOf(target: Type<any>): Type<any>[] {
|
||||
const classes: Type<any>[] = [];
|
||||
|
||||
let currentTarget = TypeUtil.getType(target);
|
||||
|
||||
while (TypeUtil.nameOf(currentTarget) !== '') {
|
||||
classes.unshift(currentTarget);
|
||||
currentTarget = TypeUtil.getInheritedType(currentTarget);
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @param {string} name
|
||||
* @param {Function} callback
|
||||
*/
|
||||
public static applyBefore(target: any, name: string, callback: Function): void {
|
||||
const original = target[name];
|
||||
target[name] = function (...args: any[]): any {
|
||||
callback(...args);
|
||||
return original.apply(this, args);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Promise<any>} promise
|
||||
* @param {number} time
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
public static promiseTimeout(promise: Promise<any>, time: number = 1000): Promise<{ ok: boolean, response: any }> {
|
||||
const timeout = (p: Promise<any>, t: number) => new Promise((resolve) => {
|
||||
p.then((response) => {
|
||||
resolve();
|
||||
return response;
|
||||
});
|
||||
setTimeout(() => resolve({ok: false}), t);
|
||||
});
|
||||
|
||||
promise = promise.then((response) => ({ok: true, response}));
|
||||
|
||||
return Promise.race([
|
||||
promise,
|
||||
timeout(promise, time),
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
|
||||
const DEFAULT_PARAMS = /=[^,]+/mg;
|
||||
const FAT_ARROWS = /=>.*$/mg;
|
3
src/util/index.ts
Normal file
3
src/util/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export * from './AnnotationUtil';
|
||||
export * from './Registry';
|
||||
export * from './TypeUtil';
|
46
tsconfig.json
Normal file
46
tsconfig.json
Normal file
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./src",
|
||||
"outDir": "./dist",
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"newLine": "LF",
|
||||
"moduleResolution": "node",
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
// "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
|
||||
// "strictNullChecks": true /* Enable strict null checks. */,
|
||||
// "strictFunctionTypes": true /* Enable strict checking of function types. */,
|
||||
// "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */,
|
||||
// "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
|
||||
// "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
|
||||
|
||||
/* Additional Checks */
|
||||
"noUnusedLocals": true /* Report errors on unused locals. */,
|
||||
"noUnusedParameters": true /* Report errors on unused parameters. */,
|
||||
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
|
||||
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
|
||||
|
||||
/* Debugging Options */
|
||||
"traceResolution": false /* Report module resolution log messages. */,
|
||||
"listEmittedFiles": false /* Print names of generated files part of the compilation. */,
|
||||
"listFiles": false /* Print names of files part of the compilation. */,
|
||||
"pretty": true /* Stylize errors and messages using color and context. */,
|
||||
|
||||
/* Experimental Options */
|
||||
"experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
|
||||
"emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */,
|
||||
|
||||
"target": "es5",
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
],
|
||||
"types": [
|
||||
"reflect-metadata",
|
||||
],
|
||||
"lib": [
|
||||
"es2015", "es2016", "es2017", "dom"
|
||||
]
|
||||
}
|
||||
}
|
34
tslint.json
Normal file
34
tslint.json
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"],
|
||||
"rules": {
|
||||
"interface-name": [true, "never-prefix"],
|
||||
// TODO: allow devDependencies only in **/*.spec.ts files:
|
||||
// waiting on https://github.com/palantir/tslint/pull/3708
|
||||
"no-implicit-dependencies": [true, "dev"],
|
||||
|
||||
/* tslint-immutable rules */
|
||||
// Recommended built-in rules
|
||||
"no-var-keyword": true,
|
||||
"no-parameter-reassignment": true,
|
||||
"typedef": [true, "call-signature"],
|
||||
|
||||
// Immutability rules
|
||||
"readonly-keyword": true,
|
||||
"readonly-array": true,
|
||||
"no-let": true,
|
||||
"no-object-mutation": true,
|
||||
"no-delete": true,
|
||||
"no-method-signature": true,
|
||||
|
||||
// Functional style rules
|
||||
"no-this": true,
|
||||
"no-class": true,
|
||||
"no-mixed-interface": true,
|
||||
"no-expression-statement": [
|
||||
true,
|
||||
{ "ignore-prefix": ["console.", "process.exit"] }
|
||||
],
|
||||
"no-if-statement": true
|
||||
/* end tslint-immutable rules */
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user