├── .editorconfig ├── .github ├── contributing.md └── issue_template.md ├── .gitignore ├── CHANGELOG.md ├── COMM-LICENSE ├── LICENSE ├── Makefile ├── README.adoc ├── code_of_conduct.md ├── doc └── version.adoc ├── java ├── .editorconfig ├── .gitignore ├── Makefile ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── stack-event │ ├── build.gradle │ └── src │ ├── main │ └── java │ │ └── io │ │ └── muoncore │ │ └── protocol │ │ └── event │ │ ├── ClientEvent.java │ │ ├── Event.java │ │ ├── EventBuilder.java │ │ ├── EventCodec.java │ │ ├── EventProtocolMessages.java │ │ ├── client │ │ ├── DefaultEventClient.java │ │ ├── EventClient.java │ │ ├── EventClientProtocol.java │ │ ├── EventProjectionControl.java │ │ ├── EventProjectionDescriptor.java │ │ ├── EventReplayControl.java │ │ ├── EventReplayMode.java │ │ └── EventResult.java │ │ └── server │ │ ├── EventServerProtocolStack.java │ │ └── EventWrapper.java │ └── test │ └── groovy │ └── io │ └── muoncore │ └── protocol │ ├── ChannelFunctionExecShimBecauseGroovyCantCallLambda.java │ └── event │ ├── client │ ├── EventClientProtocolSpec.groovy │ └── EventClientProtocolStackSpec.groovy │ └── integration │ ├── EventIntegrationSpec.groovy │ └── LoadSpec.groovy ├── javascript ├── .babelrc ├── .editorconfig ├── .npmignore ├── Makefile ├── package.json ├── src │ ├── MuonEventClient.ts │ └── protocol.ts ├── test │ └── event-test.js ├── tsconfig.json ├── tslint.json └── yarn.lock └── protocol └── .empty /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | insert_final_newline = true 5 | indent_style = space 6 | indent_size = 2 7 | 8 | # We recommend you to keep these unchanged 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | [{Makefile,**.mk}] 15 | indent_style = tab 16 | indent_size = 4 17 | -------------------------------------------------------------------------------- /.github/contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Issues 4 | 5 | When opening an issue: 6 | 7 | * include the full **backtrace** with your error 8 | * list versions you are using: Muon, Photon, AMQP, Java, Node .... 9 | 10 | It's always better to include more info rather than less. 11 | 12 | ## Code 13 | 14 | It's always best to open an issue before investing a lot of time into a 15 | fix or new functionality. Functionality must meet our design goals and 16 | vision for the project to be accepted; We would be happy to discuss how 17 | your idea can best fit into Muon 18 | 19 | ## Legal 20 | 21 | By submitting a Pull Request, you disavow any rights or claims to any changes 22 | submitted to the Muon project and assign the copyright of 23 | those changes to Muon Core Ltd, Registered in England and Wales. 24 | 25 | If you cannot or do not want to reassign those rights (your employment 26 | contract for your employer may not allow this), you should not submit a PR. 27 | Open an issue and someone else can do the work. 28 | 29 | This is a legal way of saying "If you submit a PR to us, that code becomes ours". 30 | 99.9% of the time that's what you intend anyways; we hope it doesn't scare you 31 | away from contributing. 32 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | Muon Version: 2 | Language: 3 | 4 | Services in Use: 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | xunit.xml 2 | *.iml 3 | *.ipr 4 | *.iws 5 | .idea/ 6 | node_modules/ 7 | muon.config 8 | test-results/ 9 | tempdocumentation/ 10 | distribution/ 11 | build/ 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [v0.0.9](https://github.com/muoncore/stack-event/tree/v0.0.9) (2018-03-04) 4 | [Full Changelog](https://github.com/muoncore/stack-event/compare/v0.0.8...v0.0.9) 5 | 6 | ## [v0.0.8](https://github.com/muoncore/stack-event/tree/v0.0.8) (2018-03-04) 7 | [Full Changelog](https://github.com/muoncore/stack-event/compare/v0.0.7...v0.0.8) 8 | 9 | ## [v0.0.7](https://github.com/muoncore/stack-event/tree/v0.0.7) (2018-03-03) 10 | [Full Changelog](https://github.com/muoncore/stack-event/compare/v0.0.6...v0.0.7) 11 | 12 | ## [v0.0.6](https://github.com/muoncore/stack-event/tree/v0.0.6) (2018-03-03) 13 | [Full Changelog](https://github.com/muoncore/stack-event/compare/v0.0.5...v0.0.6) 14 | 15 | ## [v0.0.5](https://github.com/muoncore/stack-event/tree/v0.0.5) (2018-03-03) 16 | [Full Changelog](https://github.com/muoncore/stack-event/compare/v0.0.4...v0.0.5) 17 | 18 | ## [v0.0.4](https://github.com/muoncore/stack-event/tree/v0.0.4) (2017-10-07) 19 | [Full Changelog](https://github.com/muoncore/stack-event/compare/v0.0.3...v0.0.4) 20 | 21 | ## [v0.0.3](https://github.com/muoncore/stack-event/tree/v0.0.3) (2017-09-02) 22 | [Full Changelog](https://github.com/muoncore/stack-event/compare/v0.0.2...v0.0.3) 23 | 24 | ## [v0.0.2](https://github.com/muoncore/stack-event/tree/v0.0.2) (2017-08-29) 25 | [Full Changelog](https://github.com/muoncore/stack-event/compare/v0.0.1...v0.0.2) 26 | 27 | **Closed issues:** 28 | 29 | - Make caused-by-id a string, to enable use as matched against order-id and also other ids [\#5](https://github.com/muoncore/stack-event/issues/5) 30 | - Add an optional entity ID to the event metadata [\#4](https://github.com/muoncore/stack-event/issues/4) 31 | 32 | ## [v0.0.1](https://github.com/muoncore/stack-event/tree/v0.0.1) (2017-06-25) 33 | 34 | 35 | \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* -------------------------------------------------------------------------------- /COMM-LICENSE: -------------------------------------------------------------------------------- 1 | END-USER LICENSE AGREEMENT 2 | 3 | ------------------------------------------------------------------------------ 4 | 5 | IMPORTANT: THIS SOFTWARE END-USER LICENSE AGREEMENT ("EULA") IS A LEGAL AGREEMENT (“Agreement”) BETWEEN YOU (THE CUSTOMER, EITHER AS AN INDIVIDUAL OR, IF PURCHASED OR OTHERWISE ACQUIRED BY OR FOR AN ENTITY, AS AN ENTITY) AND MUON CORE LTD. READ IT CAREFULLY BEFORE COMPLETING THE INSTALLATION PROCESS AND USING MUON AND RELATED SOFTWARE COMPONENTS (“SOFTWARE”). IT PROVIDES A LICENSE TO USE THE SOFTWARE AND CONTAINS WARRANTY INFORMATION AND LIABILITY DISCLAIMERS. BY INSTALLING AND USING THE SOFTWARE, YOU ARE CONFIRMING YOUR ACCEPTANCE OF THE SOFTWARE AND AGREEING TO BECOME BOUND BY THE TERMS OF THIS AGREEMENT. 6 | 7 | ------------------------------------------------------------------------------ 8 | 9 | In order to use the Software under this Agreement, you must receive a “Source URL” at the time of purchase, in accordance with the scope of use and other terms specified for each type of Software and as set forth in this Section 1 of this Agreement. 10 | 11 | 1. License Grant 12 | 13 | 1.1 General Use. This Agreement grants you a non-exclusive, non-transferable, limited license to the use rights for the Software, without the right to grant sublicenses, subject to the terms and conditions in this Agreement. The Software is licensed, not sold. 14 | 15 | 1.2 Unlimited Organization License. If you purchased an Organization License (included with the Muon Pro Software), you may install the Software on an unlimited number of Hosts. “Host” means any physical or virtual machine which is controlled by you. 16 | 17 | 1.3 Limited Organization License. If you purchased an Organization License (included with the Muon Enterprise Software), you may install the Software on an unlimited number of Hosts. “Host” means any physical or virtual machine which is controlled by you. 18 | 19 | 1.4 Archive Copies. You are entitled to make a reasonable amount of copies of the Software for archival purposes. Each copy must reproduce all copyright and other proprietary rights notices on or in the Software Product. 20 | 21 | 1.5 Electronic Delivery. All Software and license documentation shall be delivered by electronic means unless otherwise specified on the applicable invoice or at the time of purchase. Software shall be deemed delivered when it is made available for download by you (“Delivery”). 22 | 23 | 2. Modifications. Muon Core shall provide you with source code so that you can create Modifications of the original software. “Modification” means: (a) any addition to or deletion from the contents of a file included in the original Software or previous Modifications created by You, or (b) any new file that contains any part of the original Software or previous Modifications. While you retain all rights to any original work authored by you as part of the Modifications, We continue to own all copyright and other intellectual property rights in the Software. 24 | 25 | 3. Restricted Uses. 26 | 27 | 3.1 You shall not (and shall not allow any third party to): (a) decompile, disassemble, or otherwise reverse engineer the Software or attempt to reconstruct or discover any source code, underlying ideas, algorithms, file formats or programming interfaces of the Software by any means whatsoever (except and only to the extent that applicable law prohibits or restricts reverse engineering restrictions); (b) distribute, sell, sublicense, rent, lease or use the Software for time sharing, hosting, service provider or like purposes, except as expressly permitted under this Agreement; (c) redistribute the Software or Modifications other than by including the Software or a portion thereof within your own product, which must have substantially different functionality than the Software or Modifications and must not allow any third party to use the Software or Modifications, or any portions thereof, for software development or application development purposes; (d) redistribute the Software as part of a product, "appliance" or "virtual server"; (e) redistribute the Software on any server which is not directly under your control; (f) remove any product identification, proprietary, copyright or other notices contained in the Software; (g) modify any part of the Software, create a derivative work of any part of the Software (except as permitted in Section 4), or incorporate the Software, except to the extent expressly authorized in writing by Contributed Systems; (h) publicly disseminate performance information or analysis (including, without limitation, benchmarks) from any source relating to the Software; (i) utilize any equipment, device, software, or other means designed to circumvent or remove any form of Source URL or copy protection used by Contributed Systems in connection with the Software, or use the Software together with any authorization code, Source URL, serial number, or other copy protection device not supplied by Contributed Systems; (j) use the Software to develop a product which is competitive with any Contributed Systems product offerings; or (k) use unauthorized Source URLS or keycode(s) or distribute or publish Source URLs or keycode(s), except as may be expressly permitted by Contributed Systems in writing. If your unique Source URL is ever published, Contributed Systems reserves the right to terminate your access without notice. 28 | 29 | 3.2 UNDER NO CIRCUMSTANCES MAY YOU USE THE SOFTWARE AS PART OF A PRODUCT OR SERVICE THAT PROVIDES SIMILAR FUNCTIONALITY TO THE SOFTWARE ITSELF. 30 | 31 | The Open Source version of the Software (“LGPL Version”) is licensed 32 | under the terms of the GNU Lesser General Public License versions 3.0 33 | (“LGPL”) and not under this EULA. 34 | 35 | 4. Ownership. Notwithstanding anything to the contrary contained herein, except for the limited license rights expressly provided herein, Contributed Systems and its suppliers have and will retain all rights, title and interest (including, without limitation, all patent, copyright, trademark, trade secret and other intellectual property rights) in and to the Software and all copies, modifications and derivative works thereof (including any changes which incorporate any of your ideas, feedback or suggestions). You acknowledge that you are obtaining only a limited license right to the Software, and that irrespective of any use of the words “purchase”, “sale” or like terms hereunder no ownership rights are being conveyed to you under this Agreement or otherwise. 36 | 37 | 5. Fees and Payment. The Software license fees will be due and payable in full as set forth in the applicable invoice or at the time of purchase. If the Software does not function properly within two weeks of purchase, please contact us within those two weeks for a refund. You shall be responsible for all taxes, withholdings, duties and levies arising from the order (excluding taxes based on the net income of Contributed Systems). 38 | 39 | 6. Support, Maintenance and Services. Subject to the terms and conditions of this Agreement, as set forth in your invoice, and as set forth on the Muon Pro support page (https://muoncore.io/pro), support and maintenance services may be included with the purchase of your license subscription. 40 | 41 | 7. Term of Agreement. 42 | 43 | 7.1 Term. This Agreement is effective as of the Delivery of the Software and expires at such time as all license and service subscriptions hereunder have expired in accordance with their own terms (the “Term”). For clarification, the term of your license under this Agreement may be perpetual, limited for Evaluation Version, or designated as a fixed-term license in the Invoice, and shall be specified at your time of purchase. Either party may terminate this Agreement (including all related Invoices) if the other party: (a) fails to cure any material breach of this Agreement within thirty (30) days after written notice of such breach, provided that Contributed Systems may terminate this Agreement immediately upon any breach of Section 3 or if you exceed any other restrictions contained in Section 1, unless otherwise specified in this agreement; (b) ceases operation without a successor; or (c) seeks protection under any bankruptcy, receivership, trust deed, creditors arrangement, composition or comparable proceeding, or if any such proceeding is instituted against such party (and not dismissed within sixty (60) days)). Termination is not an exclusive remedy and the exercise by either party of any remedy under this Agreement will be without prejudice to any other remedies it may have under this Agreement, by law, or otherwise. 44 | 45 | 7.2 Termination. Upon any termination of this Agreement, you shall cease any and all use of any Software and destroy all copies thereof. 46 | 47 | 7.3 Expiration of License. Upon the expiration of any term under this Agreement, (a) all Software updates and services pursuant to the license shall cease, (b) you may only continue to run existing installations of the Software, (c) you may not install the Software on any additional Hosts, and (d) any new installation of the Software shall require the purchase of a new license subscription from Contributed Systems. 48 | 49 | 8. Disclaimer of Warranties. The Software is provided "as is," with all faults, defects and errors, and without warranty of any kind. Contributed Systems does not warrant that the Software will be free of bugs, errors, viruses or other defects, and Contributed Systems shall have no liability of any kind for the use of or inability to use the Software, the Software content or any associated service, and you acknowledge that it is not technically practicable for Contributed Systems to do so. 50 | To the maximum extent permitted by applicable law, Contributed Systems disclaims all warranties, express, implied, arising by law or otherwise, regarding the Software, the Software content and their respective performance or suitability for your intended use, including without limitation any implied warranty of merchantability, fitness for a particular purpose. 51 | 52 | 9. Limitation of Liability. 53 | 54 | In no event will Contributed Systems be liable for any direct, indirect, consequential, incidental, special, exemplary, or punitive damages or liabilities whatsoever arising from or relating to the Software, the Software content or this Agreement, whether based on contract, tort (including negligence), strict liability or other theory, even if Contributed Systems has been advised of the possibility of such damages. 55 | 56 | In no event will Contributed Systems' liability exceed the Software license price as indicated in the invoice. The existence of more than one claim will not enlarge or extend this limit. 57 | 58 | 10. Remedies. Your exclusive remedy and Contributed Systems’ entire liability for breach of this Agreement shall be limited, at Contributed Systems’ sole and exclusive discretion, to (a) replacement of any defective software or documentation; or (b) refund of the license fee paid to Contributed Systems, payable in accordance with Contributed Systems' refund policy. 59 | 60 | 11. Acknowledgements. 61 | 62 | 11.1 Consent to the Use of Data. You agree that Contributed Systems and its affiliates may collect and use technical information gathered as part of the product support services. Contributed Systems may use this information solely to improve products and services and will not disclose this information in a form that personally identifies you. 63 | 64 | 11.2 Verification. We or a certified auditor acting on our behalf, may, upon its reasonable request and at its expense, audit you with respect to the use of the Software. Such audit may be conducted by mail, electronic means or through an in-person visit to your place of business. Any such in-person audit shall be conducted during regular business hours at your facilities and shall not unreasonably interfere with your business activities. We shall not remove, copy, or redistribute any electronic material during the course of an audit. If an audit reveals that you are using the Software in a way that is in material violation of the terms of the EULA, then you shall pay our reasonable costs of conducting the audit. In the case of a material violation, you agree to pay Us any amounts owing that are attributable to the unauthorized use. In the alternative, We reserve the right, at our sole option, to terminate the licenses for the Software. 65 | 66 | 11.3 Government End Users. If the Software and related documentation are supplied to or purchased by or on behalf of the United States Government, then the Software is deemed to be "commercial software" as that term is used in the Federal Acquisition Regulation system. Rights of the United States shall not exceed the minimum rights set forth in FAR 52.227-19 for "restricted computer software". All other terms and conditions of this Agreement apply. 67 | 68 | 12. Third Party Software. Examples included in Software may provide links to third party libraries or code (collectively “Third Party Software”) to implement various functions. Third Party Software does not comprise part of the Software. In some cases, access to Third Party Software may be included along with the Software delivery as a convenience for demonstration purposes. Such source code and libraries may be included in the “…/examples” source tree delivered with the Software and do not comprise the Software. Licensee acknowledges (1) that some part of Third Party Software may require additional licensing of copyright and patents from the owners of such, and (2) that distribution of any of the Software referencing or including any portion of a Third Party Software may require appropriate licensing from such third parties. 69 | 70 | 71 | 13. Miscellaneous 72 | 73 | 13.1 Entire Agreement. This Agreement sets forth our entire agreement with respect to the Software and the subject matter hereof and supersedes all prior and contemporaneous understandings and agreements whether written or oral. 74 | 75 | 13.2 Amendment. Contributed Systems reserves the right, in its sole discretion, to amend this Agreement from time. Amendments to this Agreement can be located at: https://muoncore/COMM-LICENSE.html 76 | 77 | 13.3 Assignment. You may not assign this Agreement or any of its rights under this Agreement without the prior written consent of Contributed Systems and any attempted assignment without such consent shall be void. 78 | 79 | 13.4 Export Compliance. You agree to comply with all applicable laws and regulations, including laws, regulations, orders or other restrictions on export, re-export or redistribution of software. 80 | 81 | 13.5 Indemnification. You agree to defend, indemnify, and hold harmless Contributed Systems from and against any lawsuits, claims, losses, damages, fines and expenses (including attorneys' fees and costs) arising out of your use of the Software or breach of this Agreement. 82 | 83 | 13.6 Governing Law. This Agreement is governed by the laws of the England and Wales without regard to conflicts of laws provisions thereof, and without regard to the United Nations Convention on the International Sale of Goods or the Uniform Computer Information Transactions Act, as currently enacted by any jurisdiction or as may be codified or amended from time to time by any jurisdiction. The jurisdiction and venue for actions related to the subject matter hereof shall be England and Wales, and both parties hereby submit to the personal jurisdiction of such courts. 84 | 85 | 13.7 Attorneys’ Fees and Costs. The prevailing party in any action to enforce this Agreement will be entitled to recover its attorneys’ fees and costs in connection with such action. 86 | 87 | 13.8 Severability. If any provision of this Agreement is held by a court of competent jurisdiction to be invalid, illegal, or unenforceable, the remainder of this Agreement will remain in full force and effect. 88 | 89 | 13.9 Waiver. Failure or neglect by either party to enforce at any time any of the provisions of this licence Agreement shall not be construed or deemed to be a waiver of that party's rights under this Agreement. 90 | 91 | 13.10 Headings. The headings of sections and paragraphs of this Agreement are for convenience of reference only and are not intended to restrict, affect or be of any weight in the interpretation or construction of the provisions of such sections or paragraphs. 92 | 93 | 14. Contact Information. If you have any questions about this EULA, or if you want to contact Contributed Systems for any reason, please direct correspondence to info@muoncore.io 94 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Muon Core Ltd 2 | 3 | Muon is Free Software, licensed under the terms of 4 | the LGPLv3 license. Please see 5 | for license text. 6 | 7 | Muon has a commercial-friendly license allowing private forks 8 | and modifications of all projects. Please see http://muoncore.io/pro/ for 9 | more detail. You can find the commercial license terms in COMM-LICENSE. 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | publish: 2 | $(MAKE) -C java publish 3 | 4 | publish-snapshot: 5 | $(MAKE) -C java publish-snapshot 6 | $(MAKE) -C javascript publish-snapshot 7 | 8 | test: 9 | -$(MAKE) -C java test 10 | -$(MAKE) -C javascript test 11 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | |=== 2 | | Master Build | NPM Stable | Snapshots 3 | | image:https://img.shields.io/teamcity/http/teamcity.cloud.daviddawson.me/e/OpenSource_MuonReleases_Stacks_EventsSnapshot.svg[Status] 4 | | image:https://img.shields.io/npm/v/muon-stack-event.svg[NPM] 5 | | image:https://img.shields.io/npm/v/muon-stack-event/next.svg[NPM] 6 | |=== 7 | 8 | ## Event Persistence Muon Stack 9 | 10 | ## What is a Muon Stack? 11 | 12 | Muon is a set of libraries and services that let you build highly effective distributed systems that are message and event oriented. 13 | 14 | Muon is structured as a set of libraries, known as `muon-core` that give a set of infrastructure for building messaging systems. These are available in multiple languages and handle the concerns of discovery, transport, encoding and managing failures. On top of these, the exact messaging semantics that you want to express are built. These are built as a "stack", a set of channels, agents and finally a user facing API that you will use in your application code. 15 | 16 | Muon has several such stacks, covering different scenarios and tasks, letting you communicate in various ways, highly distributed, cross platform and taking advantage of best of breed infrastructure and technologies. 17 | 18 | ## What is Event Persistence? 19 | 20 | Event Driven Architectures (EDA) are a way for systems and components to interact based on the _things that have happened to them_, the events about them. Common problems with EDA are that : 21 | 22 | * events can go missing when network transported 23 | * events can be missed if a component is offline 24 | * the history is often useful for stream processing analysis, trend detection and the like. 25 | 26 | Persisting your events into an event store that permits events so be replayed on demand solves these issues. It allows your applications to emit events, observe them and then selectively replay the streams that you are interested in at some later point as well. 27 | 28 | This stack implements an event streaming API client. You can use it to interact with a remote event store, emit events and replay streams on demand. 29 | 30 | The server side is implemented by link:https://github.com/muoncore/photon[Photon] (A Clojure based Event Store with functional event Projections), link:https://github.com/muoncore/photonlite[PhotonLite] (an event stream API layer) or any other service (local or remote) that implements the server side of this protocol. This gives you the ability to vary the implementation of your event store, including having different event stores for different streams. 31 | 32 | ## Using this stack 33 | 34 | First, you need to start up one of the event stores. If you have used the link:https://github.com/muoncore/muonstarter[Muon Starter] then you have this running already. 35 | 36 | ### JVM 37 | 38 | To use the stack in Java, first import Muon, a transport/ discovery and the Event Stack 39 | 40 | *build.gradle* 41 | [source, groovy] 42 | ---- 43 | repositories { 44 | jcenter() 45 | maven { url 'https://simplicityitself.artifactoryonline.com/simplicityitself/muon' } 46 | maven { url 'https://simplicityitself.artifactoryonline.com/simplicityitself/muon-snapshot' } 47 | } 48 | 49 | dependencies { 50 | compile "io.muoncore:muon-core:" 51 | compile "io.muoncore:muon-transport-amqp:" 52 | compile "io.muoncore:muon-discovery-amqp:" 53 | compile "io.muoncore.protocol:stack-event:" 54 | } 55 | ---- 56 | 57 | #### Create an Event Client 58 | 59 | This stack allows you to emit events and replay them. For replay, it exposes an API that uses Reactive Streams Publisher/ Subscribers to manage the subscription. 60 | 61 | First then, you need to be able to obtain a Subscriber. If you don't have one already, use a FRP system of some kind to make one. Consider using Spring Reactor, Akka Streams or RxJava, amongst others. 62 | 63 | [source, java] 64 | ---- 65 | 66 | Muon muon = .. create a muon ..; 67 | 68 | DefaultEventClient events = new DefaultEventClient(muon); 69 | 70 | 71 | events.event( 72 | ClientEvent.ofType("UserRegistered") 73 | .payload(new UserRegistered("Roger", "Rabbit")) 74 | .stream("users") 75 | .build()); 76 | 77 | Subscriber subscriber = .. your subscriber .. 78 | 79 | Map args = ... 80 | 81 | /* 82 | available args:- 83 | 84 | * from - the event order-id to replay from 85 | 86 | */ 87 | 88 | 89 | events.replay( 90 | "users", 91 | EventReplayMode.REPLAY_THEN_LIVE, 92 | args, 93 | subscriber); 94 | 95 | ---- 96 | 97 | You can use these to selectively replay certain streams, play them back 98 | 99 | ### Node.js 100 | 101 | To use the client event stack, import Muon, disco/ transport and the stack. This requires the reactive streams stack to be present. 102 | 103 | ``` 104 | npm install --save muon-core@next 105 | npm install --save muon-amqp@next #or, any other transport+discovery here 106 | npm install --save muon-stack-reactive-streams@next 107 | npm install --save muon-stack-event@next 108 | ``` 109 | 110 | Then, create a Muon instance and attach the Event client stack 111 | 112 | *index.js* 113 | [source, javascript] 114 | ---- 115 | var Muon = require("muon-core") 116 | 117 | var muonurl = process.env.MUON_URL || "amqp://muon:microservices@localhost" 118 | 119 | var muon = Muon.create("hello-world-node", muonurl); <1> 120 | 121 | require("muon-stack-reactive-streams").create(muon) 122 | require("muon-stack-event").create(muon) <2> 123 | 124 | var args = { 125 | from: , 126 | stream-type: cold | hot | hot-cold, 127 | } 128 | 129 | 130 | muon.emit({ <3> 131 | "event-type": "UserRegistered", 132 | "stream-name": "users", 133 | "service-id": "my-service", 134 | payload: { 135 | firstname: "John", 136 | lastname: "Simples" 137 | } 138 | }).then(function (resp) { 139 | logger.info("Slack message persisted") 140 | }) 141 | 142 | 143 | muon.replay("user",{}, <4> 144 | function(data) { 145 | // on data received 146 | }, 147 | function(error) { 148 | // on error 149 | }, 150 | function() { 151 | // on complete 152 | } 153 | ) 154 | 155 | ---- 156 | <1> Create a new Muon instance, connecting to a local AMQP broker for discovery and transport 157 | <2> Add the event stack, in addition to the reactive streams stack. 158 | <3> Use the added `emit` method to persist events 159 | <3> Use the added `replay` method to replay historical events and continue to listen to new events 160 | 161 | ## Getting involved/ adding to this stack. 162 | 163 | Additions and extensions to this stack are very welcome. 164 | 165 | Particularly of interest are :- 166 | 167 | * Added language support 168 | * Integrate with javascript FRP libraries. 169 | 170 | ## License 171 | 172 | All code is Copyright (c) Muon Core Ltd 2017. 173 | 174 | Muon is Free Software, licensed under the terms of 175 | the LGPLv3 license as included in link:LICENSE[] 176 | 177 | Muon has a commercial-friendly license allowing private forks and closed modifications of all projects, alongside enterprise support and extended support for enterprise technologies and patterns. 178 | 179 | This will enable you to use Muon in any situation where your legal team will not accept a Free Software license. 180 | 181 | Please see http://muoncore.io/pro/ for more detail. You can find the commercial license terms in link:COMM-LICENSE[] 182 | -------------------------------------------------------------------------------- /code_of_conduct.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, and in the interest of 4 | fostering an open and welcoming community, we pledge to respect all people who 5 | contribute through reporting issues, posting feature requests, updating 6 | documentation, submitting pull requests or patches, and other activities. 7 | 8 | We are committed to making participation in this project a harassment-free 9 | experience for everyone, regardless of level of experience, gender, gender 10 | identity and expression, sexual orientation, disability, personal appearance, 11 | body size, race, ethnicity, age, religion, or nationality. 12 | 13 | Examples of unacceptable behavior by participants include: 14 | 15 | * The use of sexualized language or imagery 16 | * Personal attacks 17 | * Trolling or insulting/derogatory comments 18 | * Public or private harassment 19 | * Publishing other's private information, such as physical or electronic 20 | addresses, without explicit permission 21 | * Other unethical or unprofessional conduct 22 | 23 | Project maintainers have the right and responsibility to remove, edit, or 24 | reject comments, commits, code, wiki edits, issues, and other contributions 25 | that are not aligned to this Code of Conduct, or to ban temporarily or 26 | permanently any contributor for other behaviors that they deem inappropriate, 27 | threatening, offensive, or harmful. 28 | 29 | By adopting this Code of Conduct, project maintainers commit themselves to 30 | fairly and consistently applying these principles to every aspect of managing 31 | this project. Project maintainers who do not follow or enforce the Code of 32 | Conduct may be permanently removed from the project team. 33 | 34 | This Code of Conduct applies both within project spaces and in public spaces 35 | when an individual is representing the project or its community. 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 38 | reported by contacting the project maintainer at mperham AT gmail.com. All 39 | complaints will be reviewed and investigated and will result in a response that 40 | is deemed necessary and appropriate to the circumstances. Maintainers are 41 | obligated to maintain confidentiality with regard to the reporter of an 42 | incident. 43 | 44 | 45 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 46 | version 1.3.0, available at 47 | [http://contributor-covenant.org/version/1/3/0/][version] 48 | 49 | [homepage]: http://contributor-covenant.org 50 | [version]: http://contributor-covenant.org/version/1/3/0/ 51 | -------------------------------------------------------------------------------- /doc/version.adoc: -------------------------------------------------------------------------------- 1 | The current version is 0.0.9 2 | -------------------------------------------------------------------------------- /java/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | insert_final_newline = true 5 | indent_style = space 6 | indent_size = 2 7 | 8 | # We recommend you to keep these unchanged 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | [{Makefile,**.mk}] 15 | indent_style = tab 16 | indent_size = 4 17 | -------------------------------------------------------------------------------- /java/.gitignore: -------------------------------------------------------------------------------- 1 | xunit.xml 2 | *.iml 3 | *.ipr 4 | *.iws 5 | .idea/ 6 | node_modules/ 7 | muon.config 8 | test-results/ 9 | tempdocumentation/ 10 | distribution/ 11 | build/ 12 | .gradle/ 13 | -------------------------------------------------------------------------------- /java/Makefile: -------------------------------------------------------------------------------- 1 | 2 | install: test 3 | ./gradlew install 4 | 5 | publish-snapshot: clean 6 | ./gradlew artifactoryPublish 7 | 8 | publish: clean 9 | ifndef VERSION 10 | $(error VERSION is undefined for Stack Release) 11 | endif 12 | echo "#DO NOT EDIT MANUALLY. Change in Makefile">gradle.properties 13 | echo version=$(VERSION)>>gradle.properties 14 | echo group=io.muoncore.protocol>>gradle.properties 15 | echo exclude=>>gradle.properties 16 | ./gradlew artifactoryPublish 17 | git add gradle.properties 18 | git commit -m "Update version to $(VERSION )while publishing" 19 | git push origin 20 | 21 | test: 22 | ./gradlew --refresh-dependencies check 23 | 24 | clean: 25 | ./gradlew clean 26 | 27 | testextended: 28 | ./gradlew check 29 | 30 | -------------------------------------------------------------------------------- /java/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenLocal() 4 | jcenter() 5 | maven { 6 | url 'http://maven.tmatesoft.com/content/repositories/releases/' 7 | } 8 | maven { 9 | url "https://plugins.gradle.org/m2/" 10 | } 11 | maven { 12 | url "http://artifactory.cloud.daviddawson.me/artifactory/muon" 13 | } 14 | } 15 | dependencies { 16 | classpath 'io.muoncore.release:muon-java-release:0.0.10' 17 | classpath(group: 'org.jfrog.buildinfo', name: 'build-info-extractor-gradle', version: '3.2.0') 18 | classpath "io.franzbecker:gradle-lombok:1.8" 19 | } 20 | } 21 | 22 | apply plugin: 'io.muoncore.release' 23 | 24 | -------------------------------------------------------------------------------- /java/gradle.properties: -------------------------------------------------------------------------------- 1 | #DO NOT EDIT MANUALLY. Change in Makefile 2 | version=0.0.10 3 | group=io.muoncore.protocol 4 | exclude= 5 | -------------------------------------------------------------------------------- /java/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muoncore/stack-event/aad6dca346984f6014b8e2e028c48b87897094c1/java/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /java/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Oct 07 14:04:54 BST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /java/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /java/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /java/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name="stack-event" 2 | 3 | include "stack-event" 4 | -------------------------------------------------------------------------------- /java/stack-event/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin:"groovy" 2 | 3 | repositories { 4 | maven { 5 | url "http://artifactory.cloud.daviddawson.me/artifactory/muon" 6 | } 7 | } 8 | 9 | dependencies { 10 | compile "io.muoncore:muon-core:7.4.1" 11 | compile "io.muoncore.protocol:stack-reactive-streams:0.0.7" 12 | testCompile 'org.slf4j:slf4j-simple:1.7.12' 13 | } 14 | 15 | 16 | task sourceJar(type: Jar) { 17 | from sourceSets.main.allJava 18 | } 19 | task packageJavadoc(type: Jar) { 20 | from javadoc 21 | classifier = 'javadoc' 22 | } 23 | 24 | 25 | publishing { 26 | publications { 27 | mavenJava(MavenPublication) { 28 | artifact sourceJar { 29 | classifier "sources" 30 | } 31 | artifact packageJavadoc 32 | pom.withXml { 33 | asNode().appendNode('name', "Muon Event Log API") 34 | asNode().appendNode('description', 'Muon is a toolkit for building highly portable, polyglot, reactive APIs. This implements the Event Log class of APIs, across any Muon transport') 35 | asNode().appendNode('url', 'http://muoncore.io') 36 | def license = asNode().appendNode("licenses").appendNode("license") 37 | license.appendNode("name", "The GNU Lesser General Public License, Version 3.0") 38 | license.appendNode("url", "http://www.gnu.org/licenses/lgpl-3.0.txt") 39 | license.appendNode("distribution", "repo") 40 | 41 | asNode().appendNode("scm").appendNode("url", "https://github.com/muoncore/stack-event") 42 | 43 | def developers = asNode().appendNode("developers") 44 | def dev = developers.appendNode("developer") 45 | dev.appendNode("name", "Muon Developers") 46 | dev.appendNode("email", "info@muoncore.io") 47 | dev.appendNode("organization", "Muon Project") 48 | dev.appendNode("organizationUrl", "http://muoncore.io") 49 | 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/ClientEvent.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event; 2 | 3 | import lombok.Getter; 4 | import lombok.ToString; 5 | 6 | /** 7 | * An event created by a client, ready to be passed to an event store for persistence and canonicalisation 8 | */ 9 | @ToString 10 | public class ClientEvent { 11 | 12 | @Getter 13 | private String id; 14 | private String eventType; 15 | private String streamName; 16 | private Object payload; 17 | 18 | private String causedById; 19 | private String causedByRelation; 20 | private String schema; 21 | 22 | public ClientEvent( 23 | String id, 24 | String eventType, 25 | String streamName, 26 | String schema, 27 | String causedById, 28 | String causedByRelation, 29 | Object payload) { 30 | this.id = id; 31 | this.schema = schema; 32 | this.eventType = eventType; 33 | this.streamName = streamName; 34 | this.payload = payload; 35 | this.causedById = causedById; 36 | this.causedByRelation = causedByRelation; 37 | } 38 | 39 | public String getSchema() { 40 | return schema; 41 | } 42 | 43 | public String getEventType() { 44 | return eventType; 45 | } 46 | 47 | public String getStreamName() { 48 | return streamName; 49 | } 50 | 51 | public Object getPayload() { 52 | return payload; 53 | } 54 | 55 | public String getCausedById() { 56 | return causedById; 57 | } 58 | 59 | public String getCausedByRelation() { 60 | return causedByRelation; 61 | } 62 | 63 | public static EventBuilder ofType(String type) { 64 | return new EventBuilder().eventType(type); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/Event.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import io.muoncore.codec.Codecs; 5 | import lombok.Getter; 6 | import lombok.ToString; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * A canonical Event for Muon 12 | */ 13 | @Getter 14 | @ToString 15 | public class Event { 16 | 17 | private String id; 18 | @SerializedName("event-type") 19 | private String eventType; 20 | @SerializedName("stream-name") 21 | private String streamName; 22 | 23 | private String schema; 24 | @SerializedName("caused-by-id") 25 | private String causedById; 26 | @SerializedName("caused-by-relation") 27 | private String causedByRelation; 28 | 29 | @SerializedName("service-id") 30 | private String service; 31 | @SerializedName("order-id") 32 | private Long orderId; 33 | @SerializedName("event-time") 34 | private Long eventTime; 35 | private Map payload; 36 | private transient Codecs codecs; 37 | 38 | public Event(String id, String eventType, String streamName, String schema, String causedById, String causedByRelation, String service, Long orderId, Long eventTime, Map payload, Codecs codecs) { 39 | this.id = id; 40 | this.eventType = eventType; 41 | this.streamName = streamName; 42 | this.schema = schema; 43 | this.causedById = causedById; 44 | this.causedByRelation = causedByRelation; 45 | this.service = service; 46 | this.orderId = orderId; 47 | this.eventTime = eventTime; 48 | this.payload = payload; 49 | this.codecs = codecs; 50 | } 51 | 52 | public void setCodecs(Codecs codecs) { 53 | this.codecs = codecs; 54 | } 55 | 56 | public String getEventType() { 57 | return eventType; 58 | } 59 | 60 | public String getStreamName() { 61 | return streamName; 62 | } 63 | 64 | public String getSchema() { 65 | return schema; 66 | } 67 | 68 | public String getCausedById() { 69 | return causedById; 70 | } 71 | 72 | public String getCausedByRelation() { 73 | return causedByRelation; 74 | } 75 | 76 | public String getService() { 77 | return service; 78 | } 79 | 80 | public Long getOrderId() { 81 | return orderId; 82 | } 83 | 84 | public Long getEventTime() { 85 | return eventTime; 86 | } 87 | 88 | public X getPayload(Class type) { 89 | if (type.isAssignableFrom(Map.class)) { 90 | return (X) payload; 91 | } 92 | Codecs.EncodingResult result = codecs.encode(payload, new String[]{"application/json"}); 93 | return codecs.decode(result.getPayload(), result.getContentType(), type); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/EventBuilder.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event; 2 | 3 | /** 4 | * Construct a ClientEvent using a fluent builder. 5 | */ 6 | public class EventBuilder { 7 | private String id; 8 | private Object payload; 9 | private String eventType; 10 | private String streamName = "default"; 11 | 12 | private String causedById; 13 | private String causedByRelation; 14 | private String schema; 15 | 16 | /** 17 | * The payload of this event. can be any object that can be serialised using an existing codec. 18 | *

