diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..001cb6f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,185 @@
+
+# Created by https://www.gitignore.io/api/osx,linux,webstorm,sublimetext,node
+
+### OSX ###
+*.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+# Thumbnails
+._*
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+
+### Linux ###
+*~
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+
+### WebStorm ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff:
+.idea/workspace.xml
+.idea/tasks.xml
+
+# Sensitive or high-churn files:
+.idea/dataSources/
+.idea/dataSources.ids
+.idea/dataSources.xml
+.idea/dataSources.local.xml
+.idea/sqlDataSources.xml
+.idea/dynamic.xml
+.idea/uiDesigner.xml
+
+# Gradle:
+.idea/gradle.xml
+.idea/libraries
+
+# Mongo Explorer plugin:
+.idea/mongoSettings.xml
+
+## File-based project format:
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+### WebStorm Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+
+### SublimeText ###
+# cache files for sublime text
+*.tmlanguage.cache
+*.tmPreferences.cache
+*.stTheme.cache
+
+# workspace files are user-specific
+*.sublime-workspace
+
+# project files should be checked into the repository, unless a significant
+# proportion of contributors will probably not be using SublimeText
+# *.sublime-project
+
+# sftp configuration file
+sftp-config.json
+
+# Package control specific files
+Package Control.last-run
+Package Control.ca-list
+Package Control.ca-bundle
+Package Control.system-ca-bundle
+Package Control.cache/
+Package Control.ca-certs/
+Package Control.merged-ca-bundle
+Package Control.user-ca-bundle
+oscrypto-ca-bundle.crt
+bh_unicode_properties.cache
+
+# Sublime-github package stores a github token in this file
+# https://packagecontrol.io/packages/sublime-github
+GitHub.sublime-settings
+
+
+### Node ###
+# Logs
+logs
+*.log
+npm-debug.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (http://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules
+jspm_packages
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# Custom
+.idea
+deployer.test.js
+
+
+# End of https://www.gitignore.io/api/osx,linux,webstorm,sublimetext,node
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..7769c1f
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,14 @@
+{
+ // 使用 IntelliSense 了解相关属性。
+ // 悬停以查看现有属性的描述。
+ // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "启动程序",
+ "program": "${workspaceFolder}\\deployer.test"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..9cecc1d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ {one line to give the program's name and a brief idea of what it does.}
+ Copyright (C) {year} {name of author}
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ {project} Copyright (C) {year} {fullname}
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a821305
--- /dev/null
+++ b/README.md
@@ -0,0 +1,94 @@
+# huaweicloud-obs-sync
+
+同步本地文件目录到华为云OBS文件夹。
+
+## 特性说明
+
+1. 支持增量同步本地文件目录到华为云OBS文件夹
+1. 支持设置是否同步删除OBS文件和目录
+1. 支持指定OBS同步目录
+1. 支持设置本地过滤文件和OBS过滤文件
+
+## 安装说明
+
+``` bash
+npm install huaweicloud-obs-sync --save
+```
+
+## 使用说明
+
+``` javascript
+var obsSync = require('huaweicloud-obs-sync');
+
+// 同步整个本地目录
+obsSync.syncFolderToOBS({
+ server : "https://obs.cn-north-1.myhwclouds.com",
+ bucket: "obs-2f97",
+ accessKeyId: "R7DYQD3DQRRLTDWYtE3S",
+ secretAccessKey: "TERHf0NGpDrbhsbc1h3xymB9w22wK8lLgOFkgjCB2",
+ localDir: "D:\\public",
+ localFilesIgnorePattern: "^\\..*",
+ remoteDir: "/",
+ syncDeletedFiles: "yes",
+ syncDeletedFilesIgnorePattern: "^\\..*",
+ })
+
+//同步本地目录下的单个文件
+obsSync.syncFileToOBS("D:\\public\\images\\avast.png", {
+ server : "https://obs.cn-north-1.myhwclouds.com",
+ bucket: "obs-2f97",
+ accessKeyId: "R7DYQD3DQRRLTDWYtE3S",
+ secretAccessKey: "TERHf0NGpDrbhsbc1h3xymB9w22wK8lLgOFkgjCB2"
+ localFileName: "D:\\public\\images\\avast.png",
+ remoteFileName: "images/avast.png"
+ })
+```
+
+### syncFolderToOBS(options)
+
+同步整个本地目录到OBS
+
+| 名称 | 必选 | 默认值 | 描述 |
+| -- | -- | -- |-- |
+| server | 必填 | null | OBS服务器地址,以`https://`开头,不包含桶名称,比如`https://obs.cn-north-1.myhwclouds.com` |
+| bucket |必填 | null | OBS桶名称 |
+| accessKeyId | 必填 | null | 访问OBS的accessKeyId |
+| secretAccessKey | 必填 | null | 访问OBS的secretAccessKey |
+| localDir | 必填 | null | 本地同步目录的绝对路径 |
+| localFilesIgnorePattern | 可选 | "^\\..*" | 本地忽略文件的正则表达式,该正则表达式会应用到文件相对于`localDir`的相对路径,路径分隔符为`/` |
+| remoteDir | 可选 | / | 同步到远端的目录,路径分隔符为`/` |
+| syncDeletedFiles | 可选 | yes | `yes`或者`no`, 如果是`yes`,则本地文件删除后,OBS中的文件也会对应删除,但是`syncDeletedFilesIgnorePattern`匹配上的文件除外 |
+| syncDeletedFilesIgnorePattern | 可选 | "^\\..*" | 远端忽略文件的正则表达式,该正则表达式会应用到文件相对于`remoteDir`的相对路径,路径分隔符为`/` |
+
+### syncFileToOBS(options)
+
+同步本地目录的单个文件到OBS目录
+
+| 名称 | 必选 | 默认值 | 描述 |
+| -- | -- | -- |-- |
+| server | 必填 | null | OBS服务器地址,以`https://`开头,不包含桶名称,比如`https://obs.cn-north-1.myhwclouds.com` |
+| bucket |必填 | null | OBS桶名称 |
+| accessKeyId | 必填 | null | 访问OBS的accessKeyId |
+| secretAccessKey | 必填 | null | 访问OBS的secretAccessKey |
+| localFileName | 必填 | null | 本地文件的绝对路径 |
+| remoteFileName | 必填 | null | OBS中的全路径,路径分隔符为`/` |
+
+## 应用场景
+
+### 1. Hexo插件
+
+使用Hexo将文件发布到OBS,然后运用OBS的静态网站功能对外提供服务,参考:
+
+### 2. VSCode插件
+
+使用VSCode编辑博客,粘贴图片自动将文件上传至OBS并自动在博客中插入图片地址,参考:
+
+## 3. 定期备份
+
+定期备份本地目录到OBS
+
+## 相关资料
+
+华为云OBS的SDK地址: https://developer.huaweicloud.com/sdk?OBS
+
+Hexo插件中心地址: https://hexo.io/plugins/
\ No newline at end of file
diff --git a/lib/obs-sdk-3.0.0/enums.js b/lib/obs-sdk-3.0.0/enums.js
new file mode 100644
index 0000000..ed46c18
--- /dev/null
+++ b/lib/obs-sdk-3.0.0/enums.js
@@ -0,0 +1,44 @@
+'use strict';
+
+exports.AclPrivate = 'private';
+exports.AclPublicRead = 'public-read';
+exports.AclPublicReadWrite = 'public-read-write';
+exports.AclPublicReadDelivered = 'public-read-delivered';
+exports.AclPublicReadWriteDelivered = 'public-read-write-delivered';
+exports.AclAuthenticatedRead = 'authenticated-read';
+exports.AclBucketOwnerRead = 'bucket-owner-read';
+exports.AclBucketOwnerFullControl = 'bucket-owner-full-control';
+exports.AclLogDeliveryWrite = 'log-delivery-write';
+
+exports.StorageClassStandard = 'STANDARD';
+exports.StorageClassWarm = 'WARM';
+exports.StorageClassCold = 'COLD';
+
+exports.PermissionRead = 'READ';
+exports.PermissionWrite = 'WRITE';
+exports.PermissionReadAcp = 'READ_ACP';
+exports.PermissionWriteAcp = 'WRITE_ACP';
+exports.PermissionFullControl = 'FULL_CONTROL';
+
+exports.GroupAllUsers = 'AllUsers';
+exports.GroupAuthenticatedUsers = 'AuthenticatedUsers';
+exports.GroupLogDelivery = 'LogDelivery';
+
+exports.RestoreTierExpedited = 'Expedited';
+exports.RestoreTierStandard = 'Standard';
+exports.RestoreTierBulk = 'Bulk';
+
+exports.GranteeGroup = 'Group';
+exports.GranteeUser = 'CanonicalUser';
+
+exports.CopyMetadata = 'COPY';
+exports.ReplaceMetadata = 'REPLACE';
+
+exports.EventObjectCreatedAll = 'ObjectCreated:*';
+exports.EventObjectCreatedPut = 'ObjectCreated:Put';
+exports.EventObjectCreatedPost = 'ObjectCreated:Post';
+exports.EventObjectCreatedCopy = 'ObjectCreated:Copy';
+exports.EventObjectCreatedCompleteMultipartUpload = 'ObjectCreated:CompleteMultipartUpload';
+exports.EventObjectRemovedAll = 'ObjectRemoved:*';
+exports.EventObjectRemovedDelete = 'ObjectRemoved:Delete';
+exports.EventObjectRemovedDeleteMarkerCreated = 'ObjectRemoved:DeleteMarkerCreated';
diff --git a/lib/obs-sdk-3.0.0/log.js b/lib/obs-sdk-3.0.0/log.js
new file mode 100644
index 0000000..13a61dc
--- /dev/null
+++ b/lib/obs-sdk-3.0.0/log.js
@@ -0,0 +1,135 @@
+
+'use strict';
+
+const os = require('os');
+const fs = require('fs');
+const process = require('process');
+const path = require('path');
+const log4js = require('log4js');
+
+function checkAndCreateDir(dir,path){
+ if(!fs.existsSync(dir)){
+ let rout = path.dirname(dir);
+ if(!fs.existsSync(rout)){
+ checkAndCreateDir(rout);
+ }
+ fs.mkdirSync(dir);
+ }
+}
+
+function LogUtil(){
+ this.loggerInf = null;
+ this.loggerRun = null;
+ this.consoleLog = null;
+}
+
+LogUtil.prototype.initLog = function(filename, maxLogSize, backups, level, logToConsole, name){
+ process.on('uncaughtException', function (err) {
+ console.log(err);
+ });
+ var dir = path.dirname(filename);
+ checkAndCreateDir(dir,path);
+ var ext = path.extname(filename);
+ var file = path.basename(filename, ext);
+ if(!ext){
+ ext = '.log';
+ }
+
+ level = level === undefined ? 'info' : String(level);
+ maxLogSize = maxLogSize === undefined ? 102400 : parseInt(maxLogSize);
+ backups = backups === undefined ? 10 : parseInt(backups);
+
+ var fileInterface = path.join(dir, file + ext);
+ var layoutFormat = '%d{yyyy/MM/dd hh:mm:ss SSS}|%c|%-5p|%m';
+ var cateInterface = 'sdk-file';
+ var cateConsole = 'sdk-console';
+ if(name){
+ cateInterface += ':' + String(name);
+ cateConsole += ':' + String(name);
+ }
+
+ if(log4js.appenders.file){
+ log4js.addAppender(log4js.appenders.file(
+ fileInterface,
+ log4js.layouts.patternLayout(layoutFormat),
+ maxLogSize,
+ backups), cateInterface);
+ }else{
+ log4js.configure({
+ appenders:[
+ {
+ type:'file',
+ category:cateInterface,
+ filename:fileInterface,
+ maxLogSize:maxLogSize,
+ backups:backups,
+ layout : {
+ type:'pattern',
+ pattern: layoutFormat
+ }
+ },
+ ]
+ });
+ }
+
+ this.loggerInf = log4js.getLogger(cateInterface);
+ this.loggerInf.setLevel(level.toLowerCase());
+ if(logToConsole){
+ if(!log4js.appenders.console){
+ log4js.loadAppender('console');
+ }
+ log4js.addAppender(log4js.appenders.console(log4js.layouts.patternLayout(layoutFormat)), cateConsole);
+ this.consoleLog = log4js.getLogger(cateConsole);
+ this.consoleLog.setLevel(level.toLowerCase());
+ }
+};
+
+LogUtil.prototype._doLog = function(level, form){
+ if(level.toLowerCase() === 'debug'){
+ if(this.loggerInf){
+ this.loggerInf.debug(form);
+ }
+ if(this.consoleLog){
+ this.consoleLog.debug(form);
+ }
+ }else if(level.toLowerCase() === 'info'){
+ if(this.loggerInf){
+ this.loggerInf.info(form);
+ }
+ if(this.consoleLog){
+ this.consoleLog.info(form);
+ }
+ }else if(level.toLowerCase() === 'warn'){
+ if(this.loggerInf){
+ this.loggerInf.warn(form);
+ }
+ if(this.consoleLog){
+ this.consoleLog.warn(form);
+ }
+ }else if(level.toLowerCase() === 'error'){
+ if(this.loggerInf){
+ this.loggerInf.error(form);
+ }
+ if(this.consoleLog){
+ this.consoleLog.error(form);
+ }
+ }
+};
+
+LogUtil.prototype.isLevelEnabled = function(level){
+ return (this.loggerInf && this.loggerInf.isLevelEnabled(level)) || (this.consoleLog && this.consoleLog.isLevelEnabled(level));
+};
+
+LogUtil.prototype.runLog = function(level, methodName, msg){
+ if(!this.loggerInf && !this.consoleLog){
+ return;
+ }
+ var form = methodName + '|' + msg;
+ this._doLog(level, form);
+};
+
+
+module.exports = LogUtil;
+
+
+
diff --git a/lib/obs-sdk-3.0.0/obs.js b/lib/obs-sdk-3.0.0/obs.js
new file mode 100644
index 0000000..3ffd7b4
--- /dev/null
+++ b/lib/obs-sdk-3.0.0/obs.js
@@ -0,0 +1,1239 @@
+
+'use strict';
+
+const Utils = require('./utils');
+const LogUtil = require('./log');
+const enums = require('./enums');
+
+function ObsClient(param){
+ this.factory(param);
+}
+
+function capitalize(key){
+ return key.slice(0,1).toUpperCase() + key.slice(1);
+}
+
+const methods = [
+ 'createBucket',
+ 'listBuckets',
+ 'headBucket',
+ 'getBucketMetadata',
+ 'deleteBucket',
+ 'setBucketQuota',
+ 'getBucketQuota',
+ 'getBucketStorageInfo',
+ 'setBucketPolicy',
+ 'getBucketPolicy',
+ 'deleteBucketPolicy',
+ 'setBucketVersioningConfiguration',
+ 'getBucketVersioningConfiguration',
+ 'getBucketLocation',
+ 'listVersions',
+ 'listObjects',
+ 'setBucketLifecycleConfiguration',
+ 'getBucketLifecycleConfiguration',
+ 'deleteBucketLifecycleConfiguration',
+ 'setBucketAcl',
+ 'getBucketAcl',
+ 'setBucketLoggingConfiguration',
+ 'getBucketLoggingConfiguration',
+ 'setBucketWebsiteConfiguration',
+ 'getBucketWebsiteConfiguration',
+ 'deleteBucketWebsiteConfiguration',
+ 'setBucketNotification',
+ 'getBucketNotification',
+ 'setBucketTagging',
+ 'deleteBucketTagging',
+ 'getBucketTagging',
+ 'setBucketReplication',
+ 'deleteBucketReplication',
+ 'getBucketReplication',
+ 'getObject',
+ 'getObjectMetadata',
+ 'setObjectAcl',
+ 'getObjectAcl',
+ 'deleteObject',
+ 'deleteObjects',
+ 'listMultipartUploads',
+ 'listParts',
+ 'abortMultipartUpload',
+ 'completeMultipartUpload',
+ 'setBucketCors',
+ 'getBucketCors',
+ 'deleteBucketCors',
+ 'optionsBucket',
+ 'optionsObject',
+ 'setBucketStoragePolicy',
+ 'getBucketStoragePolicy'
+];
+
+for(let i=0;i 0){
+ val = this.util.encodeURIWithSafe(val.slice(0, index)) + val.slice(index);
+ }else{
+ param[key] = this.util.encodeURIWithSafe(val);
+ }
+ }
+ this.exec('CopyObject', param, callback);
+};
+
+ObsClient.prototype.copyPart = function(param, callback){
+ let key = 'CopySource';
+ if(key in param){
+ let val = param[key];
+ let index = val.lastIndexOf('?versionId=');
+ if(index > 0){
+ val = this.util.encodeURIWithSafe(val.slice(0, index)) + val.slice(index);
+ }else{
+ param[key] = this.util.encodeURIWithSafe(val);
+ }
+ }
+ this.exec('CopyPart', param, callback);
+};
+
+ObsClient.prototype.restoreObject = function(param, callback){
+ this.exec('RestoreObject', param, function(err, result){
+ if(!err && result.InterfaceResult && result.CommonMsg.Status < 300){
+ result.InterfaceResult.RestoreStatus = result.CommonMsg.Status === 200 ? 'AVALIABLE' : 'INPROGRESS';
+ }
+ callback(err, result);
+ });
+};
+
+ObsClient.prototype.initiateMultipartUpload = function(param, callback){
+ if(!('ContentType' in param) && 'Key' in param){
+ param.ContentType = this.util.mimeTypes[param.Key.substring(param.Key.lastIndexOf('.') + 1)];
+ }
+ this.exec('InitiateMultipartUpload', param, callback);
+};
+
+
+ObsClient.prototype.uploadPart = function(param, callback){
+ if(('Body' in param) && ('SourceFile' in param)){
+ let err = 'the input body and sourcefile exist at same time,please specify one of eigther a string or file to be send!';
+ if(this.log.isLevelEnabled('error')){
+ this.log.runLog('error', 'UploadPart', err);
+ }
+ callback(err, null);
+ return;
+ }
+ this.exec('UploadPart', param, callback);
+};
+
+
+ObsClient.prototype.uploadFile = function(param, callback){
+ param = param || {};
+ var _log = this.log;
+ var obsClient = this;
+ var funcName = 'uploadFile';
+ var start = new Date().getTime();
+ callback = callback || function(){};
+ var _callback = function(code, message, result){
+ if(_log.isLevelEnabled('info')){
+ _log.runLog('info', funcName, 'ObsClient cost ' + (new Date().getTime()-start) + ' ms');
+ }
+ if(typeof code === 'string'){
+ if(message){
+ code += ':' + String(message);
+ }
+ callback(code, result);
+ }else{
+ callback(code ? (code.CommonMsg.Code + ':' + code.CommonMsg.Message) : null, result);
+ }
+ };
+
+ if(_log.isLevelEnabled('info')){
+ _log.runLog('info', funcName, 'enter ' + funcName + '...' );
+ }
+
+ var bucket = param.Bucket;
+ if(!bucket){
+ _callback('InvalidArgument','Bucket is a required element!');
+ return;
+ }
+ bucket = String(bucket);
+
+ var key = param.Key;
+ if(!key){
+ _callback('InvalidArgument', 'Key is a required element!');
+ return;
+ }
+ key = String(key);
+
+ var uploadFile = param.UploadFile;
+ if(!uploadFile){
+ _callback('InvalidArgument', 'UploadFile is a required element!');
+ return;
+ }
+ var fs = require('fs');
+ uploadFile = String(uploadFile);
+
+ if(!fs.existsSync(uploadFile)){
+ _callback('InvalidArgument', 'UploadFile does not exist!');
+ return;
+ }
+ var fstat = fs.statSync(uploadFile);
+ if(!fstat.isFile()){
+ _callback('InvalidArgument', 'UploadFile is not a file!');
+ return;
+ }
+
+ var fileSize = fstat.size;
+
+ var enableCheckpoint = Boolean(param.EnableCheckpoint);
+ var checkpointFile = null;
+ var enableCheckSum = false;
+
+ var taskNum = parseInt(param.TaskNum) || 20;
+
+ if(enableCheckpoint){
+ checkpointFile = param.CheckpointFile;
+ checkpointFile = (checkpointFile && checkpointFile !== '') ? String(checkpointFile) : uploadFile + '.upload_record';
+ let pathLib = require('path');
+ let fileDir = pathLib.dirname(checkpointFile);
+ if(!fs.existsSync(fileDir)){
+ let mkdirsSync = function(dirname){
+ if(fs.existsSync(dirname)){
+ return true;
+ }else{
+ if(mkdirsSync(pathLib.dirname(dirname))){
+ fs.mkdirSync(dirname);
+ return true;
+ }
+ }
+ };
+ mkdirsSync(fileDir);
+ }
+ enableCheckSum = Boolean(param.EnableCheckSum);
+ }
+ if(_log.isLevelEnabled('debug')){
+ _log.runLog('debug', funcName, 'Begin to uploadFile to OBS from file:' + uploadFile);
+ }
+
+ var events = require('events');
+ var eventEmitter = new events.EventEmitter();
+
+ var calculateUploadCheckpointMD5 = function(uploadCheckpoint){
+ let data = [];
+ data.push(uploadCheckpoint.bucketName);
+ data.push(uploadCheckpoint.objectKey);
+ data.push(uploadCheckpoint.uploadFile);
+ data.push(String(uploadCheckpoint.partSize));
+ data.push(String(uploadCheckpoint.partCount));
+ if(uploadCheckpoint.contentType){
+ data.push(uploadCheckpoint.contentType);
+ }
+ if(uploadCheckpoint.acl){
+ data.push(uploadCheckpoint.acl);
+ }
+ if(uploadCheckpoint.websiteRedirectLocation){
+ data.push(uploadCheckpoint.websiteRedirectLocation);
+ }
+ if(uploadCheckpoint.sseKms){
+ data.push(uploadCheckpoint.sseKms);
+ }
+ if(uploadCheckpoint.sseKmsKey){
+ data.push(uploadCheckpoint.sseKmsKey);
+ }
+ if(uploadCheckpoint.sseC){
+ data.push(uploadCheckpoint.sseC);
+ }
+ if(uploadCheckpoint.sseCKey){
+ data.push(uploadCheckpoint.sseCKey);
+ }
+ if(uploadCheckpoint.metadata){
+ data.push(JSON.stringify(uploadCheckpoint.metadata));
+ }
+ if(uploadCheckpoint.uploadId){
+ data.push(uploadCheckpoint.uploadId);
+ }
+ if(uploadCheckpoint.partsMeta && (uploadCheckpoint.partsMeta instanceof Object)){
+ for(let key in uploadCheckpoint.partsMeta){
+ data.push(String(key));
+ let partMeta = uploadCheckpoint.partsMeta[key];
+ if(partMeta){
+ data.push(String(partMeta.offset));
+ data.push(String(partMeta.partSize));
+ data.push(String(partMeta.isCompleted));
+ data.push(String(partMeta.etag));
+ }
+ }
+ }
+ return obsClient.util.bufMD5(Buffer.from(data.join(''), 'utf8'));
+ };
+
+ var writeCheckpointFileSync = function(checkpointFile, uploadCheckpoint){
+ try{
+ fs.writeFileSync(checkpointFile, JSON.stringify(uploadCheckpoint));
+ return true;
+ }catch(e){
+ _callback('WriteCheckpointFileError', e);
+ if(_log.isLevelEnabled('debug')){
+ _log.runLog('debug', funcName, 'Write checkpoint file failed and abort upload, uploadId ' + uploadCheckpoint.uploadId);
+ }
+ if(uploadCheckpoint.uploadId){
+ obsClient.abortMultipartUpload({
+ Bucket:uploadCheckpoint.bucketName,
+ Key:uploadCheckpoint.objectKey,
+ UploadId:uploadCheckpoint.uploadId,
+ },function(e, r){
+ if(!e && (r.CommonMsg.Status < 300 || r.CommonMsg.Status === 404)){
+ fs.unlink(checkpointFile, function(){});
+ }
+ });
+ }else{
+ fs.unlink(checkpointFile, function(){});
+ }
+ return false;
+ }
+ };
+
+ var abortRequest = function(uploadCheckpoint, checkpointFile, code, message){
+ if(uploadCheckpoint && uploadCheckpoint.uploadId){
+ obsClient.abortMultipartUpload({
+ Bucket:uploadCheckpoint.bucketName,
+ Key:uploadCheckpoint.objectKey,
+ UploadId:uploadCheckpoint.uploadId,
+ },function(e, r){
+ if(!e && (r.CommonMsg.Status < 300 || r.CommonMsg.Status === 404)){
+ if(checkpointFile){
+ fs.unlink(checkpointFile, function(){});
+ }
+ }
+ _callback(code, message);
+ });
+ }else{
+ if(checkpointFile){
+ fs.unlink(checkpointFile, function(){});
+ }
+ _callback(code, message);
+ }
+ };
+
+ var transResultToError = function(result){
+ let ret = [];
+ if(result && result.CommonMsg){
+ ret.push('Status:' + result.CommonMsg.Status);
+ ret.push('Code:' + result.CommonMsg.Code);
+ ret.push('Message:' + result.CommonMsg.Message);
+ }
+ return ret.join(',');
+ };
+
+ eventEmitter.on('start to uploadFile', function(uploadCheckpoint){
+ if(!uploadCheckpoint){
+ uploadCheckpoint = {};
+ }
+ if(!uploadCheckpoint.partsMeta){
+ uploadCheckpoint.partsMeta = {};
+ }
+ var startToUploadFile = function(uploadId){
+ let finishedCount = 0;
+ let hasError = false;
+ let isAbort = false;
+ let completedRequest = function(){
+ if(finishedCount === uploadCheckpoint.partCount){
+ if(!hasError){
+ let parts = [];
+ for(let partNumber in uploadCheckpoint.partsMeta){
+ parts.push({
+ PartNumber : partNumber,
+ ETag : uploadCheckpoint.partsMeta[partNumber].etag
+ });
+ }
+ obsClient.completeMultipartUpload({
+ Bucket: uploadCheckpoint.bucketName,
+ Key : uploadCheckpoint.objectKey,
+ UploadId : uploadId,
+ Parts: parts
+ }, function(err, result){
+ if(err || result.CommonMsg.Status >= 500){
+ if(checkpointFile){
+ _callback('IncompletedUpload', err ? err : transResultToError(result));
+ }else{
+ abortRequest(uploadCheckpoint, checkpointFile, 'UploadFileFailed', err ? err : transResultToError(result));
+ }
+ }else if(result.CommonMsg.Status >= 300 && result.CommonMsg.Status < 500){
+ abortRequest(uploadCheckpoint, checkpointFile, result.CommonMsg.Code, result.CommonMsg.Message);
+ }else{
+ if(checkpointFile){
+ fs.unlink(checkpointFile, function(){});
+ }
+ _callback(null, null, result);
+ }
+ });
+ }else{
+ if(checkpointFile){
+ _callback('IncompletedUpload','UploadFile finished with error, you can retry with the same parameters');
+ }else{
+ abortRequest(uploadCheckpoint, checkpointFile, 'UploadFileFailed', 'UploadFile finished with error!');
+ }
+ }
+ }
+ };
+
+ eventEmitter.on('doUpload', function(currentGroupIndex, groupCount, taskNum){
+ let start = (currentGroupIndex - 1) * taskNum;
+ let end = (currentGroupIndex === groupCount) ? uploadCheckpoint.partCount : currentGroupIndex * taskNum;
+ let finishedCountGroup = 0;
+ while(start= 500){
+ partMeta.isCompleted = false;
+ hasError = true;
+ }else if(result.CommonMsg.Status >= 300 && result.CommonMsg.Status < 500){
+ isAbort = true;
+ abortRequest(uploadCheckpoint, checkpointFile, result.CommonMsg.Code, result.CommonMsg.Message);
+ return;
+ }else{
+ partMeta.etag = result.InterfaceResult.ETag;
+ partMeta.isCompleted = true;
+ }
+ uploadCheckpoint.partsMeta[partNumber] = partMeta;
+ if(_log.isLevelEnabled('debug')){
+ _log.runLog('debug', funcName, 'Part ' + String(partNumber) + ' is finished, uploadId ' + uploadId);
+ }
+ uploadCheckpoint.md5 = calculateUploadCheckpointMD5(uploadCheckpoint);
+ if(checkpointFile && !writeCheckpointFileSync(checkpointFile, uploadCheckpoint)){
+ return;
+ }
+ finishedCount++;
+ finishedCountGroup++;
+ let _taskNum = (currentGroupIndex === groupCount) ? (uploadCheckpoint.partCount - (currentGroupIndex - 1) * taskNum) : taskNum;
+ if(finishedCountGroup === _taskNum && finishedCount < uploadCheckpoint.partCount){
+ eventEmitter.emit('doUpload', currentGroupIndex + 1, groupCount, taskNum);
+ }
+ completedRequest();
+ });
+ }
+ start++;
+ }
+ });
+
+ let groupCount = (uploadCheckpoint.partCount % taskNum === 0) ? (uploadCheckpoint.partCount / taskNum) : (Math.floor(uploadCheckpoint.partCount / taskNum) + 1);
+ eventEmitter.emit('doUpload', 1, groupCount, taskNum);
+ };
+
+ let uploadId = uploadCheckpoint.uploadId;
+ if(!uploadId){
+ let contentType = uploadCheckpoint.contentType ? uploadCheckpoint.contentType : obsClient.util.mimeTypes[key.substring(key.lastIndexOf('.') + 1)];
+
+ if(!contentType){
+ contentType = obsClient.util.mimeTypes[uploadFile.substring(uploadFile.lastIndexOf('.') + 1)];
+ }
+
+ obsClient.initiateMultipartUpload({
+ Bucket : uploadCheckpoint.bucketName,
+ Key : uploadCheckpoint.objectKey,
+ ACL : uploadCheckpoint.acl,
+ Metadata : uploadCheckpoint.metadata,
+ WebsiteRedirectLocation : uploadCheckpoint.websiteRedirectLocation,
+ ContentType : contentType,
+ SseKms : uploadCheckpoint.sseKms,
+ SseKmsKey : uploadCheckpoint.sseKmsKey,
+ SseC : uploadCheckpoint.sseC,
+ SseCKey : uploadCheckpoint.sseCKey
+ }, function(err, result){
+ if(err){
+ if(checkpointFile){
+ fs.unlink(checkpointFile, function(){});
+ }
+ _callback('InitateMultipartUploadFailed',err);
+ return;
+ }
+ if(result.CommonMsg.Status >= 300){
+ if(checkpointFile){
+ fs.unlink(checkpointFile, function(){});
+ }
+ _callback(result);
+ return;
+ }
+
+ uploadId = result.InterfaceResult.UploadId;
+ uploadCheckpoint.uploadId = uploadId;
+ uploadCheckpoint.md5 = calculateUploadCheckpointMD5(uploadCheckpoint);
+ if(_log.isLevelEnabled('debug')){
+ _log.runLog('debug', funcName, 'Claim a new upload id ' + uploadId);
+ }
+ if(checkpointFile && !writeCheckpointFileSync(checkpointFile, uploadCheckpoint)){
+ return;
+ }
+ startToUploadFile(uploadId);
+ });
+ }else{
+ startToUploadFile(uploadId);
+ }
+ });
+
+ var uploadCheckpoint;
+ var partSize = parseInt(param.PartSize);
+ var partCount;
+ if(fileSize === 0){
+ partSize = 0;
+ partCount = 1;
+ }else{
+ partSize = isNaN(partSize) ? 5 * 1024 * 1024 : (partSize < 5 * 1024 * 1024 ? 5 * 1024 * 1024 : (partSize > 5 * 1024 * 1024 * 1024 ? 5 * 1024 * 1024 * 1024 : partSize));
+ partCount = Math.floor(fileSize / partSize);
+ if(fileSize % partSize !== 0){
+ partCount++;
+ }
+ }
+ if(_log.isLevelEnabled('debug')){
+ _log.runLog('debug', funcName, 'Total parts count ' + partCount);
+ }
+ uploadCheckpoint = {bucketName: bucket, objectKey: key, uploadFile : uploadFile, partSize : partSize, partCount : partCount};
+ uploadCheckpoint.contentType = param.ContentType;
+ uploadCheckpoint.acl = param.ACL;
+ uploadCheckpoint.websiteRedirectLocation = param.WebsiteRedirectLocation;
+ uploadCheckpoint.sseKms = param.SseKms;
+ uploadCheckpoint.sseKmsKey = param.SseKmsKey;
+ uploadCheckpoint.sseC = param.sseC;
+ uploadCheckpoint.sseCKey = param.SseCKey;
+ uploadCheckpoint.metadata = param.Metadata;
+ uploadCheckpoint.md5 = calculateUploadCheckpointMD5(uploadCheckpoint);
+ uploadCheckpoint.uploadFileStat = {fileSize : fileSize, lastModified : fstat.mtime.toUTCString()};
+
+ if(checkpointFile){
+ if(!fs.existsSync(checkpointFile)){// call uploadFile first time
+ eventEmitter.on('start to writeFile', function(){
+ fs.writeFile(checkpointFile, JSON.stringify(uploadCheckpoint), function(err){
+ if(err){
+ _callback('WriteCheckpointFileError',err);
+ return;
+ }
+ eventEmitter.emit('start to uploadFile', uploadCheckpoint);
+ });
+ });
+ if(enableCheckSum){
+ obsClient.util.fileMD5(uploadFile, function(err, checkSum){
+ if(err){
+ checkSum = '';
+ }
+ uploadCheckpoint.uploadFileStat.checkSum = checkSum;
+ eventEmitter.emit('start to writeFile');
+ });
+ }else{
+ eventEmitter.emit('start to writeFile');
+ }
+ }else{
+ fs.readFile(checkpointFile, function(err, data){
+ if(err){
+ fs.unlink(checkpointFile, function(){});
+ _callback('ReadCheckpointFileError',err);
+ return;
+ }
+ try{
+ uploadCheckpoint = JSON.parse(data);
+ }catch(e){
+ fs.unlink(checkpointFile, function(){});
+ _callback('ParseCheckpointFileError', e);
+ return;
+ }
+ if(!uploadCheckpoint || uploadCheckpoint.bucketName !== bucket || uploadCheckpoint.objectKey !== key || uploadCheckpoint.uploadFile !== uploadFile ||
+ !uploadCheckpoint.uploadFileStat || uploadCheckpoint.uploadFileStat.fileSize !== fstat.size || uploadCheckpoint.uploadFileStat.lastModified !== fstat.mtime.toUTCString() ||
+ uploadCheckpoint.md5 !== calculateUploadCheckpointMD5(uploadCheckpoint)){
+ abortRequest(uploadCheckpoint, checkpointFile, 'CheckpointFileInvalid', 'CheckpointFile is invalid!');
+ return;
+ }
+
+ if(uploadCheckpoint.uploadFileStat.checkSum){
+ obsClient.util.fileMD5(uploadFile, function(err, checkSum){
+ if(err || checkSum !== uploadCheckpoint.uploadFileStat.checkSum){
+ abortRequest(uploadCheckpoint, checkpointFile, 'CheckpointFileInvalid','CheckpointFile is invalid!');
+ return;
+ }
+ eventEmitter.emit('start to uploadFile', uploadCheckpoint);
+ });
+ }else{
+ eventEmitter.emit('start to uploadFile', uploadCheckpoint);
+ }
+ });
+ }
+ }else{
+ eventEmitter.emit('start to uploadFile', uploadCheckpoint);
+ }
+};
+
+ObsClient.prototype.downloadFile = function(param, callback){
+ param = param || {};
+ var _log = this.log;
+ var obsClient = this;
+ var funcName = 'downloadFile';
+ var start = new Date().getTime();
+ callback = callback || function(){};
+ var _callback = function(code, message, result){
+ if(_log.isLevelEnabled('info')){
+ _log.runLog('info', funcName, 'ObsClient cost ' + (new Date().getTime() - start) + ' ms');
+ }
+ if(typeof code === 'string'){
+ if(message){
+ code += ':' + String(message);
+ }
+ callback(code, result);
+ }else{
+ callback(code ? (code.CommonMsg.Code + ':' + code.CommonMsg.Message) : null, result);
+ }
+ };
+
+ if(_log.isLevelEnabled('info')){
+ _log.runLog('info', funcName, 'enter ' + funcName + '...' );
+ }
+
+ var bucket = param.Bucket;
+ if(!bucket){
+ _callback('InvalidArgument','Bucket is a required element!');
+ return;
+ }
+ bucket = String(bucket);
+
+ var key = param.Key;
+ if(!key){
+ _callback('InvalidArgument', 'Key is a required element!');
+ return;
+ }
+ key = String(key);
+
+ var pathLib = require('path');
+
+ var downloadFile;
+ if(!param.DownloadFile){
+ downloadFile = require('process').cwd() + pathLib.sep + key;
+ if(_log.isLevelEnabled('info')){
+ _log.runLog('info', funcName, 'DownloadFile is not set, will put file to path:' + downloadFile);
+ }
+ }else{
+ downloadFile = String(param.DownloadFile);
+ }
+ var downloadTempFile = downloadFile + '.temp';
+ var fs = require('fs');
+
+ var taskNum = parseInt(param.TaskNum) || 20;
+
+ obsClient.getObjectMetadata({
+ Bucket : bucket,
+ Key : key,
+ VersionId : param.VersionId,
+ }, function(err, result){
+
+ let enableCheckpoint = Boolean(param.EnableCheckpoint);
+ let checkpointFile = null;
+ let mkdirsSync = function(dirname){
+ if(fs.existsSync(dirname)){
+ return true;
+ }else{
+ if(mkdirsSync(pathLib.dirname(dirname))){
+ fs.mkdirSync(dirname);
+ return true;
+ }
+ }
+ };
+ if(enableCheckpoint){
+ checkpointFile = param.CheckpointFile;
+ checkpointFile = (checkpointFile && checkpointFile !== '') ? String(checkpointFile) : downloadFile + '.download_record';
+ let checkPointFileDir = pathLib.dirname(checkpointFile);
+ if(!fs.existsSync(checkPointFileDir)){
+ mkdirsSync(checkPointFileDir);
+ }
+ }
+
+ let tempFileDir = pathLib.dirname(downloadTempFile);
+ if(!fs.existsSync(tempFileDir)){
+ mkdirsSync(tempFileDir);
+ }
+
+ if(err || result.CommonMsg.Status >= 500){
+ _callback('GetObjectSizeError', err);
+ return;
+ }
+
+ if(result.CommonMsg.Status >= 300 && result.CommonMsg.Status < 500){
+ fs.unlink(downloadTempFile, function(){});
+ if(checkpointFile){
+ fs.unlink(checkpointFile, function(){});
+ }
+ _callback(result);
+ return;
+ }
+
+ let objectSize = parseInt(result.InterfaceResult.ContentLength);
+
+ if(objectSize === 0){
+ fs.writeFileSync(downloadFile, Buffer.from(''));
+ callback(null, result);
+ return;
+ }
+
+ let objestStat = result;
+
+ let events = require('events');
+ let eventEmitter = new events.EventEmitter();
+
+ let calculateDownloadCheckpointMD5 = function(downloadCheckpoint){
+ let data = [];
+ data.push(downloadCheckpoint.bucketName);
+ data.push(downloadCheckpoint.objectKey);
+ data.push(downloadCheckpoint.downloadFile);
+ data.push(String(downloadCheckpoint.partSize));
+ data.push(String(downloadCheckpoint.partCount));
+ if(downloadCheckpoint.versionId){
+ data.push(downloadCheckpoint.versionId);
+ }
+ if(downloadCheckpoint.ifMatch){
+ data.push(downloadCheckpoint.ifMatch);
+ }
+ if(downloadCheckpoint.ifModifiedSince){
+ data.push(downloadCheckpoint.ifModifiedSince);
+ }
+ if(downloadCheckpoint.ifNoneMatch){
+ data.push(downloadCheckpoint.ifNoneMatch);
+ }
+ if(downloadCheckpoint.ifUnmodifiedSince){
+ data.push(downloadCheckpoint.ifUnmodifiedSince);
+ }
+ if(downloadCheckpoint.sseC){
+ data.push(downloadCheckpoint.sseC);
+ }
+ if(downloadCheckpoint.sseCKey){
+ data.push(downloadCheckpoint.sseCKey);
+ }
+ if(downloadCheckpoint.partsMeta && (downloadCheckpoint.partsMeta instanceof Object)){
+ for(let key in downloadCheckpoint.partsMeta){
+ data.push(String(key));
+ let partMeta = downloadCheckpoint.partsMeta[key];
+ if(partMeta){
+ data.push(String(partMeta.startPos));
+ data.push(String(partMeta.endPos));
+ data.push(String(partMeta.isCompleted));
+ }
+ }
+ }
+ return obsClient.util.bufMD5(Buffer.from(data.join(''), 'utf8'));
+ };
+
+ let writeCheckpointFileSync = function(checkpointFile, downloadCheckpoint){
+ try{
+ if(fs.existsSync(downloadTempFile)){
+ let tempFileStat = fs.statSync(downloadTempFile);
+ if(!downloadCheckpoint.tempFileStatus){
+ downloadCheckpoint.tempFileStatus = {};
+ }
+ downloadCheckpoint.tempFileStatus.fileSize = tempFileStat.size;
+ downloadCheckpoint.tempFileStatus.lastModified = tempFileStat.mtime.toUTCString();
+ }
+ fs.writeFileSync(checkpointFile, JSON.stringify(downloadCheckpoint));
+ return true;
+ }catch(e){
+ fs.unlink(checkpointFile, function(){});
+ fs.unlink(downloadTempFile, function(){});
+ _callback('WriteCheckpointFileError', e);
+ if(_log.isLevelEnabled('warn')){
+ _log.runLog('warn', funcName, 'Write checkpoint file failed');
+ }
+ return false;
+ }
+ };
+
+ eventEmitter.on('start to downloadFile', function(downloadCheckpoint){
+
+ if(!downloadCheckpoint){
+ downloadCheckpoint = {};
+ }
+
+ if(!downloadCheckpoint.partsMeta){
+ downloadCheckpoint.partsMeta = {};
+ }
+ if(_log.isLevelEnabled('debug')){
+ _log.runLog('debug', funcName, 'Begin to downloadFile from OBS to:' + downloadFile);
+ }
+
+ fs.open(downloadTempFile, 'a', function(err, fd){
+ if(err){
+ if(checkpointFile){
+ fs.unlink(checkpointFile, function(){});
+ }
+ _callback('OpenDownloadTempFileError',err);
+ return;
+ }
+ let finishedCount = 0;
+ let hasError = false;
+ let isAbort = false;
+
+ let completedDownload = function(result){
+ if(finishedCount === downloadCheckpoint.partCount){
+ try{
+ fs.closeSync(fd);
+ }catch(e){
+ if(_log.isLevelEnabled('debug')){
+ _log.runLog('debug', funcName, 'Close temp file error :' + e);
+ }
+ }
+ if(!hasError){
+ fs.rename(downloadTempFile, downloadFile, function(err){
+ if(err){
+ if(checkpointFile){
+ if(!writeCheckpointFileSync(checkpointFile, downloadCheckpoint)){
+ return;
+ }
+ _callback('IncompletedDownload','DownloadFile finished but rename temp file error, you can retry with the same parameters, err:' + err);
+ }else{
+ fs.unlink(downloadTempFile, function(){});
+ _callback('DownloadFileFailed','DownloadFile finished but rename temp file error');
+ }
+ return;
+ }
+ if(checkpointFile){
+ fs.unlink(checkpointFile, function(){});
+ }
+ if(result && result.InterfaceResult){
+ delete result.InterfaceResult.ContentLength;
+ }
+ _callback(null, null, result);
+ });
+ }else{
+ if(checkpointFile){
+ if(!writeCheckpointFileSync(checkpointFile, downloadCheckpoint)){
+ return;
+ }
+ _callback('IncompletedDownload','DownloadFile finished with error, you can retry with the same parameters');
+ }else{
+ fs.unlink(downloadTempFile, function(){});
+ _callback('DownloadFileFailed','DownloadFile finished with error');
+ }
+ }
+ }
+ };
+
+ eventEmitter.on('doDownload', function(currentGroupIndex, groupCount, taskNum){
+ let start = (currentGroupIndex - 1) * taskNum;
+ let end = (currentGroupIndex === groupCount) ? downloadCheckpoint.partCount : currentGroupIndex * taskNum;
+ let finishedCountGroup = 0;
+ while(start < end){
+ if(isAbort){
+ return;
+ }
+ let i = start + 1;
+ if(downloadCheckpoint.partsMeta[i] && downloadCheckpoint.partsMeta[i].isCompleted){
+ finishedCount++;
+ finishedCountGroup++;
+ let _taskNum = (currentGroupIndex === groupCount) ? (downloadCheckpoint.partCount - (currentGroupIndex - 1) * taskNum) : taskNum;
+ if(finishedCountGroup === _taskNum && finishedCount < downloadCheckpoint.partCount){
+ eventEmitter.emit('doDownload', currentGroupIndex + 1, groupCount, taskNum);
+ }
+ completedDownload();
+ }else{
+ let startPos = (i-1) * downloadCheckpoint.partSize;
+ let endPos = (i === downloadCheckpoint.partCount) ? (downloadCheckpoint.objectStatus.objectSize-1) : (i * downloadCheckpoint.partSize - 1);
+ obsClient.getObject({
+ Bucket: downloadCheckpoint.bucketName,
+ Key: downloadCheckpoint.objectKey,
+ VersionId : downloadCheckpoint.versionId,
+ Range: 'bytes=' + startPos + '-' + endPos,
+ SaveAsStream : true,
+ IfMatch : downloadCheckpoint.ifMatch,
+ IfModifiedSince : downloadCheckpoint.ifModifiedSince,
+ IfNoneMatch : downloadCheckpoint.ifNoneMatch,
+ IfUnmodifiedSince : downloadCheckpoint.ifUnmodifiedSince,
+ SseC : downloadCheckpoint.sseC,
+ SseCKey : downloadCheckpoint.sseCKey
+ }, function(err, result) {
+ if(isAbort){
+ return;
+ }
+ let partMeta = {startPos : startPos, endPos : endPos};
+ if(err || result.CommonMsg.Status >= 500){
+ partMeta.isCompleted = false;
+ hasError = true;
+ downloadCheckpoint.partsMeta[i] = partMeta;
+ downloadCheckpoint.md5 = calculateDownloadCheckpointMD5(downloadCheckpoint);
+ if(checkpointFile && !writeCheckpointFileSync(checkpointFile, downloadCheckpoint)){
+ return;
+ }
+ finishedCount++;
+ finishedCountGroup++;
+ let _taskNum = (currentGroupIndex === groupCount) ? (downloadCheckpoint.partCount - (currentGroupIndex - 1) * taskNum) : taskNum;
+ if(finishedCountGroup === _taskNum && finishedCount < downloadCheckpoint.partCount){
+ eventEmitter.emit('doDownload', currentGroupIndex + 1, groupCount, taskNum);
+ }
+ completedDownload();
+ }else if(result.CommonMsg.Status >= 300 && result.CommonMsg.Status < 500){
+ isAbort = true;
+ try{
+ fs.closeSync(fd);
+ }catch(e){
+ if(_log.isLevelEnabled('debug')){
+ _log.runLog('debug', funcName, 'Close temp file error :' + e);
+ }
+ }
+ if(checkpointFile){
+ fs.unlink(checkpointFile, function(){});
+ }
+ fs.unlink(downloadTempFile, function(){});
+ _callback(result);
+ return;
+ }else{
+ let _startPos = startPos;
+ result.InterfaceResult.Content.on('data', function(data){
+ fs.write(fd, data, 0, data.length, _startPos, function(err){
+ if(err && partMeta.isCompleted === undefined){
+ partMeta.isCompleted = false;
+ hasError = true;
+ downloadCheckpoint.partsMeta[i] = partMeta;
+ downloadCheckpoint.md5 = calculateDownloadCheckpointMD5(downloadCheckpoint);
+ if(checkpointFile && !writeCheckpointFileSync(checkpointFile, downloadCheckpoint)){
+ return;
+ }
+ finishedCount++;
+ finishedCountGroup++;
+ let _taskNum = (currentGroupIndex === groupCount) ? (downloadCheckpoint.partCount - (currentGroupIndex - 1) * taskNum) : taskNum;
+ if(finishedCountGroup === _taskNum && finishedCount < downloadCheckpoint.partCount){
+ eventEmitter.emit('doDownload', currentGroupIndex + 1, groupCount, taskNum);
+ }
+ completedDownload();
+ return;
+ }
+ });
+ _startPos += data.length;
+ }).on('error', function(){
+ if(partMeta.isCompleted === undefined){
+ partMeta.isCompleted = false;
+ hasError = true;
+ downloadCheckpoint.partsMeta[i] = partMeta;
+ downloadCheckpoint.md5 = calculateDownloadCheckpointMD5(downloadCheckpoint);
+ if(checkpointFile && !writeCheckpointFileSync(checkpointFile, downloadCheckpoint)){
+ return;
+ }
+ finishedCount++;
+ finishedCountGroup++;
+ let _taskNum = (currentGroupIndex === groupCount) ? (downloadCheckpoint.partCount - (currentGroupIndex - 1) * taskNum) : taskNum;
+ if(finishedCountGroup === _taskNum && finishedCount < downloadCheckpoint.partCount){
+ eventEmitter.emit('doDownload', currentGroupIndex + 1, groupCount, taskNum);
+ }
+ completedDownload();
+ }
+ }).on('end',function(){
+ if(partMeta.isCompleted === undefined){
+ partMeta.isCompleted = true;
+ downloadCheckpoint.partsMeta[i] = partMeta;
+ downloadCheckpoint.md5 = calculateDownloadCheckpointMD5(downloadCheckpoint);
+ if(checkpointFile && !writeCheckpointFileSync(checkpointFile, downloadCheckpoint)){
+ return;
+ }
+ finishedCount++;
+ finishedCountGroup++;
+ let _taskNum = (currentGroupIndex === groupCount) ? (downloadCheckpoint.partCount - (currentGroupIndex - 1) * taskNum) : taskNum;
+ if(finishedCountGroup === _taskNum && finishedCount < downloadCheckpoint.partCount){
+ eventEmitter.emit('doDownload', currentGroupIndex + 1, groupCount, taskNum);
+ }
+ delete result.InterfaceResult.Content;
+ completedDownload(result);
+ }
+ });
+ }
+ });
+ }
+ start++;
+ }
+
+ });
+ let groupCount = (downloadCheckpoint.partCount % taskNum === 0) ? (downloadCheckpoint.partCount / taskNum) : (Math.floor(downloadCheckpoint.partCount / taskNum) + 1);
+ eventEmitter.emit('doDownload', 1, groupCount, taskNum);
+ });
+
+ });
+
+ let downloadCheckpoint;
+ let partSize = parseInt(param.PartSize);
+ partSize = isNaN(partSize) ? 5 * 1024 * 1024 : (partSize > 0 ? partSize : 5 * 1024 * 1024);
+ let partCount = objectSize % partSize === 0 ? Math.floor(objectSize / partSize) : Math.floor(objectSize / partSize) + 1;
+ if(_log.isLevelEnabled('debug')){
+ _log.runLog('debug', funcName, 'Total parts count ' + partCount);
+ }
+ downloadCheckpoint = {bucketName: bucket, objectKey: key, downloadFile : downloadFile, partSize : partSize, partCount : partCount};
+ downloadCheckpoint.versionId = param.VersionId;
+ downloadCheckpoint.ifMatch = param.IfMatch;
+ downloadCheckpoint.ifModifiedSince = param.IfModifiedSince;
+ downloadCheckpoint.ifNoneMatch = param.IfNoneMatch;
+ downloadCheckpoint.ifUnmodifiedSince = param.IfUnmodifiedSince;
+ downloadCheckpoint.sseC = param.SseC;
+ downloadCheckpoint.sseCKey = param.SseCKey;
+ downloadCheckpoint.md5 = calculateDownloadCheckpointMD5(downloadCheckpoint);
+ downloadCheckpoint.objectStatus = {objectSize : objectSize, lastModified : objestStat.InterfaceResult.LastModified, etag: objestStat.InterfaceResult.ETag};
+
+ if(checkpointFile){
+ if(!fs.existsSync(checkpointFile)){// call downloadFile first time
+ if(fs.existsSync(downloadTempFile)){
+ try{
+ fs.unlinkSync(downloadTempFile);
+ }catch(e){
+ _callback('DeleteTempFileError', e);
+ return;
+ }
+ }
+ fs.writeFile(checkpointFile, JSON.stringify(downloadCheckpoint), function(err){
+ if(err){
+ _callback('WriteCheckpointFileError',err);
+ return;
+ }
+ eventEmitter.emit('start to downloadFile', downloadCheckpoint);
+ });
+ }else{
+ fs.readFile(checkpointFile, function(err, data){
+ if(err){
+ fs.unlink(checkpointFile, function(){});
+ fs.unlink(downloadTempFile, function(){});
+ _callback('ReadCheckpointFileError',err);
+ return;
+ }
+ try{
+ downloadCheckpoint = JSON.parse(data);
+ }catch(e){
+ fs.unlink(checkpointFile, function(){});
+ fs.unlink(downloadTempFile, function(){});
+ _callback('ParseCheckpointFileError', e);
+ return;
+ }
+ // check if temp file is valid
+ let verifyTempFileStatus = function(tempFileStatus){
+ if(!tempFileStatus){
+ return true;
+ }
+ if(!fs.existsSync(downloadTempFile)){
+ return false;
+ }
+ return true;
+ // Do not verify the tempFileStatus so as to support program crash situation
+// let fstat = fs.statSync(downloadTempFile);
+// return tempFileStatus.fileSize === fstat.size && tempFileStatus.lastModified === fstat.mtime.toUTCString();
+ };
+ //verify
+ if(!downloadCheckpoint || downloadCheckpoint.bucketName !== bucket || downloadCheckpoint.objectKey !== key || downloadCheckpoint.downloadFile !== downloadFile ||
+ !downloadCheckpoint.objectStatus || downloadCheckpoint.objectStatus.objectSize !== objectSize || downloadCheckpoint.objectStatus.lastModified !== objestStat.InterfaceResult.LastModified ||
+ downloadCheckpoint.objectStatus.etag !== objestStat.InterfaceResult.ETag || !verifyTempFileStatus(downloadCheckpoint.tempFileStatus) || downloadCheckpoint.md5 !== calculateDownloadCheckpointMD5(downloadCheckpoint)){
+ fs.unlink(checkpointFile, function(){});
+ fs.unlink(downloadTempFile, function(){});
+ _callback('CheckpointFileError', 'CheckpointFile is invalid!');
+ return;
+ }
+ eventEmitter.emit('start to downloadFile', downloadCheckpoint);
+ });
+ }
+ }else{
+ if(fs.existsSync(downloadTempFile)){
+ try{
+ fs.unlinkSync(downloadTempFile);
+ }catch(e){
+ _callback('DeleteTempFileError', e);
+ return;
+ }
+ }
+ eventEmitter.emit('start to downloadFile', downloadCheckpoint);
+ }
+ });
+};
+
+function isFunction(obj){
+ return Object.prototype.toString.call(obj) === '[object Function]';
+}
+
+for(let key in ObsClient.prototype){
+ let current = ObsClient.prototype[key];
+ ObsClient.prototype[key] = function(param, callback){
+ if(isFunction(param)){
+ current.call(this, null, param);
+ return;
+ }
+ if(isFunction(callback)){
+ current.call(this, param, callback);
+ }else{
+ let that = this;
+ return new Promise(function(resolve, reject) {
+ current.call(that, param, function(err, result){
+ if(err){
+ reject(err);
+ return;
+ }
+ resolve(result);
+ });
+ });
+ }
+ };
+}
+
+ObsClient.prototype.close = function(){
+ if(this.util){
+ this.util.close();
+ delete this.util;
+ }
+};
+
+ObsClient.prototype.exec = function(funcName, param, callback){
+ var _log = this.log;
+ if(_log.isLevelEnabled('info')){
+ _log.runLog('info', funcName, 'enter ' + funcName + '...' );
+ }
+ var start = new Date().getTime();
+ param = param || {};
+ var _callback = function(err, msg){
+ if(_log.isLevelEnabled('info')){
+ _log.runLog('info', funcName, 'ObsClient cost ' + (new Date().getTime() - start) + ' ms');
+ }
+ callback(err, msg);
+ };
+ var opt = this.util.makeParam(funcName, param);
+ if('err' in opt){
+ _callback(opt['err'], null);
+ return;
+ }
+ this.util.sendRequest(funcName, opt, _callback);
+};
+
+ObsClient.prototype.initLog = function(param){
+ param = param || {};
+ this.log.initLog(param.file_full_path, param.max_log_size, param.backups, param.level, param.log_to_console, param.name);
+ if(this.log.isLevelEnabled('warn')){
+ var msg = ['[OBS SDK Version=' + this.util.obsSdkVersion];
+ if(this.util.server){
+ let port = this.util.port ? ':' + this.util.port : '';
+ msg.push('Endpoint=' + (this.util.is_secure? 'https' : 'http') + '://' + this.util.server + port);
+ }
+ msg.push('Access Mode=' + (this.util.path_style ? 'Path' : 'Virtual Hosting') + ']');
+ this.log.runLog('warn', 'init', msg.join('];['));
+ }
+};
+
+ObsClient.prototype.factory = function(param){
+ this.log = new LogUtil();
+ this.util = new Utils(this.log);
+ param = param || {};
+ this.util.initFactory(param.access_key_id, param.secret_access_key, param.is_secure,
+ param.server, param.path_style, param.signature, param.region, param.port, param.max_retry_count,
+ param.timeout, param.ssl_verify, param.long_conn_param, param.security_token);
+};
+
+ObsClient.prototype.refresh = function(access_key_id, secret_access_key, security_token){
+ this.util.refresh(access_key_id, secret_access_key, security_token);
+};
+
+ObsClient.prototype.enums = enums;
+
+ObsClient.prototype.createV2SignedUrlSync = function(param){
+ return this.util.createV2SignedUrlSync(param);
+};
+
+ObsClient.prototype.createV4SignedUrlSync = function(param){
+ return this.util.createV4SignedUrlSync(param);
+};
+
+
+ObsClient.prototype.createSignedUrlSync = function(param){
+ return this.util.createSignedUrlSync(param);
+};
+
+ObsClient.prototype.createV4PostSignatureSync = function(param){
+ return this.util.createV4PostSignatureSync(param);
+};
+
+ObsClient.prototype.createPostSignatureSync = function(param){
+ return this.util.createPostSignatureSync(param);
+};
+
+for(let key in ObsClient.prototype){
+ ObsClient.prototype[capitalize(key)] = ObsClient.prototype[key];
+}
+
+for(let key in ObsClient.prototype){
+ let index = key.indexOf('Configuration');
+ if(index > 0 && index + 'Configuration'.length === key.length){
+ ObsClient.prototype[key.slice(0, index)] = ObsClient.prototype[key];
+ }
+}
+
+module.exports = ObsClient;
+
diff --git a/lib/obs-sdk-3.0.0/obsModel.js b/lib/obs-sdk-3.0.0/obsModel.js
new file mode 100644
index 0000000..0558d5f
--- /dev/null
+++ b/lib/obs-sdk-3.0.0/obsModel.js
@@ -0,0 +1,3247 @@
+'use strict';
+
+const owner = {
+ 'type' : 'object',
+ 'location' : 'xml',
+ 'sentAs' : 'Owner',
+ 'parameters' : {
+ 'ID' : {
+ 'sentAs' : 'ID',
+ }
+ }
+};
+
+const initiator = {
+ 'type' : 'object',
+ 'location' : 'xml',
+ 'sentAs' : 'Initiator',
+ 'parameters' : {
+ 'ID' : {
+ 'sentAs' : 'ID',
+ },
+ },
+};
+const commonPrefixes = {
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'CommonPrefixes',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Prefix' : {
+ 'sentAs' : 'Prefix',
+ },
+ }
+ }
+};
+
+const grants = {
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'wrapper' : 'AccessControlList',
+ 'sentAs' : 'Grant',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Grantee' : {
+ 'type' : 'object',
+ 'sentAs' : 'Grantee',
+ 'parameters' : {
+ 'Type' : {
+ 'type' : 'ignore',
+ },
+ 'ID' : {
+ 'sentAs' : 'ID',
+ },
+ 'URI' : {
+ 'sentAs' : 'Canned',
+ 'type' : 'adapter'
+ }
+ },
+ },
+ 'Permission' : {
+ 'sentAs' : 'Permission',
+ },
+ 'Delivered' :{
+ 'sentAs' : 'Delivered',
+ }
+ },
+ },
+};
+
+const loggingEnabled = {
+ 'type' : 'object',
+ 'location' : 'xml',
+ 'sentAs' : 'LoggingEnabled',
+ 'parameters' : {
+ 'TargetBucket' : {
+ 'sentAs' : 'TargetBucket',
+ },
+ 'TargetPrefix' : {
+ 'sentAs' : 'TargetPrefix',
+ },
+ 'TargetGrants' : {
+ 'type' : 'array',
+ 'wrapper' : 'TargetGrants',
+ 'sentAs' : 'Grant',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Grantee' : {
+ 'type' : 'object',
+ 'sentAs' : 'Grantee',
+ 'parameters' : {
+ 'Type' : {
+ 'type' : 'ignore',
+ },
+ 'ID' : {
+ 'sentAs' : 'ID',
+ },
+ 'URI' : {
+ 'sentAs' : 'Canned',
+ 'type' : 'adapter'
+ }
+ },
+ },
+ 'Permission' : {
+ 'sentAs' : 'Permission',
+ },
+ },
+ },
+ },
+ },
+};
+
+const rules = {
+ 'required' : true,
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'Rule',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'ID' : {
+ 'sentAs' : 'ID',
+ },
+ 'Prefix' : {
+ 'sentAs' : 'Prefix',
+ },
+ 'Status' : {
+ 'sentAs' : 'Status',
+ },
+ 'Transitions' : {
+ 'type' : 'array',
+ 'sentAs' : 'Transition',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'StorageClass' :{
+ 'sentAs' : 'StorageClass',
+ 'type' : 'adapter'
+ },
+ 'Date' : {
+ 'sentAs' : 'Date',
+ },
+ 'Days' : {
+ 'type' : 'number',
+ 'sentAs' : 'Days'
+ }
+ }
+ }
+ },
+ 'Expiration' : {
+ 'type' : 'object',
+ 'sentAs' : 'Expiration',
+ 'parameters' : {
+ 'Date' : {
+ 'sentAs' : 'Date',
+ },
+ 'Days' : {
+ 'type' : 'number',
+ 'sentAs' : 'Days'
+ },
+ },
+ },
+ 'NoncurrentVersionTransitions' :{
+ 'type' : 'array',
+ 'sentAs' : 'NoncurrentVersionTransition',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'StorageClass' :{
+ 'sentAs' : 'StorageClass',
+ 'type' : 'adapter'
+ },
+ 'NoncurrentDays' : {
+ 'type' : 'number',
+ 'sentAs' : 'NoncurrentDays'
+ }
+ }
+ }
+ },
+ 'NoncurrentVersionExpiration' : {
+ 'type' : 'object',
+ 'sentAs' : 'NoncurrentVersionExpiration',
+ 'parameters' : {
+ 'NoncurrentDays' : {
+ 'type' : 'number',
+ 'sentAs' : 'NoncurrentDays',
+ },
+ },
+ }
+ },
+ },
+};
+
+const redirectAllRequestsTo = {
+ 'type' : 'object',
+ 'location' : 'xml',
+ 'sentAs' : 'RedirectAllRequestsTo',
+ 'parameters' : {
+ 'HostName' : {
+ 'sentAs' : 'HostName',
+ },
+ 'Protocol' : {
+ 'sentAs' : 'Protocol',
+ },
+ }
+};
+
+const routingRules = {
+ 'type' : 'array',
+ 'wrapper' : 'RoutingRules',
+ 'location' : 'xml',
+ 'sentAs' : 'RoutingRule',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Condition' : {
+ 'type' : 'object',
+ 'sentAs' : 'Condition',
+ 'parameters' : {
+ 'HttpErrorCodeReturnedEquals' : {
+ 'sentAs' : 'HttpErrorCodeReturnedEquals',
+ },
+ 'KeyPrefixEquals' : {
+ 'sentAs' : 'KeyPrefixEquals',
+ },
+ },
+ },
+ 'Redirect' : {
+ 'type' : 'object',
+ 'sentAs' : 'Redirect',
+ 'parameters' : {
+ 'HostName' : {
+ 'sentAs' : 'HostName',
+ },
+ 'HttpRedirectCode' : {
+ 'sentAs' : 'HttpRedirectCode',
+ },
+ 'Protocol' : {
+ 'sentAs' : 'Protocol',
+ },
+ 'ReplaceKeyPrefixWith' : {
+ 'sentAs' : 'ReplaceKeyPrefixWith',
+ },
+ 'ReplaceKeyWith' : {
+ 'sentAs' : 'ReplaceKeyWith',
+ }
+ }
+ },
+ },
+ },
+};
+
+const indexDocument = {
+ 'type' : 'object',
+ 'location' : 'xml',
+ 'sentAs' : 'IndexDocument',
+ 'parameters' : {
+ 'Suffix' : {
+ 'sentAs' : 'Suffix',
+ },
+ }
+};
+
+const errorDocument = {
+ 'type' : 'object',
+ 'location' : 'xml',
+ 'sentAs' : 'ErrorDocument',
+ 'parameters' : {
+ 'Key' : {
+ 'sentAs' : 'Key',
+ },
+ }
+};
+
+const corsRule = {
+ 'required' : true,
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'CORSRule',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'ID' : {
+ 'sentAs' : 'ID',
+ },
+ 'AllowedMethod' : {
+ 'type' : 'array',
+ 'sentAs' : 'AllowedMethod',
+ 'items' : {
+ 'type' : 'string',
+ },
+ },
+ 'AllowedOrigin' : {
+ 'type' : 'array',
+ 'sentAs' : 'AllowedOrigin',
+ 'items' : {
+ 'type' : 'string',
+ },
+ },
+ 'AllowedHeader' : {
+ 'type' : 'array',
+ 'sentAs' : 'AllowedHeader',
+ 'items' : {
+ 'type' : 'string',
+ },
+ },
+ 'MaxAgeSeconds' : {
+ 'type' : 'number',
+ 'sentAs' : 'MaxAgeSeconds',
+ },
+ 'ExposeHeader' : {
+ 'type' : 'array',
+ 'sentAs' : 'ExposeHeader',
+ 'items' : {
+ 'type' : 'string',
+ },
+ },
+ },
+ },
+};
+
+const topicConfiguration = {
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'TopicConfiguration',
+ 'items' : {
+ 'type' : 'object',
+ 'location' : 'xml',
+ 'parameters' : {
+ 'ID' : {
+ 'sentAs' : 'Id'
+ },
+ 'Filter' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'FilterRules' : {
+ 'wrapper' : 'Object',
+ 'type' : 'array',
+ 'sentAs' : 'FilterRule',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Name' : {},
+ 'Value' : {}
+ }
+ }
+ }
+ }
+ },
+ 'Topic' : {},
+
+ 'Event' : {
+ 'type' : 'array',
+ 'items' : {
+ 'type' : 'adapter',
+ }
+ }
+ }
+ }
+};
+
+const tagSet = {
+ 'required' : true,
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'wrapper' : 'TagSet',
+ 'sentAs' : 'Tag',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Key' : {
+ 'sentAs' : 'Key',
+ },
+ 'Value' : {
+ 'sentAs' : 'Value',
+ }
+ }
+ }
+};
+
+const replicationRules = {
+ 'required' : true,
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'Rule',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'ID' : {
+ 'sentAs' : 'ID',
+ },
+ 'Prefix' : {
+ 'sentAs' : 'Prefix',
+ },
+ 'Status' : {
+ 'sentAs' : 'Status',
+ },
+ 'Destination' :{
+ 'type' : 'object',
+ 'sentAs' : 'Destination',
+ 'parameters' :{
+ 'Bucket' : {
+ 'sentAs' : 'Bucket',
+ 'type' : 'adapter'
+ },
+ 'StorageClass' :{
+ 'sentAs' : 'StorageClass',
+ 'type' : 'adapter'
+ }
+ }
+ }
+ },
+ }
+};
+
+const operations = {
+ 'CreateBucket' : {
+ 'httpMethod' : 'PUT',
+ 'data' : {
+ 'xmlRoot' : 'CreateBucketConfiguration',
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'ACL' : {
+ 'location' : 'header',
+ 'sentAs' : 'acl',
+ 'withPrefix' : true,
+ 'type' : 'adapter'
+ },
+ 'StorageClass' : {
+ 'location' : 'header',
+ 'sentAs' : 'storage-class',
+ 'withPrefix' : true,
+ 'type' : 'adapter'
+ },
+ 'Location' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Location'
+ },
+ 'GrantRead' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-read',
+ 'withPrefix' : true,
+ },
+
+ 'GrantWrite' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-write',
+ 'withPrefix' : true,
+ },
+
+ 'GrantReadAcp' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-read-acp',
+ 'withPrefix' : true,
+ },
+
+ 'GrantWriteAcp' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-write-acp',
+ 'withPrefix' : true,
+ },
+
+ 'GrantFullControl' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-full-control',
+ 'withPrefix' : true,
+ },
+
+ 'GrantReadDelivered' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-read-delivered',
+ 'withPrefix' : true,
+ },
+
+ 'GrantFullControlDelivered' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-full-control-delivered',
+ 'withPrefix' : true,
+ }
+ }
+ },
+
+ 'ListBuckets' : {
+ 'httpMethod' : 'GET',
+ 'parameters' : {
+ }
+ },
+
+ 'ListBucketsOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'ListAllMyBucketsResult',
+ },
+ 'parameters' : {
+ 'Owner' : {
+ 'type' : 'object',
+ 'location' : 'xml',
+ 'sentAs' : 'Owner',
+ 'parameters' : {
+ 'ID' : {
+ 'sentAs' : 'ID',
+ },
+ },
+
+ },
+ 'Buckets' : {
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'wrapper' : 'Buckets',
+ 'sentAs' : 'Bucket',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'BucketName' : {
+ 'sentAs' : 'Name',
+ },
+ 'CreationDate' : {
+ 'type' : 'date',
+ 'sentAs' : 'CreationDate'
+ },
+ 'Location' : {
+ 'sentAs' : 'Location'
+ }
+ },
+ },
+ },
+ },
+ },
+
+ 'HeadBucket' : {
+ 'httpMethod' : 'HEAD',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+
+
+ 'GetBucketMetadata' : {
+ 'httpMethod' : 'HEAD',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+
+ 'Origin' : {
+ 'location' : 'header',
+ 'sentAs' : 'Origin'
+ },
+
+ 'RequestHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'Access-Control-Request-Headers'
+ }
+ },
+ },
+
+ 'GetBucketMetadataOutput' : {
+ 'parameters' : {
+ 'StorageClass' : {
+ 'location' : 'header',
+ 'sentAs' : 'storage-class',
+ 'withPrefix' : true
+ },
+ 'ObsVersion' : {
+ 'location' : 'header',
+ 'sentAs' : 'version',
+ 'withPrefix' : true
+ },
+ 'Location' : {
+ 'location' : 'header',
+ 'sentAs' : 'bucket-location',
+ 'withPrefix' : true
+ },
+ 'AllowOrigin' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-origin'
+ },
+ 'MaxAgeSeconds' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-max-age'
+ },
+ 'ExposeHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-expose-headers'
+ },
+ 'AllowMethod' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-methods'
+ },
+ 'AllowHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-headers'
+ }
+ }
+ },
+
+ 'DeleteBucket' : {
+ 'httpMethod' : 'DELETE',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+
+ 'ListObjects' : {
+ 'httpMethod' : 'GET',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Prefix' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'prefix',
+ },
+ 'Marker' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'marker',
+ },
+ 'MaxKeys' : {
+ 'type' : 'number',
+ 'location' : 'urlPath',
+ 'sentAs' : 'max-keys',
+ },
+ 'Delimiter' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'delimiter',
+ },
+ },
+ },
+
+ 'ListObjectsOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'ListBucketResult',
+ },
+ 'parameters' : {
+ 'Location' : {
+ 'location' : 'header',
+ 'sentAs' : 'bucket-location',
+ 'withPrefix' : true
+ },
+ 'Bucket' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Name',
+ },
+ 'Delimiter' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Delimiter',
+ },
+ 'IsTruncated' : {
+ 'location' : 'xml',
+ 'sentAs' : 'IsTruncated',
+ },
+ 'Prefix' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Prefix',
+ },
+ 'Marker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Marker',
+ },
+ 'NextMarker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'NextMarker',
+ },
+ 'MaxKeys' : {
+ 'location' : 'xml',
+ 'sentAs' : 'MaxKeys',
+ },
+ 'Contents' : {
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'Contents',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Key' : {
+ 'sentAs' : 'Key',
+ },
+ 'LastModified' : {
+ 'type' : 'date',
+ 'sentAs' : 'LastModified',
+ },
+ 'ETag' : {
+ 'sentAs' : 'ETag',
+ },
+ 'Size' : {
+ 'sentAs' : 'Size',
+ },
+ 'Type' :{
+ 'sentAs' : 'Type'
+ },
+ 'StorageClass' : {
+ 'sentAs' : 'StorageClass',
+ },
+ 'Owner' : owner
+ },
+ },
+
+ },
+ 'CommonPrefixes' : commonPrefixes
+ },
+ },
+
+ 'ListVersions' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'versions',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Prefix' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'prefix',
+ },
+ 'KeyMarker' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'key-marker',
+ },
+ 'MaxKeys' : {
+ 'type' : 'number',
+ 'location' : 'urlPath',
+ 'sentAs' : 'max-keys',
+ },
+ 'Delimiter' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'delimiter',
+ },
+ 'VersionIdMarker' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'version-id-marker',
+ },
+ },
+ },
+ 'ListVersionsOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'ListVersionsResult',
+ },
+ 'parameters' : {
+ 'Location' : {
+ 'location' : 'header',
+ 'sentAs' : 'bucket-location',
+ 'withPrefix' : true
+ },
+ 'Bucket' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Name',
+ },
+ 'Prefix' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Prefix',
+ },
+ 'Delimiter' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Delimiter',
+ },
+ 'KeyMarker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'KeyMarker',
+ },
+ 'VersionIdMarker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'VersionIdMarker',
+ },
+ 'NextKeyMarker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'NextKeyMarker',
+ },
+ 'NextVersionIdMarker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'NextVersionIdMarker',
+ },
+ 'MaxKeys' : {
+ 'location' : 'xml',
+ 'sentAs' : 'MaxKeys',
+ },
+ 'IsTruncated' : {
+ 'location' : 'xml',
+ 'sentAs' : 'IsTruncated',
+ },
+ 'Versions' : {
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'Version',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Key' : {
+ 'sentAs' : 'Key',
+ },
+ 'VersionId' : {
+ 'sentAs' : 'VersionId',
+ },
+ 'IsLatest' : {
+ 'sentAs' : 'IsLatest',
+ },
+ 'LastModified' : {
+ 'type' : 'date',
+ 'sentAs' : 'LastModified',
+ },
+ 'ETag' : {
+ 'sentAs' : 'ETag',
+ },
+ 'Size' : {
+ 'sentAs' : 'Size',
+ },
+ 'Type' :{
+ 'sentAs' : 'Type'
+ },
+ 'Owner' : owner,
+ 'StorageClass' : {
+ 'sentAs' : 'StorageClass',
+ }
+ }
+ },
+ },
+ 'DeleteMarkers' : {
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'DeleteMarker',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Key' : {
+ 'sentAs' : 'Key',
+ },
+ 'VersionId' : {
+ 'sentAs' : 'VersionId',
+ },
+ 'IsLatest' : {
+ 'sentAs' : 'IsLatest',
+ },
+ 'LastModified' : {
+ 'type' : 'date',
+ 'sentAs' : 'LastModified',
+ },
+ 'Owner' : owner
+ }
+ },
+ },
+ 'CommonPrefixes' : commonPrefixes
+ },
+ },
+
+ 'GetBucketLocation' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'location',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+
+ 'GetBucketLocationOutput' : {
+ 'data' : {
+ 'type' : 'xml'
+ },
+ 'parameters' : {
+ 'Location' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Location'
+ },
+ },
+ },
+
+ 'GetBucketStorageInfo' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'storageinfo',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+ 'GetBucketStorageInfoOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'GetBucketStorageInfoResult',
+ },
+ 'parameters' : {
+ 'Size' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Size',
+ },
+ 'ObjectNumber' : {
+ 'location' : 'xml',
+ 'sentAs' : 'ObjectNumber',
+ },
+ },
+ },
+
+ 'SetBucketQuota' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'quota',
+ 'data' : {
+ 'xmlRoot' : 'Quota',
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'StorageQuota' : {
+ 'required' : true,
+ 'location' : 'xml',
+ 'sentAs' : 'StorageQuota',
+ },
+ },
+ },
+
+ 'GetBucketQuota' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'quota',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+
+ },
+ },
+ 'GetBucketQuotaOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'Quota',
+ },
+ 'parameters' : {
+ 'StorageQuota' : {
+ 'location' : 'xml',
+ 'sentAs' : 'StorageQuota',
+ },
+ },
+ },
+
+ 'SetBucketAcl' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'acl',
+ 'data' : {
+ 'xmlRoot' : 'AccessControlPolicy',
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'ACL' : {
+ 'location' : 'header',
+ 'sentAs' : 'acl',
+ 'withPrefix' : true,
+ 'type' : 'adapter'
+ },
+ 'Owner' : owner,
+ 'Grants' : grants
+ },
+ },
+
+ 'GetBucketAcl' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'acl',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+ 'GetBucketAclOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'AccessControlPolicy',
+ },
+ 'parameters' : {
+ 'Owner' : owner,
+ 'Grants' : grants
+ }
+ },
+
+ 'SetBucketLoggingConfiguration' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'logging',
+ 'data' : {
+ 'xmlRoot' : 'BucketLoggingStatus',
+ 'xmlAllowEmpty' : true
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Agency' :{
+ 'location' : 'xml',
+ 'sentAs' : 'Agency',
+ },
+ 'LoggingEnabled' : loggingEnabled,
+ },
+ },
+
+ 'GetBucketLoggingConfiguration' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'logging',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+ 'GetBucketLoggingConfigurationOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'BucketLoggingStatus',
+ },
+ 'parameters' : {
+ 'Agency' :{
+ 'location' : 'xml',
+ 'sentAs' : 'Agency'
+ },
+ 'LoggingEnabled' : loggingEnabled,
+ },
+ },
+
+ 'SetBucketPolicy' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'policy',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Policy' : {
+ 'required' : true,
+ 'location' : 'body',
+ },
+ },
+ },
+
+ 'GetBucketPolicy' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'policy',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+ 'GetBucketPolicyOutput' : {
+ 'data' : {
+ 'type' : 'body',
+ },
+ 'parameters' : {
+ 'Policy' : {
+ 'location' : 'body',
+ },
+ },
+ },
+ 'DeleteBucketPolicy' : {
+ 'httpMethod' : 'DELETE',
+ 'urlPath' : 'policy',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+
+ 'SetBucketLifecycleConfiguration' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'lifecycle',
+ 'data' : {
+ 'xmlRoot' : 'LifecycleConfiguration',
+ 'md5' : true
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Rules' : rules
+ },
+ },
+
+ 'GetBucketLifecycleConfiguration' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'lifecycle',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+ 'GetBucketLifecycleConfigurationOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'LifecycleConfiguration',
+ },
+ 'parameters' : {
+ 'Rules' : rules
+ },
+ },
+
+ 'DeleteBucketLifecycleConfiguration' : {
+ 'httpMethod' : 'DELETE',
+ 'urlPath' : 'lifecycle',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+
+ 'SetBucketWebsiteConfiguration' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'website',
+ 'data' : {
+ 'xmlRoot' : 'WebsiteConfiguration',
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'RedirectAllRequestsTo' : redirectAllRequestsTo,
+ 'IndexDocument' : indexDocument,
+ 'ErrorDocument' : errorDocument,
+ 'RoutingRules' : routingRules
+ },
+ },
+
+ 'GetBucketWebsiteConfiguration' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'website',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+ 'GetBucketWebsiteConfigurationOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'WebsiteConfiguration',
+ },
+ 'parameters' : {
+ 'RedirectAllRequestsTo' : redirectAllRequestsTo,
+ 'IndexDocument' : indexDocument,
+ 'ErrorDocument' : errorDocument,
+ 'RoutingRules' : routingRules,
+ },
+ },
+ 'DeleteBucketWebsiteConfiguration' : {
+ 'httpMethod' : 'DELETE',
+ 'urlPath' : 'website',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+
+ 'SetBucketVersioningConfiguration' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'versioning',
+ 'data' : {
+ 'xmlRoot' : 'VersioningConfiguration',
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'VersionStatus' : {
+ 'required' : true,
+ 'location' : 'xml',
+ 'sentAs' : 'Status',
+ },
+ },
+ },
+
+ 'GetBucketVersioningConfiguration' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'versioning',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+ 'GetBucketVersioningConfigurationOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'VersioningConfiguration',
+ },
+ 'parameters' : {
+ 'VersionStatus' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Status',
+ },
+ },
+ },
+
+ 'SetBucketCors' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'cors',
+ 'data' : {
+ 'xmlRoot' : 'CORSConfiguration',
+ 'md5' : true
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'CorsRules' : corsRule
+ },
+ },
+ 'GetBucketCors' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'cors',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+ 'GetBucketCorsOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'CORSConfiguration',
+ },
+ 'parameters' : {
+ 'CorsRules' : corsRule
+ },
+ },
+ 'DeleteBucketCors' : {
+ 'httpMethod' : 'DELETE',
+ 'urlPath' : 'cors',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ },
+ },
+
+ 'SetBucketNotification' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'notification',
+ 'data' : {
+ 'xmlRoot' : 'NotificationConfiguration',
+ 'xmlAllowEmpty' : true
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri'
+ },
+ 'TopicConfigurations' : topicConfiguration
+ }
+ },
+
+
+ 'GetBucketNotification' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'notification',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ }
+ },
+
+ 'GetBucketNotificationOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'NotificationConfiguration',
+ },
+ 'parameters' : {
+ 'TopicConfigurations' : topicConfiguration
+ },
+ },
+
+ 'OptionsBucket' : {
+ 'httpMethod' : 'OPTIONS',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Origin' : {
+ 'required' : true,
+ 'location' : 'header',
+ 'sentAs' : 'Origin',
+ },
+ 'AccessControlRequestMethods' : {
+ 'required' : true,
+ 'type' : 'array',
+ 'location' : 'header',
+ 'sentAs' : 'Access-Control-Request-Method',
+ 'items' : {
+ 'type' : 'string',
+ },
+ },
+ 'AccessControlRequestHeaders' : {
+ 'type' : 'array',
+ 'location' : 'header',
+ 'sentAs' : 'Access-Control-Request-Headers',
+ 'items' : {
+ 'type' : 'string',
+ },
+ },
+ },
+ },
+ 'OptionsBucketOutput' : {
+ 'parameters' : {
+ 'AllowOrigin' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-origin',
+ },
+ 'AllowHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-headers',
+ },
+ 'AllowMethod' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-methods',
+ },
+ 'ExposeHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-expose-headers',
+ },
+ 'MaxAgeSeconds' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-max-age',
+ },
+ },
+ },
+
+ 'SetBucketTagging' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'tagging',
+ 'data' : {
+ 'xmlRoot' : 'Tagging',
+ 'md5' : true
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri'
+ },
+ 'Tags' : tagSet
+ }
+ },
+
+ 'GetBucketTagging' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'tagging',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ }
+ },
+
+ 'GetBucketTaggingOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'Tagging',
+ },
+ 'parameters' : {
+ 'Tags' : tagSet
+ }
+ },
+
+ 'DeleteBucketTagging' : {
+ 'httpMethod' : 'DELETE',
+ 'urlPath' : 'tagging',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ }
+ },
+
+ 'SetBucketStoragePolicy' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'storageClass',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'StorageClass' :{
+ 'required' : true,
+ 'location' : 'xml',
+ 'type' : 'adapter',
+ 'sentAs' : 'StorageClass'
+ }
+ }
+ },
+
+ 'GetBucketStoragePolicy' :{
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'storageClass',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ }
+ },
+
+ 'GetBucketStoragePolicyOutput' :{
+ 'data' : {
+ 'type' : 'xml',
+ },
+ 'parameters' : {
+ 'StorageClass' : {
+ 'location' : 'xml',
+ 'type' : 'string',
+ 'sentAs' : 'StorageClass'
+ }
+ }
+ },
+
+ 'SetBucketReplication' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'replication',
+ 'data' : {
+ 'xmlRoot' : 'ReplicationConfiguration',
+ 'md5' : true
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri'
+ },
+ 'Agency' :{
+ 'location' : 'xml',
+ 'sentAs' : 'Agency'
+ },
+ 'Rules' : replicationRules
+ }
+ },
+
+ 'GetBucketReplication' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'replication',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ }
+ },
+
+ 'GetBucketReplicationOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'ReplicationConfiguration',
+ },
+ 'parameters' : {
+ 'Agency' :{
+ 'location' : 'xml',
+ 'sentAs' : 'Agency'
+ },
+ 'Rules' : replicationRules
+ }
+ },
+
+ 'DeleteBucketReplication' : {
+ 'httpMethod' : 'DELETE',
+ 'urlPath' : 'replication',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ }
+ },
+
+ 'PutObject' : {
+ 'httpMethod' : 'PUT',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'ContentMD5' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-MD5',
+ },
+ 'ContentType' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-Type'
+ },
+ 'Offset' : {
+ 'type' : 'plain'
+ },
+ 'ContentLength' :{
+ 'location' : 'header',
+ 'sentAs' : 'Content-Length',
+ 'type' : 'plain'
+ },
+ 'ACL' : {
+ 'location' : 'header',
+ 'sentAs' : 'acl',
+ 'withPrefix' : true
+ },
+ 'GrantRead' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-read',
+ 'withPrefix' : true,
+ },
+ 'GrantReadAcp' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-read-acp',
+ 'withPrefix' : true,
+ },
+ 'GrantWriteAcp' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-write-acp',
+ 'withPrefix' : true,
+ },
+ 'GrantFullControl' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-full-control',
+ 'withPrefix' : true,
+ },
+ 'StorageClass' : {
+ 'location' : 'header',
+ 'sentAs' : 'storage-class',
+ 'withPrefix' : true,
+ },
+ 'Metadata' : {
+ 'type' : 'object',
+ 'location' : 'header',
+ 'sentAs' : 'meta-',
+ 'withPrefix' : true,
+ },
+ 'WebsiteRedirectLocation' : {
+ 'location' : 'header',
+ 'sentAs' : 'website-redirect-location',
+ 'withPrefix' : true,
+ },
+ 'Expires' : {
+ 'location' : 'header',
+ 'sentAs' : 'expires',
+ 'type' : 'number',
+ 'withPrefix' : true,
+ },
+ 'SuccessActionRedirect':{
+ 'location' : 'header',
+ 'sentAs' : 'success-action-redirect'
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true,
+ 'type' : 'adapter'
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true,
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true,
+ },
+ 'SseCKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key',
+ 'type' : 'password',
+ 'withPrefix' : true,
+ },
+ 'Body' : {
+ 'location' : 'body',
+ },
+ 'SourceFile' : {
+ 'type' : 'srcFile',
+ }
+ },
+ },
+ 'PutObjectOutput' : {
+ 'parameters' : {
+ 'ETag' : {
+ 'location' : 'header',
+ 'sentAs' : 'etag',
+ },
+ 'VersionId' : {
+ 'location' : 'header',
+ 'sentAs' : 'version-id',
+ 'withPrefix' : true,
+ },
+ 'StorageClass' :{
+ 'location' : 'header',
+ 'sentAs' : 'storage-class',
+ 'withPrefix' : true,
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true,
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true,
+ },
+ 'SseCKeyMd5' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key-MD5',
+ 'withPrefix' : true,
+ }
+ },
+ },
+
+ 'AppendObject' : {
+ 'httpMethod' : 'POST',
+ 'urlPath' : 'append',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Position' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'position',
+ 'type' : 'number'
+ },
+ 'ContentMD5' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-MD5',
+ },
+ 'ContentType' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-Type'
+ },
+ 'Offset' : {
+ 'type' : 'plain'
+ },
+ 'ContentLength' :{
+ 'location' : 'header',
+ 'sentAs' : 'Content-Length',
+ 'type' : 'plain'
+ },
+ 'ACL' : {
+ 'location' : 'header',
+ 'sentAs' : 'acl',
+ 'withPrefix' : true
+ },
+ 'GrantRead' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-read',
+ 'withPrefix' : true,
+ },
+ 'GrantReadAcp' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-read-acp',
+ 'withPrefix' : true,
+ },
+ 'GrantWriteAcp' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-write-acp',
+ 'withPrefix' : true,
+ },
+ 'GrantFullControl' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-full-control',
+ 'withPrefix' : true,
+ },
+ 'StorageClass' : {
+ 'location' : 'header',
+ 'sentAs' : 'storage-class',
+ 'withPrefix' : true,
+ },
+ 'Metadata' : {
+ 'type' : 'object',
+ 'location' : 'header',
+ 'sentAs' : 'meta-',
+ 'withPrefix' : true,
+ },
+ 'WebsiteRedirectLocation' : {
+ 'location' : 'header',
+ 'sentAs' : 'website-redirect-location',
+ 'withPrefix' : true,
+ },
+ 'Expires' : {
+ 'location' : 'header',
+ 'sentAs' : 'expires',
+ 'type' : 'number',
+ 'withPrefix' : true,
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true,
+ 'type' : 'adapter'
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true,
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true,
+ },
+ 'SseCKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key',
+ 'type' : 'password',
+ 'withPrefix' : true,
+ },
+ 'Body' : {
+ 'location' : 'body',
+ },
+ 'SourceFile' : {
+ 'type' : 'srcFile',
+ }
+ },
+ },
+ 'AppendObjectOutput' : {
+ 'parameters' : {
+ 'ETag' : {
+ 'location' : 'header',
+ 'sentAs' : 'etag',
+ },
+ 'NextPosition' : {
+ 'location' : 'header',
+ 'sentAs' : 'next-append-position',
+ 'withPrefix' : true,
+ },
+ 'StorageClass' :{
+ 'location' : 'header',
+ 'sentAs' : 'storage-class',
+ 'withPrefix' : true,
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true,
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true,
+ },
+ 'SseCKeyMd5' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key-MD5',
+ 'withPrefix' : true,
+ }
+ },
+ },
+
+ 'GetObject' : {
+ 'httpMethod' : 'GET',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'ResponseCacheControl' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'response-cache-control',
+ },
+ 'ResponseContentDisposition' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'response-content-disposition',
+ },
+ 'ResponseContentEncoding' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'response-content-encoding',
+ },
+ 'ResponseContentLanguage' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'response-content-language',
+ },
+ 'ResponseContentType' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'response-content-type',
+ },
+ 'ResponseExpires' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'response-expires',
+ },
+ 'VersionId' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'versionId',
+ },
+ 'ImageProcess' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'x-image-process',
+ },
+ 'IfMatch' : {
+ 'location' : 'header',
+ 'sentAs' : 'If-Match',
+ },
+ 'IfModifiedSince' : {
+ 'location' : 'header',
+ 'sentAs' : 'If-Modified-Since',
+ },
+ 'IfNoneMatch' : {
+ 'location' : 'header',
+ 'sentAs' : 'If-None-Match',
+ },
+ 'IfUnmodifiedSince' : {
+ 'location' : 'header',
+ 'sentAs' : 'If-Unmodified-Since',
+ },
+ 'Range' : {
+ 'location' : 'header',
+ 'sentAs' : 'Range',
+ },
+ 'Origin' :{
+ 'location' : 'header',
+ 'sentAs' : 'Origin'
+ },
+ 'RequestHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'Access-Control-Request-Headers'
+ },
+ 'SaveAsFile' : {
+ 'type' : 'dstFile',
+ },
+ 'SaveAsStream' : {
+ 'type' : 'plain'
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key',
+ 'type' : 'password',
+ 'withPrefix' : true
+ }
+ }
+ },
+ 'GetObjectOutput' : {
+ 'data' : {
+ 'type' : 'body'
+ },
+ 'parameters' : {
+ 'Content' : {
+ 'location' : 'body',
+ },
+ 'Expiration' : {
+ 'location' : 'header',
+ 'sentAs' : 'expiration',
+ 'withPrefix' : true
+ },
+ 'ETag' : {
+ 'location' : 'header',
+ 'sentAs' : 'etag',
+ },
+ 'CacheControl' : {
+ 'location' : 'header',
+ 'sentAs' : 'Cache-Control',
+ },
+ 'ContentDisposition' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-Disposition',
+ },
+ 'ContentEncoding' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-Encoding',
+ },
+ 'ContentLanguage' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-Language',
+ },
+ 'ContentType' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-Type',
+ },
+ 'Expires' : {
+ 'location' : 'header',
+ 'sentAs' : 'Expires',
+ },
+ 'VersionId' : {
+ 'location' : 'header',
+ 'sentAs' : 'version-id',
+ 'withPrefix' : true
+ },
+ 'ContentLength' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-Length',
+ },
+ 'DeleteMarker' : {
+ 'location' : 'header',
+ 'sentAs' : 'delete-marker',
+ 'withPrefix' : true
+ },
+ 'LastModified' : {
+ 'type' : 'date',
+ 'location' : 'header',
+ 'sentAs' : 'Last-Modified',
+ },
+ 'WebsiteRedirectLocation' : {
+ 'location' : 'header',
+ 'sentAs' : 'website-redirect-location',
+ 'withPrefix' : true
+ },
+ 'StorageClass' : {
+ 'location' : 'header',
+ 'sentAs' : 'storage-class',
+ 'withPrefix' : true
+ },
+ 'Restore' : {
+ 'location' : 'header',
+ 'sentAs' : 'restore',
+ 'withPrefix' : true
+ },
+ 'AllowOrigin' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-origin'
+ },
+ 'MaxAgeSeconds' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-max-age'
+ },
+ 'ExposeHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-expose-headers'
+ },
+ 'AllowMethod' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-methods'
+ },
+ 'AllowHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-headers'
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKeyMd5' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key-MD5',
+ 'withPrefix' : true
+ },
+ 'Metadata' : {
+ 'location' : 'header',
+ 'type' : 'object',
+ 'sentAs' : 'meta-',
+ 'withPrefix' : true
+ }
+ },
+ },
+ 'CopyObject' : {
+ 'httpMethod' : 'PUT',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'ACL' : {
+ 'location' : 'header',
+ 'sentAs' : 'acl',
+ 'withPrefix' : true
+ },
+ 'GrantRead' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-read',
+ 'withPrefix' : true,
+ },
+ 'GrantReadAcp' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-read-acp',
+ 'withPrefix' : true,
+ },
+ 'GrantWriteAcp' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-write-acp',
+ 'withPrefix' : true,
+ },
+ 'GrantFullControl' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-full-control',
+ 'withPrefix' : true,
+ },
+ 'StorageClass' : {
+ 'location' : 'header',
+ 'sentAs' : 'storage-class',
+ 'withPrefix' : true
+ },
+ 'CopySource' : {
+ 'required' : true,
+ 'location' : 'header',
+ 'sentAs' : 'copy-source',
+ 'withPrefix' : true,
+ 'skipEncoding' : true
+ },
+ 'CopySourceIfMatch' : {
+ 'location' : 'header',
+ 'sentAs' : 'copy-source-if-match',
+ 'withPrefix' : true
+ },
+ 'CopySourceIfModifiedSince' : {
+ 'location' : 'header',
+ 'sentAs' : 'copy-source-if-modified-since',
+ 'withPrefix' : true
+ },
+ 'CopySourceIfNoneMatch' : {
+ 'location' : 'header',
+ 'sentAs' : 'copy-source-if-none-match',
+ 'withPrefix' : true
+ },
+ 'CopySourceIfUnmodifiedSince' : {
+ 'location' : 'header',
+ 'sentAs' : 'copy-source-if-unmodified-since',
+ 'withPrefix' : true
+ },
+ 'ContentType' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-Type'
+ },
+ 'ContentEncoding' : {
+ 'location' : 'header',
+ 'sentAs' : 'content-encoding'
+ },
+ 'ContentLanguage' : {
+ 'location' : 'header',
+ 'sentAs' : 'content-language'
+ },
+ 'ContentDisposition' : {
+ 'location' : 'header',
+ 'sentAs' : 'content-disposition'
+ },
+ 'CacheControl' : {
+ 'location' : 'header',
+ 'sentAs' : 'cache-control'
+ },
+ 'Expires' : {
+ 'location' : 'header',
+ 'sentAs' : 'expires'
+ },
+ 'Metadata' : {
+ 'type' : 'object',
+ 'location' : 'header',
+ 'sentAs' : 'meta-',
+ 'withPrefix' : true
+ },
+ 'MetadataDirective' : {
+ 'location' : 'header',
+ 'sentAs' : 'metadata-directive',
+ 'withPrefix' : true
+ },
+ 'WebsiteRedirectLocation' : {
+ 'location' : 'header',
+ 'sentAs' : 'website-redirect-location',
+ 'withPrefix' : true
+ },
+ 'SuccessActionRedirect':{
+ 'location' : 'header',
+ 'sentAs' : 'success-action-redirect'
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true,
+ 'type' : 'adapter'
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key',
+ 'type' : 'password',
+ 'withPrefix' : true
+ },
+ 'CopySourceSseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'copy-source-server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'CopySourceSseCKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'copy-source-server-side-encryption-customer-key',
+ 'type' : 'password',
+ 'withPrefix' : true
+ },
+ },
+ },
+ 'CopyObjectOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'CopyObjectResult',
+ },
+ 'parameters' : {
+ 'VersionId' : {
+ 'location' : 'header',
+ 'sentAs' : 'version-id',
+ 'withPrefix' : true
+ },
+ 'CopySourceVersionId' : {
+ 'location' : 'header',
+ 'sentAs' : 'copy-source-version-id',
+ 'withPrefix' : true
+ },
+ 'ETag' : {
+ 'location' : 'xml',
+ 'sentAs' : 'ETag',
+ },
+ 'LastModified' : {
+ 'type' : 'date',
+ 'location' : 'xml',
+ 'sentAs' : 'LastModified',
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKeyMd5' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key-MD5',
+ 'withPrefix' : true
+ }
+ },
+ },
+
+ 'RestoreObject' : {
+ 'httpMethod' : 'POST',
+ 'urlPath' : 'restore',
+ 'data' : {
+ 'xmlRoot' : 'RestoreRequest',
+ 'md5' : true
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'VersionId' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'versionId',
+ },
+ 'Days' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Days'
+ },
+ 'Tier' : {
+ 'wrapper' : 'GlacierJobParameters',
+ 'location' : 'xml',
+ 'sentAs' : 'Tier',
+ }
+ }
+ },
+
+ 'GetObjectMetadata' : {
+ 'httpMethod' : 'HEAD',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'VersionId' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'versionId',
+ },
+ 'Origin' : {
+ 'location' : 'header',
+ 'sentAs' : 'Origin'
+ },
+ 'RequestHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'Access-Control-Request-Headers'
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key',
+ 'type' : 'password',
+ 'withPrefix' : true
+ },
+ },
+ },
+
+ 'GetObjectMetadataOutput' : {
+ 'parameters' : {
+ 'Expiration' : {
+ 'location' : 'header',
+ 'sentAs' : 'expiration',
+ 'withPrefix' : true
+ },
+ 'LastModified' : {
+ 'type' : 'date',
+ 'location' : 'header',
+ 'sentAs' : 'Last-Modified',
+ },
+ 'ContentLength' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-Length',
+ },
+ 'ContentType' :{
+ 'location' : 'header',
+ 'sentAs' : 'Content-Type'
+ },
+ 'ETag' : {
+ 'location' : 'header',
+ 'sentAs' : 'etag',
+ },
+ 'VersionId' : {
+ 'location' : 'header',
+ 'sentAs' : 'version-id',
+ 'withPrefix' : true
+ },
+ 'WebsiteRedirectLocation' : {
+ 'location' : 'header',
+ 'sentAs' : 'website-redirect-location',
+ 'withPrefix' : true
+ },
+ 'StorageClass' : {
+ 'location' : 'header',
+ 'sentAs' : 'storage-class',
+ 'withPrefix' : true
+ },
+ 'Restore' : {
+ 'location' : 'header',
+ 'sentAs' : 'restore',
+ 'withPrefix' : true
+ },
+ 'ObjectType' :{
+ 'location' : 'header',
+ 'sentAs' : 'object-type',
+ 'withPrefix' : true
+ },
+ 'NextPosition' :{
+ 'location' : 'header',
+ 'sentAs' : 'next-append-position',
+ 'withPrefix' : true
+ },
+ 'AllowOrigin' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-origin'
+ },
+ 'MaxAgeSeconds' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-max-age'
+ },
+ 'ExposeHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-expose-headers'
+ },
+ 'AllowMethod' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-methods'
+ },
+ 'AllowHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-headers'
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKeyMd5' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key-MD5',
+ 'withPrefix' : true
+ },
+ 'Metadata' : {
+ 'location' : 'header',
+ 'type' : 'object',
+ 'sentAs' : 'meta-',
+ 'withPrefix' : true
+ }
+ },
+ },
+
+ 'SetObjectAcl' : {
+ 'httpMethod' : 'PUT',
+ 'urlPath' : 'acl',
+ 'data' : {
+ 'xmlRoot' : 'AccessControlPolicy',
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'VersionId' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'versionId',
+ },
+ 'ACL' : {
+ 'location' : 'header',
+ 'sentAs' : 'acl',
+ 'withPrefix' : true,
+ 'type' : 'adapter'
+ },
+ 'Delivered' :{
+ 'location' : 'xml',
+ 'sentAs' : 'Delivered'
+ },
+ 'Owner' : owner,
+ 'Grants' : grants
+ },
+ },
+ 'SetObjectAclOutput' : {
+ 'parameters' : {
+ 'VersionId' : {
+ 'location' : 'header',
+ 'sentAs' : 'version-id',
+ 'withPrefix' : true
+ },
+ },
+ },
+ 'GetObjectAcl' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'acl',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'VersionId' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'versionId',
+ },
+ },
+ },
+ 'GetObjectAclOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'AccessControlPolicy',
+ },
+ 'parameters' : {
+ 'VersionId' : {
+ 'location' : 'header',
+ 'sentAs' : 'version-id',
+ 'withPrefix' : true
+ },
+ 'Delivered' :{
+ 'location' : 'xml',
+ 'sentAs' : 'Delivered'
+ },
+ 'Owner' : owner,
+ 'Grants' : grants
+ },
+ },
+ 'DeleteObject' : {
+ 'httpMethod' : 'DELETE',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'VersionId' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'versionId',
+ },
+ },
+ },
+ 'DeleteObjectOutput' : {
+ 'parameters' : {
+ 'VersionId' : {
+ 'location' : 'header',
+ 'sentAs' : 'version-id',
+ 'withPrefix' : true
+ },
+ 'DeleteMarker' : {
+ 'location' : 'header',
+ 'sentAs' : 'delete-marker',
+ 'withPrefix' : true
+ },
+ },
+ },
+ 'DeleteObjects' : {
+ 'httpMethod' : 'POST',
+ 'urlPath' : 'delete',
+ 'data' : {
+ 'xmlRoot' : 'Delete',
+ 'md5' : true
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Quiet' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Quiet',
+ },
+ 'Objects' : {
+ 'required' : true,
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'Object',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Key' : {
+ 'sentAs' : 'Key',
+ },
+ 'VersionId' : {
+ 'sentAs' : 'VersionId',
+ },
+ },
+ },
+ },
+ },
+ },
+ 'DeleteObjectsOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'DeleteResult',
+ },
+ 'parameters' : {
+ 'Deleteds' : {
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'Deleted',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Key' : {
+ 'sentAs' : 'Key',
+ },
+ 'VersionId' : {
+ 'sentAs' : 'VersionId',
+ },
+ 'DeleteMarker' : {
+ 'sentAs' : 'DeleteMarker',
+ },
+ 'DeleteMarkerVersionId' : {
+ 'sentAs' : 'DeleteMarkerVersionId',
+ },
+ }
+ },
+ },
+ 'Errors' : {
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'Error',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'Key' : {
+ 'sentAs' : 'Key',
+ },
+ 'VersionId' : {
+ 'sentAs' : 'VersionId',
+ },
+ 'Code' : {
+ 'sentAs' : 'Code',
+ },
+ 'Message' : {
+ 'sentAs' : 'Message',
+ },
+ }
+ },
+ },
+ },
+ },
+
+ 'InitiateMultipartUpload' : {
+ 'httpMethod' : 'POST',
+ 'urlPath' : 'uploads',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'ACL' : {
+ 'location' : 'header',
+ 'sentAs' : 'acl',
+ 'withPrefix' : true
+ },
+ 'GrantRead' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-read',
+ 'withPrefix' : true,
+ },
+ 'GrantReadAcp' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-read-acp',
+ 'withPrefix' : true,
+ },
+ 'GrantWriteAcp' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-write-acp',
+ 'withPrefix' : true,
+ },
+ 'GrantFullControl' : {
+ 'location' : 'header',
+ 'sentAs' : 'grant-full-control',
+ 'withPrefix' : true,
+ },
+ 'StorageClass' : {
+ 'location' : 'header',
+ 'sentAs' : 'storage-class',
+ 'withPrefix' : true
+ },
+ 'Metadata' : {
+ 'type' : 'object',
+ 'location' : 'header',
+ 'sentAs' : 'meta-',
+ 'withPrefix' : true
+ },
+ 'WebsiteRedirectLocation' : {
+ 'location' : 'header',
+ 'sentAs' : 'website-redirect-location',
+ 'withPrefix' : true
+ },
+ 'Expires' : {
+ 'location' : 'header',
+ 'sentAs' : 'expires',
+ 'type' : 'number',
+ 'withPrefix' : true
+ },
+ 'ContentType' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-Type'
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true,
+ 'type' : 'adapter'
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key',
+ 'type' : 'password',
+ 'withPrefix' : true
+ },
+ },
+ },
+ 'InitiateMultipartUploadOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'InitiateMultipartUploadResult',
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Bucket',
+ },
+ 'Key' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Key',
+ },
+ 'UploadId' : {
+ 'location' : 'xml',
+ 'sentAs' : 'UploadId',
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKeyMd5' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key-MD5',
+ 'withPrefix' : true
+ }
+ },
+ },
+ 'ListMultipartUploads' : {
+ 'httpMethod' : 'GET',
+ 'urlPath' : 'uploads',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Delimiter' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'delimiter',
+ },
+ 'KeyMarker' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'key-marker',
+ },
+ 'MaxUploads' : {
+ 'type' : 'number',
+ 'location' : 'urlPath',
+ 'sentAs' : 'max-uploads',
+ },
+ 'Prefix' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'prefix',
+ },
+ 'UploadIdMarker' : {
+ 'location' : 'urlPath',
+ 'sentAs' : 'upload-id-marker',
+ },
+ },
+ },
+ 'ListMultipartUploadsOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'ListMultipartUploadsResult',
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Bucket',
+ },
+ 'KeyMarker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'KeyMarker',
+ },
+ 'UploadIdMarker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'UploadIdMarker',
+ },
+ 'NextKeyMarker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'NextKeyMarker',
+ },
+ 'Prefix' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Prefix',
+ },
+ 'Delimiter' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Delimiter',
+ },
+ 'NextUploadIdMarker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'NextUploadIdMarker',
+ },
+ 'MaxUploads' : {
+ 'location' : 'xml',
+ 'sentAs' : 'MaxUploads',
+ },
+ 'IsTruncated' : {
+ 'location' : 'xml',
+ 'sentAs' : 'IsTruncated',
+ },
+ 'Uploads' : {
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'Upload',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'UploadId' : {
+ 'sentAs' : 'UploadId',
+ },
+ 'Key' : {
+ 'sentAs' : 'Key',
+ },
+ 'Initiated' : {
+ 'sentAs' : 'Initiated',
+ },
+ 'StorageClass' : {
+ 'sentAs' : 'StorageClass',
+ },
+ 'Owner' : owner,
+ 'Initiator' : initiator
+ },
+ },
+ },
+ 'CommonPrefixes' : commonPrefixes
+ },
+ },
+ 'UploadPart' : {
+ 'httpMethod' : 'PUT',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'PartNumber' : {
+ 'required' : true,
+ 'type' : 'number',
+ 'location' : 'urlPath',
+ 'sentAs' : 'partNumber',
+ },
+ 'UploadId' : {
+ 'required' : true,
+ 'location' : 'urlPath',
+ 'sentAs' : 'uploadId',
+ },
+ 'ContentMD5' : {
+ 'location' : 'header',
+ 'sentAs' : 'Content-MD5',
+ },
+ 'Body' : {
+ 'location' : 'body',
+ },
+ 'SourceFile' : {
+ 'type' : 'srcFile',
+ },
+ 'Offset' : {
+ 'type' : 'plain'
+ },
+ 'PartSize' : {
+ 'type' : 'plain'
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key',
+ 'type' : 'password',
+ 'withPrefix' : true
+ }
+ },
+ },
+ 'UploadPartOutput' : {
+ 'parameters' : {
+ 'ETag' : {
+ 'location' : 'header',
+ 'sentAs' : 'etag',
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKeyMd5' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key-MD5',
+ 'withPrefix' : true
+ }
+ },
+ },
+ 'ListParts' : {
+ 'httpMethod' : 'GET',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'UploadId' : {
+ 'required' : true,
+ 'location' : 'urlPath',
+ 'sentAs' : 'uploadId',
+ },
+ 'MaxParts' : {
+ 'type' : 'number',
+ 'location' : 'urlPath',
+ 'sentAs' : 'max-parts',
+ },
+ 'PartNumberMarker' : {
+ 'type' : 'number',
+ 'location' : 'urlPath',
+ 'sentAs' : 'part-number-marker',
+ },
+ },
+ },
+ 'ListPartsOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'ListPartsResult',
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Bucket',
+ },
+ 'Key' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Key',
+ },
+ 'UploadId' : {
+ 'location' : 'xml',
+ 'sentAs' : 'UploadId',
+ },
+ 'PartNumberMarker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'PartNumberMarker',
+ },
+ 'NextPartNumberMarker' : {
+ 'location' : 'xml',
+ 'sentAs' : 'NextPartNumberMarker',
+ },
+ 'MaxParts' : {
+ 'location' : 'xml',
+ 'sentAs' : 'MaxParts',
+ },
+ 'IsTruncated' : {
+ 'location' : 'xml',
+ 'sentAs' : 'IsTruncated',
+ },
+ 'StorageClass' : {
+ 'location' : 'xml',
+ 'sentAs' : 'StorageClass',
+ },
+ 'Initiator':initiator,
+ 'Owner' : owner,
+ 'Parts' : {
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'Part',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'PartNumber' : {
+ 'sentAs' : 'PartNumber',
+ },
+ 'LastModified' : {
+ 'type' : 'date',
+ 'sentAs' : 'LastModified',
+ },
+ 'ETag' : {
+ 'sentAs' : 'ETag',
+ },
+ 'Size' : {
+ 'sentAs' : 'Size',
+ },
+ },
+ },
+ }
+ },
+ },
+ 'CopyPart' : {
+ 'httpMethod' : 'PUT',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'PartNumber' : {
+ 'required' : true,
+ 'location' : 'urlPath',
+ 'sentAs' : 'partNumber',
+ 'type' : 'number',
+ },
+ 'UploadId' : {
+ 'required' : true,
+ 'location' : 'urlPath',
+ 'sentAs' : 'uploadId',
+ },
+ 'CopySource' : {
+ 'required' : true,
+ 'location' : 'header',
+ 'sentAs' : 'copy-source',
+ 'skipEncoding' : true,
+ 'withPrefix' : true
+ },
+ 'CopySourceRange' : {
+ 'location' : 'header',
+ 'sentAs' : 'copy-source-range',
+ 'withPrefix' : true
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key',
+ 'type' : 'password',
+ 'withPrefix' : true
+ },
+ 'CopySourceSseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'copy-source-server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'CopySourceSseCKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'copy-source-server-side-encryption-customer-key',
+ 'type' : 'password',
+ 'withPrefix' : true
+ }
+ },
+ },
+ 'CopyPartOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'CopyPartResult',
+ },
+ 'parameters' : {
+ 'LastModified' : {
+ 'type' : 'date',
+ 'location' : 'xml',
+ 'sentAs' : 'LastModified',
+ },
+ 'ETag' : {
+ 'location' : 'xml',
+ 'sentAs' : 'ETag',
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKeyMd5' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key-MD5',
+ 'withPrefix' : true
+ }
+ },
+ },
+ 'AbortMultipartUpload' : {
+ 'httpMethod' : 'DELETE',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'UploadId' : {
+ 'required' : true,
+ 'location' : 'urlPath',
+ 'sentAs' : 'uploadId',
+ },
+ },
+ },
+
+ 'CompleteMultipartUpload' : {
+ 'httpMethod' : 'POST',
+ 'data' : {
+ 'xmlRoot' : 'CompleteMultipartUpload',
+ },
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'UploadId' : {
+ 'required' : true,
+ 'location' : 'urlPath',
+ 'sentAs' : 'uploadId',
+ },
+ 'Parts' : {
+ 'required' : true,
+ 'type' : 'array',
+ 'location' : 'xml',
+ 'sentAs' : 'Part',
+ 'items' : {
+ 'type' : 'object',
+ 'parameters' : {
+ 'PartNumber' : {
+ 'sentAs' : 'PartNumber',
+ },
+ 'ETag' : {
+ 'sentAs' : 'ETag',
+ },
+ },
+ },
+ },
+ },
+ },
+ 'CompleteMultipartUploadOutput' : {
+ 'data' : {
+ 'type' : 'xml',
+ 'xmlRoot' : 'CompleteMultipartUploadResult',
+ },
+ 'parameters' : {
+ 'VersionId' : {
+ 'location' : 'header',
+ 'sentAs' : 'version-id',
+ 'withPrefix' : true
+ },
+ 'Location' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Location',
+ },
+ 'Bucket' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Bucket',
+ },
+ 'Key' : {
+ 'location' : 'xml',
+ 'sentAs' : 'Key',
+ },
+ 'ETag' : {
+ 'location' : 'xml',
+ 'sentAs' : 'ETag',
+ },
+ 'SseKms' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption',
+ 'withPrefix' : true
+ },
+ 'SseKmsKey' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-kms-key-id',
+ 'withPrefix' : true
+ },
+ 'SseC' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-algorithm',
+ 'withPrefix' : true
+ },
+ 'SseCKeyMd5' :{
+ 'location' : 'header',
+ 'sentAs' : 'server-side-encryption-customer-key-MD5',
+ 'withPrefix' : true
+ }
+ },
+ },
+
+ 'OptionsObject' : {
+ 'httpMethod' : 'OPTIONS',
+ 'parameters' : {
+ 'Bucket' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Key' : {
+ 'required' : true,
+ 'location' : 'uri',
+ },
+ 'Origin' : {
+ 'required' : true,
+ 'location' : 'header',
+ 'sentAs' : 'Origin',
+ },
+ 'AccessControlRequestMethods' : {
+ 'required' : true,
+ 'type' : 'array',
+ 'location' : 'header',
+ 'sentAs' : 'Access-Control-Request-Method',
+ 'items' : {
+ 'type' : 'string',
+ },
+ },
+ 'AccessControlRequestHeaders' : {
+ 'type' : 'array',
+ 'location' : 'header',
+ 'sentAs' : 'Access-Control-Request-Headers',
+ 'items' : {
+ 'type' : 'string',
+ },
+ },
+ },
+ },
+ 'OptionsObjectOutput' : {
+ 'parameters' : {
+ 'AllowOrigin' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-origin',
+ },
+ 'AllowHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-headers',
+ },
+ 'AllowMethod' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-allow-methods',
+ },
+ 'ExposeHeader' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-expose-headers',
+ },
+ 'MaxAgeSeconds' : {
+ 'location' : 'header',
+ 'sentAs' : 'access-control-max-age',
+ },
+ },
+ }
+};
+
+
+module.exports = operations;
\ No newline at end of file
diff --git a/lib/obs-sdk-3.0.0/utils.js b/lib/obs-sdk-3.0.0/utils.js
new file mode 100644
index 0000000..32ad198
--- /dev/null
+++ b/lib/obs-sdk-3.0.0/utils.js
@@ -0,0 +1,2026 @@
+'use strict';
+
+const crypto = require('crypto');
+const fs = require('fs');
+const events = require('events');
+const httpLib = require('http');
+const httpsLib = require('https');
+const xml2js = require('xml2js');
+const urlLib = require('url');
+const pathLib = require('path');
+const streamLib = require('stream');
+const obsModel = require('./obsModel');
+const v2Model = require('./v2Model');
+
+const CONTENT_SHA256 = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
+const OBS_SDK_VERSION = '3.0.0';
+
+const mimeTypes = {
+ '7z' : 'application/x-7z-compressed',
+ 'aac' : 'audio/x-aac',
+ 'ai' : 'application/postscript',
+ 'aif' : 'audio/x-aiff',
+ 'asc' : 'text/plain',
+ 'asf' : 'video/x-ms-asf',
+ 'atom' : 'application/atom+xml',
+ 'avi' : 'video/x-msvideo',
+ 'bmp' : 'image/bmp',
+ 'bz2' : 'application/x-bzip2',
+ 'cer' : 'application/pkix-cert',
+ 'crl' : 'application/pkix-crl',
+ 'crt' : 'application/x-x509-ca-cert',
+ 'css' : 'text/css',
+ 'csv' : 'text/csv',
+ 'cu' : 'application/cu-seeme',
+ 'deb' : 'application/x-debian-package',
+ 'doc' : 'application/msword',
+ 'docx' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'dvi' : 'application/x-dvi',
+ 'eot' : 'application/vnd.ms-fontobject',
+ 'eps' : 'application/postscript',
+ 'epub' : 'application/epub+zip',
+ 'etx' : 'text/x-setext',
+ 'flac' : 'audio/flac',
+ 'flv' : 'video/x-flv',
+ 'gif' : 'image/gif',
+ 'gz' : 'application/gzip',
+ 'htm' : 'text/html',
+ 'html' : 'text/html',
+ 'ico' : 'image/x-icon',
+ 'ics' : 'text/calendar',
+ 'ini' : 'text/plain',
+ 'iso' : 'application/x-iso9660-image',
+ 'jar' : 'application/java-archive',
+ 'jpe' : 'image/jpeg',
+ 'jpeg' : 'image/jpeg',
+ 'jpg' : 'image/jpeg',
+ 'js' : 'text/javascript',
+ 'json' : 'application/json',
+ 'latex' : 'application/x-latex',
+ 'log' : 'text/plain',
+ 'm4a' : 'audio/mp4',
+ 'm4v' : 'video/mp4',
+ 'mid' : 'audio/midi',
+ 'midi' : 'audio/midi',
+ 'mov' : 'video/quicktime',
+ 'mp3' : 'audio/mpeg',
+ 'mp4' : 'video/mp4',
+ 'mp4a' : 'audio/mp4',
+ 'mp4v' : 'video/mp4',
+ 'mpe' : 'video/mpeg',
+ 'mpeg' : 'video/mpeg',
+ 'mpg' : 'video/mpeg',
+ 'mpg4' : 'video/mp4',
+ 'oga' : 'audio/ogg',
+ 'ogg' : 'audio/ogg',
+ 'ogv' : 'video/ogg',
+ 'ogx' : 'application/ogg',
+ 'pbm' : 'image/x-portable-bitmap',
+ 'pdf' : 'application/pdf',
+ 'pgm' : 'image/x-portable-graymap',
+ 'png' : 'image/png',
+ 'pnm' : 'image/x-portable-anymap',
+ 'ppm' : 'image/x-portable-pixmap',
+ 'ppt' : 'application/vnd.ms-powerpoint',
+ 'pptx' : 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+ 'ps' : 'application/postscript',
+ 'qt' : 'video/quicktime',
+ 'rar' : 'application/x-rar-compressed',
+ 'ras' : 'image/x-cmu-raster',
+ 'rss' : 'application/rss+xml',
+ 'rtf' : 'application/rtf',
+ 'sgm' : 'text/sgml',
+ 'sgml' : 'text/sgml',
+ 'svg' : 'image/svg+xml',
+ 'swf' : 'application/x-shockwave-flash',
+ 'tar' : 'application/x-tar',
+ 'tif' : 'image/tiff',
+ 'tiff' : 'image/tiff',
+ 'torrent' : 'application/x-bittorrent',
+ 'ttf' : 'application/x-font-ttf',
+ 'txt' : 'text/plain',
+ 'wav' : 'audio/x-wav',
+ 'webm' : 'video/webm',
+ 'wma' : 'audio/x-ms-wma',
+ 'wmv' : 'video/x-ms-wmv',
+ 'woff' : 'application/x-font-woff',
+ 'wsdl' : 'application/wsdl+xml',
+ 'xbm' : 'image/x-xbitmap',
+ 'xls' : 'application/vnd.ms-excel',
+ 'xlsx' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'xml' : 'application/xml',
+ 'xpm' : 'image/x-xpixmap',
+ 'xwd' : 'image/x-xwindowdump',
+ 'yaml' : 'text/yaml',
+ 'yml' : 'text/yaml',
+ 'zip' : 'application/zip',
+};
+
+
+const allowedResourceParameterNames = [
+ 'acl',
+ 'backtosource',
+ 'policy',
+ 'torrent',
+ 'logging',
+ 'location',
+ 'storageinfo',
+ 'quota',
+ 'storageclass',
+ 'storagepolicy',
+ 'requestpayment',
+ 'versions',
+ 'versioning',
+ 'versionid',
+ 'uploads',
+ 'uploadid',
+ 'partnumber',
+ 'website',
+ 'notification',
+ 'replication',
+ 'lifecycle',
+ 'deletebucket',
+ 'delete',
+ 'cors',
+ 'restore',
+ 'tagging',
+ 'append',
+ 'position',
+ 'response-content-type',
+ 'response-content-language',
+ 'response-expires',
+ 'response-cache-control',
+ 'response-content-disposition',
+ 'response-content-encoding',
+ 'x-image-process',
+ 'x-oss-process'
+];
+
+
+const allowedResponseHttpHeaderMetadataNames = [
+ 'content-type',
+ 'content-md5',
+ 'content-length',
+ 'content-language',
+ 'expires',
+ 'origin',
+ 'cache-control',
+ 'content-disposition',
+ 'content-encoding',
+ 'x-default-storage-class',
+ 'location',
+ 'date',
+ 'etag',
+ 'host',
+ 'last-modified',
+ 'content-range',
+ 'x-reserved',
+ 'access-control-allow-origin',
+ 'access-control-allow-headers',
+ 'access-control-max-age',
+ 'access-control-allow-methods',
+ 'access-control-expose-headers',
+ 'connection'
+];
+
+const commonHeaders = {
+ 'content-length' : 'ContentLength',
+ 'date' : 'Date',
+ 'x-reserved' : 'Reserved'
+};
+
+const obsAllowedStorageClass = ['STANDARD', 'WARM', 'COLD'];
+
+const v2AllowedStorageClass = ['STANDARD', 'STANDARD_IA', 'GLACIER'];
+
+const obsAllowedAcl = ['private', 'public-read', 'public-read-write', 'public-read-delivered', 'public-read-write-delivered'];
+
+const v2AllowedAcl = ['private', 'public-read', 'public-read-write', 'authenticated-read', 'bucket-owner-read', 'bucket-owner-full-control', 'log-delivery-write'];
+
+const obsAllowedUri = ['Everyone'];
+
+const v2AllowedUri = ['http://acs.amazonaws.com/groups/global/AllUsers', 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers', 'http://acs.amazonaws.com/groups/s3/LogDelivery'];
+
+const obsAllowedEvent = ['ObjectCreated:*', 'ObjectCreated:Put', 'ObjectCreated:Post', 'ObjectCreated:Copy',
+ 'ObjectCreated:CompleteMultipartUpload', 'ObjectRemoved:*', 'ObjectRemoved:Delete', 'ObjectRemoved:DeleteMarkerCreated'];
+const v2AllowedEvent = ['s3:ObjectCreated:*', 's3:ObjectCreated:Put', 's3:ObjectCreated:Post', 's3:ObjectCreated:Copy',
+ 's3:ObjectCreated:CompleteMultipartUpload', 's3:ObjectRemoved:*', 's3:ObjectRemoved:Delete', 's3:ObjectRemoved:DeleteMarkerCreated'];
+
+function encodeURIWithSafe(str, safe, skipEncoding){
+ str = String(str);
+ if(str.length === 0){
+ return '';
+ }
+ if(skipEncoding){
+ return str;
+ }
+ let ret;
+ if(safe){
+ ret = [];
+ for(let i=0;i=0 ? str[i] : encodeURIComponent(str[i]));
+ }
+ ret = ret.join('');
+ }else{
+ ret = encodeURIComponent(str);
+ }
+ return ret.replace(/!/g, '%21')
+ .replace(/~/g,'%7E')
+ .replace(/\*/g, '%2A')
+ .replace(/'/g, '%27')
+ .replace(/\(/g, '%28')
+ .replace(/\)/g, '%29');
+}
+
+function headerTostring(obj){
+ return JSON ? JSON.stringify(obj) : '';
+}
+
+function parseObjectFromHeaders(sentAs, headers){
+ var metadata = {};
+ for(let key in headers){
+ let k = String(key).toLowerCase();
+ if(k.indexOf(sentAs) === 0){
+ metadata[k.slice(sentAs.length)] = headers[key];
+ }
+ }
+ return metadata;
+}
+
+function mkdirsSync(dirname){
+ return fs.existsSync(dirname) ? true : (mkdirsSync(pathLib.dirname(dirname)) ? fs.mkdirSync(dirname) : false);
+}
+
+function isArray(obj){
+ return Object.prototype.toString.call(obj) === '[object Array]';
+}
+
+function isObject(obj){
+ return Object.prototype.toString.call(obj) === '[object Object]';
+}
+
+function utcToLocaleString(utcDate){
+ return utcDate ? new Date(Date.parse(utcDate)).toLocaleString() : '';
+}
+
+function makeObjFromXml(xml, bc){
+ xml2js.parseString(xml, {explicitArray:false, ignoreAttrs:true}, function(err, result){
+ if(err){
+ bc(err, null);
+ return;
+ }
+ bc(null, result);
+ });
+}
+
+
+function getExpireDate(utcDateStr){
+ var date = new Date(Date.parse(utcDateStr));
+ var hour = date.getUTCHours();
+ var min = date.getUTCMinutes();
+ var sec = date.getUTCSeconds();
+ var day = date.getUTCDate();
+ var moth = date.getUTCMonth() + 1;
+ var year = date.getUTCFullYear();
+ var shortDate = '';
+ var longDate = '';
+ var expireDate = '';
+ expireDate += year + '-';
+
+ if(moth < 10){
+ expireDate += '0';
+ }
+ expireDate += moth + '-';
+
+ if(day < 10){
+ expireDate += '0';
+ }
+ expireDate += day + 'T';
+
+ if(hour < 10){
+ expireDate += '0';
+ }
+ expireDate += hour + ':';
+
+ if(min < 10){
+ expireDate += '0';
+ }
+ expireDate += min + ':';
+
+ if(sec < 10){
+ expireDate += '0';
+ }
+ expireDate += sec + 'Z';
+ return expireDate;
+}
+
+function getDates(utcDateStr){
+ var date = new Date(Date.parse(utcDateStr));
+ var hour = date.getUTCHours();
+ var min = date.getUTCMinutes();
+ var sec = date.getUTCSeconds();
+ var day = date.getUTCDate();
+ var moth = date.getUTCMonth() + 1;
+ var year = date.getUTCFullYear();
+ var shortDate = '';
+ var longDate = '';
+ shortDate += year;
+
+ if(moth < 10){
+ shortDate += '0';
+ }
+ shortDate += moth;
+
+ if(day < 10){
+ shortDate += '0';
+ }
+ shortDate += day;
+
+ longDate += shortDate + 'T';
+ if(hour < 10){
+ longDate += '0';
+ }
+ longDate += hour;
+
+ if(min < 10){
+ longDate += '0';
+ }
+ longDate += min;
+
+ if(sec < 10){
+ longDate += '0';
+ }
+ longDate += sec + 'Z';
+ return [shortDate, longDate];
+}
+
+function getSignedAndCanonicalHeaders(header){
+ var arrheadKey = [];
+ var arrhead = {};
+ for(let key in header){
+ arrheadKey.push(key.toLowerCase());
+ arrhead[key.toLowerCase()] = header[key];
+ }
+ arrheadKey = arrheadKey.sort();
+ var signedHeaders = '';
+ var canonicalHeaders = '';
+ for(let i = 0; i < arrheadKey.length; i++){
+ if(i !== 0){
+ signedHeaders += ';';
+ }
+ signedHeaders += arrheadKey[i];
+ canonicalHeaders += arrheadKey[i] + ':' + arrhead[arrheadKey[i]] + '\n';
+ }
+ return [signedHeaders, canonicalHeaders];
+}
+
+function createV4Signature(shortDate, sk, region, stringToSign){
+ var dateKey = crypto.createHmac('sha256', 'AWS4' + sk).update(shortDate).digest();
+ var dateRegionKey = crypto.createHmac('sha256', dateKey).update(region).digest();
+ var dateRegionServiceKey = crypto.createHmac('sha256', dateRegionKey).update('s3').digest();
+ var signingKey = crypto.createHmac('sha256',dateRegionServiceKey).update('aws4_request').digest();
+ return crypto.createHmac('sha256',signingKey).update(stringToSign).digest('hex');
+}
+
+function getV4Signature(shortDate, longDate, sk, region, canonicalRequest){
+ var scop = shortDate + '/' + region + '/s3/aws4_request';
+ var stringToSign = 'AWS4-HMAC-SHA256' + '\n';
+ stringToSign += longDate + '\n';
+ stringToSign += scop + '\n';
+ stringToSign += crypto.createHash('sha256').update(canonicalRequest).digest('hex');
+ return createV4Signature(shortDate, sk, region, stringToSign);
+}
+
+
+function Utils(logger) {
+ this.log = logger;
+ this.ak = null;
+ this.sk = null;
+ this.securityToken = null;
+ this.isSecure = true;
+ this.server = null;
+ this.pathStyle = false;
+ this.signature = 'v2';
+ this.region = 'region';
+ this.port = null;
+ this.maxRetryCount = 3;
+ this.timeout = 60;
+ this.sslVerify = false;
+ this.httpAgent = false;
+ this.httpsAgent = false;
+ this.obsSdkVersion = OBS_SDK_VERSION;
+}
+
+Utils.prototype.encodeURIWithSafe = encodeURIWithSafe;
+
+Utils.prototype.mimeTypes = mimeTypes;
+
+Utils.prototype.close = function(){
+ if(this.httpAgent){
+ this.httpAgent.destroy();
+ }
+ if(this.httpsAgent){
+ this.httpsAgent.destroy();
+ }
+};
+
+Utils.prototype.refresh = function(ak, sk, securityToken){
+ this.ak = ak ? String(ak).trim() : null;
+ this.sk = sk ? String(sk).trim(): null;
+ this.securityToken = securityToken ? String(securityToken).trim() : null;
+};
+
+Utils.prototype.initFactory = function(ak, sk, isSecure,
+ server, pathStyle, signature, region, port, maxRetryCount, timeout, sslVerify, long_conn_param, securityToken){
+
+ this.refresh(ak, sk, securityToken);
+
+ if (!server) {
+ throw new Error('Server is not set');
+ }
+ server = String(server).trim();
+
+ if(server.indexOf('https://') === 0){
+ server = server.slice('https://'.length);
+ isSecure = true;
+ }else if(server.indexOf('http://') === 0){
+ server = server.slice('http://'.length);
+ isSecure = false;
+ }
+
+ let index = server.lastIndexOf('/');
+ while(index >= 0){
+ server = server.slice(0, index);
+ index = server.lastIndexOf('/');
+ }
+
+ index = server.indexOf(':');
+ if(index >= 0){
+ port = server.slice(index + 1);
+ server = server.slice(0, index);
+ }
+ this.server = server;
+
+ if(/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/.test(this.server)){
+ pathStyle = true;
+ }
+
+ if (isSecure !== undefined) {
+ this.isSecure = Boolean(isSecure);
+ }
+ if (pathStyle !== undefined) {
+ this.pathStyle = Boolean(pathStyle);
+ }
+ if (signature !== undefined) {
+ this.signature = String(signature).trim().toLowerCase();
+ }
+
+ if(this.signature === 'obs'){
+ this.headerPrefix = 'x-obs-';
+ this.headerMetaPrefix = 'x-obs-meta-';
+ this.authPrefix = 'OBS';
+ }else{
+ this.headerPrefix = 'x-amz-';
+ this.headerMetaPrefix = 'x-amz-meta-';
+ this.authPrefix = 'AWS';
+ }
+
+ if(region !== undefined){
+ this.region = String(region).trim();
+ }
+
+ this.port = port ? parseInt(port) : (this.isSecure ? 443 : 80);
+
+ if(maxRetryCount !== undefined){
+ this.maxRetryCount = parseInt(maxRetryCount);
+ }
+
+ if(timeout !== undefined){
+ this.timeout = parseInt(timeout);
+ }
+
+ if(sslVerify !== undefined){
+ this.sslVerify = sslVerify;
+ }
+
+ if(long_conn_param !== undefined && Number(long_conn_param) >= 0){
+ this.httpAgent = new httpLib.Agent({keepAlive : true, keepAliveMsecs : Number(long_conn_param) * 1000});
+ this.httpsAgent = new httpsLib.Agent({keepAlive : true, keepAliveMsecs : Number(long_conn_param) * 1000});
+ }
+};
+
+Utils.prototype.SseKmsAdapter = function(value){
+ value = value || '';
+ value = String(value);
+ let index = value.indexOf('aws:');
+ if(this.signature === 'obs'){
+ return index === 0 ? value.slice(4) : value;
+ }else{
+ return index === 0 ? value : 'aws:' + value;
+ }
+};
+
+Utils.prototype.BucketAdapter = function(value){
+ value = value || '';
+ value = String(value);
+ let index = value.indexOf('arn:aws:s3:::');
+ if(this.signature === 'obs'){
+ return index === 0 ? value.slice('arn:aws:s3:::'.length) : value;
+ }else{
+ return index === 0 ? value : 'arn:aws:s3:::' + value;
+ }
+};
+
+
+Utils.prototype.EventAdapter = function(value){
+ value = value || '';
+ value = String(value);
+ if(this.signature === 'obs'){
+ if(obsAllowedEvent.indexOf(value) >= 0){
+ return value;
+ }
+ if(v2AllowedEvent.indexOf(value) >= 0){
+ return value.substring(3);
+ }
+ }else{
+ if(v2AllowedEvent.indexOf(value) >= 0){
+ return value;
+ }
+ if(obsAllowedEvent.indexOf(value) >= 0){
+ return 's3:' + value;
+ }
+ }
+ return '';
+};
+
+Utils.prototype.URIAdapter = function(value){
+ value = value || '';
+ value = String(value);
+ if(this.signature === 'obs'){
+ if(obsAllowedUri.indexOf(value) >= 0){
+ return value;
+ }
+ if(value === 'AllUsers' || value === 'http://acs.amazonaws.com/groups/global/AllUsers'){
+ return 'Everyone';
+ }
+ }else{
+ if(v2AllowedUri.indexOf(value) >= 0){
+ return value;
+ }
+ if(value === 'Everyone' || value === 'AllUsers'){
+ return 'http://acs.amazonaws.com/groups/global/AllUsers';
+ }else if(value === 'AuthenticatedUsers'){
+ return 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers';
+ }else if(value === 'LogDelivery'){
+ return 'http://acs.amazonaws.com/groups/s3/LogDelivery';
+ }
+ }
+ return '';
+};
+
+
+Utils.prototype.StorageClassAdapter = function(value){
+ value = value || '';
+ value = String(value).toUpperCase();
+ if(this.signature === 'obs'){
+ if(obsAllowedStorageClass.indexOf(value) >= 0){
+ return value;
+ }
+ if(value === 'STANDARD_IA'){
+ return 'WARM';
+ }else if(value === 'GLACIER'){
+ return 'COLD';
+ }
+ }else{
+ if(v2AllowedStorageClass.indexOf(value) >= 0){
+ return value;
+ }
+ if(value === 'WARM'){
+ return 'STANDARD_IA';
+ }else if(value === 'COLD'){
+ return 'GLACIER';
+ }
+ }
+ return '';
+};
+
+Utils.prototype.ACLAdapter = function(value){
+ value = value || '';
+ value = String(value).toLowerCase();
+ if(this.signature === 'obs'){
+ if(obsAllowedAcl.indexOf(value) >= 0){
+ return value;
+ }
+ }else{
+ if(value === 'public-read-delivered'){
+ value = 'public-read';
+ }else if(value === 'public-read-write-delivered'){
+ value = 'public-read-write';
+ }
+
+ if(v2AllowedAcl.indexOf(value) >= 0){
+ return value;
+ }
+ }
+ return '';
+};
+
+
+Utils.prototype.toXml = function(mXml, xmlMeta, root, sentAs){
+ var xml = '';
+ if(root !== null){
+ xml += this.buildXml(mXml, xmlMeta, root, sentAs);
+ }else{
+ for (let key in xmlMeta){
+ if(key in mXml){
+ let meta = xmlMeta[key];
+ xml += this.buildXml(mXml, meta, key, meta.sentAs || key);
+ }
+ }
+ }
+ return xml;
+};
+
+Utils.prototype.buildXml = function(mXml, xmlMeta, key, sentAs){
+ var xml = '';
+ let type = xmlMeta.type;
+ if(type === 'array'){
+ for(let i = 0; i < mXml[key].length; i++){
+ if(xmlMeta.items.type === 'object'){
+ let result = this.toXml(mXml[key][i], xmlMeta.items.parameters, null);
+ if(result !== ''){
+ xml += '<' + sentAs + '>'+ result + '' + sentAs + '>';
+ }
+ }else if(xmlMeta.items.type === 'adapter'){
+ xml += '<' + sentAs + '>' + String(this[key + 'Adapter'](mXml[key][i])).replace(/&/g, '&').replace(/'/g, ''').replace(/"/g, '"') + '' + sentAs + '>';
+ }else if(xmlMeta.items.type !== 'array'){
+ xml += '<' + sentAs + '>'+ String(mXml[key][i]).replace(/&/g, '&').replace(/'/g, ''').replace(/"/g, '"') + '' + sentAs +'>';
+ }
+ }
+ }else if(type === 'object'){
+ let result = this.toXml(mXml[key], xmlMeta.parameters, null);
+ if(result !== ''){
+ xml += '<' + sentAs;
+ if('data' in xmlMeta){
+ if('xsiNamespace' in xmlMeta.data){
+ xml += ' xmlns:xsi="' + xmlMeta.data.xsiNamespace + '"';
+ }
+ if('xsiType' in xmlMeta.data){
+ xml += ' xsi:type="' + mXml[key][xmlMeta.data.xsiType] + '"';
+ }
+ }
+ xml += '>';
+ xml += result + '' + sentAs + '>';
+ }
+
+ }else if(type === 'adapter'){
+ xml += '<' + sentAs + '>' + String(this[key + 'Adapter'](mXml[key])).replace(/&/g, '&').replace(/'/g, ''').replace(/"/g, '"') + '' + sentAs + '>';
+ }else if(type !== 'ignore'){
+ xml += '<' + sentAs + '>' + String(mXml[key]).replace(/&/g, '&').replace(/'/g, ''').replace(/"/g, '"') + '' + sentAs + '>';
+ }
+ if(xml && xmlMeta.wrapper){
+ let _wrapper = xmlMeta.wrapper;
+ xml = '<' + _wrapper + '>' + xml + '' + _wrapper + '>';
+ }
+ return xml;
+};
+
+
+
+Utils.prototype.jsonToObject = function(model, obj, root){
+ var opt = {};
+ if(root !== null){
+ this.buildObject(model, obj, root, opt);
+ }else{
+ for(let key in model){
+ this.buildObject(model, obj, key, opt);
+ }
+ }
+ return opt;
+};
+
+Utils.prototype.buildObject = function(model, obj, key, opt){
+ if(isObject(obj)){
+ let flag = true;
+ let wrapper = model[key].wrapper;
+ if(wrapper && wrapper in obj){
+ obj = obj[wrapper];
+ flag = isObject(obj);
+ }
+ if(flag){
+ let sentAs = model[key].sentAs || key;
+ if(sentAs in obj){
+ if(model[key].type === 'object'){
+ opt[key] = this.jsonToObject(model[key].parameters, obj[sentAs], null);
+ }else if(model[key].type === 'array'){
+ let arr = [];
+ if(!isArray(obj[sentAs])){
+ arr[0] = model[key].items.type === 'object' ? this.jsonToObject(model[key].items.parameters, obj[sentAs], null) : obj[sentAs];
+ }else{
+ for (let i = 0; i < obj[sentAs].length; i++ ){
+ arr[i] = model[key].items.type === 'object' ? this.jsonToObject(model[key].items.parameters, obj[sentAs][i], null) : obj[sentAs][i];
+ }
+ }
+ opt[key] = arr;
+ }else if(model[key].type === 'date'){
+ opt[key] = utcToLocaleString(obj[sentAs]);
+ }else{
+ opt[key] = obj[sentAs];
+ }
+ }
+ }
+ }
+
+ if(opt[key] === undefined){
+ if(model[key].type === 'object'){
+ opt[key] = model[key].parameters ? this.jsonToObject(model[key].parameters, null, null) : {};
+ }else if(model[key].type === 'array'){
+ opt[key] = [];
+ }else{
+ opt[key] = '';
+ }
+ }
+};
+
+Utils.prototype.makeParam = function(methodName, param){
+ var model = this.signature === 'obs' ? obsModel[methodName] : v2Model[methodName];
+ var method = model.httpMethod;
+ var uri = '/';
+ var urlPath = '';
+ var xml = '';
+ var exheaders = {};
+ var opt = {};
+
+ if ('urlPath' in model){
+ urlPath += '?';
+ urlPath += model.urlPath;
+ }
+ for (let key in model.parameters){
+ let meta = model.parameters[key];
+ if (meta.require && !(key in param)){
+ opt.err = key + ' is a required element!';
+ if(this.log.isLevelEnabled('warn')){
+ this.log.runLog('warn', methodName, opt.err);
+ }
+ return opt;
+ }
+
+ if(param[key] !== null && param[key] !== undefined){
+
+ if(meta.type === 'srcFile' || meta.type === 'dstFile'){
+ opt[meta.type] = param[key];
+ continue;
+ }
+
+ if(meta.type === 'plain'){
+ opt[key] = param[key];
+ }
+
+ let sentAs = meta.sentAs || key;
+
+ if(meta.withPrefix){
+ sentAs = this.headerPrefix + sentAs;
+ }
+
+ if(meta.location === 'uri'){
+ if(uri !== '/'){
+ uri += '/';
+ }
+ uri += param[key];
+ }else if(meta.location === 'header'){
+ let safe = meta.encodingSafe || ' ;/?:@&=+$,';
+ if(meta.type === 'object'){
+ if(this.headerMetaPrefix === sentAs){
+ for(let item in param[key]){
+ let value = param[key][item];
+ item = String(item).trim().toLowerCase();
+ exheaders[item.indexOf(sentAs) === 0 ? item: sentAs + item] = encodeURIWithSafe(value, safe);
+ }
+ }
+ }else if(meta.type === 'array'){
+ let arr = [];
+ for(let i=0;i= 0)){
+ urlPath += sep + encodeURIWithSafe(sentAs, '/') + '=' + encodeURIWithSafe(String(value), '/');
+ }
+ }else if(meta.location === 'xml'){
+ let mxml = this.toXml(param, meta, key, sentAs);
+ if(mxml){
+ xml += mxml;
+ }
+ }else if(meta.location === 'body'){
+ xml = param[key];
+ }
+ }
+ }
+
+ if('data' in model && 'xmlRoot' in model.data){
+ if(xml || model.data.xmlAllowEmpty){
+ let xmlRoot = model.data.xmlRoot;
+ xml = '<' + xmlRoot + '>' + xml + '' + xmlRoot + '>';
+ }
+ }
+
+ exheaders.Host = this.server;
+
+ if(!this.pathStyle){
+ let uriList = uri.split('/');
+ if(uriList.length >= 2 && uriList[1]){
+ exheaders.Host = uriList[1] + '.' + exheaders.Host;
+ let requestUri = uri.replace(uriList[1], '');
+ if(requestUri.indexOf('//') === 0){
+ requestUri = requestUri.slice(1);
+ }
+ if(this.signature === 'v4'){
+ uri = requestUri;
+ }else if(requestUri === '/'){
+ uri += '/';
+ }
+ opt.requestUri = encodeURIWithSafe(requestUri, '/');
+ }
+ }
+ opt.method = method;
+ opt.uri = encodeURIWithSafe(uri, '/');
+ opt.urlPath = urlPath;
+ if(xml){
+ if(!(xml instanceof streamLib.Readable)){
+ let body = Buffer.from(String(xml), 'utf8');
+ if(model.data && model.data.md5){
+ exheaders['Content-MD5'] = this.bufMD5(body);
+ }
+ exheaders['Content-Length'] = body.length === 0 ? '0' : String(body.length);
+ }
+ opt.xml = xml;
+ if(this.log.isLevelEnabled('debug')){
+ this.log.runLog('debug', methodName, 'request content:' + xml);
+ }
+ }
+ opt.headers = exheaders;
+
+ if('srcFile' in opt){
+ if (!fs.existsSync(opt.srcFile)) {
+ opt.err = 'the file [' + opt.srcFile + '] is not exist!';
+ if(this.log.isLevelEnabled('error')){
+ this.log.runLog('error', methodName, opt.err);
+ }
+ return opt;
+ }
+
+ let fileSize = fs.statSync(opt.srcFile).size;
+ if ('Content-Length' in opt.headers || 'PartSize' in opt || 'Offset' in opt) {
+ let offset = opt.Offset;
+ offset = (offset && offset >= 0 && offset < fileSize) ? offset : 0;
+ let partSize;
+ if('PartSize' in opt){
+ partSize = opt.PartSize;
+ }else if('Content-Length' in opt.headers){
+ partSize = parseInt(opt.headers['Content-Length']);
+ }else{
+ partSize = fileSize;
+ }
+ partSize = (partSize && partSize > 0 && partSize <= fileSize - offset) ? partSize : fileSize - offset;
+ opt.PartSize = partSize;
+ opt.Offset = offset;
+ opt.headers['Content-Length'] = String(opt.PartSize);
+ }
+ }
+
+ return opt;
+};
+
+Utils.prototype.sendRequest = function(funcName, opt, backcall, count){
+ if(count === undefined){
+ count = 1;
+ }
+ let that = this;
+ let readable = opt.xml instanceof streamLib.Readable;
+ that.makeRequest(funcName, opt, function(err,msg){
+ if(err && !readable && msg !== 'PREMATURE_END'
+ && msg !== 'SELF_SIGNED_CERT_IN_CHAIN' && msg !== 'DEPTH_ZERO_SELF_SIGNED_CERT' && count <= that.maxRetryCount){
+ that.sendRequest(funcName, opt, backcall, count + 1);
+ }else if(err === 'redirect' && !readable && msg){
+ let uri = urlLib.parse(msg);
+ opt.headers.Host = uri.hostname;
+ opt.protocol = uri.protocol;
+ opt.port = uri.port || (opt.protocol.toLowerCase().indexOf('https') === 0 ? 443 : 80);
+ that.sendRequest(funcName, opt, backcall);
+ }else{
+ backcall(err,msg);
+ }
+ });
+};
+
+Utils.prototype.doAuth = function(opt, methodName) {
+ var interestHeader = ['Content-MD5', 'Content-Type', 'Date'];
+ var log = this.log;
+ var stringToSign = opt.method + '\n';
+ for(let i=0;i= 0){
+ urlPath += urlPath === '' ? '?' : '&';
+ urlPath += key;
+ if(listvar.length === 2 && listvar[1]){
+ urlPath += '=' + decodeURIComponent(listvar[1]);
+ }
+ }
+ }
+ path += urlPath;
+ }
+ stringToSign += path;
+ if(log.isLevelEnabled('debug')){
+ log.runLog('debug',methodName, 'stringToSign:' + stringToSign);
+ }
+ opt.headers.Authorization = this.authPrefix + ' ' + this.ak + ':' + crypto.createHmac('sha1', this.sk).update(stringToSign).digest('base64');
+};
+
+Utils.prototype.v4Auth = function(opt, methodName){
+ opt.headers[this.headerPrefix + 'content-sha256'] = CONTENT_SHA256;
+ var header = opt.headers;
+ var log = this.log;
+ var shortDate = null;
+ var longDate = null;
+
+ if(this.headerPrefix + 'date' in header){
+ longDate = header[this.headerPrefix + 'date'];
+ shortDate = longDate.slice(0, longDate.indexOf('T'));
+ }else{
+ let dates = getDates(header.Date);
+ shortDate = dates[0];
+ longDate = dates[1];
+ }
+
+ var credential = this.ak + '/' + shortDate + '/' + this.region + '/s3/aws4_request';
+
+ var signedAndCanonicalHeaders = getSignedAndCanonicalHeaders(header);
+
+ var signedHeaders = signedAndCanonicalHeaders[0];
+ var canonicalHeaders = signedAndCanonicalHeaders[1];
+
+ var canonicalQueryString = '';
+ if(opt.urlPath){
+ let path = opt.urlPath.slice(1);
+ let arrPath = path.split('&').sort();
+ for(let i=0;i= 300 && serverback.statusCode < 400 && serverback.statusCode !== 304 && !readable){
+ let location = headers.location || headers.Location;
+ if(location){
+ if(log.isLevelEnabled('warn')){
+ let err = 'http code is 3xx, need to redirect to ' + location;
+ log.runLog('warn', methodName, err);
+ }
+ bc('redirect', location);
+ }else{
+ let err = 'get redirect code 3xx, but no location in headers';
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, err);
+ }
+ bc(err, null);
+ }
+ }else if(serverback.statusCode < 300){
+ if(dstFile){
+ let fileDir = pathLib.dirname(dstFile);
+ if(mkdirsSync(fileDir)){
+ let stream = fs.createWriteStream(dstFile);
+ serverback.on('error', function(err){
+ stream.end();
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'get response stream error [' + headerTostring(err) + ']');
+ }
+ bc(err, null);
+ }).on('end', function(){
+ stream.end();
+ that.contrustCommonMsg(opt, obj, headers, methodName);
+ if(log.isLevelEnabled('debug')){
+ log.runLog('debug', methodName, 'exec interface ' + methodName + ' finish, Status:' + opt['CommonMsg']['Status'] + ', Code: ,Message: ');
+ }
+ }).pipe(stream);
+
+ stream.on('close', function(){
+ if(opt.InterfaceResult && opt.InterfaceResult.ContentLength !== undefined){
+ if(fs.existsSync(dstFile)){
+ let fstat = fs.statSync(dstFile);
+ if(fstat.size !== parseInt(opt.InterfaceResult.ContentLength)){
+ bc('premature end of Content-Length delimiter message body (expected:' + opt.InterfaceResult.ContentLength + '; received:' + fstat.size + ')', 'PREMATURE_END');
+ return;
+ }
+ }
+ }
+ doLog();
+ });
+ }else{
+ bc('failed to create file:' + dstFile, null);
+ }
+ }else if(('data' in model) && saveAsStream){
+ that.contrustCommonMsg(opt, obj, headers, methodName);
+ if(log.isLevelEnabled('debug')){
+ let respMsg = 'Status: ' + opt.CommonMsg.Status + ', headers: ' + headerTostring(headers);
+ log.runLog('debug', methodName, respMsg);
+ }
+
+ for (let key in obj){
+ if(obj[key].location === 'body'){
+ if(opt.InterfaceResult && opt.InterfaceResult.ContentLength !== undefined){
+ let contentLength = parseInt(opt.InterfaceResult.ContentLength);
+ serverback.$readedCount = 0;
+ serverback.$expectedCount = contentLength;
+ serverback.on('data', function(data){
+ serverback.$readedCount += data.length;
+ }).on('end', function(){
+ let expectedCount = serverback.$expectedCount;
+ let readedCount = serverback.$readedCount;
+ delete serverback.$readedCount;
+ delete serverback.$expectedCount;
+ if(expectedCount !== readedCount){
+ throw new Error('premature end of Content-Length delimiter message body (expected:' + serverback.$expectedCount + '; received:' + serverback.$readedCount + ')');
+ }
+ });
+ }
+ opt.InterfaceResult[key] = serverback;
+ break;
+ }
+ }
+ doLog();
+ }else{
+ let body = [];
+ serverback.on('data', function(data) {
+ body.push(data);
+ }).on('error', function(err){
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'get response stream error [' + headerTostring(err) + ']');
+ }
+ bc(err, null);
+ }).on('end', function() {
+ that.contrustCommonMsg(opt, obj, headers, methodName);
+ body = Buffer.concat(body);
+
+ if(log.isLevelEnabled('debug')){
+ let respMsg = 'Status: ' + opt.CommonMsg.Status + ', headers: ' + headerTostring(headers);
+ if(body){
+ respMsg += 'body length: ' + body.length;
+ log.runLog('debug', methodName, 'response body length:' + body.length);
+ }
+ log.runLog('debug', methodName, respMsg);
+ }
+
+ if(body && ('data' in model)){
+ if(model.data.type === 'xml'){
+ makeObjFromXml(body, function(err,result){
+ if(err){
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'change xml to json err [' + headerTostring(err) + ']' );
+ }
+ bc(err, null);
+ return;
+ }
+ let tempResult = result;
+ if(model.data.xmlRoot && (model.data.xmlRoot in tempResult)){
+ tempResult = result[model.data.xmlRoot];
+ }
+ if(isObject(tempResult)){
+ for (let key in obj){
+ if(obj[key].location === 'xml'){
+ opt.InterfaceResult[key] = that.jsonToObject(obj, tempResult, key)[key];
+ }
+ }
+ }
+ });
+ }else if(model.data.type === 'body'){
+ for (let key in obj){
+ if(obj[key].location === 'body'){
+ opt.InterfaceResult[key] = body;
+ break;
+ }
+ }
+ }
+ }
+ doLog();
+ });
+ }
+ }else{
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'request error with http status code:' + serverback.statusCode);
+ }
+ let body = [];
+ serverback.on('data', function(data) {
+ body.push(data);
+ }).on('error', function(err){
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'get response stream error [' + headerTostring(err) + ']');
+ }
+ bc(err, null);
+ }).on('end', function() {
+ body = Buffer.concat(body);
+ if(log.isLevelEnabled('debug')){
+ let respMsg = 'Status: ' + opt.CommonMsg.Status + ', headers: ' + headerTostring(headers);
+ if(body !== ''){
+ respMsg += 'body: ' + body;
+ log.runLog('debug', methodName, 'response body :' + body);
+ }
+ log.runLog('debug', methodName, respMsg);
+ }
+
+ if(body){
+ makeObjFromXml(body, function(err, re){
+ if(err){
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'change xml to json err [' + headerTostring(err) + ']' );
+ }
+ bc(err,null);
+ return;
+ }
+ if(re && 'Error' in re){
+ let errMsg = re.Error;
+ opt.CommonMsg.Code = errMsg.Code;
+ opt.CommonMsg.Message = errMsg.Message;
+ opt.CommonMsg.HostId = errMsg.HostId;
+ opt.CommonMsg.RequestId = errMsg.RequestId;
+
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'request error with error code:' + opt.CommonMsg.Code + ', error message:' + opt.CommonMsg.Message + ', request id:' + opt.CommonMsg.RequestId);
+ }
+
+ }
+ doLog();
+ });
+ }else{
+ doLog();
+ }
+ });
+ }
+
+};
+
+Utils.prototype.makeRequest = function(methodName, opt, bc){
+ var log = this.log;
+ var body = opt.xml;
+ var readable = body instanceof streamLib.Readable;
+
+ var nowDate = new Date();
+ opt.headers.Date = nowDate.toUTCString();
+
+ delete opt.headers.Authorization;//retry bug fix
+
+ var ex = opt.headers;
+ var path = (opt.requestUri ? opt.requestUri : opt.uri) + opt.urlPath;
+ var method = opt.method;
+
+ if(this.ak && this.sk){
+ if(this.securityToken){
+ opt.headers[this.headerPrefix + 'security-token'] = this.securityToken;
+ }
+ if(this.signature === 'v4'){
+ this.v4Auth(opt, methodName);
+ }else{
+ this.doAuth(opt, methodName);
+ }
+ }
+
+ ex['User-Agent'] = 'obs-sdk-js/' + this.obsSdkVersion;
+
+ if(log.isLevelEnabled('info')){
+ log.runLog('info', methodName, 'prepare request parameters ok, then Send request to service start');
+ }
+
+ if(log.isLevelEnabled('debug')){
+ let header_msg = {};
+ for (let key in ex){
+ header_msg[key] = ex[key];
+ }
+ header_msg.Authorization = '****';
+
+ let msg = 'method:' + method + ', path:' + path + 'headers:' + headerTostring(header_msg);
+ if (body && !readable) {
+ msg += 'body:' + body;
+ }
+ log.runLog('debug', methodName, 'request msg:' + msg);
+ }
+
+ var reopt = {
+ method : method,
+ host : ex.Host,
+ port : opt.port || this.port,
+ path : path,
+ ca : !this.sslVerify || !fs.existsSync(String(this.sslVerify)) ? null : fs.readFileSync(String(this.sslVerify)),
+ checkServerIdentity: function (host, cert) {
+ return undefined;//do not verify hostname
+ },
+ rejectUnauthorized : Boolean(this.sslVerify),
+ headers : ex
+ };
+
+ var start = nowDate.getTime();
+
+ var _isSecure = opt.protocol ? opt.protocol.toLowerCase().indexOf('https') === 0 : this.isSecure;
+
+ reopt.agent = _isSecure ? this.httpsAgent : this.httpAgent;
+
+ var _http = _isSecure ? httpsLib : httpLib;
+
+ var req = _http.request(reopt);
+ req.setNoDelay(true);
+ req.setTimeout(this.timeout * 1000);
+
+ var that = this;
+
+ req.on('response', function(serverback) {
+ if(log.isLevelEnabled('info')){
+ log.runLog('info', methodName, 'http cost ' + (new Date().getTime() - start) + ' ms');
+ }
+ that.getRequest(methodName, serverback, opt.dstFile, bc, opt.SaveAsStream, readable);
+ }).on('error', function(err){
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'Send request to service error [' + headerTostring(err) + ']');
+ }
+ if(log.isLevelEnabled('info')){
+ log.runLog('info', methodName, 'http cost ' + (new Date().getTime() - start) + ' ms');
+ }
+ bc(err, null);
+ });
+
+ if(method in ['GET', 'HEAD', 'OPTIONS']){
+ req.end();
+ return;
+ }
+
+ if(body){
+ if(readable){
+ if('ContentLength' in opt){
+ let contentLength = parseInt(opt.ContentLength);
+ let writeCount = 0;
+ body.on('data', function(data){
+ if(writeCount >= contentLength){
+ req.end();
+ if(body.destroy){
+ body.destroy();
+ }
+ return;
+ }
+ if(contentLength - writeCount > data.length){
+ req.write(data, function(err){
+ if(err){
+ req.abort();
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'read stream to send error [' + err + ']');
+ }
+ bc(err, null);
+ return;
+ }
+ writeCount += data.length;
+ });
+ }else{
+ req.write(Buffer.from(data, 0, contentLength - writeCount), function(err){
+ if(err){
+ req.abort();
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'read stream to send error [' + err + ']');
+ }
+ bc(err, null);
+ return;
+ }
+ writeCount = contentLength;
+ });
+ }
+ });
+ }else{
+ body.pipe(req);
+ }
+ body.on('error',function(err){
+ req.abort();
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'read file to send error [' + headerTostring(err) + ']');
+ }
+ bc(err,null);
+ }).on('end', function(){
+ req.end();
+ });
+ }else{
+ req.end(String(body));
+ }
+ return;
+ }
+ if(!('srcFile' in opt)){
+ req.end();
+ return;
+ }
+
+ let offset = opt.Offset >= 0 ? opt.Offset : 0;
+ if('PartSize' in opt){
+ this.doSend(req, opt.srcFile, offset, parseInt(opt.PartSize), methodName, bc);
+ }else if('ContentLength' in opt){
+ this.doSend(req, opt.srcFile, offset, parseInt(opt.ContentLength), methodName, bc);
+ }else{
+ let stream = fs.createReadStream(opt.srcFile);
+ stream.on('error', function(err){
+ req.abort();
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'read file to send error [' + headerTostring(err) + ']');
+ }
+ bc(err, null);
+ }).on('end', function(){
+ req.end();
+ }).pipe(req);
+ }
+
+};
+
+Utils.prototype.doSend = function(req, srcFile, initPos, totalCount, methodName, bc){
+ var log = this.log;
+ fs.open(srcFile, 'r', function(err, fd){
+ if(err){
+ req.abort();
+ fs.close(fd,function(err){});
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'read file to send error [' + err + ']');
+ }
+ bc(err, null);
+ return;
+ }
+
+ var buffer = Buffer.alloc(65536);
+ var _doSend = function(sendPosition, sendCount){
+ if(sendCount >= totalCount){
+ req.end();
+ fs.close(fd,function(err){});
+ return;
+ }
+
+ var sendCountOnce = (totalCount - sendCount) > buffer.length ? buffer.length : totalCount - sendCount;
+
+ fs.read(fd, buffer, 0, sendCountOnce, sendPosition, function(err, bytes){
+ if (err){
+ req.abort();
+ fs.close(fd,function(err){});
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'read file to send error [' + err + ']');
+ }
+ bc(err, null);
+ return;
+ }
+ if(bytes <= 0){
+ req.end();
+ fs.close(fd, function(err){});
+ return;
+ }
+ req.write(buffer.slice(0, bytes), function(err){
+ if(err){
+ req.abort();
+ fs.close(fd,function(err){});
+ if(log.isLevelEnabled('error')){
+ log.runLog('error', methodName, 'read file to send error [' + err + ']');
+ }
+ bc(err, null);
+ return;
+ }
+ _doSend(sendPosition + bytes, sendCount + bytes);
+ });
+ });
+ };
+ _doSend(initPos, 0);
+ });
+};
+
+Utils.prototype.bufMD5 = function(buf) {
+ return crypto.createHash('md5').update(buf).digest('base64');
+};
+
+Utils.prototype.fileMD5 = function (filePath, bc){
+ var stream = fs.createReadStream(filePath);
+ var sha = crypto.createHash('md5');
+ stream.on('error',function(err){
+ if(err){
+ bc(err,null);
+ }
+ }).on('data', function(data){
+ sha.update(data);
+ }).on('end', function(){
+ var md5 = sha.digest('base64');
+ bc(null, md5);
+ });
+};
+
+
+Utils.prototype.createSignedUrlSync = function(param){
+ return this.signature === 'v4' ? this.createV4SignedUrlSync(param) : this.createV2SignedUrlSync(param);
+};
+
+Utils.prototype.createV2SignedUrlSync = function(param){
+ param = param || {};
+
+ var method = param.Method ? String(param.Method) : 'GET';
+ var bucketName = param.Bucket ? String(param.Bucket) : null;
+ var objectKey = param.Key ? String(param.Key) : null;
+ var specialParam = param.SpecialParam ? String(param.SpecialParam) : null;
+
+ if(this.signature === 'obs' && specialParam === 'storagePolicy'){
+ specialParam = 'storageClass';
+ }else if(this.signature === 'v2' && specialParam === 'storageClass'){
+ specialParam = 'storagePolicy';
+ }
+
+ var expires = param.Expires ? parseInt(param.Expires) : 300;
+ var headers = {};
+ if(param.Headers && (param.Headers instanceof Object) && !(param.Headers instanceof Array)){
+ for(let key in param.Headers){
+ headers[key] = param.Headers[key];
+ }
+ }
+
+ var queryParams = {};
+ if(param.QueryParams && (param.QueryParams instanceof Object) && !(param.QueryParams instanceof Array)){
+ for(let key in param.QueryParams){
+ queryParams[key] = param.QueryParams[key];
+ }
+ }
+
+ if(this.securityToken && !queryParams[this.headerPrefix + 'security-token']){
+ queryParams[this.headerPrefix + 'security-token'] = this.securityToken;
+ }
+
+ var result = '';
+ var resource = '';
+ var host = this.server;
+ if(bucketName){
+ resource += '/' + bucketName;
+ if(this.pathStyle){
+ result += '/' + bucketName;
+ }else{
+ host = bucketName + '.' + host;
+ resource += '/';
+ }
+ }
+
+ headers.Host = host;
+
+ if(objectKey){
+ objectKey = encodeURIWithSafe(objectKey, '/');
+ result += '/' + objectKey;
+ if(resource.lastIndexOf('/') !== resource.length - 1){
+ resource += '/';
+ }
+ resource += objectKey;
+ }
+
+ if(resource === ''){
+ resource = '/';
+ }
+
+ result += '?';
+
+ if(specialParam){
+ queryParams[specialParam] = '';
+ }
+
+ if(this.signature === 'v2'){
+ queryParams.AWSAccessKeyId = this.ak;
+ }else{
+ queryParams.AccessKeyId = this.ak;
+ }
+
+ if(expires < 0){
+ expires = 300;
+ }
+ expires = parseInt(new Date().getTime() / 1000) + expires;
+
+ queryParams.Expires = String(expires);
+
+ var interestHeaders = {};
+ for(let name in headers){
+ let key = String(name).toLowerCase();
+ if(key === 'content-type' || key === 'content-md5' || key.length > this.headerPrefix.length && key.slice(0,this.headerPrefix.length) === this.headerPrefix){
+ interestHeaders[key] = headers[name];
+ }
+ }
+
+ var queryParamsKeys = [];
+ for(let key in queryParams){
+ queryParamsKeys.push(key);
+ }
+ queryParamsKeys.sort();
+ var index = 0;
+ var flag = false;
+ var _resource = [];
+ for(let i=0;i=0 || key.toLowerCase().indexOf(this.headerPrefix) === 0){
+ flag = true;
+ let _val = val ? key + '=' + decodeURIComponent(val) : key;
+ _resource.push(_val);
+ }
+ result += '&';
+ index++;
+ }
+ _resource = _resource.join('&');
+ if(flag){
+ _resource = '?' + _resource;
+ }
+ resource += _resource;
+ var stringToSign = [method];
+ stringToSign.push('\n');
+
+ if('content-md5' in interestHeaders){
+ stringToSign.push(interestHeaders['content-md5']);
+ }
+ stringToSign.push('\n');
+
+ if('content-type' in interestHeaders){
+ stringToSign.push(interestHeaders['content-type']);
+ }
+ stringToSign.push('\n');
+
+ stringToSign.push(String(expires));
+ stringToSign.push('\n');
+
+ var temp = [];
+ var i = 0;
+ for(let key in interestHeaders){
+ if (key.length > this.headerPrefix.length && key.slice(0, this.headerPrefix.length) === this.headerPrefix){
+ temp[i++] = key;
+ }
+ }
+ temp = temp.sort();
+ for(let j=0;j {
+ options = options || {};
+ if (!options.hasOwnProperty('server') || !options.hasOwnProperty('bucket')
+ || !options.hasOwnProperty('accessKeyId') || !options.hasOwnProperty('secretAccessKey')
+ || !options.hasOwnProperty('localDir')) {
+ throw new Error('server, bucket, accessKeyId, secretAccessKey, localDir must not be empty');
+ }
+
+ if (options.server.substring(0, 8) != "https://") {
+ throw new Error('server option must start with "https://", e.g. "https://obs.cn-north-1.myhwclouds.com"');
+ }
+
+ if (!options.hasOwnProperty('localFilesIgnorePattern')) options.localFilesIgnorePattern = "$\\..*";
+ if (!options.hasOwnProperty('remoteDir')) options.remoteDir = "/";
+ if (!options.hasOwnProperty('syncDeletedFiles')) options.syncDeletedFiles = "yes";
+ if (!options.hasOwnProperty('syncDeletedFilesIgnorePattern')) options.syncDeletedFilesIgnorePattern = "$\\..*";
+
+ options.localDir = path.normalize(options.localDir).replace(/(^\s*)|(\s*$)/g, "")
+ options.remoteDir = options.remoteDir.replace(/(^\/*)|(\/*$)/g, "").replace(/(^\s*)|(\s*$)/g, "")
+ return options;
+ }
+
+ let checkSyncFileToOptions = (options) => {
+ options = options || {};
+ if (!options.hasOwnProperty('server') || !options.hasOwnProperty('bucket')
+ || !options.hasOwnProperty('accessKeyId') || !options.hasOwnProperty('secretAccessKey')
+ || !options.hasOwnProperty('localFileName') || !options.hasOwnProperty('remoteFileName')) {
+ throw new Error('server, bucket, accessKeyId, secretAccessKey, localFileName remoteFileName must not be empty');
+ }
+
+ if (options.server.substring(0, 8) != "https://") {
+ throw new Error('server option must start with "https://", e.g. "https://obs.cn-north-1.myhwclouds.com"');
+ }
+
+ options.localFileName = path.normalize(options.localFileName).replace(/(^\s*)|(\s*$)/g, "")
+ options.remoteFileName = options.remoteFileName.replace(/(^\/*)|(\/*$)/g, "").replace(/(^\s*)|(\s*$)/g, "")
+ return options;
+ }
+
+ let getObsClient = (options) => {
+ return new ObsClient({
+ access_key_id: options.accessKeyId,
+ secret_access_key: options.secretAccessKey,
+ server : options.server,
+ });
+ };
+
+ let getOBSFileList = async (options) => {
+ let baseUrl = options.server.replace("https://", "https://" + options.bucket + ".") + "?max-keys=1000&prefix=" + urlencode(options.remoteDir);
+ let marker = "";
+ let result = [];
+ console.log("get remote obs file list ...");
+ while (true) {
+ let data = await new Promise((resolver, reject) => {
+ let url = marker == "" ? baseUrl : baseUrl + "&marker=" + urlencode(marker);
+ console.log(url);
+ request(url, (error, response, body) => {
+ if (error) reject(error);
+ xml2js.parseString(body, {explicitArray:false, ignoreAttrs:true}, (error, result) => {
+ resolver(result);
+ });
+ });
+ });
+ if (data.ListBucketResult.Contents != undefined) {
+ result = result.concat(data.ListBucketResult.Contents);
+ }
+ if (data.ListBucketResult.NextMarker == "" || data.ListBucketResult.NextMarker == undefined) {
+ break;
+ }
+ marker = data.ListBucketResult.NextMarker;
+ }
+ console.log("get remote obs file list success, total file " + result.length);
+ return [options, result];
+ }
+
+ let getChangedFileList = (info) => {
+ let options = info[0];
+ let remoteFileList = info[1];
+ console.log("=================sync files start================================");
+ console.log("get local file list ...");
+ let localFileList = hexofs.listDirSync(options.localDir).map(item => {
+ let data = hexofs.readFileSync(path.join(options.localDir, item), {escape: false, encoding: null});
+ let result = {
+ filename: path.join(options.localDir, item),
+ linuxFilename: item.replace(/\\/g, "/"),
+ obsKey: options.remoteDir == "" ? item.replace(/\\/g, "/") : options.remoteDir + "/" + item.replace(/\\/g, "/"),
+ md5: crypto.createHash('md5').update(data).digest('hex'),
+ base64MD5: crypto.createHash('md5').update(data).digest("base64")
+ };
+ return result;
+ })
+ console.log("get local file list success, total file " + localFileList.length);
+
+ console.log("calculate changed local file list ...");
+ var updatedFileList = [];
+ let localFilesIgnoreRegex = new RegExp(options.localFilesIgnorePattern);
+ for (var i = 0; i < localFileList.length; i++) {
+ let isUpdated = true;
+ for (var j = 0; j < remoteFileList.length; j++) {
+ if (remoteFileList[j].Key == localFileList[i].obsKey) {
+ if (remoteFileList[j].ETag.replace(/"/g, "") == localFileList[i].md5) {
+ isUpdated = false;
+ }
+ break;
+ }
+ }
+ if (isUpdated && !localFilesIgnoreRegex.test(localFileList[i].linuxFilename)) {
+ updatedFileList.push(localFileList[i]);
+ }
+ }
+ console.log("calculate changed local file list success, total changed file " + updatedFileList.length);
+
+ console.log("calculate deleted local file list ...");
+ var deletedFileList = [];
+ let syncDeletedFilesIgnoreRegex = new RegExp(options.syncDeletedFilesIgnorePattern);
+ for (var i = 0; i < remoteFileList.length; i++) {
+ let isExist = false;
+ for (var j = 0; j < localFileList.length; j++) {
+ if (remoteFileList[i].Key == localFileList[j].obsKey) {
+ isExist = true;
+ break;
+ }
+ }
+ if (!isExist && !syncDeletedFilesIgnoreRegex.test(remoteFileList[i].Key)) {
+ deletedFileList.push(remoteFileList[i]);
+ }
+ }
+ console.log("calculate deleted local file list success, total changed file " + deletedFileList.length);
+ return [options, updatedFileList, deletedFileList];
+ }
+
+ let uploadFiles = async (info) => {
+ let options = info[0];
+ let updatedFileList = info[1];
+ let deletedFileList = info[2];
+ let obsClient = getObsClient(options);
+
+ console.log("===========> uploading files ...");
+ await Promise.all(updatedFileList.map(function (item) {
+ return new Promise((resolver, reject) => {
+ obsClient.putObject({
+ Bucket : options.bucket,
+ Key : item.obsKey,
+ SourceFile : item.filename,
+ ContentMD5: item.base64MD5
+ }, (err, result) => {
+ if(err){
+ console.error('upload file--> ' + item.obsKey + ', error, ' + err);
+ reject(err);
+ }else{
+ console.error('upload file--> ' + item.obsKey + ', ' + result.CommonMsg.Status);
+ resolver(result.CommonMsg.Status);
+ }
+ });
+ });
+ }));
+ console.log("===========> uploading files finished...");
+
+ if (options.syncDeletedFiles == "yes") {
+ console.log("===========> deleting files ...");
+ await Promise.all(deletedFileList.map(function (item) {
+ return new Promise((resolver, reject) => {
+ obsClient.deleteObject({
+ Bucket : options.bucket,
+ Key : item.Key
+ }, (err, result) => {
+ if(err){
+ console.error('delete file--> ' + item.Ke + ', error, ' + err);
+ reject(err);
+ }else{
+ console.error('delete file --> ' + item.Key + ', response code: ' + result.CommonMsg.Status);
+ resolver(result.CommonMsg.Status);
+ }
+ });
+ });
+ }));
+ console.log("===========> deleting files finished...");
+ }
+ obsClient.close();
+ console.log("=================sync files finished================================");
+ }
+
+ this.syncFolderToOBS = (options) => {
+ return getOBSFileList(checkSyncToOptions(options)).then(getChangedFileList).then(uploadFiles);
+ }
+
+ this.syncFileToOBS = (options) => {
+ options = checkSyncFileToOptions(options);
+ return new Promise((resolver, reject) => {
+ let data = hexofs.readFileSync(options.localFileName, {escape: false, encoding: null});
+ let obsClient = getObsClient(options);
+ obsClient.putObject({
+ Bucket : options.bucket,
+ Key : options.remoteFileName,
+ SourceFile : options.localFileName,
+ ContentMD5: crypto.createHash('md5').update(data).digest("base64")
+ }, (err, result) => {
+ obsClient.close();
+ if(err){
+ console.error('upload file--> ' + item.obsKey + ', error, ' + err);
+ reject(err);
+ }else{
+ console.error('upload file--> ' + item.obsKey + ', ' + result.CommonMsg.Status);
+ resolver(result.CommonMsg.Status);
+ }
+ });
+ });
+ }
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..9329fa2
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,2362 @@
+{
+ "name": "huaweicloud-obs-sync",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "ajv": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+ "requires": {
+ "co": "4.6.0",
+ "fast-deep-equal": "1.1.0",
+ "fast-json-stable-stringify": "2.0.0",
+ "json-schema-traverse": "0.3.1"
+ }
+ },
+ "anymatch": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+ "requires": {
+ "micromatch": "2.3.11",
+ "normalize-path": "2.1.1"
+ }
+ },
+ "arr-diff": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+ "requires": {
+ "arr-flatten": "1.1.0"
+ }
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
+ },
+ "array-unique": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM="
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "requires": {
+ "safer-buffer": "2.1.2"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
+ },
+ "async-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0="
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ },
+ "aws4": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "requires": {
+ "cache-base": "1.0.1",
+ "class-utils": "0.3.6",
+ "component-emitter": "1.2.1",
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "mixin-deep": "1.3.1",
+ "pascalcase": "0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "optional": true,
+ "requires": {
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "binary-extensions": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz",
+ "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg=="
+ },
+ "bluebird": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz",
+ "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg=="
+ },
+ "braces": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+ "requires": {
+ "expand-range": "1.8.2",
+ "preserve": "0.2.0",
+ "repeat-element": "1.1.3"
+ }
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "requires": {
+ "collection-visit": "1.0.0",
+ "component-emitter": "1.2.1",
+ "get-value": "2.0.6",
+ "has-value": "1.0.0",
+ "isobject": "3.0.1",
+ "set-value": "2.0.0",
+ "to-object-path": "0.3.0",
+ "union-value": "1.0.0",
+ "unset-value": "1.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ }
+ }
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "chokidar": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+ "requires": {
+ "anymatch": "1.3.2",
+ "async-each": "1.0.1",
+ "fsevents": "1.2.4",
+ "glob-parent": "2.0.0",
+ "inherits": "2.0.3",
+ "is-binary-path": "1.0.1",
+ "is-glob": "2.0.1",
+ "path-is-absolute": "1.0.1",
+ "readdirp": "2.2.1"
+ }
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "requires": {
+ "arr-union": "3.1.0",
+ "define-property": "0.2.5",
+ "isobject": "3.0.1",
+ "static-extend": "0.1.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ }
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "requires": {
+ "map-visit": "1.0.0",
+ "object-visit": "1.0.1"
+ }
+ },
+ "combined-stream": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
+ "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ },
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "1.0.0"
+ }
+ },
+ "date-format": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/date-format/-/date-format-0.0.0.tgz",
+ "integrity": "sha1-CSBoY6sHDrRZrOpVQsvYVrEZZrM="
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "requires": {
+ "is-descriptor": "1.0.2",
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1",
+ "safer-buffer": "2.1.2"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+ "requires": {
+ "is-posix-bracket": "0.1.1"
+ }
+ },
+ "expand-range": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+ "requires": {
+ "fill-range": "2.2.4"
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "requires": {
+ "assign-symbols": "1.0.0",
+ "is-extendable": "1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "fast-deep-equal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+ "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+ },
+ "filename-regex": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+ "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY="
+ },
+ "fill-range": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
+ "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==",
+ "requires": {
+ "is-number": "2.1.0",
+ "isobject": "2.1.0",
+ "randomatic": "3.1.0",
+ "repeat-element": "1.1.3",
+ "repeat-string": "1.6.1"
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
+ },
+ "for-own": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+ "requires": {
+ "for-in": "1.0.2"
+ }
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "form-data": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.6",
+ "mime-types": "2.1.20"
+ },
+ "dependencies": {
+ "combined-stream": {
+ "version": "1.0.6",
+ "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ }
+ }
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "requires": {
+ "map-cache": "0.2.2"
+ }
+ },
+ "fsevents": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
+ "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
+ "optional": true,
+ "requires": {
+ "nan": "2.11.1",
+ "node-pre-gyp": "0.10.0"
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.1.1",
+ "bundled": true,
+ "optional": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "bundled": true
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "bundled": true,
+ "optional": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.4",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "delegates": "1.0.0",
+ "readable-stream": "2.3.6"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "bundled": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "bundled": true,
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "chownr": {
+ "version": "1.0.1",
+ "bundled": true,
+ "optional": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "bundled": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "bundled": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "bundled": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "bundled": true,
+ "optional": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "deep-extend": {
+ "version": "0.5.1",
+ "bundled": true,
+ "optional": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "bundled": true,
+ "optional": true
+ },
+ "detect-libc": {
+ "version": "1.0.3",
+ "bundled": true,
+ "optional": true
+ },
+ "fs-minipass": {
+ "version": "1.2.5",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "minipass": "2.2.4"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "bundled": true,
+ "optional": true
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "aproba": "1.2.0",
+ "console-control-strings": "1.1.0",
+ "has-unicode": "2.0.1",
+ "object-assign": "4.1.1",
+ "signal-exit": "3.0.2",
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1",
+ "wide-align": "1.1.2"
+ }
+ },
+ "glob": {
+ "version": "7.1.2",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "bundled": true,
+ "optional": true
+ },
+ "iconv-lite": {
+ "version": "0.4.21",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "safer-buffer": "2.1.2"
+ }
+ },
+ "ignore-walk": {
+ "version": "3.0.1",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "minimatch": "3.0.4"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "bundled": true
+ },
+ "ini": {
+ "version": "1.3.5",
+ "bundled": true,
+ "optional": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "bundled": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "bundled": true,
+ "optional": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "bundled": true,
+ "requires": {
+ "brace-expansion": "1.1.11"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "bundled": true
+ },
+ "minipass": {
+ "version": "2.2.4",
+ "bundled": true,
+ "requires": {
+ "safe-buffer": "5.1.1",
+ "yallist": "3.0.2"
+ }
+ },
+ "minizlib": {
+ "version": "1.1.0",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "minipass": "2.2.4"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "bundled": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "bundled": true,
+ "optional": true
+ },
+ "needle": {
+ "version": "2.2.0",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "debug": "2.6.9",
+ "iconv-lite": "0.4.21",
+ "sax": "1.2.4"
+ }
+ },
+ "node-pre-gyp": {
+ "version": "0.10.0",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "detect-libc": "1.0.3",
+ "mkdirp": "0.5.1",
+ "needle": "2.2.0",
+ "nopt": "4.0.1",
+ "npm-packlist": "1.1.10",
+ "npmlog": "4.1.2",
+ "rc": "1.2.7",
+ "rimraf": "2.6.2",
+ "semver": "5.5.0",
+ "tar": "4.4.1"
+ }
+ },
+ "nopt": {
+ "version": "4.0.1",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "abbrev": "1.1.1",
+ "osenv": "0.1.5"
+ }
+ },
+ "npm-bundled": {
+ "version": "1.0.3",
+ "bundled": true,
+ "optional": true
+ },
+ "npm-packlist": {
+ "version": "1.1.10",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "ignore-walk": "3.0.1",
+ "npm-bundled": "1.0.3"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "are-we-there-yet": "1.1.4",
+ "console-control-strings": "1.1.0",
+ "gauge": "2.7.4",
+ "set-blocking": "2.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "bundled": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "bundled": true,
+ "optional": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "bundled": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "bundled": true,
+ "optional": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "bundled": true,
+ "optional": true
+ },
+ "osenv": {
+ "version": "0.1.5",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "os-homedir": "1.0.2",
+ "os-tmpdir": "1.0.2"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "bundled": true,
+ "optional": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "bundled": true,
+ "optional": true
+ },
+ "rc": {
+ "version": "1.2.7",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "deep-extend": "0.5.1",
+ "ini": "1.3.5",
+ "minimist": "1.2.0",
+ "strip-json-comments": "2.0.1"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "bundled": true,
+ "optional": true
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.1.1",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "glob": "7.1.2"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "bundled": true
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "bundled": true,
+ "optional": true
+ },
+ "sax": {
+ "version": "1.2.4",
+ "bundled": true,
+ "optional": true
+ },
+ "semver": {
+ "version": "5.5.0",
+ "bundled": true,
+ "optional": true
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "bundled": true,
+ "optional": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "bundled": true,
+ "optional": true
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "bundled": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "bundled": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "bundled": true,
+ "optional": true
+ },
+ "tar": {
+ "version": "4.4.1",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "chownr": "1.0.1",
+ "fs-minipass": "1.2.5",
+ "minipass": "2.2.4",
+ "minizlib": "1.1.0",
+ "mkdirp": "0.5.1",
+ "safe-buffer": "5.1.1",
+ "yallist": "3.0.2"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "bundled": true,
+ "optional": true
+ },
+ "wide-align": {
+ "version": "1.1.2",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "string-width": "1.0.2"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "bundled": true
+ },
+ "yallist": {
+ "version": "3.0.2",
+ "bundled": true
+ }
+ }
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "requires": {
+ "assert-plus": "1.0.0"
+ }
+ },
+ "glob-base": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
+ "requires": {
+ "glob-parent": "2.0.0",
+ "is-glob": "2.0.1"
+ }
+ },
+ "glob-parent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+ "requires": {
+ "is-glob": "2.0.1"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+ },
+ "har-validator": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz",
+ "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==",
+ "requires": {
+ "ajv": "5.5.2",
+ "har-schema": "2.0.0"
+ }
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "requires": {
+ "get-value": "2.0.6",
+ "has-values": "1.0.0",
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ }
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "requires": {
+ "is-number": "3.0.0",
+ "kind-of": "4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "hexo-fs": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/hexo-fs/-/hexo-fs-0.1.6.tgz",
+ "integrity": "sha1-+YDMw7x50PuS7dvYh7wgpWUA0D8=",
+ "requires": {
+ "bluebird": "3.5.2",
+ "chokidar": "1.7.0",
+ "escape-string-regexp": "1.0.5",
+ "graceful-fs": "4.1.11"
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.14.2"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "requires": {
+ "safer-buffer": "2.1.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "requires": {
+ "binary-extensions": "1.12.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
+ "is-dotfile": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+ "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE="
+ },
+ "is-equal-shallow": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+ "requires": {
+ "is-primitive": "2.0.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
+ },
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "is-number": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "requires": {
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ }
+ }
+ },
+ "is-posix-bracket": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+ "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q="
+ },
+ "is-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU="
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "optional": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+ },
+ "json-schema-traverse": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ },
+ "log4js": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/log4js/-/log4js-1.1.1.tgz",
+ "integrity": "sha1-wh0px2BAieTyVYM+f5SzRh3h/0M=",
+ "requires": {
+ "debug": "2.6.9",
+ "semver": "5.5.1",
+ "streamroller": "0.4.1"
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "requires": {
+ "object-visit": "1.0.1"
+ }
+ },
+ "math-random": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
+ "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w="
+ },
+ "micromatch": {
+ "version": "2.3.11",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+ "requires": {
+ "arr-diff": "2.0.0",
+ "array-unique": "0.2.1",
+ "braces": "1.8.5",
+ "expand-brackets": "0.1.5",
+ "extglob": "0.3.2",
+ "filename-regex": "2.0.1",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1",
+ "kind-of": "3.2.2",
+ "normalize-path": "2.1.1",
+ "object.omit": "2.0.1",
+ "parse-glob": "3.0.4",
+ "regex-cache": "0.4.4"
+ }
+ },
+ "mime-db": {
+ "version": "1.36.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz",
+ "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw=="
+ },
+ "mime-types": {
+ "version": "2.1.20",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz",
+ "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==",
+ "requires": {
+ "mime-db": "1.36.0"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ },
+ "mixin-deep": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+ "requires": {
+ "for-in": "1.0.2",
+ "is-extendable": "1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "nan": {
+ "version": "2.11.1",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz",
+ "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==",
+ "optional": true
+ },
+ "nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "fragment-cache": "0.2.1",
+ "is-windows": "1.0.2",
+ "kind-of": "6.0.2",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.2",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "requires": {
+ "remove-trailing-separator": "1.1.0"
+ }
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "requires": {
+ "copy-descriptor": "0.1.1",
+ "define-property": "0.2.5",
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ }
+ }
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "requires": {
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ }
+ }
+ },
+ "object.omit": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+ "requires": {
+ "for-own": "0.1.5",
+ "is-extendable": "0.1.1"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "requires": {
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ }
+ }
+ },
+ "parse-glob": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+ "requires": {
+ "glob-base": "0.3.0",
+ "is-dotfile": "1.0.3",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1"
+ }
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
+ },
+ "preserve": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks="
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
+ },
+ "psl": {
+ "version": "1.1.29",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
+ "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ=="
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ },
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+ },
+ "randomatic": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz",
+ "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==",
+ "requires": {
+ "is-number": "4.0.0",
+ "kind-of": "6.0.2",
+ "math-random": "1.0.1"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ=="
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "2.0.0",
+ "safe-buffer": "5.1.2",
+ "string_decoder": "1.1.1",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "readdirp": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "micromatch": "3.1.10",
+ "readable-stream": "2.3.6"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "requires": {
+ "arr-flatten": "1.1.0",
+ "array-unique": "0.3.2",
+ "extend-shallow": "2.0.1",
+ "fill-range": "4.0.0",
+ "isobject": "3.0.1",
+ "repeat-element": "1.1.3",
+ "snapdragon": "0.8.2",
+ "snapdragon-node": "2.1.1",
+ "split-string": "3.1.0",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "requires": {
+ "debug": "2.6.9",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "posix-character-classes": "0.1.1",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.2",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "requires": {
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "expand-brackets": "2.1.4",
+ "extend-shallow": "2.0.1",
+ "fragment-cache": "0.2.1",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.2",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1",
+ "to-regex-range": "2.1.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "braces": "2.3.2",
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "extglob": "2.0.4",
+ "fragment-cache": "0.2.1",
+ "kind-of": "6.0.2",
+ "nanomatch": "1.2.13",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.2",
+ "to-regex": "3.0.2"
+ }
+ }
+ }
+ },
+ "regex-cache": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
+ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
+ "requires": {
+ "is-equal-shallow": "0.1.3"
+ }
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "requires": {
+ "extend-shallow": "3.0.2",
+ "safe-regex": "1.1.0"
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
+ },
+ "repeat-element": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g=="
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
+ },
+ "request": {
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+ "requires": {
+ "aws-sign2": "0.7.0",
+ "aws4": "1.8.0",
+ "caseless": "0.12.0",
+ "combined-stream": "1.0.7",
+ "extend": "3.0.2",
+ "forever-agent": "0.6.1",
+ "form-data": "2.3.2",
+ "har-validator": "5.1.0",
+ "http-signature": "1.2.0",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.20",
+ "oauth-sign": "0.9.0",
+ "performance-now": "2.1.0",
+ "qs": "6.5.2",
+ "safe-buffer": "5.1.2",
+ "tough-cookie": "2.4.3",
+ "tunnel-agent": "0.6.0",
+ "uuid": "3.3.2"
+ }
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
+ },
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "requires": {
+ "ret": "0.1.15"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+ },
+ "semver": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz",
+ "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw=="
+ },
+ "set-value": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "split-string": "3.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "requires": {
+ "base": "0.11.2",
+ "debug": "2.6.9",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "map-cache": "0.2.2",
+ "source-map": "0.5.7",
+ "source-map-resolve": "0.5.2",
+ "use": "3.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "requires": {
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "snapdragon-util": "3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "source-map-resolve": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+ "requires": {
+ "atob": "2.1.2",
+ "decode-uri-component": "0.2.0",
+ "resolve-url": "0.2.1",
+ "source-map-url": "0.4.0",
+ "urix": "0.1.0"
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "requires": {
+ "extend-shallow": "3.0.2"
+ }
+ },
+ "sshpk": {
+ "version": "1.14.2",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz",
+ "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
+ "requires": {
+ "asn1": "0.2.4",
+ "assert-plus": "1.0.0",
+ "bcrypt-pbkdf": "1.0.2",
+ "dashdash": "1.14.1",
+ "ecc-jsbn": "0.1.2",
+ "getpass": "0.1.7",
+ "jsbn": "0.1.1",
+ "safer-buffer": "2.1.2",
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "requires": {
+ "define-property": "0.2.5",
+ "object-copy": "0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ }
+ }
+ },
+ "streamroller": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.4.1.tgz",
+ "integrity": "sha1-1DW9WXQ3Or2b2QaDWVEwhRBswF8=",
+ "requires": {
+ "date-format": "0.0.0",
+ "debug": "0.7.4",
+ "mkdirp": "0.5.1",
+ "readable-stream": "1.1.14"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "0.7.4",
+ "resolved": "http://registry.npmjs.org/debug/-/debug-0.7.4.tgz",
+ "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk="
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ }
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "requires": {
+ "safe-buffer": "5.1.2"
+ }
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "requires": {
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "regex-not": "1.0.2",
+ "safe-regex": "1.1.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "requires": {
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ }
+ }
+ },
+ "tough-cookie": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+ "requires": {
+ "psl": "1.1.29",
+ "punycode": "1.4.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "requires": {
+ "safe-buffer": "5.1.2"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "optional": true
+ },
+ "union-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+ "requires": {
+ "arr-union": "3.1.0",
+ "get-value": "2.0.6",
+ "is-extendable": "0.1.1",
+ "set-value": "0.4.3"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "set-value": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "to-object-path": "0.3.0"
+ }
+ }
+ }
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "requires": {
+ "has-value": "0.3.1",
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "requires": {
+ "get-value": "2.0.6",
+ "has-values": "0.1.4",
+ "isobject": "2.1.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ }
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
+ },
+ "urlencode": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/urlencode/-/urlencode-1.1.0.tgz",
+ "integrity": "sha1-HyuibwE8hfATP3o61v8nMK33y7c=",
+ "requires": {
+ "iconv-lite": "0.4.24"
+ }
+ },
+ "use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "uuid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "1.3.0"
+ }
+ },
+ "xml2js": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
+ "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+ "requires": {
+ "sax": "1.2.4",
+ "xmlbuilder": "9.0.7"
+ }
+ },
+ "xmlbuilder": {
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..7e55a2e
--- /dev/null
+++ b/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "huaweicloud-obs-sync",
+ "version": "1.0.0",
+ "description": "sync files to huaweicloud obs.",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/ruanxinyu/huaweicloud-obs-sync.git"
+ },
+ "homepage": "http://blog.ruanxinyu.cn",
+ "keywords": [
+ "sync",
+ "huaweicloud-obs"
+ ],
+ "main": "lib/sync",
+ "author": "ruanxinyu",
+ "license": "MIT",
+ "dependencies": {
+ "bluebird": "^3.4.7",
+ "hexo-fs": "^0.1.6",
+ "log4js": "^1.1.1",
+ "xml2js": "^0.4.19",
+ "request": "^2.88.0",
+ "urlencode": "^1.1.0"
+ },
+ "bugs": {
+ "url": "https://github.com/ruanxinyu/huaweicloud-obs-sync/issues"
+ },
+ "directories": {
+ "lib": "lib"
+ },
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ }
+}