├── LICENSE ├── README.md ├── concept.png ├── main.go └── verify ├── index.js ├── package-lock.json └── package.json /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 OpenFaaS Author(s) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## AWS Lambda Shim for OpenFaaS 2 | 3 | This example shows how to run an unmodified AWS Lambda function on OpenFaaS. The same code could be built into an OpenFaaS tempalte as is uploaded to S3 to run on AWS Lambda platform. 4 | 5 | This is highly experimental / early-work and only a PoC. 6 | 7 | Watch the [Video demo / walk-through](https://www.youtube.com/watch?v=o_PiCR3p74k) 8 | 9 | ## Run locally 10 | 11 | ### Run the Lambda runtime 12 | 13 | You'll need Node 8, 10 or 11 installed on your local machine. 14 | 15 | * Clone Docker Lambda for Node.js 10 16 | 17 | ``` 18 | git clone https://github.com/lambci/node-custom-lambda 19 | cd node-custom-lambda/v10.x 20 | cd test 21 | npm i 22 | cd .. 23 | 24 | LAMBDA_TASK_ROOT=./test _HANDLER=".handler" AWS_LAMBDA_RUNTIME_API=127.0.0.1:9000 node bootstrap.js 25 | ``` 26 | 27 | This example uses a function in the "test" folder, edit it if you want to. 28 | 29 | ### Run the OpenFaaS shim 30 | 31 | You'll need Go 1.10 or Go 1.11 installed locally for this part. 32 | 33 | * Clone the shim and run it: 34 | 35 | ``` 36 | git clone https://github.com/alexellis/lambda-on-openfaas-poc 37 | cd lambda-on-openfaas-poc 38 | 39 | AWS_LAMBDA_FUNCTION_NAME=openfaas port=8080 shim_port=9000 go run main.go 40 | ``` 41 | 42 | ### Invoke the Lambda function via the OpenFaaS shim 43 | 44 | ``` 45 | for i in {0..100} ; do curl localhost:8080 -d '{"invocation": "#: '$i'"}' && echo ; done 46 | ``` 47 | 48 | If you like run this in multiple windows at the same time: 49 | 50 | ``` 51 | ( 52 | for i in {0..100} ; do curl localhost:8080 -d '{"invocation": "#: '$i'"}' && echo ; done & 53 | for i in {101..201} ; do curl localhost:8080 -d '{"invocation": "#: '$i'"}' && echo ; done & 54 | for i in {202..302} ; do curl localhost:8080 -d '{"invocation": "#: '$i'"}' && echo ; done & 55 | ) 56 | ``` 57 | 58 | ## Conceptual diagram 59 | 60 | ![](./concept.png) 61 | 62 | ## How do we know it works? 63 | 64 | You can test it out using the Node.js tester program in the verify folder. 65 | 66 | It verifies that if a request inputs a certain number that it's also echoed in the response. 67 | 68 | ``` 69 | cd verify 70 | npm i 71 | node index.js 72 | ``` 73 | 74 | If all the responses are correct you'll see `[x]` printed back on each line, otherwise the delta. 75 | 76 | Test in parallel: 77 | 78 | ``` 79 | ( 80 | node index.js & 81 | node index.js & 82 | node index.js & 83 | ) 84 | ``` 85 | 86 | ## What next? 87 | 88 | This code needs packaging as a Docker image to be deployed and run on OpenFaaS. It could be part of the of-watchdog project as an additional mode, i.e. `lambda-shim` or similar. 89 | 90 | Is this finished/tested? No it's just an early proof-of-concept. Some internal pub/sub mechanism is probably required. 91 | 92 | See also: 93 | 94 | * [Lambda custom runtimes](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html) 95 | * [Lambda Runtime Interface](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html) 96 | * [Blog: OpenFaaS Template Store](https://www.openfaas.com/blog/template-store/) 97 | -------------------------------------------------------------------------------- /concept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexellis/lambda-on-openfaas-poc/HEAD/concept.png -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | "net/http" 8 | "os" 9 | "path" 10 | "sync" 11 | 12 | "github.com/docker/distribution/uuid" 13 | "github.com/gorilla/mux" 14 | ) 15 | 16 | type Invocation struct { 17 | Req []byte 18 | Res []byte 19 | } 20 | 21 | func main() { 22 | 23 | work := make(chan *Invocation) 24 | responseChannel := make(chan *Invocation) 25 | 26 | r := mux.NewRouter() 27 | 28 | r.HandleFunc("/2018-06-01/runtime/invocation/next", nextHandler(work)) 29 | r.HandleFunc("/2018-06-01/runtime/invocation/{id}/response", responseHandler(responseChannel)) 30 | 31 | s := &http.Server{ 32 | Addr: fmt.Sprintf(":%s", os.Getenv("shim_port")), 33 | MaxHeaderBytes: 1 << 20, // Max header of 1MB 34 | } 35 | 36 | ofR := mux.NewRouter() 37 | ofR.HandleFunc("/", enqueue(work, responseChannel)) 38 | 39 | http.Handle("/", ofR) 40 | http.Handle("/2018-06-01/", r) 41 | ofServer := &http.Server{ 42 | Addr: fmt.Sprintf(":%s", os.Getenv("port")), 43 | MaxHeaderBytes: 1 << 20, // Max header of 1MB 44 | } 45 | 46 | wg := sync.WaitGroup{} 47 | wg.Add(2) 48 | go func() { 49 | log.Printf("Lambda shim listening on port: %s", os.Getenv("shim_port")) 50 | log.Fatal(s.ListenAndServe()) 51 | wg.Done() 52 | }() 53 | 54 | go func() { 55 | log.Printf("Watchdog shim listening on port: %s", os.Getenv("port")) 56 | log.Fatal(ofServer.ListenAndServe()) 57 | wg.Done() 58 | }() 59 | 60 | ioutil.WriteFile(path.Join(os.TempDir(), ".lock"), []byte{}, 0775) 61 | 62 | wg.Wait() 63 | } 64 | 65 | func nextHandler(workCh chan *Invocation) func(http.ResponseWriter, *http.Request) { 66 | return func(w http.ResponseWriter, r *http.Request) { 67 | defer r.Body.Close() 68 | 69 | select { 70 | case invocation := <-workCh: 71 | 72 | callID := uuid.Generate().String() 73 | 74 | w.Header().Set("lambda-runtime-aws-request-id", callID) 75 | log.Println("next - " + callID) 76 | host, _ := os.Hostname() 77 | w.Header().Set("lambda-runtime-invoked-function-arn", host) 78 | 79 | w.WriteHeader(http.StatusOK) 80 | log.Println("next - [req] " + string(invocation.Req)) 81 | w.Write(invocation.Req) 82 | 83 | } 84 | } 85 | } 86 | 87 | func enqueue(workCh chan *Invocation, doneCh chan *Invocation) func(http.ResponseWriter, *http.Request) { 88 | return func(w http.ResponseWriter, r *http.Request) { 89 | log.Println("enqueue started: " + r.RequestURI) 90 | invocation := Invocation{} 91 | if r.Body != nil { 92 | body, _ := ioutil.ReadAll(r.Body) 93 | log.Println("enqueue data -> " + string(body)) 94 | invocation.Req = body 95 | } 96 | 97 | workCh <- &invocation 98 | 99 | select { 100 | case invocationRes := <-doneCh: 101 | 102 | w.Write(invocationRes.Res) 103 | log.Println("enqueue done") 104 | return 105 | } 106 | } 107 | } 108 | 109 | func responseHandler(responseWorkChannel chan *Invocation) func(http.ResponseWriter, *http.Request) { 110 | return func(w http.ResponseWriter, r *http.Request) { 111 | defer r.Body.Close() 112 | 113 | w.WriteHeader(http.StatusAccepted) 114 | log.Println("StatusAccepted: " + r.RequestURI) 115 | 116 | if r.Body != nil { 117 | body, _ := ioutil.ReadAll(r.Body) 118 | 119 | log.Println("Response: " + string(body)) 120 | 121 | invocation := Invocation{} 122 | invocation.Res = body 123 | responseWorkChannel <- &invocation 124 | } 125 | 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /verify/index.js: -------------------------------------------------------------------------------- 1 | const request = require('request') 2 | 3 | for(let i=0;i<100;i++) { 4 | var x = i; 5 | let r = { 6 | body: {"input": x.toString()}, 7 | json: true, 8 | uri: "http://localhost:8080" 9 | }; 10 | 11 | request.post(r, (err, res, bodyOut) => { 12 | if(err) { 13 | console.error(err); 14 | } 15 | 16 | if(bodyOut.event.input == r.body.input){ 17 | console.log("[x]"); 18 | } else { 19 | console.log(bodyOut.event.input,r.body.input); 20 | } 21 | 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /verify/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get-set", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "ajv": { 8 | "version": "6.6.1", 9 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz", 10 | "integrity": "sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==", 11 | "requires": { 12 | "fast-deep-equal": "^2.0.1", 13 | "fast-json-stable-stringify": "^2.0.0", 14 | "json-schema-traverse": "^0.4.1", 15 | "uri-js": "^4.2.2" 16 | } 17 | }, 18 | "asn1": { 19 | "version": "0.2.4", 20 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 21 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 22 | "requires": { 23 | "safer-buffer": "~2.1.0" 24 | } 25 | }, 26 | "assert-plus": { 27 | "version": "1.0.0", 28 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 29 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 30 | }, 31 | "asynckit": { 32 | "version": "0.4.0", 33 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 34 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 35 | }, 36 | "aws-sign2": { 37 | "version": "0.7.0", 38 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 39 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 40 | }, 41 | "aws4": { 42 | "version": "1.8.0", 43 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", 44 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" 45 | }, 46 | "bcrypt-pbkdf": { 47 | "version": "1.0.2", 48 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 49 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 50 | "requires": { 51 | "tweetnacl": "^0.14.3" 52 | } 53 | }, 54 | "caseless": { 55 | "version": "0.12.0", 56 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 57 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 58 | }, 59 | "combined-stream": { 60 | "version": "1.0.7", 61 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", 62 | "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", 63 | "requires": { 64 | "delayed-stream": "~1.0.0" 65 | } 66 | }, 67 | "core-util-is": { 68 | "version": "1.0.2", 69 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 70 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 71 | }, 72 | "dashdash": { 73 | "version": "1.14.1", 74 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 75 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 76 | "requires": { 77 | "assert-plus": "^1.0.0" 78 | } 79 | }, 80 | "delayed-stream": { 81 | "version": "1.0.0", 82 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 83 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 84 | }, 85 | "ecc-jsbn": { 86 | "version": "0.1.2", 87 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 88 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 89 | "requires": { 90 | "jsbn": "~0.1.0", 91 | "safer-buffer": "^2.1.0" 92 | } 93 | }, 94 | "extend": { 95 | "version": "3.0.2", 96 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 97 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 98 | }, 99 | "extsprintf": { 100 | "version": "1.3.0", 101 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 102 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 103 | }, 104 | "fast-deep-equal": { 105 | "version": "2.0.1", 106 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 107 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" 108 | }, 109 | "fast-json-stable-stringify": { 110 | "version": "2.0.0", 111 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 112 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 113 | }, 114 | "forever-agent": { 115 | "version": "0.6.1", 116 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 117 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 118 | }, 119 | "form-data": { 120 | "version": "2.3.3", 121 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 122 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 123 | "requires": { 124 | "asynckit": "^0.4.0", 125 | "combined-stream": "^1.0.6", 126 | "mime-types": "^2.1.12" 127 | } 128 | }, 129 | "getpass": { 130 | "version": "0.1.7", 131 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 132 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 133 | "requires": { 134 | "assert-plus": "^1.0.0" 135 | } 136 | }, 137 | "har-schema": { 138 | "version": "2.0.0", 139 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 140 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 141 | }, 142 | "har-validator": { 143 | "version": "5.1.3", 144 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", 145 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", 146 | "requires": { 147 | "ajv": "^6.5.5", 148 | "har-schema": "^2.0.0" 149 | } 150 | }, 151 | "http-signature": { 152 | "version": "1.2.0", 153 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 154 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 155 | "requires": { 156 | "assert-plus": "^1.0.0", 157 | "jsprim": "^1.2.2", 158 | "sshpk": "^1.7.0" 159 | } 160 | }, 161 | "is-typedarray": { 162 | "version": "1.0.0", 163 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 164 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 165 | }, 166 | "isstream": { 167 | "version": "0.1.2", 168 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 169 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 170 | }, 171 | "jsbn": { 172 | "version": "0.1.1", 173 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 174 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 175 | }, 176 | "json-schema": { 177 | "version": "0.2.3", 178 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 179 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 180 | }, 181 | "json-schema-traverse": { 182 | "version": "0.4.1", 183 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 184 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 185 | }, 186 | "json-stringify-safe": { 187 | "version": "5.0.1", 188 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 189 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 190 | }, 191 | "jsprim": { 192 | "version": "1.4.1", 193 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 194 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 195 | "requires": { 196 | "assert-plus": "1.0.0", 197 | "extsprintf": "1.3.0", 198 | "json-schema": "0.2.3", 199 | "verror": "1.10.0" 200 | } 201 | }, 202 | "mime-db": { 203 | "version": "1.37.0", 204 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", 205 | "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" 206 | }, 207 | "mime-types": { 208 | "version": "2.1.21", 209 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", 210 | "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", 211 | "requires": { 212 | "mime-db": "~1.37.0" 213 | } 214 | }, 215 | "oauth-sign": { 216 | "version": "0.9.0", 217 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 218 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 219 | }, 220 | "performance-now": { 221 | "version": "2.1.0", 222 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 223 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 224 | }, 225 | "psl": { 226 | "version": "1.1.29", 227 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", 228 | "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" 229 | }, 230 | "punycode": { 231 | "version": "2.1.1", 232 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 233 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 234 | }, 235 | "qs": { 236 | "version": "6.5.2", 237 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 238 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 239 | }, 240 | "request": { 241 | "version": "2.88.0", 242 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", 243 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", 244 | "requires": { 245 | "aws-sign2": "~0.7.0", 246 | "aws4": "^1.8.0", 247 | "caseless": "~0.12.0", 248 | "combined-stream": "~1.0.6", 249 | "extend": "~3.0.2", 250 | "forever-agent": "~0.6.1", 251 | "form-data": "~2.3.2", 252 | "har-validator": "~5.1.0", 253 | "http-signature": "~1.2.0", 254 | "is-typedarray": "~1.0.0", 255 | "isstream": "~0.1.2", 256 | "json-stringify-safe": "~5.0.1", 257 | "mime-types": "~2.1.19", 258 | "oauth-sign": "~0.9.0", 259 | "performance-now": "^2.1.0", 260 | "qs": "~6.5.2", 261 | "safe-buffer": "^5.1.2", 262 | "tough-cookie": "~2.4.3", 263 | "tunnel-agent": "^0.6.0", 264 | "uuid": "^3.3.2" 265 | } 266 | }, 267 | "safe-buffer": { 268 | "version": "5.1.2", 269 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 270 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 271 | }, 272 | "safer-buffer": { 273 | "version": "2.1.2", 274 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 275 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 276 | }, 277 | "sshpk": { 278 | "version": "1.15.2", 279 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", 280 | "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", 281 | "requires": { 282 | "asn1": "~0.2.3", 283 | "assert-plus": "^1.0.0", 284 | "bcrypt-pbkdf": "^1.0.0", 285 | "dashdash": "^1.12.0", 286 | "ecc-jsbn": "~0.1.1", 287 | "getpass": "^0.1.1", 288 | "jsbn": "~0.1.0", 289 | "safer-buffer": "^2.0.2", 290 | "tweetnacl": "~0.14.0" 291 | } 292 | }, 293 | "tough-cookie": { 294 | "version": "2.4.3", 295 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 296 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 297 | "requires": { 298 | "psl": "^1.1.24", 299 | "punycode": "^1.4.1" 300 | }, 301 | "dependencies": { 302 | "punycode": { 303 | "version": "1.4.1", 304 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 305 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 306 | } 307 | } 308 | }, 309 | "tunnel-agent": { 310 | "version": "0.6.0", 311 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 312 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 313 | "requires": { 314 | "safe-buffer": "^5.0.1" 315 | } 316 | }, 317 | "tweetnacl": { 318 | "version": "0.14.5", 319 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 320 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 321 | }, 322 | "uri-js": { 323 | "version": "4.2.2", 324 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 325 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 326 | "requires": { 327 | "punycode": "^2.1.0" 328 | } 329 | }, 330 | "uuid": { 331 | "version": "3.3.2", 332 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 333 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" 334 | }, 335 | "verror": { 336 | "version": "1.10.0", 337 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 338 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 339 | "requires": { 340 | "assert-plus": "^1.0.0", 341 | "core-util-is": "1.0.2", 342 | "extsprintf": "^1.2.0" 343 | } 344 | } 345 | } 346 | } 347 | -------------------------------------------------------------------------------- /verify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get-set", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "request": "^2.88.0" 14 | } 15 | } 16 | --------------------------------------------------------------------------------