19 | * Optional. 20 | */ 21 | public EventBuilder payload(Object payload) { 22 | this.payload = payload; 23 | return this; 24 | } 25 | 26 | /** 27 | * Set the schema version of this event. This can be used later on during projection or replay 28 | * to enable auto upgrade of the event schema during replay and projection. 29 | *

30 | * Optional 31 | */ 32 | public EventBuilder schema(String schema) { 33 | this.schema = schema; 34 | return this; 35 | } 36 | 37 | /** 38 | * The event type. This gives the event an identity 39 | *

40 | * Mandatory. 41 | */ 42 | public EventBuilder eventType(String eventType) { 43 | this.eventType = eventType; 44 | return this; 45 | } 46 | 47 | public EventBuilder id(String id) { 48 | this.id = id; 49 | return this; 50 | } 51 | 52 | /** 53 | * Which stream this event should persist on. 54 | *

55 | * if not supplied, will be set to 'default' 56 | */ 57 | public EventBuilder stream(String streamName) { 58 | this.streamName = streamName; 59 | return this; 60 | } 61 | 62 | /** 63 | * Add a causal relationship to another event. 64 | *

65 | * Optional 66 | */ 67 | public EventBuilder causedBy(String causedById, String relation) { 68 | this.causedById = causedById; 69 | this.causedByRelation = relation; 70 | return this; 71 | } 72 | 73 | public ClientEvent build() { 74 | return new ClientEvent( 75 | id, 76 | eventType, 77 | streamName, 78 | schema, 79 | causedById, 80 | causedByRelation, 81 | payload); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/EventCodec.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event; 2 | 3 | import io.muoncore.codec.Codecs; 4 | import io.muoncore.config.AutoConfiguration; 5 | import io.muoncore.protocol.Auth; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | public class EventCodec { 11 | 12 | private static final String ID = "id"; 13 | private static final String STREAM_NAME = "stream-name"; 14 | private static final String PAYLOAD = "payload"; 15 | private static final String EVENT_TYPE = "event-type"; 16 | private static final String CAUSED_BY = "caused-by"; 17 | private static final String CAUSED_BY_RELATION = "caused-by-relation"; 18 | private static final String SERVICE = "service-id"; 19 | private static final String ORDER_ID = "order-id"; 20 | private static final String EVENT_TIME = "event-time"; 21 | private static final String SCHEMA = "schema"; 22 | 23 | 24 | public static Auth getAuthFromMap(Map data, Codecs codecs) { 25 | return new Auth( 26 | (String) data.get("provider"), 27 | (String) data.get("token") 28 | ); 29 | } 30 | 31 | public static Event getEventFromMap(Map data, Codecs codecs) { 32 | return new Event( 33 | (String) data.get(ID), 34 | (String) data.get(EVENT_TYPE), 35 | (String) data.get(STREAM_NAME), 36 | (String) data.get(SCHEMA), 37 | getAsString(data.get(CAUSED_BY)), 38 | (String) data.get(CAUSED_BY_RELATION), 39 | (String) data.get(SERVICE), 40 | getAsLong(data.get(ORDER_ID)), 41 | getAsLong(data.get(EVENT_TIME)), 42 | (Map)data.get(PAYLOAD), 43 | codecs 44 | ); 45 | } 46 | 47 | private static Long getAsLong(Object val) { 48 | if (val instanceof Double) { 49 | Double dat = (Double) val; 50 | return dat.longValue(); 51 | } else if (val instanceof String) { 52 | return Long.valueOf((String) val); 53 | } 54 | return null; 55 | } 56 | 57 | private static String getAsString(Object val) { 58 | if (val instanceof Double) { 59 | Double dat = (Double) val; 60 | return String.valueOf(dat.longValue()); 61 | } 62 | return String.valueOf(val); 63 | } 64 | 65 | public static Map getMapFromClientEvent(ClientEvent event, Auth auth, AutoConfiguration config) { 66 | Map payload = new HashMap<>(); 67 | payload.put(ID, event.getId()); 68 | payload.put(STREAM_NAME, event.getStreamName()); 69 | payload.put(PAYLOAD, event.getPayload()); 70 | payload.put(EVENT_TYPE, event.getEventType()); 71 | payload.put(CAUSED_BY, event.getCausedById()); 72 | payload.put(CAUSED_BY_RELATION, event.getCausedByRelation()); 73 | payload.put(SERVICE, config.getServiceName()); 74 | payload.put(SCHEMA, event.getSchema()); 75 | payload.put("provider", auth.getProvider()); 76 | payload.put("token", auth.getToken()); 77 | return payload; 78 | } 79 | 80 | public static Map getMapFromEvent(Event event) { 81 | Map payload = new HashMap<>(); 82 | payload.put(ID, event.getId()); 83 | payload.put(STREAM_NAME, event.getStreamName()); 84 | payload.put(PAYLOAD, event.getPayload(Map.class)); 85 | payload.put(EVENT_TYPE, event.getEventType()); 86 | payload.put(CAUSED_BY, event.getCausedById()); 87 | payload.put(CAUSED_BY_RELATION, event.getCausedByRelation()); 88 | payload.put(SERVICE, event.getService()); 89 | payload.put(ORDER_ID, event.getOrderId()); 90 | payload.put(EVENT_TIME, event.getEventTime()); 91 | payload.put(SCHEMA, event.getSchema()); 92 | return payload; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/EventProtocolMessages.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event; 2 | 3 | public class EventProtocolMessages { 4 | public final static String PROTOCOL="event"; 5 | public final static String EVENT_RESULT ="EventProcessed"; 6 | public final static String EVENT ="EventEmitted"; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/client/DefaultEventClient.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.client; 2 | 3 | import io.muoncore.Discovery; 4 | import io.muoncore.Muon; 5 | import io.muoncore.ServiceDescriptor; 6 | import io.muoncore.api.ChannelFutureAdapter; 7 | import io.muoncore.api.MuonFuture; 8 | import io.muoncore.channel.Channel; 9 | import io.muoncore.channel.Channels; 10 | import io.muoncore.codec.Codecs; 11 | import io.muoncore.config.AutoConfiguration; 12 | import io.muoncore.exception.MuonException; 13 | import io.muoncore.message.MuonInboundMessage; 14 | import io.muoncore.message.MuonOutboundMessage; 15 | import io.muoncore.protocol.Auth; 16 | import io.muoncore.protocol.event.ClientEvent; 17 | import io.muoncore.protocol.event.Event; 18 | import io.muoncore.protocol.reactivestream.client.ReactiveStreamClient; 19 | import io.muoncore.protocol.reactivestream.client.StreamData; 20 | import io.muoncore.transport.client.TransportClient; 21 | import org.reactivestreams.Subscriber; 22 | import org.reactivestreams.Subscription; 23 | 24 | import java.net.URI; 25 | import java.net.URISyntaxException; 26 | import java.util.Collections; 27 | import java.util.HashMap; 28 | import java.util.Map; 29 | import java.util.Optional; 30 | import java.util.concurrent.ExecutionException; 31 | import java.util.stream.Collectors; 32 | 33 | public class DefaultEventClient implements EventClient { 34 | 35 | private AutoConfiguration config; 36 | private Discovery discovery; 37 | private Codecs codecs; 38 | private TransportClient transportClient; 39 | private ReactiveStreamClient reactiveStreamClientProtocolStack; 40 | 41 | private Muon muon; 42 | 43 | public DefaultEventClient(Muon muon) { 44 | this.muon = muon; 45 | this.config = muon.getConfiguration(); 46 | this.discovery = muon.getDiscovery(); 47 | this.codecs = muon.getCodecs(); 48 | this.transportClient = muon.getTransportClient(); 49 | this.reactiveStreamClientProtocolStack = new ReactiveStreamClient(muon); 50 | } 51 | 52 | @Override 53 | public MuonFuture eventAsync(ClientEvent event, Auth auth) { 54 | Channel api2eventproto = Channels.channel("eventapi", "eventproto"); 55 | 56 | ChannelFutureAdapter adapter = 57 | new ChannelFutureAdapter<>(api2eventproto.left()); 58 | 59 | Channel timeoutChannel = Channels.timeout(muon.getScheduler(), 1000); 60 | 61 | new EventClientProtocol<>( 62 | config, 63 | discovery, 64 | codecs, 65 | auth, 66 | api2eventproto.right(), 67 | timeoutChannel.left()); 68 | 69 | Channels.connect(timeoutChannel.right(), transportClient.openClientChannel()); 70 | 71 | return adapter.request(event); 72 | } 73 | 74 | 75 | @Override 76 | public EventResult event(ClientEvent event, Auth auth) { 77 | try { 78 | Channel api2eventproto = Channels.channel("eventapi", "eventproto"); 79 | 80 | ChannelFutureAdapter adapter = 81 | new ChannelFutureAdapter<>(api2eventproto.left()); 82 | 83 | Channel timeoutChannel = Channels.timeout(muon.getScheduler(), 1000); 84 | 85 | new EventClientProtocol<>( 86 | config, 87 | discovery, 88 | codecs, 89 | auth, 90 | api2eventproto.right(), 91 | timeoutChannel.left()); 92 | 93 | Channels.connect(timeoutChannel.right(), transportClient.openClientChannel()); 94 | 95 | return adapter.request(event).get(); 96 | } catch (InterruptedException | ExecutionException e) { 97 | throw new MuonException(e); 98 | } 99 | } 100 | 101 | @Override 102 | public MuonFuture replay(String streamName, Auth auth, EventReplayMode mode, Subscriber subscriber) { 103 | return replay(streamName, auth, mode, Collections.emptyMap(), subscriber); 104 | } 105 | 106 | @Override 107 | public MuonFuture replay(String streamName, Auth auth, EventReplayMode mode, Map args, Subscriber subscriber) { 108 | String replayType; 109 | switch (mode) { 110 | case LIVE_ONLY: 111 | replayType = "hot"; 112 | break; 113 | case REPLAY_ONLY: 114 | replayType = "cold"; 115 | break; 116 | case REPLAY_THEN_LIVE: 117 | default: 118 | replayType = "hot-cold"; 119 | } 120 | 121 | //TODO, manage a params object and turn it into a querystring. 122 | Map params = new HashMap<>(); 123 | params.put("stream-type", replayType); 124 | params.put("stream-name", streamName); 125 | 126 | params.putAll(args); 127 | 128 | String query = params.entrySet() 129 | .stream() 130 | .map(entry -> entry.getKey() + "=" + entry.getValue()) 131 | .collect(Collectors.joining("&")); 132 | 133 | 134 | Optional eventStore = discovery.getServiceWithTags("eventstore"); 135 | if (eventStore.isPresent()) { 136 | String eventStoreName = eventStore.get().getIdentifier(); 137 | try { 138 | reactiveStreamClientProtocolStack.subscribe(new URI("stream://" + eventStoreName + "/stream?" + query), auth, new Subscriber() { 139 | @Override 140 | public void onSubscribe(Subscription s) { 141 | subscriber.onSubscribe(s); 142 | } 143 | 144 | @Override 145 | public void onNext(StreamData data) { 146 | Event event = data.getPayload(Event.class); 147 | event.setCodecs(codecs); 148 | subscriber.onNext(event); 149 | } 150 | 151 | @Override 152 | public void onError(Throwable t) { 153 | subscriber.onError(t); 154 | } 155 | 156 | @Override 157 | public void onComplete() { 158 | subscriber.onComplete(); 159 | } 160 | }); 161 | } catch (URISyntaxException e) { 162 | throw new MuonException("The name provided [" + eventStoreName + "] is invalid", e); 163 | } 164 | } else { 165 | throw new MuonException("There is no event store present in the distributed system, is Photon running?"); 166 | } 167 | return null; 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/client/EventClient.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.client; 2 | 3 | import io.muoncore.api.MuonFuture; 4 | import io.muoncore.protocol.Auth; 5 | import io.muoncore.protocol.event.ClientEvent; 6 | import io.muoncore.protocol.event.Event; 7 | import org.reactivestreams.Subscriber; 8 | 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | public interface EventClient { 13 | 14 | /** 15 | * Emit an event into the remote event store. 16 | * @param event 17 | * @return 18 | */ 19 | EventResult event(ClientEvent event, Auth auth); 20 | MuonFuture eventAsync(ClientEvent event, Auth auth); 21 | 22 | /** 23 | * Load an event by id 24 | */ 25 | // MuonFuture> loadEvent(String id, Class type); 26 | 27 | /** 28 | * Replay an event stream, allowing the creation of an aggregated data structure (a reduction or projection) 29 | * Or serial processing of the stream. 30 | * 31 | * This method requires an event store to be active in the distributed system. If one is not active, a MuonException 32 | * will be thrown. 33 | * 34 | * This will optionally replay from the start of the stream up to the current and then switch to HOT processing for all messages 35 | * after this. 36 | * 37 | * @param streamName The name of the stream to be replayed 38 | * @param mode Whether to replay just the future data, or request to load historical data, if supported on the remote stream 39 | * @param subscriber The reactive streams subscriber that will listen to the event stream. 40 | */ 41 | MuonFuture replay(String streamName, Auth auth, EventReplayMode mode, Subscriber subscriber); 42 | MuonFuture replay(String streamName, Auth auth, EventReplayMode mode, Map args, Subscriber subscriber); 43 | } 44 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/client/EventClientProtocol.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.client; 2 | 3 | import io.muoncore.Discovery; 4 | import io.muoncore.ServiceDescriptor; 5 | import io.muoncore.channel.ChannelConnection; 6 | import io.muoncore.channel.impl.TimeoutChannel; 7 | import io.muoncore.codec.Codecs; 8 | import io.muoncore.config.AutoConfiguration; 9 | import io.muoncore.message.MuonInboundMessage; 10 | import io.muoncore.message.MuonMessageBuilder; 11 | import io.muoncore.message.MuonOutboundMessage; 12 | import io.muoncore.protocol.Auth; 13 | import io.muoncore.protocol.event.ClientEvent; 14 | import io.muoncore.protocol.event.EventCodec; 15 | import io.muoncore.protocol.event.EventProtocolMessages; 16 | import io.muoncore.transport.TransportEvents; 17 | import lombok.extern.slf4j.Slf4j; 18 | 19 | import java.util.Map; 20 | import java.util.Optional; 21 | 22 | /** 23 | * This middleware will accept an Event. It will then attempt to locate an event store to send a persistence Request to 24 | */ 25 | @Slf4j 26 | public class EventClientProtocol { 27 | 28 | public EventClientProtocol( 29 | AutoConfiguration configuration, 30 | Discovery discovery, 31 | Codecs codecs, 32 | Auth auth, 33 | ChannelConnection leftChannelConnection, 34 | ChannelConnection rightChannelConnection) { 35 | 36 | rightChannelConnection.receive(message -> { 37 | if (message == null) { 38 | leftChannelConnection.shutdown(); 39 | return; 40 | } 41 | 42 | EventResult result; 43 | 44 | switch (message.getStep()) { 45 | case EventProtocolMessages.EVENT_RESULT: 46 | result = codecs.decode(message.getPayload(), message.getContentType(), EventResult.class); 47 | break; 48 | case TransportEvents.SERVICE_NOT_FOUND: 49 | result = new EventResult(EventResult.EventResultStatus.FAILED, 50 | "Event Store Service Not Found"); 51 | break; 52 | case TransportEvents.CONNECTION_FAILURE: 53 | result = new EventResult(EventResult.EventResultStatus.FAILED, 54 | "Event Store is not contactable, the transport could not complete a connection to it. This may be transient"); 55 | break; 56 | case TransportEvents.PROTOCOL_NOT_FOUND: 57 | result = new EventResult(EventResult.EventResultStatus.FAILED, 58 | "Remote service does not support event sink protocol"); 59 | break; 60 | 61 | case TimeoutChannel.TIMEOUT_STEP: 62 | result = new EventResult(EventResult.EventResultStatus.FAILED, 63 | "A timeout occurred, the remote service did not send a response"); 64 | break; 65 | default: 66 | if ("text/plain".equals(message.getContentType())) { 67 | log.debug("Unknown step '{}'", message.getStep()); 68 | result = new EventResult(EventResult.EventResultStatus.FAILED, new String(message.getPayload())); 69 | } else { 70 | result = new EventResult(EventResult.EventResultStatus.FAILED, "Unknown step " + message.getStep()); 71 | } 72 | } 73 | 74 | leftChannelConnection.send(result); 75 | leftChannelConnection.shutdown(); 76 | }); 77 | 78 | leftChannelConnection.receive(event -> { 79 | if (event == null) { 80 | rightChannelConnection.shutdown(); 81 | return; 82 | } 83 | Optional eventService = discovery.getServiceWithTags("eventstore"); 84 | 85 | if (!eventService.isPresent()) { 86 | //TODO, a failure, no event store available. 87 | leftChannelConnection.send(new EventResult(EventResult.EventResultStatus.FAILED, 88 | "No Event Store available")); 89 | } else { 90 | 91 | Map payload = EventCodec.getMapFromClientEvent(event, auth, configuration); 92 | 93 | Codecs.EncodingResult result = codecs.encode(payload, eventService.get().getCodecs()); 94 | MuonOutboundMessage msg = MuonMessageBuilder.fromService(configuration.getServiceName()) 95 | .toService(eventService.get().getIdentifier()) 96 | .protocol(EventProtocolMessages.PROTOCOL) 97 | .step(EventProtocolMessages.EVENT) 98 | .contentType(result.getContentType()) 99 | .payload(result.getPayload()).build(); 100 | 101 | rightChannelConnection.send(msg); 102 | } 103 | }); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/client/EventProjectionControl.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.client; 2 | 3 | public interface EventProjectionControl { 4 | 5 | /** 6 | * Obtain the latest available projection state. 7 | */ 8 | ProjectionType getCurrentState(); 9 | 10 | 11 | } 12 | 13 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/client/EventProjectionDescriptor.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.client; 2 | 3 | public class EventProjectionDescriptor { 4 | 5 | private String name; 6 | 7 | public EventProjectionDescriptor(String name) { 8 | this.name = name; 9 | } 10 | 11 | public String getName() { 12 | return name; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "EventProjectionDescriptor{" + 18 | "name='" + name + '\'' + 19 | '}'; 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/client/EventReplayControl.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.client; 2 | 3 | public interface EventReplayControl { 4 | void cancel(); 5 | } 6 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/client/EventReplayMode.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.client; 2 | 3 | public enum EventReplayMode { 4 | LIVE_ONLY, REPLAY_THEN_LIVE, REPLAY_ONLY 5 | } 6 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/client/EventResult.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.client; 2 | 3 | public class EventResult { 4 | 5 | private long eventTime; 6 | private long orderId; 7 | private EventResultStatus status; 8 | private String cause; 9 | 10 | public EventResult() { 11 | } 12 | 13 | public EventResult(EventResultStatus status, String cause) { 14 | this.status = status; 15 | this.cause = cause; 16 | } 17 | 18 | public EventResult(EventResultStatus status, String cause, long orderId, long eventTime) { 19 | this.status = status; 20 | this.cause = cause; 21 | this.orderId = orderId; 22 | this.eventTime = eventTime; 23 | } 24 | 25 | public long getEventTime() { 26 | return eventTime; 27 | } 28 | 29 | public long getOrderId() { 30 | return orderId; 31 | } 32 | 33 | public EventResultStatus getStatus() { 34 | return status; 35 | } 36 | 37 | public String getCause() { 38 | return cause; 39 | } 40 | 41 | public enum EventResultStatus { 42 | PERSISTED, FAILED 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "EventResult{" + 48 | "eventTime=" + eventTime + 49 | ", orderId=" + orderId + 50 | ", status=" + status + 51 | ", cause='" + cause + '\'' + 52 | '}'; 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/server/EventServerProtocolStack.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.server; 2 | 3 | import io.muoncore.Discovery; 4 | import io.muoncore.channel.*; 5 | import io.muoncore.codec.Codecs; 6 | import io.muoncore.descriptors.ProtocolDescriptor; 7 | import io.muoncore.descriptors.SchemaDescriptor; 8 | import io.muoncore.message.MuonInboundMessage; 9 | import io.muoncore.message.MuonMessageBuilder; 10 | import io.muoncore.message.MuonOutboundMessage; 11 | import io.muoncore.protocol.Auth; 12 | import io.muoncore.protocol.ServerProtocolStack; 13 | import io.muoncore.protocol.event.Event; 14 | import io.muoncore.protocol.event.EventCodec; 15 | import io.muoncore.protocol.event.EventProtocolMessages; 16 | import io.muoncore.protocol.event.client.EventResult; 17 | 18 | import java.util.Collections; 19 | import java.util.Map; 20 | 21 | /** 22 | * Server side of the event protocol 23 | */ 24 | public class EventServerProtocolStack implements 25 | ServerProtocolStack { 26 | 27 | private final ChannelConnection.ChannelFunctionhandler; 28 | private Codecs codecs; 29 | private Discovery discovery; 30 | private Dispatcher dispatcher = Dispatchers.poolDispatcher(); 31 | 32 | public EventServerProtocolStack(ChannelConnection.ChannelFunction handler, 33 | Codecs codecs, Discovery discovery) { 34 | this.codecs = codecs; 35 | this.handler = handler; 36 | this.discovery = discovery; 37 | } 38 | 39 | @Override 40 | @SuppressWarnings("unchecked") 41 | public ChannelConnection createChannel() { 42 | 43 | Channel api2 = Channels.channel("eventserver", "transport"); 44 | 45 | api2.left().receive( message -> { 46 | if (message == null || message.getPayload() == null) { 47 | return; 48 | } 49 | 50 | Map data = codecs.decode(message.getPayload(), message.getContentType(), Map.class); 51 | Event ev = EventCodec.getEventFromMap(data, codecs); 52 | Auth auth = EventCodec.getAuthFromMap(data, codecs); 53 | 54 | Channel evserver = Channels.channel("eventserverapp", "wrapper"); 55 | EventWrapper wrapper = new EventWrapper(ev, auth, evserver.left()); 56 | 57 | evserver.right().receive( eventResult -> { 58 | 59 | Codecs.EncodingResult result = codecs.encode(eventResult, discovery.getCodecsForService(message.getSourceServiceName())); 60 | 61 | MuonOutboundMessage msg = MuonMessageBuilder.fromService(message.getTargetServiceName()) 62 | .toService(message.getSourceServiceName()) 63 | .protocol(EventProtocolMessages.PROTOCOL) 64 | .step(EventProtocolMessages.EVENT_RESULT) 65 | .contentType(result.getContentType()) 66 | .payload(result.getPayload()).build(); 67 | 68 | dispatcher.dispatch(msg, api2.left()::send, Throwable::printStackTrace); 69 | }); 70 | 71 | dispatcher.dispatch(wrapper, handler::apply, Throwable::printStackTrace); 72 | }); 73 | 74 | return api2.right(); 75 | } 76 | 77 | @Override 78 | public ProtocolDescriptor getProtocolDescriptor() { 79 | 80 | return new ProtocolDescriptor( 81 | EventProtocolMessages.PROTOCOL, 82 | "Event Sink Protocol", 83 | "Provides a discoverable sink for events to flow into without needing explicit service endpoints", 84 | Collections.emptyList()); 85 | } 86 | 87 | @Override 88 | public Map getSchemasFor(String endpoint) { 89 | return Collections.emptyMap(); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /java/stack-event/src/main/java/io/muoncore/protocol/event/server/EventWrapper.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.server; 2 | 3 | import io.muoncore.channel.ChannelConnection; 4 | import io.muoncore.protocol.Auth; 5 | import io.muoncore.protocol.event.Event; 6 | import io.muoncore.protocol.event.client.EventResult; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Data; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | public class EventWrapper { 13 | 14 | private Event event; 15 | private Auth auth; 16 | private ChannelConnection channel; 17 | 18 | public void persisted( 19 | long orderId, 20 | long eventTime 21 | ) { 22 | channel.send(new EventResult( 23 | EventResult.EventResultStatus.PERSISTED, "Event persisted", orderId, eventTime 24 | )); 25 | } 26 | 27 | public void failed(String reason) { 28 | channel.send(new EventResult( 29 | EventResult.EventResultStatus.FAILED, reason 30 | )); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java/stack-event/src/test/groovy/io/muoncore/protocol/ChannelFunctionExecShimBecauseGroovyCantCallLambda.java: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol; 2 | 3 | import io.muoncore.channel.ChannelConnection; 4 | 5 | /* 6 | * workaround for inability to directly invoke lambdas from groovy without the dynamic coercion 7 | * 8 | * When performing spock argument capture, the actual lambda appears in a groovy context. 9 | * 10 | * Requiring this shim be used to convert and invoke in java. 11 | */ 12 | public class ChannelFunctionExecShimBecauseGroovyCantCallLambda { 13 | 14 | private ChannelConnection.ChannelFunction function; 15 | 16 | public ChannelFunctionExecShimBecauseGroovyCantCallLambda(ChannelConnection.ChannelFunction func) { 17 | this.function = func; 18 | } 19 | 20 | public void call(Object arg) { 21 | function.apply(arg); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /java/stack-event/src/test/groovy/io/muoncore/protocol/event/client/EventClientProtocolSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.client 2 | 3 | import io.muoncore.Discovery 4 | import io.muoncore.ServiceDescriptor 5 | import io.muoncore.channel.Channel 6 | import io.muoncore.channel.Channels 7 | import io.muoncore.channel.impl.TimeoutChannel 8 | import io.muoncore.codec.Codecs 9 | import io.muoncore.config.AutoConfiguration 10 | import io.muoncore.message.MuonInboundMessage 11 | import io.muoncore.message.MuonMessageBuilder 12 | import io.muoncore.message.MuonOutboundMessage 13 | import io.muoncore.protocol.Auth 14 | import io.muoncore.protocol.event.ClientEvent 15 | import io.muoncore.protocol.event.EventProtocolMessages 16 | import spock.lang.Specification 17 | import spock.util.concurrent.PollingConditions 18 | 19 | class EventClientProtocolSpec extends Specification { 20 | 21 | def "protocol sends an event on for event Event"() { 22 | 23 | def discovery = Mock(Discovery) { 24 | getServiceWithTags(_) >> Optional.of(new ServiceDescriptor("tombola", [], [], [], [])) 25 | } 26 | def codecs = Mock(Codecs) { 27 | encode(_, _) >> new Codecs.EncodingResult(null, null) 28 | getAvailableCodecs() >> [] 29 | } 30 | 31 | def leftChannel = Channels.channel("left", "right") 32 | def rightChannel = Channels.channel("left", "right") 33 | 34 | def ret 35 | 36 | rightChannel.right().receive({ 37 | ret = it 38 | }) 39 | 40 | def proto = new EventClientProtocol( 41 | new AutoConfiguration(serviceName: "tombola"), 42 | discovery, codecs, new Auth(), 43 | leftChannel.right(), rightChannel.left()) 44 | 45 | when: 46 | leftChannel.left().send(ClientEvent.ofType("awesome") 47 | .stream("awesome") 48 | .payload(["1":2, "payload":true]) 49 | .build()) 50 | 51 | then: 52 | new PollingConditions().eventually { 53 | ret instanceof MuonOutboundMessage 54 | ret.step == EventProtocolMessages.EVENT 55 | } 56 | } 57 | 58 | def "protocol returns FAILED if a timeout given"() { 59 | 60 | def discovery = Mock(Discovery) { 61 | getServiceWithTags(_) >> Optional.of(new ServiceDescriptor("tombola", [], [], [], [])) 62 | } 63 | def codecs = Mock(Codecs) { 64 | encode(_, _) >> new Codecs.EncodingResult(null, null) 65 | getAvailableCodecs() >> [] 66 | } 67 | 68 | def leftChannel = Channels.channel("left", "right") 69 | Channel rightChannel = Channels.channel("left", "right") 70 | 71 | def ret 72 | 73 | rightChannel.right().receive({ 74 | rightChannel.right().send(MuonMessageBuilder.fromService("blah") 75 | .step(TimeoutChannel.TIMEOUT_STEP) 76 | .buildInbound()) 77 | }) 78 | 79 | leftChannel.left().receive { 80 | if (it != null) { 81 | println "Got a response! ${it}" 82 | ret = it 83 | } 84 | } 85 | 86 | def proto = new EventClientProtocol( 87 | new AutoConfiguration(serviceName: "tombola"), 88 | discovery, codecs, new Auth(), 89 | leftChannel.right(), rightChannel.left()) 90 | 91 | when: 92 | leftChannel.left().send(ClientEvent.ofType("awesome") 93 | .stream("awesome") 94 | .payload(["1":2, "payload":true]) 95 | .build()) 96 | 97 | then: 98 | new PollingConditions().eventually { 99 | ret instanceof EventResult 100 | ret.status == EventResult.EventResultStatus.FAILED 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /java/stack-event/src/test/groovy/io/muoncore/protocol/event/client/EventClientProtocolStackSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.client 2 | 3 | import io.muoncore.Discovery 4 | import io.muoncore.Muon 5 | import io.muoncore.ServiceDescriptor 6 | import io.muoncore.api.MuonFuture 7 | import io.muoncore.channel.ChannelConnection 8 | import io.muoncore.channel.impl.StandardAsyncChannel 9 | import io.muoncore.channel.support.Scheduler 10 | import io.muoncore.codec.Codecs 11 | import io.muoncore.config.AutoConfiguration 12 | import io.muoncore.descriptors.ProtocolDescriptor 13 | import io.muoncore.descriptors.ServiceExtendedDescriptor 14 | import io.muoncore.message.MuonMessage 15 | import io.muoncore.message.MuonMessageBuilder 16 | import io.muoncore.protocol.Auth 17 | import io.muoncore.protocol.ChannelFunctionExecShimBecauseGroovyCantCallLambda 18 | import io.muoncore.protocol.event.ClientEvent 19 | import io.muoncore.transport.client.TransportClient 20 | import spock.lang.Specification 21 | import spock.lang.Timeout 22 | import spock.util.concurrent.PollingConditions 23 | 24 | @Timeout(5) 25 | class EventClientProtocolStackSpec extends Specification { 26 | 27 | def "Stack sends all with the event protocol set"() { 28 | 29 | StandardAsyncChannel.echoOut=true 30 | def config = new AutoConfiguration(serviceName: "tombola") 31 | 32 | def discovery = Mock(Discovery) { 33 | getServiceWithTags(_) >> Optional.of(new ServiceDescriptor("tombola", [], [], [], [])) 34 | } 35 | 36 | def clientChannel = Mock(ChannelConnection) 37 | def transportClient = Mock(TransportClient) { 38 | openClientChannel() >> clientChannel 39 | } 40 | 41 | def muon = Mock(Muon) { 42 | getTransportClient() >> transportClient 43 | getDiscovery() >> discovery 44 | getConfiguration() >> config 45 | getCodecs() >> Mock(Codecs) { 46 | getAvailableCodecs() >> ([] as String[]) 47 | encode(_, _) >> new Codecs.EncodingResult(new byte[0], "application/json") 48 | } 49 | getScheduler() >> new Scheduler() 50 | } 51 | 52 | def eventStore = new DefaultEventClient(muon) 53 | 54 | when: 55 | eventStore.event( 56 | ClientEvent.ofType("SomethingHappened").stream("awesome").payload([]).build(), auth()) 57 | sleep(50) 58 | 59 | then: 60 | 1 * clientChannel.send({ it?.protocol == "event" }) 61 | 62 | cleanup: 63 | StandardAsyncChannel.echoOut=false 64 | } 65 | 66 | def "Sends a 404 response if no eventstore service found"() { 67 | 68 | StandardAsyncChannel.echoOut=true 69 | 70 | def discovery = Mock(Discovery) { 71 | getServiceWithTags(_) >> Optional.empty() 72 | } 73 | def clientChannel = Mock(ChannelConnection) 74 | def transportClient = Mock(TransportClient) { 75 | openClientChannel() >> clientChannel 76 | } 77 | 78 | def muon = Mock(Muon) { 79 | getTransportClient() >> transportClient 80 | getDiscovery() >> discovery 81 | } 82 | 83 | def eventStore = new DefaultEventClient(muon) 84 | 85 | when: 86 | def response = eventStore.event( 87 | new ClientEvent("myid", "awesome", "SomethingHappened2", "simples", "1234", "myService", []), auth()) 88 | 89 | then: 90 | response 91 | response.status == EventResult.EventResultStatus.FAILED 92 | 93 | cleanup: 94 | StandardAsyncChannel.echoOut=false 95 | } 96 | 97 | @Timeout(30) 98 | def "Sends a failed response if timeout occurs"() { 99 | 100 | StandardAsyncChannel.echoOut=true 101 | def config = new AutoConfiguration(serviceName: "tombola") 102 | def discovery = Mock(Discovery) { 103 | getServiceWithTags(_) >> Optional.of(new ServiceDescriptor("tombola", [], [], [], [])) 104 | } 105 | def clientChannel = Mock(ChannelConnection) 106 | def transportClient = Mock(TransportClient) { 107 | openClientChannel() >> clientChannel 108 | } 109 | 110 | def muon = Mock(Muon) { 111 | getScheduler() >> new Scheduler() 112 | getConfiguration() >> config 113 | getTransportClient() >> transportClient 114 | getDiscovery() >> discovery 115 | getCodecs() >> Mock(Codecs) { 116 | getAvailableCodecs() >> ([] as String[]) 117 | encode(_, _) >> new Codecs.EncodingResult(new byte[0], "application/json") 118 | } 119 | } 120 | 121 | def eventStore = new DefaultEventClient(muon) 122 | 123 | when: 124 | def response = eventStore.event( 125 | new ClientEvent("myid", "awesome", "SomethingHappened2", "simples", "1234", "myService", []), auth()) 126 | 127 | then: 128 | response 129 | response.status == EventResult.EventResultStatus.FAILED 130 | 131 | cleanup: 132 | StandardAsyncChannel.echoOut=false 133 | } 134 | 135 | def muon() { 136 | Muon 137 | } 138 | 139 | def auth() { 140 | new Auth("faked", "faked") 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /java/stack-event/src/test/groovy/io/muoncore/protocol/event/integration/EventIntegrationSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.integration 2 | 3 | import io.muoncore.MultiTransportMuon 4 | import io.muoncore.Muon 5 | import io.muoncore.codec.json.JsonOnlyCodecs 6 | import io.muoncore.config.AutoConfiguration 7 | import io.muoncore.liblib.reactor.rx.Streams 8 | import io.muoncore.memory.discovery.InMemDiscovery 9 | import io.muoncore.memory.transport.InMemTransport 10 | import io.muoncore.memory.transport.bus.EventBus 11 | import io.muoncore.protocol.Auth 12 | import io.muoncore.protocol.event.ClientEvent 13 | import io.muoncore.protocol.event.Event 14 | import io.muoncore.protocol.event.client.DefaultEventClient 15 | import io.muoncore.protocol.event.client.EventReplayMode 16 | import io.muoncore.protocol.event.client.EventResult 17 | import io.muoncore.protocol.event.server.EventServerProtocolStack 18 | import io.muoncore.protocol.event.server.EventWrapper 19 | import io.muoncore.protocol.reactivestream.messages.ReactiveStreamSubscriptionRequest 20 | import io.muoncore.protocol.reactivestream.server.PublisherLookup 21 | import io.muoncore.protocol.reactivestream.server.ReactiveStreamServer 22 | import org.reactivestreams.Subscriber 23 | import org.reactivestreams.Subscription 24 | import spock.lang.Specification 25 | import spock.util.concurrent.PollingConditions 26 | 27 | class EventIntegrationSpec extends Specification { 28 | 29 | def discovery = new InMemDiscovery() 30 | def eventbus = new EventBus() 31 | 32 | def "can emit a series of events and have them recieved on the server side"() { 33 | 34 | def data = [] 35 | List results = [] 36 | 37 | boolean fail = true 38 | 39 | def muon2 = muonEventStore { EventWrapper ev -> 40 | println "Event is the awesome ${ev.event}" 41 | data << ev.event 42 | if (!fail) { 43 | ev.persisted(12345, System.currentTimeMillis()) 44 | fail = true 45 | } else { 46 | ev.failed("Something went wrong") 47 | fail = false 48 | } 49 | } 50 | 51 | def muon1 = muon("simples") 52 | 53 | def evClient = new DefaultEventClient(muon1) 54 | 55 | 56 | when: 57 | 58 | results << evClient.event(new ClientEvent("myid", "awesome", "SomethingHappened", "myid", "1234", "muon1", [msg: "HELLO WORLD"]), auth()) 59 | results << evClient.event(new ClientEvent("myid", "awesome", "SomethingHappened", "myid", "1234", "muon1", [msg: "HELLO WORLD"]), auth()) 60 | results << evClient.event(new ClientEvent("myid", "awesome", "SomethingHappened", "myid", "1234", "muon1", [msg: "HELLO WORLD"]), auth()) 61 | results << evClient.event(new ClientEvent("myid", "awesome", "SomethingHappened", "myid", "1234", "muon1", [msg: "HELLO WORLD"]), auth()) 62 | 63 | then: 64 | new PollingConditions().eventually { 65 | data.size() == 4 66 | results.size() == 4 67 | results.findAll { it.status == EventResult.EventResultStatus.PERSISTED }.size() == 2 68 | results.findAll { it.status == EventResult.EventResultStatus.FAILED }.size() == 2 69 | } 70 | } 71 | 72 | def "auth is available on the server"() { 73 | 74 | def capturedauth 75 | 76 | def muon2 = muonEventStore { EventWrapper ev -> 77 | capturedauth = ev.auth 78 | } 79 | 80 | def muon1 = muon("simples") 81 | 82 | def evClient = new DefaultEventClient(muon1) 83 | 84 | when: 85 | 86 | evClient.event(new ClientEvent("myid", "awesome", "SomethingHappened", "myid", "1234", "muon1", [msg: "HELLO WORLD"]), auth()) 87 | 88 | then: 89 | new PollingConditions().eventually { 90 | capturedauth != null 91 | capturedauth == auth() 92 | } 93 | } 94 | 95 | def "data remains in order"() { 96 | 97 | def data = [] 98 | 99 | def muon2 = muonEventStore { EventWrapper ev -> 100 | println "Event is the awesome ${ev.event}" 101 | data << ev.event 102 | ev.persisted(54321, System.currentTimeMillis()) 103 | } 104 | 105 | def muon1 = muon("simples") 106 | def evClient = new DefaultEventClient(muon1) 107 | 108 | when: 109 | 200.times { 110 | evClient.event(new ClientEvent("myid", "${it}", "SomethingHappened", "1.0", "1234", "muon1", [msg: "HELLO WORLD"]), auth()) 111 | } 112 | 113 | then: 114 | new PollingConditions(timeout: 30).eventually { 115 | data.size() == 200 116 | def sorted = new ArrayList(data).sort { 117 | Integer.parseInt(it.eventType) 118 | } 119 | data == sorted 120 | } 121 | } 122 | 123 | def "partial replay works"() { 124 | 125 | def data = [] 126 | 127 | def muon2 = muonEventStore { EventWrapper ev -> 128 | println "Event is the awesome ${ev.event}" 129 | data << ev.event 130 | ev.persisted(54321, System.currentTimeMillis()) 131 | } 132 | 133 | def muon1 = muon("simples") 134 | def args 135 | muon2.publishGeneratedSource("/stream", PublisherLookup.PublisherType.HOT) { 136 | ReactiveStreamSubscriptionRequest subscriptionRequest -> 137 | println "ARGS = ${subscriptionRequest.args}" 138 | args = subscriptionRequest.args 139 | return Streams.from() 140 | } 141 | def evClient = new DefaultEventClient(muon1) 142 | def replayed = [] 143 | 144 | when: 145 | evClient.replay("SomethingHappened", auth(), EventReplayMode.REPLAY_THEN_LIVE, ["from": 112345], new Subscriber() { 146 | @Override 147 | void onSubscribe(Subscription s) { 148 | s.request(Integer.MAX_VALUE) 149 | } 150 | 151 | @Override 152 | void onNext(Object o) { 153 | replayed << o 154 | } 155 | 156 | @Override 157 | void onError(Throwable t) { t.printStackTrace() } 158 | 159 | @Override 160 | void onComplete() { 161 | println "Completed" 162 | } 163 | }) 164 | 165 | then: 166 | new PollingConditions(timeout: 30).eventually { 167 | args && args.from == "112345" 168 | } 169 | } 170 | 171 | Muon muon(name) { 172 | def config = new AutoConfiguration(serviceName: name) 173 | def transport = new InMemTransport(config, eventbus) 174 | 175 | new MultiTransportMuon(config, discovery, [transport], new JsonOnlyCodecs()) 176 | } 177 | 178 | public ReactiveStreamServer muonEventStore(Closure handler) { 179 | def config = new AutoConfiguration(tags: ["eventstore"], serviceName: "chronos") 180 | def transport = new InMemTransport(config, eventbus) 181 | 182 | def muon = new MultiTransportMuon(config, discovery, [transport], new JsonOnlyCodecs()) 183 | 184 | muon.protocolStacks.registerServerProtocol(new EventServerProtocolStack(handler, muon.codecs, discovery)) 185 | 186 | new ReactiveStreamServer(muon) 187 | } 188 | 189 | Auth auth() { 190 | new Auth("faked", "faked") 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /java/stack-event/src/test/groovy/io/muoncore/protocol/event/integration/LoadSpec.groovy: -------------------------------------------------------------------------------- 1 | package io.muoncore.protocol.event.integration 2 | 3 | import io.muoncore.MultiTransportMuon 4 | import io.muoncore.Muon 5 | import io.muoncore.codec.json.JsonOnlyCodecs 6 | import io.muoncore.config.AutoConfiguration 7 | import io.muoncore.liblib.reactor.rx.Streams 8 | import io.muoncore.memory.discovery.InMemDiscovery 9 | import io.muoncore.memory.transport.InMemTransport 10 | import io.muoncore.memory.transport.bus.EventBus 11 | import io.muoncore.protocol.Auth 12 | import io.muoncore.protocol.event.ClientEvent 13 | import io.muoncore.protocol.event.client.DefaultEventClient 14 | import io.muoncore.protocol.event.client.EventReplayMode 15 | import io.muoncore.protocol.event.server.EventServerProtocolStack 16 | import io.muoncore.protocol.event.server.EventWrapper 17 | import io.muoncore.protocol.reactivestream.messages.ReactiveStreamSubscriptionRequest 18 | import io.muoncore.protocol.reactivestream.server.PublisherLookup 19 | import io.muoncore.protocol.reactivestream.server.ReactiveStreamServer 20 | import org.reactivestreams.Subscriber 21 | import org.reactivestreams.Subscription 22 | import spock.lang.Specification 23 | import spock.util.concurrent.PollingConditions 24 | 25 | class LoadSpec extends Specification { 26 | 27 | def discovery = new InMemDiscovery() 28 | def eventbus = new EventBus() 29 | 30 | def "many subscribes and then emit works"() { 31 | 32 | def data = [] 33 | 34 | def muon2 = muonEventStore { EventWrapper ev -> 35 | println "Event is the awesome ${ev.event}" 36 | data << ev.event 37 | ev.persisted(54321, System.currentTimeMillis()) 38 | } 39 | 40 | def muons = [ 41 | muon("simple1"), 42 | muon("simple2"), 43 | muon("simple3"), 44 | muon("simple4"), 45 | muon("simple5"), 46 | muon("simple6")] 47 | 48 | def args 49 | muon2.publishGeneratedSource("/stream", PublisherLookup.PublisherType.HOT) { 50 | ReactiveStreamSubscriptionRequest subscriptionRequest -> 51 | println "ARGS = ${subscriptionRequest.args}" 52 | args = subscriptionRequest.args 53 | return Streams.from() 54 | } 55 | 56 | def evClients = muons.collect { 57 | new DefaultEventClient(it) 58 | } 59 | 60 | when: 61 | def replayed = evClients.collect { 62 | def replayed = [] 63 | 64 | it.replay("SomethingHappened",auth(), EventReplayMode.REPLAY_THEN_LIVE, ["from": 112345], new Subscriber() { 65 | @Override 66 | void onSubscribe(Subscription s) { 67 | s.request(Integer.MAX_VALUE) 68 | } 69 | 70 | @Override 71 | void onNext(Object o) { 72 | replayed << o 73 | } 74 | 75 | @Override 76 | void onError(Throwable t) { t.printStackTrace() } 77 | 78 | @Override 79 | void onComplete() { 80 | println "Completed" 81 | } 82 | }) 83 | replayed 84 | } 85 | 86 | 50.times { 87 | evClients[0].event(new ClientEvent("id", "${it}" as String, "SomethingHappened", "1.0", "", "muon1", [msg: "HELLO WORLD"]), auth()) 88 | } 89 | 90 | then: 91 | new PollingConditions(timeout: 30).eventually { 92 | args && args.from == "112345" 93 | } 94 | } 95 | 96 | Muon muon(name) { 97 | def config = new AutoConfiguration(serviceName: name) 98 | def transport = new InMemTransport(config, eventbus) 99 | 100 | new MultiTransportMuon(config, discovery, [transport], new JsonOnlyCodecs()) 101 | } 102 | 103 | ReactiveStreamServer muonEventStore(Closure handler) { 104 | def config = new AutoConfiguration(tags:["eventstore"], serviceName: "chronos") 105 | def transport = new InMemTransport(config, eventbus) 106 | 107 | def muon = new MultiTransportMuon(config, discovery, [transport], new JsonOnlyCodecs()) 108 | 109 | muon.protocolStacks.registerServerProtocol(new EventServerProtocolStack(handler, muon.codecs, discovery)) 110 | 111 | new ReactiveStreamServer(muon) 112 | } 113 | 114 | Auth auth() { 115 | new Auth("faked", "faked") 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /javascript/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | ["transform-runtime", { 4 | "polyfill": false, 5 | "regenerator": true 6 | }] 7 | ], 8 | "presets": ["es2015"] 9 | } 10 | -------------------------------------------------------------------------------- /javascript/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | insert_final_newline = true 5 | indent_style = space 6 | indent_size = 2 7 | 8 | # We recommend you to keep these unchanged 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | [{Makefile,**.mk}] 15 | indent_style = tab 16 | indent_size = 4 17 | -------------------------------------------------------------------------------- /javascript/.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | test/ 3 | .npmignore 4 | xunit.xml 5 | tempdocumentation/ 6 | test-results 7 | old 8 | projectFilesBackup 9 | -------------------------------------------------------------------------------- /javascript/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY: test 3 | 4 | build: clean 5 | -tsc 6 | 7 | clean: 8 | rm -rf distribution 9 | 10 | publish-snapshot: 11 | yarn 12 | yarn build 13 | npm version --no-git-tag-version prerelease 14 | npm publish --tag next 15 | git add package.json 16 | git commit -m "Update snapshot version" 17 | git push origin 18 | 19 | 20 | test: 21 | yarn 22 | tsc 23 | yarn test 24 | -------------------------------------------------------------------------------- /javascript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "muon-stack-event", 3 | "version": "0.0.1-49", 4 | "description": "", 5 | "main": "./distribution/protocol.js", 6 | "scripts": { 7 | "test": "XUNIT_FILE=test-results/xunit.xml ./node_modules/.bin/mocha --recursive -R xunit-file test/", 8 | "build": "tsc ." 9 | }, 10 | "author": "Muon Core Ltd", 11 | "license": "LGPLv3", 12 | "dependencies": { 13 | "babel-runtime": "^6.18.0", 14 | "muon-core": "^7.3.0-1" 15 | }, 16 | "devDependencies": { 17 | "@types/node": "^9.6.0", 18 | "babel-cli": "^6.18.0", 19 | "babel-plugin-transform-runtime": "^6.15.0", 20 | "babel-preset-es2015": "^6.18.0", 21 | "mocha": "2.5.3", 22 | "mocha-multi": "0.9.1", 23 | "mocha-sinon": "1.1.5", 24 | "mocha-teamcity-reporter": "1.1.1", 25 | "should": "11.1.0", 26 | "sinon": "1.17.5", 27 | "ts-node": "^5.0.1", 28 | "typedoc": "^0.11.1", 29 | "typescript": "^2.7.2", 30 | "xunit-file": "^1.0.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /javascript/src/MuonEventClient.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export default class MuonEventClient { 4 | 5 | muon: any 6 | 7 | constructor(muon: any) { 8 | this.muon = muon 9 | } 10 | 11 | public subscribe(stream: string, auth: Auth, exec: (event: MuonEvent) => Promise): void { 12 | this.connect(stream, auth, exec) 13 | } 14 | 15 | public async emitWithAuth(auth: Auth, event: MuonEvent): Promise { 16 | 17 | let accountUpdate = { 18 | "id": event.id, 19 | "event-type": event.eventType, 20 | "stream-name": event.streamName, 21 | "service-id": "aether", 22 | payload: event.payload 23 | } 24 | 25 | try { 26 | let ret = await this.muon.emit(accountUpdate, auth) 27 | // console.log("Persisted Event" + JSON.stringify(ret)) 28 | return ret 29 | } catch (error) { 30 | console.log("Event Emit failed " + JSON.stringify(error)) 31 | return { 32 | success:false, 33 | error: error 34 | } 35 | } 36 | } 37 | 38 | private connect(stream: string, auth: Auth, exec: (event: MuonEvent) => void) { 39 | let __this: any 40 | 41 | this.muon.replay(stream, auth, {}, function (event: any) { 42 | 43 | let ev: MuonEvent = { 44 | payload: event.payload, 45 | id: event.id, 46 | service: event["service-id"], 47 | streamName: event["stream-name"], 48 | eventType: event["event-type"] 49 | } as MuonEvent 50 | 51 | exec(ev) 52 | }, function (error: any) { 53 | console.log("Stream listener disconnected from event store, reconnecting ", error) 54 | setTimeout(__this.connect, 1000) 55 | }, function () { 56 | console.log("Completed!") 57 | setTimeout(__this.connect, 1000) 58 | }) 59 | } 60 | } 61 | 62 | export class MuonEventResult { 63 | 64 | } 65 | 66 | export class MuonEvent { 67 | 68 | constructor(readonly id: string, 69 | readonly payload: any, 70 | readonly service: string, 71 | readonly streamName: string, 72 | readonly eventType: string) {} 73 | } 74 | 75 | export class Auth { 76 | constructor(readonly provider: string, 77 | readonly token: string) {} 78 | } 79 | -------------------------------------------------------------------------------- /javascript/src/protocol.ts: -------------------------------------------------------------------------------- 1 | import {Auth, MuonEvent, MuonEventResult} from "./MuonEventClient"; 2 | 3 | const messages = require("muon-core").Messages 4 | 5 | export function create(muon: any): void { 6 | 7 | let api = exports.getApi(muon, muon.infrastructure().serviceName, muon.infrastructure()); 8 | api.muon = muon 9 | 10 | muon.addServerStack(api) 11 | 12 | muon.replay = function (streamName: string, auth: Auth, config: any, callback: any, errorCallback: any, completeCallback: any) { 13 | return api.replay(streamName, auth, config, callback, errorCallback, completeCallback); 14 | } 15 | muon.emit = function(event: any, auth: Auth) { 16 | return api.emit(event, auth) 17 | } 18 | } 19 | 20 | export function getApi(muon: any, name: string, infrastructure: object): EventApi { 21 | console.log("MESSAGES = " + require("muon-core")) 22 | 23 | return new EventApi(muon, name, infrastructure) 24 | } 25 | 26 | 27 | export default class EventApi { 28 | 29 | constructor(readonly muon: any, readonly serviceName: string, readonly infrastructure: any) {} 30 | 31 | public name(): string { 32 | return "event" 33 | } 34 | 35 | public endpoints(): Array { 36 | return []; 37 | } 38 | 39 | public async replay(streamName: string, auth: object, config: any, 40 | clientCallback: (event: MuonEvent) => Promise, 41 | errorCallback: (error: any) => Promise, 42 | completeCallback: () => Promise) { 43 | return new Promise((res, rej) => { 44 | let muon = this.muon 45 | this.infrastructure.discovery.discoverServices(function(services: any) { 46 | let store = services.findServiceWithTags(["eventstore"]) 47 | 48 | if (store == null || store == undefined) { 49 | errorCallback({ 50 | status: "FAILED", 51 | cause: "No event store could be found, is Photon running?" 52 | }) 53 | rej(new Error("No event store could be found, is Photon running?")) 54 | } 55 | 56 | config['stream-name'] = streamName 57 | 58 | let subscriber = muon.subscribe("stream://" + store.identifier + "/stream", auth, config, clientCallback, errorCallback, completeCallback) 59 | 60 | res(new EventReplayControl(subscriber.cancel)) 61 | }) 62 | }) 63 | 64 | } 65 | 66 | public async emit(event: object, auth: Auth): Promise { 67 | 68 | let client = this 69 | 70 | return new Promise(async (resolve, reject) => { 71 | 72 | let transport = await client.infrastructure.getTransport(); 73 | 74 | client.infrastructure.discovery.discoverServices(function (services: any) { 75 | let eventStore = services.findServiceWithTags(["eventstore"]) 76 | 77 | if (eventStore == undefined || eventStore == null) { 78 | reject({ 79 | eventTime: null, 80 | orderId: null, 81 | status: "FAILED", 82 | cause: "No event store could be found, is Photon running?" 83 | }) 84 | return 85 | } 86 | 87 | let transChannel = transport.openChannel(eventStore.identifier, client.name()); 88 | 89 | let callback = function (resp: any) { 90 | if (!resp) { 91 | // logger.warn('client-api promise failed check! calling promise.reject()'); 92 | reject(resp); 93 | } else { 94 | // logger.trace('promise calling promise.resolve() event.id=' + resp.id); 95 | let payload = messages.decode(resp.payload) 96 | // logger.debug("EVENT Incoming message is " + JSON.stringify(payload)) 97 | resolve(payload); 98 | } 99 | }; 100 | 101 | let ev: any = event 102 | 103 | ev["token"] = auth.token 104 | ev["provider"] = auth.provider 105 | let evMessage = messages.muonMessage(event, client.serviceName, eventStore.identifier, client.name(), "EventEmitted"); 106 | 107 | transChannel.listen(callback); 108 | transChannel.send(evMessage); 109 | }); 110 | }); 111 | } 112 | } 113 | 114 | export class EventReplayControl { 115 | 116 | constructor(readonly exec: () => void) {} 117 | 118 | cancel(): void { 119 | this.exec() 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /javascript/test/event-test.js: -------------------------------------------------------------------------------- 1 | var bichannel = require('muon-core').channel(); 2 | var event = require("../distribution/proto"); 3 | var assert = require('assert'); 4 | var expect = require('expect.js'); 5 | var messages = require('muon-core').Messages; 6 | var sinon = require("sinon") 7 | require("sexylog") 8 | 9 | describe("test event protocol:", function () { 10 | 11 | this.timeout(8000); 12 | 13 | it("event emit", function (done) { 14 | 15 | var transport = { openChannel: function (remoteService, protocolName) {} }; 16 | var mockTransport = sinon.mock(transport); 17 | 18 | var channel = bichannel.create("faketransport") 19 | 20 | channel.rightConnection().listen(function(msg) { 21 | 22 | logger.info("Got a message " + JSON.stringify(msg)) 23 | assert(msg.target_service == "myeventstore") 24 | 25 | channel.rightConnection().send( 26 | messages.muonMessage({ 27 | eventTime: "1234", 28 | orderId: "1234", 29 | status: "PERSISTED", 30 | cause: null 31 | }, "faked", "evstore", "event", "EventProcessed") 32 | ) 33 | }) 34 | 35 | mockTransport.expects("openChannel").once().withArgs("myeventstore", "event").returns(channel.leftConnection()); 36 | 37 | var infrastructure = { 38 | getTransport: function() { return { 39 | then: function(exec) { 40 | exec(transport) 41 | } 42 | } }, 43 | discovery: { 44 | discoverServices: function(exec) { 45 | exec({ 46 | findServiceWithTags: function(tags) { 47 | assert(tags == "eventstore") 48 | return { 49 | identifier: "myeventstore", 50 | tags: ["eventstore", "awesomeService"], 51 | codecs: ["application/json"], 52 | connectionUrls: [] 53 | } 54 | } 55 | }) 56 | } 57 | } 58 | } 59 | 60 | var api = event.getApi({}, 'server', infrastructure); 61 | 62 | api.emit({ 63 | "event-type": null, 64 | "stream-name": null, 65 | schema: null, 66 | "caused-by-id":null, 67 | "caused-by-relation": null, 68 | "service-id": null, 69 | service: null, 70 | "order-id": null, 71 | "event-time": null, 72 | payload: null 73 | }, {token: "awesome"}).then(function(response) { 74 | assert(response) 75 | assert(response.orderId == "1234") 76 | assert(response.status == "PERSISTED") 77 | done(); 78 | }) 79 | 80 | setTimeout(function() { 81 | mockTransport.verify() 82 | }, 500) 83 | }); 84 | }); 85 | -------------------------------------------------------------------------------- /javascript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "node", 4 | "target": "es5", 5 | "module":"commonjs", 6 | "lib": ["es2015", "es2016", "es2017", "dom"], 7 | "strict": true, 8 | "sourceMap": true, 9 | "declaration": true, 10 | "allowSyntheticDefaultImports": true, 11 | "experimentalDecorators": true, 12 | "emitDecoratorMetadata": true, 13 | "declarationDir": "distribution", 14 | "outDir": "distribution", 15 | // "allowJs": true, 16 | "typeRoots": [ 17 | "node_modules/@types" 18 | ] 19 | }, 20 | "include": [ 21 | "src" 22 | ] 23 | // "files": [ 24 | // "src/global.ts" 25 | // ] 26 | } 27 | -------------------------------------------------------------------------------- /javascript/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "tslint-config-standard", 4 | "tslint-config-prettier" 5 | ] 6 | } -------------------------------------------------------------------------------- /javascript/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/events@*": 6 | version "1.2.0" 7 | resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" 8 | 9 | "@types/fs-extra@5.0.1": 10 | version "5.0.1" 11 | resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.1.tgz#cd856fbbdd6af2c11f26f8928fd8644c9e9616c9" 12 | dependencies: 13 | "@types/node" "*" 14 | 15 | "@types/glob@*": 16 | version "5.0.35" 17 | resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a" 18 | dependencies: 19 | "@types/events" "*" 20 | "@types/minimatch" "*" 21 | "@types/node" "*" 22 | 23 | "@types/handlebars@4.0.36": 24 | version "4.0.36" 25 | resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.0.36.tgz#ff57c77fa1ab6713bb446534ddc4d979707a3a79" 26 | 27 | "@types/highlight.js@9.12.2": 28 | version "9.12.2" 29 | resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.12.2.tgz#6ee7cd395effe5ec80b515d3ff1699068cd0cd1d" 30 | 31 | "@types/lodash@4.14.104": 32 | version "4.14.104" 33 | resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.104.tgz#53ee2357fa2e6e68379341d92eb2ecea4b11bb80" 34 | 35 | "@types/marked@0.3.0": 36 | version "0.3.0" 37 | resolved "https://registry.yarnpkg.com/@types/marked/-/marked-0.3.0.tgz#583c223dd33385a1dda01aaf77b0cd0411c4b524" 38 | 39 | "@types/minimatch@*", "@types/minimatch@3.0.3": 40 | version "3.0.3" 41 | resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" 42 | 43 | "@types/node@*", "@types/node@^9.6.0": 44 | version "9.6.0" 45 | resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.0.tgz#d3480ee666df9784b1001a1872a2f6ccefb6c2d7" 46 | 47 | "@types/shelljs@0.7.8": 48 | version "0.7.8" 49 | resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.8.tgz#4b4d6ee7926e58d7bca448a50ba442fd9f6715bd" 50 | dependencies: 51 | "@types/glob" "*" 52 | "@types/node" "*" 53 | 54 | abbrev@1: 55 | version "1.1.1" 56 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 57 | 58 | ajv@^4.9.1: 59 | version "4.11.8" 60 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" 61 | dependencies: 62 | co "^4.6.0" 63 | json-stable-stringify "^1.0.1" 64 | 65 | align-text@^0.1.1, align-text@^0.1.3: 66 | version "0.1.4" 67 | resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" 68 | dependencies: 69 | kind-of "^3.0.2" 70 | longest "^1.0.1" 71 | repeat-string "^1.5.2" 72 | 73 | amdefine@>=0.0.4: 74 | version "1.0.1" 75 | resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" 76 | 77 | ansi-regex@^2.0.0: 78 | version "2.1.1" 79 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 80 | 81 | ansi-styles@^2.2.1: 82 | version "2.2.1" 83 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 84 | 85 | ansi-styles@^3.2.1: 86 | version "3.2.1" 87 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 88 | dependencies: 89 | color-convert "^1.9.0" 90 | 91 | anymatch@^1.3.0: 92 | version "1.3.2" 93 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" 94 | dependencies: 95 | micromatch "^2.1.5" 96 | normalize-path "^2.0.0" 97 | 98 | aproba@^1.0.3: 99 | version "1.2.0" 100 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" 101 | 102 | are-we-there-yet@~1.1.2: 103 | version "1.1.4" 104 | resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" 105 | dependencies: 106 | delegates "^1.0.0" 107 | readable-stream "^2.0.6" 108 | 109 | arr-diff@^2.0.0: 110 | version "2.0.0" 111 | resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" 112 | dependencies: 113 | arr-flatten "^1.0.1" 114 | 115 | arr-flatten@^1.0.1: 116 | version "1.1.0" 117 | resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" 118 | 119 | array-find-index@^1.0.1: 120 | version "1.0.2" 121 | resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" 122 | 123 | array-unique@^0.2.1: 124 | version "0.2.1" 125 | resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" 126 | 127 | arrify@^1.0.0: 128 | version "1.0.1" 129 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 130 | 131 | asn1@~0.2.3: 132 | version "0.2.3" 133 | resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" 134 | 135 | assert-plus@1.0.0, assert-plus@^1.0.0: 136 | version "1.0.0" 137 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" 138 | 139 | assert-plus@^0.2.0: 140 | version "0.2.0" 141 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" 142 | 143 | async-each@^1.0.0: 144 | version "1.0.1" 145 | resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" 146 | 147 | async@^1.4.0: 148 | version "1.5.2" 149 | resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" 150 | 151 | async@~1.0.0: 152 | version "1.0.0" 153 | resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" 154 | 155 | asynckit@^0.4.0: 156 | version "0.4.0" 157 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 158 | 159 | aws-sign2@~0.6.0: 160 | version "0.6.0" 161 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" 162 | 163 | aws4@^1.2.1: 164 | version "1.6.0" 165 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" 166 | 167 | babel-cli@^6.18.0: 168 | version "6.26.0" 169 | resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" 170 | dependencies: 171 | babel-core "^6.26.0" 172 | babel-polyfill "^6.26.0" 173 | babel-register "^6.26.0" 174 | babel-runtime "^6.26.0" 175 | commander "^2.11.0" 176 | convert-source-map "^1.5.0" 177 | fs-readdir-recursive "^1.0.0" 178 | glob "^7.1.2" 179 | lodash "^4.17.4" 180 | output-file-sync "^1.1.2" 181 | path-is-absolute "^1.0.1" 182 | slash "^1.0.0" 183 | source-map "^0.5.6" 184 | v8flags "^2.1.1" 185 | optionalDependencies: 186 | chokidar "^1.6.1" 187 | 188 | babel-code-frame@^6.26.0: 189 | version "6.26.0" 190 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" 191 | dependencies: 192 | chalk "^1.1.3" 193 | esutils "^2.0.2" 194 | js-tokens "^3.0.2" 195 | 196 | babel-core@^6.26.0: 197 | version "6.26.0" 198 | resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" 199 | dependencies: 200 | babel-code-frame "^6.26.0" 201 | babel-generator "^6.26.0" 202 | babel-helpers "^6.24.1" 203 | babel-messages "^6.23.0" 204 | babel-register "^6.26.0" 205 | babel-runtime "^6.26.0" 206 | babel-template "^6.26.0" 207 | babel-traverse "^6.26.0" 208 | babel-types "^6.26.0" 209 | babylon "^6.18.0" 210 | convert-source-map "^1.5.0" 211 | debug "^2.6.8" 212 | json5 "^0.5.1" 213 | lodash "^4.17.4" 214 | minimatch "^3.0.4" 215 | path-is-absolute "^1.0.1" 216 | private "^0.1.7" 217 | slash "^1.0.0" 218 | source-map "^0.5.6" 219 | 220 | babel-generator@^6.26.0: 221 | version "6.26.1" 222 | resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" 223 | dependencies: 224 | babel-messages "^6.23.0" 225 | babel-runtime "^6.26.0" 226 | babel-types "^6.26.0" 227 | detect-indent "^4.0.0" 228 | jsesc "^1.3.0" 229 | lodash "^4.17.4" 230 | source-map "^0.5.7" 231 | trim-right "^1.0.1" 232 | 233 | babel-helper-call-delegate@^6.24.1: 234 | version "6.24.1" 235 | resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" 236 | dependencies: 237 | babel-helper-hoist-variables "^6.24.1" 238 | babel-runtime "^6.22.0" 239 | babel-traverse "^6.24.1" 240 | babel-types "^6.24.1" 241 | 242 | babel-helper-define-map@^6.24.1: 243 | version "6.26.0" 244 | resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" 245 | dependencies: 246 | babel-helper-function-name "^6.24.1" 247 | babel-runtime "^6.26.0" 248 | babel-types "^6.26.0" 249 | lodash "^4.17.4" 250 | 251 | babel-helper-function-name@^6.24.1: 252 | version "6.24.1" 253 | resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" 254 | dependencies: 255 | babel-helper-get-function-arity "^6.24.1" 256 | babel-runtime "^6.22.0" 257 | babel-template "^6.24.1" 258 | babel-traverse "^6.24.1" 259 | babel-types "^6.24.1" 260 | 261 | babel-helper-get-function-arity@^6.24.1: 262 | version "6.24.1" 263 | resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" 264 | dependencies: 265 | babel-runtime "^6.22.0" 266 | babel-types "^6.24.1" 267 | 268 | babel-helper-hoist-variables@^6.24.1: 269 | version "6.24.1" 270 | resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" 271 | dependencies: 272 | babel-runtime "^6.22.0" 273 | babel-types "^6.24.1" 274 | 275 | babel-helper-optimise-call-expression@^6.24.1: 276 | version "6.24.1" 277 | resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" 278 | dependencies: 279 | babel-runtime "^6.22.0" 280 | babel-types "^6.24.1" 281 | 282 | babel-helper-regex@^6.24.1: 283 | version "6.26.0" 284 | resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" 285 | dependencies: 286 | babel-runtime "^6.26.0" 287 | babel-types "^6.26.0" 288 | lodash "^4.17.4" 289 | 290 | babel-helper-replace-supers@^6.24.1: 291 | version "6.24.1" 292 | resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" 293 | dependencies: 294 | babel-helper-optimise-call-expression "^6.24.1" 295 | babel-messages "^6.23.0" 296 | babel-runtime "^6.22.0" 297 | babel-template "^6.24.1" 298 | babel-traverse "^6.24.1" 299 | babel-types "^6.24.1" 300 | 301 | babel-helpers@^6.24.1: 302 | version "6.24.1" 303 | resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" 304 | dependencies: 305 | babel-runtime "^6.22.0" 306 | babel-template "^6.24.1" 307 | 308 | babel-messages@^6.23.0: 309 | version "6.23.0" 310 | resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" 311 | dependencies: 312 | babel-runtime "^6.22.0" 313 | 314 | babel-plugin-check-es2015-constants@^6.22.0: 315 | version "6.22.0" 316 | resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" 317 | dependencies: 318 | babel-runtime "^6.22.0" 319 | 320 | babel-plugin-transform-es2015-arrow-functions@^6.22.0: 321 | version "6.22.0" 322 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" 323 | dependencies: 324 | babel-runtime "^6.22.0" 325 | 326 | babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: 327 | version "6.22.0" 328 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" 329 | dependencies: 330 | babel-runtime "^6.22.0" 331 | 332 | babel-plugin-transform-es2015-block-scoping@^6.24.1: 333 | version "6.26.0" 334 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" 335 | dependencies: 336 | babel-runtime "^6.26.0" 337 | babel-template "^6.26.0" 338 | babel-traverse "^6.26.0" 339 | babel-types "^6.26.0" 340 | lodash "^4.17.4" 341 | 342 | babel-plugin-transform-es2015-classes@^6.24.1: 343 | version "6.24.1" 344 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" 345 | dependencies: 346 | babel-helper-define-map "^6.24.1" 347 | babel-helper-function-name "^6.24.1" 348 | babel-helper-optimise-call-expression "^6.24.1" 349 | babel-helper-replace-supers "^6.24.1" 350 | babel-messages "^6.23.0" 351 | babel-runtime "^6.22.0" 352 | babel-template "^6.24.1" 353 | babel-traverse "^6.24.1" 354 | babel-types "^6.24.1" 355 | 356 | babel-plugin-transform-es2015-computed-properties@^6.24.1: 357 | version "6.24.1" 358 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" 359 | dependencies: 360 | babel-runtime "^6.22.0" 361 | babel-template "^6.24.1" 362 | 363 | babel-plugin-transform-es2015-destructuring@^6.22.0: 364 | version "6.23.0" 365 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" 366 | dependencies: 367 | babel-runtime "^6.22.0" 368 | 369 | babel-plugin-transform-es2015-duplicate-keys@^6.24.1: 370 | version "6.24.1" 371 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" 372 | dependencies: 373 | babel-runtime "^6.22.0" 374 | babel-types "^6.24.1" 375 | 376 | babel-plugin-transform-es2015-for-of@^6.22.0: 377 | version "6.23.0" 378 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" 379 | dependencies: 380 | babel-runtime "^6.22.0" 381 | 382 | babel-plugin-transform-es2015-function-name@^6.24.1: 383 | version "6.24.1" 384 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" 385 | dependencies: 386 | babel-helper-function-name "^6.24.1" 387 | babel-runtime "^6.22.0" 388 | babel-types "^6.24.1" 389 | 390 | babel-plugin-transform-es2015-literals@^6.22.0: 391 | version "6.22.0" 392 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" 393 | dependencies: 394 | babel-runtime "^6.22.0" 395 | 396 | babel-plugin-transform-es2015-modules-amd@^6.24.1: 397 | version "6.24.1" 398 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" 399 | dependencies: 400 | babel-plugin-transform-es2015-modules-commonjs "^6.24.1" 401 | babel-runtime "^6.22.0" 402 | babel-template "^6.24.1" 403 | 404 | babel-plugin-transform-es2015-modules-commonjs@^6.24.1: 405 | version "6.26.0" 406 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" 407 | dependencies: 408 | babel-plugin-transform-strict-mode "^6.24.1" 409 | babel-runtime "^6.26.0" 410 | babel-template "^6.26.0" 411 | babel-types "^6.26.0" 412 | 413 | babel-plugin-transform-es2015-modules-systemjs@^6.24.1: 414 | version "6.24.1" 415 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" 416 | dependencies: 417 | babel-helper-hoist-variables "^6.24.1" 418 | babel-runtime "^6.22.0" 419 | babel-template "^6.24.1" 420 | 421 | babel-plugin-transform-es2015-modules-umd@^6.24.1: 422 | version "6.24.1" 423 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" 424 | dependencies: 425 | babel-plugin-transform-es2015-modules-amd "^6.24.1" 426 | babel-runtime "^6.22.0" 427 | babel-template "^6.24.1" 428 | 429 | babel-plugin-transform-es2015-object-super@^6.24.1: 430 | version "6.24.1" 431 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" 432 | dependencies: 433 | babel-helper-replace-supers "^6.24.1" 434 | babel-runtime "^6.22.0" 435 | 436 | babel-plugin-transform-es2015-parameters@^6.24.1: 437 | version "6.24.1" 438 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" 439 | dependencies: 440 | babel-helper-call-delegate "^6.24.1" 441 | babel-helper-get-function-arity "^6.24.1" 442 | babel-runtime "^6.22.0" 443 | babel-template "^6.24.1" 444 | babel-traverse "^6.24.1" 445 | babel-types "^6.24.1" 446 | 447 | babel-plugin-transform-es2015-shorthand-properties@^6.24.1: 448 | version "6.24.1" 449 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" 450 | dependencies: 451 | babel-runtime "^6.22.0" 452 | babel-types "^6.24.1" 453 | 454 | babel-plugin-transform-es2015-spread@^6.22.0: 455 | version "6.22.0" 456 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" 457 | dependencies: 458 | babel-runtime "^6.22.0" 459 | 460 | babel-plugin-transform-es2015-sticky-regex@^6.24.1: 461 | version "6.24.1" 462 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" 463 | dependencies: 464 | babel-helper-regex "^6.24.1" 465 | babel-runtime "^6.22.0" 466 | babel-types "^6.24.1" 467 | 468 | babel-plugin-transform-es2015-template-literals@^6.22.0: 469 | version "6.22.0" 470 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" 471 | dependencies: 472 | babel-runtime "^6.22.0" 473 | 474 | babel-plugin-transform-es2015-typeof-symbol@^6.22.0: 475 | version "6.23.0" 476 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" 477 | dependencies: 478 | babel-runtime "^6.22.0" 479 | 480 | babel-plugin-transform-es2015-unicode-regex@^6.24.1: 481 | version "6.24.1" 482 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" 483 | dependencies: 484 | babel-helper-regex "^6.24.1" 485 | babel-runtime "^6.22.0" 486 | regexpu-core "^2.0.0" 487 | 488 | babel-plugin-transform-regenerator@^6.24.1: 489 | version "6.26.0" 490 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" 491 | dependencies: 492 | regenerator-transform "^0.10.0" 493 | 494 | babel-plugin-transform-runtime@^6.15.0: 495 | version "6.23.0" 496 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz#88490d446502ea9b8e7efb0fe09ec4d99479b1ee" 497 | dependencies: 498 | babel-runtime "^6.22.0" 499 | 500 | babel-plugin-transform-strict-mode@^6.24.1: 501 | version "6.24.1" 502 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" 503 | dependencies: 504 | babel-runtime "^6.22.0" 505 | babel-types "^6.24.1" 506 | 507 | babel-polyfill@^6.26.0: 508 | version "6.26.0" 509 | resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" 510 | dependencies: 511 | babel-runtime "^6.26.0" 512 | core-js "^2.5.0" 513 | regenerator-runtime "^0.10.5" 514 | 515 | babel-preset-es2015@^6.18.0: 516 | version "6.24.1" 517 | resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" 518 | dependencies: 519 | babel-plugin-check-es2015-constants "^6.22.0" 520 | babel-plugin-transform-es2015-arrow-functions "^6.22.0" 521 | babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" 522 | babel-plugin-transform-es2015-block-scoping "^6.24.1" 523 | babel-plugin-transform-es2015-classes "^6.24.1" 524 | babel-plugin-transform-es2015-computed-properties "^6.24.1" 525 | babel-plugin-transform-es2015-destructuring "^6.22.0" 526 | babel-plugin-transform-es2015-duplicate-keys "^6.24.1" 527 | babel-plugin-transform-es2015-for-of "^6.22.0" 528 | babel-plugin-transform-es2015-function-name "^6.24.1" 529 | babel-plugin-transform-es2015-literals "^6.22.0" 530 | babel-plugin-transform-es2015-modules-amd "^6.24.1" 531 | babel-plugin-transform-es2015-modules-commonjs "^6.24.1" 532 | babel-plugin-transform-es2015-modules-systemjs "^6.24.1" 533 | babel-plugin-transform-es2015-modules-umd "^6.24.1" 534 | babel-plugin-transform-es2015-object-super "^6.24.1" 535 | babel-plugin-transform-es2015-parameters "^6.24.1" 536 | babel-plugin-transform-es2015-shorthand-properties "^6.24.1" 537 | babel-plugin-transform-es2015-spread "^6.22.0" 538 | babel-plugin-transform-es2015-sticky-regex "^6.24.1" 539 | babel-plugin-transform-es2015-template-literals "^6.22.0" 540 | babel-plugin-transform-es2015-typeof-symbol "^6.22.0" 541 | babel-plugin-transform-es2015-unicode-regex "^6.24.1" 542 | babel-plugin-transform-regenerator "^6.24.1" 543 | 544 | babel-register@^6.26.0: 545 | version "6.26.0" 546 | resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" 547 | dependencies: 548 | babel-core "^6.26.0" 549 | babel-runtime "^6.26.0" 550 | core-js "^2.5.0" 551 | home-or-tmp "^2.0.0" 552 | lodash "^4.17.4" 553 | mkdirp "^0.5.1" 554 | source-map-support "^0.4.15" 555 | 556 | babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: 557 | version "6.26.0" 558 | resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" 559 | dependencies: 560 | core-js "^2.4.0" 561 | regenerator-runtime "^0.11.0" 562 | 563 | babel-template@^6.24.1, babel-template@^6.26.0: 564 | version "6.26.0" 565 | resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" 566 | dependencies: 567 | babel-runtime "^6.26.0" 568 | babel-traverse "^6.26.0" 569 | babel-types "^6.26.0" 570 | babylon "^6.18.0" 571 | lodash "^4.17.4" 572 | 573 | babel-traverse@^6.24.1, babel-traverse@^6.26.0: 574 | version "6.26.0" 575 | resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" 576 | dependencies: 577 | babel-code-frame "^6.26.0" 578 | babel-messages "^6.23.0" 579 | babel-runtime "^6.26.0" 580 | babel-types "^6.26.0" 581 | babylon "^6.18.0" 582 | debug "^2.6.8" 583 | globals "^9.18.0" 584 | invariant "^2.2.2" 585 | lodash "^4.17.4" 586 | 587 | babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: 588 | version "6.26.0" 589 | resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" 590 | dependencies: 591 | babel-runtime "^6.26.0" 592 | esutils "^2.0.2" 593 | lodash "^4.17.4" 594 | to-fast-properties "^1.0.3" 595 | 596 | babylon@^6.18.0: 597 | version "6.18.0" 598 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" 599 | 600 | balanced-match@^1.0.0: 601 | version "1.0.0" 602 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 603 | 604 | bcrypt-pbkdf@^1.0.0: 605 | version "1.0.1" 606 | resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" 607 | dependencies: 608 | tweetnacl "^0.14.3" 609 | 610 | binary-extensions@^1.0.0: 611 | version "1.11.0" 612 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" 613 | 614 | block-stream@*: 615 | version "0.0.9" 616 | resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" 617 | dependencies: 618 | inherits "~2.0.0" 619 | 620 | body-parser@*, body-parser@^1.17.2: 621 | version "1.18.2" 622 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" 623 | dependencies: 624 | bytes "3.0.0" 625 | content-type "~1.0.4" 626 | debug "2.6.9" 627 | depd "~1.1.1" 628 | http-errors "~1.6.2" 629 | iconv-lite "0.4.19" 630 | on-finished "~2.3.0" 631 | qs "6.5.1" 632 | raw-body "2.3.2" 633 | type-is "~1.6.15" 634 | 635 | boom@2.x.x: 636 | version "2.10.1" 637 | resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" 638 | dependencies: 639 | hoek "2.x.x" 640 | 641 | brace-expansion@^1.1.7: 642 | version "1.1.11" 643 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 644 | dependencies: 645 | balanced-match "^1.0.0" 646 | concat-map "0.0.1" 647 | 648 | braces@^1.8.2: 649 | version "1.8.5" 650 | resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" 651 | dependencies: 652 | expand-range "^1.8.1" 653 | preserve "^0.2.0" 654 | repeat-element "^1.1.2" 655 | 656 | browser-stdout@1.3.1: 657 | version "1.3.1" 658 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 659 | 660 | builtin-modules@^1.0.0: 661 | version "1.1.1" 662 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 663 | 664 | bytes@3.0.0: 665 | version "3.0.0" 666 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" 667 | 668 | callsite@*, callsite@1.0.0: 669 | version "1.0.0" 670 | resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" 671 | 672 | camelcase-keys@^2.0.0: 673 | version "2.1.0" 674 | resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" 675 | dependencies: 676 | camelcase "^2.0.0" 677 | map-obj "^1.0.0" 678 | 679 | camelcase@^1.0.2: 680 | version "1.2.1" 681 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" 682 | 683 | camelcase@^2.0.0: 684 | version "2.1.1" 685 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" 686 | 687 | caseless@~0.12.0: 688 | version "0.12.0" 689 | resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" 690 | 691 | center-align@^0.1.1: 692 | version "0.1.3" 693 | resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" 694 | dependencies: 695 | align-text "^0.1.3" 696 | lazy-cache "^1.0.3" 697 | 698 | chalk@^1.1.3: 699 | version "1.1.3" 700 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 701 | dependencies: 702 | ansi-styles "^2.2.1" 703 | escape-string-regexp "^1.0.2" 704 | has-ansi "^2.0.0" 705 | strip-ansi "^3.0.0" 706 | supports-color "^2.0.0" 707 | 708 | chalk@^2.3.0: 709 | version "2.3.2" 710 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" 711 | dependencies: 712 | ansi-styles "^3.2.1" 713 | escape-string-regexp "^1.0.5" 714 | supports-color "^5.3.0" 715 | 716 | chokidar@^1.6.1: 717 | version "1.7.0" 718 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" 719 | dependencies: 720 | anymatch "^1.3.0" 721 | async-each "^1.0.0" 722 | glob-parent "^2.0.0" 723 | inherits "^2.0.1" 724 | is-binary-path "^1.0.0" 725 | is-glob "^2.0.0" 726 | path-is-absolute "^1.0.0" 727 | readdirp "^2.0.0" 728 | optionalDependencies: 729 | fsevents "^1.0.0" 730 | 731 | cliui@^2.1.0: 732 | version "2.1.0" 733 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" 734 | dependencies: 735 | center-align "^0.1.1" 736 | right-align "^0.1.1" 737 | wordwrap "0.0.2" 738 | 739 | clone@^1.0.2: 740 | version "1.0.4" 741 | resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" 742 | 743 | co@^4.6.0: 744 | version "4.6.0" 745 | resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" 746 | 747 | code-point-at@^1.0.0: 748 | version "1.1.0" 749 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 750 | 751 | color-convert@^1.9.0: 752 | version "1.9.1" 753 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 754 | dependencies: 755 | color-name "^1.1.1" 756 | 757 | color-name@^1.1.1: 758 | version "1.1.3" 759 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 760 | 761 | colors@*: 762 | version "1.2.1" 763 | resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.1.tgz#f4a3d302976aaf042356ba1ade3b1a2c62d9d794" 764 | 765 | colors@1.0.x: 766 | version "1.0.3" 767 | resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" 768 | 769 | combined-stream@^1.0.5, combined-stream@~1.0.5: 770 | version "1.0.6" 771 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" 772 | dependencies: 773 | delayed-stream "~1.0.0" 774 | 775 | commander@0.6.1: 776 | version "0.6.1" 777 | resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" 778 | 779 | commander@2.11.0: 780 | version "2.11.0" 781 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" 782 | 783 | commander@2.3.0: 784 | version "2.3.0" 785 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" 786 | 787 | commander@^2.11.0: 788 | version "2.15.1" 789 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" 790 | 791 | concat-map@0.0.1: 792 | version "0.0.1" 793 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 794 | 795 | console-control-strings@^1.0.0, console-control-strings@~1.1.0: 796 | version "1.1.0" 797 | resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" 798 | 799 | console.table@*: 800 | version "0.10.0" 801 | resolved "https://registry.yarnpkg.com/console.table/-/console.table-0.10.0.tgz#0917025588875befd70cf2eff4bef2c6e2d75d04" 802 | dependencies: 803 | easy-table "1.1.0" 804 | 805 | content-type@~1.0.4: 806 | version "1.0.4" 807 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 808 | 809 | convert-source-map@^1.5.0: 810 | version "1.5.1" 811 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" 812 | 813 | core-js@^2.4.0, core-js@^2.5.0: 814 | version "2.5.3" 815 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" 816 | 817 | core-util-is@1.0.2, core-util-is@~1.0.0: 818 | version "1.0.2" 819 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 820 | 821 | cors@^2.8.3: 822 | version "2.8.4" 823 | resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.4.tgz#2bd381f2eb201020105cd50ea59da63090694686" 824 | dependencies: 825 | object-assign "^4" 826 | vary "^1" 827 | 828 | cryptiles@2.x.x: 829 | version "2.0.5" 830 | resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" 831 | dependencies: 832 | boom "2.x.x" 833 | 834 | currently-unhandled@^0.4.1: 835 | version "0.4.1" 836 | resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" 837 | dependencies: 838 | array-find-index "^1.0.1" 839 | 840 | cycle@1.0.x: 841 | version "1.0.3" 842 | resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" 843 | 844 | daemon@1.1.0: 845 | version "1.1.0" 846 | resolved "https://registry.yarnpkg.com/daemon/-/daemon-1.1.0.tgz#6c5102c81db0be856fc9008fc2c935b398864ae8" 847 | 848 | dashdash@^1.12.0: 849 | version "1.14.1" 850 | resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" 851 | dependencies: 852 | assert-plus "^1.0.0" 853 | 854 | dateformat@^1.0.12: 855 | version "1.0.12" 856 | resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" 857 | dependencies: 858 | get-stdin "^4.0.1" 859 | meow "^3.3.0" 860 | 861 | debug@2.2.0: 862 | version "2.2.0" 863 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" 864 | dependencies: 865 | ms "0.7.1" 866 | 867 | debug@2.6.9, debug@^2.2.0, debug@^2.6.8: 868 | version "2.6.9" 869 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 870 | dependencies: 871 | ms "2.0.0" 872 | 873 | debug@3.1.0: 874 | version "3.1.0" 875 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 876 | dependencies: 877 | ms "2.0.0" 878 | 879 | debug@~0.7.4: 880 | version "0.7.4" 881 | resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" 882 | 883 | decamelize@^1.0.0, decamelize@^1.1.2: 884 | version "1.2.0" 885 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 886 | 887 | deep-extend@~0.4.0: 888 | version "0.4.2" 889 | resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" 890 | 891 | defaults@^1.0.3: 892 | version "1.0.3" 893 | resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" 894 | dependencies: 895 | clone "^1.0.2" 896 | 897 | delayed-stream@~1.0.0: 898 | version "1.0.0" 899 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 900 | 901 | delegates@^1.0.0: 902 | version "1.0.0" 903 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 904 | 905 | depd@1.1.1: 906 | version "1.1.1" 907 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" 908 | 909 | depd@~1.1.1: 910 | version "1.1.2" 911 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 912 | 913 | detect-indent@^4.0.0: 914 | version "4.0.0" 915 | resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" 916 | dependencies: 917 | repeating "^2.0.0" 918 | 919 | detect-libc@^1.0.2: 920 | version "1.0.3" 921 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" 922 | 923 | diff@1.4.0: 924 | version "1.4.0" 925 | resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" 926 | 927 | diff@3.5.0, diff@^3.1.0: 928 | version "3.5.0" 929 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" 930 | 931 | easy-table@1.1.0: 932 | version "1.1.0" 933 | resolved "https://registry.yarnpkg.com/easy-table/-/easy-table-1.1.0.tgz#86f9ab4c102f0371b7297b92a651d5824bc8cb73" 934 | optionalDependencies: 935 | wcwidth ">=1.0.1" 936 | 937 | ecc-jsbn@~0.1.1: 938 | version "0.1.1" 939 | resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" 940 | dependencies: 941 | jsbn "~0.1.0" 942 | 943 | ee-first@1.1.1: 944 | version "1.1.1" 945 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 946 | 947 | error-ex@^1.2.0: 948 | version "1.3.1" 949 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" 950 | dependencies: 951 | is-arrayish "^0.2.1" 952 | 953 | es6-promise@^4.1.0: 954 | version "4.2.4" 955 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" 956 | 957 | escape-string-regexp@1.0.2: 958 | version "1.0.2" 959 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" 960 | 961 | escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: 962 | version "1.0.5" 963 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 964 | 965 | esutils@^2.0.2: 966 | version "2.0.2" 967 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 968 | 969 | expand-brackets@^0.1.4: 970 | version "0.1.5" 971 | resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" 972 | dependencies: 973 | is-posix-bracket "^0.1.0" 974 | 975 | expand-range@^1.8.1: 976 | version "1.8.2" 977 | resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" 978 | dependencies: 979 | fill-range "^2.1.0" 980 | 981 | expect.js@*, expect.js@0.3.1: 982 | version "0.3.1" 983 | resolved "https://registry.yarnpkg.com/expect.js/-/expect.js-0.3.1.tgz#b0a59a0d2eff5437544ebf0ceaa6015841d09b5b" 984 | 985 | extend@~3.0.0: 986 | version "3.0.1" 987 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" 988 | 989 | extglob@^0.3.1: 990 | version "0.3.2" 991 | resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" 992 | dependencies: 993 | is-extglob "^1.0.0" 994 | 995 | extsprintf@1.3.0: 996 | version "1.3.0" 997 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" 998 | 999 | extsprintf@^1.2.0: 1000 | version "1.4.0" 1001 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" 1002 | 1003 | eyes@0.1.x: 1004 | version "0.1.8" 1005 | resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" 1006 | 1007 | filename-regex@^2.0.0: 1008 | version "2.0.1" 1009 | resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" 1010 | 1011 | fill-range@^2.1.0: 1012 | version "2.2.3" 1013 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" 1014 | dependencies: 1015 | is-number "^2.1.0" 1016 | isobject "^2.0.0" 1017 | randomatic "^1.1.3" 1018 | repeat-element "^1.1.2" 1019 | repeat-string "^1.5.2" 1020 | 1021 | find-up@^1.0.0: 1022 | version "1.1.2" 1023 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" 1024 | dependencies: 1025 | path-exists "^2.0.0" 1026 | pinkie-promise "^2.0.0" 1027 | 1028 | for-in@^1.0.1: 1029 | version "1.0.2" 1030 | resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" 1031 | 1032 | for-own@^0.1.4: 1033 | version "0.1.5" 1034 | resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" 1035 | dependencies: 1036 | for-in "^1.0.1" 1037 | 1038 | forever-agent@~0.6.1: 1039 | version "0.6.1" 1040 | resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" 1041 | 1042 | form-data@~2.1.1: 1043 | version "2.1.4" 1044 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" 1045 | dependencies: 1046 | asynckit "^0.4.0" 1047 | combined-stream "^1.0.5" 1048 | mime-types "^2.1.12" 1049 | 1050 | formatio@1.1.1: 1051 | version "1.1.1" 1052 | resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9" 1053 | dependencies: 1054 | samsam "~1.1" 1055 | 1056 | fs-extra@^5.0.0: 1057 | version "5.0.0" 1058 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" 1059 | dependencies: 1060 | graceful-fs "^4.1.2" 1061 | jsonfile "^4.0.0" 1062 | universalify "^0.1.0" 1063 | 1064 | fs-readdir-recursive@^1.0.0: 1065 | version "1.1.0" 1066 | resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" 1067 | 1068 | fs.realpath@^1.0.0: 1069 | version "1.0.0" 1070 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 1071 | 1072 | fsevents@^1.0.0: 1073 | version "1.1.3" 1074 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" 1075 | dependencies: 1076 | nan "^2.3.0" 1077 | node-pre-gyp "^0.6.39" 1078 | 1079 | fstream-ignore@^1.0.5: 1080 | version "1.0.5" 1081 | resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" 1082 | dependencies: 1083 | fstream "^1.0.0" 1084 | inherits "2" 1085 | minimatch "^3.0.0" 1086 | 1087 | fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: 1088 | version "1.0.11" 1089 | resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" 1090 | dependencies: 1091 | graceful-fs "^4.1.2" 1092 | inherits "~2.0.0" 1093 | mkdirp ">=0.5 0" 1094 | rimraf "2" 1095 | 1096 | gauge@~2.7.3: 1097 | version "2.7.4" 1098 | resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" 1099 | dependencies: 1100 | aproba "^1.0.3" 1101 | console-control-strings "^1.0.0" 1102 | has-unicode "^2.0.0" 1103 | object-assign "^4.1.0" 1104 | signal-exit "^3.0.0" 1105 | string-width "^1.0.1" 1106 | strip-ansi "^3.0.1" 1107 | wide-align "^1.1.0" 1108 | 1109 | get-stdin@^4.0.1: 1110 | version "4.0.1" 1111 | resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" 1112 | 1113 | getpass@^0.1.1: 1114 | version "0.1.7" 1115 | resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" 1116 | dependencies: 1117 | assert-plus "^1.0.0" 1118 | 1119 | glob-base@^0.3.0: 1120 | version "0.3.0" 1121 | resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" 1122 | dependencies: 1123 | glob-parent "^2.0.0" 1124 | is-glob "^2.0.0" 1125 | 1126 | glob-parent@^2.0.0: 1127 | version "2.0.0" 1128 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" 1129 | dependencies: 1130 | is-glob "^2.0.0" 1131 | 1132 | glob@3.2.11: 1133 | version "3.2.11" 1134 | resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" 1135 | dependencies: 1136 | inherits "2" 1137 | minimatch "0.3" 1138 | 1139 | glob@7.1.2, glob@^7.0.0, glob@^7.0.5, glob@^7.1.2: 1140 | version "7.1.2" 1141 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 1142 | dependencies: 1143 | fs.realpath "^1.0.0" 1144 | inflight "^1.0.4" 1145 | inherits "2" 1146 | minimatch "^3.0.4" 1147 | once "^1.3.0" 1148 | path-is-absolute "^1.0.0" 1149 | 1150 | globals@^9.18.0: 1151 | version "9.18.0" 1152 | resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" 1153 | 1154 | graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6: 1155 | version "4.1.11" 1156 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" 1157 | 1158 | growl@1.10.3: 1159 | version "1.10.3" 1160 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" 1161 | 1162 | growl@1.9.2: 1163 | version "1.9.2" 1164 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" 1165 | 1166 | handlebars@^4.0.6: 1167 | version "4.0.11" 1168 | resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" 1169 | dependencies: 1170 | async "^1.4.0" 1171 | optimist "^0.6.1" 1172 | source-map "^0.4.4" 1173 | optionalDependencies: 1174 | uglify-js "^2.6" 1175 | 1176 | har-schema@^1.0.5: 1177 | version "1.0.5" 1178 | resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" 1179 | 1180 | har-validator@~4.2.1: 1181 | version "4.2.1" 1182 | resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" 1183 | dependencies: 1184 | ajv "^4.9.1" 1185 | har-schema "^1.0.5" 1186 | 1187 | has-ansi@^2.0.0: 1188 | version "2.0.0" 1189 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 1190 | dependencies: 1191 | ansi-regex "^2.0.0" 1192 | 1193 | has-flag@^2.0.0: 1194 | version "2.0.0" 1195 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" 1196 | 1197 | has-flag@^3.0.0: 1198 | version "3.0.0" 1199 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 1200 | 1201 | has-unicode@^2.0.0: 1202 | version "2.0.1" 1203 | resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" 1204 | 1205 | hawk@3.1.3, hawk@~3.1.3: 1206 | version "3.1.3" 1207 | resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" 1208 | dependencies: 1209 | boom "2.x.x" 1210 | cryptiles "2.x.x" 1211 | hoek "2.x.x" 1212 | sntp "1.x.x" 1213 | 1214 | he@1.1.1: 1215 | version "1.1.1" 1216 | resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" 1217 | 1218 | highlight.js@^9.0.0: 1219 | version "9.12.0" 1220 | resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" 1221 | 1222 | hoek@2.x.x: 1223 | version "2.16.3" 1224 | resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" 1225 | 1226 | hoek@4.x.x: 1227 | version "4.2.1" 1228 | resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" 1229 | 1230 | home-or-tmp@^2.0.0: 1231 | version "2.0.0" 1232 | resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" 1233 | dependencies: 1234 | os-homedir "^1.0.0" 1235 | os-tmpdir "^1.0.1" 1236 | 1237 | hosted-git-info@^2.1.4: 1238 | version "2.6.0" 1239 | resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.6.0.tgz#23235b29ab230c576aab0d4f13fc046b0b038222" 1240 | 1241 | http-errors@1.6.2, http-errors@~1.6.2: 1242 | version "1.6.2" 1243 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" 1244 | dependencies: 1245 | depd "1.1.1" 1246 | inherits "2.0.3" 1247 | setprototypeof "1.0.3" 1248 | statuses ">= 1.3.1 < 2" 1249 | 1250 | http-signature@~1.1.0: 1251 | version "1.1.1" 1252 | resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" 1253 | dependencies: 1254 | assert-plus "^0.2.0" 1255 | jsprim "^1.2.2" 1256 | sshpk "^1.7.0" 1257 | 1258 | iconv-lite@0.4.19: 1259 | version "0.4.19" 1260 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" 1261 | 1262 | indent-string@^2.1.0: 1263 | version "2.1.0" 1264 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" 1265 | dependencies: 1266 | repeating "^2.0.0" 1267 | 1268 | inflight@^1.0.4: 1269 | version "1.0.6" 1270 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 1271 | dependencies: 1272 | once "^1.3.0" 1273 | wrappy "1" 1274 | 1275 | inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.3: 1276 | version "2.0.3" 1277 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 1278 | 1279 | inherits@2.0.1: 1280 | version "2.0.1" 1281 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" 1282 | 1283 | ini@~1.3.0: 1284 | version "1.3.5" 1285 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" 1286 | 1287 | interpret@^1.0.0: 1288 | version "1.1.0" 1289 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" 1290 | 1291 | invariant@^2.2.2: 1292 | version "2.2.4" 1293 | resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" 1294 | dependencies: 1295 | loose-envify "^1.0.0" 1296 | 1297 | is-arrayish@^0.2.1: 1298 | version "0.2.1" 1299 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" 1300 | 1301 | is-binary-path@^1.0.0: 1302 | version "1.0.1" 1303 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" 1304 | dependencies: 1305 | binary-extensions "^1.0.0" 1306 | 1307 | is-buffer@^1.1.5: 1308 | version "1.1.6" 1309 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" 1310 | 1311 | is-builtin-module@^1.0.0: 1312 | version "1.0.0" 1313 | resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" 1314 | dependencies: 1315 | builtin-modules "^1.0.0" 1316 | 1317 | is-dotfile@^1.0.0: 1318 | version "1.0.3" 1319 | resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" 1320 | 1321 | is-equal-shallow@^0.1.3: 1322 | version "0.1.3" 1323 | resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" 1324 | dependencies: 1325 | is-primitive "^2.0.0" 1326 | 1327 | is-extendable@^0.1.1: 1328 | version "0.1.1" 1329 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" 1330 | 1331 | is-extglob@^1.0.0: 1332 | version "1.0.0" 1333 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" 1334 | 1335 | is-finite@^1.0.0: 1336 | version "1.0.2" 1337 | resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" 1338 | dependencies: 1339 | number-is-nan "^1.0.0" 1340 | 1341 | is-fullwidth-code-point@^1.0.0: 1342 | version "1.0.0" 1343 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 1344 | dependencies: 1345 | number-is-nan "^1.0.0" 1346 | 1347 | is-glob@^2.0.0, is-glob@^2.0.1: 1348 | version "2.0.1" 1349 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" 1350 | dependencies: 1351 | is-extglob "^1.0.0" 1352 | 1353 | is-number@^2.1.0: 1354 | version "2.1.0" 1355 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" 1356 | dependencies: 1357 | kind-of "^3.0.2" 1358 | 1359 | is-number@^3.0.0: 1360 | version "3.0.0" 1361 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" 1362 | dependencies: 1363 | kind-of "^3.0.2" 1364 | 1365 | is-posix-bracket@^0.1.0: 1366 | version "0.1.1" 1367 | resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" 1368 | 1369 | is-primitive@^2.0.0: 1370 | version "2.0.0" 1371 | resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" 1372 | 1373 | is-string@^1.0.4: 1374 | version "1.0.4" 1375 | resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64" 1376 | 1377 | is-typedarray@~1.0.0: 1378 | version "1.0.0" 1379 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 1380 | 1381 | is-utf8@^0.2.0: 1382 | version "0.2.1" 1383 | resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" 1384 | 1385 | isarray@1.0.0, isarray@~1.0.0: 1386 | version "1.0.0" 1387 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 1388 | 1389 | isemail@2.x.x: 1390 | version "2.2.1" 1391 | resolved "https://registry.yarnpkg.com/isemail/-/isemail-2.2.1.tgz#0353d3d9a62951080c262c2aa0a42b8ea8e9e2a6" 1392 | 1393 | isobject@^2.0.0: 1394 | version "2.1.0" 1395 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 1396 | dependencies: 1397 | isarray "1.0.0" 1398 | 1399 | isstream@0.1.x, isstream@~0.1.2: 1400 | version "0.1.2" 1401 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" 1402 | 1403 | items@2.x.x: 1404 | version "2.1.1" 1405 | resolved "https://registry.yarnpkg.com/items/-/items-2.1.1.tgz#8bd16d9c83b19529de5aea321acaada78364a198" 1406 | 1407 | jade@0.26.3: 1408 | version "0.26.3" 1409 | resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" 1410 | dependencies: 1411 | commander "0.6.1" 1412 | mkdirp "0.3.0" 1413 | 1414 | joi@^10.5.2: 1415 | version "10.6.0" 1416 | resolved "https://registry.yarnpkg.com/joi/-/joi-10.6.0.tgz#52587f02d52b8b75cdb0c74f0b164a191a0e1fc2" 1417 | dependencies: 1418 | hoek "4.x.x" 1419 | isemail "2.x.x" 1420 | items "2.x.x" 1421 | topo "2.x.x" 1422 | 1423 | js-csp@^0.9.3: 1424 | version "0.9.3" 1425 | resolved "https://registry.yarnpkg.com/js-csp/-/js-csp-0.9.3.tgz#8514769c62a39fbdeacd91228230955cdeeee1a3" 1426 | dependencies: 1427 | babel-runtime "^6.22.0" 1428 | lodash "^4.17.4" 1429 | 1430 | js-tokens@^3.0.0, js-tokens@^3.0.2: 1431 | version "3.0.2" 1432 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" 1433 | 1434 | jsbn@~0.1.0: 1435 | version "0.1.1" 1436 | resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" 1437 | 1438 | jsesc@^1.3.0: 1439 | version "1.3.0" 1440 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" 1441 | 1442 | jsesc@~0.5.0: 1443 | version "0.5.0" 1444 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" 1445 | 1446 | json-schema@0.2.3: 1447 | version "0.2.3" 1448 | resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" 1449 | 1450 | json-stable-stringify@^1.0.1: 1451 | version "1.0.1" 1452 | resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" 1453 | dependencies: 1454 | jsonify "~0.0.0" 1455 | 1456 | json-stringify-safe@~5.0.1: 1457 | version "5.0.1" 1458 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 1459 | 1460 | json5@^0.5.1: 1461 | version "0.5.1" 1462 | resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" 1463 | 1464 | jsonfile@^4.0.0: 1465 | version "4.0.0" 1466 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" 1467 | optionalDependencies: 1468 | graceful-fs "^4.1.6" 1469 | 1470 | jsonify@~0.0.0: 1471 | version "0.0.0" 1472 | resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" 1473 | 1474 | jsonutil@0.2.0: 1475 | version "0.2.0" 1476 | resolved "https://registry.yarnpkg.com/jsonutil/-/jsonutil-0.2.0.tgz#fe1f9cf8735658660d5a178ef6f6789f8e2fead5" 1477 | 1478 | jsprim@^1.2.2: 1479 | version "1.4.1" 1480 | resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" 1481 | dependencies: 1482 | assert-plus "1.0.0" 1483 | extsprintf "1.3.0" 1484 | json-schema "0.2.3" 1485 | verror "1.10.0" 1486 | 1487 | kind-of@^3.0.2: 1488 | version "3.2.2" 1489 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" 1490 | dependencies: 1491 | is-buffer "^1.1.5" 1492 | 1493 | kind-of@^4.0.0: 1494 | version "4.0.0" 1495 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" 1496 | dependencies: 1497 | is-buffer "^1.1.5" 1498 | 1499 | lazy-cache@^1.0.3: 1500 | version "1.0.4" 1501 | resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" 1502 | 1503 | load-json-file@^1.0.0: 1504 | version "1.1.0" 1505 | resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" 1506 | dependencies: 1507 | graceful-fs "^4.1.2" 1508 | parse-json "^2.2.0" 1509 | pify "^2.0.0" 1510 | pinkie-promise "^2.0.0" 1511 | strip-bom "^2.0.0" 1512 | 1513 | lodash@^4.17.4, lodash@^4.17.5: 1514 | version "4.17.5" 1515 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" 1516 | 1517 | lolex@1.3.2: 1518 | version "1.3.2" 1519 | resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" 1520 | 1521 | longest@^1.0.1: 1522 | version "1.0.1" 1523 | resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" 1524 | 1525 | loose-envify@^1.0.0: 1526 | version "1.3.1" 1527 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" 1528 | dependencies: 1529 | js-tokens "^3.0.0" 1530 | 1531 | loud-rejection@^1.0.0: 1532 | version "1.6.0" 1533 | resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" 1534 | dependencies: 1535 | currently-unhandled "^0.4.1" 1536 | signal-exit "^3.0.0" 1537 | 1538 | lru-cache@2: 1539 | version "2.7.3" 1540 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" 1541 | 1542 | make-error@^1.1.1: 1543 | version "1.3.4" 1544 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.4.tgz#19978ed575f9e9545d2ff8c13e33b5d18a67d535" 1545 | 1546 | map-obj@^1.0.0, map-obj@^1.0.1: 1547 | version "1.0.1" 1548 | resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" 1549 | 1550 | marked@^0.3.17: 1551 | version "0.3.18" 1552 | resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.18.tgz#3ef058cd926101849b92a7a7c15db18c7fc76b2f" 1553 | 1554 | media-typer@0.3.0: 1555 | version "0.3.0" 1556 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 1557 | 1558 | meow@^3.3.0: 1559 | version "3.7.0" 1560 | resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" 1561 | dependencies: 1562 | camelcase-keys "^2.0.0" 1563 | decamelize "^1.1.2" 1564 | loud-rejection "^1.0.0" 1565 | map-obj "^1.0.1" 1566 | minimist "^1.1.3" 1567 | normalize-package-data "^2.3.4" 1568 | object-assign "^4.0.1" 1569 | read-pkg-up "^1.0.1" 1570 | redent "^1.0.0" 1571 | trim-newlines "^1.0.0" 1572 | 1573 | micromatch@^2.1.5: 1574 | version "2.3.11" 1575 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" 1576 | dependencies: 1577 | arr-diff "^2.0.0" 1578 | array-unique "^0.2.1" 1579 | braces "^1.8.2" 1580 | expand-brackets "^0.1.4" 1581 | extglob "^0.3.1" 1582 | filename-regex "^2.0.0" 1583 | is-extglob "^1.0.0" 1584 | is-glob "^2.0.1" 1585 | kind-of "^3.0.2" 1586 | normalize-path "^2.0.1" 1587 | object.omit "^2.0.0" 1588 | parse-glob "^3.0.4" 1589 | regex-cache "^0.4.2" 1590 | 1591 | mime-db@~1.33.0: 1592 | version "1.33.0" 1593 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" 1594 | 1595 | mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.7: 1596 | version "2.1.18" 1597 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" 1598 | dependencies: 1599 | mime-db "~1.33.0" 1600 | 1601 | minimatch@0.3: 1602 | version "0.3.0" 1603 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" 1604 | dependencies: 1605 | lru-cache "2" 1606 | sigmund "~1.0.0" 1607 | 1608 | minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: 1609 | version "3.0.4" 1610 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 1611 | dependencies: 1612 | brace-expansion "^1.1.7" 1613 | 1614 | minimist@0.0.8: 1615 | version "0.0.8" 1616 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 1617 | 1618 | minimist@^1.1.3, minimist@^1.2.0: 1619 | version "1.2.0" 1620 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 1621 | 1622 | minimist@~0.0.1: 1623 | version "0.0.10" 1624 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" 1625 | 1626 | mkdirp@0.3.0: 1627 | version "0.3.0" 1628 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" 1629 | 1630 | mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.1: 1631 | version "0.5.1" 1632 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 1633 | dependencies: 1634 | minimist "0.0.8" 1635 | 1636 | mocha-multi@0.9.1: 1637 | version "0.9.1" 1638 | resolved "https://registry.yarnpkg.com/mocha-multi/-/mocha-multi-0.9.1.tgz#0f97ff4214f1a7accaf43e4bdc7cdfc73746d835" 1639 | dependencies: 1640 | debug "~0.7.4" 1641 | is-string "^1.0.4" 1642 | mkdirp "^0.5.1" 1643 | 1644 | mocha-sinon@1.1.5: 1645 | version "1.1.5" 1646 | resolved "https://registry.yarnpkg.com/mocha-sinon/-/mocha-sinon-1.1.5.tgz#42d187996c56ce68bf0ec08b6611c44c75b01cd8" 1647 | 1648 | mocha-teamcity-reporter@1.1.1: 1649 | version "1.1.1" 1650 | resolved "https://registry.yarnpkg.com/mocha-teamcity-reporter/-/mocha-teamcity-reporter-1.1.1.tgz#696e67b3d3d3bf7222c3608f3523537f85411439" 1651 | dependencies: 1652 | mocha ">=1.13.0" 1653 | 1654 | mocha@2.5.3: 1655 | version "2.5.3" 1656 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.5.3.tgz#161be5bdeb496771eb9b35745050b622b5aefc58" 1657 | dependencies: 1658 | commander "2.3.0" 1659 | debug "2.2.0" 1660 | diff "1.4.0" 1661 | escape-string-regexp "1.0.2" 1662 | glob "3.2.11" 1663 | growl "1.9.2" 1664 | jade "0.26.3" 1665 | mkdirp "0.5.1" 1666 | supports-color "1.2.0" 1667 | to-iso-string "0.0.2" 1668 | 1669 | mocha@>=1.13.0: 1670 | version "5.0.5" 1671 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.5.tgz#e228e3386b9387a4710007a641f127b00be44b52" 1672 | dependencies: 1673 | browser-stdout "1.3.1" 1674 | commander "2.11.0" 1675 | debug "3.1.0" 1676 | diff "3.5.0" 1677 | escape-string-regexp "1.0.5" 1678 | glob "7.1.2" 1679 | growl "1.10.3" 1680 | he "1.1.1" 1681 | mkdirp "0.5.1" 1682 | supports-color "4.4.0" 1683 | 1684 | moment@^2.18.1: 1685 | version "2.21.0" 1686 | resolved "https://registry.yarnpkg.com/moment/-/moment-2.21.0.tgz#2a114b51d2a6ec9e6d83cf803f838a878d8a023a" 1687 | 1688 | ms@0.7.1: 1689 | version "0.7.1" 1690 | resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" 1691 | 1692 | ms@2.0.0: 1693 | version "2.0.0" 1694 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 1695 | 1696 | muon-core@^7.3.0-1: 1697 | version "7.3.0-77" 1698 | resolved "https://registry.yarnpkg.com/muon-core/-/muon-core-7.3.0-77.tgz#1811d1042fb3cc78039624ace094fbac1ba1e539" 1699 | dependencies: 1700 | babel-runtime "^6.18.0" 1701 | body-parser "^1.17.2" 1702 | callsite "1.0.0" 1703 | cors "^2.8.3" 1704 | daemon "1.1.0" 1705 | es6-promise "^4.1.0" 1706 | expect.js "0.3.1" 1707 | joi "^10.5.2" 1708 | js-csp "^0.9.3" 1709 | jsonutil "0.2.0" 1710 | moment "^2.18.1" 1711 | pako "^1.0.5" 1712 | rsvp "^3.5.0" 1713 | rx "4.1.0" 1714 | sexylog "0.0.3" 1715 | split "1.0.0" 1716 | stack-trace "0.0.10" 1717 | string-format "0.5.0" 1718 | underscore "1.8.3" 1719 | url "0.11.0" 1720 | url-template "2.0.8" 1721 | uuid "^3.0.1" 1722 | 1723 | nan@^2.3.0: 1724 | version "2.10.0" 1725 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" 1726 | 1727 | node-pre-gyp@^0.6.39: 1728 | version "0.6.39" 1729 | resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" 1730 | dependencies: 1731 | detect-libc "^1.0.2" 1732 | hawk "3.1.3" 1733 | mkdirp "^0.5.1" 1734 | nopt "^4.0.1" 1735 | npmlog "^4.0.2" 1736 | rc "^1.1.7" 1737 | request "2.81.0" 1738 | rimraf "^2.6.1" 1739 | semver "^5.3.0" 1740 | tar "^2.2.1" 1741 | tar-pack "^3.4.0" 1742 | 1743 | node-uuid@*: 1744 | version "1.4.8" 1745 | resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" 1746 | 1747 | nopt@^4.0.1: 1748 | version "4.0.1" 1749 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" 1750 | dependencies: 1751 | abbrev "1" 1752 | osenv "^0.1.4" 1753 | 1754 | normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: 1755 | version "2.4.0" 1756 | resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" 1757 | dependencies: 1758 | hosted-git-info "^2.1.4" 1759 | is-builtin-module "^1.0.0" 1760 | semver "2 || 3 || 4 || 5" 1761 | validate-npm-package-license "^3.0.1" 1762 | 1763 | normalize-path@^2.0.0, normalize-path@^2.0.1: 1764 | version "2.1.1" 1765 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" 1766 | dependencies: 1767 | remove-trailing-separator "^1.0.1" 1768 | 1769 | npmlog@^4.0.2: 1770 | version "4.1.2" 1771 | resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" 1772 | dependencies: 1773 | are-we-there-yet "~1.1.2" 1774 | console-control-strings "~1.1.0" 1775 | gauge "~2.7.3" 1776 | set-blocking "~2.0.0" 1777 | 1778 | number-is-nan@^1.0.0: 1779 | version "1.0.1" 1780 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 1781 | 1782 | oauth-sign@~0.8.1: 1783 | version "0.8.2" 1784 | resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" 1785 | 1786 | object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0: 1787 | version "4.1.1" 1788 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 1789 | 1790 | object.omit@^2.0.0: 1791 | version "2.0.1" 1792 | resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" 1793 | dependencies: 1794 | for-own "^0.1.4" 1795 | is-extendable "^0.1.1" 1796 | 1797 | on-finished@~2.3.0: 1798 | version "2.3.0" 1799 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 1800 | dependencies: 1801 | ee-first "1.1.1" 1802 | 1803 | once@^1.3.0, once@^1.3.3: 1804 | version "1.4.0" 1805 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1806 | dependencies: 1807 | wrappy "1" 1808 | 1809 | optimist@^0.6.1: 1810 | version "0.6.1" 1811 | resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" 1812 | dependencies: 1813 | minimist "~0.0.1" 1814 | wordwrap "~0.0.2" 1815 | 1816 | os-homedir@^1.0.0: 1817 | version "1.0.2" 1818 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 1819 | 1820 | os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: 1821 | version "1.0.2" 1822 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 1823 | 1824 | osenv@^0.1.4: 1825 | version "0.1.5" 1826 | resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" 1827 | dependencies: 1828 | os-homedir "^1.0.0" 1829 | os-tmpdir "^1.0.0" 1830 | 1831 | output-file-sync@^1.1.2: 1832 | version "1.1.2" 1833 | resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" 1834 | dependencies: 1835 | graceful-fs "^4.1.4" 1836 | mkdirp "^0.5.1" 1837 | object-assign "^4.1.0" 1838 | 1839 | pako@^1.0.5: 1840 | version "1.0.6" 1841 | resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" 1842 | 1843 | parse-glob@^3.0.4: 1844 | version "3.0.4" 1845 | resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" 1846 | dependencies: 1847 | glob-base "^0.3.0" 1848 | is-dotfile "^1.0.0" 1849 | is-extglob "^1.0.0" 1850 | is-glob "^2.0.0" 1851 | 1852 | parse-json@^2.2.0: 1853 | version "2.2.0" 1854 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" 1855 | dependencies: 1856 | error-ex "^1.2.0" 1857 | 1858 | path-exists@^2.0.0: 1859 | version "2.1.0" 1860 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" 1861 | dependencies: 1862 | pinkie-promise "^2.0.0" 1863 | 1864 | path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: 1865 | version "1.0.1" 1866 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1867 | 1868 | path-parse@^1.0.5: 1869 | version "1.0.5" 1870 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" 1871 | 1872 | path-type@^1.0.0: 1873 | version "1.1.0" 1874 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" 1875 | dependencies: 1876 | graceful-fs "^4.1.2" 1877 | pify "^2.0.0" 1878 | pinkie-promise "^2.0.0" 1879 | 1880 | performance-now@^0.2.0: 1881 | version "0.2.0" 1882 | resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" 1883 | 1884 | pify@^2.0.0: 1885 | version "2.3.0" 1886 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" 1887 | 1888 | pinkie-promise@^2.0.0: 1889 | version "2.0.1" 1890 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" 1891 | dependencies: 1892 | pinkie "^2.0.0" 1893 | 1894 | pinkie@^2.0.0: 1895 | version "2.0.4" 1896 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 1897 | 1898 | preserve@^0.2.0: 1899 | version "0.2.0" 1900 | resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" 1901 | 1902 | private@^0.1.6, private@^0.1.7: 1903 | version "0.1.8" 1904 | resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" 1905 | 1906 | process-nextick-args@~2.0.0: 1907 | version "2.0.0" 1908 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" 1909 | 1910 | progress@^2.0.0: 1911 | version "2.0.0" 1912 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" 1913 | 1914 | punycode@1.3.2: 1915 | version "1.3.2" 1916 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" 1917 | 1918 | punycode@^1.4.1: 1919 | version "1.4.1" 1920 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" 1921 | 1922 | qs@6.5.1: 1923 | version "6.5.1" 1924 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" 1925 | 1926 | qs@~6.4.0: 1927 | version "6.4.0" 1928 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" 1929 | 1930 | querystring@0.2.0: 1931 | version "0.2.0" 1932 | resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" 1933 | 1934 | randomatic@^1.1.3: 1935 | version "1.1.7" 1936 | resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" 1937 | dependencies: 1938 | is-number "^3.0.0" 1939 | kind-of "^4.0.0" 1940 | 1941 | raw-body@2.3.2: 1942 | version "2.3.2" 1943 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" 1944 | dependencies: 1945 | bytes "3.0.0" 1946 | http-errors "1.6.2" 1947 | iconv-lite "0.4.19" 1948 | unpipe "1.0.0" 1949 | 1950 | rc@^1.1.7: 1951 | version "1.2.6" 1952 | resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.6.tgz#eb18989c6d4f4f162c399f79ddd29f3835568092" 1953 | dependencies: 1954 | deep-extend "~0.4.0" 1955 | ini "~1.3.0" 1956 | minimist "^1.2.0" 1957 | strip-json-comments "~2.0.1" 1958 | 1959 | read-pkg-up@^1.0.1: 1960 | version "1.0.1" 1961 | resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" 1962 | dependencies: 1963 | find-up "^1.0.0" 1964 | read-pkg "^1.0.0" 1965 | 1966 | read-pkg@^1.0.0: 1967 | version "1.1.0" 1968 | resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" 1969 | dependencies: 1970 | load-json-file "^1.0.0" 1971 | normalize-package-data "^2.3.2" 1972 | path-type "^1.0.0" 1973 | 1974 | readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4: 1975 | version "2.3.5" 1976 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.5.tgz#b4f85003a938cbb6ecbce2a124fb1012bd1a838d" 1977 | dependencies: 1978 | core-util-is "~1.0.0" 1979 | inherits "~2.0.3" 1980 | isarray "~1.0.0" 1981 | process-nextick-args "~2.0.0" 1982 | safe-buffer "~5.1.1" 1983 | string_decoder "~1.0.3" 1984 | util-deprecate "~1.0.1" 1985 | 1986 | readdirp@^2.0.0: 1987 | version "2.1.0" 1988 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" 1989 | dependencies: 1990 | graceful-fs "^4.1.2" 1991 | minimatch "^3.0.2" 1992 | readable-stream "^2.0.2" 1993 | set-immediate-shim "^1.0.1" 1994 | 1995 | rechoir@^0.6.2: 1996 | version "0.6.2" 1997 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" 1998 | dependencies: 1999 | resolve "^1.1.6" 2000 | 2001 | redent@^1.0.0: 2002 | version "1.0.0" 2003 | resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" 2004 | dependencies: 2005 | indent-string "^2.1.0" 2006 | strip-indent "^1.0.1" 2007 | 2008 | regenerate@^1.2.1: 2009 | version "1.3.3" 2010 | resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" 2011 | 2012 | regenerator-runtime@^0.10.5: 2013 | version "0.10.5" 2014 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" 2015 | 2016 | regenerator-runtime@^0.11.0: 2017 | version "0.11.1" 2018 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" 2019 | 2020 | regenerator-transform@^0.10.0: 2021 | version "0.10.1" 2022 | resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" 2023 | dependencies: 2024 | babel-runtime "^6.18.0" 2025 | babel-types "^6.19.0" 2026 | private "^0.1.6" 2027 | 2028 | regex-cache@^0.4.2: 2029 | version "0.4.4" 2030 | resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" 2031 | dependencies: 2032 | is-equal-shallow "^0.1.3" 2033 | 2034 | regexpu-core@^2.0.0: 2035 | version "2.0.0" 2036 | resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" 2037 | dependencies: 2038 | regenerate "^1.2.1" 2039 | regjsgen "^0.2.0" 2040 | regjsparser "^0.1.4" 2041 | 2042 | regjsgen@^0.2.0: 2043 | version "0.2.0" 2044 | resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" 2045 | 2046 | regjsparser@^0.1.4: 2047 | version "0.1.5" 2048 | resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" 2049 | dependencies: 2050 | jsesc "~0.5.0" 2051 | 2052 | remove-trailing-separator@^1.0.1: 2053 | version "1.1.0" 2054 | resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" 2055 | 2056 | repeat-element@^1.1.2: 2057 | version "1.1.2" 2058 | resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" 2059 | 2060 | repeat-string@^1.5.2: 2061 | version "1.6.1" 2062 | resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" 2063 | 2064 | repeating@^2.0.0: 2065 | version "2.0.1" 2066 | resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" 2067 | dependencies: 2068 | is-finite "^1.0.0" 2069 | 2070 | request@2.81.0: 2071 | version "2.81.0" 2072 | resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" 2073 | dependencies: 2074 | aws-sign2 "~0.6.0" 2075 | aws4 "^1.2.1" 2076 | caseless "~0.12.0" 2077 | combined-stream "~1.0.5" 2078 | extend "~3.0.0" 2079 | forever-agent "~0.6.1" 2080 | form-data "~2.1.1" 2081 | har-validator "~4.2.1" 2082 | hawk "~3.1.3" 2083 | http-signature "~1.1.0" 2084 | is-typedarray "~1.0.0" 2085 | isstream "~0.1.2" 2086 | json-stringify-safe "~5.0.1" 2087 | mime-types "~2.1.7" 2088 | oauth-sign "~0.8.1" 2089 | performance-now "^0.2.0" 2090 | qs "~6.4.0" 2091 | safe-buffer "^5.0.1" 2092 | stringstream "~0.0.4" 2093 | tough-cookie "~2.3.0" 2094 | tunnel-agent "^0.6.0" 2095 | uuid "^3.0.0" 2096 | 2097 | resolve@^1.1.6: 2098 | version "1.6.0" 2099 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.6.0.tgz#0fbd21278b27b4004481c395349e7aba60a9ff5c" 2100 | dependencies: 2101 | path-parse "^1.0.5" 2102 | 2103 | right-align@^0.1.1: 2104 | version "0.1.3" 2105 | resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" 2106 | dependencies: 2107 | align-text "^0.1.1" 2108 | 2109 | rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1: 2110 | version "2.6.2" 2111 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" 2112 | dependencies: 2113 | glob "^7.0.5" 2114 | 2115 | rsvp@^3.5.0: 2116 | version "3.6.2" 2117 | resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" 2118 | 2119 | rx@4.1.0: 2120 | version "4.1.0" 2121 | resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" 2122 | 2123 | safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 2124 | version "5.1.1" 2125 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" 2126 | 2127 | samsam@1.1.2: 2128 | version "1.1.2" 2129 | resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" 2130 | 2131 | samsam@~1.1: 2132 | version "1.1.3" 2133 | resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.3.tgz#9f5087419b4d091f232571e7fa52e90b0f552621" 2134 | 2135 | "semver@2 || 3 || 4 || 5", semver@^5.3.0: 2136 | version "5.5.0" 2137 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" 2138 | 2139 | set-blocking@~2.0.0: 2140 | version "2.0.0" 2141 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 2142 | 2143 | set-immediate-shim@^1.0.1: 2144 | version "1.0.1" 2145 | resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" 2146 | 2147 | setprototypeof@1.0.3: 2148 | version "1.0.3" 2149 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" 2150 | 2151 | sexylog@0.0.3: 2152 | version "0.0.3" 2153 | resolved "https://registry.yarnpkg.com/sexylog/-/sexylog-0.0.3.tgz#ae25d1553006addf419ca3f7066b67bcbbf114b5" 2154 | dependencies: 2155 | body-parser "*" 2156 | callsite "*" 2157 | colors "*" 2158 | console.table "*" 2159 | expect.js "*" 2160 | node-uuid "*" 2161 | split "*" 2162 | stack-trace "*" 2163 | underscore "*" 2164 | url "*" 2165 | winston "*" 2166 | 2167 | shelljs@^0.8.1: 2168 | version "0.8.1" 2169 | resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.1.tgz#729e038c413a2254c4078b95ed46e0397154a9f1" 2170 | dependencies: 2171 | glob "^7.0.0" 2172 | interpret "^1.0.0" 2173 | rechoir "^0.6.2" 2174 | 2175 | should-equal@^1.0.0: 2176 | version "1.0.1" 2177 | resolved "http://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz#0b6e9516f2601a9fb0bb2dcc369afa1c7e200af7" 2178 | dependencies: 2179 | should-type "^1.0.0" 2180 | 2181 | should-format@^3.0.1: 2182 | version "3.0.3" 2183 | resolved "https://registry.yarnpkg.com/should-format/-/should-format-3.0.3.tgz#9bfc8f74fa39205c53d38c34d717303e277124f1" 2184 | dependencies: 2185 | should-type "^1.3.0" 2186 | should-type-adaptors "^1.0.1" 2187 | 2188 | should-type-adaptors@^1.0.0, should-type-adaptors@^1.0.1: 2189 | version "1.1.0" 2190 | resolved "https://registry.yarnpkg.com/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz#401e7f33b5533033944d5cd8bf2b65027792e27a" 2191 | dependencies: 2192 | should-type "^1.3.0" 2193 | should-util "^1.0.0" 2194 | 2195 | should-type@^1.0.0, should-type@^1.3.0, should-type@^1.4.0: 2196 | version "1.4.0" 2197 | resolved "https://registry.yarnpkg.com/should-type/-/should-type-1.4.0.tgz#0756d8ce846dfd09843a6947719dfa0d4cff5cf3" 2198 | 2199 | should-util@^1.0.0: 2200 | version "1.0.0" 2201 | resolved "https://registry.yarnpkg.com/should-util/-/should-util-1.0.0.tgz#c98cda374aa6b190df8ba87c9889c2b4db620063" 2202 | 2203 | should@11.1.0: 2204 | version "11.1.0" 2205 | resolved "https://registry.yarnpkg.com/should/-/should-11.1.0.tgz#1d2ee7d3b150e965611ebe37be7dcf0fe2075a8e" 2206 | dependencies: 2207 | should-equal "^1.0.0" 2208 | should-format "^3.0.1" 2209 | should-type "^1.4.0" 2210 | should-type-adaptors "^1.0.0" 2211 | should-util "^1.0.0" 2212 | 2213 | sigmund@~1.0.0: 2214 | version "1.0.1" 2215 | resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" 2216 | 2217 | signal-exit@^3.0.0: 2218 | version "3.0.2" 2219 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 2220 | 2221 | sinon@1.17.5: 2222 | version "1.17.5" 2223 | resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.5.tgz#1038cba830e37012e99a64837ecd3b67200c058c" 2224 | dependencies: 2225 | formatio "1.1.1" 2226 | lolex "1.3.2" 2227 | samsam "1.1.2" 2228 | util ">=0.10.3 <1" 2229 | 2230 | slash@^1.0.0: 2231 | version "1.0.0" 2232 | resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" 2233 | 2234 | sntp@1.x.x: 2235 | version "1.0.9" 2236 | resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" 2237 | dependencies: 2238 | hoek "2.x.x" 2239 | 2240 | source-map-support@^0.4.15: 2241 | version "0.4.18" 2242 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" 2243 | dependencies: 2244 | source-map "^0.5.6" 2245 | 2246 | source-map-support@^0.5.3: 2247 | version "0.5.4" 2248 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.4.tgz#54456efa89caa9270af7cd624cc2f123e51fbae8" 2249 | dependencies: 2250 | source-map "^0.6.0" 2251 | 2252 | source-map@^0.4.4: 2253 | version "0.4.4" 2254 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" 2255 | dependencies: 2256 | amdefine ">=0.0.4" 2257 | 2258 | source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: 2259 | version "0.5.7" 2260 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 2261 | 2262 | source-map@^0.6.0: 2263 | version "0.6.1" 2264 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 2265 | 2266 | spdx-correct@^3.0.0: 2267 | version "3.0.0" 2268 | resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" 2269 | dependencies: 2270 | spdx-expression-parse "^3.0.0" 2271 | spdx-license-ids "^3.0.0" 2272 | 2273 | spdx-exceptions@^2.1.0: 2274 | version "2.1.0" 2275 | resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" 2276 | 2277 | spdx-expression-parse@^3.0.0: 2278 | version "3.0.0" 2279 | resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" 2280 | dependencies: 2281 | spdx-exceptions "^2.1.0" 2282 | spdx-license-ids "^3.0.0" 2283 | 2284 | spdx-license-ids@^3.0.0: 2285 | version "3.0.0" 2286 | resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" 2287 | 2288 | split@*: 2289 | version "1.0.1" 2290 | resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" 2291 | dependencies: 2292 | through "2" 2293 | 2294 | split@1.0.0: 2295 | version "1.0.0" 2296 | resolved "https://registry.yarnpkg.com/split/-/split-1.0.0.tgz#c4395ce683abcd254bc28fe1dabb6e5c27dcffae" 2297 | dependencies: 2298 | through "2" 2299 | 2300 | sshpk@^1.7.0: 2301 | version "1.14.1" 2302 | resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.1.tgz#130f5975eddad963f1d56f92b9ac6c51fa9f83eb" 2303 | dependencies: 2304 | asn1 "~0.2.3" 2305 | assert-plus "^1.0.0" 2306 | dashdash "^1.12.0" 2307 | getpass "^0.1.1" 2308 | optionalDependencies: 2309 | bcrypt-pbkdf "^1.0.0" 2310 | ecc-jsbn "~0.1.1" 2311 | jsbn "~0.1.0" 2312 | tweetnacl "~0.14.0" 2313 | 2314 | stack-trace@*, stack-trace@0.0.10, stack-trace@0.0.x: 2315 | version "0.0.10" 2316 | resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" 2317 | 2318 | "statuses@>= 1.3.1 < 2": 2319 | version "1.4.0" 2320 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" 2321 | 2322 | string-format@0.5.0: 2323 | version "0.5.0" 2324 | resolved "https://registry.yarnpkg.com/string-format/-/string-format-0.5.0.tgz#bfc4a69a250f17f273d97336797daf5dca6ecf30" 2325 | 2326 | string-width@^1.0.1, string-width@^1.0.2: 2327 | version "1.0.2" 2328 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 2329 | dependencies: 2330 | code-point-at "^1.0.0" 2331 | is-fullwidth-code-point "^1.0.0" 2332 | strip-ansi "^3.0.0" 2333 | 2334 | string_decoder@~1.0.3: 2335 | version "1.0.3" 2336 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" 2337 | dependencies: 2338 | safe-buffer "~5.1.0" 2339 | 2340 | stringstream@~0.0.4: 2341 | version "0.0.5" 2342 | resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" 2343 | 2344 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: 2345 | version "3.0.1" 2346 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 2347 | dependencies: 2348 | ansi-regex "^2.0.0" 2349 | 2350 | strip-bom@^2.0.0: 2351 | version "2.0.0" 2352 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" 2353 | dependencies: 2354 | is-utf8 "^0.2.0" 2355 | 2356 | strip-indent@^1.0.1: 2357 | version "1.0.1" 2358 | resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" 2359 | dependencies: 2360 | get-stdin "^4.0.1" 2361 | 2362 | strip-json-comments@~2.0.1: 2363 | version "2.0.1" 2364 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 2365 | 2366 | supports-color@1.2.0: 2367 | version "1.2.0" 2368 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" 2369 | 2370 | supports-color@4.4.0: 2371 | version "4.4.0" 2372 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" 2373 | dependencies: 2374 | has-flag "^2.0.0" 2375 | 2376 | supports-color@^2.0.0: 2377 | version "2.0.0" 2378 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 2379 | 2380 | supports-color@^5.3.0: 2381 | version "5.3.0" 2382 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" 2383 | dependencies: 2384 | has-flag "^3.0.0" 2385 | 2386 | tar-pack@^3.4.0: 2387 | version "3.4.1" 2388 | resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" 2389 | dependencies: 2390 | debug "^2.2.0" 2391 | fstream "^1.0.10" 2392 | fstream-ignore "^1.0.5" 2393 | once "^1.3.3" 2394 | readable-stream "^2.1.4" 2395 | rimraf "^2.5.1" 2396 | tar "^2.2.1" 2397 | uid-number "^0.0.6" 2398 | 2399 | tar@^2.2.1: 2400 | version "2.2.1" 2401 | resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" 2402 | dependencies: 2403 | block-stream "*" 2404 | fstream "^1.0.2" 2405 | inherits "2" 2406 | 2407 | through@2: 2408 | version "2.3.8" 2409 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 2410 | 2411 | to-fast-properties@^1.0.3: 2412 | version "1.0.3" 2413 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" 2414 | 2415 | to-iso-string@0.0.2: 2416 | version "0.0.2" 2417 | resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" 2418 | 2419 | topo@2.x.x: 2420 | version "2.0.2" 2421 | resolved "https://registry.yarnpkg.com/topo/-/topo-2.0.2.tgz#cd5615752539057c0dc0491a621c3bc6fbe1d182" 2422 | dependencies: 2423 | hoek "4.x.x" 2424 | 2425 | tough-cookie@~2.3.0: 2426 | version "2.3.4" 2427 | resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" 2428 | dependencies: 2429 | punycode "^1.4.1" 2430 | 2431 | trim-newlines@^1.0.0: 2432 | version "1.0.0" 2433 | resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" 2434 | 2435 | trim-right@^1.0.1: 2436 | version "1.0.1" 2437 | resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" 2438 | 2439 | ts-node@^5.0.1: 2440 | version "5.0.1" 2441 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-5.0.1.tgz#78e5d1cb3f704de1b641e43b76be2d4094f06f81" 2442 | dependencies: 2443 | arrify "^1.0.0" 2444 | chalk "^2.3.0" 2445 | diff "^3.1.0" 2446 | make-error "^1.1.1" 2447 | minimist "^1.2.0" 2448 | mkdirp "^0.5.1" 2449 | source-map-support "^0.5.3" 2450 | yn "^2.0.0" 2451 | 2452 | tunnel-agent@^0.6.0: 2453 | version "0.6.0" 2454 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 2455 | dependencies: 2456 | safe-buffer "^5.0.1" 2457 | 2458 | tweetnacl@^0.14.3, tweetnacl@~0.14.0: 2459 | version "0.14.5" 2460 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" 2461 | 2462 | type-is@~1.6.15: 2463 | version "1.6.16" 2464 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" 2465 | dependencies: 2466 | media-typer "0.3.0" 2467 | mime-types "~2.1.18" 2468 | 2469 | typedoc-default-themes@^0.5.0: 2470 | version "0.5.0" 2471 | resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz#6dc2433e78ed8bea8e887a3acde2f31785bd6227" 2472 | 2473 | typedoc@^0.11.1: 2474 | version "0.11.1" 2475 | resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.11.1.tgz#9f033887fd2218c769e1045feb88a1efed9f12c9" 2476 | dependencies: 2477 | "@types/fs-extra" "5.0.1" 2478 | "@types/handlebars" "4.0.36" 2479 | "@types/highlight.js" "9.12.2" 2480 | "@types/lodash" "4.14.104" 2481 | "@types/marked" "0.3.0" 2482 | "@types/minimatch" "3.0.3" 2483 | "@types/shelljs" "0.7.8" 2484 | fs-extra "^5.0.0" 2485 | handlebars "^4.0.6" 2486 | highlight.js "^9.0.0" 2487 | lodash "^4.17.5" 2488 | marked "^0.3.17" 2489 | minimatch "^3.0.0" 2490 | progress "^2.0.0" 2491 | shelljs "^0.8.1" 2492 | typedoc-default-themes "^0.5.0" 2493 | typescript "2.7.2" 2494 | 2495 | typescript@2.7.2, typescript@^2.7.2: 2496 | version "2.7.2" 2497 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836" 2498 | 2499 | uglify-js@^2.6: 2500 | version "2.8.29" 2501 | resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" 2502 | dependencies: 2503 | source-map "~0.5.1" 2504 | yargs "~3.10.0" 2505 | optionalDependencies: 2506 | uglify-to-browserify "~1.0.0" 2507 | 2508 | uglify-to-browserify@~1.0.0: 2509 | version "1.0.2" 2510 | resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" 2511 | 2512 | uid-number@^0.0.6: 2513 | version "0.0.6" 2514 | resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" 2515 | 2516 | underscore@*, underscore@1.8.3: 2517 | version "1.8.3" 2518 | resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" 2519 | 2520 | universalify@^0.1.0: 2521 | version "0.1.1" 2522 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" 2523 | 2524 | unpipe@1.0.0: 2525 | version "1.0.0" 2526 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 2527 | 2528 | url-template@2.0.8: 2529 | version "2.0.8" 2530 | resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" 2531 | 2532 | url@*, url@0.11.0: 2533 | version "0.11.0" 2534 | resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" 2535 | dependencies: 2536 | punycode "1.3.2" 2537 | querystring "0.2.0" 2538 | 2539 | user-home@^1.1.1: 2540 | version "1.1.1" 2541 | resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" 2542 | 2543 | util-deprecate@~1.0.1: 2544 | version "1.0.2" 2545 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 2546 | 2547 | "util@>=0.10.3 <1": 2548 | version "0.10.3" 2549 | resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" 2550 | dependencies: 2551 | inherits "2.0.1" 2552 | 2553 | uuid@^3.0.0, uuid@^3.0.1: 2554 | version "3.2.1" 2555 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" 2556 | 2557 | v8flags@^2.1.1: 2558 | version "2.1.1" 2559 | resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" 2560 | dependencies: 2561 | user-home "^1.1.1" 2562 | 2563 | validate-npm-package-license@^3.0.1: 2564 | version "3.0.3" 2565 | resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338" 2566 | dependencies: 2567 | spdx-correct "^3.0.0" 2568 | spdx-expression-parse "^3.0.0" 2569 | 2570 | vary@^1: 2571 | version "1.1.2" 2572 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 2573 | 2574 | verror@1.10.0: 2575 | version "1.10.0" 2576 | resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" 2577 | dependencies: 2578 | assert-plus "^1.0.0" 2579 | core-util-is "1.0.2" 2580 | extsprintf "^1.2.0" 2581 | 2582 | wcwidth@>=1.0.1: 2583 | version "1.0.1" 2584 | resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" 2585 | dependencies: 2586 | defaults "^1.0.3" 2587 | 2588 | wide-align@^1.1.0: 2589 | version "1.1.2" 2590 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" 2591 | dependencies: 2592 | string-width "^1.0.2" 2593 | 2594 | window-size@0.1.0: 2595 | version "0.1.0" 2596 | resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" 2597 | 2598 | winston@*: 2599 | version "2.4.1" 2600 | resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.1.tgz#a3a9265105564263c6785b4583b8c8aca26fded6" 2601 | dependencies: 2602 | async "~1.0.0" 2603 | colors "1.0.x" 2604 | cycle "1.0.x" 2605 | eyes "0.1.x" 2606 | isstream "0.1.x" 2607 | stack-trace "0.0.x" 2608 | 2609 | wordwrap@0.0.2: 2610 | version "0.0.2" 2611 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" 2612 | 2613 | wordwrap@~0.0.2: 2614 | version "0.0.3" 2615 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" 2616 | 2617 | wrappy@1: 2618 | version "1.0.2" 2619 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 2620 | 2621 | xunit-file@^1.0.0: 2622 | version "1.0.0" 2623 | resolved "https://registry.yarnpkg.com/xunit-file/-/xunit-file-1.0.0.tgz#6cb35a024ee94b49b2507ee3878968c6baaec398" 2624 | dependencies: 2625 | dateformat "^1.0.12" 2626 | mkdirp "^0.5.1" 2627 | 2628 | yargs@~3.10.0: 2629 | version "3.10.0" 2630 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" 2631 | dependencies: 2632 | camelcase "^1.0.2" 2633 | cliui "^2.1.0" 2634 | decamelize "^1.0.0" 2635 | window-size "0.1.0" 2636 | 2637 | yn@^2.0.0: 2638 | version "2.0.0" 2639 | resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" 2640 | -------------------------------------------------------------------------------- /protocol/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muoncore/stack-event/aad6dca346984f6014b8e2e028c48b87897094c1/protocol/.empty --------------------------------------------------------------------------------