# HG changeset patch
# User cin
# Date 2019-11-22 23:04:44
# Node ID 32db28d9ca076bb79b293687085625ad618d9dd7
# Parent f89186e365b160bbd26f2e3274ccdab009d06e65
# Parent 73578135a36ad9f6a3392098bcb1079e9e865195
Merge with ts-plugin
diff --git a/.eslintrc.json b/.eslintrc.json
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -9,7 +9,7 @@
"ecmaFeatures": {
"jsx": true
},
- "sourceType": "module"
+ "sourceType": "script"
},
"extends": "eslint:recommended",
"rules": {
diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -3,3 +3,4 @@ syntax: glob
build/
node_modules/
src/typings/
+ivy-repo/
diff --git a/.project b/.project
new file mode 100644
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+
+
+ core
+ Project implabjs-core created by Buildship.
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,14 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Launch browser tests",
+ "type": "node",
+ "request": "launch",
+ "program": "${workspaceFolder}/build/test/tests/index.js",
+ "cwd": "${workspaceFolder}/build/test",
+ "sourceMaps": true,
+ "preLaunchTask": "Build browser test"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -11,5 +11,11 @@
"**/node_modules/**": true,
"/build": true
},
- "editor.minimap.enabled": false
+ "editor.minimap.enabled": false,
+ "files.exclude": {
+ "**/.classpath": true,
+ "**/.project": true,
+ "**/.settings": true,
+ "**/.factorypath": true
+ }
}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,15 @@
+{
+ "version": "2.0.0",
+ "command": "./gradlew",
+ "type": "shell",
+ "tasks": [
+ {
+ "label": "Build browser test",
+ "args": [
+ "assembleTest",
+ "-Psymbols=local",
+ "-Pflavour=browser"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
--- a/build.gradle
+++ b/build.gradle
@@ -1,278 +1,244 @@
-// если версия явно не заданы вычисляем ее из тэга ревизии v.{num}***
-// результатом будет версия '{num}.{distance}' где distance - расстояние от
-// текущей ревизии до ревизии с тэгом
-def tagDistance = 0;
-def isRelease = false;
-
-if (!version) {
-
- def rev = ["hg", "log", "-r", ".", "--template", "{latesttag('re:^v') % '{tag}-{distance}'}"].execute().text.trim();
-
- def tagVersion;
-
- def match = (rev =~ /^v(\d+\.\d+\.\d+).*-(\d+)$/);
-
- if (match.size()) {
- tagVersion = match[0][1];
- tagDistance = match[0][2].toInteger();
- } else {
- throw new Exception("A version must be specied");
- }
-
- version = tagVersion;
-
- if (tagDistance > 0)
- version++;
-} else {
- println "explicit version: $version";
+plugins {
+ id "org.implab.gradle-typescript" version "1.1.1"
+ id "org.implab.gradle-hg"
+ id "ivy-publish"
}
-if (hasProperty('versionSuffix') && versionSuffix) {
- version += "-$versionSuffix"
-}
+if (!symbols in ['local', 'pack', 'none'])
+ throw new Exception("The symbols property value is invalid: $symbols");
-if(!npmName)
- npmName = name;
+if (!flavour in ['browser', 'node'])
+ throw new Exception("The flavour property value is invalid: $flavour");
-if (hasProperty('release')) {
- isRelease = (release != 'false')
-} else {
- isRelease = (tagDistance == 0);
+ext {
+ packageName = flavour == 'browser' ? "@$npmScope/$name-amd" : "@$npmScope/$name"
+ lint = project.hasProperty('lint') ? project.lint ?: true : false
}
-if(!["amd", "commonjs", "system", "umd", "es6", "esnext"].contains(jsmodule))
- throw new Exception("Invalid jsmodule specified: $jsmodule");
-if(!["es3", "es5", "es6", "es2016", "es2017", "esnext"].contains(target))
- throw new Exception("Invalid target specified: $target")
-
-def targetLibs = [
- "es3" : "es5,es2015.promise,es2015.symbol,dom,scripthost",
- "es5" : "es5,es2015.promise,es2015.symbol,dom,scripthost"
-];
-
-ext.packageName="@$npmScope/$npmName";
-
-def srcDir = "$projectDir/src"
-def typingsDir = "$srcDir/typings"
-def distDir = "$buildDir/dist"
-def testDir = "$buildDir/test"
-def lib = targetLibs[target] ?: "${target},dom";
-
-println "lib: $lib";
-
-def sourceSets = ["main", "amd", "cjs"];
-def testSets = ["test", "testAmd", "testCjs"];
-
-task beforeBuild {
-}
-
-def createSoursetTasks = { String name, String outDir ->
- def setName = name.capitalize();
-
- def compileDir = "$buildDir/compile/$name"
- def declDir = "$typingsDir/$name"
- def setDir = "$projectDir/src/$name"
- def jsDir = outDir;
-
- def beforeBuildTask = task "beforeBuild$setName"(dependsOn: beforeBuild) {
+sources {
+ amd {
+ typings {
+ srcDir main.output.typingsDir
+ }
}
- def copyJsTask = task "copyJs$setName"(dependsOn: beforeBuildTask, type: Copy) {
- from "$setDir/js"
- into jsDir
+ cjs {
+ typings {
+ srcDir main.output.typingsDir
+ }
+ }
+
+ testAmd {
+ typings {
+ srcDir main.output.typingsDir
+ srcDir amd.output.typingsDir
+ srcDir test.output.typingsDir
+ }
}
- def lintJsTask = task "lintJs$setName"(dependsOn: beforeBuildTask, type: Exec) {
- inputs.dir("$setDir/js/").skipWhenEmpty();
- commandLine "eslint", '--format', 'stylish', "$setDir/js/"
+ testCjs {
+ typings {
+ srcDir main.output.typingsDir
+ srcDir cjs.output.typingsDir
+ srcDir test.output.typingsDir
+ }
}
+}
- def compileTsTask = task "compileTs$setName"(dependsOn: beforeBuildTask, type: Exec) {
- inputs.dir("$setDir/ts").skipWhenEmpty()
- inputs.file("$srcDir/tsconfig.json")
- inputs.file("$setDir/tsconfig.json")
- outputs.dir(compileDir)
- outputs.dir(declDir)
-
- commandLine 'node_modules/.bin/tsc',
- '-p', "$setDir/tsconfig.json",
- '-t', target,
- '-m', jsmodule,
- '-d',
- '--sourceMap',
- '--sourceRoot', "file://$setDir/ts",
- '--outDir', compileDir,
- '--declarationDir', declDir
+typescript {
+ compilerOptions {
+ types = []
+ declaration = true
+
+ if(symbols != 'none') {
+ sourceMap = true
+ sourceRoot = "_src"
+ }
- if (lib)
- args '--lib', lib
- }
-
- def copyTsOutputTask = task "copyTsOutput$setName"(dependsOn: compileTsTask, type: Copy) {
- from compileDir
- into jsDir
- }
-
- def copyTypingsTask = task "copyTypings$setName"(dependsOn: compileTsTask, type: Copy) {
- from declDir
- into jsDir
+ if (flavour == 'node') {
+ module = "commonjs"
+ target = "es2017"
+ lib = ["es2017", "dom", "scripthost"]
+ } else if (flavour == 'browser') {
+ module = "amd"
+ target = "es5"
+ lib = ["es5", "dom", "scripthost", "es2015.promise", "es2015.symbol", "es2015.iterable" ]
+ }
}
+ tscCmd = "$projectDir/node_modules/.bin/tsc"
+ tsLintCmd = "$projectDir/node_modules/.bin/tslint"
+ esLintCmd = "$projectDir/node_modules/.bin/eslint"
+}
- def copyResourcesTask = task "copyResources$setName"(dependsOn: beforeBuildTask, type: Copy) {
- from "$setDir/resources"
- into outDir
- }
+npm {
+ npmCmd = "npm"
+}
- task "build$setName" {
- dependsOn copyTypingsTask,
- copyTsOutputTask,
- copyJsTask,
- copyResourcesTask,
- lintJsTask
+tasks.matching{ it.name =~ /^lint/ }.configureEach {
+ onlyIf { lint }
+}
+
+if (symbols == 'local') {
+ tasks.matching{ it.name =~ /^configureTs/ }.configureEach {
+ compilerOptions {
+ sourceRoot = "file://" + it.rootDir
+ }
}
}
task printVersion {
doLast {
+ println "packageName: $packageName";
println "version: $version";
- println "isRelease: $isRelease, tagDistance: $tagDistance";
- println "packageName: $packageName";
- println "bundle: ${pack.outputs.files.join(',')}";
- println "target: $target";
- println "module: $jsmodule";
+ println "flavour: $flavour";
+ println "target: $typescript.compilerOptions.target";
+ println "module: $typescript.compilerOptions.module";
+ println "lint: $lint";
+ println "symbols: $symbols";
}
}
task clean {
doLast {
delete buildDir
- delete typingsDir
+ }
+}
+
+npmPackMeta {
+ meta {
+ name = packageName
+ }
+}
+
+configureTsCjs {
+ dependsOn sources.main.output
+ compilerOptions {
+ types += [ "node" ]
+ }
+}
+
+configureTsAmd {
+ dependsOn sources.main.output
+ compilerOptions {
+ types += [ "requirejs", "dojo-typings" ]
}
}
-task _initBuild {
- mustRunAfter clean
+test {
+ workingDir layout.buildDirectory.dir("test");
+ commandLine "node", "tests/index.js"
+}
- def buildInfoFile = "$buildDir/platform";
- inputs.property('target',target);
- inputs.property('jsmodule',jsmodule);
- outputs.file(buildInfoFile);
-
- doLast {
- delete buildDir
- mkdir buildDir
-
- def f = new File(buildInfoFile);
- f << "$target-$jsmodule";
+assemble {
+ if (flavour == 'browser') {
+ dependsOn sources.amd.output
+ from sources.amd.output.compiledDir
+ from sources.amd.resources
+ }
+ if (flavour == 'node') {
+ dependsOn sources.cjs.output
+ from sources.cjs.output.compiledDir
+ from sources.cjs.resources
}
}
-task cleanNpm {
- doLast {
- delete 'node_modules'
+assembleTest {
+ if (flavour == 'browser') {
+ dependsOn sources.amd.output, sources.testAmd.output
+
+ from sources.amd.output.compiledDir
+ from sources.testAmd.output.compiledDir
+ from sources.amd.resources
+ from sources.testAmd.resources
+ }
+ if (flavour == 'node') {
+ dependsOn sources.cjs.output, sources.testCjs.output
+
+ from sources.cjs.output.compiledDir
+ from sources.testCjs.output.compiledDir
+ from sources.cjs.resources
+ from sources.testCjs.resources
}
}
-task _npmInstall() {
- inputs.file("package.json")
- outputs.dir("node_modules")
- doLast {
- exec {
- commandLine 'npm', 'install'
- }
+typings {
+ if (flavour == 'browser') {
+ dependsOn sources.amd.output
+ from sources.amd.output.typingsDir
+ }
+ if (flavour == 'node') {
+ dependsOn sources.cjs.output
+ from sources.cjs.output.typingsDir
}
}
-beforeBuild {
- dependsOn _initBuild
- dependsOn _npmInstall
-}
-
-sourceSets.each { createSoursetTasks(it, distDir) }
+task npmPackTypings(type: Copy) {
+ npmPackContents.dependsOn it
+ dependsOn sources.main.output
+
+ from sources.main.output.typingsDir
-testSets.each { createSoursetTasks(it, testDir) }
+ if (flavour == 'browser') {
+ dependsOn sources.amd.output
+ from sources.amd.output.typingsDir
+ }
+ if (flavour == 'node') {
+ dependsOn sources.cjs.output
+ from sources.cjs.output.typingsDir
+ }
-compileTsAmd {
- dependsOn compileTsMain
-}
-
-compileTsCjs {
- dependsOn compileTsMain
+ into npm.packageDir
}
-task build(dependsOn: buildMain) {
- if (jsmodule == "amd")
- dependsOn buildAmd
- if (jsmodule == "commonjs")
- dependsOn buildCjs
-}
-
-compileTsTest {
- dependsOn build
-}
-
-compileTsTestAmd {
- dependsOn compileTsTest
-}
-
-compileTsTestCjs {
- dependsOn compileTsTest
-}
-
-task _installLocalCjsDependency(dependsOn: [buildTestCjs, "_packageMeta"], type: Exec) {
- inputs.file("$distDir/package.json")
- outputs.upToDateWhen {
- new File("$testDir/$packageName").exists()
+task npmPackSources(type: Copy) {
+ from sources.main.ts
+ if (symbols == 'pack') {
+ npmPackContents.dependsOn npmPackSources
+ }
+
+ if (flavour == 'browser') {
+ from sources.amd.ts
+ }
+ if (flavour == 'node') {
+ from sources.cjs.ts
}
- workingDir testDir
-
- commandLine 'npm', 'install', '--no-save', '--force', distDir
+ into npm.packageDir.dir("_src")
}
-task test(dependsOn: [buildTest], type: Exec) {
- if (jsmodule == "amd")
- dependsOn buildTestAmd
- if (jsmodule == "commonjs") {
- dependsOn buildTestCjs
- dependsOn _installLocalCjsDependency
+
+
+task packJsTar(type: Tar) {
+ dependsOn assemble;
+
+ archiveBaseName = provider { packageName }
+
+ destinationDirectory = buildDir
+ archiveClassifier = provider { typescript.compilerOptions.module }
+ compression = Compression.GZIP
+
+ from(assemble.outputs)
+
+ doLast {
+ println archiveName;
}
-
- commandLine 'node', "$testDir/run-tests.js"
}
-task _packageMeta(type: Copy) {
- mustRunAfter build
-
- inputs.property("version", version)
- from('.') {
- include '.npmignore', 'readme.md', 'license', 'history.md'
- }
- from("$srcDir/package.${jsmodule}.tmpl.json") {
- expand project.properties
- rename { "package.json" }
- }
- into distDir
+task packTypingsTar(type: Tar) {
}
-task pack(dependsOn: [build, _packageMeta], type: Exec) {
- workingDir distDir
- outputs.file("$npmScope-$npmName-${version}.tgz")
-
- commandLine 'npm', 'pack'
-}
+publishing {
+ publications {
+ local(IvyPublication) {
+ artifact(packJsTar) {
+ type = "js"
+ }
+ }
+ }
-task publish(dependsOn: [build, _packageMeta], type: Exec) {
- doFirst {
- if (!isRelease)
- throw new Exception("Can't publish an unreleased version");
+ repositories {
+ ivy {
+ url "ivy-repo"
+ }
}
- workingDir distDir
-
- commandLine 'npm', 'publish', '--access', 'public'
-}
-
-task markRelease(type: Exec) {
- onlyIf { tagDistance > 1 }
- commandLine "hg", "tag", "v$version";
}
\ No newline at end of file
diff --git a/buildSrc/src/main/groovy/org/implab/gradle/hg/MercurialPlugin.groovy b/buildSrc/src/main/groovy/org/implab/gradle/hg/MercurialPlugin.groovy
new file mode 100644
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/implab/gradle/hg/MercurialPlugin.groovy
@@ -0,0 +1,32 @@
+package org.implab.gradle.hg;
+
+import org.gradle.api.Plugin;
+import org.gradle.api.Project;
+
+public class MercurialPlugin implements Plugin {
+ public void apply(Project project) {
+ if (!project.version) {
+
+ def rev = ["hg", "log", "-r", ".", "--template", "{latesttag('re:^v') % '{tag}-{distance}'}"].execute().text.trim();
+
+ def tagVersion;
+ def tagDistance;
+
+ def match = (rev =~ /^v(\d+\.\d+\.\d+).*-(\d+)$/);
+
+ if (match.size()) {
+ tagVersion = match[0][1];
+ tagDistance = match[0][2].toInteger();
+ } else {
+ throw new Exception("A version must be specied");
+ }
+
+ project.version = tagVersion;
+
+ if (tagDistance > 0)
+ project.version++;
+ } else {
+ println "explicit version: $project.version";
+ }
+ }
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/org.implab.gradle-hg.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/org.implab.gradle-hg.properties
new file mode 100644
--- /dev/null
+++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/org.implab.gradle-hg.properties
@@ -0,0 +1,1 @@
+implementation-class=org.implab.gradle.hg.MercurialPlugin
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,9 +1,9 @@
+group=org.implab
version=
author=Implab team
-jsmodule=amd
-target=es5
-description=Dependency injection, logging, simple and fast text template engine
+description=Dependency injection, logging, simple and fast text processing tools
license=BSD-2-Clause
repository=https://bitbucket.org/implab/implabjs-core
npmScope=implab
-npmName=core-amd
\ No newline at end of file
+flavour=browser
+symbols=pack
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/package-lock.json b/package-lock.json
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,10 +4,36 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "@babel/code-frame": {
+ "version": "7.5.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
+ "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.0.0"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
+ "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.0",
+ "esutils": "^2.0.2",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@types/chai": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.3.tgz",
+ "integrity": "sha512-VRw2xEGbll3ZiTQ4J02/hUjNqZoue1bMhoo2dgM2LXjDdyaq4q80HgBDHwpI0/VKlo4Eg+BavyQMv/NYgTetzA==",
+ "dev": true
+ },
"@types/node": {
- "version": "10.12.18",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz",
- "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==",
+ "version": "8.10.55",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.55.tgz",
+ "integrity": "sha512-iZeh1EgupfmAAOASk580R1SL5lWF3CsBVgVH0395qyNF8fhO16xy1UwAav2PdGxIIsYRn7RzJgMGjdsvam6YYg==",
"dev": true
},
"@types/requirejs": {
@@ -25,6 +51,66 @@
"@types/node": "*"
}
},
+ "acorn": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
+ "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz",
+ "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==",
+ "dev": true
+ },
+ "ajv": {
+ "version": "6.10.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
+ "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-escapes": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+ "dev": true
+ },
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -41,22 +127,111 @@
"concat-map": "0.0.1"
}
},
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+ "dev": true
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^2.0.0"
+ }
+ },
+ "cli-width": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
- "core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
- "dev": true
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
},
- "deep-equal": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.1.2.tgz",
- "integrity": "sha1-skbCuApXCkfBG+HZvRBw7IeLh84=",
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true
},
"define-properties": {
@@ -69,49 +244,71 @@
},
"dependencies": {
"object-keys": {
- "version": "1.0.12",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
- "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true
}
}
},
- "defined": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz",
- "integrity": "sha1-817qfXBekzuvE7LwOz+D2SFAOz4=",
+ "diff": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
"dev": true
},
+ "doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
"dojo": {
- "version": "1.14.2",
- "resolved": "https://registry.npmjs.org/dojo/-/dojo-1.14.2.tgz",
- "integrity": "sha512-TI+Ytgfh/VfmHWERp45Jte6NFMdoJTPsvUP/uzJUvAXET8FP2h442LePWWJ/q/xZ4V0V8OtdJhx8It/GB+Zbxg==",
+ "version": "1.10.10",
+ "resolved": "https://registry.npmjs.org/dojo/-/dojo-1.10.10.tgz",
+ "integrity": "sha512-kg79C8Yyd317cG3MgXGMH4AeQ8TgNr8H/PpA3BRms7DTfl0CJCRAgGE/C6d9Nw55s1ID/fEsfS+P3bj1s7dWgA==",
"dev": true
},
- "duplexer": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
- "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+ "dojo-typings": {
+ "version": "1.11.9",
+ "resolved": "https://registry.npmjs.org/dojo-typings/-/dojo-typings-1.11.9.tgz",
+ "integrity": "sha512-mh8w+Mau2Y1QfTEszEAdO7j6ycNhYxF/Ing6nAk1eUg6NxjeT0viVHjICMd9sU3U463vM2G+KfBBK5grk3/Mlw==",
+ "dev": true,
+ "requires": {
+ "@types/chai": "^4.0.4"
+ }
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true
},
"es-abstract": {
- "version": "1.13.0",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
- "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.15.0.tgz",
+ "integrity": "sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.0",
"function-bind": "^1.1.1",
"has": "^1.0.3",
+ "has-symbols": "^1.0.0",
"is-callable": "^1.1.4",
"is-regex": "^1.0.4",
- "object-keys": "^1.0.12"
+ "object-inspect": "^1.6.0",
+ "object-keys": "^1.1.1",
+ "string.prototype.trimleft": "^2.1.0",
+ "string.prototype.trimright": "^2.1.0"
},
"dependencies": {
"object-keys": {
- "version": "1.0.12",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
- "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true
}
}
@@ -127,37 +324,193 @@
"is-symbol": "^1.0.2"
}
},
- "faucet": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/faucet/-/faucet-0.0.1.tgz",
- "integrity": "sha1-WX3PHSGJosBiMhtZHo8VHtIDnZw=",
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "eslint": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz",
+ "integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "ajv": "^6.10.0",
+ "chalk": "^2.1.0",
+ "cross-spawn": "^6.0.5",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "eslint-scope": "^5.0.0",
+ "eslint-utils": "^1.3.1",
+ "eslint-visitor-keys": "^1.0.0",
+ "espree": "^6.0.0",
+ "esquery": "^1.0.1",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^5.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob-parent": "^5.0.0",
+ "globals": "^11.7.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^6.4.1",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.14",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.2",
+ "progress": "^2.0.0",
+ "regexpp": "^2.0.1",
+ "semver": "^6.1.2",
+ "strip-ansi": "^5.2.0",
+ "strip-json-comments": "^3.0.1",
+ "table": "^5.2.3",
+ "text-table": "^0.2.0",
+ "v8-compile-cache": "^2.0.3"
+ }
+ },
+ "eslint-scope": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
+ "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-utils": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz",
+ "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.0.0"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
+ "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
+ "dev": true
+ },
+ "espree": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz",
+ "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==",
"dev": true,
"requires": {
- "defined": "0.0.0",
- "duplexer": "~0.1.1",
- "minimist": "0.0.5",
- "sprintf": "~0.1.3",
- "tap-parser": "~0.4.0",
- "tape": "~2.3.2",
- "through2": "~0.2.3"
- },
- "dependencies": {
- "tape": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/tape/-/tape-2.3.3.tgz",
- "integrity": "sha1-Lnzgox3wn41oUWZKcYQuDKUFevc=",
- "dev": true,
- "requires": {
- "deep-equal": "~0.1.0",
- "defined": "~0.0.0",
- "inherits": "~2.0.1",
- "jsonify": "~0.0.0",
- "resumer": "~0.0.0",
- "through": "~2.3.4"
- }
- }
+ "acorn": "^7.0.0",
+ "acorn-jsx": "^5.0.2",
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+ "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.0.0"
+ }
+ },
+ "esrecurse": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.1.0"
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true
+ },
+ "external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "dev": true,
+ "requires": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
}
},
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+ "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^2.0.1"
+ }
+ },
+ "flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "dev": true,
+ "requires": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ }
+ },
+ "flatted": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
+ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
+ "dev": true
+ },
"for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -179,10 +532,16 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
"glob": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
- "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
@@ -193,6 +552,21 @@
"path-is-absolute": "^1.0.0"
}
},
+ "glob-parent": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
+ "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ },
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -202,12 +576,49 @@
"function-bind": "^1.1.1"
}
},
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
"has-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
"dev": true
},
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "import-fresh": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz",
+ "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -224,6 +635,27 @@
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
+ "inquirer": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
+ "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^3.2.0",
+ "chalk": "^2.4.2",
+ "cli-cursor": "^2.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^2.0.0",
+ "lodash": "^4.17.12",
+ "mute-stream": "0.0.7",
+ "run-async": "^2.2.0",
+ "rxjs": "^6.4.0",
+ "string-width": "^2.1.0",
+ "strip-ansi": "^5.1.0",
+ "through": "^2.3.6"
+ }
+ },
"is-callable": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
@@ -236,6 +668,33 @@
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
"dev": true
},
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+ "dev": true
+ },
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
@@ -254,16 +713,60 @@
"has-symbols": "^1.0.0"
}
},
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
},
- "jsonify": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
- "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "lodash": {
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+ "dev": true
+ },
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
"dev": true
},
"minimatch": {
@@ -276,9 +779,42 @@
}
},
"minimist": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.5.tgz",
- "integrity": "sha1-16oye87PUY+RBqxrjwA/o7zqhWY=",
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
},
"object-inspect": {
@@ -287,12 +823,6 @@
"integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==",
"dev": true
},
- "object-keys": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
- "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
- "dev": true
- },
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -302,29 +832,85 @@
"wrappy": "1"
}
},
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.4",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "wordwrap": "~1.0.0"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
"path-is-absolute": {
"version": "1.0.1",
"resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
"path-parse": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true
},
- "readable-stream": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
- "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "0.0.1",
- "string_decoder": "~0.10.x"
- }
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "regexpp": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+ "dev": true
},
"requirejs": {
"version": "2.3.6",
@@ -333,12 +919,28 @@
"dev": true
},
"resolve": {
- "version": "1.7.1",
- "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
- "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz",
+ "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==",
"dev": true,
"requires": {
- "path-parse": "^1.0.5"
+ "path-parse": "^1.0.6"
+ }
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
+ "requires": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
}
},
"resumer": {
@@ -350,12 +952,104 @@
"through": "~2.3.4"
}
},
- "sprintf": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/sprintf/-/sprintf-0.1.5.tgz",
- "integrity": "sha1-j4PjmpMXwaUCy324BQ5Rxnn27c8=",
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "run-async": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+ "dev": true,
+ "requires": {
+ "is-promise": "^2.1.0"
+ }
+ },
+ "rxjs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz",
+ "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "astral-regex": "^1.0.0",
+ "is-fullwidth-code-point": "^2.0.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
"string.prototype.trim": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz",
@@ -367,38 +1061,99 @@
"function-bind": "^1.0.2"
}
},
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "string.prototype.trimleft": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz",
+ "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "function-bind": "^1.1.1"
+ }
+ },
+ "string.prototype.trimright": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz",
+ "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "function-bind": "^1.1.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ }
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
+ "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
"dev": true
},
- "tap-parser": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-0.4.3.tgz",
- "integrity": "sha1-pOrhkMENdsehEZIf84u+TVjwnuo=",
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "table": {
+ "version": "5.4.6",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+ "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
"dev": true,
"requires": {
- "inherits": "~2.0.1",
- "readable-stream": "~1.1.11"
+ "ajv": "^6.10.2",
+ "lodash": "^4.17.14",
+ "slice-ansi": "^2.1.0",
+ "string-width": "^3.0.0"
+ },
+ "dependencies": {
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ }
}
},
"tape": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.2.tgz",
- "integrity": "sha512-lPXKRKILZ1kZaUy5ynWKs8ATGSUO7HAFHCFnBam6FaGSqPdOwMWbxXHq4EXFLE8WRTleo/YOMXkaUTRmTB1Fiw==",
+ "version": "4.11.0",
+ "resolved": "https://registry.npmjs.org/tape/-/tape-4.11.0.tgz",
+ "integrity": "sha512-yixvDMX7q7JIs/omJSzSZrqulOV51EC9dK8dM0TzImTIkHWfe2/kFyL5v+d9C+SrCMaICk59ujsqFAVidDqDaA==",
"dev": true,
"requires": {
"deep-equal": "~1.0.1",
"defined": "~1.0.0",
"for-each": "~0.3.3",
"function-bind": "~1.1.1",
- "glob": "~7.1.2",
+ "glob": "~7.1.4",
"has": "~1.0.3",
- "inherits": "~2.0.3",
+ "inherits": "~2.0.4",
"minimist": "~1.2.0",
"object-inspect": "~1.6.0",
- "resolve": "~1.7.1",
+ "resolve": "~1.11.1",
"resumer": "~0.0.0",
"string.prototype.trim": "~1.1.2",
"through": "~2.3.8"
@@ -416,6 +1171,12 @@
"integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
"dev": true
},
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
"minimist": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
@@ -424,32 +1185,114 @@
}
}
},
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
"through": {
"version": "2.3.8",
"resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
- "through2": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
- "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"dev": true,
"requires": {
- "readable-stream": "~1.1.9",
- "xtend": "~2.1.1"
+ "os-tmpdir": "~1.0.2"
}
},
"tslib": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
- "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
+ "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
"dev": true
},
+ "tslint": {
+ "version": "5.18.0",
+ "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz",
+ "integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "builtin-modules": "^1.1.1",
+ "chalk": "^2.3.0",
+ "commander": "^2.12.1",
+ "diff": "^3.2.0",
+ "glob": "^7.1.1",
+ "js-yaml": "^3.13.1",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "resolve": "^1.3.2",
+ "semver": "^5.3.0",
+ "tslib": "^1.8.0",
+ "tsutils": "^2.29.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
+ },
+ "tsutils": {
+ "version": "2.29.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
+ "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ }
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
"typescript": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz",
- "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==",
+ "version": "3.6.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz",
+ "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==",
+ "dev": true
+ },
+ "uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "v8-compile-cache": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
+ "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
+ "dev": true
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
"dev": true
},
"wrappy": {
@@ -458,13 +1301,13 @@
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
- "xtend": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
- "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+ "write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
"dev": true,
"requires": {
- "object-keys": "~0.4.0"
+ "mkdirp": "^0.5.1"
}
}
}
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -17,19 +17,18 @@
"access": "public"
},
"peerDependencies": {
- "dojo": "^1.10.0",
- "tslib": "latest"
+ "dojo": "^1.10.0"
},
"devDependencies": {
- "@types/node": "latest",
- "@types/requirejs": "latest",
- "@types/tape": "latest",
- "dojo": "^1.10.0",
- "faucet": "latest",
+ "@types/node": "^8.0.0",
+ "@types/requirejs": "~2.1.31",
+ "@types/tape": "~4.2.33",
+ "dojo": "~1.10.0",
+ "dojo-typings": "^1.11.9",
"requirejs": "latest",
- "tape": "^4.9.2",
- "tslib": "latest",
- "typescript": "latest"
- },
- "types": "main.d.ts"
+ "tape": "~4.11.0",
+ "typescript": "~3.6.4",
+ "eslint": "6.1.0",
+ "tslint": "5.18.0"
+ }
}
diff --git a/src/amd/ts/di/ResolverHelper.ts b/src/amd/ts/di/ResolverHelper.ts
--- a/src/amd/ts/di/ResolverHelper.ts
+++ b/src/amd/ts/di/ResolverHelper.ts
@@ -4,7 +4,7 @@ import { TraceSource } from "../log/Trac
import m = require("module");
const sandboxId = Uuid();
-define(sandboxId, ["require"], r => r);
+define(sandboxId, ["require"], (r: any) => r);
const globalRequire = getGlobal().require as Require || requirejs;
diff --git a/src/amd/tsconfig.json b/src/amd/tsconfig.json
--- a/src/amd/tsconfig.json
+++ b/src/amd/tsconfig.json
@@ -2,15 +2,13 @@
"extends": "../tsconfig",
"compilerOptions": {
"types": [
- "requirejs"
+ "requirejs",
+ "dojo-typings"
],
"rootDir": "ts",
"rootDirs": [
"ts",
- "../typings/main"
+ "../main/ts"
]
- },
- "include": [
- "ts/**/*.ts"
- ]
+ }
}
\ No newline at end of file
diff --git a/src/package.amd.tmpl.json b/src/package.amd.tmpl.json
deleted file mode 100644
--- a/src/package.amd.tmpl.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "name": "${packageName}",
- "version": "${version}",
- "description": "${description}",
- "main": "main.js",
- "keywords": [
- "di",
- "ioc",
- "logging",
- "template engine",
- "dependency injection"
- ],
- "author": "${author}",
- "license": "${license}",
- "repository": "$repository",
- "publishConfig": {
- "access": "public"
- },
- "peerDependencies": {
- "dojo": "^1.10.0"
- },
- "module": "${jsmodule}",
- "target": "${target}"
-}
\ No newline at end of file
diff --git a/src/package.commonjs.tmpl.json b/src/package.commonjs.tmpl.json
deleted file mode 100644
--- a/src/package.commonjs.tmpl.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "name": "${packageName}",
- "version": "${version}",
- "description": "${description}",
- "main": "main.js",
- "keywords": [
- "di",
- "ioc",
- "logging",
- "template engine",
- "dependency injection"
- ],
- "author": "${author}",
- "license": "${license}",
- "repository": "$repository",
- "publishConfig": {
- "access": "public"
- },
- "module": "${jsmodule}",
- "target": "${target}"
-}
\ No newline at end of file
diff --git a/src/test/ts/ActivatableTests.ts b/src/test/ts/ActivatableTests.ts
deleted file mode 100644
--- a/src/test/ts/ActivatableTests.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { MockActivationController } from "./mock/MockActivationController";
-import { SimpleActivatable } from "./mock/SimpleActivatable";
-import { test } from "./TestTraits";
-
-test("simple activation", async t => {
-
- const a = new SimpleActivatable();
- t.false(a.isActive());
-
- await a.activate();
- t.true(a.isActive());
-
- await a.deactivate();
- t.false(a.isActive());
-});
-
-test("controller activation", async t => {
-
- const a = new SimpleActivatable();
- const c = new MockActivationController();
-
- t.false(a.isActive(), "the component is not active by default");
- t.assert(c.getActive() == null, "the activation controller doesn't have an active component by default");
- t.assert(a.getActivationController() == null, "the component doesn't have an activation controller by default");
-
- t.comment("Active the component through the controller");
- await c.activate(a);
- t.true(a.isActive(), "The component should successfully activate");
- t.equal(c.getActive(), a, "The controller should point to the activated component");
- t.equal(a.getActivationController(), c, "The component should point to the controller");
-
- t.comment("Deactive the component throug the controller");
- await c.deactivate();
-
- t.false(a.isActive(), "The component should successfully deactivate");
- t.equal(c.getActive(), null, "The controller shouldn't point to any component");
- t.equal(a.getActivationController(), c, "The componet should point to it's controller");
-});
-
-test("handle error in onActivating", async t => {
- const a = new SimpleActivatable();
-
- a.onActivating = async () => {
- throw new Error("Should fail");
- };
-
- try {
- await a.activate();
- t.fail("activation should fail");
- } catch {
- }
-
- t.false(a.isActive(), "the component should remain inactive");
-});
diff --git a/src/test/ts/CancellationTests.ts b/src/test/ts/CancellationTests.ts
deleted file mode 100644
--- a/src/test/ts/CancellationTests.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import { Cancellation } from "@implab/core/Cancellation";
-import { delay } from "@implab/core/safe";
-import { test } from "./TestTraits";
-
-test("standalone cancellation", async t => {
-
- let doCancel: (e) => void;
-
- const ct = new Cancellation(cancel => {
- doCancel = cancel;
- });
-
- let counter = 0;
- const reason = "BILL";
-
- t.true(ct.isSupported(), "Cancellation must be supported");
- t.false(ct.isRequested(), "Cancellation shouldn't be requested");
- ct.throwIfRequested();
- t.pass("The exception shouldn't be thrown unless the cancellation is requested");
-
- ct.register(() => counter++);
- t.equals(counter, 0, "counter should be zero");
-
- ct.register(() => counter++).destroy();
-
- doCancel(reason);
-
- t.true(ct.isRequested(), "Cancellation should be requested");
- t.equals(counter, 1, "The registered callback should be triggered");
-
- ct.register(() => counter++);
- t.equals(counter, 2, "The callback should be triggered immediately");
-
- let msg;
- ct.register(e => msg = e);
- t.equals(msg, reason, "The cancellation reason should be passed to callback");
-
- try {
- msg = null;
- ct.throwIfRequested();
- t.fail("The exception should be thrown");
- } catch (e) {
- msg = e;
- }
- t.equals(msg, reason, "The cancellation reason should be catched");
-});
-
-test("async cancellation", async t => {
-
- const ct = new Cancellation(cancel => {
- cancel("STOP!");
- });
-
- try {
- await delay(0, ct);
- t.fail("Should thow the exception");
- } catch (e) {
- t.equals(e, "STOP!", "Should throw the cancellation reason");
- }
-});
-
-test("cancel with external event", async t => {
- const ct = new Cancellation(cancel => {
- setTimeout(x => cancel("STOP!"), 0);
- });
-
- try {
- await delay(10000, ct);
- t.fail("Should thow the exception");
- } catch (e) {
- t.equals(e, "STOP!", "Should throw the cancellation reason");
- }
-});
-
-test("operation normal flow", async t => {
-
- let htimeout;
- const ct = new Cancellation(cancel => {
- htimeout = setTimeout(() => cancel("STOP!"), 1000);
- });
-
- try {
- await delay(0, ct);
- t.pass("Should pass");
- } finally {
- clearTimeout(htimeout);
- }
-});
diff --git a/src/test/ts/ContainerTests.ts b/src/test/ts/ContainerTests.ts
deleted file mode 100644
--- a/src/test/ts/ContainerTests.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-import { test } from "./TestTraits";
-import { Container } from "@implab/core/di/Container";
-import { ReferenceDescriptor } from "@implab/core/di/ReferenceDescriptor";
-import { AggregateDescriptor } from "@implab/core/di/AggregateDescriptor";
-import { ValueDescriptor } from "@implab/core/di/ValueDescriptor";
-import { Foo } from "./mock/Foo";
-import { Bar } from "./mock/Bar";
-import { isNull } from "@implab/core/safe";
-
-test("Container register/resolve tests", async t => {
- const container = new Container();
-
- const connection1 = "db://localhost";
-
- t.throws(
- () => container.register("bla-bla", "bla-bla"),
- "Do not allow to register anything other than descriptors"
- );
-
- t.doesNotThrow(
- () => container.register("connection", new ValueDescriptor(connection1)),
- "register ValueDescriptor"
- );
-
- t.equals(container.resolve("connection"), connection1, "resolve string value");
-
- t.doesNotThrow(
- () => container.register(
- "dbParams",
- new AggregateDescriptor({
- timeout: 10,
- connection: new ReferenceDescriptor({ name: "connection" })
- })
- ),
- "register AggregateDescriptor"
- );
-
- const dbParams = container.resolve("dbParams");
- t.equals(dbParams.connection, connection1, "should get string value 'dbParams.connection'");
-});
-
-test("Container configure/resolve tests", async t => {
-
- const container = new Container();
-
- await container.configure({
- foo: {
- $type: Foo
- },
-
- box: {
- $type: Bar,
- params: {
- $dependency: "foo"
- }
- },
-
- bar: {
- $type: Bar,
- params: {
- db: {
- provider: {
- $dependency: "db"
- }
- }
- }
- }
- });
- t.pass("should configure from js object");
-
- const f1 = container.resolve("foo");
-
- t.assert(!isNull(f1), "foo should be not null");
-
- t.throws(() => container.resolve("bar"), "should not resolve dependency 'db'");
-
-});
-
-test("Load configuration from module", async t => {
- const container = new Container();
-
- await container.configure("./mock/config1", { contextRequire: require });
- t.pass("The configuration should load");
-
- const f1 = container.resolve("foo");
-
- t.assert(!isNull(f1), "foo should be not null");
-
- const b1 = container.resolve("bar") as Bar;
-
- t.assert(!isNull(b1), "bar should not be null");
- t.assert(!isNull(b1.foo), "bar.foo should not be null");
-});
diff --git a/src/test/ts/ObservableTests.ts b/src/test/ts/ObservableTests.ts
deleted file mode 100644
--- a/src/test/ts/ObservableTests.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { TraceSource, DebugLevel } from "@implab/core/log/TraceSource";
-import { Observable } from "@implab/core/Observable";
-import { IObservable } from "@implab/core/interfaces";
-import { delay } from "@implab/core/safe";
-import { test } from "./TestTraits";
-
-const trace = TraceSource.get("ObservableTests");
-
-test("events sequence example", async t => {
-
- let events: IObservable;
-
- const done = new Promise(resolve => {
- events = new Observable(async (notify, fail, finish) => {
- for (let i = 0; i < 10; i++) {
- await delay(0);
- notify(i);
- }
- finish();
- resolve();
- });
- });
-
- let count = 0;
- let complete = false;
- events.on(x => count = count + x, null, () => complete = true);
-
- const first = await events.next();
-
- t.equals(first, 0, "the first event");
- t.false(complete, "the sequence is not complete");
-
- await done;
-
- t.equals(count, 45, "the summ of the evetns");
- t.true(complete, "the sequence is complete");
-});
-
-test("event sequence termination", async t => {
- let events: IObservable;
-
- const done = new Promise(resolve => {
- events = new Observable(async (notify, fail, complete) => {
- await delay(0);
- notify(1);
- complete();
- notify(2);
- complete();
- fail("Sequence terminated");
- resolve();
- });
- });
-
- let count = 0;
- events.on(() => {}, e => count++, () => count++);
-
- const first = await events.next();
- t.equals(first, 1, "the first message");
- try {
- await events.next();
- t.fail("shoud throw an exception");
- } catch (e) {
- t.pass("the sequence is terminated");
- }
-
- await done;
-
- t.equals(count, 1, "the sequence must be terminated once");
-});
diff --git a/src/test/ts/SafeTests.ts b/src/test/ts/SafeTests.ts
deleted file mode 100644
--- a/src/test/ts/SafeTests.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-import { Cancellation } from "@implab/core/Cancellation";
-import { first, isPromise, firstWhere, delay, nowait } from "@implab/core/safe";
-import { test } from "./TestTraits";
-
-test("await delay test", async t => {
- // schedule delay
- let resolved = false;
- let res = delay(0).then(() => resolved = true);
-
- t.false(resolved, "the delay should be async");
-
- await res;
- t.pass("await delay");
-
- // create cancellation token
- let cancel: (e?: any) => void;
- const ct = new Cancellation(c => cancel = c);
-
- // schedule delay
- resolved = false;
- res = delay(0, ct).then(() => resolved = true);
-
- t.false(resolved, "created delay with ct");
-
- // cancel
- cancel();
-
- try {
- await res;
- t.fail("the delay should fail when it is cancelled");
- } catch {
- t.pass("the delay is cancelled");
- }
-
- t.throws(() => {
- // try schedule delay after the cancellation is requested
- nowait(delay(0, ct));
- }, "Should throw if cancelled before start");
-});
-
-test("sequemce test", async t => {
- const sequence = ["a", "b", "c"];
- const empty = [];
-
- // synchronous tests
- t.equals(first(sequence), "a", "Should return the first element");
- t.equals(firstWhere(sequence, x => x === "b"), "b", "Should get the second element");
-
- let v: string;
- let e: Error;
- first(sequence, x => v = x);
- t.equal(v, "a", "The callback should be called for the first element");
- firstWhere(sequence, x => x === "b", x => v = x);
- t.equal(v, "b", "The callback should be called for the second element");
-
- t.throws(() => {
- first(empty);
- }, "Should throw when the sequence is empty");
-
- t.throws(() => {
- firstWhere(empty, x => x === "b");
- }, "Should throw when the sequence is empty");
-
- t.throws(() => {
- first(empty, x => v = x);
- }, "Should throw when the sequence is empty");
-
- t.throws(() => {
- firstWhere(empty, x => x === "b", x => v = x);
- }, "Should throw when the sequence is empty");
-
- t.throws(() => {
- firstWhere(sequence, x => x === "z");
- }, "Should throw when the element isn't found");
-
- t.throws(() => {
- firstWhere(sequence, x => x === "z", x => v = x);
- }, "Should throw when the element isn't found");
-
- first(empty, null, x => e = x);
- t.true(e, "The errorback should be called for the empty sequence");
-
- // async tests
- const asyncSequence = Promise.resolve(sequence);
- const asyncEmptySequence = Promise.resolve(empty);
-
- const promise = first(asyncSequence);
- t.true(isPromise(promise), "Should return promise");
-
- v = await promise;
- t.equal(v, "a", "Should return the first element");
-
- v = await new Promise(resolve => first(asyncSequence, resolve));
- t.equal(v, "a", "The callback should be called for the first element");
-});
diff --git a/src/test/ts/TestTraits.ts b/src/test/ts/TestTraits.ts
deleted file mode 100644
--- a/src/test/ts/TestTraits.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import { IObservable, ICancellation, IDestroyable } from "@implab/core/interfaces";
-import { Cancellation } from "@implab/core/Cancellation";
-import { TraceEvent, LogLevel, WarnLevel, DebugLevel, TraceSource } from "@implab/core/log/TraceSource";
-import * as tape from "tape";
-import { argumentNotNull, destroy } from "@implab/core/safe";
-
-export class TapeWriter implements IDestroyable {
- private readonly _tape: tape.Test;
-
- private readonly _subscriptions = new Array();
- private _destroyed;
-
- constructor(t: tape.Test) {
- argumentNotNull(t, "tape");
- this._tape = t;
- }
-
- writeEvents(source: IObservable, ct: ICancellation = Cancellation.none) {
- if (!this._destroyed) {
- const subscription = source.on(this.writeEvent.bind(this));
- if (ct.isSupported()) {
- ct.register(subscription.destroy.bind(subscription));
- }
- this._subscriptions.push(subscription);
- }
- }
-
- writeEvent(next: TraceEvent) {
- if (next.level >= DebugLevel) {
- this._tape.comment(`DEBUG ${next.source.id} ${next}`);
- } else if (next.level >= LogLevel) {
- this._tape.comment(`LOG ${next.source.id} ${next}`);
- } else if (next.level >= WarnLevel) {
- this._tape.comment(`WARN ${next.source.id} ${next}`);
- } else {
- this._tape.comment(`ERROR ${next.source.id} ${next}`);
- }
- }
-
- destroy() {
- this._subscriptions.forEach(destroy);
- }
-}
-
-export function test(name: string, cb: (t: tape.Test, trace: TraceSource) => any) {
- tape(name, async t => {
- const writer = new TapeWriter(t);
-
- // this trace is not announced through the TraceSource global registry
- const trace = new TraceSource(name);
- trace.level = DebugLevel;
- writer.writeEvents(trace.events);
-
- const h = TraceSource.on(ts => {
- ts.level = DebugLevel;
- writer.writeEvents(ts.events);
- });
-
- try {
- await cb(t, trace);
- } catch (e) {
-
- // verbose error information
- // tslint:disable-next-line
- console.error(e);
- t.fail(e);
-
- } finally {
- t.end();
- destroy(writer);
- destroy(h);
- }
- });
-}
diff --git a/src/test/ts/TextTests.ts b/src/test/ts/TextTests.ts
deleted file mode 100644
--- a/src/test/ts/TextTests.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { StringBuilder } from "@implab/core/text/StringBuilder";
-import { test } from "./TestTraits";
-import { MockConsole } from "./mock/MockConsole";
-import { ConsoleWriter } from "@implab/core/log/ConsoleWriter";
-
-test("String builder", async t => {
- const sb = new StringBuilder();
-
- sb.write("hello");
- t.equals(sb.toString(), "hello", "Write simple text");
-
- sb.write(", ");
- sb.write("world!");
- t.equals(sb.toString(), "hello, world!", "Append text");
-
- sb.clear();
- t.equals(sb.toString(), "", "Clear");
-
- sb.write(1);
- t.equals(sb.toString(), "1", "Write number");
-
- sb.clear();
- sb.writeValue(0.123);
- t.equals(sb.toString(), "0.123", "Format number");
-
- sb.clear();
- sb.writeValue(new Date("2019-01-02T00:00:00.000Z"));
- t.equals(sb.toString(), "2019-01-02T00:00:00.000Z", "Format date (ISO)");
-
- sb.clear();
- sb.write("{0}", "hello");
- t.equals(sb.toString(), "hello", "Simple format text");
-
- sb.write(", {0}!", "world");
- t.equals(sb.toString(), "hello, world!", "Append formatted text");
-
- sb.clear();
- sb.write("abc: {0:json}; {0.length}; {0.1} {{olo}}", ["a", "b", "c"]);
- t.equals(sb.toString(), 'abc: [\n "a",\n "b",\n "c"\n]; 3; b {olo}', "Format string with spec");
-
- sb.clear();
- t.throws(() => sb.write("}", 0), "Should die on bad format: '}'");
- t.throws(() => sb.write("{", 0), "Should die on bad format: '{'");
- t.throws(() => sb.write("{}", 0), "Should die on bad format: '{}'");
- t.throws(() => sb.write("{:}", 0), "Should die on bad format: '{:}'");
- t.throws(() => sb.write("{{0}", 0), "Should die on bad format: '{{0}'");
-
-});
-
-test("ConsoleWriter", t => {
- const mockConsole = new MockConsole();
- const writer = new ConsoleWriter(mockConsole);
-
- writer.setLogLevel("log");
-
- writer.writeLine("Hello, world!");
-
- t.equals(mockConsole.getBuffer().length, 1, "One line should be written");
- t.equals(mockConsole.getBuffer()[0].level, "log", "LogLevel should be 'log'");
- t.deepEqual(mockConsole.getBuffer()[0].data, ["Hello, world!"], "The buffer should contain single string");
-
- mockConsole.clear();
- writer.setLogLevel("debug");
- writer.write("Bring ");
- writer.write("the {0}!", "light");
- t.equals(mockConsole.getBuffer().length, 0, "No line should be written");
- writer.writeLine();
-
- t.equals(mockConsole.getBuffer().length, 1, "One line should be written");
- t.equals(mockConsole.getBuffer()[0].level, "debug", "LogLevel should be 'log'");
- t.deepEqual(mockConsole.getBuffer()[0].data, ["Bring the light!"], "Should concatenate string parts together");
-
- mockConsole.clear();
- writer.writeLine("It's {0} o'clock, lets have some {1}!", { h: 5}, { title: "tee" });
-
- t.deepEqual(mockConsole.getBuffer()[0].data, ["It's ", { h: 5}, " o'clock, lets have some ", { title: "tee" }, "!"], "Non string parts should be psassed as is");
-
- mockConsole.clear();
- writer.writeLine("{0} or {1} to {2}", {i: 25}, 6, 4);
- t.deepEqual(mockConsole.getBuffer()[0].data, [{i: 25}, " or 6 to 4"], "25 or 6 to 4");
-
- mockConsole.clear();
- writer.writeLine("{0} or {1} to {2}! Let's have some {3}", 25, 6, 4, { product: "tee" } );
- t.deepEqual(mockConsole.getBuffer()[0].data, ["25 or 6 to 4! Let's have some ", { product: "tee" }], "Should handle many text chunks and object at the end");
-
-});
diff --git a/src/test/ts/TraceSourceTests.ts b/src/test/ts/TraceSourceTests.ts
deleted file mode 100644
--- a/src/test/ts/TraceSourceTests.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { TraceSource, DebugLevel } from "@implab/core/log/TraceSource";
-import * as tape from "tape";
-import { TapeWriter, test } from "./TestTraits";
-import { MockConsole } from "./mock/MockConsole";
-import { ConsoleLogger } from "@implab/core/log/writers/ConsoleLogger";
-import { ConsoleWriter } from "@implab/core/log/ConsoleWriter";
-
-const sourceId = "test/TraceSourceTests";
-
-tape("trace message", t => {
- const trace = TraceSource.get(sourceId);
-
- trace.level = DebugLevel;
-
- const h = trace.events.on(ev => {
- t.equal(ev.source, trace, "sender should be the current trace source");
- t.equal(ev.level, DebugLevel, "level should be debug level");
- t.equal(ev.toString(), "Hello, World!", "The message should be a formatted message");
-
- t.end();
- });
-
- trace.debug("Hello, {0}!", "World");
-
- h.destroy();
-});
-
-tape("trace event", t => {
- const trace = TraceSource.get(sourceId);
-
- trace.level = DebugLevel;
-
- const event = {
- name: "custom event"
- };
-
- const h = trace.events.on(ev => {
- t.equal(ev.source, trace, "sender should be the current trace source");
- t.equal(ev.level, DebugLevel, "level should be debug level");
- t.equal(ev.message, event, "The message should be the specified object");
-
- t.end();
- });
-
- trace.traceEvent(DebugLevel, event);
-
- h.destroy();
-});
-
-tape("tape comment writer", async t => {
- const writer = new TapeWriter(t);
-
- TraceSource.on(ts => {
- writer.writeEvents(ts.events);
- });
-
- const trace = TraceSource.get(sourceId);
- trace.level = DebugLevel;
-
- trace.log("Hello, {0}!", "World");
- trace.log("Multi\n line");
- trace.warn("Look at me!");
- trace.error("DIE!");
-
- writer.destroy();
-
- trace.log("You shouldn't see it!");
-
- t.comment("DONE");
-
- t.end();
-});
-
-test("console writer", (t, trace) => {
-
- const mockConsole = new MockConsole();
- const writer = new ConsoleWriter(mockConsole);
- const consoleLog = new ConsoleLogger(writer);
- consoleLog.writeEvents(trace.events);
-
- trace.log("Hello, world!");
- t.deepEqual(mockConsole.getLine(0), ["console writer: Hello, world!"], "Log one string");
-
- trace.log({ foo: "bar" });
- t.deepEqual(mockConsole.getLine(1), ["console writer: ", { foo: "bar" }], "Log an object");
-
- trace.log("json: {0:json}", { foo: "bar" });
- t.deepEqual(mockConsole.getLine(2), ['console writer: json: {\n "foo": "bar"\n}'], "should convert to string substitutions with spec");
-});
diff --git a/src/test/ts/dummy.ts b/src/test/ts/dummy.ts
deleted file mode 100644
--- a/src/test/ts/dummy.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import * as tape from "tape";
-import { Uuid } from "@implab/core/Uuid";
-
-tape("simple", t => {
- t.pass("sync assert");
- setTimeout(() => {
- t.pass("async assert");
- t.comment(Uuid());
- t.ok(Uuid() !== Uuid());
- // end should be called after the last assertion
- t.end();
- }, 100);
-});
diff --git a/src/test/ts/mock/MockActivationController.ts b/src/test/ts/mock/MockActivationController.ts
--- a/src/test/ts/mock/MockActivationController.ts
+++ b/src/test/ts/mock/MockActivationController.ts
@@ -1,5 +1,5 @@
-import { IActivatable, ICancellation, IActivationController } from "@implab/core/interfaces";
-import { Cancellation } from "@implab/core/Cancellation";
+import { IActivatable, ICancellation, IActivationController } from "../interfaces";
+import { Cancellation } from "../Cancellation";
export class MockActivationController implements IActivationController {
diff --git a/src/test/ts/mock/MockConsole.ts b/src/test/ts/mock/MockConsole.ts
--- a/src/test/ts/mock/MockConsole.ts
+++ b/src/test/ts/mock/MockConsole.ts
@@ -1,4 +1,4 @@
-import {NullConsole} from "@implab/core/log/NullConsole";
+import {NullConsole} from "../log/NullConsole";
interface ConsoleLineData {
level: string;
diff --git a/src/test/ts/mock/SimpleActivatable.ts b/src/test/ts/mock/SimpleActivatable.ts
--- a/src/test/ts/mock/SimpleActivatable.ts
+++ b/src/test/ts/mock/SimpleActivatable.ts
@@ -1,5 +1,5 @@
-import { AsyncComponent } from "@implab/core/components/AsyncComponent";
-import { ActivatableMixin } from "@implab/core/components/ActivatableMixin";
+import { AsyncComponent } from "../components/AsyncComponent";
+import { ActivatableMixin } from "../components/ActivatableMixin";
export class SimpleActivatable extends ActivatableMixin(AsyncComponent) {
diff --git a/src/test/ts/tests/ActivatableTests.ts b/src/test/ts/tests/ActivatableTests.ts
new file mode 100644
--- /dev/null
+++ b/src/test/ts/tests/ActivatableTests.ts
@@ -0,0 +1,54 @@
+import { MockActivationController } from "../mock/MockActivationController";
+import { SimpleActivatable } from "../mock/SimpleActivatable";
+import { test } from "./TestTraits";
+
+test("simple activation", async t => {
+
+ const a = new SimpleActivatable();
+ t.false(a.isActive());
+
+ await a.activate();
+ t.true(a.isActive());
+
+ await a.deactivate();
+ t.false(a.isActive());
+});
+
+test("controller activation", async t => {
+
+ const a = new SimpleActivatable();
+ const c = new MockActivationController();
+
+ t.false(a.isActive(), "the component is not active by default");
+ t.assert(c.getActive() == null, "the activation controller doesn't have an active component by default");
+ t.assert(a.getActivationController() == null, "the component doesn't have an activation controller by default");
+
+ t.comment("Active the component through the controller");
+ await c.activate(a);
+ t.true(a.isActive(), "The component should successfully activate");
+ t.equal(c.getActive(), a, "The controller should point to the activated component");
+ t.equal(a.getActivationController(), c, "The component should point to the controller");
+
+ t.comment("Deactive the component throug the controller");
+ await c.deactivate();
+
+ t.false(a.isActive(), "The component should successfully deactivate");
+ t.equal(c.getActive(), null, "The controller shouldn't point to any component");
+ t.equal(a.getActivationController(), c, "The componet should point to it's controller");
+});
+
+test("handle error in onActivating", async t => {
+ const a = new SimpleActivatable();
+
+ a.onActivating = async () => {
+ throw new Error("Should fail");
+ };
+
+ try {
+ await a.activate();
+ t.fail("activation should fail");
+ } catch {
+ }
+
+ t.false(a.isActive(), "the component should remain inactive");
+});
diff --git a/src/test/ts/tests/CancellationTests.ts b/src/test/ts/tests/CancellationTests.ts
new file mode 100644
--- /dev/null
+++ b/src/test/ts/tests/CancellationTests.ts
@@ -0,0 +1,88 @@
+import { Cancellation } from "../Cancellation";
+import { delay } from "../safe";
+import { test } from "./TestTraits";
+
+test("standalone cancellation", async t => {
+
+ let doCancel: (e) => void;
+
+ const ct = new Cancellation(cancel => {
+ doCancel = cancel;
+ });
+
+ let counter = 0;
+ const reason = "BILL";
+
+ t.true(ct.isSupported(), "Cancellation must be supported");
+ t.false(ct.isRequested(), "Cancellation shouldn't be requested");
+ ct.throwIfRequested();
+ t.pass("The exception shouldn't be thrown unless the cancellation is requested");
+
+ ct.register(() => counter++);
+ t.equals(counter, 0, "counter should be zero");
+
+ ct.register(() => counter++).destroy();
+
+ doCancel(reason);
+
+ t.true(ct.isRequested(), "Cancellation should be requested");
+ t.equals(counter, 1, "The registered callback should be triggered");
+
+ ct.register(() => counter++);
+ t.equals(counter, 2, "The callback should be triggered immediately");
+
+ let msg;
+ ct.register(e => msg = e);
+ t.equals(msg, reason, "The cancellation reason should be passed to callback");
+
+ try {
+ msg = null;
+ ct.throwIfRequested();
+ t.fail("The exception should be thrown");
+ } catch (e) {
+ msg = e;
+ }
+ t.equals(msg, reason, "The cancellation reason should be catched");
+});
+
+test("async cancellation", async t => {
+
+ const ct = new Cancellation(cancel => {
+ cancel("STOP!");
+ });
+
+ try {
+ await delay(0, ct);
+ t.fail("Should thow the exception");
+ } catch (e) {
+ t.equals(e, "STOP!", "Should throw the cancellation reason");
+ }
+});
+
+test("cancel with external event", async t => {
+ const ct = new Cancellation(cancel => {
+ setTimeout(x => cancel("STOP!"), 0);
+ });
+
+ try {
+ await delay(10000, ct);
+ t.fail("Should thow the exception");
+ } catch (e) {
+ t.equals(e, "STOP!", "Should throw the cancellation reason");
+ }
+});
+
+test("operation normal flow", async t => {
+
+ let htimeout;
+ const ct = new Cancellation(cancel => {
+ htimeout = setTimeout(() => cancel("STOP!"), 1000);
+ });
+
+ try {
+ await delay(0, ct);
+ t.pass("Should pass");
+ } finally {
+ clearTimeout(htimeout);
+ }
+});
diff --git a/src/test/ts/tests/ContainerTests.ts b/src/test/ts/tests/ContainerTests.ts
new file mode 100644
--- /dev/null
+++ b/src/test/ts/tests/ContainerTests.ts
@@ -0,0 +1,93 @@
+import { test } from "./TestTraits";
+import { Container } from "../di/Container";
+import { ReferenceDescriptor } from "../di/ReferenceDescriptor";
+import { AggregateDescriptor } from "../di/AggregateDescriptor";
+import { ValueDescriptor } from "../di/ValueDescriptor";
+import { Foo } from "../mock/Foo";
+import { Bar } from "../mock/Bar";
+import { isNull } from "../safe";
+
+test("Container register/resolve tests", async t => {
+ const container = new Container();
+
+ const connection1 = "db://localhost";
+
+ t.throws(
+ () => container.register("bla-bla", "bla-bla"),
+ "Do not allow to register anything other than descriptors"
+ );
+
+ t.doesNotThrow(
+ () => container.register("connection", new ValueDescriptor(connection1)),
+ "register ValueDescriptor"
+ );
+
+ t.equals(container.resolve("connection"), connection1, "resolve string value");
+
+ t.doesNotThrow(
+ () => container.register(
+ "dbParams",
+ new AggregateDescriptor({
+ timeout: 10,
+ connection: new ReferenceDescriptor({ name: "connection" })
+ })
+ ),
+ "register AggregateDescriptor"
+ );
+
+ const dbParams = container.resolve("dbParams");
+ t.equals(dbParams.connection, connection1, "should get string value 'dbParams.connection'");
+});
+
+test("Container configure/resolve tests", async t => {
+
+ const container = new Container();
+
+ await container.configure({
+ foo: {
+ $type: Foo
+ },
+
+ box: {
+ $type: Bar,
+ params: {
+ $dependency: "foo"
+ }
+ },
+
+ bar: {
+ $type: Bar,
+ params: {
+ db: {
+ provider: {
+ $dependency: "db"
+ }
+ }
+ }
+ }
+ });
+ t.pass("should configure from js object");
+
+ const f1 = container.resolve("foo");
+
+ t.assert(!isNull(f1), "foo should be not null");
+
+ t.throws(() => container.resolve("bar"), "should not resolve dependency 'db'");
+
+});
+
+test("Load configuration from module", async t => {
+ const container = new Container();
+
+ await container.configure("../mock/config1", { contextRequire: require });
+ t.pass("The configuration should load");
+
+ const f1 = container.resolve("foo");
+
+ t.assert(!isNull(f1), "foo should be not null");
+
+ const b1 = container.resolve("bar") as Bar;
+
+ t.assert(!isNull(b1), "bar should not be null");
+ t.assert(!isNull(b1.foo), "bar.foo should not be null");
+});
diff --git a/src/test/ts/tests/ObservableTests.ts b/src/test/ts/tests/ObservableTests.ts
new file mode 100644
--- /dev/null
+++ b/src/test/ts/tests/ObservableTests.ts
@@ -0,0 +1,69 @@
+import { TraceSource } from "../log/TraceSource";
+import { Observable } from "../Observable";
+import { IObservable } from "../interfaces";
+import { delay } from "../safe";
+import { test } from "./TestTraits";
+
+const trace = TraceSource.get("ObservableTests");
+
+test("events sequence example", async t => {
+
+ let events: IObservable;
+
+ const done = new Promise(resolve => {
+ events = new Observable(async (notify, fail, finish) => {
+ for (let i = 0; i < 10; i++) {
+ await delay(0);
+ notify(i);
+ }
+ finish();
+ resolve();
+ });
+ });
+
+ let count = 0;
+ let complete = false;
+ events.on(x => count = count + x, null, () => complete = true);
+
+ const first = await events.next();
+
+ t.equals(first, 0, "the first event");
+ t.false(complete, "the sequence is not complete");
+
+ await done;
+
+ t.equals(count, 45, "the summ of the evetns");
+ t.true(complete, "the sequence is complete");
+});
+
+test("event sequence termination", async t => {
+ let events: IObservable;
+
+ const done = new Promise(resolve => {
+ events = new Observable(async (notify, fail, complete) => {
+ await delay(0);
+ notify(1);
+ complete();
+ notify(2);
+ complete();
+ fail("Sequence terminated");
+ resolve();
+ });
+ });
+
+ let count = 0;
+ events.on(() => {}, e => count++, () => count++);
+
+ const first = await events.next();
+ t.equals(first, 1, "the first message");
+ try {
+ await events.next();
+ t.fail("shoud throw an exception");
+ } catch (e) {
+ t.pass("the sequence is terminated");
+ }
+
+ await done;
+
+ t.equals(count, 1, "the sequence must be terminated once");
+});
diff --git a/src/test/ts/tests/SafeTests.ts b/src/test/ts/tests/SafeTests.ts
new file mode 100644
--- /dev/null
+++ b/src/test/ts/tests/SafeTests.ts
@@ -0,0 +1,95 @@
+import { Cancellation } from "../Cancellation";
+import { first, isPromise, firstWhere, delay, nowait } from "../safe";
+import { test } from "./TestTraits";
+
+test("await delay test", async t => {
+ // schedule delay
+ let resolved = false;
+ let res = delay(0).then(() => resolved = true);
+
+ t.false(resolved, "the delay should be async");
+
+ await res;
+ t.pass("await delay");
+
+ // create cancellation token
+ let cancel: (e?: any) => void;
+ const ct = new Cancellation(c => cancel = c);
+
+ // schedule delay
+ resolved = false;
+ res = delay(0, ct).then(() => resolved = true);
+
+ t.false(resolved, "created delay with ct");
+
+ // cancel
+ cancel();
+
+ try {
+ await res;
+ t.fail("the delay should fail when it is cancelled");
+ } catch {
+ t.pass("the delay is cancelled");
+ }
+
+ t.throws(() => {
+ // try schedule delay after the cancellation is requested
+ nowait(delay(0, ct));
+ }, "Should throw if cancelled before start");
+});
+
+test("sequemce test", async t => {
+ const sequence = ["a", "b", "c"];
+ const empty = [];
+
+ // synchronous tests
+ t.equals(first(sequence), "a", "Should return the first element");
+ t.equals(firstWhere(sequence, x => x === "b"), "b", "Should get the second element");
+
+ let v: string;
+ let e: Error;
+ first(sequence, x => v = x);
+ t.equal(v, "a", "The callback should be called for the first element");
+ firstWhere(sequence, x => x === "b", x => v = x);
+ t.equal(v, "b", "The callback should be called for the second element");
+
+ t.throws(() => {
+ first(empty);
+ }, "Should throw when the sequence is empty");
+
+ t.throws(() => {
+ firstWhere(empty, x => x === "b");
+ }, "Should throw when the sequence is empty");
+
+ t.throws(() => {
+ first(empty, x => v = x);
+ }, "Should throw when the sequence is empty");
+
+ t.throws(() => {
+ firstWhere(empty, x => x === "b", x => v = x);
+ }, "Should throw when the sequence is empty");
+
+ t.throws(() => {
+ firstWhere(sequence, x => x === "z");
+ }, "Should throw when the element isn't found");
+
+ t.throws(() => {
+ firstWhere(sequence, x => x === "z", x => v = x);
+ }, "Should throw when the element isn't found");
+
+ first(empty, null, x => e = x);
+ t.true(e, "The errorback should be called for the empty sequence");
+
+ // async tests
+ const asyncSequence = Promise.resolve(sequence);
+ const asyncEmptySequence = Promise.resolve(empty);
+
+ const promise = first(asyncSequence);
+ t.true(isPromise(promise), "Should return promise");
+
+ v = await promise;
+ t.equal(v, "a", "Should return the first element");
+
+ v = await new Promise(resolve => first(asyncSequence, resolve));
+ t.equal(v, "a", "The callback should be called for the first element");
+});
diff --git a/src/test/ts/tests/TestTraits.ts b/src/test/ts/tests/TestTraits.ts
new file mode 100644
--- /dev/null
+++ b/src/test/ts/tests/TestTraits.ts
@@ -0,0 +1,74 @@
+import { IObservable, ICancellation, IDestroyable } from "../interfaces";
+import { Cancellation } from "../Cancellation";
+import { TraceEvent, LogLevel, WarnLevel, DebugLevel, TraceSource } from "../log/TraceSource";
+import * as tape from "tape";
+import { argumentNotNull, destroy } from "../safe";
+
+export class TapeWriter implements IDestroyable {
+ private readonly _tape: tape.Test;
+
+ private readonly _subscriptions = new Array();
+ private _destroyed;
+
+ constructor(t: tape.Test) {
+ argumentNotNull(t, "tape");
+ this._tape = t;
+ }
+
+ writeEvents(source: IObservable, ct: ICancellation = Cancellation.none) {
+ if (!this._destroyed) {
+ const subscription = source.on(this.writeEvent.bind(this));
+ if (ct.isSupported()) {
+ ct.register(subscription.destroy.bind(subscription));
+ }
+ this._subscriptions.push(subscription);
+ }
+ }
+
+ writeEvent(next: TraceEvent) {
+ if (next.level >= DebugLevel) {
+ this._tape.comment(`DEBUG ${next.source.id} ${next}`);
+ } else if (next.level >= LogLevel) {
+ this._tape.comment(`LOG ${next.source.id} ${next}`);
+ } else if (next.level >= WarnLevel) {
+ this._tape.comment(`WARN ${next.source.id} ${next}`);
+ } else {
+ this._tape.comment(`ERROR ${next.source.id} ${next}`);
+ }
+ }
+
+ destroy() {
+ this._subscriptions.forEach(destroy);
+ }
+}
+
+export function test(name: string, cb: (t: tape.Test, trace: TraceSource) => any) {
+ tape(name, async t => {
+ const writer = new TapeWriter(t);
+
+ // this trace is not announced through the TraceSource global registry
+ const trace = new TraceSource(name);
+ trace.level = DebugLevel;
+ writer.writeEvents(trace.events);
+
+ const h = TraceSource.on(ts => {
+ ts.level = DebugLevel;
+ writer.writeEvents(ts.events);
+ });
+
+ try {
+ await cb(t, trace);
+ } catch (e) {
+
+ // verbose error information
+ // tslint:disable-next-line
+ console.error(e);
+ t.fail(e);
+
+ } finally {
+ t.end();
+ destroy(writer);
+ destroy(h);
+ }
+ });
+}
diff --git a/src/test/ts/tests/TextTests.ts b/src/test/ts/tests/TextTests.ts
new file mode 100644
--- /dev/null
+++ b/src/test/ts/tests/TextTests.ts
@@ -0,0 +1,86 @@
+import { StringBuilder } from "../text/StringBuilder";
+import { test } from "./TestTraits";
+import { MockConsole } from "../mock/MockConsole";
+import { ConsoleWriter } from "../log/ConsoleWriter";
+
+test("String builder", async t => {
+ const sb = new StringBuilder();
+
+ sb.write("hello");
+ t.equals(sb.toString(), "hello", "Write simple text");
+
+ sb.write(", ");
+ sb.write("world!");
+ t.equals(sb.toString(), "hello, world!", "Append text");
+
+ sb.clear();
+ t.equals(sb.toString(), "", "Clear");
+
+ sb.write(1);
+ t.equals(sb.toString(), "1", "Write number");
+
+ sb.clear();
+ sb.writeValue(0.123);
+ t.equals(sb.toString(), "0.123", "Format number");
+
+ sb.clear();
+ sb.writeValue(new Date("2019-01-02T00:00:00.000Z"));
+ t.equals(sb.toString(), "2019-01-02T00:00:00.000Z", "Format date (ISO)");
+
+ sb.clear();
+ sb.write("{0}", "hello");
+ t.equals(sb.toString(), "hello", "Simple format text");
+
+ sb.write(", {0}!", "world");
+ t.equals(sb.toString(), "hello, world!", "Append formatted text");
+
+ sb.clear();
+ sb.write("abc: {0:json}; {0.length}; {0.1} {{olo}}", ["a", "b", "c"]);
+ t.equals(sb.toString(), 'abc: [\n "a",\n "b",\n "c"\n]; 3; b {olo}', "Format string with spec");
+
+ sb.clear();
+ t.throws(() => sb.write("}", 0), "Should die on bad format: '}'");
+ t.throws(() => sb.write("{", 0), "Should die on bad format: '{'");
+ t.throws(() => sb.write("{}", 0), "Should die on bad format: '{}'");
+ t.throws(() => sb.write("{:}", 0), "Should die on bad format: '{:}'");
+ t.throws(() => sb.write("{{0}", 0), "Should die on bad format: '{{0}'");
+
+});
+
+test("ConsoleWriter", t => {
+ const mockConsole = new MockConsole();
+ const writer = new ConsoleWriter(mockConsole);
+
+ writer.setLogLevel("log");
+
+ writer.writeLine("Hello, world!");
+
+ t.equals(mockConsole.getBuffer().length, 1, "One line should be written");
+ t.equals(mockConsole.getBuffer()[0].level, "log", "LogLevel should be 'log'");
+ t.deepEqual(mockConsole.getBuffer()[0].data, ["Hello, world!"], "The buffer should contain single string");
+
+ mockConsole.clear();
+ writer.setLogLevel("debug");
+ writer.write("Bring ");
+ writer.write("the {0}!", "light");
+ t.equals(mockConsole.getBuffer().length, 0, "No line should be written");
+ writer.writeLine();
+
+ t.equals(mockConsole.getBuffer().length, 1, "One line should be written");
+ t.equals(mockConsole.getBuffer()[0].level, "debug", "LogLevel should be 'log'");
+ t.deepEqual(mockConsole.getBuffer()[0].data, ["Bring the light!"], "Should concatenate string parts together");
+
+ mockConsole.clear();
+ writer.writeLine("It's {0} o'clock, lets have some {1}!", { h: 5}, { title: "tee" });
+
+ t.deepEqual(mockConsole.getBuffer()[0].data, ["It's ", { h: 5}, " o'clock, lets have some ", { title: "tee" }, "!"], "Non string parts should be psassed as is");
+
+ mockConsole.clear();
+ writer.writeLine("{0} or {1} to {2}", {i: 25}, 6, 4);
+ t.deepEqual(mockConsole.getBuffer()[0].data, [{i: 25}, " or 6 to 4"], "25 or 6 to 4");
+
+ mockConsole.clear();
+ writer.writeLine("{0} or {1} to {2}! Let's have some {3}", 25, 6, 4, { product: "tee" } );
+ t.deepEqual(mockConsole.getBuffer()[0].data, ["25 or 6 to 4! Let's have some ", { product: "tee" }], "Should handle many text chunks and object at the end");
+
+});
diff --git a/src/test/ts/tests/TraceSourceTests.ts b/src/test/ts/tests/TraceSourceTests.ts
new file mode 100644
--- /dev/null
+++ b/src/test/ts/tests/TraceSourceTests.ts
@@ -0,0 +1,89 @@
+import { TraceSource, DebugLevel } from "../log/TraceSource";
+import * as tape from "tape";
+import { TapeWriter, test } from "./TestTraits";
+import { MockConsole } from "../mock/MockConsole";
+import { ConsoleLogger } from "../log/writers/ConsoleLogger";
+import { ConsoleWriter } from "../log/ConsoleWriter";
+
+const sourceId = "test/TraceSourceTests";
+
+tape("trace message", t => {
+ const trace = TraceSource.get(sourceId);
+
+ trace.level = DebugLevel;
+
+ const h = trace.events.on(ev => {
+ t.equal(ev.source, trace, "sender should be the current trace source");
+ t.equal(ev.level, DebugLevel, "level should be debug level");
+ t.equal(ev.toString(), "Hello, World!", "The message should be a formatted message");
+
+ t.end();
+ });
+
+ trace.debug("Hello, {0}!", "World");
+
+ h.destroy();
+});
+
+tape("trace event", t => {
+ const trace = TraceSource.get(sourceId);
+
+ trace.level = DebugLevel;
+
+ const event = {
+ name: "custom event"
+ };
+
+ const h = trace.events.on(ev => {
+ t.equal(ev.source, trace, "sender should be the current trace source");
+ t.equal(ev.level, DebugLevel, "level should be debug level");
+ t.equal(ev.message, event, "The message should be the specified object");
+
+ t.end();
+ });
+
+ trace.traceEvent(DebugLevel, event);
+
+ h.destroy();
+});
+
+tape("tape comment writer", async t => {
+ const writer = new TapeWriter(t);
+
+ TraceSource.on(ts => {
+ writer.writeEvents(ts.events);
+ });
+
+ const trace = TraceSource.get(sourceId);
+ trace.level = DebugLevel;
+
+ trace.log("Hello, {0}!", "World");
+ trace.log("Multi\n line");
+ trace.warn("Look at me!");
+ trace.error("DIE!");
+
+ writer.destroy();
+
+ trace.log("You shouldn't see it!");
+
+ t.comment("DONE");
+
+ t.end();
+});
+
+test("console writer", (t, trace) => {
+
+ const mockConsole = new MockConsole();
+ const writer = new ConsoleWriter(mockConsole);
+ const consoleLog = new ConsoleLogger(writer);
+ consoleLog.writeEvents(trace.events);
+
+ trace.log("Hello, world!");
+ t.deepEqual(mockConsole.getLine(0), ["console writer: Hello, world!"], "Log one string");
+
+ trace.log({ foo: "bar" });
+ t.deepEqual(mockConsole.getLine(1), ["console writer: ", { foo: "bar" }], "Log an object");
+
+ trace.log("json: {0:json}", { foo: "bar" });
+ t.deepEqual(mockConsole.getLine(2), ['console writer: json: {\n "foo": "bar"\n}'], "should convert to string substitutions with spec");
+});
diff --git a/src/test/ts/tests/dummy.ts b/src/test/ts/tests/dummy.ts
new file mode 100644
--- /dev/null
+++ b/src/test/ts/tests/dummy.ts
@@ -0,0 +1,13 @@
+import * as tape from "tape";
+import { Uuid } from "../Uuid";
+
+tape("simple", t => {
+ t.pass("sync assert");
+ setTimeout(() => {
+ t.pass("async assert");
+ t.comment(Uuid());
+ t.ok(Uuid() !== Uuid());
+ // end should be called after the last assertion
+ t.end();
+ }, 100);
+});
diff --git a/src/test/tsconfig.json b/src/test/tsconfig.json
--- a/src/test/tsconfig.json
+++ b/src/test/tsconfig.json
@@ -3,11 +3,10 @@
"compilerOptions": {
"rootDir": "ts",
"baseUrl": ".",
- "paths": {
- "@implab/core/*": [
- "../../build/dist/*"
- ]
- }
+ "rootDirs": [
+ "ts",
+ "../main/ts"
+ ]
},
"include" : [
"ts/**/*.ts"
diff --git a/src/testAmd/js/example.js b/src/testAmd/js/example.js
deleted file mode 100644
--- a/src/testAmd/js/example.js
+++ /dev/null
@@ -1,7 +0,0 @@
-define(["tape", "core/Uuid"], function(tape, Uuid) {
- "use strict";
- tape('uuid', function(t) {
- t.notEqual(Uuid(),Uuid());
- t.end();
- });
-});
\ No newline at end of file
diff --git a/src/testAmd/js/plan.js b/src/testAmd/js/plan.js
deleted file mode 100644
--- a/src/testAmd/js/plan.js
+++ /dev/null
@@ -1,10 +0,0 @@
-define([
- "./ActivatableTests",
- "./trace-test",
- "./TraceSourceTests",
- "./CancellationTests",
- "./ObservableTests",
- "./ContainerTests",
- "./SafeTests",
- "./TextTests"
-]);
\ No newline at end of file
diff --git a/src/testAmd/js/run-tests.js b/src/testAmd/js/run-tests.js
deleted file mode 100644
--- a/src/testAmd/js/run-tests.js
+++ /dev/null
@@ -1,22 +0,0 @@
-var rjs = require('requirejs');
-
-rjs.config({
- baseUrl: '.',
- packages: [{
- name: "@implab/core",
- location: "build/dist"
- },
- {
- name: "test",
- location: "build/test"
- },
- {
- name: "dojo",
- location: "node_modules/dojo"
- }
- ],
- nodeRequire: require
-});
-
-
-rjs(['test/plan']);
\ No newline at end of file
diff --git a/src/testAmd/js/tests/example.js b/src/testAmd/js/tests/example.js
new file mode 100644
--- /dev/null
+++ b/src/testAmd/js/tests/example.js
@@ -0,0 +1,7 @@
+define(["tape", "../Uuid"], function(tape, Uuid) {
+ "use strict";
+ tape('uuid', function(t) {
+ t.notEqual(Uuid(),Uuid());
+ t.end();
+ });
+});
\ No newline at end of file
diff --git a/src/testAmd/js/tests/index.js b/src/testAmd/js/tests/index.js
new file mode 100644
--- /dev/null
+++ b/src/testAmd/js/tests/index.js
@@ -0,0 +1,9 @@
+var rjs = require('requirejs');
+
+rjs.config({
+ baseUrl: '.',
+ nodeRequire: require
+});
+
+
+rjs(['./tests/plan']);
\ No newline at end of file
diff --git a/src/testAmd/js/tests/plan.js b/src/testAmd/js/tests/plan.js
new file mode 100644
--- /dev/null
+++ b/src/testAmd/js/tests/plan.js
@@ -0,0 +1,10 @@
+define([
+ "./ActivatableTests",
+ "./trace-test",
+ "./TraceSourceTests",
+ "./CancellationTests",
+ "./ObservableTests",
+ "./ContainerTests",
+ "./SafeTests",
+ "./TextTests"
+]);
\ No newline at end of file
diff --git a/src/testAmd/js/tests/trace-test.js b/src/testAmd/js/tests/trace-test.js
new file mode 100644
--- /dev/null
+++ b/src/testAmd/js/tests/trace-test.js
@@ -0,0 +1,30 @@
+define(["require", "tape"], function(require, tape) {
+ "use strict";
+ var sourceId = '73a633f3-eab8-49b0-8601-07cae710f234';
+ var sourceId2 = '3ba9c7cd-ed77-437b-9a2f-1cbeb1226b5b';
+ tape('Load TraceSource for the module', function(t) {
+ require(["../log/trace!" + sourceId, "../log/TraceSource"], function(trace, TraceSource_1) {
+ var TraceSource = TraceSource_1.TraceSource;
+ t.equal(trace && trace.id, sourceId, "trace should be taken from the loader plugin parameter");
+
+ var count = 0;
+
+ var h = TraceSource.on(function(x) {
+ if(x.id == sourceId || x.id == sourceId2)
+ count++;
+ });
+
+ t.equal(count, 1, "should see created channel immediatelly");
+ t.equal(trace, TraceSource.get(sourceId), "should get same TraceSource from registry");
+ t.equal(count, 1);
+
+ TraceSource.get(sourceId2);
+
+ t.equal(count, 2);
+
+ h.destroy();
+
+ t.end();
+ });
+ });
+});
\ No newline at end of file
diff --git a/src/testAmd/js/trace-test.js b/src/testAmd/js/trace-test.js
deleted file mode 100644
--- a/src/testAmd/js/trace-test.js
+++ /dev/null
@@ -1,30 +0,0 @@
-define(["tape"], function(tape) {
- "use strict";
- var sourceId = '73a633f3-eab8-49b0-8601-07cae710f234';
- var sourceId2 = '3ba9c7cd-ed77-437b-9a2f-1cbeb1226b5b';
- tape('Load TraceSource for the module', function(t) {
- require(["@implab/core/log/trace!" + sourceId, "@implab/core/log/TraceSource"], function(trace, TraceSource_1) {
- var TraceSource = TraceSource_1.TraceSource;
- t.equal(trace && trace.id, sourceId, "trace should be taken from the loader plugin parameter");
-
- var count = 0;
-
- var h = TraceSource.on(function(x) {
- if(x.id == sourceId || x.id == sourceId2)
- count++;
- });
-
- t.equal(count, 1, "should see created channel immediatelly");
- t.equal(trace, TraceSource.get(sourceId), "should get same TraceSource from registry");
- t.equal(count, 1);
-
- TraceSource.get(sourceId2);
-
- t.equal(count, 2);
-
- h.destroy();
-
- t.end();
- });
- });
-});
\ No newline at end of file
diff --git a/src/testCjs/ts/plan.ts b/src/testCjs/ts/plan.ts
deleted file mode 100644
--- a/src/testCjs/ts/plan.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import "./ActivatableTests";
-import "./TraceSourceTests";
-import "./CancellationTests";
-import "./ObservableTests";
-import "./ContainerTests";
-import "./SafeTests";
-import "./TextTests";
diff --git a/src/testCjs/ts/run-tests.ts b/src/testCjs/ts/run-tests.ts
deleted file mode 100644
--- a/src/testCjs/ts/run-tests.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-import "./plan";
diff --git a/src/testCjs/ts/tests/index.ts b/src/testCjs/ts/tests/index.ts
new file mode 100644
--- /dev/null
+++ b/src/testCjs/ts/tests/index.ts
@@ -0,0 +1,1 @@
+import "./plan";
diff --git a/src/testCjs/ts/tests/plan.ts b/src/testCjs/ts/tests/plan.ts
new file mode 100644
--- /dev/null
+++ b/src/testCjs/ts/tests/plan.ts
@@ -0,0 +1,7 @@
+import "./ActivatableTests";
+import "./TraceSourceTests";
+import "./CancellationTests";
+import "./ObservableTests";
+import "./ContainerTests";
+import "./SafeTests";
+import "./TextTests";
diff --git a/src/tsconfig.json b/src/tsconfig.json
--- a/src/tsconfig.json
+++ b/src/tsconfig.json
@@ -4,7 +4,6 @@
"noEmitOnError": true,
"listFiles": true,
"types": [],
- "lib": ["es5", "es2015.promise", "es2015.symbol", "dom", "scripthost"]
- },
- "files": []
+ "lib": ["es5", "es2015.promise", "es2015.symbol", "es2015.iterable", "dom", "scripthost"]
+ }
}
\ No newline at end of file
diff --git a/tslint.json b/tslint.json
--- a/tslint.json
+++ b/tslint.json
@@ -1,5 +1,6 @@
{
"extends": "tslint:recommended",
+ "defaultSeverity": "warn",
"rules": {
"align": [
true,