├── .gitignore ├── LICENSE ├── README.md ├── graphql-example ├── package.json ├── resolvers.js ├── schema.gql ├── server.js └── yarn.lock ├── lesson ├── package.json ├── resolvers.js ├── schema.gql ├── server.js └── yarn.lock └── rest ├── groups.json ├── idols.json ├── package.json ├── server.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Sira Sujjinanont 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 | # rest-to-graphql 2 | Example that demo on first Facebook Hackathon Bangkok. Oct 27, 2017 3 | 4 | 5 | # Credit 6 | Member database borrow from http://stage48.net 7 | -------------------------------------------------------------------------------- /graphql-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "apollo-server-express": "^1.2.0", 4 | "body-parser": "^1.18.2", 5 | "express": "^4.16.2", 6 | "graphql": "^0.11.7", 7 | "graphql-tools": "^2.6.1", 8 | "isomorphic-fetch": "^2.2.1" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /graphql-example/resolvers.js: -------------------------------------------------------------------------------- 1 | const fetch = require('isomorphic-fetch') 2 | 3 | const request = (path, query) => { 4 | return fetch(`http://localhost:3000${path}`) 5 | .then(function(response) { 6 | if (response.status >= 400) { 7 | throw new Error("Bad response from server"); 8 | } 9 | return response.json() 10 | }) 11 | } 12 | 13 | module.exports = { 14 | Query: { 15 | groups() { 16 | return request('/groups') 17 | }, 18 | async idols(doc, { limit = 10 }) { 19 | const result = await request('/idols') 20 | return result.slice(0, limit) 21 | } 22 | }, 23 | Mutation: { 24 | addIdol(doc, { name, team }) { 25 | return ({ 26 | name, 27 | team 28 | }) 29 | } 30 | }, 31 | Group: { 32 | }, 33 | Idol: { 34 | age(doc) { 35 | const birthdate = new Date(doc.birthdate) 36 | const currentYear = new Date().getYear() 37 | return currentYear - birthdate.getYear() 38 | }, 39 | height(doc, { unit = 'CM' }) { 40 | return unit === 'CM' ? doc.height : parseFloat(((doc.height / 2.54) / 12).toFixed(2)) 41 | }, 42 | group(doc) { 43 | return request(`/groups/${doc.group}`) 44 | } 45 | }, 46 | } -------------------------------------------------------------------------------- /graphql-example/schema.gql: -------------------------------------------------------------------------------- 1 | enum HeightUnit { 2 | CM 3 | FOOT 4 | } 5 | type Group { 6 | id: ID! 7 | name: String 8 | location: String 9 | since: String 10 | } 11 | 12 | # Idol information 13 | type Idol { 14 | id: ID! # the ! means that every author object _must_ have an id 15 | # Member in team 16 | team: String 17 | picture: String 18 | # Name in roman characters 19 | romaji: String 20 | # Name in local 21 | name: String 22 | birthdate: String 23 | birthplace: String 24 | age: Int 25 | bloodType: String 26 | height(unit: HeightUnit): Float 27 | agency: String 28 | generation: String 29 | group: Group 30 | } 31 | 32 | type Query { 33 | # Retrieve for idols information 34 | idols(limit: Int): [Idol] 35 | # Retrieve for groups information 36 | groups: [Group] 37 | } 38 | 39 | type Mutation { 40 | addIdol(name: String, team: String): Idol 41 | } 42 | 43 | schema { 44 | query: Query 45 | mutation: Mutation 46 | } -------------------------------------------------------------------------------- /graphql-example/server.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const express = require('express') 3 | const { makeExecutableSchema } = require('graphql-tools') 4 | const bodyParser = require('body-parser') 5 | const { graphqlExpress, graphiqlExpress } = require('apollo-server-express') 6 | 7 | const resolvers = require('./resolvers') 8 | const typeDefs = fs.readFileSync('./schema.gql', 'utf8') 9 | 10 | const schema = makeExecutableSchema({ 11 | typeDefs, 12 | resolvers 13 | }) 14 | 15 | const app = express() 16 | app.use('/graphql', bodyParser.json(), graphqlExpress({ schema })) 17 | app.use('/graphiql', graphiqlExpress({ 18 | endpointURL: '/graphql', 19 | })) 20 | 21 | const PORT = process.env.PORT || 5000 22 | app.listen(PORT, () => { 23 | console.log(`listen http://localhost:${PORT}`) 24 | }) 25 | -------------------------------------------------------------------------------- /graphql-example/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | accepts@~1.3.4: 6 | version "1.3.4" 7 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" 8 | dependencies: 9 | mime-types "~2.1.16" 10 | negotiator "0.6.1" 11 | 12 | apollo-cache-control@^0.0.x: 13 | version "0.0.7" 14 | resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.0.7.tgz#ffef56413a429a1ce204be5b78d248c4fe3b67ac" 15 | dependencies: 16 | graphql-extensions "^0.0.x" 17 | 18 | apollo-server-core@^1.2.0: 19 | version "1.2.0" 20 | resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.2.0.tgz#e851c47444991b6f89f88529237076b83e01e8ee" 21 | dependencies: 22 | apollo-cache-control "^0.0.x" 23 | apollo-tracing "^0.1.0" 24 | graphql-extensions "^0.0.x" 25 | 26 | apollo-server-express@^1.2.0: 27 | version "1.2.0" 28 | resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.2.0.tgz#026b12b453b8ecac6044b205b6a85fe596fb5f9e" 29 | dependencies: 30 | apollo-server-core "^1.2.0" 31 | apollo-server-module-graphiql "^1.2.0" 32 | 33 | apollo-server-module-graphiql@^1.2.0: 34 | version "1.2.0" 35 | resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.2.0.tgz#899d84f3b747795dbbfc8354aa51622ef038151c" 36 | 37 | apollo-tracing@^0.1.0: 38 | version "0.1.1" 39 | resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.1.1.tgz#7a5707543fc102f81cda7ba45b98331a82a6750b" 40 | dependencies: 41 | graphql-extensions "^0.0.x" 42 | 43 | apollo-utilities@^0.1.1-0: 44 | version "0.1.1-1" 45 | resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-0.1.1-1.tgz#a637c2a5b49e06f20dd9adf7c55ec1ff69a97592" 46 | 47 | array-flatten@1.1.1: 48 | version "1.1.1" 49 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 50 | 51 | body-parser@1.18.2, body-parser@^1.18.2: 52 | version "1.18.2" 53 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" 54 | dependencies: 55 | bytes "3.0.0" 56 | content-type "~1.0.4" 57 | debug "2.6.9" 58 | depd "~1.1.1" 59 | http-errors "~1.6.2" 60 | iconv-lite "0.4.19" 61 | on-finished "~2.3.0" 62 | qs "6.5.1" 63 | raw-body "2.3.2" 64 | type-is "~1.6.15" 65 | 66 | bytes@3.0.0: 67 | version "3.0.0" 68 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" 69 | 70 | content-disposition@0.5.2: 71 | version "0.5.2" 72 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" 73 | 74 | content-type@~1.0.4: 75 | version "1.0.4" 76 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 77 | 78 | cookie-signature@1.0.6: 79 | version "1.0.6" 80 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 81 | 82 | cookie@0.3.1: 83 | version "0.3.1" 84 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" 85 | 86 | core-js@^2.5.1: 87 | version "2.5.1" 88 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" 89 | 90 | debug@2.6.9: 91 | version "2.6.9" 92 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 93 | dependencies: 94 | ms "2.0.0" 95 | 96 | depd@1.1.1, depd@~1.1.1: 97 | version "1.1.1" 98 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" 99 | 100 | deprecated-decorator@^0.1.6: 101 | version "0.1.6" 102 | resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" 103 | 104 | destroy@~1.0.4: 105 | version "1.0.4" 106 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 107 | 108 | ee-first@1.1.1: 109 | version "1.1.1" 110 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 111 | 112 | encodeurl@~1.0.1: 113 | version "1.0.1" 114 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" 115 | 116 | encoding@^0.1.11: 117 | version "0.1.12" 118 | resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" 119 | dependencies: 120 | iconv-lite "~0.4.13" 121 | 122 | escape-html@~1.0.3: 123 | version "1.0.3" 124 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 125 | 126 | etag@~1.8.1: 127 | version "1.8.1" 128 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 129 | 130 | express@^4.16.2: 131 | version "4.16.2" 132 | resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" 133 | dependencies: 134 | accepts "~1.3.4" 135 | array-flatten "1.1.1" 136 | body-parser "1.18.2" 137 | content-disposition "0.5.2" 138 | content-type "~1.0.4" 139 | cookie "0.3.1" 140 | cookie-signature "1.0.6" 141 | debug "2.6.9" 142 | depd "~1.1.1" 143 | encodeurl "~1.0.1" 144 | escape-html "~1.0.3" 145 | etag "~1.8.1" 146 | finalhandler "1.1.0" 147 | fresh "0.5.2" 148 | merge-descriptors "1.0.1" 149 | methods "~1.1.2" 150 | on-finished "~2.3.0" 151 | parseurl "~1.3.2" 152 | path-to-regexp "0.1.7" 153 | proxy-addr "~2.0.2" 154 | qs "6.5.1" 155 | range-parser "~1.2.0" 156 | safe-buffer "5.1.1" 157 | send "0.16.1" 158 | serve-static "1.13.1" 159 | setprototypeof "1.1.0" 160 | statuses "~1.3.1" 161 | type-is "~1.6.15" 162 | utils-merge "1.0.1" 163 | vary "~1.1.2" 164 | 165 | finalhandler@1.1.0: 166 | version "1.1.0" 167 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" 168 | dependencies: 169 | debug "2.6.9" 170 | encodeurl "~1.0.1" 171 | escape-html "~1.0.3" 172 | on-finished "~2.3.0" 173 | parseurl "~1.3.2" 174 | statuses "~1.3.1" 175 | unpipe "~1.0.0" 176 | 177 | forwarded@~0.1.2: 178 | version "0.1.2" 179 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" 180 | 181 | fresh@0.5.2: 182 | version "0.5.2" 183 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 184 | 185 | graphql-extensions@^0.0.x: 186 | version "0.0.5" 187 | resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.0.5.tgz#63bc4a3fd31aab12bfadf783cbc038a9a6937cf0" 188 | dependencies: 189 | core-js "^2.5.1" 190 | source-map-support "^0.5.0" 191 | 192 | graphql-tools@^2.6.1: 193 | version "2.6.1" 194 | resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-2.6.1.tgz#9f6d1600951a05b18b83c52986c42eee4fd3cb1b" 195 | dependencies: 196 | apollo-utilities "^0.1.1-0" 197 | deprecated-decorator "^0.1.6" 198 | uuid "^3.1.0" 199 | 200 | graphql@^0.11.7: 201 | version "0.11.7" 202 | resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.11.7.tgz#e5abaa9cb7b7cccb84e9f0836bf4370d268750c6" 203 | dependencies: 204 | iterall "1.1.3" 205 | 206 | http-errors@1.6.2, http-errors@~1.6.2: 207 | version "1.6.2" 208 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" 209 | dependencies: 210 | depd "1.1.1" 211 | inherits "2.0.3" 212 | setprototypeof "1.0.3" 213 | statuses ">= 1.3.1 < 2" 214 | 215 | iconv-lite@0.4.19, iconv-lite@~0.4.13: 216 | version "0.4.19" 217 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" 218 | 219 | inherits@2.0.3: 220 | version "2.0.3" 221 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 222 | 223 | ipaddr.js@1.5.2: 224 | version "1.5.2" 225 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0" 226 | 227 | is-stream@^1.0.1: 228 | version "1.1.0" 229 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 230 | 231 | isomorphic-fetch@^2.2.1: 232 | version "2.2.1" 233 | resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" 234 | dependencies: 235 | node-fetch "^1.0.1" 236 | whatwg-fetch ">=0.10.0" 237 | 238 | iterall@1.1.3: 239 | version "1.1.3" 240 | resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.1.3.tgz#1cbbff96204056dde6656e2ed2e2226d0e6d72c9" 241 | 242 | media-typer@0.3.0: 243 | version "0.3.0" 244 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 245 | 246 | merge-descriptors@1.0.1: 247 | version "1.0.1" 248 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 249 | 250 | methods@~1.1.2: 251 | version "1.1.2" 252 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 253 | 254 | mime-db@~1.30.0: 255 | version "1.30.0" 256 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" 257 | 258 | mime-types@~2.1.15, mime-types@~2.1.16: 259 | version "2.1.17" 260 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" 261 | dependencies: 262 | mime-db "~1.30.0" 263 | 264 | mime@1.4.1: 265 | version "1.4.1" 266 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" 267 | 268 | ms@2.0.0: 269 | version "2.0.0" 270 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 271 | 272 | negotiator@0.6.1: 273 | version "0.6.1" 274 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" 275 | 276 | node-fetch@^1.0.1: 277 | version "1.7.3" 278 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" 279 | dependencies: 280 | encoding "^0.1.11" 281 | is-stream "^1.0.1" 282 | 283 | on-finished@~2.3.0: 284 | version "2.3.0" 285 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 286 | dependencies: 287 | ee-first "1.1.1" 288 | 289 | parseurl@~1.3.2: 290 | version "1.3.2" 291 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" 292 | 293 | path-to-regexp@0.1.7: 294 | version "0.1.7" 295 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 296 | 297 | proxy-addr@~2.0.2: 298 | version "2.0.2" 299 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec" 300 | dependencies: 301 | forwarded "~0.1.2" 302 | ipaddr.js "1.5.2" 303 | 304 | qs@6.5.1: 305 | version "6.5.1" 306 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" 307 | 308 | range-parser@~1.2.0: 309 | version "1.2.0" 310 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" 311 | 312 | raw-body@2.3.2: 313 | version "2.3.2" 314 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" 315 | dependencies: 316 | bytes "3.0.0" 317 | http-errors "1.6.2" 318 | iconv-lite "0.4.19" 319 | unpipe "1.0.0" 320 | 321 | safe-buffer@5.1.1: 322 | version "5.1.1" 323 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" 324 | 325 | send@0.16.1: 326 | version "0.16.1" 327 | resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" 328 | dependencies: 329 | debug "2.6.9" 330 | depd "~1.1.1" 331 | destroy "~1.0.4" 332 | encodeurl "~1.0.1" 333 | escape-html "~1.0.3" 334 | etag "~1.8.1" 335 | fresh "0.5.2" 336 | http-errors "~1.6.2" 337 | mime "1.4.1" 338 | ms "2.0.0" 339 | on-finished "~2.3.0" 340 | range-parser "~1.2.0" 341 | statuses "~1.3.1" 342 | 343 | serve-static@1.13.1: 344 | version "1.13.1" 345 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" 346 | dependencies: 347 | encodeurl "~1.0.1" 348 | escape-html "~1.0.3" 349 | parseurl "~1.3.2" 350 | send "0.16.1" 351 | 352 | setprototypeof@1.0.3: 353 | version "1.0.3" 354 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" 355 | 356 | setprototypeof@1.1.0: 357 | version "1.1.0" 358 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" 359 | 360 | source-map-support@^0.5.0: 361 | version "0.5.0" 362 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.0.tgz#2018a7ad2bdf8faf2691e5fddab26bed5a2bacab" 363 | dependencies: 364 | source-map "^0.6.0" 365 | 366 | source-map@^0.6.0: 367 | version "0.6.1" 368 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 369 | 370 | "statuses@>= 1.3.1 < 2": 371 | version "1.4.0" 372 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" 373 | 374 | statuses@~1.3.1: 375 | version "1.3.1" 376 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" 377 | 378 | type-is@~1.6.15: 379 | version "1.6.15" 380 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" 381 | dependencies: 382 | media-typer "0.3.0" 383 | mime-types "~2.1.15" 384 | 385 | unpipe@1.0.0, unpipe@~1.0.0: 386 | version "1.0.0" 387 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 388 | 389 | utils-merge@1.0.1: 390 | version "1.0.1" 391 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 392 | 393 | uuid@^3.1.0: 394 | version "3.1.0" 395 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" 396 | 397 | vary@~1.1.2: 398 | version "1.1.2" 399 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 400 | 401 | whatwg-fetch@>=0.10.0: 402 | version "2.0.3" 403 | resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" 404 | -------------------------------------------------------------------------------- /lesson/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "apollo-server-express": "^1.2.0", 4 | "body-parser": "^1.18.2", 5 | "express": "^4.16.2", 6 | "graphql": "^0.11.7", 7 | "graphql-tools": "^2.6.1", 8 | "isomorphic-fetch": "^2.2.1" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lesson/resolvers.js: -------------------------------------------------------------------------------- 1 | const fetch = require('isomorphic-fetch') 2 | 3 | const request = (path, query) => { 4 | return fetch(`http://localhost:3000${path}`) 5 | .then(function(response) { 6 | if (response.status >= 400) { 7 | throw new Error("Bad response from server"); 8 | } 9 | return response.json() 10 | }) 11 | } 12 | 13 | module.exports = { 14 | Idol: { 15 | height(doc, { unit = 'CM' }, { user }) { 16 | if (unit !== 'CM') return + (doc.height / 2.54 / 12).toFixed(2) 17 | return doc.height 18 | } 19 | }, 20 | Query: { 21 | listIdol() { 22 | return request('/idols') 23 | }, 24 | listGroup() { 25 | return request('/groups') 26 | } 27 | }, 28 | Mutation: { 29 | login(doc, { username, password }) { 30 | return "Success" 31 | }, 32 | createIdol(doc, { name }) { 33 | return ({ 34 | id: 555, 35 | name: "ชื่อ", 36 | height: 167 37 | }) 38 | } 39 | }, 40 | } -------------------------------------------------------------------------------- /lesson/schema.gql: -------------------------------------------------------------------------------- 1 | enum BloodType { 2 | A 3 | B 4 | O 5 | AB 6 | } 7 | 8 | enum HeightUnit { 9 | CM 10 | FOOT 11 | } 12 | 13 | type Idol { 14 | id: ID! 15 | # กลุ่มไง 16 | group: Group 17 | # ทีมไง 18 | team: String 19 | # รูป 20 | picture: String 21 | romaji: String 22 | name: String 23 | nickname: String 24 | birthdate: String 25 | birthplace: String 26 | bloodType: BloodType 27 | age: Int 28 | height(unit: HeightUnit): Float 29 | agency: String 30 | generation: String 31 | } 32 | 33 | type Group { 34 | id: ID! 35 | name: String 36 | location: String 37 | since: Int 38 | } 39 | 40 | type Query { 41 | # เอาไว้แสดลงผล Idol ไงจ้ะ 42 | listIdol: [Idol] 43 | listGroup: [Group] 44 | } 45 | 46 | inputType { 47 | name: String 48 | } 49 | 50 | type Mutation { 51 | login(username: String!, password: String!): String 52 | createIdol(payload: IdolInput): Idol 53 | } 54 | 55 | schema { 56 | query: Query 57 | mutation: Mutation 58 | } -------------------------------------------------------------------------------- /lesson/server.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const express = require('express') 3 | const { makeExecutableSchema } = require('graphql-tools') 4 | const bodyParser = require('body-parser') 5 | const { graphqlExpress, graphiqlExpress } = require('apollo-server-express') 6 | 7 | const resolvers = require('./resolvers') 8 | const typeDefs = fs.readFileSync('./schema.gql', 'utf8') 9 | 10 | const schema = makeExecutableSchema({ 11 | typeDefs, 12 | resolvers 13 | }) 14 | 15 | const app = express() 16 | app.use('/graphql', bodyParser.json(), graphqlExpress({ schema })) 17 | app.use('/graphiql', graphiqlExpress({ 18 | endpointURL: '/graphql', 19 | })) 20 | 21 | const PORT = process.env.PORT || 5000 22 | app.listen(PORT, () => { 23 | console.log(`listen http://localhost:${PORT}`) 24 | }) 25 | -------------------------------------------------------------------------------- /lesson/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | accepts@~1.3.4: 6 | version "1.3.4" 7 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" 8 | dependencies: 9 | mime-types "~2.1.16" 10 | negotiator "0.6.1" 11 | 12 | apollo-cache-control@^0.0.x: 13 | version "0.0.7" 14 | resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.0.7.tgz#ffef56413a429a1ce204be5b78d248c4fe3b67ac" 15 | dependencies: 16 | graphql-extensions "^0.0.x" 17 | 18 | apollo-server-core@^1.2.0: 19 | version "1.2.0" 20 | resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.2.0.tgz#e851c47444991b6f89f88529237076b83e01e8ee" 21 | dependencies: 22 | apollo-cache-control "^0.0.x" 23 | apollo-tracing "^0.1.0" 24 | graphql-extensions "^0.0.x" 25 | 26 | apollo-server-express@^1.2.0: 27 | version "1.2.0" 28 | resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.2.0.tgz#026b12b453b8ecac6044b205b6a85fe596fb5f9e" 29 | dependencies: 30 | apollo-server-core "^1.2.0" 31 | apollo-server-module-graphiql "^1.2.0" 32 | 33 | apollo-server-module-graphiql@^1.2.0: 34 | version "1.2.0" 35 | resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.2.0.tgz#899d84f3b747795dbbfc8354aa51622ef038151c" 36 | 37 | apollo-tracing@^0.1.0: 38 | version "0.1.1" 39 | resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.1.1.tgz#7a5707543fc102f81cda7ba45b98331a82a6750b" 40 | dependencies: 41 | graphql-extensions "^0.0.x" 42 | 43 | apollo-utilities@^0.1.1-0: 44 | version "0.1.1-1" 45 | resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-0.1.1-1.tgz#a637c2a5b49e06f20dd9adf7c55ec1ff69a97592" 46 | 47 | array-flatten@1.1.1: 48 | version "1.1.1" 49 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 50 | 51 | body-parser@1.18.2, body-parser@^1.18.2: 52 | version "1.18.2" 53 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" 54 | dependencies: 55 | bytes "3.0.0" 56 | content-type "~1.0.4" 57 | debug "2.6.9" 58 | depd "~1.1.1" 59 | http-errors "~1.6.2" 60 | iconv-lite "0.4.19" 61 | on-finished "~2.3.0" 62 | qs "6.5.1" 63 | raw-body "2.3.2" 64 | type-is "~1.6.15" 65 | 66 | bytes@3.0.0: 67 | version "3.0.0" 68 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" 69 | 70 | content-disposition@0.5.2: 71 | version "0.5.2" 72 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" 73 | 74 | content-type@~1.0.4: 75 | version "1.0.4" 76 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 77 | 78 | cookie-signature@1.0.6: 79 | version "1.0.6" 80 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 81 | 82 | cookie@0.3.1: 83 | version "0.3.1" 84 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" 85 | 86 | core-js@^2.5.1: 87 | version "2.5.1" 88 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" 89 | 90 | debug@2.6.9: 91 | version "2.6.9" 92 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 93 | dependencies: 94 | ms "2.0.0" 95 | 96 | depd@1.1.1, depd@~1.1.1: 97 | version "1.1.1" 98 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" 99 | 100 | deprecated-decorator@^0.1.6: 101 | version "0.1.6" 102 | resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" 103 | 104 | destroy@~1.0.4: 105 | version "1.0.4" 106 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 107 | 108 | ee-first@1.1.1: 109 | version "1.1.1" 110 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 111 | 112 | encodeurl@~1.0.1: 113 | version "1.0.1" 114 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" 115 | 116 | encoding@^0.1.11: 117 | version "0.1.12" 118 | resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" 119 | dependencies: 120 | iconv-lite "~0.4.13" 121 | 122 | escape-html@~1.0.3: 123 | version "1.0.3" 124 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 125 | 126 | etag@~1.8.1: 127 | version "1.8.1" 128 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 129 | 130 | express@^4.16.2: 131 | version "4.16.2" 132 | resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" 133 | dependencies: 134 | accepts "~1.3.4" 135 | array-flatten "1.1.1" 136 | body-parser "1.18.2" 137 | content-disposition "0.5.2" 138 | content-type "~1.0.4" 139 | cookie "0.3.1" 140 | cookie-signature "1.0.6" 141 | debug "2.6.9" 142 | depd "~1.1.1" 143 | encodeurl "~1.0.1" 144 | escape-html "~1.0.3" 145 | etag "~1.8.1" 146 | finalhandler "1.1.0" 147 | fresh "0.5.2" 148 | merge-descriptors "1.0.1" 149 | methods "~1.1.2" 150 | on-finished "~2.3.0" 151 | parseurl "~1.3.2" 152 | path-to-regexp "0.1.7" 153 | proxy-addr "~2.0.2" 154 | qs "6.5.1" 155 | range-parser "~1.2.0" 156 | safe-buffer "5.1.1" 157 | send "0.16.1" 158 | serve-static "1.13.1" 159 | setprototypeof "1.1.0" 160 | statuses "~1.3.1" 161 | type-is "~1.6.15" 162 | utils-merge "1.0.1" 163 | vary "~1.1.2" 164 | 165 | finalhandler@1.1.0: 166 | version "1.1.0" 167 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" 168 | dependencies: 169 | debug "2.6.9" 170 | encodeurl "~1.0.1" 171 | escape-html "~1.0.3" 172 | on-finished "~2.3.0" 173 | parseurl "~1.3.2" 174 | statuses "~1.3.1" 175 | unpipe "~1.0.0" 176 | 177 | forwarded@~0.1.2: 178 | version "0.1.2" 179 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" 180 | 181 | fresh@0.5.2: 182 | version "0.5.2" 183 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 184 | 185 | graphql-extensions@^0.0.x: 186 | version "0.0.5" 187 | resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.0.5.tgz#63bc4a3fd31aab12bfadf783cbc038a9a6937cf0" 188 | dependencies: 189 | core-js "^2.5.1" 190 | source-map-support "^0.5.0" 191 | 192 | graphql-tools@^2.6.1: 193 | version "2.6.1" 194 | resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-2.6.1.tgz#9f6d1600951a05b18b83c52986c42eee4fd3cb1b" 195 | dependencies: 196 | apollo-utilities "^0.1.1-0" 197 | deprecated-decorator "^0.1.6" 198 | uuid "^3.1.0" 199 | 200 | graphql@^0.11.7: 201 | version "0.11.7" 202 | resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.11.7.tgz#e5abaa9cb7b7cccb84e9f0836bf4370d268750c6" 203 | dependencies: 204 | iterall "1.1.3" 205 | 206 | http-errors@1.6.2, http-errors@~1.6.2: 207 | version "1.6.2" 208 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" 209 | dependencies: 210 | depd "1.1.1" 211 | inherits "2.0.3" 212 | setprototypeof "1.0.3" 213 | statuses ">= 1.3.1 < 2" 214 | 215 | iconv-lite@0.4.19, iconv-lite@~0.4.13: 216 | version "0.4.19" 217 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" 218 | 219 | inherits@2.0.3: 220 | version "2.0.3" 221 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 222 | 223 | ipaddr.js@1.5.2: 224 | version "1.5.2" 225 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0" 226 | 227 | is-stream@^1.0.1: 228 | version "1.1.0" 229 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 230 | 231 | isomorphic-fetch@^2.2.1: 232 | version "2.2.1" 233 | resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" 234 | dependencies: 235 | node-fetch "^1.0.1" 236 | whatwg-fetch ">=0.10.0" 237 | 238 | iterall@1.1.3: 239 | version "1.1.3" 240 | resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.1.3.tgz#1cbbff96204056dde6656e2ed2e2226d0e6d72c9" 241 | 242 | media-typer@0.3.0: 243 | version "0.3.0" 244 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 245 | 246 | merge-descriptors@1.0.1: 247 | version "1.0.1" 248 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 249 | 250 | methods@~1.1.2: 251 | version "1.1.2" 252 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 253 | 254 | mime-db@~1.30.0: 255 | version "1.30.0" 256 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" 257 | 258 | mime-types@~2.1.15, mime-types@~2.1.16: 259 | version "2.1.17" 260 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" 261 | dependencies: 262 | mime-db "~1.30.0" 263 | 264 | mime@1.4.1: 265 | version "1.4.1" 266 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" 267 | 268 | ms@2.0.0: 269 | version "2.0.0" 270 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 271 | 272 | negotiator@0.6.1: 273 | version "0.6.1" 274 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" 275 | 276 | node-fetch@^1.0.1: 277 | version "1.7.3" 278 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" 279 | dependencies: 280 | encoding "^0.1.11" 281 | is-stream "^1.0.1" 282 | 283 | on-finished@~2.3.0: 284 | version "2.3.0" 285 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 286 | dependencies: 287 | ee-first "1.1.1" 288 | 289 | parseurl@~1.3.2: 290 | version "1.3.2" 291 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" 292 | 293 | path-to-regexp@0.1.7: 294 | version "0.1.7" 295 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 296 | 297 | proxy-addr@~2.0.2: 298 | version "2.0.2" 299 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec" 300 | dependencies: 301 | forwarded "~0.1.2" 302 | ipaddr.js "1.5.2" 303 | 304 | qs@6.5.1: 305 | version "6.5.1" 306 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" 307 | 308 | range-parser@~1.2.0: 309 | version "1.2.0" 310 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" 311 | 312 | raw-body@2.3.2: 313 | version "2.3.2" 314 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" 315 | dependencies: 316 | bytes "3.0.0" 317 | http-errors "1.6.2" 318 | iconv-lite "0.4.19" 319 | unpipe "1.0.0" 320 | 321 | safe-buffer@5.1.1: 322 | version "5.1.1" 323 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" 324 | 325 | send@0.16.1: 326 | version "0.16.1" 327 | resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" 328 | dependencies: 329 | debug "2.6.9" 330 | depd "~1.1.1" 331 | destroy "~1.0.4" 332 | encodeurl "~1.0.1" 333 | escape-html "~1.0.3" 334 | etag "~1.8.1" 335 | fresh "0.5.2" 336 | http-errors "~1.6.2" 337 | mime "1.4.1" 338 | ms "2.0.0" 339 | on-finished "~2.3.0" 340 | range-parser "~1.2.0" 341 | statuses "~1.3.1" 342 | 343 | serve-static@1.13.1: 344 | version "1.13.1" 345 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" 346 | dependencies: 347 | encodeurl "~1.0.1" 348 | escape-html "~1.0.3" 349 | parseurl "~1.3.2" 350 | send "0.16.1" 351 | 352 | setprototypeof@1.0.3: 353 | version "1.0.3" 354 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" 355 | 356 | setprototypeof@1.1.0: 357 | version "1.1.0" 358 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" 359 | 360 | source-map-support@^0.5.0: 361 | version "0.5.0" 362 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.0.tgz#2018a7ad2bdf8faf2691e5fddab26bed5a2bacab" 363 | dependencies: 364 | source-map "^0.6.0" 365 | 366 | source-map@^0.6.0: 367 | version "0.6.1" 368 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 369 | 370 | "statuses@>= 1.3.1 < 2": 371 | version "1.4.0" 372 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" 373 | 374 | statuses@~1.3.1: 375 | version "1.3.1" 376 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" 377 | 378 | type-is@~1.6.15: 379 | version "1.6.15" 380 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" 381 | dependencies: 382 | media-typer "0.3.0" 383 | mime-types "~2.1.15" 384 | 385 | unpipe@1.0.0, unpipe@~1.0.0: 386 | version "1.0.0" 387 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 388 | 389 | utils-merge@1.0.1: 390 | version "1.0.1" 391 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 392 | 393 | uuid@^3.1.0: 394 | version "3.1.0" 395 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" 396 | 397 | vary@~1.1.2: 398 | version "1.1.2" 399 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 400 | 401 | whatwg-fetch@>=0.10.0: 402 | version "2.0.3" 403 | resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" 404 | -------------------------------------------------------------------------------- /rest/groups.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "BNK48", 4 | "location": "Bangkok", 5 | "since": 2017 6 | }, 7 | { 8 | "name": "AKB48", 9 | "location": "Japan", 10 | "since": 2005 11 | } 12 | ] 13 | -------------------------------------------------------------------------------- /rest/idols.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "group": "BNK48", 4 | "team": "Trainee", 5 | "picture": "http://stage48.net/wiki/index.php/File:CherprangAreekulBNK2017.jpg", 6 | "romaji": "Cherprang Areekul", 7 | "name": "เฌอปราง อารีย์กุล", 8 | "nickname": "Cherprang", 9 | "birthdate": "May 2, 1996", 10 | "birthplace": "Bangkok, Thailand", 11 | "bloodType": "B", 12 | "age": 21, 13 | "height": 160, 14 | "agency": "Ignite Records", 15 | "generation": "1st" 16 | }, 17 | { 18 | "group": "BNK48", 19 | "team": "Trainee", 20 | "picture": "http://stage48.net/wiki/index.php/File:ChristinLarsenBNK2017.jpg", 21 | "romaji": "Christin Larsen", 22 | "name": "คริสติน ลาร์เซ่น", 23 | "nickname": "Namhom", 24 | "birthdate": "June 17, 2002", 25 | "birthplace": "Sisaket, Thailand", 26 | "bloodType": "AB", 27 | "age": 15, 28 | "height": 165, 29 | "agency": "Ignite Records", 30 | "generation": "1st" 31 | }, 32 | { 33 | "group": "BNK48", 34 | "team": "Trainee", 35 | "picture": "http://stage48.net/wiki/index.php/File:IradaTavachphongsriBNK2017.jpg", 36 | "romaji": "Irada Tavachphongsri", 37 | "name": "ไอรดา ธวัชผ่องศรี", 38 | "nickname": "Cincin", 39 | "birthdate": "November 7, 2000", 40 | "birthplace": "Bangkok, Thailand", 41 | "bloodType": "AB", 42 | "age": 16, 43 | "height": 165, 44 | "agency": "Ignite Records", 45 | "generation": "1st" 46 | }, 47 | { 48 | "group": "BNK48", 49 | "team": "Trainee", 50 | "picture": "http://stage48.net/wiki/index.php/File:IsarapaThawatpakdeeBNK2017.jpg", 51 | "romaji": "Isarapa Thawatpakdee", 52 | "name": "อิสราภา ธวัชภักดี", 53 | "nickname": "Tarwaan", 54 | "birthdate": "December 18, 1996", 55 | "birthplace": "Nakhon Pathom, Thailand", 56 | "bloodType": "O", 57 | "age": 20, 58 | "height": 156, 59 | "agency": "Ignite Records", 60 | "generation": "1st" 61 | }, 62 | { 63 | "group": "BNK48", 64 | "team": "Trainee", 65 | "picture": "http://stage48.net/wiki/index.php/File:JennisOprasertBNK2017.jpg", 66 | "romaji": "Jennis Oprasert", 67 | "name": "เจนนิษฐ์ โอ่ประเสริฐ", 68 | "nickname": "Jennis", 69 | "birthdate": "July 4, 2000", 70 | "birthplace": "Petchaburi, Thailand", 71 | "bloodType": "O", 72 | "age": 17, 73 | "height": 161, 74 | "agency": "Ignite Records", 75 | "generation": "1st" 76 | }, 77 | { 78 | "group": "BNK48", 79 | "team": "Trainee", 80 | "picture": "http://stage48.net/wiki/index.php/File:JetsupaKruetangBNK2017.jpg", 81 | "romaji": "Jetsupa Kruetang", 82 | "name": "เจตสุภา เครือแตง", 83 | "nickname": "Jan", 84 | "birthdate": "April 8, 1994", 85 | "birthplace": "Singburi, Thailand", 86 | "bloodType": "O", 87 | "age": 23, 88 | "height": 162, 89 | "agency": "Ignite Records", 90 | "generation": "1st" 91 | }, 92 | { 93 | "group": "BNK48", 94 | "team": "Trainee", 95 | "picture": "http://stage48.net/wiki/index.php/File:JiradapaIntajakBNK2017.jpg", 96 | "romaji": "Jiradapa Intajak", 97 | "name": "จิรดาภา อินทจักร", 98 | "nickname": "Pupe", 99 | "birthdate": "January 18, 1998", 100 | "birthplace": "Chiang Rai, Thailand", 101 | "bloodType": "B", 102 | "age": 19, 103 | "height": 160, 104 | "agency": "Ignite Records", 105 | "generation": "1st" 106 | }, 107 | { 108 | "group": "BNK48", 109 | "team": "Trainee", 110 | "picture": "http://stage48.net/wiki/index.php/File:KanteeraWadcharathadsanakulBNK2017.jpg", 111 | "romaji": "Kanteera Wadcharathadsanakul", 112 | "name": "กานต์ธีรา วัชรทัศนกุล", 113 | "nickname": "Noey", 114 | "birthdate": "April 9, 1997", 115 | "birthplace": "Samut Prakan, Thailand", 116 | "bloodType": "AB", 117 | "age": 20, 118 | "height": 158, 119 | "agency": "Ignite Records", 120 | "generation": "1st" 121 | }, 122 | { 123 | "group": "BNK48", 124 | "team": "Trainee", 125 | "picture": "http://stage48.net/wiki/index.php/File:KorapatNilprapaBNK2017.jpg", 126 | "romaji": "Korapat Nilprapa", 127 | "name": "กรภัทร์ นิลประภา", 128 | "nickname": "Kate", 129 | "birthdate": "June 9, 2001", 130 | "birthplace": "Phayao, Thailand", 131 | "bloodType": "B", 132 | "age": 16, 133 | "height": 162, 134 | "agency": "Ignite Records", 135 | "generation": "1st" 136 | }, 137 | { 138 | "group": "BNK48", 139 | "team": "Trainee", 140 | "picture": "http://stage48.net/wiki/index.php/File:KunjiranutIntarasinBNK2017.jpg", 141 | "romaji": "Kunjiranut Intarasin", 142 | "name": "กุลจิราณัฐ อินทรศิลป์", 143 | "nickname": "Jane", 144 | "birthdate": "March 23, 2000", 145 | "birthplace": "Pathum Thani, Thailand", 146 | "bloodType": "B", 147 | "age": 17, 148 | "height": 159, 149 | "agency": "Ignite Records", 150 | "generation": "1st" 151 | }, 152 | { 153 | "group": "BNK48", 154 | "team": "Trainee", 155 | "picture": "http://stage48.net/wiki/index.php/File:MananyaKaojuBNK2017.jpg", 156 | "romaji": "Mananya Kaoju", 157 | "name": "มนัญญา เกาะจู", 158 | "nickname": "Nink", 159 | "birthdate": "February 3, 2000", 160 | "birthplace": "Samut Sakorn, Thailand", 161 | "bloodType": "B", 162 | "age": 17, 163 | "height": 163, 164 | "agency": "Ignite Records", 165 | "generation": "1st" 166 | }, 167 | { 168 | "group": "BNK48", 169 | "team": "Trainee", 170 | "picture": "http://stage48.net/wiki/index.php/File:MesaChinavicharanaBNK2017.jpg", 171 | "romaji": "Mesa Chinavicharana", 172 | "name": "เมษา จีนะวิจารณะ", 173 | "nickname": "Maysa", 174 | "birthdate": "April 8, 1999", 175 | "birthplace": "Bangkok, Thailand", 176 | "bloodType": "A", 177 | "age": 18, 178 | "height": 162, 179 | "agency": "Ignite Records", 180 | "generation": "1st" 181 | }, 182 | { 183 | "group": "BNK48", 184 | "team": "Trainee", 185 | "picture": "http://stage48.net/wiki/index.php/File:MilinDokthianBNK2017.jpg", 186 | "romaji": "Milin Dokthian", 187 | "name": "มิลิน ดอกเทียน", 188 | "nickname": "Nam-Neung", 189 | "birthdate": "November 11, 1996", 190 | "birthplace": "Singburi, Thailand", 191 | "bloodType": "B", 192 | "age": 20, 193 | "height": 160, 194 | "agency": "Ignite Records", 195 | "generation": "1st" 196 | }, 197 | { 198 | "group": "BNK48", 199 | "team": "Trainee", 200 | "picture": "http://stage48.net/wiki/index.php/File:MioriOhkuboBNK2017.jpg", 201 | "romaji": "Miori Ohkubo", 202 | "name": "มิโอริ โอคุโบะ", 203 | "nickname": "Miori Miiko", 204 | "birthdate": "September 30, 1998", 205 | "birthplace": "Ibaraki, Japan", 206 | "bloodType": "O", 207 | "age": 19, 208 | "height": 153, 209 | "agency": "Ignite Records", 210 | "generation": "1st" 211 | }, 212 | { 213 | "group": "BNK48", 214 | "team": "Trainee", 215 | "picture": "http://stage48.net/wiki/index.php/File:NapaphatWorraphuttanonBNK2017.jpg", 216 | "romaji": "Napaphat Worraphuttanon", 217 | "name": "ณปภัช วรพฤทธานนท์", 218 | "nickname": "Jaa", 219 | "birthdate": "January 20, 2003", 220 | "birthplace": "Bangkok, Thailand", 221 | "bloodType": "B", 222 | "age": 14, 223 | "height": 160, 224 | "agency": "Ignite Records", 225 | "generation": "1st" 226 | }, 227 | { 228 | "group": "BNK48", 229 | "team": "Trainee", 230 | "picture": "http://stage48.net/wiki/index.php/File:NatrujaChutiwansoponBNK2017.jpg", 231 | "romaji": "Natruja Chutiwansopon", 232 | "name": "ณัฐรุจา ชุติวรรณโสภณ", 233 | "nickname": "Kaew", 234 | "birthdate": "March 31, 1994", 235 | "birthplace": "Chonburi, Thailand", 236 | "bloodType": "B", 237 | "age": 23, 238 | "height": 156, 239 | "agency": "Ignite Records", 240 | "generation": "1st" 241 | }, 242 | { 243 | "group": "BNK48", 244 | "team": "Trainee", 245 | "picture": "http://stage48.net/wiki/index.php/File:NayikaSrinianBNK2017.jpg", 246 | "romaji": "Nayika Srinian", 247 | "name": "นายิกา ศรีเนียน", 248 | "nickname": "Can", 249 | "birthdate": "November 10, 1997", 250 | "birthplace": "Bangkok, Thailand", 251 | "bloodType": "B", 252 | "age": 19, 253 | "height": 160, 254 | "agency": "Ignite Records", 255 | "generation": "1st" 256 | }, 257 | { 258 | "group": "BNK48", 259 | "team": "Trainee", 260 | "picture": "http://stage48.net/wiki/index.php/File:PanisaSrilaloengBNK2017.jpg", 261 | "romaji": "Panisa Srilaloeng", 262 | "name": "ปณิศา ศรีละเลิง", 263 | "nickname": "Mind", 264 | "birthdate": "September 6, 2001", 265 | "birthplace": "Nakhon Ratchasima, Thailand", 266 | "bloodType": "B", 267 | "age": 16, 268 | "height": 165, 269 | "agency": "Ignite Records", 270 | "generation": "1st" 271 | }, 272 | { 273 | "group": "BNK48", 274 | "team": "Trainee", 275 | "picture": "http://stage48.net/wiki/index.php/File:PatchananJiajirachoteBNK2017.jpg", 276 | "romaji": "Patchanan Jiajirachote", 277 | "name": "พัศชนันท์ เจียจิรโชติ", 278 | "nickname": "Orn", 279 | "birthdate": "February 3, 1997", 280 | "birthplace": "Bangkok, Thailand", 281 | "bloodType": "O", 282 | "age": 20, 283 | "height": 164, 284 | "agency": "Ignite Records", 285 | "generation": "1st" 286 | }, 287 | { 288 | "group": "BNK48", 289 | "team": "Trainee", 290 | "picture": "http://stage48.net/wiki/index.php/File:PichayapaNathaBNK2017.jpg", 291 | "romaji": "Pichayapa Natha", 292 | "name": "พิชญาภา นาถา", 293 | "nickname": "Namsai", 294 | "birthdate": "October 26, 1999", 295 | "birthplace": "Chiang Mai, Thailand", 296 | "bloodType": "O", 297 | "age": 18, 298 | "height": 164, 299 | "agency": "Ignite Records", 300 | "generation": "1st" 301 | }, 302 | { 303 | "group": "BNK48", 304 | "team": "Trainee", 305 | "picture": "http://stage48.net/wiki/index.php/File:PimrapatPhadungwatanachokBNK2017.jpg", 306 | "romaji": "Pimrapat Phadungwatanachok", 307 | "name": "พิมรภัส ผดุงวัฒนะโชค", 308 | "nickname": "Mobile", 309 | "birthdate": "July 9, 2002", 310 | "birthplace": "Bangkok, Thailand", 311 | "bloodType": "O", 312 | "age": 15, 313 | "height": 164, 314 | "agency": "Ignite Records", 315 | "generation": "1st" 316 | }, 317 | { 318 | "group": "BNK48", 319 | "team": "Trainee", 320 | "picture": "http://stage48.net/wiki/index.php/File:PraewaSuthamphongBNK2017.jpg", 321 | "romaji": "Praewa Suthamphong", 322 | "name": "แพรวา สุธรรมพงษ์", 323 | "nickname": "Music", 324 | "birthdate": "February 24, 2001", 325 | "birthplace": "Bangkok, Thailand", 326 | "bloodType": "B", 327 | "age": 16, 328 | "height": 164, 329 | "agency": "Ignite Records", 330 | "generation": "1st" 331 | }, 332 | { 333 | "group": "BNK48", 334 | "team": "Trainee", 335 | "picture": "http://stage48.net/wiki/index.php/File:PunsikornTiyakornBNK2017.jpg", 336 | "romaji": "Punsikorn Tiyakorn", 337 | "name": "ปัญสิกรณ์ ติยะกร", 338 | "nickname": "Pun", 339 | "birthdate": "November 9, 2000", 340 | "birthplace": "Bangkok, Thailand", 341 | "bloodType": "A", 342 | "age": 16, 343 | "height": 166, 344 | "agency": "Ignite Records", 345 | "generation": "1st" 346 | }, 347 | { 348 | "group": "BNK48", 349 | "team": "Trainee", 350 | "picture": "http://stage48.net/wiki/index.php/File:RinradaInthaisongBNK2017.jpg", 351 | "romaji": "Rinrada Inthaisong", 352 | "name": "รินรดา อินทร์ไธสง", 353 | "nickname": "Piam", 354 | "birthdate": "June 4, 2003", 355 | "birthplace": "Saraburi, Thailand", 356 | "bloodType": "B", 357 | "age": 14, 358 | "height": 159, 359 | "agency": "Ignite Records", 360 | "generation": "1st" 361 | }, 362 | { 363 | "group": "BNK48", 364 | "team": "Trainee", 365 | "picture": "http://stage48.net/wiki/index.php/File:SawitchayaKajonrungsilpBNK2017.jpg", 366 | "romaji": "Sawitchaya Kajonrungsilp", 367 | "name": "สวิชญา ขจรรุ่งศิลป์", 368 | "nickname": "Satchan", 369 | "birthdate": "December 13, 2003", 370 | "birthplace": "Bangkok, Thailand", 371 | "bloodType": "A", 372 | "age": 13, 373 | "height": 150, 374 | "agency": "Ignite Records", 375 | "generation": "1st" 376 | }, 377 | { 378 | "group": "BNK48", 379 | "team": "Trainee", 380 | "picture": "http://stage48.net/wiki/index.php/File:SuchayaSaenkhotBNK2017.jpg", 381 | "romaji": "Suchaya Saenkhot", 382 | "name": "สุชญา แสนโคต", 383 | "nickname": "Jib", 384 | "birthdate": "July 4, 2002", 385 | "birthplace": "Lopburi, Thailand", 386 | "bloodType": "A", 387 | "age": 15, 388 | "height": 150, 389 | "agency": "Ignite Records", 390 | "generation": "1st" 391 | }, 392 | { 393 | "group": "BNK48", 394 | "team": "Trainee", 395 | "picture": "http://stage48.net/wiki/index.php/File:VathusiriPhuwapunyasiriBNK2017.jpg", 396 | "romaji": "Vathusiri Phuwapunyasiri", 397 | "name": "วฑูศิริ ภูวปัญญาสิริ", 398 | "nickname": "Korn", 399 | "birthdate": "Junuary 21, 1999", 400 | "birthplace": "Bangkok, Thailand", 401 | "bloodType": "O", 402 | "age": 18, 403 | "height": 163, 404 | "agency": "Ignite Records", 405 | "generation": "1st" 406 | }, 407 | { 408 | "group": "BNK48", 409 | "team": "Trainee", 410 | "picture": "http://stage48.net/wiki/index.php/File:WarattayaDeesomlertBNK2017.jpg", 411 | "romaji": "Warattaya Deesomlert", 412 | "name": "วรัทยา ดีสมเลิศ", 413 | "nickname": "Kaimook", 414 | "birthdate": "August 27, 1997", 415 | "birthplace": "Bangkok, Thailand", 416 | "bloodType": "O", 417 | "age": 20, 418 | "height": 153, 419 | "agency": "Ignite Records", 420 | "generation": "1st" 421 | }, 422 | { 423 | "group": "AKB48", 424 | "team": "A", 425 | "picture": "http://stage48.net/wiki/index.php/File:IriyamaAnnaA2017.jpg", 426 | "romaji": "Iriyama Anna", 427 | "name": "入山杏奈", 428 | "nickname": "Annin (あんにん)", 429 | "birthdate": "December 3, 1995", 430 | "birthplace": "Chiba, Japan", 431 | "bloodType": "B", 432 | "age": 21, 433 | "height": 160, 434 | "agency": "Ota Pro", 435 | "generation": "10th" 436 | }, 437 | { 438 | "group": "AKB48", 439 | "team": "A", 440 | "picture": "http://stage48.net/wiki/index.php/File:OyaShizuka2017.jpg", 441 | "romaji": "Oya Shizuka", 442 | "name": "大家志津香", 443 | "nickname": "Shiichan (しいちゃん)", 444 | "birthdate": "December 28, 1991", 445 | "birthplace": "Fukuoka, Japan", 446 | "bloodType": "O", 447 | "age": 25, 448 | "height": 164, 449 | "agency": "Watanabe Pro", 450 | "generation": "4th" 451 | }, 452 | { 453 | "group": "AKB48", 454 | "team": "A", 455 | "picture": "http://stage48.net/wiki/index.php/File:KojimaNatsuki2017.jpg", 456 | "romaji": "Kojima Natsuki", 457 | "name": "小嶋菜月", 458 | "nickname": "Nattsun (なっつん)", 459 | "birthdate": "March 8, 1995", 460 | "birthplace": "Chiba, Japan", 461 | "bloodType": "O", 462 | "age": 22, 463 | "height": 154, 464 | "agency": "AKS", 465 | "generation": "11th" 466 | }, 467 | { 468 | "group": "AKB48", 469 | "team": "A", 470 | "picture": "http://stage48.net/wiki/index.php/File:SasakiYukari2017.jpg", 471 | "romaji": "Sasaki Yukari", 472 | "name": "佐々木優佳里", 473 | "nickname": "Yukarun (ゆかるん)", 474 | "birthdate": "August 28, 1995", 475 | "birthplace": "Saitama, Japan", 476 | "bloodType": "B", 477 | "age": 22, 478 | "height": 158, 479 | "agency": "AKS", 480 | "generation": "12th" 481 | }, 482 | { 483 | "group": "AKB48", 484 | "team": "M / A", 485 | "picture": "http://stage48.net/wiki/index.php/File:ShiromaMiruA2017.jpg", 486 | "romaji": "Shiroma Miru", 487 | "name": "白間美瑠", 488 | "nickname": "Mirurun (みるるん)", 489 | "birthdate": "October 14, 1997", 490 | "birthplace": "Osaka, Japan", 491 | "bloodType": "B", 492 | "age": 20, 493 | "height": 156, 494 | "agency": "Yoshimoto Kyoraku", 495 | "generation": "NMB48 1st" 496 | }, 497 | { 498 | "group": "AKB48", 499 | "team": "A", 500 | "picture": "http://stage48.net/wiki/index.php/File:TakitaKayoko2017.jpg", 501 | "romaji": "Takita Kayoko", 502 | "name": "田北香世子", 503 | "nickname": "Kayoyon (かよよん)", 504 | "birthdate": "February 13, 1997", 505 | "birthplace": "Chiba, Japan", 506 | "bloodType": "O", 507 | "age": 20, 508 | "height": 155, 509 | "agency": "AKS", 510 | "generation": "Draft 1st" 511 | }, 512 | { 513 | "group": "AKB48", 514 | "team": "A", 515 | "picture": "http://stage48.net/wiki/index.php/File:TaniguchiMegu2017.jpg", 516 | "romaji": "Taniguchi Megu", 517 | "name": "谷口めぐ", 518 | "nickname": "Omegu (おめぐ)", 519 | "birthdate": "November 12, 1998", 520 | "birthplace": "Tokyo, Japan", 521 | "bloodType": "A", 522 | "age": 18, 523 | "height": 159, 524 | "agency": "AKS", 525 | "generation": "15th (Tentative)" 526 | }, 527 | { 528 | "group": "AKB48", 529 | "team": "A", 530 | "picture": "http://stage48.net/wiki/index.php/File:NakanishiChiyori2017.jpg", 531 | "romaji": "Nakanishi Chiyori", 532 | "name": "中西智代梨", 533 | "nickname": "Chori (ちょり)", 534 | "birthdate": "May 12, 1995", 535 | "birthplace": "Fukuoka, Japan", 536 | "bloodType": "O", 537 | "age": 22, 538 | "height": 161, 539 | "agency": "AKS", 540 | "generation": "HKT48 1st" 541 | }, 542 | { 543 | "group": "AKB48", 544 | "team": "A", 545 | "picture": "http://stage48.net/wiki/index.php/File:HiwatashiYui2017.jpg", 546 | "romaji": "Hiwatashi Yui", 547 | "name": "樋渡結依", 548 | "nickname": "Hiiwatan (ひーわたん)", 549 | "birthdate": "April 30, 2000", 550 | "birthplace": "Saitama, Japan", 551 | "bloodType": "A", 552 | "age": 17, 553 | "height": 151, 554 | "agency": "AKS", 555 | "generation": "Draft 2nd Generation" 556 | }, 557 | { 558 | "group": "AKB48", 559 | "team": "A", 560 | "picture": "http://stage48.net/wiki/index.php/File:MiyazakiMiho2017.jpg", 561 | "romaji": "Miyazaki Miho", 562 | "name": "宮崎美穂", 563 | "nickname": "Myao (みゃお)", 564 | "birthdate": "July 30, 1993", 565 | "birthplace": "Tokyo, Japan", 566 | "bloodType": "O", 567 | "age": 24, 568 | "height": 159, 569 | "agency": "HoriPro", 570 | "generation": "5th" 571 | }, 572 | { 573 | "group": "AKB48", 574 | "team": "KIV / A", 575 | "picture": "http://stage48.net/wiki/index.php/File:MiyawakiSakuraA2017.jpg", 576 | "romaji": "Miyawaki Sakura", 577 | "name": "宮脇咲良", 578 | "nickname": "Sakura (さくら)", 579 | "birthdate": "March 19, 1998", 580 | "birthplace": "Kagoshima, Japan", 581 | "bloodType": "A", 582 | "age": 19, 583 | "height": 163, 584 | "agency": "AKS", 585 | "generation": "HKT48 1st" 586 | }, 587 | { 588 | "group": "AKB48", 589 | "team": "8 / A", 590 | "picture": "http://stage48.net/wiki/index.php/File:YamadaNanami82017.jpg", 591 | "romaji": "Yamada Nanami", 592 | "name": "山田菜々美", 593 | "nickname": "Nanamichan (ななみちゃん) / Nanami (ななみ) / Yamada (山田)", 594 | "birthdate": "February 9, 1999", 595 | "birthplace": "Hyogo, Japan", 596 | "bloodType": "B", 597 | "age": 18, 598 | "height": 155, 599 | "agency": "AKS", 600 | "generation": "Team 8" 601 | }, 602 | { 603 | "group": "AKB48", 604 | "team": "A", 605 | "picture": "http://stage48.net/wiki/index.php/File:YokoyamaYui2017.jpg", 606 | "romaji": "Yokoyama Yui", 607 | "name": "横山由依", 608 | "nickname": "Yui (ゆい) / Yuihan (ゆいはん)", 609 | "birthdate": "December 8, 1992", 610 | "birthplace": "Kyoto, Japan", 611 | "bloodType": "B", 612 | "age": 24, 613 | "height": 158, 614 | "agency": "Ota Pro", 615 | "generation": "9th" 616 | }, 617 | { 618 | "group": "AKB48", 619 | "team": "K", 620 | "picture": "http://stage48.net/wiki/index.php/File:AbeMariaK2017.jpg", 621 | "romaji": "Abe Maria", 622 | "name": "阿部マリア", 623 | "nickname": "Abemaru (あべまる) / Maria (まりあ)", 624 | "birthdate": "November 29, 1995", 625 | "birthplace": "Kyoto, Japan", 626 | "bloodType": "B", 627 | "age": 21, 628 | "height": 167, 629 | "agency": "Japan Music Entertainment", 630 | "generation": "10th" 631 | }, 632 | { 633 | "group": "AKB48", 634 | "team": "K", 635 | "picture": "http://stage48.net/wiki/index.php/File:IchikawaManamiK2017.jpg", 636 | "romaji": "Ichikawa Manami", 637 | "name": "市川愛美", 638 | "nickname": "Manami (まなみ)", 639 | "birthdate": "August 26, 1999", 640 | "birthplace": "Tokyo, Japan", 641 | "bloodType": "A", 642 | "age": 18, 643 | "height": 157, 644 | "agency": "AKS", 645 | "generation": "15th" 646 | }, 647 | { 648 | "group": "AKB48", 649 | "team": "H / K", 650 | "picture": "http://stage48.net/wiki/index.php/File:KodamaHarukaK2017.jpg", 651 | "romaji": "Kodama Haruka", 652 | "name": "兒玉遥", 653 | "nickname": "Haruppi (はるっぴ) / Harupyo (はるぴょ)", 654 | "birthdate": "September 19, 1996", 655 | "birthplace": "Fukuoka, Japan", 656 | "bloodType": "O", 657 | "age": 21, 658 | "height": 158, 659 | "agency": "AKS", 660 | "generation": "HKT48 1st" 661 | }, 662 | { 663 | "group": "AKB48", 664 | "team": "K", 665 | "picture": "http://stage48.net/wiki/index.php/File:KuboSatoneKKS2017.jpg", 666 | "romaji": "Kubo Satone", 667 | "name": "久保怜音", 668 | "nickname": "Satopii (さとぴー)", 669 | "birthdate": "November 20, 2003", 670 | "birthplace": "Kanagawa, Japan", 671 | "bloodType": "O", 672 | "age": 13, 673 | "height": 150, 674 | "agency": "AKS", 675 | "generation": "Draft 2nd" 676 | }, 677 | { 678 | "group": "AKB48", 679 | "team": "K", 680 | "picture": "http://stage48.net/wiki/index.php/File:ShinozakiAyanaK2017.jpg", 681 | "romaji": "Shinozaki Ayana", 682 | "name": "篠崎彩奈", 683 | "nickname": "Ayanan (あやなん)", 684 | "birthdate": "January 8, 1996", 685 | "birthplace": "Saitama, Japan", 686 | "bloodType": "B", 687 | "age": 21, 688 | "height": 154, 689 | "agency": "AKS", 690 | "generation": "13th" 691 | }, 692 | { 693 | "group": "AKB48", 694 | "team": "K", 695 | "picture": "http://stage48.net/wiki/index.php/File:ShimadaHarukaK2017.jpg", 696 | "romaji": "Shimada Haruka", 697 | "name": "島田晴香", 698 | "nickname": "Haruu (はるぅ)", 699 | "birthdate": "December 16, 1992", 700 | "birthplace": "Shizuoka, Japan", 701 | "bloodType": "B", 702 | "age": 24, 703 | "height": 161, 704 | "agency": "FLAVE", 705 | "generation": "9th" 706 | }, 707 | { 708 | "group": "AKB48", 709 | "team": "K", 710 | "picture": "http://stage48.net/wiki/index.php/File:ShimoguchiHinanaK2017.jpg", 711 | "romaji": "Shimoguchi Hinana", 712 | "name": "下口ひなな", 713 | "nickname": "Hinana (ひなな)", 714 | "birthdate": "July 19, 2001", 715 | "birthplace": "Chiba, Japan", 716 | "bloodType": "O", 717 | "age": 16, 718 | "height": 152, 719 | "agency": "AKS", 720 | "generation": "Draft 1st" 721 | }, 722 | { 723 | "group": "AKB48", 724 | "team": "K", 725 | "picture": "http://stage48.net/wiki/index.php/File:TanoYukaK2017.jpg", 726 | "romaji": "Tano Yuuka", 727 | "name": "田野優花", 728 | "nickname": "Tanochan (たのちゃん)", 729 | "birthdate": "March 7, 1997", 730 | "birthplace": "Tokyo, Japan", 731 | "bloodType": "O", 732 | "age": 20, 733 | "height": 150, 734 | "agency": "AKS", 735 | "generation": "12th" 736 | }, 737 | { 738 | "group": "AKB48", 739 | "team": "8 / K", 740 | "picture": "http://stage48.net/wiki/index.php/File:NakanoIkumi82017.jpg", 741 | "romaji": "Nakano Ikumi", 742 | "name": "中野郁海", 743 | "nickname": "Ikumin (いくみん)", 744 | "birthdate": "August 20, 2000", 745 | "birthplace": "Tottori, Japan", 746 | "bloodType": null, 747 | "age": 17, 748 | "height": 161, 749 | "agency": "AKS", 750 | "generation": "Team 8" 751 | }, 752 | { 753 | "group": "AKB48", 754 | "team": "K", 755 | "picture": "http://stage48.net/wiki/index.php/File:FujitaNanaK2017.jpg", 756 | "romaji": "Fujita Nana", 757 | "name": "藤田奈那", 758 | "nickname": "Naana (なぁな)", 759 | "birthdate": "December 28, 1996", 760 | "birthplace": "Tokyo, Japan", 761 | "bloodType": "A", 762 | "age": 20, 763 | "height": 162, 764 | "agency": "AKS", 765 | "generation": "10th" 766 | }, 767 | { 768 | "group": "AKB48", 769 | "team": "K", 770 | "picture": "http://stage48.net/wiki/index.php/File:MinegishiMinamiK2017.jpg", 771 | "romaji": "Minegishi Minami", 772 | "name": "峯岸みなみ", 773 | "nickname": "Miichan (みぃちゃん)", 774 | "birthdate": "November 15, 1992", 775 | "birthplace": "Tokyo, Japan", 776 | "bloodType": "B", 777 | "age": 24, 778 | "height": 158, 779 | "agency": "Production Ogi", 780 | "generation": "1st" 781 | }, 782 | { 783 | "group": "AKB48", 784 | "team": "K", 785 | "picture": "http://stage48.net/wiki/index.php/File:MukaichiMionK2017.jpg", 786 | "romaji": "Mukaichi Mion", 787 | "name": "向井地美音", 788 | "nickname": "Miion (みーおん)", 789 | "birthdate": "January 29, 1998", 790 | "birthplace": "Saitama, Japan", 791 | "bloodType": "O", 792 | "age": 19, 793 | "height": 148.5, 794 | "agency": "Mama & Son Inc.", 795 | "generation": "15th" 796 | }, 797 | { 798 | "group": "AKB48", 799 | "team": "K", 800 | "picture": "http://stage48.net/wiki/index.php/File:MutoTomuK2017.jpg", 801 | "romaji": "Mutou Tomu", 802 | "name": "武藤十夢", 803 | "nickname": "Tomu (とむ)", 804 | "birthdate": "November 25, 1994", 805 | "birthplace": "Tokyo, Japan", 806 | "bloodType": "B", 807 | "age": 22, 808 | "height": 158, 809 | "agency": "AKS", 810 | "generation": "12th" 811 | }, 812 | { 813 | "group": "AKB48", 814 | "team": "K", 815 | "picture": "http://stage48.net/wiki/index.php/File:MogiShinobuK2017.jpg", 816 | "romaji": "Mogi Shinobu", 817 | "name": "茂木忍", 818 | "nickname": "Mogichan (もぎちゃん)", 819 | "birthdate": "February 16, 1997", 820 | "birthplace": "Chiba, Japan", 821 | "bloodType": "AB", 822 | "age": 20, 823 | "height": 162, 824 | "agency": "AKS", 825 | "generation": "13th" 826 | }, 827 | { 828 | "group": "AKB48", 829 | "team": "K", 830 | "picture": "http://stage48.net/wiki/index.php/File:YumotoAmiK2017.jpg", 831 | "romaji": "Yumoto Ami", 832 | "name": "湯本亜美", 833 | "nickname": "Yuami (ゆあみ)", 834 | "birthdate": "October 3, 1997", 835 | "birthplace": "Saitama, Japan", 836 | "bloodType": "O", 837 | "age": 20, 838 | "height": 156.5, 839 | "agency": "AKS", 840 | "generation": "15th" 841 | }, 842 | { 843 | "group": "AKB48", 844 | "team": "B / NIII", 845 | "picture": "http://stage48.net/wiki/index.php/File:KashiwagiYukiB2017.jpg", 846 | "romaji": "Kashiwagi Yuki", 847 | "name": "柏木由紀", 848 | "nickname": "Yukirin (ゆきりん)", 849 | "birthdate": "July 15, 1991", 850 | "birthplace": "Kagoshima, Japan", 851 | "bloodType": "A", 852 | "age": 26, 853 | "height": 164, 854 | "agency": "Watanabe Pro", 855 | "generation": "3rd" 856 | }, 857 | { 858 | "group": "AKB48", 859 | "team": "B", 860 | "picture": "http://stage48.net/wiki/index.php/File:KatoRena2017.jpg", 861 | "romaji": "Kato Rena", 862 | "name": "加藤玲奈", 863 | "nickname": "Renacchi (れなっち)", 864 | "birthdate": "July 10, 1997", 865 | "birthplace": "Chiba, Japan", 866 | "bloodType": "B", 867 | "age": 20, 868 | "height": 159, 869 | "agency": "Mama & Son Inc.", 870 | "generation": "10th" 871 | }, 872 | { 873 | "group": "AKB48", 874 | "team": "B", 875 | "picture": "http://stage48.net/wiki/index.php/File:GotoMoeB2017.jpg", 876 | "romaji": "Goto Moe", 877 | "name": "後藤萌咲", 878 | "nickname": "Moekyun (もえきゅん)", 879 | "birthdate": "May 20, 2001", 880 | "birthplace": "Aichi, Japan", 881 | "bloodType": "O", 882 | "age": 16, 883 | "height": 153, 884 | "agency": "AKS", 885 | "generation": "Draft 1st" 886 | }, 887 | { 888 | "group": "AKB48", 889 | "team": "8 / B", 890 | "picture": "http://stage48.net/wiki/index.php/File:SakaguchiNagisa82017.jpg", 891 | "romaji": "Sakaguchi Nagisa", 892 | "name": "坂口渚沙", 893 | "nickname": "Nagi (なぎ)", 894 | "birthdate": "December 23, 2000", 895 | "birthplace": "Hokkaido, Japan", 896 | "bloodType": "A", 897 | "age": 16, 898 | "height": 147, 899 | "agency": "AKS", 900 | "generation": "Team 8" 901 | }, 902 | { 903 | "group": "AKB48", 904 | "team": "B", 905 | "picture": "http://stage48.net/wiki/index.php/File:TakeuchiMiyuB2017.jpg", 906 | "romaji": "Takeuchi Miyu", 907 | "name": "竹内美宥", 908 | "nickname": "Miyumiyu (みゆみゆ)", 909 | "birthdate": "January 12, 1996", 910 | "birthplace": "Tokyo, Japan", 911 | "bloodType": "O", 912 | "age": 21, 913 | "height": 154, 914 | "agency": "Oh Enterprise", 915 | "generation": "9th" 916 | }, 917 | { 918 | "group": "AKB48", 919 | "team": "B", 920 | "picture": "http://stage48.net/wiki/index.php/File:TatsuyaMakihoB2017.jpg", 921 | "romaji": "Tatsuya Makiho", 922 | "name": "達家真姫宝", 923 | "nickname": "Makichan (まきちゃん)", 924 | "birthdate": "October 19, 2001", 925 | "birthplace": "Tokyo, Japan", 926 | "bloodType": "B", 927 | "age": 16, 928 | "height": 157, 929 | "agency": "AKS", 930 | "generation": "15th (Tentative)" 931 | }, 932 | { 933 | "group": "AKB48", 934 | "team": "B", 935 | "picture": "http://stage48.net/wiki/index.php/File:NishikawaReiKKS2017.jpg", 936 | "romaji": "Nishikawa Rei", 937 | "name": "西川怜", 938 | "nickname": "Rei (れい)", 939 | "birthdate": "October 25, 2003", 940 | "birthplace": "Tokyo, Japan", 941 | "bloodType": "B", 942 | "age": 14, 943 | "height": 149, 944 | "agency": "AKS", 945 | "generation": "Draft 2nd" 946 | }, 947 | { 948 | "group": "AKB48", 949 | "team": "B", 950 | "picture": "http://stage48.net/wiki/index.php/File:FukuokaSeinaB2017.jpg", 951 | "romaji": "Fukuoka Seina", 952 | "name": "福岡聖菜", 953 | "nickname": "Seichan (せいちゃん)", 954 | "birthdate": "August 1, 2000", 955 | "birthplace": "Kanagawa, Japan", 956 | "bloodType": "O", 957 | "age": 17, 958 | "height": 150, 959 | "agency": "AKS", 960 | "generation": "15th" 961 | }, 962 | { 963 | "group": "AKB48", 964 | "team": "B", 965 | "picture": "http://stage48.net/wiki/index.php/File:MaChiaLingB2017.jpg", 966 | "romaji": "Ma Chia-Ling", 967 | "name": "馬嘉伶", 968 | "nickname": "Macharin (まちゃりん)", 969 | "birthdate": "December 22, 1997", 970 | "birthplace": "Taichung, Taiwan", 971 | "bloodType": "A", 972 | "age": 19, 973 | "height": null, 974 | "agency": "AKS", 975 | "generation": "AKB48 Taiwan Audition" 976 | }, 977 | { 978 | "group": "AKB48", 979 | "team": "H / B", 980 | "picture": "http://stage48.net/wiki/index.php/File:YabukiNakoB2017.jpg", 981 | "romaji": "Yabuki Nako", 982 | "name": "矢吹奈子", 983 | "nickname": "Nako (なこ) / Kinako (きなこ)", 984 | "birthdate": "June 18, 2001", 985 | "birthplace": "Tokyo, Japan", 986 | "bloodType": "**", 987 | "age": 16, 988 | "height": 145, 989 | "agency": "AKS", 990 | "generation": "HKT48 3rd" 991 | }, 992 | { 993 | "group": "AKB48", 994 | "team": "B", 995 | "picture": "http://stage48.net/wiki/index.php/File:YamabeAyuKKS2017.jpg", 996 | "romaji": "Yamabe Ayu", 997 | "name": "山邊歩夢", 998 | "nickname": "Ayu (あゆ)", 999 | "birthdate": "February 3, 2002", 1000 | "birthplace": "Chiba, Japan", 1001 | "bloodType": "B", 1002 | "age": 14, 1003 | "height": 149, 1004 | "agency": "AKS", 1005 | "generation": "Draft 2nd" 1006 | }, 1007 | { 1008 | "group": "AKB48", 1009 | "team": "B", 1010 | "picture": "http://stage48.net/wiki/index.php/File:WatanabeMayuB2017.jpg", 1011 | "romaji": "Watanabe Mayu", 1012 | "name": "渡辺麻友", 1013 | "nickname": "Mayuyu (まゆゆ)", 1014 | "birthdate": "March 26, 1994", 1015 | "birthplace": "Saitama, Japan", 1016 | "bloodType": "A", 1017 | "age": 23, 1018 | "height": 156, 1019 | "agency": "Production Ogi", 1020 | "generation": "3rd" 1021 | } 1022 | ] -------------------------------------------------------------------------------- /rest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rest", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "dependencies": { 7 | "body-parser": "^1.18.2", 8 | "express": "^4.16.2", 9 | "lodash": "^4.17.4", 10 | "moment": "^2.19.1", 11 | "morgan": "^1.9.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /rest/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const _ = require('lodash') 3 | const moment = require('moment') 4 | const morgan = require('morgan') 5 | const bodyParser = require('body-parser') 6 | 7 | const groups = require('./groups.json') 8 | groups.forEach((group, i) => { 9 | group.id = i + 1 10 | }) 11 | 12 | const idols = require('./idols.json') 13 | idols.forEach((idol, i) => { 14 | // create ID for each idols 15 | idol.id = i + 1 16 | // date format 17 | idol.birthdate = moment(idol.birthdate, 'MMMM D, YYYY').format('YYYY-MM-DD') + 'T00:00:00Z' 18 | // set group name to group id 19 | idol.group = _.find(groups, { name: idol.group }).id 20 | }) 21 | 22 | const app = express() 23 | 24 | app.use(morgan('dev')) 25 | 26 | app.get('/idols', (req, res) => { 27 | let result = idols.slice() 28 | ;['team', 'bloodType', 'birthplace', 'generation'].forEach((key) => { 29 | if (req.query[key]) result = _.filter(result, { [key]: req.query[key] }) 30 | }) 31 | ;['group'].forEach((key) => { 32 | if (req.query[key]) result = _.filter(result, { [key]: parseInt(req.query[key]) }) 33 | }) 34 | res.json(result) 35 | }) 36 | 37 | app.get('/idols/:id', (req, res) => { 38 | const idol = _.find(idols, { id: parseInt(req.params.id) }) 39 | if (!idol) return res.status(404).send('idol not found') 40 | res.json(idol) 41 | }) 42 | 43 | app.get('/groups', (req, res) => { 44 | res.json(groups) 45 | }) 46 | 47 | app.get('/groups/:id', (req, res) => { 48 | const group = _.find(groups, { id: parseInt(req.params.id) }) 49 | if (!group) return res.status(404).send('group not found') 50 | res.json(group) 51 | }) 52 | 53 | app.post('/idols', bodyParser.json(), (req, res) => { 54 | const idol = req.body 55 | idol.id = idols.length 56 | idols.push(idol) 57 | res.json(idol) 58 | }) 59 | 60 | const PORT = process.env.PORT || 3000 61 | app.listen(PORT, () => { 62 | console.log(`listen http://localhost:${PORT}`) 63 | }) 64 | 65 | -------------------------------------------------------------------------------- /rest/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | accepts@~1.3.4: 6 | version "1.3.4" 7 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" 8 | dependencies: 9 | mime-types "~2.1.16" 10 | negotiator "0.6.1" 11 | 12 | array-flatten@1.1.1: 13 | version "1.1.1" 14 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 15 | 16 | basic-auth@~2.0.0: 17 | version "2.0.0" 18 | resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.0.tgz#015db3f353e02e56377755f962742e8981e7bbba" 19 | dependencies: 20 | safe-buffer "5.1.1" 21 | 22 | body-parser@1.18.2, body-parser@^1.18.2: 23 | version "1.18.2" 24 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" 25 | dependencies: 26 | bytes "3.0.0" 27 | content-type "~1.0.4" 28 | debug "2.6.9" 29 | depd "~1.1.1" 30 | http-errors "~1.6.2" 31 | iconv-lite "0.4.19" 32 | on-finished "~2.3.0" 33 | qs "6.5.1" 34 | raw-body "2.3.2" 35 | type-is "~1.6.15" 36 | 37 | bytes@3.0.0: 38 | version "3.0.0" 39 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" 40 | 41 | content-disposition@0.5.2: 42 | version "0.5.2" 43 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" 44 | 45 | content-type@~1.0.4: 46 | version "1.0.4" 47 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 48 | 49 | cookie-signature@1.0.6: 50 | version "1.0.6" 51 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 52 | 53 | cookie@0.3.1: 54 | version "0.3.1" 55 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" 56 | 57 | debug@2.6.9: 58 | version "2.6.9" 59 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 60 | dependencies: 61 | ms "2.0.0" 62 | 63 | depd@1.1.1, depd@~1.1.1: 64 | version "1.1.1" 65 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" 66 | 67 | destroy@~1.0.4: 68 | version "1.0.4" 69 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 70 | 71 | ee-first@1.1.1: 72 | version "1.1.1" 73 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 74 | 75 | encodeurl@~1.0.1: 76 | version "1.0.1" 77 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" 78 | 79 | escape-html@~1.0.3: 80 | version "1.0.3" 81 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 82 | 83 | etag@~1.8.1: 84 | version "1.8.1" 85 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 86 | 87 | express@^4.16.2: 88 | version "4.16.2" 89 | resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" 90 | dependencies: 91 | accepts "~1.3.4" 92 | array-flatten "1.1.1" 93 | body-parser "1.18.2" 94 | content-disposition "0.5.2" 95 | content-type "~1.0.4" 96 | cookie "0.3.1" 97 | cookie-signature "1.0.6" 98 | debug "2.6.9" 99 | depd "~1.1.1" 100 | encodeurl "~1.0.1" 101 | escape-html "~1.0.3" 102 | etag "~1.8.1" 103 | finalhandler "1.1.0" 104 | fresh "0.5.2" 105 | merge-descriptors "1.0.1" 106 | methods "~1.1.2" 107 | on-finished "~2.3.0" 108 | parseurl "~1.3.2" 109 | path-to-regexp "0.1.7" 110 | proxy-addr "~2.0.2" 111 | qs "6.5.1" 112 | range-parser "~1.2.0" 113 | safe-buffer "5.1.1" 114 | send "0.16.1" 115 | serve-static "1.13.1" 116 | setprototypeof "1.1.0" 117 | statuses "~1.3.1" 118 | type-is "~1.6.15" 119 | utils-merge "1.0.1" 120 | vary "~1.1.2" 121 | 122 | finalhandler@1.1.0: 123 | version "1.1.0" 124 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" 125 | dependencies: 126 | debug "2.6.9" 127 | encodeurl "~1.0.1" 128 | escape-html "~1.0.3" 129 | on-finished "~2.3.0" 130 | parseurl "~1.3.2" 131 | statuses "~1.3.1" 132 | unpipe "~1.0.0" 133 | 134 | forwarded@~0.1.2: 135 | version "0.1.2" 136 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" 137 | 138 | fresh@0.5.2: 139 | version "0.5.2" 140 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 141 | 142 | http-errors@1.6.2, http-errors@~1.6.2: 143 | version "1.6.2" 144 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" 145 | dependencies: 146 | depd "1.1.1" 147 | inherits "2.0.3" 148 | setprototypeof "1.0.3" 149 | statuses ">= 1.3.1 < 2" 150 | 151 | iconv-lite@0.4.19: 152 | version "0.4.19" 153 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" 154 | 155 | inherits@2.0.3: 156 | version "2.0.3" 157 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 158 | 159 | ipaddr.js@1.5.2: 160 | version "1.5.2" 161 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0" 162 | 163 | lodash@^4.17.4: 164 | version "4.17.4" 165 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" 166 | 167 | media-typer@0.3.0: 168 | version "0.3.0" 169 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 170 | 171 | merge-descriptors@1.0.1: 172 | version "1.0.1" 173 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 174 | 175 | methods@~1.1.2: 176 | version "1.1.2" 177 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 178 | 179 | mime-db@~1.30.0: 180 | version "1.30.0" 181 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" 182 | 183 | mime-types@~2.1.15, mime-types@~2.1.16: 184 | version "2.1.17" 185 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" 186 | dependencies: 187 | mime-db "~1.30.0" 188 | 189 | mime@1.4.1: 190 | version "1.4.1" 191 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" 192 | 193 | moment@^2.19.1: 194 | version "2.19.1" 195 | resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.1.tgz#56da1a2d1cbf01d38b7e1afc31c10bcfa1929167" 196 | 197 | morgan@^1.9.0: 198 | version "1.9.0" 199 | resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.0.tgz#d01fa6c65859b76fcf31b3cb53a3821a311d8051" 200 | dependencies: 201 | basic-auth "~2.0.0" 202 | debug "2.6.9" 203 | depd "~1.1.1" 204 | on-finished "~2.3.0" 205 | on-headers "~1.0.1" 206 | 207 | ms@2.0.0: 208 | version "2.0.0" 209 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 210 | 211 | negotiator@0.6.1: 212 | version "0.6.1" 213 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" 214 | 215 | on-finished@~2.3.0: 216 | version "2.3.0" 217 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 218 | dependencies: 219 | ee-first "1.1.1" 220 | 221 | on-headers@~1.0.1: 222 | version "1.0.1" 223 | resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" 224 | 225 | parseurl@~1.3.2: 226 | version "1.3.2" 227 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" 228 | 229 | path-to-regexp@0.1.7: 230 | version "0.1.7" 231 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 232 | 233 | proxy-addr@~2.0.2: 234 | version "2.0.2" 235 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec" 236 | dependencies: 237 | forwarded "~0.1.2" 238 | ipaddr.js "1.5.2" 239 | 240 | qs@6.5.1: 241 | version "6.5.1" 242 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" 243 | 244 | range-parser@~1.2.0: 245 | version "1.2.0" 246 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" 247 | 248 | raw-body@2.3.2: 249 | version "2.3.2" 250 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" 251 | dependencies: 252 | bytes "3.0.0" 253 | http-errors "1.6.2" 254 | iconv-lite "0.4.19" 255 | unpipe "1.0.0" 256 | 257 | safe-buffer@5.1.1: 258 | version "5.1.1" 259 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" 260 | 261 | send@0.16.1: 262 | version "0.16.1" 263 | resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" 264 | dependencies: 265 | debug "2.6.9" 266 | depd "~1.1.1" 267 | destroy "~1.0.4" 268 | encodeurl "~1.0.1" 269 | escape-html "~1.0.3" 270 | etag "~1.8.1" 271 | fresh "0.5.2" 272 | http-errors "~1.6.2" 273 | mime "1.4.1" 274 | ms "2.0.0" 275 | on-finished "~2.3.0" 276 | range-parser "~1.2.0" 277 | statuses "~1.3.1" 278 | 279 | serve-static@1.13.1: 280 | version "1.13.1" 281 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" 282 | dependencies: 283 | encodeurl "~1.0.1" 284 | escape-html "~1.0.3" 285 | parseurl "~1.3.2" 286 | send "0.16.1" 287 | 288 | setprototypeof@1.0.3: 289 | version "1.0.3" 290 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" 291 | 292 | setprototypeof@1.1.0: 293 | version "1.1.0" 294 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" 295 | 296 | "statuses@>= 1.3.1 < 2": 297 | version "1.4.0" 298 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" 299 | 300 | statuses@~1.3.1: 301 | version "1.3.1" 302 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" 303 | 304 | type-is@~1.6.15: 305 | version "1.6.15" 306 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" 307 | dependencies: 308 | media-typer "0.3.0" 309 | mime-types "~2.1.15" 310 | 311 | unpipe@1.0.0, unpipe@~1.0.0: 312 | version "1.0.0" 313 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 314 | 315 | utils-merge@1.0.1: 316 | version "1.0.1" 317 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 318 | 319 | vary@~1.1.2: 320 | version "1.1.2" 321 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 322 | --------------------------------------------------------------------------------