Compare commits
117 Commits
7bd4224a05
...
master
Author | SHA1 | Date | |
---|---|---|---|
5d9f4754a5 | |||
2cac260954 | |||
d298b8e842 | |||
bd63607477 | |||
55d461fb8e | |||
895893e76a | |||
39fbc73c74 | |||
e1c26e2c5e | |||
d3a93108e2 | |||
7a79aca59b | |||
ffb086a774 | |||
d1499bb6d4 | |||
a6d4a35588 | |||
2e4bb21354 | |||
3ed5253fc4 | |||
274f2b4b7a | |||
6eae1742d6 | |||
cc59df51d0 | |||
2a950310be | |||
9b4ad340a2 | |||
dfc0bc3b7e | |||
c2ea65a992 | |||
3de5485650 | |||
dfd3df544c | |||
7fe6dee81c | |||
1d7791c2b0 | |||
3c8dcf3ad2 | |||
ab70c46501 | |||
3af8b97258 | |||
431e21806b | |||
1541018701 | |||
0eea261e56 | |||
00546001eb | |||
db3ae308e6 | |||
20394e65f8 | |||
7b9ce83c71 | |||
fccd69db74 | |||
95814c5541 | |||
27cec2cb0b | |||
3716e80674 | |||
3b9e3d416a | |||
8b8fbb3ec5 | |||
374940757a | |||
228c204255 | |||
a1715aa117 | |||
c053340e5e | |||
a208a2fb50 | |||
52597ca46f | |||
efa44f0405 | |||
2dc969a47d | |||
bc50897afc | |||
64ec1b5db5 | |||
999d493c68 | |||
1a98e86954 | |||
7a9e12e62d | |||
89a861a2dd | |||
715f64408d | |||
f00db0efe5 | |||
ce4e78e0d5 | |||
332e833134 | |||
9b85bb119f | |||
cf9e238dc7 | |||
bda39f279f | |||
111df45892 | |||
e90e504fb9 | |||
bff13c3364 | |||
6f242fb79f | |||
81965a1398 | |||
9891a7e247 | |||
a2e26cbf93 | |||
4d50fdb490 | |||
b55786d755 | |||
c1fcde7d6f | |||
03f0104bca | |||
ec82717208 | |||
c2e0a11295 | |||
f3d26fd6a0 | |||
84d070b2a9 | |||
975f527172 | |||
6e529676fe | |||
4d58e47679 | |||
73b2963baf | |||
9e0ce1ee89 | |||
0e68972aba | |||
1be4f80fa3 | |||
68190192e1 | |||
15e4e8f553 | |||
5d26782a6e | |||
27bed3ae65 | |||
785ebe6944 | |||
cb83201faa | |||
ebb33fca4f | |||
6a5dce8460 | |||
bb3e4a867a | |||
03c879b073 | |||
e67d76029e | |||
9457505a4c | |||
9581fbf2b3 | |||
80bd577823 | |||
98f5cc49d1 | |||
22001b3d99 | |||
a9bd25cf41 | |||
a1bc4c5b9b | |||
c332ce82dd | |||
19b74cdcda | |||
58c390fc61 | |||
eabb5705bd | |||
bed627ad82 | |||
78dfe76a43 | |||
4bd4740a86 | |||
a73e0d1d80 | |||
6baeade4c0 | |||
1534917132 | |||
0c4ccc3b43 | |||
b2d9e9f0bf | |||
81283fd3c5 | |||
0ca4e754cb |
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@ -0,0 +1 @@
|
||||
/dist/
|
21
.eslintrc.js
21
.eslintrc.js
@ -1,3 +1,10 @@
|
||||
/*
|
||||
* Copyright (C) Sapphirecode - All Rights Reserved
|
||||
* This file is part of Requestor which is released under BSD-3-Clause.
|
||||
* See file 'LICENSE' for full license details.
|
||||
* Created by Timo Hocker <timo@sapphirecode.ovh>, March 2020
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
env: {
|
||||
commonjs: true,
|
||||
@ -5,16 +12,6 @@ module.exports = {
|
||||
node: true
|
||||
},
|
||||
extends: [
|
||||
'standard'
|
||||
],
|
||||
globals: {
|
||||
Atomics: 'readonly',
|
||||
SharedArrayBuffer: 'readonly'
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018
|
||||
},
|
||||
rules: {
|
||||
semi: 0
|
||||
}
|
||||
'@sapphirecode'
|
||||
]
|
||||
}
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -1 +1,7 @@
|
||||
/node_modules/
|
||||
/coverage/
|
||||
/.nyc_output/
|
||||
/dist/
|
||||
|
||||
# stryker temp files
|
||||
.stryker-tmp
|
||||
|
@ -1 +0,0 @@
|
||||
/test/
|
69
Jenkinsfile
vendored
69
Jenkinsfile
vendored
@ -1,46 +1,23 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
VERSION = VersionNumber([
|
||||
versionNumberString:
|
||||
'${BUILDS_ALL_TIME}',
|
||||
versionPrefix: '1.1.',
|
||||
worstResultForIncrement: 'SUCCESS'
|
||||
])
|
||||
publish = 0
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Setup') {
|
||||
steps {
|
||||
echo 'Setting up test environment'
|
||||
sh 'npm ci'
|
||||
sh 'nodejs jenkins.js ${VERSION}'
|
||||
script {
|
||||
currentBuild.displayName = env.VERSION
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Testing') {
|
||||
steps {
|
||||
echo 'Running tests...'
|
||||
sh 'npm test'
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
success {
|
||||
script {
|
||||
publish = sh script: "git log -1 | grep '\\[no publish\\]'", returnStatus: true
|
||||
if (publish != 0) {
|
||||
echo 'Deploying'
|
||||
sh 'npm publish'
|
||||
} else {
|
||||
echo 'Build successful, Commit not marked for deploying'
|
||||
currentBuild.result = "UNSTABLE"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
VERSION = VersionNumber([
|
||||
versionNumberString:
|
||||
'${BUILDS_ALL_TIME}',
|
||||
versionPrefix: '2.0.',
|
||||
worstResultForIncrement: 'SUCCESS'
|
||||
])
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Building') {
|
||||
steps {
|
||||
script {
|
||||
currentBuild.displayName = env.VERSION
|
||||
}
|
||||
sh 'yarn ci ${VERSION}'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
664
LICENSE
664
LICENSE
@ -1,637 +1,29 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
|
||||
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) 2019 Timo Hocker
|
||||
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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:
|
||||
|
||||
bin Copyright (C) 2019 Timo Hocker
|
||||
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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 <http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
Copyright (c) 2020, Timo Hocker
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of requestor nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
130
README.md
130
README.md
@ -1,60 +1,70 @@
|
||||
# Requestor
|
||||
|
||||
Split express request handlers into individual files to make your api a little
|
||||
more structured.
|
||||
|
||||
## Installation
|
||||
|
||||
npmrc:
|
||||
|
||||
used to set the registry for @scode
|
||||
|
||||
```npmrc
|
||||
@scode:registry=https://npm.scode.ovh
|
||||
```
|
||||
|
||||
install the package:
|
||||
|
||||
`npm i --save @scode/requestor`
|
||||
|
||||
## Usage
|
||||
|
||||
The path to which the individual modules respond is defined by their name.
|
||||
|
||||
'.' is used as path separator.
|
||||
|
||||
`method-subdir.subdir.subdir.js`
|
||||
|
||||
method can be any of [post, get, put, delete, all]
|
||||
|
||||
to avoid names like `get-.js` root is used for the root directory
|
||||
(`get-root.js`)
|
||||
|
||||
index.js:
|
||||
|
||||
```js
|
||||
const requestor = require('requestor');
|
||||
const express = require('express');
|
||||
|
||||
const app = express();
|
||||
requestor(app, 'api', {foo: 'bar'});
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
api/get-root.js
|
||||
|
||||
```js
|
||||
// will respont to get requests on /
|
||||
module.exports = (req, res, next, opts) => {
|
||||
res.send(opts.foo);
|
||||
};
|
||||
```
|
||||
|
||||
api/post-subfolder.js
|
||||
|
||||
```js
|
||||
// will respont to post requests on /subfolder/
|
||||
module.exports = (req, res, next, opts) => {
|
||||
res.send(opts.foo);
|
||||
};
|
||||
```
|
||||
# Requestor
|
||||
|
||||
Split express request handlers into individual files to make your api a little
|
||||
more structured.
|
||||
|
||||
## Installation
|
||||
|
||||
npmrc:
|
||||
|
||||
used to set the registry for @scode
|
||||
|
||||
```npmrc
|
||||
@scode:registry=https://npm.scode.ovh
|
||||
```
|
||||
|
||||
install the package:
|
||||
|
||||
`npm i --save @scode/requestor`
|
||||
|
||||
## Usage
|
||||
|
||||
The path to which the individual modules respond is defined by their name.
|
||||
|
||||
'.' is used as path separator.
|
||||
|
||||
`method-subdir.subdir.subdir.js`
|
||||
|
||||
method can be any of [post, get, put, delete, all]
|
||||
|
||||
to avoid names like `get-.js` root is used for the root directory
|
||||
(`get-root.js`)
|
||||
|
||||
index.js:
|
||||
|
||||
```js
|
||||
const requestor = require('requestor');
|
||||
const express = require('express');
|
||||
|
||||
const app = express();
|
||||
requestor(app, 'api', {opts: {foo: 'bar'}});
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
api/get-root.js
|
||||
|
||||
```js
|
||||
// will respond to get requests on /
|
||||
module.exports = (req, res, next, opts) => {
|
||||
res.send(opts.foo);
|
||||
};
|
||||
```
|
||||
|
||||
api/post-subfolder.js
|
||||
|
||||
```js
|
||||
// will respond to post requests on /subfolder/
|
||||
module.exports = (req, res, next, opts) => {
|
||||
res.send(opts.foo);
|
||||
};
|
||||
```
|
||||
|
||||
optionally, you can set a subdirectory for all requests
|
||||
|
||||
```js
|
||||
//...
|
||||
|
||||
requestor(app, 'api', {subdir: 'subdir'});
|
||||
|
||||
// requests that before responded to /foo/bar/ will now respond to /subdir/foo/bar/
|
||||
```
|
||||
|
44
index.js
44
index.js
@ -1,44 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
/**
|
||||
* Load all request handlers in the given folder
|
||||
*
|
||||
* @param {any} app express app
|
||||
* @param {string} modulefolder
|
||||
* @param {any} opts object to pass to the handlers (for example database access)
|
||||
*/
|
||||
module.exports = function (app, modulefolder, opts = {}, subdir = '') {
|
||||
for (const f of fs.readdirSync(modulefolder)) {
|
||||
const regex = /(.*?)-(.*?)\.js/;
|
||||
let [, method, url] = regex.exec(f);
|
||||
url = '/' + subdir + '/' + url + '/';
|
||||
url = url
|
||||
.replace(/^\/root/i, '/')
|
||||
.replace(/\./g, '/')
|
||||
.replace(/\/+/g, '/');
|
||||
|
||||
const handler = require(path.join(process.cwd(), modulefolder, f));
|
||||
const func = (req, res, next) => {
|
||||
handler(req, res, next, opts);
|
||||
};
|
||||
|
||||
switch (method) {
|
||||
case 'post':
|
||||
app.post(url, func);
|
||||
break;
|
||||
case 'get':
|
||||
app.get(url, func);
|
||||
break;
|
||||
case 'put':
|
||||
app.put(url, func);
|
||||
break;
|
||||
case 'delete':
|
||||
app.delete(url, func);
|
||||
break;
|
||||
case 'all':
|
||||
app.all(url, func);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
27
jenkins.js
27
jenkins.js
@ -1,5 +1,22 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
||||
pkg.version = process.argv[2];
|
||||
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2));
|
||||
'use strict';
|
||||
|
||||
const https = require ('https');
|
||||
const fs = require ('fs');
|
||||
const { execSync: exec_sync } = require ('child_process');
|
||||
|
||||
const run_file = fs.createWriteStream ('.jenkins.run.js');
|
||||
|
||||
const [
|
||||
,, ...args
|
||||
] = process.argv;
|
||||
|
||||
run_file.on ('close', () => {
|
||||
exec_sync (`node .jenkins.run.js ${args.join (' ')}`, { stdio: 'inherit' });
|
||||
});
|
||||
|
||||
https.get (
|
||||
'https://git.scode.ovh/Timo/standard/raw/branch/master/jenkins.run.js',
|
||||
(msg) => {
|
||||
msg.pipe (run_file);
|
||||
}
|
||||
);
|
||||
|
17
lib/.eslintrc.js
Normal file
17
lib/.eslintrc.js
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) Sapphirecode - All Rights Reserved
|
||||
* This file is part of Requestor which is released under BSD-3-Clause.
|
||||
* See file 'LICENSE' for full license details.
|
||||
* Created by Timo Hocker <timo@sapphirecode.ovh>, March 2020
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
env: {
|
||||
commonjs: true,
|
||||
es6: true,
|
||||
node: true
|
||||
},
|
||||
extends: [
|
||||
'@sapphirecode/eslint-config-ts'
|
||||
]
|
||||
}
|
8
lib/CrudHandler.ts
Normal file
8
lib/CrudHandler.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
export interface CrudHandler {
|
||||
create(req: Request, res: Response): Promise<void>;
|
||||
read(req: Request, res: Response): Promise<void>;
|
||||
update(req: Request, res: Response): Promise<void>;
|
||||
delete(req: Request, res: Response): Promise<void>;
|
||||
}
|
160
lib/DatabaseCrudHandler.ts
Normal file
160
lib/DatabaseCrudHandler.ts
Normal file
@ -0,0 +1,160 @@
|
||||
import { Request, Response, Router } from 'express';
|
||||
import { http } from '@sapphirecode/consts';
|
||||
import { ControlModel, DatabaseModel } from '@sapphirecode/modelling';
|
||||
import { CrudHandler } from './CrudHandler';
|
||||
import { HttpHandler } from './HttpHandler';
|
||||
import { DatabaseCrudOptionsReader } from './DatabaseCrudOptionsReader';
|
||||
import { DatabaseCrudOptions } from './DatabaseCrudOptions';
|
||||
|
||||
export class DatabaseCrudHandler extends HttpHandler implements CrudHandler {
|
||||
protected cm:
|
||||
new (object: Record<string, string|number|boolean>) => ControlModel;
|
||||
|
||||
protected dm: new (id?: number) => DatabaseModel;
|
||||
protected options: DatabaseCrudOptionsReader;
|
||||
|
||||
public constructor (
|
||||
cm: new (object: Record<string, string|number|boolean>) => ControlModel,
|
||||
dm: new (id?: number) => DatabaseModel,
|
||||
options: DatabaseCrudOptions = {}
|
||||
) {
|
||||
super ();
|
||||
this.cm = cm;
|
||||
this.dm = dm;
|
||||
this.options = new DatabaseCrudOptionsReader (options);
|
||||
}
|
||||
|
||||
protected validate_body (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Record<string, unknown> | null> | Record<string, unknown> | null {
|
||||
if (typeof req.body === 'undefined') {
|
||||
res.status (http.status_bad_request);
|
||||
res.end ('body was undefined');
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return JSON.parse (req.body);
|
||||
}
|
||||
catch (e) {
|
||||
res.status (http.status_bad_request);
|
||||
res.end ('invalid json input');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public async create (req: Request, res: Response): Promise<void> {
|
||||
if (!await this.options.create_authorization (req, res))
|
||||
return;
|
||||
|
||||
const body_data = await this.validate_body (req, res);
|
||||
if (body_data === null)
|
||||
return;
|
||||
|
||||
const cm = new this.cm (body_data as Record<string|string, number|boolean>);
|
||||
cm.update ();
|
||||
|
||||
const dm = new this.dm;
|
||||
dm.assign (cm);
|
||||
await dm.write ();
|
||||
|
||||
res.status (http.status_created)
|
||||
.end (dm.id);
|
||||
}
|
||||
|
||||
public async read (req: Request, res: Response): Promise<void> {
|
||||
if (!await this.options.read_authorization (req, res))
|
||||
return;
|
||||
|
||||
if (typeof req.headers.id === 'undefined') {
|
||||
res.status (http.status_bad_request)
|
||||
.end ('id undefined');
|
||||
return;
|
||||
}
|
||||
|
||||
const dm = new this.dm (parseInt (req.headers.id as string));
|
||||
const found = await dm.read ();
|
||||
|
||||
const cm = new this.cm (dm.get_data ());
|
||||
cm.update ();
|
||||
|
||||
res.status (found ? http.status_ok : http.status_not_found)
|
||||
.json (cm.get_data ());
|
||||
}
|
||||
|
||||
public async update (req: Request, res: Response): Promise<void> {
|
||||
if (!await this.options.update_authorization (req, res))
|
||||
return;
|
||||
|
||||
const body_data = await this.validate_body (req, res);
|
||||
if (body_data === null)
|
||||
return;
|
||||
|
||||
if (typeof req.headers.id === 'undefined') {
|
||||
res.status (http.status_bad_request)
|
||||
.end ('id undefined');
|
||||
return;
|
||||
}
|
||||
|
||||
const dm = new this.dm (parseInt (req.headers.id as string));
|
||||
const found = await dm.read ();
|
||||
if (!found) {
|
||||
res.status (http.status_not_found)
|
||||
.end ();
|
||||
return;
|
||||
}
|
||||
|
||||
const cm = new this.cm (dm.get_data ());
|
||||
cm.update ();
|
||||
|
||||
cm.assign_object (body_data);
|
||||
cm.update ();
|
||||
|
||||
dm.assign (cm);
|
||||
|
||||
const written = await dm.write ();
|
||||
|
||||
res.status (written ? http.status_ok : http.status_internal_server_error)
|
||||
.end ();
|
||||
}
|
||||
|
||||
public async delete (req: Request, res: Response): Promise<void> {
|
||||
if (!await this.options.delete_authorization (req, res))
|
||||
return;
|
||||
|
||||
if (typeof req.headers.id === 'undefined') {
|
||||
res.status (http.status_bad_request)
|
||||
.end ('id undefined');
|
||||
return;
|
||||
}
|
||||
|
||||
const dm = new this.dm (parseInt (req.headers.id as string));
|
||||
const found = await dm.read ();
|
||||
if (!found) {
|
||||
res.status (http.status_not_found)
|
||||
.end ();
|
||||
return;
|
||||
}
|
||||
|
||||
const deleted = await dm.delete ();
|
||||
|
||||
res.status (deleted ? http.status_ok : http.status_internal_server_error)
|
||||
.end ();
|
||||
}
|
||||
|
||||
protected async create_or_update (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
if (typeof req.headers.id === 'undefined')
|
||||
await this.create (req, res);
|
||||
else
|
||||
await this.update (req, res);
|
||||
}
|
||||
|
||||
public register_handlers (router: Router): void {
|
||||
router.post ('/', this.create_or_update);
|
||||
router.get ('/', this.read);
|
||||
router.delete ('/', this.delete);
|
||||
}
|
||||
}
|
17
lib/DatabaseCrudOptions.ts
Normal file
17
lib/DatabaseCrudOptions.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
type Authorization = {
|
||||
(req: Request, res: Response): Promise<boolean>;
|
||||
(req: Request, res: Response, next: Function): unknown;
|
||||
}
|
||||
|
||||
interface DatabaseCrudOptions {
|
||||
general_authorization?: Authorization;
|
||||
create_authorization?: Authorization;
|
||||
read_authorization?: Authorization;
|
||||
update_authorization?: Authorization;
|
||||
delete_authorization?: Authorization;
|
||||
optional_columns?: Array<string>;
|
||||
}
|
||||
|
||||
export { Authorization, DatabaseCrudOptions };
|
74
lib/DatabaseCrudOptionsReader.ts
Normal file
74
lib/DatabaseCrudOptionsReader.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import { Request, Response } from 'express';
|
||||
import { DatabaseCrudOptions, Authorization } from './DatabaseCrudOptions';
|
||||
|
||||
type AuthRunner = {
|
||||
(req: Request, res: Response): Promise<boolean>;
|
||||
}
|
||||
|
||||
export class DatabaseCrudOptionsReader {
|
||||
private _options: DatabaseCrudOptions;
|
||||
|
||||
public constructor (options: DatabaseCrudOptions) {
|
||||
this._options = options;
|
||||
}
|
||||
|
||||
private get_auth_runner (
|
||||
auth?: Authorization
|
||||
): AuthRunner {
|
||||
if (typeof auth === 'undefined')
|
||||
return (): Promise<boolean> => new Promise ((r) => r (true));
|
||||
return (req, res): Promise<boolean> => new Promise (
|
||||
(resolve: (value: boolean) => void) => {
|
||||
(async (): Promise<void> => {
|
||||
let resolved = false;
|
||||
const result = await auth (req, res, (cb: unknown) => {
|
||||
resolved = true;
|
||||
resolve (typeof cb === 'undefined' || cb === true);
|
||||
});
|
||||
if (!resolved)
|
||||
resolve (result === true);
|
||||
}) ();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public get optional_columns (): Array<string> | undefined {
|
||||
return this._options.optional_columns;
|
||||
}
|
||||
|
||||
public get create_authorization (): Authorization {
|
||||
const general = this.get_auth_runner (this._options.general_authorization);
|
||||
const specific = this.get_auth_runner (this._options.create_authorization);
|
||||
return async (req: Request, res: Response): Promise<boolean> => {
|
||||
const result = (await general (req, res)) && (await specific (req, res));
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
public get read_authorization (): Authorization {
|
||||
const general = this.get_auth_runner (this._options.general_authorization);
|
||||
const specific = this.get_auth_runner (this._options.read_authorization);
|
||||
return async (req: Request, res: Response): Promise<boolean> => {
|
||||
const result = (await general (req, res)) && (await specific (req, res));
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
public get update_authorization (): Authorization {
|
||||
const general = this.get_auth_runner (this._options.general_authorization);
|
||||
const specific = this.get_auth_runner (this._options.update_authorization);
|
||||
return async (req: Request, res: Response): Promise<boolean> => {
|
||||
const result = (await general (req, res)) && (await specific (req, res));
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
public get delete_authorization (): Authorization {
|
||||
const general = this.get_auth_runner (this._options.general_authorization);
|
||||
const specific = this.get_auth_runner (this._options.delete_authorization);
|
||||
return async (req: Request, res: Response): Promise<boolean> => {
|
||||
const result = (await general (req, res)) && (await specific (req, res));
|
||||
return result;
|
||||
};
|
||||
}
|
||||
}
|
11
lib/HttpHandler.ts
Normal file
11
lib/HttpHandler.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Router } from 'express';
|
||||
|
||||
export abstract class HttpHandler {
|
||||
public abstract register_handlers(router: Router): void;
|
||||
|
||||
public get_router (): Router {
|
||||
const r = Router ();
|
||||
this.register_handlers (r);
|
||||
return r;
|
||||
}
|
||||
}
|
3
lib/index.ts
Normal file
3
lib/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export { HttpHandler } from './HttpHandler';
|
||||
export { CrudHandler } from './CrudHandler';
|
||||
export { DatabaseCrudHandler } from './DatabaseCrudHandler';
|
2101
package-lock.json
generated
2101
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
42
package.json
42
package.json
@ -1,10 +1,13 @@
|
||||
{
|
||||
"name": "@scode/requestor",
|
||||
"version": "1.0.3",
|
||||
"description": "Split express paths into individual files to make api programming more structured",
|
||||
"main": "index.js",
|
||||
"name": "@sapphirecode/requestor",
|
||||
"version": "1.0.0",
|
||||
"description": "Express handler templates",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
"test": "echo \"no test\"",
|
||||
"compile": "tsc",
|
||||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue,.mjs",
|
||||
"ci": "yarn --frozen-lockfile && node jenkins.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -14,15 +17,24 @@
|
||||
"express"
|
||||
],
|
||||
"author": "Timo Hocker",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-config-standard": "^14.1.0",
|
||||
"eslint-plugin-import": "^2.19.1",
|
||||
"eslint-plugin-node": "^10.0.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"mocha": "^6.2.2"
|
||||
}
|
||||
"@ava/typescript": "^1.1.1",
|
||||
"@sapphirecode/eslint-config-ts": "^1.0.29",
|
||||
"eslint": "^6.8.0",
|
||||
"typescript": "^3.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sapphirecode/consts": "^1.1.9",
|
||||
"@sapphirecode/modelling": "^1.0.19",
|
||||
"@types/express": "^4.17.6",
|
||||
"express": "^4.17.1"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"/dist/"
|
||||
]
|
||||
}
|
||||
|
77
test/main.js
77
test/main.js
@ -1,77 +0,0 @@
|
||||
const { describe, it, beforeEach } = require('mocha');
|
||||
const expect = require('chai').expect;
|
||||
|
||||
const requestor = require('../index');
|
||||
|
||||
const mock = {
|
||||
registered: {},
|
||||
post: function (path, handler) {
|
||||
this.registered['post-' + path] = handler;
|
||||
},
|
||||
get: function (path, handler) {
|
||||
this.registered['get-' + path] = handler;
|
||||
},
|
||||
put: function (path, handler) {
|
||||
this.registered['put-' + path] = handler;
|
||||
},
|
||||
delete: function (path, handler) {
|
||||
this.registered['delete-' + path] = handler;
|
||||
},
|
||||
all: function (path, handler) {
|
||||
this.registered['all-' + path] = handler;
|
||||
}
|
||||
};
|
||||
|
||||
describe('requestor', () => {
|
||||
beforeEach(() => {
|
||||
mock.registered = {};
|
||||
});
|
||||
|
||||
it('should detect all requests on root', () => {
|
||||
requestor(mock, './test/root');
|
||||
expect(mock.registered).to.have.all.keys([
|
||||
'post-/',
|
||||
'get-/',
|
||||
'put-/',
|
||||
'delete-/',
|
||||
'all-/'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should detect requests on root.subfolder', () => {
|
||||
requestor(mock, './test/root.sub');
|
||||
expect(mock.registered).to.have.all.keys([
|
||||
'post-/sub/',
|
||||
'get-/sub/',
|
||||
'put-/sub/',
|
||||
'delete-/sub/',
|
||||
'all-/sub/'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should detect requests on subfolder', () => {
|
||||
requestor(mock, './test/sub');
|
||||
expect(mock.registered).to.have.all.keys([
|
||||
'post-/sub/',
|
||||
'get-/sub/',
|
||||
'put-/sub/',
|
||||
'delete-/sub/',
|
||||
'all-/sub/',
|
||||
'get-/sub/lv1/lv2/lv3/',
|
||||
'all-/sub/root/'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should build requests with subdirectory', () => {
|
||||
requestor(mock, './test/sub', {}, 'test');
|
||||
expect(mock.registered).to.have.all.keys([
|
||||
'post-/test/sub/',
|
||||
'get-/test/sub/',
|
||||
'put-/test/sub/',
|
||||
'delete-/test/sub/',
|
||||
'all-/test/sub/',
|
||||
'get-/test/sub/lv1/lv2/lv3/',
|
||||
'all-/test/sub/root/'
|
||||
]);
|
||||
});
|
||||
});
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (req, res, next, opts) => {
|
||||
// dummy endpoint: do nothing
|
||||
};
|
66
tsconfig.json
Normal file
66
tsconfig.json
Normal file
@ -0,0 +1,66 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
"declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
"outDir": "./dist", /* Redirect output structure to the directory. */
|
||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
|
||||
/* Advanced Options */
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||
}
|
||||
}
|
1922
yarn-error.log
Normal file
1922
yarn-error.log
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user