##// END OF EJS Templates
initial port of implab/web
cin -
r0:7110eac54b19 v1.0.0 default
parent child
Show More
@@ -0,0 +1,27
1 {
2 "env": {
3 "browser": true,
4 "commonjs": true,
5 "amd": true,
6 "node": true
7 },
8 "parserOptions": {
9 "ecmaFeatures": {
10 "jsx": true
11 },
12 "sourceType": "module"
13 },
14 "extends": "eslint:recommended",
15 "rules": {
16 "no-const-assign": "warn",
17 "no-this-before-super": "warn",
18 "no-undef": "error",
19 "no-unreachable": "warn",
20 "no-unused-vars": "warn",
21 "constructor-super": "warn",
22 "valid-typeof": "warn",
23 "semi" : "warn",
24 "no-invalid-this" : "error",
25 "no-console": "off"
26 }
27 } No newline at end of file
@@ -0,0 +1,5
1 syntax: glob
2 .gradle/
3 build/
4 node_modules/
5 src/typings/
@@ -0,0 +1,16
1 {
2 "java.configuration.updateBuildConfiguration": "disabled",
3 "tslint.enable": true,
4 "search.exclude": {
5 "**/node_modules": true,
6 "**/bower_components": true,
7 "/build": true
8 },
9 "files.watcherExclude": {
10 "**/.git/objects/**": true,
11 "**/.git/subtree-cache/**": true,
12 "**/node_modules/**": true,
13 "/build": true
14 },
15 "editor.minimap.enabled": false
16 } No newline at end of file
@@ -0,0 +1,276
1 // Ссли вСрсия явно Π½Π΅ Π·Π°Π΄Π°Π½Ρ‹ вычисляСм Π΅Π΅ ΠΈΠ· тэга Ρ€Π΅Π²ΠΈΠ·ΠΈΠΈ v.{num}***
2 // Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ Π±ΡƒΠ΄Π΅Ρ‚ вСрсия '{num}.{distance}' Π³Π΄Π΅ distance - расстояниС ΠΎΡ‚
3 // Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ€Π΅Π²ΠΈΠ·ΠΈΠΈ Π΄ΠΎ Ρ€Π΅Π²ΠΈΠ·ΠΈΠΈ с тэгом
4 def tagDistance = 0;
5 def isRelease = false;
6
7 if (!version) {
8
9 def rev = ["hg", "log", "-r", ".", "--template", "{latesttag('re:^v') % '{tag}-{distance}'}"].execute().text.trim();
10
11 def tagVersion;
12
13 def match = (rev =~ /^v(\d+\.\d+\.\d+).*-(\d+)$/);
14
15 if (match.size()) {
16 tagVersion = match[0][1];
17 tagDistance = match[0][2].toInteger();
18
19 version = tagVersion;
20
21 if (tagDistance > 0)
22 version++;
23 } else {
24 throw new Exception("A version must be specied");
25 }
26 } else {
27 println "explicit version: $version";
28 }
29
30 if (hasProperty('versionSuffix') && versionSuffix) {
31 version += "-$versionSuffix"
32 }
33
34 if(!npmName)
35 npmName = name;
36
37 if (hasProperty('release')) {
38 isRelease = (release != 'false')
39 } else {
40 isRelease = (tagDistance == 0);
41 }
42
43 if(!["amd", "commonjs", "system", "umd", "es6", "esnext"].contains(jsmodule))
44 throw new Exception("Invalid jsmodule specified: $jsmodule");
45 if(!["es3", "es5", "es6", "es2016", "es2017", "esnext"].contains(target))
46 throw new Exception("Invalid target specified: $target")
47
48 def targetLibs = [
49 "es3" : "es5,es2015.promise,es2015.symbol,dom,scripthost",
50 "es5" : "es5,es2015.promise,es2015.symbol,dom,scripthost"
51 ];
52
53 ext.packageName="@$npmScope/$npmName";
54
55 def srcDir = "$projectDir/src"
56 def typingsDir = "$srcDir/typings"
57 def distDir = "$buildDir/dist"
58 def testDir = "$buildDir/test"
59 def lib = targetLibs[target] ?: "${target},dom";
60
61 println "lib: $lib";
62
63 def sourceSets = ["main", "amd", "cjs"];
64 def testSets = ["test", "testAmd", "testCjs"];
65
66 task beforeBuild {
67 }
68
69 def createSoursetTasks = { String name, String outDir ->
70 def setName = name.capitalize();
71
72 def compileDir = "$buildDir/compile/$name"
73 def declDir = "$typingsDir/$name"
74 def setDir = "$projectDir/src/$name"
75 def jsDir = outDir;
76
77 def beforeBuildTask = task "beforeBuild$setName"(dependsOn: beforeBuild) {
78 }
79
80 def copyJsTask = task "copyJs$setName"(dependsOn: beforeBuildTask, type: Copy) {
81 from "$setDir/js"
82 into jsDir
83 }
84
85 def lintJsTask = task "lintJs$setName"(dependsOn: beforeBuildTask, type: Exec) {
86 inputs.dir("$setDir/js/").skipWhenEmpty();
87 commandLine "eslint", '--format', 'stylish', "$setDir/js/"
88 }
89
90 def compileTsTask = task "compileTs$setName"(dependsOn: beforeBuildTask, type: Exec) {
91 inputs.dir("$setDir/ts").skipWhenEmpty()
92 inputs.file("$srcDir/tsconfig.json")
93 inputs.file("$setDir/tsconfig.json")
94 outputs.dir(compileDir)
95 outputs.dir(declDir)
96
97 commandLine 'node_modules/.bin/tsc',
98 '-p', "$setDir/tsconfig.json",
99 '-t', target,
100 '-m', jsmodule,
101 '-d',
102 '--outDir', compileDir,
103 '--declarationDir', declDir
104
105 if (lib)
106 args '--lib', lib
107 }
108
109 def copyTsOutputTask = task "copyTsOutput$setName"(dependsOn: compileTsTask, type: Copy) {
110 from compileDir
111 into jsDir
112 }
113
114 def copyTypingsTask = task "copyTypings$setName"(dependsOn: compileTsTask, type: Copy) {
115 from declDir
116 into jsDir
117 }
118
119 def copyResourcesTask = task "copyResources$setName"(dependsOn: beforeBuildTask, type: Copy) {
120 from "$setDir/resources"
121 into outDir
122 }
123
124 task "build$setName" {
125 dependsOn copyTypingsTask,
126 copyTsOutputTask,
127 copyJsTask,
128 copyResourcesTask,
129 lintJsTask
130 }
131 }
132
133 task printVersion {
134 doLast {
135 println "version: $version";
136 println "isRelease: $isRelease, tagDistance: $tagDistance";
137 println "packageName: $packageName";
138 println "bundle: ${pack.outputs.files.join(',')}";
139 println "target: $target";
140 println "module: $jsmodule";
141 }
142 }
143
144 task clean {
145 doLast {
146 delete buildDir
147 delete typingsDir
148 }
149 }
150
151 task _initBuild {
152 mustRunAfter clean
153
154 def buildInfoFile = "$buildDir/platform";
155 inputs.property('target',target);
156 inputs.property('jsmodule',jsmodule);
157 outputs.file(buildInfoFile);
158
159 doLast {
160 delete buildDir
161 mkdir buildDir
162
163 def f = new File(buildInfoFile);
164 f << "$target-$jsmodule";
165 }
166 }
167
168 task cleanNpm {
169 doLast {
170 delete 'node_modules'
171 }
172 }
173
174 task _npmInstall() {
175 inputs.file("package.json")
176 outputs.dir("node_modules")
177 doLast {
178 exec {
179 commandLine 'npm', 'install'
180 }
181 }
182 }
183
184 beforeBuild {
185 dependsOn _initBuild
186 dependsOn _npmInstall
187 }
188
189 sourceSets.each { createSoursetTasks(it, distDir) }
190
191 testSets.each { createSoursetTasks(it, testDir) }
192
193 compileTsAmd {
194 dependsOn compileTsMain
195 }
196
197 compileTsCjs {
198 dependsOn compileTsMain
199 }
200
201 task build(dependsOn: buildMain) {
202 if (jsmodule == "amd")
203 dependsOn buildAmd
204 if (jsmodule == "commonjs")
205 dependsOn buildCjs
206 }
207
208 compileTsTest {
209 dependsOn build
210 }
211
212 compileTsTestAmd {
213 dependsOn compileTsTest
214 }
215
216 compileTsTestCjs {
217 dependsOn compileTsTest
218 }
219
220 task _installLocalCjsDependency(dependsOn: [buildTestCjs, "_packageMeta"], type: Exec) {
221 inputs.file("$distDir/package.json")
222 outputs.upToDateWhen {
223 new File("$testDir/$packageName").exists()
224 }
225
226 workingDir testDir
227
228 commandLine 'npm', 'install', '--no-save', '--force', distDir
229 }
230
231 task test(dependsOn: [buildTest], type: Exec) {
232 if (jsmodule == "amd")
233 dependsOn buildTestAmd
234 if (jsmodule == "commonjs") {
235 dependsOn buildTestCjs
236 dependsOn _installLocalCjsDependency
237 }
238
239 commandLine 'node', "$testDir/run-tests.js"
240 }
241
242 task _packageMeta(type: Copy) {
243 mustRunAfter build
244
245 inputs.property("version", version)
246 from('.') {
247 include '.npmignore', 'readme.md', 'license', 'history.md'
248 }
249 from("package.${jsmodule}.json") {
250 expand project.properties
251 rename { "package.json" }
252 }
253 into distDir
254 }
255
256 task pack(dependsOn: [build, _packageMeta], type: Exec) {
257 workingDir distDir
258 outputs.file("$npmScope-$npmName-${version}.tgz")
259
260 commandLine 'npm', 'pack'
261 }
262
263 task publish(dependsOn: [build, _packageMeta], type: Exec) {
264 doFirst {
265 if (!isRelease)
266 throw new Exception("Can't publish an unreleased version");
267 }
268 workingDir distDir
269
270 commandLine 'npm', 'publish', '--access', 'public'
271 }
272
273 task markRelease(type: Exec) {
274 onlyIf { tagDistance > 1 }
275 commandLine "hg", "tag", "v$version";
276 } No newline at end of file
@@ -0,0 +1,9
1 version=
2 author=Implab team
3 jsmodule=amd
4 target=es5
5 description=The simple framework for writing a RESTful application
6 license=BSD-2-Clause
7 repository=https://bitbucket.org/implab/implabjs-web
8 npmScope=implab
9 npmName=web No newline at end of file
1 NO CONTENT: new file 100644, binary diff hidden
@@ -0,0 +1,5
1 distributionBase=GRADLE_USER_HOME
2 distributionPath=wrapper/dists
3 distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip
4 zipStoreBase=GRADLE_USER_HOME
5 zipStorePath=wrapper/dists
@@ -0,0 +1,172
1 #!/usr/bin/env sh
2
3 ##############################################################################
4 ##
5 ## Gradle start up script for UN*X
6 ##
7 ##############################################################################
8
9 # Attempt to set APP_HOME
10 # Resolve links: $0 may be a link
11 PRG="$0"
12 # Need this for relative symlinks.
13 while [ -h "$PRG" ] ; do
14 ls=`ls -ld "$PRG"`
15 link=`expr "$ls" : '.*-> \(.*\)$'`
16 if expr "$link" : '/.*' > /dev/null; then
17 PRG="$link"
18 else
19 PRG=`dirname "$PRG"`"/$link"
20 fi
21 done
22 SAVED="`pwd`"
23 cd "`dirname \"$PRG\"`/" >/dev/null
24 APP_HOME="`pwd -P`"
25 cd "$SAVED" >/dev/null
26
27 APP_NAME="Gradle"
28 APP_BASE_NAME=`basename "$0"`
29
30 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 DEFAULT_JVM_OPTS='"-Xmx64m"'
32
33 # Use the maximum available, or set MAX_FD != -1 to use that value.
34 MAX_FD="maximum"
35
36 warn () {
37 echo "$*"
38 }
39
40 die () {
41 echo
42 echo "$*"
43 echo
44 exit 1
45 }
46
47 # OS specific support (must be 'true' or 'false').
48 cygwin=false
49 msys=false
50 darwin=false
51 nonstop=false
52 case "`uname`" in
53 CYGWIN* )
54 cygwin=true
55 ;;
56 Darwin* )
57 darwin=true
58 ;;
59 MINGW* )
60 msys=true
61 ;;
62 NONSTOP* )
63 nonstop=true
64 ;;
65 esac
66
67 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68
69 # Determine the Java command to use to start the JVM.
70 if [ -n "$JAVA_HOME" ] ; then
71 if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 # IBM's JDK on AIX uses strange locations for the executables
73 JAVACMD="$JAVA_HOME/jre/sh/java"
74 else
75 JAVACMD="$JAVA_HOME/bin/java"
76 fi
77 if [ ! -x "$JAVACMD" ] ; then
78 die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79
80 Please set the JAVA_HOME variable in your environment to match the
81 location of your Java installation."
82 fi
83 else
84 JAVACMD="java"
85 which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86
87 Please set the JAVA_HOME variable in your environment to match the
88 location of your Java installation."
89 fi
90
91 # Increase the maximum file descriptors if we can.
92 if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 MAX_FD_LIMIT=`ulimit -H -n`
94 if [ $? -eq 0 ] ; then
95 if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 MAX_FD="$MAX_FD_LIMIT"
97 fi
98 ulimit -n $MAX_FD
99 if [ $? -ne 0 ] ; then
100 warn "Could not set maximum file descriptor limit: $MAX_FD"
101 fi
102 else
103 warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 fi
105 fi
106
107 # For Darwin, add options to specify how the application appears in the dock
108 if $darwin; then
109 GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 fi
111
112 # For Cygwin, switch paths to Windows format before running java
113 if $cygwin ; then
114 APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 JAVACMD=`cygpath --unix "$JAVACMD"`
117
118 # We build the pattern for arguments to be converted via cygpath
119 ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 SEP=""
121 for dir in $ROOTDIRSRAW ; do
122 ROOTDIRS="$ROOTDIRS$SEP$dir"
123 SEP="|"
124 done
125 OURCYGPATTERN="(^($ROOTDIRS))"
126 # Add a user-defined pattern to the cygpath arguments
127 if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 fi
130 # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 i=0
132 for arg in "$@" ; do
133 CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135
136 if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 else
139 eval `echo args$i`="\"$arg\""
140 fi
141 i=$((i+1))
142 done
143 case $i in
144 (0) set -- ;;
145 (1) set -- "$args0" ;;
146 (2) set -- "$args0" "$args1" ;;
147 (3) set -- "$args0" "$args1" "$args2" ;;
148 (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 esac
155 fi
156
157 # Escape application args
158 save () {
159 for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 echo " "
161 }
162 APP_ARGS=$(save "$@")
163
164 # Collect all arguments for the java command, following the shell quoting and substitution rules
165 eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166
167 # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 cd "$(dirname "$0")"
170 fi
171
172 exec "$JAVACMD" "$@"
@@ -0,0 +1,84
1 @if "%DEBUG%" == "" @echo off
2 @rem ##########################################################################
3 @rem
4 @rem Gradle startup script for Windows
5 @rem
6 @rem ##########################################################################
7
8 @rem Set local scope for the variables with windows NT shell
9 if "%OS%"=="Windows_NT" setlocal
10
11 set DIRNAME=%~dp0
12 if "%DIRNAME%" == "" set DIRNAME=.
13 set APP_BASE_NAME=%~n0
14 set APP_HOME=%DIRNAME%
15
16 @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 set DEFAULT_JVM_OPTS="-Xmx64m"
18
19 @rem Find java.exe
20 if defined JAVA_HOME goto findJavaFromJavaHome
21
22 set JAVA_EXE=java.exe
23 %JAVA_EXE% -version >NUL 2>&1
24 if "%ERRORLEVEL%" == "0" goto init
25
26 echo.
27 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 echo.
29 echo Please set the JAVA_HOME variable in your environment to match the
30 echo location of your Java installation.
31
32 goto fail
33
34 :findJavaFromJavaHome
35 set JAVA_HOME=%JAVA_HOME:"=%
36 set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
38 if exist "%JAVA_EXE%" goto init
39
40 echo.
41 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 echo.
43 echo Please set the JAVA_HOME variable in your environment to match the
44 echo location of your Java installation.
45
46 goto fail
47
48 :init
49 @rem Get command-line arguments, handling Windows variants
50
51 if not "%OS%" == "Windows_NT" goto win9xME_args
52
53 :win9xME_args
54 @rem Slurp the command line arguments.
55 set CMD_LINE_ARGS=
56 set _SKIP=2
57
58 :win9xME_args_slurp
59 if "x%~1" == "x" goto execute
60
61 set CMD_LINE_ARGS=%*
62
63 :execute
64 @rem Setup the command line
65
66 set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67
68 @rem Execute Gradle
69 "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70
71 :end
72 @rem End local scope for the variables with windows NT shell
73 if "%ERRORLEVEL%"=="0" goto mainEnd
74
75 :fail
76 rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 rem the _cmd.exe /c_ return code!
78 if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 exit /b 1
80
81 :mainEnd
82 if "%OS%"=="Windows_NT" endlocal
83
84 :omega
@@ -0,0 +1,10
1 HISTORY
2 =======
3
4 1.0.0
5 -----
6
7 First release, the port from legacy project, intorduces the following features
8
9 - `security` - basic security model and concepts
10 - A resource-oriented web application framework No newline at end of file
@@ -0,0 +1,22
1 Copyright 2017-2019 Implab team
2
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions are met:
5
6 1. Redistributions of source code must retain the above copyright notice, this
7 list of conditions and the following disclaimer.
8
9 2. Redistributions in binary form must reproduce the above copyright notice,
10 this list of conditions and the following disclaimer in the documentation
11 and/or other materials provided with the distribution.
12
13 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
17 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. No newline at end of file
@@ -0,0 +1,477
1 {
2 "name": "@implab/web",
3 "version": "0.0.1-dev",
4 "lockfileVersion": 1,
5 "requires": true,
6 "dependencies": {
7 "@implab/core-amd": {
8 "version": "1.2.15",
9 "resolved": "https://registry.npmjs.org/@implab/core-amd/-/core-amd-1.2.15.tgz",
10 "integrity": "sha512-Vc5L9W/jz62R2fW1RnhPd6S503oztJLgddBGgNgJ4JjaBZt9P/Ym+98jAMkFbtCY3dX1RLM0SuI33hDPoG8Wgw==",
11 "dev": true
12 },
13 "@types/node": {
14 "version": "11.9.4",
15 "resolved": "https://registry.npmjs.org/@types/node/-/node-11.9.4.tgz",
16 "integrity": "sha512-Zl8dGvAcEmadgs1tmSPcvwzO1YRsz38bVJQvH1RvRqSR9/5n61Q1ktcDL0ht3FXWR+ZpVmXVwN1LuH4Ax23NsA==",
17 "dev": true
18 },
19 "@types/requirejs": {
20 "version": "2.1.31",
21 "resolved": "https://registry.npmjs.org/@types/requirejs/-/requirejs-2.1.31.tgz",
22 "integrity": "sha512-b2soeyuU76rMbcRJ4e0hEl0tbMhFwZeTC0VZnfuWlfGlk6BwWNsev6kFu/twKABPX29wkX84wU2o+cEJoXsiTw==",
23 "dev": true
24 },
25 "@types/tape": {
26 "version": "4.2.33",
27 "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz",
28 "integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==",
29 "dev": true,
30 "requires": {
31 "@types/node": "*"
32 }
33 },
34 "balanced-match": {
35 "version": "1.0.0",
36 "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
37 "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
38 "dev": true
39 },
40 "brace-expansion": {
41 "version": "1.1.11",
42 "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
43 "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
44 "dev": true,
45 "requires": {
46 "balanced-match": "^1.0.0",
47 "concat-map": "0.0.1"
48 }
49 },
50 "concat-map": {
51 "version": "0.0.1",
52 "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
53 "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
54 "dev": true
55 },
56 "core-util-is": {
57 "version": "1.0.2",
58 "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
59 "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
60 "dev": true
61 },
62 "deep-equal": {
63 "version": "0.1.2",
64 "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.1.2.tgz",
65 "integrity": "sha1-skbCuApXCkfBG+HZvRBw7IeLh84=",
66 "dev": true
67 },
68 "define-properties": {
69 "version": "1.1.3",
70 "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
71 "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
72 "dev": true,
73 "requires": {
74 "object-keys": "^1.0.12"
75 },
76 "dependencies": {
77 "object-keys": {
78 "version": "1.1.0",
79 "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz",
80 "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==",
81 "dev": true
82 }
83 }
84 },
85 "defined": {
86 "version": "0.0.0",
87 "resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz",
88 "integrity": "sha1-817qfXBekzuvE7LwOz+D2SFAOz4=",
89 "dev": true
90 },
91 "dojo": {
92 "version": "1.15.0",
93 "resolved": "https://registry.npmjs.org/dojo/-/dojo-1.15.0.tgz",
94 "integrity": "sha512-+1r5Nj1+iaHI8AxUadqsSp8wJMJM6sslr3INgWKhxUA0xHznBNY0htt38XLyheuy1G7oOwsh4X1An+Uzirj7Gw==",
95 "dev": true
96 },
97 "duplexer": {
98 "version": "0.1.1",
99 "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
100 "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
101 "dev": true
102 },
103 "es-abstract": {
104 "version": "1.13.0",
105 "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
106 "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
107 "dev": true,
108 "requires": {
109 "es-to-primitive": "^1.2.0",
110 "function-bind": "^1.1.1",
111 "has": "^1.0.3",
112 "is-callable": "^1.1.4",
113 "is-regex": "^1.0.4",
114 "object-keys": "^1.0.12"
115 },
116 "dependencies": {
117 "object-keys": {
118 "version": "1.1.0",
119 "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz",
120 "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==",
121 "dev": true
122 }
123 }
124 },
125 "es-to-primitive": {
126 "version": "1.2.0",
127 "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
128 "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
129 "dev": true,
130 "requires": {
131 "is-callable": "^1.1.4",
132 "is-date-object": "^1.0.1",
133 "is-symbol": "^1.0.2"
134 }
135 },
136 "faucet": {
137 "version": "0.0.1",
138 "resolved": "https://registry.npmjs.org/faucet/-/faucet-0.0.1.tgz",
139 "integrity": "sha1-WX3PHSGJosBiMhtZHo8VHtIDnZw=",
140 "dev": true,
141 "requires": {
142 "defined": "0.0.0",
143 "duplexer": "~0.1.1",
144 "minimist": "0.0.5",
145 "sprintf": "~0.1.3",
146 "tap-parser": "~0.4.0",
147 "tape": "~2.3.2",
148 "through2": "~0.2.3"
149 },
150 "dependencies": {
151 "tape": {
152 "version": "2.3.3",
153 "resolved": "https://registry.npmjs.org/tape/-/tape-2.3.3.tgz",
154 "integrity": "sha1-Lnzgox3wn41oUWZKcYQuDKUFevc=",
155 "dev": true,
156 "requires": {
157 "deep-equal": "~0.1.0",
158 "defined": "~0.0.0",
159 "inherits": "~2.0.1",
160 "jsonify": "~0.0.0",
161 "resumer": "~0.0.0",
162 "through": "~2.3.4"
163 }
164 }
165 }
166 },
167 "for-each": {
168 "version": "0.3.3",
169 "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
170 "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
171 "dev": true,
172 "requires": {
173 "is-callable": "^1.1.3"
174 }
175 },
176 "fs.realpath": {
177 "version": "1.0.0",
178 "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
179 "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
180 "dev": true
181 },
182 "function-bind": {
183 "version": "1.1.1",
184 "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
185 "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
186 "dev": true
187 },
188 "glob": {
189 "version": "7.1.3",
190 "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
191 "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
192 "dev": true,
193 "requires": {
194 "fs.realpath": "^1.0.0",
195 "inflight": "^1.0.4",
196 "inherits": "2",
197 "minimatch": "^3.0.4",
198 "once": "^1.3.0",
199 "path-is-absolute": "^1.0.0"
200 }
201 },
202 "has": {
203 "version": "1.0.3",
204 "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
205 "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
206 "dev": true,
207 "requires": {
208 "function-bind": "^1.1.1"
209 }
210 },
211 "has-symbols": {
212 "version": "1.0.0",
213 "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
214 "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
215 "dev": true
216 },
217 "inflight": {
218 "version": "1.0.6",
219 "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
220 "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
221 "dev": true,
222 "requires": {
223 "once": "^1.3.0",
224 "wrappy": "1"
225 }
226 },
227 "inherits": {
228 "version": "2.0.3",
229 "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
230 "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
231 "dev": true
232 },
233 "is-callable": {
234 "version": "1.1.4",
235 "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
236 "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
237 "dev": true
238 },
239 "is-date-object": {
240 "version": "1.0.1",
241 "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
242 "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
243 "dev": true
244 },
245 "is-regex": {
246 "version": "1.0.4",
247 "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
248 "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
249 "dev": true,
250 "requires": {
251 "has": "^1.0.1"
252 }
253 },
254 "is-symbol": {
255 "version": "1.0.2",
256 "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
257 "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
258 "dev": true,
259 "requires": {
260 "has-symbols": "^1.0.0"
261 }
262 },
263 "isarray": {
264 "version": "0.0.1",
265 "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
266 "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
267 "dev": true
268 },
269 "jsonify": {
270 "version": "0.0.0",
271 "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
272 "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
273 "dev": true
274 },
275 "minimatch": {
276 "version": "3.0.4",
277 "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
278 "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
279 "dev": true,
280 "requires": {
281 "brace-expansion": "^1.1.7"
282 }
283 },
284 "minimist": {
285 "version": "0.0.5",
286 "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.5.tgz",
287 "integrity": "sha1-16oye87PUY+RBqxrjwA/o7zqhWY=",
288 "dev": true
289 },
290 "object-inspect": {
291 "version": "1.6.0",
292 "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz",
293 "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==",
294 "dev": true
295 },
296 "object-keys": {
297 "version": "0.4.0",
298 "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
299 "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
300 "dev": true
301 },
302 "once": {
303 "version": "1.4.0",
304 "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
305 "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
306 "dev": true,
307 "requires": {
308 "wrappy": "1"
309 }
310 },
311 "path-is-absolute": {
312 "version": "1.0.1",
313 "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
314 "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
315 "dev": true
316 },
317 "path-parse": {
318 "version": "1.0.6",
319 "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
320 "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
321 "dev": true
322 },
323 "readable-stream": {
324 "version": "1.1.14",
325 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
326 "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
327 "dev": true,
328 "requires": {
329 "core-util-is": "~1.0.0",
330 "inherits": "~2.0.1",
331 "isarray": "0.0.1",
332 "string_decoder": "~0.10.x"
333 }
334 },
335 "requirejs": {
336 "version": "2.3.6",
337 "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
338 "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==",
339 "dev": true
340 },
341 "resolve": {
342 "version": "1.10.0",
343 "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
344 "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
345 "dev": true,
346 "requires": {
347 "path-parse": "^1.0.6"
348 }
349 },
350 "resumer": {
351 "version": "0.0.0",
352 "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz",
353 "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=",
354 "dev": true,
355 "requires": {
356 "through": "~2.3.4"
357 }
358 },
359 "sprintf": {
360 "version": "0.1.5",
361 "resolved": "https://registry.npmjs.org/sprintf/-/sprintf-0.1.5.tgz",
362 "integrity": "sha1-j4PjmpMXwaUCy324BQ5Rxnn27c8=",
363 "dev": true
364 },
365 "string.prototype.trim": {
366 "version": "1.1.2",
367 "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz",
368 "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=",
369 "dev": true,
370 "requires": {
371 "define-properties": "^1.1.2",
372 "es-abstract": "^1.5.0",
373 "function-bind": "^1.0.2"
374 }
375 },
376 "string_decoder": {
377 "version": "0.10.31",
378 "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
379 "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
380 "dev": true
381 },
382 "tap-parser": {
383 "version": "0.4.3",
384 "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-0.4.3.tgz",
385 "integrity": "sha1-pOrhkMENdsehEZIf84u+TVjwnuo=",
386 "dev": true,
387 "requires": {
388 "inherits": "~2.0.1",
389 "readable-stream": "~1.1.11"
390 }
391 },
392 "tape": {
393 "version": "4.10.1",
394 "resolved": "https://registry.npmjs.org/tape/-/tape-4.10.1.tgz",
395 "integrity": "sha512-G0DywYV1jQeY3axeYnXUOt6ktnxS9OPJh97FGR3nrua8lhWi1zPflLxcAHavZ7Jf3qUfY7cxcVIVFa4mY2IY1w==",
396 "dev": true,
397 "requires": {
398 "deep-equal": "~1.0.1",
399 "defined": "~1.0.0",
400 "for-each": "~0.3.3",
401 "function-bind": "~1.1.1",
402 "glob": "~7.1.3",
403 "has": "~1.0.3",
404 "inherits": "~2.0.3",
405 "minimist": "~1.2.0",
406 "object-inspect": "~1.6.0",
407 "resolve": "~1.10.0",
408 "resumer": "~0.0.0",
409 "string.prototype.trim": "~1.1.2",
410 "through": "~2.3.8"
411 },
412 "dependencies": {
413 "deep-equal": {
414 "version": "1.0.1",
415 "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
416 "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
417 "dev": true
418 },
419 "defined": {
420 "version": "1.0.0",
421 "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
422 "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
423 "dev": true
424 },
425 "minimist": {
426 "version": "1.2.0",
427 "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
428 "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
429 "dev": true
430 }
431 }
432 },
433 "through": {
434 "version": "2.3.8",
435 "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
436 "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
437 "dev": true
438 },
439 "through2": {
440 "version": "0.2.3",
441 "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
442 "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
443 "dev": true,
444 "requires": {
445 "readable-stream": "~1.1.9",
446 "xtend": "~2.1.1"
447 }
448 },
449 "tslib": {
450 "version": "1.9.3",
451 "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
452 "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
453 "dev": true
454 },
455 "typescript": {
456 "version": "3.3.3",
457 "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.3.tgz",
458 "integrity": "sha512-Y21Xqe54TBVp+VDSNbuDYdGw0BpoR/Q6wo/+35M8PAU0vipahnyduJWirxxdxjsAkS7hue53x2zp8gz7F05u0A==",
459 "dev": true
460 },
461 "wrappy": {
462 "version": "1.0.2",
463 "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
464 "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
465 "dev": true
466 },
467 "xtend": {
468 "version": "2.1.2",
469 "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
470 "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
471 "dev": true,
472 "requires": {
473 "object-keys": "~0.4.0"
474 }
475 }
476 }
477 }
@@ -0,0 +1,25
1 {
2 "name": "${packageName}",
3 "version": "${version}",
4 "description": "${description}",
5 "main": "main.js",
6 "keywords": [
7 "di",
8 "ioc",
9 "logging",
10 "template engine",
11 "dependency injection"
12 ],
13 "author": "${author}",
14 "license": "${license}",
15 "repository": "$repository",
16 "publishConfig": {
17 "access": "public"
18 },
19 "peerDependencies": {
20 "dojo": "^1.10.0",
21 "@implab/core-amd": "^1.2.0"
22 },
23 "module": "${jsmodule}",
24 "target": "${target}"
25 } No newline at end of file
@@ -0,0 +1,37
1 {
2 "name": "@implab/web",
3 "version": "0.0.1-dev",
4 "description": "Simple web framework",
5 "main": "main.js",
6 "keywords": [
7 "di",
8 "ioc",
9 "logging",
10 "template engine",
11 "dependency injection"
12 ],
13 "author": "Implab team",
14 "license": "BSD-2-Clause",
15 "repository": "https://bitbucket.org/implab/implabjs",
16 "publishConfig": {
17 "access": "public"
18 },
19 "peerDependencies": {
20 "dojo": "^1.10.0",
21 "@implab/core-amd": "^1.2.15",
22 "tslib": "latest"
23 },
24 "devDependencies": {
25 "@types/node": "latest",
26 "@types/requirejs": "latest",
27 "@types/tape": "latest",
28 "@implab/core-amd": "^1.2.15",
29 "dojo": "^1.10.0",
30 "faucet": "latest",
31 "requirejs": "latest",
32 "tape": "^4.9.2",
33 "tslib": "latest",
34 "typescript": "latest"
35 },
36 "types": "main.d.ts"
37 }
@@ -0,0 +1,27
1 # Implabjs-core
2
3 Набор стандартных Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ для создания ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ со слоТным Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΠΎΠΌ.
4 Π”Π°Π½Π½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅
5 Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² срСдС Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠ², Ρ‚Π°ΠΊ ΠΈ Π² сСрвСрных срСдах.
6
7 Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° написана Π½Π° TypeScript, нСкоторая Ρ‡Π°ΡΡ‚ΡŒ Π½Π° JavaScript, Π½ΠΎ постСпСнно
8 планируСтся ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Π½Π° использованиС TypeScript
9
10 Π‘ΠΎΠ»Π΅Π΅ подробная докумСнтация доступна ΠΏΠΎ ссылкС: <https://bitbucket.org/implab/implabjs-core/src/default/docs/ru/>
11
12 ## ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹
13
14 ### DI
15
16 ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ для внСдрСния зависимостСй, позволяСт Π³ΠΈΠ±ΠΊΠΎ ΠΎΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ структуру
17 прилоТСния ΠΈ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ слабосвязанныС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹.
18
19 ### LOG
20
21 БрСдства Турналирования ΠΏΠΎΡ…ΠΎΠΆΠΈΠ΅ Π½Π° JLog, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ эффСктивно вСсти ΠΆΡƒΡ€Π½Π°Π»
22 выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.
23
24 ### Cancellations
25
26 Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Ρ‹ для ΠΎΡ‚ΠΌΠ΅Π½Ρ‹ асинхронных ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ с .NET
27 CancelationToken.
@@ -0,0 +1,15
1 /*
2 * This settings file was generated by the Gradle 'init' task.
3 *
4 * The settings file is used to specify which projects to include in your build.
5 * In a single project build this file can be empty or even removed.
6 *
7 * Detailed information about configuring a multi-project build in Gradle can be found
8 * in the user guide at https://docs.gradle.org/3.5/userguide/multi_project_builds.html
9 */
10
11 // To declare projects as part of a multi-project build use the 'include' method
12
13 //include 'sub-project-name'
14
15 rootProject.name = 'web' No newline at end of file
@@ -0,0 +1,167
1 define([
2 "dojo/_base/declare",
3 "dojo/_base/lang",
4 "dojo/when",
5 "cluster",
6 "os",
7 "implab/safe",
8 "./HttpResponse",
9 "./BaseResponse",
10 "dojo/Deferred",
11 "./HttpException",
12 "@implab/core/log/trace!"],
13 function (declare, lang, when, cluster, os, safe, HttpResponse, BaseResponse, Deferred, HttpException, trace) {
14 return declare(null, {
15 _container: null,
16 _serverPort: null,
17 _bindAddr: null,
18
19 _useCluster: null,
20
21 _requestConfig: null,
22 _restartFailedWorkers: null,
23
24 // ΠΌΠΎΠ΄ΡƒΠ»ΠΈ, ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ запрос.
25 _modules: null,
26 _handlers: null,
27
28 constructor: function (options) {
29 safe.argumentNotNull(options, "options");
30 safe.argumentNotNull(options.container, "options.container");
31 safe.argumentNotNull(options.serverPort, "options.serverPort");
32 safe.argumentNotNull(options.useCluster, "options.useCluster");
33 safe.argumentNotEmptyString(options.bindAddr, "options.bindAddr");
34 safe.argumentNotEmptyString(options.requestConfig, "options.requestConfig");
35
36 this.options = options || {};
37 this._modules = [];
38
39 this._container = options.container;
40
41 this._serverPort = options.serverPort;
42 this._bindAddr = options.bindAddr;
43 this._useCluster = options.useCluster;
44 this._restartFailedWorkers = options.restartFailedWorkers;
45
46 this._requestConfig = options.requestConfig;
47
48 this._container.getService("httpHandlers").forEach(handler => {
49 this.handle(handler);
50 });
51 },
52
53 start: function () {
54 let me = this;
55 const numCPUs = os.cpus().length;
56 if (cluster.isMaster && me._useCluster) {
57 // Fork workers.
58 for (let i = 0; i < numCPUs; i++) {
59 cluster.fork();
60 }
61
62 cluster.on('exit', function (worker, code, signal) {
63 if(me._restartFailedWorkers){
64 trace.log("worker {0} died. Signal {1}. Restarting ...", worker.process.pid, signal);
65 cluster.fork();
66 } else {
67 trace.log("worker {0} died.", worker.process.pid);
68 }
69 });
70 } else {
71 // Workers can share any TCP connection
72 // In this case it is an HTTP server
73 this.listen(this._serverPort, this._bindAddr);
74 }
75 },
76
77 listen: function (port, host) {
78 this._host = host;
79 this._port = port;
80
81 this._createServer(this.options, lang.hitch(this, "_handler")).listen(port, host, lang.hitch(this, "_listening"));
82 },
83
84 handle: function (module) {
85 if (module instanceof Function)
86 this._modules.push(module);
87 else if (module.invoke instanceof Function)
88 this._modules.push(function (req, next) {
89 return module.invoke(req, next);
90 });
91 else
92 throw "module shoud be a function or should have an invoke method";
93 },
94
95 _createServer: function () {
96 throw "NOT IMPLEMENTED";
97 },
98
99 _createRequest: function (container, req, res) {
100 return container.configure(this._requestConfig)
101 .then(function () {
102 let httpRequest = container.getService("httpRequest");
103 httpRequest.init(req, res);
104 return httpRequest;
105 });
106 },
107
108 //handler function to pass to the approperate server (like node.http)
109 _handler: function (req, res) {
110 let i = 0;
111 let me = this;
112
113 let requestContainer = this._container.createChildContainer();
114
115 when(this._createRequest(requestContainer, req, res), function (httpRequest) {
116 let next = function () {
117 if (i < me._modules.length) {
118 let module = me._modules[i];
119 i++;
120 try {
121 return when(module(httpRequest, next));
122 } catch (err) {
123 let d = new Deferred();
124 d.reject(err);
125 return d;
126 }
127 }
128 };
129
130 when(next(), function (result) {
131 if (!result)
132 throw "no response is provided, this is a serious bug";
133
134 if (result instanceof BaseResponse) {
135 result.send(res);
136 } else {
137 let httpResp = new HttpResponse();
138 httpResp.content = "BUG: " + result.toString();
139 httpResp.send(res);
140 }
141 requestContainer.dispose();
142 }).then(null, function (err) {
143 if (res.finished) {
144 trace.log("caught exception after the response is sent: {0}", err);
145 return;
146 }
147 let httpResp;
148 if (err instanceof HttpException)
149 httpResp = new HttpResponse(err.message, {
150 statusCode: err.code,
151 headers: err.headers
152 });
153 else
154 httpResp = new HttpResponse(err.toString(), {
155 statusCode: 500
156 });
157 httpResp.send(res);
158 requestContainer.dispose();
159 });
160 });
161 },
162 _listening: function () {
163 trace.log("Listening {0}:{1}", this._host, this._port);
164 },
165
166 });
167 }); No newline at end of file
@@ -0,0 +1,7
1 define([ "dojo/_base/declare"], function(declare) {
2 return declare(null, {
3 send : function(/*serverResponse*/) {
4 throw "NOT IMPLEMENTED";
5 }
6 });
7 }); No newline at end of file
@@ -0,0 +1,22
1 define(["dojo/_base/declare", "dojo/when", "./BaseResponse", "./ModelResponse"],function(declare,when, BaseResponse, ModelResponse) {
2 return declare(null,{
3 invoke: function(httpRequest, next) {
4 return when(next(), function(result) {
5 if (!(result instanceof BaseResponse) ){
6 result = new ModelResponse(result);
7 }
8
9 if (!(result instanceof ModelResponse))
10 return result;
11
12 result.presenter = {
13 present: JSON.stringify,
14 contentType: "application/json; charset=utf-8"
15 };
16
17 // TODO select presenter and assing it to result.presenter
18 return result;
19 });
20 }
21 });
22 }); No newline at end of file
@@ -0,0 +1,206
1 define([ "dojo/_base/declare", "dojo/_base/lang" ], function(declare, lang) {
2 let cls = declare(null, {
3 type : null,
4 subtype : null,
5 parameters: null,
6
7 constructor: function(media,parameters) {
8 if (!media)
9 throw "A media must be specified";
10 media = media.toString();
11 let parts = media.match(/^([a-zA-Z-]+)\/([a-zA-Z\-+]+)$/);
12 if(!parts)
13 throw "An invalid media type supplied";
14 this.type = parts[1];
15 this.subtype = parts[2];
16 this.parameters = parameters || {};
17 },
18
19 toString : function() {
20 let res = [this.type,'/',this.subtype];
21 for(var p in this.parameters) {
22 res.push('; ');
23 res.push(p);
24 res.push('=');
25 res.push(this._escapeValue(this.parameters[p]));
26 }
27
28 return res.join('');
29 },
30
31 _escapeValue : function(value) {
32 if (value) {
33 value = value.toString();
34 if(value.match(/[()<>@,:;\\".[\]]/))
35 return '"' + value.replace(/[()<>@,:;\\".[\]]/g, function(x) { return "\\"+ x; } ) + '"';
36 }
37 return value;
38 }
39
40 });
41
42 let parseSpace = function(text,start) {
43 for(var i = start; i < text.length; i++) {
44 if(!text[i].match(/\s/))
45 break;
46 }
47 return {
48 pos: i
49 };
50 };
51
52 let parseToken = function(text,start,required) {
53 let token = [];
54 for(var i=start; i< text.length; i++) {
55 let char = text[i];
56 if (!char.match(/[\w-]/))
57 break;
58 token.push(char);
59 }
60
61 if (required && token.length == 0) {
62 if (i == text.length)
63 throw new Error("Unexpected end of line");
64 else
65 throw lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[i], pos: i});
66 }
67
68 return {
69 value : token.join(''),
70 pos : i
71 };
72 };
73
74
75 let parseMedia = function(text,start) {
76 let type, subtype;
77 let t = parseToken(text,start,true);
78
79 type = t.value;
80 start = t.pos;
81
82 if (text[start] != '/')
83 throw lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[start], pos: start});
84 start++;
85
86 t = parseToken(text,start,true);
87 subtype = t.value;
88 start = t.pos;
89
90 return {
91 value: {
92 type : type,
93 subtype: subtype
94 },
95 pos : start
96 };
97 };
98
99 let parseLiteral = function(text,pos,required) {
100 let data = [];
101 let escape, stop;
102 for(var i=pos; (i < text.length) && !stop; i++) {
103 if (escape) {
104 data.push(text[i]);
105 escape = false;
106 } else {
107 switch(text[i]) {
108
109 case '"':
110 if (pos != i)
111 stop = true;
112 break;
113 case '\\':
114 escape = true;
115 break;
116 default:
117 if (pos == i) {
118 stop = true;
119 i--;
120 } else {
121 data.push(text[i]);
122 }
123 }
124 }
125 }
126
127 if(required && data.length == 0)
128 new lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[i], pos: i});
129
130 return {
131 value : data.join(''),
132 pos : i
133 };
134 };
135
136 let parseParam = function(text,pos) {
137 let t,name,value;
138 t = parseToken(text,pos,true);
139
140 name = t.value;
141 pos = t.pos;
142
143 t = parseSpace(text,pos);
144 pos = t.pos;
145
146 if (text[pos] != '=')
147 throw lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[pos], pos: pos});
148 pos++;
149
150 t = parseSpace(text,pos);
151 pos = t.pos;
152
153 t = parseToken(text,pos,false);
154 if (t.pos != pos) {
155 value = t.value;
156 pos = t.pos;
157 } else {
158 t = parseLiteral(text,pos,false);
159 if (t.pos == pos)
160 throw lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[pos], pos: pos});
161 pos = t.pos;
162 value = t.value;
163 }
164
165 return {
166 value : {
167 name : name,
168 value : value
169 },
170 pos : pos
171 };
172 };
173
174 cls.parse = function(text) {
175 let t,pos = 0, media, params = {};
176 t = parseMedia(text,pos);
177 media = t.value;
178 pos = t.pos;
179
180
181 while(pos < text.length) {
182 t = parseSpace(text,pos);
183 pos = t.pos;
184
185 if (pos < text.length) {
186 if(text[pos] == ';') {
187 pos ++;
188 t = parseSpace(text,pos);
189 pos = t.pos;
190
191 t = parseParam(text,pos);
192
193 params[t.value.name] = t.value.value;
194 pos = t.pos;
195
196 } else {
197 throw lang.replace("Unexpected char '{char}' at '{pos}'", { char: text[pos], pos: pos});
198 }
199 }
200 }
201
202 return new cls( media.type + '/' + media.subtype, params );
203 };
204
205 return cls;
206 }); No newline at end of file
@@ -0,0 +1,238
1 /**
2 *
3 */
4 define(["dojo/_base/declare", "dojo/_base/lang", "implab/safe"], function (declare, lang, safe) {
5
6
7 var formats = {
8 "base64+json": {
9 encode: function (data) {
10 return new Buffer(JSON.stringify(data)).toString('base64');
11 },
12 decode: function (data) {
13 try {
14 return JSON.parse(new Buffer(data, 'base64').toString());
15 } catch (err) {
16 return null;
17 }
18 }
19 },
20 "base64": {
21 encode: function (data) {
22 if (!safe.isPrimitive(data))
23 throw new Error("Can'n serialize a complex data");
24 return new Buffer(data).toString('base64');
25 },
26 decode: function (data) {
27 return new Buffer(data, 'base64').toString();
28 },
29 },
30 "simple": {
31 encode: function (data) {
32 if (!safe.isPrimitive(data))
33 throw new Error("Can'n serialize a complex data");
34 return safe.isNull(data) ? "" : data.toString();
35 },
36 decode: function (data) {
37 return data;
38 }
39 }
40 };
41
42 let args = {
43 secure: false,
44 httpOnly: false,
45 path: null,
46 domain: null,
47 maxAge: null,
48 expires: null,
49 extension: null,
50 format: null
51 };
52
53 let Cookie = declare(null, {
54 secure: false,
55 httpOnly: false,
56 path: null,
57 name: null,
58 domain: null,
59 maxAge: null,
60 expires: null,
61 extension: null,
62 value: null,
63 format: "base64+json",
64 _createTime: null,
65
66 constructor: function (name, value, opts) {
67 safe.argumentNotEmptyString(name, "name");
68
69 if (opts) {
70 for (let i in opts)
71 if (i in args)
72 this[i] = opts[i];
73 }
74
75 this.name = name;
76 this.value = value;
77 this._createTime = new Date();
78 },
79
80 isExpired: function () {
81 let expires;
82 if (this.maxAge) {
83 let dt = this.getNormalMaxAge();
84 expires = new Date(this._createTime.getTime() + dt * 1000);
85 } else if (this.expires) {
86 expires = new Date(this.expires);
87 }
88
89 return (expires && new Date() > expires);
90 },
91
92 getNormalMaxAge: function () {
93 if (safe.isNull(this.maxAge))
94 return null;
95 if (safe.isNumber(this.maxAge))
96 return Math.round(this.maxAge);
97
98 let norm = Number(this.maxAge);
99
100 if (norm == this.maxAge)
101 return Math.round(norm);
102
103 let parts = this.maxAge.toString().match("^(?:(\\d+)d)?(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$");
104 if (parts) {
105 let factor = [0, 86400, 3600, 60, 1];
106 norm = 0;
107 for (let i = 1; i < parts.length; i++) {
108 norm += factor[i] * (Number(parts[i]) || 0);
109 }
110 } else {
111 norm = null;
112 }
113
114 return norm;
115 },
116
117 toString: function () {
118 let data = [];
119
120 let pair = function (name, value, enc) {
121 if (!safe.isNullOrEmptyString(value))
122 data.push([name, enc ? enc(value) : value].join('='));
123 };
124
125 let flag = function (name, isSet) {
126 if (isSet)
127 data.push(name);
128 };
129
130 pair(this.name, this.value, this.format ? Cookie.formats[this.format].encode : null);
131 pair("Expires", this.expires, function (d) {
132 return new Date(d).toUTCString();
133 });
134 pair("Max-Age", this.getNormalMaxAge());
135 pair("Domain", this.domain);
136 pair("Path", this.path);
137 flag("Secure", this.secure);
138 flag("HttpOnly", this.httpOnly);
139 flag(this.extension, this.extension);
140
141 return data.join('; ');
142 }
143
144 });
145
146 /**
147 * ΠŸΠ°Ρ€ΡΠΈΡ‚ строку с ΠΏΠ΅Ρ‡Π΅Π½ΡŒΠΊΠ°ΠΌΠΈ ΠΈΠ· HTTP Π·Π°Π³ΠΎΠ»ΠΎΠΊΠ° Cookies
148 *
149 * @return Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ ΠΏΠ΅Ρ‡Π΅Π½Π΅ΠΊ Π² Π²ΠΈΠ΄Π΅ { "cookie-name" : {
150 * value='raw%20data', decode : function(format) {} } }
151 *
152 */
153 Cookie.parseHeaderValue = function (str) {
154 safe.argumentNotEmptyString(str, "str");
155
156 let pairs = str.split(/;\s*/);
157 let cookies = {};
158
159 for (let i in pairs) {
160 let pair = pairs[i];
161 let idx = pair.indexOf('=');
162 if (idx >= 0) {
163 cookies[pair.substring(0, idx)] = {
164 value: pair.substring(idx + 1),
165 decode: function (format) {
166 if (!format)
167 format = "simple";
168
169 if (!formats[format])
170 throw new Error("The specified format '" + format + "' is unsupported");
171 let decode = formats[format].decode;
172
173 return decode(this.value);
174 }
175 };
176 }
177 }
178
179 return cookies;
180
181 };
182
183 Cookie.formats = formats;
184
185 Cookie.parse = function (str, format) {
186 safe.argumentNotEmptyString(str, "str");
187 if (!format)
188 format = "simple";
189
190 if (!formats[format])
191 throw new Error("The specified format '" + format + "' is unsupported");
192
193 let pairs = str.split(/;\s*/);
194 let options = {
195 format: format
196 };
197
198 let cookieName, cookieValue, first = true;
199
200 let map = {
201 "Expires": "expires",
202 "Max-Age": "maxAge",
203 "Domain": "domain",
204 "Path": "path",
205 "Secure": "secure",
206 "HttpOnly": "httpOnly"
207 };
208
209 for (let i in pairs) {
210 let pair = pairs[i];
211 let idx = pair.indexOf('=');
212
213 if (idx >= 0) {
214
215 let name = pair.substring(0, idx);
216 let value = pair.substring(idx + 1);
217
218 if (first) {
219 cookieName = name;
220 cookieValue = value;
221 first = false;
222 } else {
223 if (name in map)
224 options[map[name]] = value;
225 }
226 } else {
227 if (pair in map)
228 options[map[pair]] = true;
229 else
230 options.extension = pair;
231 }
232 }
233
234 return new Cookie(cookieName, cookieValue, options);
235 };
236
237 return Cookie;
238 }); No newline at end of file
@@ -0,0 +1,6
1 define(["dojo/_base/declare", "./HttpException"], function (declare, httpException) {
2 return declare([httpException], {
3 code: 403,
4 message: "Forbidden"
5 });
6 });
@@ -0,0 +1,9
1 define(["dojo/_base/declare","./HttpResponse"],function(declare,HttpResponse) {
2 return declare(null,{
3 invoke: function(/*httpRequest, next*/) {
4 return new HttpResponse("Hello, world!",{
5 contentType : "text/plain; charset=utf-8"
6 });
7 }
8 });
9 }); No newline at end of file
@@ -0,0 +1,11
1 define([
2 "dojo/_base/declare",
3 "./BaseApplication",
4 "dojo/node!http"
5 ], function(declare, base, http) {
6 return declare(base, {
7 _createServer : function(options, handler) {
8 return http.createServer(handler);
9 }
10 });
11 }); No newline at end of file
@@ -0,0 +1,7
1 define(["dojo/_base/declare"], function (declare) {
2 return declare(null, {
3 code: 500,
4 message: "Internal server error",
5 headers: null
6 });
7 });
@@ -0,0 +1,123
1 define([
2 "dojo/_base/declare",
3 "dojo/Deferred",
4 "url",
5 "implab/safe",
6 "./Cookie",
7 "./ContentType",
8 "implab/log/trace!"], function (declare, Deferred, url, safe, Cookie, ContentType, trace) {
9 return declare([], {
10
11 // http.IncommingMessage
12 message: null,
13
14 response: null,
15
16 session: null,
17
18 cookieFormat: "base64+json",
19 _contentType: null,
20 _container: null,
21 _initialised: false,
22
23 constructor: function (options) {
24 safe.argumentNotNull(options, "options");
25 safe.argumentNotNull(options.container, "options.container");
26 this._container = options.container;
27
28 trace.log("Request created");
29 },
30
31 init: function (message, response) {
32 safe.argumentNotNull(message, "message");
33
34 this.message = message;
35 this.method = message.method;
36 this.path = url.parse(message.url, true, true).pathname;
37
38 this.response = response;
39
40 this._initialised = true;
41 },
42
43 _checkInit: function () {
44 if(!this._initialised){
45 throw new Error("Request is not initialised. 'init' function should be called");
46 }
47 },
48
49 getService: function (service) {
50 return this._container.getService(service);
51 },
52
53 getContainer: function () {
54 return this._container;
55 },
56
57 getRemoteAddress: function () {
58 return this.message.socket.remoteAddress;
59 },
60
61 readAllText: function (encoding) {
62 this._checkInit();
63 if (!encoding)
64 encoding = this.getContentType().parameters.charset || 'utf8';
65 this.message.setEncoding(encoding);
66
67 let d = new Deferred();
68
69 let chunks = [];
70
71 this.message.on('data', function (chunk) {
72 chunks.push(chunk);
73 });
74 this.message.on('end', function () {
75 d.resolve(chunks.join(''));
76 });
77 this.message.on('error', function (e) {
78 d.reject(e);
79 });
80 return d;
81 },
82
83 header: function (name) {
84 safe.argumentNotEmptyString(name, "name");
85 this._checkInit();
86
87 return this.message.headers[name.toLowerCase()];
88 },
89
90 getContentType: function () {
91 this._checkInit();
92 if (safe.isNull(this._contentType))
93 this._contentType = ContentType.parse(this.header('Content-Type'));
94 return this._contentType;
95 },
96 /** Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ‡Π΅Π½ΡŒΠΊΠΈ ΠΈΠ· запроса.
97 * @name Имя ΠΏΠ΅Ρ‡Π΅Π½ΡŒΠΊΠΈ
98 * @format Π€ΠΎΡ€ΠΌΠ°Ρ‚ значСния, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ json+base64
99 * @return ΠžΠ±ΡŠΠ΅ΠΊΡ‚ со Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΏΠ΅Ρ‡Π΅Π½ΡŒΠΊΠΈ
100 */
101 cookie: function (name, format) {
102 safe.argumentNotEmptyString(name, "name");
103 this._checkInit();
104
105 if (!format)
106 format = this.cookieFormat;
107
108 if (safe.isNull(this._cookies)) {
109 let cookiesHeader = this.header("Cookie");
110 if (!safe.isNullOrEmptyString(cookiesHeader))
111 this._cookies = Cookie.parseHeaderValue(cookiesHeader);
112 else
113 this._cookies = {};
114 }
115
116 let cookie = this._cookies[name];
117 if (safe.isNull(cookie))
118 return null;
119
120 return cookie.decode(format);
121 }
122 });
123 }); No newline at end of file
@@ -0,0 +1,137
1 define([ "dojo/_base/declare", "dojo/_base/lang", "implab/safe" ,"./ContentType", "./BaseResponse", "./Cookie" ], function(declare, lang,safe, ContentType, BaseResponse, Cookie) {
2 return declare(BaseResponse, {
3 statusCode : 0,
4 _headers : null,
5 content : null,
6 _contentType : null,
7 _cookies : null,
8
9 getContentType : function() {
10 return this._contentType;
11 },
12
13 setContentType : function(value) {
14 if (value) {
15 this._contentType = value instanceof ContentType ? value : ContentType.parse(value.toString());
16 this._headers["Content-Type"] = this._contentType.toString();
17 } else {
18 this._contentType = null;
19 delete this._headers["Content-Type"];
20 }
21 this._headers["Content-Type"] = value ? value.toString() : value;
22 },
23
24 /**
25 * ЗаписываСт cookies
26 * @cookie {String|Cookie} ΠΏΠ΅Ρ‡Π΅Π½ΡŒΠΊΠ° ΠΈΠ»ΠΈ имя ΠΏΠ΅Ρ‡Π΅Π½ΡŒΠΊΠΈ ΠΈΠ»ΠΈ ΠΏΠ΅Ρ‡Π΅Π½ΡŒΠΊΠ° сохранСнная Π² строку.
27 * @value? {*} Ссли {cookie} строка с ΠΈΠΌΠ΅Π½Π΅ΠΌ, Ρ‚ΠΎ Π² этом ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π΅ пСрСдаСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
28 * @options? {Object} Ссли {cookie} строка с ΠΈΠΌΠ΅Π½Π΅ΠΌ, Ρ‚ΠΎ Π² этом ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ свойства ΠΏΠ΅Ρ‡Π΅Π½Π΅ΠΊ.
29 */
30 setCookie : function(cookie /*, value, options*/) {
31 if (arguments.length == 1) {
32 if (safe.isString(cookie))
33 cookie = Cookie.parse(cookie);
34 safe.argumentOfType(cookie, Cookie, "cookie");
35 this._cookies[cookie.name] = cookie;
36 } else {
37 safe.argumentNotEmptyString(cookie,"cookie");
38 let value = arguments[1];
39 let options = arguments[2];
40
41 let cc = new Cookie(cookie,value,options);
42
43 this._cookies[cc.name] = cc;
44 }
45 },
46
47 _setCookies : function(cookies) {
48 if (!(cookies instanceof Array))
49 cookies = [cookies];
50 let me = this;
51 cookies.forEach(function(cookie){
52 me.setCookie(cookie);
53 });
54 },
55
56 forgetCookie : function(name) {
57 this.setCookie(new Cookie(name,"__erased__", { maxAge : 0 }));
58 },
59
60 setHeader : function(name, value) {
61 if (!name)
62 throw "A name is requried";
63 name = this._normalizeHeaderName(name);
64
65 if (name == "Content-Type")
66 this.setContentType(value);
67 if (name == "Set-Cookie")
68 this._setCookies(value);
69 else
70 this._headers[name] = value;
71 },
72
73 getHeader : function(name) {
74 if (!name)
75 throw "A name is requried";
76 name = this._normalizeHeaderName(name);
77
78 return this._headers[name];
79 },
80
81 _normalizeHeaderName : function(name) {
82 return name.toLowerCase().replace(/\b\w/g, function(s) {
83 return s.toUpperCase();
84 });
85 },
86
87 constructor : function(content, options) {
88 this._headers = {};
89 this._cookies = {};
90
91 this.content = content;
92 this.statusCode = content ? 200 : 203;
93
94 if (options) {
95 if ("statusCode" in options)
96 this.statusCode = options.statusCode;
97 if ("headers" in options) {
98 for ( let header in options.headers)
99 this.setHeader(header, options.headers[header]);
100 }
101 if ("contentType" in options)
102 this.setContentType(options.contentType);
103 }
104 },
105
106 send : function(serverResponse) {
107 if (!serverResponse)
108 throw "ServerResponse is required";
109
110 this.writeHead(serverResponse);
111
112 this.writeEntity(serverResponse);
113
114 serverResponse.end();
115 },
116
117 writeHead : function(serverResponse) {
118 let headers = lang.clone(this._headers);
119 let cookies = [];
120 for (let key in this._cookies)
121 cookies.push(this._cookies[key].toString());
122 headers["Set-Cookie"] = cookies;
123
124 serverResponse.writeHead(this.statusCode, headers);
125 },
126
127 writeEntity : function(serverResponse) {
128 if (this.content instanceof Function) {
129 this.content(serverResponse);
130 } else if (this.content) {
131 serverResponse.write(this.content, this._contentType ? this._contentType.parameters.charset : undefined);
132 }
133 }
134
135
136 });
137 }); No newline at end of file
@@ -0,0 +1,93
1 define([], function() {
2 return {
3 application : {
4 atom: 'application/atom+xml',
5 json : 'application/json',
6 javascript: 'application/javascript',
7 octetStream: 'application/octet-stream',
8 ogg: 'application/ogg',
9 pdf: 'application/pdf',
10 soap: 'application/soap+xml',
11 xhtml: 'application/xhtml+xml',
12 dtd: 'application/xml-dtd',
13 zip: 'application/zip',
14 gzip: 'application/x-gzip',
15 form: 'application/x-www-form-urlencoded',
16 ttf: 'application/x-font-ttf',
17 tar: 'application/x-tar',
18 pkcs12: 'application/x-pkcs12',
19 pfx: 'application/x-pkcs12',
20 spc: 'application/x-pkcs7-certificates',
21 p7b: 'application/x-pkcs7-certificates',
22 p7r: 'application/x-pkcs7-certreqresp',
23 p7c: 'application/x-pkcs7-mime',
24 p7s: 'application/x-pkcs7-signature'
25 },
26 audio : {
27 mulaw: 'audio/basic',
28 pcm24: 'audio/L24',
29 mp4: 'audio/mp4',
30 mp3: 'audio/mpeg',
31 mpeg: 'audio/mpeg',
32 ogg: 'audio/ogg',
33 vorbis: 'audio/vorbis',
34 wma: 'audio/x-ms-wma',
35 wmaRedirect: 'audio/x-ms-wax',
36 realAudio: 'audio/vnd.rn-realaudio',
37 wav: 'audio/vnd.wave',
38 webm: 'audio/webm'
39 },
40 image: {
41 gif: 'image/gif',
42 jpeg: 'image/jpeg',
43 msJpeg: 'image/pjpeg',
44 png: 'image/png',
45 svg: 'image/svg+xml',
46 tiff: 'image/tiff',
47 ico: 'image/vnd.microsoft.icon',
48 wbmp: 'image/vnd.wap.wbmp',
49 bmp: 'image/bmp'
50 },
51 message : {
52 http: 'message/http',
53 imdn: 'message/imdn+xml',
54 emailPartial: 'message/partial',
55 email: 'message/rfc822'
56 },
57 model : {
58 example: 'model/example',
59 iges: 'model/iges',
60 mesh: 'model/mesh',
61 vrml: 'model/vrml',
62 x3db: 'model/x3d+binary',
63 x3dv: 'model/x3d+vrml',
64 x3d: 'model/x3d+xml'
65 },
66 multipart: {
67 mixed: 'multipart/mixed',
68 alternative: 'multipart/alternative',
69 related: 'multipart/related',
70 form: 'multipart/form-data',
71 signed: 'multipart/signed',
72 encrypted: 'multipart/encrypted'
73 },
74 text : {
75 cmd: 'text/cmd',
76 css: 'text/css',
77 csv: 'text/csv',
78 html: 'text/html',
79 plain: 'text/plain',
80 xml: 'text/xml'
81 },
82 video: {
83 mpeg: 'video/mpeg',
84 mp4: 'video/mp4',
85 ogg: 'video/ogg',
86 quicktime: 'video/quicktime',
87 webm: 'video/webm',
88 wmv: 'video/x-ms-wmv',
89 flv: 'video/x-flv'
90 }
91
92 };
93 }); No newline at end of file
@@ -0,0 +1,29
1 define([ "dojo/_base/declare", "./HttpResponse" ], function(declare, HttpResponse) {
2 return declare(HttpResponse, {
3 presenter : null,
4
5 constructor : function(model, options) {
6 if (options && options.presenter)
7 this.presenter = options.presenter;
8 },
9
10 send : function() {
11 console.log("try to present: " + this.content);
12 if (!this.presenter)
13 throw "The presenter isn't specified for the model '" + this.content + "'";
14
15 if (this.statusCode != 203 && this.presenter.contentType)
16 this.setHeader("Content-type", this.presenter.contentType);
17
18 this.inherited(arguments);
19
20 },
21
22 writeEntity : function(serverResponse) {
23 if (this.statusCode == 203)
24 return;
25
26 serverResponse.write(this.presenter.present(this.content), this.getContentType() ? this.getContentType().parameters.charset : undefined);
27 }
28 });
29 }); No newline at end of file
@@ -0,0 +1,6
1 define(["dojo/_base/declare", "./HttpException"], function (declare, httpException) {
2 return declare([httpException], {
3 code: 405,
4 message: "Method Not Allowed"
5 });
6 });
@@ -0,0 +1,6
1 define(["dojo/_base/declare", "./HttpException"], function (declare, httpException) {
2 return declare([httpException], {
3 code: 404,
4 message: "Not found"
5 });
6 });
@@ -0,0 +1,129
1 define([
2 "dojo/_base/declare",
3 "dojo/_base/lang",
4 "dojo/when",
5 "implab/safe",
6 "./NotAllowedException",
7 "./HttpResponse"
8 ], function (
9 declare,
10 lang,
11 when,
12 safe,
13 NotAllowedException,
14 HttpResponse
15 ) {
16 let resource = declare(null, {
17
18 // instance members
19 request: null,
20
21 // Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ рСсурс
22 parent: null,
23
24 // имя Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ рСсурса, являСтся Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ΠΎΠΌ ΠΏΡƒΡ‚ΠΈ ΠΊ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌΠΎΠΌΡƒ
25 // рСсурсу
26 name: null,
27
28 allowedMethods: {
29 "head": 0,
30 "options": 0,
31 "get": 0,
32 "post": 0,
33 "put": 1, // extended method
34 "delete": 1 // extended method
35 },
36
37 constructor: function (options) {
38 if (options) {
39 declare.safeMixin(this, options);
40 }
41 },
42
43 accessCheck: null,
44
45 getAllowedMethods: function (cors) {
46 let methods = [];
47 for (var m in this.allowedMethods) {
48 if (m in this && (cors && this.allowedMethods[m] || !cors))
49 methods.push(m.toUpperCase());
50 }
51 return methods;
52 },
53
54 options: function () {
55 let resp = new HttpResponse(null, {
56 headers: {
57 "Access-Control-Allow-Methods": this.getAllowedMethods(true),
58 "Allowed-Methods": this.getAllowedMethods()
59 }
60 });
61 return resp;
62 },
63
64 invoke: function () {
65 let method = this.request.method.toLowerCase();
66
67 let me = this;
68
69 if (!(method in this)) {
70 throw new NotAllowedException(); // TODO: Π’ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ список Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² (verbs)
71 }
72
73 if (!safe.isNull(this.accessCheck)) {
74 return when(this.request.session, function (session) {
75 me.session = session;
76 return when(me.accessCheck(), function () {
77 return me[method]();
78 });
79 }, function (err) {
80 console.log(err);
81 throw err;
82 });
83 } else {
84 return this[method]();
85 }
86 },
87
88 render: function (view, model, mimeType) {
89 return function (resp) {
90 if (mimeType)
91 resp.type(mimeType);
92 resp.render(view, {
93 model: model
94 });
95 };
96
97 },
98
99 getChild: function (name) {
100 if (this.children && name in this.children) {
101 let child = this.children[name];
102
103 if (typeof child == "function") {
104 return child({
105 request: this.request,
106 parent: this,
107 name: name
108 });
109 } else if (child.hasOwnProperty("isInstanceOf") && child.isInstanceOf(resource)) {
110 return lang.mixin(child, {
111 request: this.request,
112 parent: this,
113 name: name
114 });
115 } else {
116 return new resource(lang.mixin(child, {
117 request: this.request,
118 parent: this,
119 name: name
120 }));
121 }
122 } else {
123 return null;
124 }
125 }
126 });
127
128 return resource;
129 }); No newline at end of file
@@ -0,0 +1,50
1 define([
2 "dojo/_base/declare",
3 "dojo/_base/lang",
4 "dojo/when",
5 "./NotFoundException",
6 "./HttpException",
7 "./Resource",
8 "implab/safe"
9 ],
10 function (declare, lang, when, notFoundException, httpException, resource, safe) {
11
12 return declare([], {
13 _resourcesConfig: null,
14
15 constructor: function (options) {
16 safe.argumentNotNull(options, "options");
17 safe.argumentNotNull(options.resourcesConfig, "options.resourcesConfig");
18
19 this._resourcesConfig = options.resourcesConfig;
20 },
21
22 createResource: function (req) {
23 let container = req.getContainer();
24 return container.configure(this._resourcesConfig)
25 .then(function(){
26 let rc = container.getService("resource");
27
28 if(rc.hasOwnProperty("isInstanceOf") && rc.isInstanceOf(resource)) {
29 return rc;
30 } else {
31 return new resource(lang.mixin(rc,{request: req}));
32 }
33 });
34 },
35
36 invoke: function (req/*, next*/) {
37 return when(this.createResource(req), function (rc) {
38 req.path.split(/\/+/).forEach(function (child) {
39 if (child) {
40 rc = rc.getChild(child);
41 if (!rc) {
42 throw new notFoundException();
43 }
44 }
45 });
46 return rc.invoke();
47 });
48 }
49 });
50 });
@@ -0,0 +1,23
1 define([ "dojo/_base/declare", "./BaseResponse" ], function(declare, BaseResponse) {
2 /**
3 * Π—Π°Π³Π»ΡƒΡˆΠΊΠ° вмСсто ΠΎΡ‚Π²Π΅Ρ‚Π° сСрвСра, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΡ€ΠΈ использовании "Ρ€ΠΎΠ΄Π½Ρ‹Ρ…" ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ
4 * node, Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‰ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ с ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠΌ, для Ρ‡Π΅Π³ΠΎ Ρƒ HttpRequest Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ
5 * свйоство response, Π° вмСсто ΠΎΡ‚Π²Π΅Ρ‚Π° возвращаСтся Π·Π°Π³Π»ΡƒΡˆΠΊΠ°.
6 */
7 return declare(BaseResponse, {
8 _serverResponse : null,
9
10 constructor : function(serverResponse) {
11 this._serverResponse = serverResponse;
12 },
13
14 setHeader : function() {
15 this._serverResponse.setHeader.apply(this._serverResponse, arguments);
16 },
17
18 send : function(serverResponse) {
19 if (!serverResponse.finished)
20 serverResponse.end();
21 }
22 });
23 }); No newline at end of file
@@ -0,0 +1,18
1 /**
2 * Created by internet on 6/21/16.
3 */
4 'user strict';
5 /*=====
6 return {
7 // summary:
8 // The implab package main module; implab package is somewhat unusual in that the main module currently just provides an empty object.
9 // Apps should require modules from the implab packages directly, rather than loading this module.
10 };
11 =====*/
12
13 /**
14 The entry point
15 @module implab
16 */
17
18 module.exports = {}; No newline at end of file
@@ -0,0 +1,13
1 /**
2 * Created by andrei on 22.08.16.
3 */
4 define(['dojo/_base/declare'], function(declare){
5 let AuthCode = declare(null, {
6 });
7
8 AuthCode.SUCCSESS = 0;
9 AuthCode.INCMPLETE = 1;
10 AuthCode.FAIL = 2;
11
12 return AuthCode;
13 });
@@ -0,0 +1,93
1 /**
2 * ΠœΠΎΠ΄ΡƒΠ»ΡŒ, ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‰ΠΈΠΉ Π·Π° созданиС контСкста бСзопасности (сСссии).
3 *
4 * Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ сСссии сохраняСтся Π² ΠΏΠ΅Ρ‡Π΅Π½ΡŒΠΊΠ°Ρ… Π½Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅.
5 */
6 define([
7 "dojo/_base/declare",
8 "dojo/when",
9 "implab/safe",
10 "../Cookie",
11 "../security/SecData",
12 "../BaseResponse",
13 "implab/log/trace!"
14 ], function (declare, when, safe, Cookie, SecData, BaseResponse, trace) {
15 let COOKIE_NAME = "ssid";
16
17 return declare(null, {
18 _request : null,
19 _provider : null,
20 _cookies : null,
21 _sessionData: null,
22
23 constructor : function(options) {
24 safe.argumentNotNull(options, "options");
25 safe.argumentNotNull(options.securityProvider, "options.securityProvider");
26 safe.argumentNotNull(options.request, "options.request");
27
28 this._request = options.request;
29 this._provider = options.securityProvider;
30 this._cookies = [];
31 },
32
33 /**
34 * ВызываСтся ΠΈΠ· {SecurityHandler} ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ запроса.
35 *
36 * @resp ΠΎΡ‚Π²Π΅Ρ‚ сСрвСра
37 */
38 completeRequest : function(resp) {
39 trace.log("completeRequest");
40 if (resp instanceof BaseResponse)
41 this._cookies.forEach(function(cookie) {
42 resp.setCookie(cookie);
43 });
44 if (!safe.isNull(this._sessionData))
45 return this._sessionData.save().then(function () {
46 return resp;
47 });
48 return resp;
49 },
50
51 handleError : function(err) {
52 throw err;
53 },
54
55 initSession : function(userIdentity) {
56 safe.argumentNotNull(userIdentity, "userIdentity");
57 let me = this;
58
59 return when(me._provider.getSessions().createSession(userIdentity, SecData.newSSID()), function(session) {
60 if (!session) {
61 throw new Error("Can`t init session");
62 }
63
64 me._sessionData = session;
65 trace.log("Created session {0} for user {1}", session.sessionId, userIdentity.getUser().login);
66 me._cookies.push(new Cookie(COOKIE_NAME,session.sessionId));
67 return session;
68 });
69 },
70
71 /* aync */
72 getSession : function() {
73 let cookie;
74 let me = this;
75 try {
76 cookie = this._request.cookie(COOKIE_NAME);
77
78 if (!cookie)
79 return null;
80
81 return when(me._provider.getSessions().getSession(cookie), function(session) {
82 me._sessionData = session;
83 return session;
84 });
85 } catch (e) {
86 trace.log("getSession: {0}", e);
87 return null;
88 }
89 }
90
91 });
92
93 }); No newline at end of file
@@ -0,0 +1,81
1 /**
2 * @class Identity идСнтификационная информация (удостовСрСниС) ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.
3 * ΠžΠΏΠΈΡΡ‹Π²Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΈ способ Π΅Π³ΠΎ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π² систСмС. Π”Π°Π½Π½Ρ‹ΠΉ
4 * класс являСтся Π·Π°Π³Π»ΡƒΡˆΠΊΠΎΠΉ, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰Π΅ΠΉ интСрфСйс, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚
5 * ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для создания ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠ½Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ.
6 */
7 define([
8 "dojo/_base/declare",
9 "implab/safe",
10 "./SecData"
11 ], function (declare, safe, SecData) {
12 let identity = declare(null, {
13 _user : null,
14
15 _isAnonymous : null,
16
17 _secData : null,
18
19 constructor : function(user, opts) {
20 this._user = user;
21 safe.mixin(this, opts, {
22 isAnonymous : '_isAnonymous',
23 secData : '_secData'
24 });
25 },
26
27 getUser : function() {
28 return this._user;
29 },
30
31 getSecData : function() {
32 return this._secData;
33 },
34
35 /**
36 * ΠŸΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ Ρ€Π°ΡƒΠ½Π΄ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ, измСняСт Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ состояниС. Π”Π΅Π»Π΅Π³ΠΈΡ€ΡƒΠ΅Ρ‚
37 * Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ SecData.
38 *
39 * @param challenge
40 * {*} - Π΄Π°Π½Π½Ρ‹Π΅ для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ, зависит ΠΎΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ,
41 * Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΠ°Ρ€ΠΎΠ»ΡŒ.
42 * @retuns authResult {Object} - Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ { challenge :
43 * 'response data', code : AUTH_* }.
44 * @throws {Error}
45 * Π² случаС ошибки ΠΈΠ»ΠΈ Ссли ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π½Π΅ Π·Π°Π΄Π°Π½.
46 */
47 doAuth : function(challenge) {
48 if (this._secData)
49 return this._secData.doAuth(challenge);
50
51 throw new Error("Authentication is not available for this object");
52 },
53
54 getAuthType : function() {
55 if (this._secData)
56 return this._secData.getAuthType();
57
58 return null;
59 },
60
61 getIsAuthenticated : function() {
62 if (this._secData) {
63 return this._secData.getAuthSate() == SecData.AUTH_SUCCESS;
64 }
65 return false;
66 },
67
68 getIsAnonymous : function() {
69 return this._isAnonymous;
70 },
71
72 getAuthState : function() {
73 if (this._secData)
74 return this._secData.getAuthState();
75
76 throw new Error("Authentication is not available for this object");
77 }
78 });
79
80 return identity;
81 }); No newline at end of file
@@ -0,0 +1,18
1 define([
2 "dojo/_base/declare",
3 "./SecData"
4 ], function (declare, SecData) {
5 return declare(SecData, {
6 doAuth: function (/*challenge*/) {
7 return {
8 code: SecData.AUTH_SUCCESS
9 };
10 },
11 getAuthState: function () {
12 return SecData.AUTH_SUCCESS;
13 },
14 getAuthType: function () {
15 return "none";
16 }
17 });
18 }); No newline at end of file
@@ -0,0 +1,73
1 define([
2 "dojo/_base/declare", "dojo/node!crypto"], function (declare, crypto) {
3 let SecData = declare(null, {
4 _state: null,
5 _token: null,
6 _authType: null,
7
8 constructor: function (authType) {
9 this._authType = authType;
10 },
11
12 /**
13 * ΠŸΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ Ρ€Π°ΡƒΠ½Π΄ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ, измСняСт Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ состояниС.
14 * @param challenge {*} - Π΄Π°Π½Π½Ρ‹Π΅ для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ, зависит ΠΎΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΠ°Ρ€ΠΎΠ»ΡŒ.
15 * @retuns authResult {Object} - Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ { challenge : 'response data', code : AUTH_* }.
16 */
17 doAuth: function (challenge) {
18 let password = challenge;
19
20 if (this.validateHash(password)) {
21 this._state = SecData.AUTH_SUCCESS;
22 } else {
23 this._state = SecData.AUTH_FAIL;
24 }
25
26 return {
27 code: this._state
28 };
29
30 },
31 getAuthState: function () {
32 return this._state;
33 },
34 getAuthType: function () {
35 return this._authType;
36 },
37
38 generateHash: function (password) {
39 return md5hex(password);
40 },
41 parse: function (token) {
42 this._token = token;
43 },
44
45 validateHash: function (password) {
46 return this.generateHash(password) == this._token;
47 }
48 });
49
50
51 SecData.AUTH_SUCCESS = 0;
52 SecData.AUTH_INCOMPLETE = 1;
53 SecData.AUTH_FAIL = 2;
54
55
56 function md5hex() {
57 let md5 = crypto.createHash('md5');
58
59 for (let i = 0; i < arguments.length; i++)
60 md5.update(String(arguments[i]));
61
62 return md5.digest('hex');
63 }
64
65 let i = 0;
66
67 SecData.md5hex = md5hex;
68 SecData.newSSID = function () {
69 return md5hex(new Date().getTime(), Math.random(), i++);
70 };
71
72 return SecData;
73 }); No newline at end of file
@@ -0,0 +1,56
1 /**
2 * ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ систСмы бСзопасности, встраиваСтся Π² стСк ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ запросов ΠΈ
3 * ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ процСсс создания контСкста бСзопасности рСгистрируСт Π² запросС
4 * сСрвис с ΠΈΠΌΠ΅Π½Π΅ΠΌ session.
5 *
6 * Для получСния ΠΈ создания контСкста бСзопасности ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ
7 * SecurityAuthority ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ подлинности ΠΈ
8 * Π΄ΠΎΠ²Π΅Ρ€Π΅Π½Π½ΠΎΡΡ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠΉ сСссии, ΠΏΠΎ сути SecurityAuthority Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»
9 * бСзопасности.
10 *
11 * ΠŸΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ доступС ΠΊ сСрвисам Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π° прозрачная аутСнтификация, ΠΏΡ€ΠΈ этом
12 * создаСтся новая сСссия, для Π΅Π΅ создания ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ IdentityProvider.
13 * IdentityProvider - внСшний ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΡŽ
14 * прСдоставляСт ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ собствСнныС ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹.
15 *
16 * ПослС получСния Π΄Π°Π½Π½Ρ‹Ρ… Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΎΡ‚ IdentityProvider ΠΎΠ½ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π²
17 * SecurityAuthority для создания сСссии.
18 *
19 * ΠœΠ½ΠΎΠ³ΠΎΡΡ‚Π°ΠΏΠ½Π°Ρ аутСнтификация сСссии - случай ΠΏΠΎΠΊΠ° чисто тСорСтичСский, ΠΎΠ΄Π°Π½ΠΊΠΎ,
20 * Π² случаС нСобходимости SecurityAuthtority Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ
21 * сСсии, Ссли трСбуСтся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ этап Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ сСссии, Π΄Π°Π½Π½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅
22 * ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ запроса ΠΈ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ
23 * SecurityAuthority.handleError ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΡ‚Π²Π΅Ρ‚ сСрвСра
24 * для продолТСния Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.
25 */
26 define([ "dojo/_base/declare", "dojo/when"],
27 function(declare, when) {
28
29 return declare(null, {
30 constructor : function(/*options*/) {
31 },
32
33 /**
34 * Π’ΠΎΡ‡ΠΊΠ° Π²Ρ…ΠΎΠ΄Π° Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ, вызываСтся инфраструктурой ΠΏΡ€ΠΈ
35 * ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ запроса.
36 *
37 * @req Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ запрос.
38 * @next Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅, вызываСтся ΠΊΠΎΠ³Π΄Π° сСссия ΡƒΠΆΠ΅
39 * зарСгистрирована Π² Π»ΠΎΠΊΠ°Ρ‚ΠΎΡ€Π΅.
40 * @async
41 */
42 invoke : function(req, next) {
43 let authority = req.getService("securityAuthority");
44 return when(next(), function(resp) {
45 if (authority)
46 return authority.completeRequest(resp);
47 return resp;
48 }, function(err) {
49 if (authority)
50 return authority.handleError(err);
51 else
52 throw err;
53 });
54 }
55 });
56 });
@@ -0,0 +1,31
1 /**
2 * Created by andrei on 21.08.16.
3 */
4 define([
5 "dojo/_base/declare",
6 "implab/safe",
7 "./NoneSecData",
8 "./SecData"
9 ], function(declare, safe, NoneSecData, SecData) {
10 let SecurityServices = declare(null, {
11 });
12
13 SecurityServices.getSecurityDataService = function(tokenType) {
14 switch (tokenType) {
15 case this.PASSWORD_AUTH_TYPE:
16 return new SecData(tokenType);
17 case this.SATISFY_ANY_AUTH_TYPE:
18 return new NoneSecData();
19 case this.REJECT_ALL_AUTH_TYPE:
20 throw Error("NotImplemented");
21 default:
22 throw Error("Unsupported auth type " + tokenType);
23 }
24
25 };
26 SecurityServices.PASSWORD_AUTH_TYPE = "password";
27 SecurityServices.SATISFY_ANY_AUTH_TYPE = "satisfyany";
28 SecurityServices.REJECT_ALL_AUTH_TYPE = "rejectall";
29
30 return SecurityServices;
31 });
@@ -0,0 +1,101
1 /**
2 * Created by andrei on 08.04.16.
3 */
4 define([
5 "dojo/_base/declare",
6 "dojo/_base/lang",
7 "dojo/when",
8 "implab/safe",
9 "../ForbiddenException"],
10 function (declare, lang, when, safe, ForbiddenException) {
11 return declare(null, {
12 _container: null,
13 _sessionData: null,
14 /**
15 * Π‘ΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΡƒΡŽ сСссию. Если прозрачная аутСнтификация Π½Π΅
16 * ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΠ»Π°ΡΡŒ, ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ сСссии Π½Π΅Ρ‚, Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ создана сСссия
17 * для Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. Π­Ρ‚ΠΎ сдСлано ΠΎΠΏΡ†ΠΈΠ΅ΠΉ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π½Π΅ Π²ΠΎ
18 * всСх систСмах трСбуСтся, ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ Π°Π½ΠΎΠ½ΠΈΠΌΠ½Ρ‹Ρ…
19 * ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ (это Π½Π΅ бСсплатно).
20 */
21 _createAnonymousSession: false,
22
23 /**
24 * Π Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… ΠΈΠ· внСшнСго источника
25 * Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.
26 */
27 _autoRegisterUsers: false,
28
29 constructor: function (options) {
30 safe.argumentNotNull(options, "options");
31 safe.argumentNotNull(options.container, "options.container");
32
33 this._container = options.container;
34
35 this._createAnonymousSession = options.createAnonymousSession || this._createAnonymousSession;
36 this._autoRegisterUsers = options.autoRegisterUsers || this._autoRegisterUsers;
37
38 this._sessionData = this._initSession();
39 },
40 getSessionData: function () {
41 return this._sessionData;
42 },
43
44 /**
45 * @remarks БосзданиС/восстановлСниС сСссии происходит Π² нСсколько
46 * этапов 1. ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ сСссию. 2. Если ΡƒΠΏΠ΅ΡˆΠ½ΠΎ, Ρ‚ΠΎ
47 * Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ. 3. ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ,
48 * ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ identityProvider 4. Если ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ 5. Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ
49 * Π½ΠΎΠ²ΡƒΡŽ сСссию для ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ 6.
50 * Π˜Π½Π°Ρ‡Π΅ Ссли установлСн ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ _createAnonymousSession 7.
51 * Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²ΡƒΡŽ Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΡƒΡŽ сСссию. 8. Π˜Π½Π°Ρ‡Π΅, Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ
52 */
53 _initSession: function () {
54 let me = this;
55
56 let securityAuthority = me._container.getService("securityAuthority");
57 let securityProvider = me._container.getService("securityProvider");
58 let identityProvider = me._container.getService("identityProvider");
59
60 if (!securityAuthority)
61 throw new Error("Sessions are not supported, no security authority is supplied");
62
63
64 // пытаСмся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ сСссию
65 return when(securityAuthority.getSession(), function (session) {
66 if (session)
67 return session;
68
69 // пытаСмся ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ сСссию с использованиСм
70 // ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΈΠ· внСшнСго
71 // источника Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ
72 if (identityProvider) {
73 return when(identityProvider.getUserLogin(), function (login) {
74 if (login) {
75 return when(securityProvider.createUserIdentity(login, false, {
76 createUser: me._autoRegisterUsers
77 }), function (uid) {
78 return securityAuthority.initSession(uid);
79 }, function (err) {
80 console.log("Failed to create session for '" + login + "' ", err);
81 throw new ForbiddenException();
82 });
83 } else if (me._createAnonymousSession) {
84 return when(securityProvider.getAnonymousIdentity(), function (uid) {
85 return securityAuthority.initSession(uid);
86 });
87 } else {
88 throw new ForbiddenException();
89 }
90 });
91 } else if (me._createAnonymousSession) {
92 return when(securityProvider.getAnonymousIdentity(), function (uid) {
93 return securityAuthority.initSession(uid);
94 });
95 }
96
97 throw new ForbiddenException();
98 });
99 }
100 });
101 }); No newline at end of file
@@ -0,0 +1,40
1 {
2 "extends": "tslint:recommended",
3 "rules": {
4 "align": [
5 true,
6 "parameters",
7 "statements"
8 ],
9 "interface-name": [false],
10 "max-line-length": [ true, 185 ],
11 "member-access": false,
12 "member-ordering": [
13 false,
14 "variables-before-functions"
15 ],
16 "no-bitwise": false,
17 "no-empty": false,
18 "no-namespace": false,
19 "no-string-literal": false,
20 "ordered-imports": false,
21 "one-line": [
22 true,
23 "check-open-brace",
24 "check-catch",
25 "check-whitespace"
26 ],
27 "object-literal-sort-keys": false,
28 "trailing-comma": [
29 true,
30 {
31 "singleline": "never",
32 "multiline": "never"
33 }
34 ],
35 "variable-name": false,
36 "curly": false,
37 "array-type": false,
38 "arrow-parens": [true, "ban-single-arg-parens"]
39 }
40 } No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now