최현준

add LINEBOT & connect to my channel

Showing 1000 changed files with 4784 additions and 0 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

No preview for this file type
1 +# mother project : kakaoBot<br>
2 +최근 수정: 2018/12/01<br>
3 +추가기능 : 파파고 api를 이용한 카카오톡에서 전송한 사진 속 글자 인식및 번역
4 +
1 +var express = require('express');
2 +var app = express();
3 +const line = require('@line/bot-sdk');
4 +//https://theia17.herokuapp.com/callback
5 +
6 +//papago api
7 +var request = require('request');
8 +
9 +//번역 api_url
10 +var translate_api_url = 'https://openapi.naver.com/v1/papago/n2mt';
11 +
12 +//언어감지 api_url
13 +var languagedetect_api_url = 'https://openapi.naver.com/v1/papago/detectLangs'
14 +
15 +// Naver Auth Key
16 +//새로 발급받은 naver papago api id, pw 입력
17 +var client_id = 'xZMx34y7uru1v8lywZ2d';
18 +var client_secret = 'p6L7M7WsH9';
19 +
20 +const config = {
21 + channelAccessToken: 'm79m/yBsTVzZeC9pYqSLzEL00Hp0HqsVE/0ZsZxW2HNAwdnb9TwDgBcOyCn3/aJASXsE8ekpyGg4Gts/4r8LO72OTZec9Np5Mh9g1vrgyDj5theWv4g2miE5F1Cqax4X3waj1aIzDGHcUZdHD6fQvAdB04t89/1O/w1cDnyilFU=',
22 + channelSecret: '284e3cf5c7838415f99ea0bd7ed412a6',
23 +};
24 +
25 +// create LINE SDK client
26 +const client = new line.Client(config);
27 +
28 +// create Express app
29 +// about Express itself: https://expressjs.com/
30 +// register a webhook handler with middleware
31 +// about the middleware, please refer to doc
32 +app.post('/webhook', line.middleware(config), (req, res) => {
33 + Promise
34 + .all(req.body.events.map(handleEvent))
35 + .then((result) => res.json(result))
36 + .catch((err) => {
37 + console.error(err);
38 + res.status(200).end();
39 + });
40 +});
41 +
42 +// event handler
43 +function handleEvent(event) {
44 + if (event.type !== 'message' || event.message.type !== 'text') {
45 + // ignore non-text-message event
46 + return Promise.resolve(null);
47 + }
48 + return new Promise(function(resolve, reject) {
49 + //언어 감지 option
50 + var detect_options = {
51 + url : languagedetect_api_url,
52 + form : {'query': event.message.text},
53 + headers: {'X-Naver-Client-Id': client_id, 'X-Naver-Client-Secret': client_secret}
54 + };
55 +
56 + //papago 언어 감지
57 + request.post(detect_options,function(error,response,body){
58 + console.log(response.statusCode);
59 + if(!error && response.statusCode == 200){
60 + var detect_body = JSON.parse(response.body);
61 + var source = '';
62 + var target = '';
63 + var result = { type: 'text', text:''};
64 +
65 + //언어 감지가 제대로 됐는지 확인
66 + console.log(detect_body.langCode);
67 +
68 +
69 + //번역은 한국어->영어 / 영어->한국어만 지원
70 + if(detect_body.langCode == 'ko'||detect_body.langCode == 'en'){
71 + source = detect_body.langCode == 'ko' ? 'ko':'en';
72 + target = source == 'ko' ? 'en':'ko';
73 + //papago 번역 option
74 + var options = {
75 + url: translate_api_url,
76 + // 한국어(source : ko), 영어(target: en), 카톡에서 받는 메시지(text)
77 + form: {'source':source, 'target':target, 'text':event.message.text},
78 + headers: {'X-Naver-Client-Id': client_id, 'X-Naver-Client-Secret': client_secret}
79 + };
80 +
81 + // Naver Post API
82 + request.post(options, function(error, response, body){
83 + // Translate API Sucess
84 + if(!error && response.statusCode == 200){
85 + // JSON
86 + var objBody = JSON.parse(response.body);
87 + // Message 잘 찍히는지 확인
88 +
89 + result.text = objBody.message.result.translatedText;
90 + console.log(result.text);
91 + //번역된 문장 보내기
92 + client.replyMessage(event.replyToken,result).then(resolve).catch(reject);
93 + }
94 + });
95 + }
96 + // 메시지의 언어가 영어 또는 한국어가 아닐 경우
97 + else{
98 + result.text = '언어를 감지할 수 없습니다. \n 번역 언어는 한글 또는 영어만 가능합니다.';
99 + client.replyMessage(event.replyToken,result).then(resolve).catch(reject);
100 + }
101 +
102 + }
103 +
104 + });
105 +
106 + });
107 + }
108 +
109 +app.listen(3000, function () {
110 + console.log('Linebot listening on port 3000!');
111 +});
...\ No newline at end of file ...\ No newline at end of file
1 +#!/usr/bin/env node
2 +
3 +/**
4 + * Module dependencies.
5 + */
6 +
7 +var app = require('../app');
8 +var debug = require('debug')('project:server');
9 +var http = require('http');
10 +
11 +/**
12 + * Get port from environment and store in Express.
13 + */
14 +
15 +var port = normalizePort(process.env.PORT || '3000');
16 +app.set('port', port);
17 +
18 +/**
19 + * Create HTTP server.
20 + */
21 +
22 +var server = http.createServer(app);
23 +
24 +/**
25 + * Listen on provided port, on all network interfaces.
26 + */
27 +
28 +server.listen(port);
29 +server.on('error', onError);
30 +server.on('listening', onListening);
31 +
32 +/**
33 + * Normalize a port into a number, string, or false.
34 + */
35 +
36 +function normalizePort(val) {
37 + var port = parseInt(val, 10);
38 +
39 + if (isNaN(port)) {
40 + // named pipe
41 + return val;
42 + }
43 +
44 + if (port >= 0) {
45 + // port number
46 + return port;
47 + }
48 +
49 + return false;
50 +}
51 +
52 +/**
53 + * Event listener for HTTP server "error" event.
54 + */
55 +
56 +function onError(error) {
57 + if (error.syscall !== 'listen') {
58 + throw error;
59 + }
60 +
61 + var bind = typeof port === 'string'
62 + ? 'Pipe ' + port
63 + : 'Port ' + port;
64 +
65 + // handle specific listen errors with friendly messages
66 + switch (error.code) {
67 + case 'EACCES':
68 + console.error(bind + ' requires elevated privileges');
69 + process.exit(1);
70 + break;
71 + case 'EADDRINUSE':
72 + console.error(bind + ' is already in use');
73 + process.exit(1);
74 + break;
75 + default:
76 + throw error;
77 + }
78 +}
79 +
80 +/**
81 + * Event listener for HTTP server "listening" event.
82 + */
83 +
84 +function onListening() {
85 + var addr = server.address();
86 + var bind = typeof addr === 'string'
87 + ? 'pipe ' + addr
88 + : 'port ' + addr.port;
89 + debug('Listening on ' + bind);
90 +}
1 +#!/bin/sh
2 +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3 +
4 +case `uname` in
5 + *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
6 +esac
7 +
8 +if [ -x "$basedir/node" ]; then
9 + "$basedir/node" "$basedir/../mime/cli.js" "$@"
10 + ret=$?
11 +else
12 + node "$basedir/../mime/cli.js" "$@"
13 + ret=$?
14 +fi
15 +exit $ret
1 +@IF EXIST "%~dp0\node.exe" (
2 + "%~dp0\node.exe" "%~dp0\..\mime\cli.js" %*
3 +) ELSE (
4 + @SETLOCAL
5 + @SET PATHEXT=%PATHEXT:;.JS;=;%
6 + node "%~dp0\..\mime\cli.js" %*
7 +)
...\ No newline at end of file ...\ No newline at end of file
1 +#!/bin/sh
2 +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3 +
4 +case `uname` in
5 + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
6 +esac
7 +
8 +if [ -x "$basedir/node" ]; then
9 + "$basedir/node" "$basedir/../sshpk/bin/sshpk-conv" "$@"
10 + ret=$?
11 +else
12 + node "$basedir/../sshpk/bin/sshpk-conv" "$@"
13 + ret=$?
14 +fi
15 +exit $ret
1 +@ECHO off
2 +SETLOCAL
3 +CALL :find_dp0
4 +
5 +IF EXIST "%dp0%\node.exe" (
6 + SET "_prog=%dp0%\node.exe"
7 +) ELSE (
8 + SET "_prog=node"
9 + SET PATHEXT=%PATHEXT:;.JS;=;%
10 +)
11 +
12 +"%_prog%" "%dp0%\..\sshpk\bin\sshpk-conv" %*
13 +ENDLOCAL
14 +EXIT /b %errorlevel%
15 +:find_dp0
16 +SET dp0=%~dp0
17 +EXIT /b
1 +#!/usr/bin/env pwsh
2 +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
3 +
4 +$exe=""
5 +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
6 + # Fix case when both the Windows and Linux builds of Node
7 + # are installed in the same directory
8 + $exe=".exe"
9 +}
10 +$ret=0
11 +if (Test-Path "$basedir/node$exe") {
12 + & "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-conv" $args
13 + $ret=$LASTEXITCODE
14 +} else {
15 + & "node$exe" "$basedir/../sshpk/bin/sshpk-conv" $args
16 + $ret=$LASTEXITCODE
17 +}
18 +exit $ret
1 +#!/bin/sh
2 +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3 +
4 +case `uname` in
5 + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
6 +esac
7 +
8 +if [ -x "$basedir/node" ]; then
9 + "$basedir/node" "$basedir/../sshpk/bin/sshpk-sign" "$@"
10 + ret=$?
11 +else
12 + node "$basedir/../sshpk/bin/sshpk-sign" "$@"
13 + ret=$?
14 +fi
15 +exit $ret
1 +@ECHO off
2 +SETLOCAL
3 +CALL :find_dp0
4 +
5 +IF EXIST "%dp0%\node.exe" (
6 + SET "_prog=%dp0%\node.exe"
7 +) ELSE (
8 + SET "_prog=node"
9 + SET PATHEXT=%PATHEXT:;.JS;=;%
10 +)
11 +
12 +"%_prog%" "%dp0%\..\sshpk\bin\sshpk-sign" %*
13 +ENDLOCAL
14 +EXIT /b %errorlevel%
15 +:find_dp0
16 +SET dp0=%~dp0
17 +EXIT /b
1 +#!/usr/bin/env pwsh
2 +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
3 +
4 +$exe=""
5 +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
6 + # Fix case when both the Windows and Linux builds of Node
7 + # are installed in the same directory
8 + $exe=".exe"
9 +}
10 +$ret=0
11 +if (Test-Path "$basedir/node$exe") {
12 + & "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-sign" $args
13 + $ret=$LASTEXITCODE
14 +} else {
15 + & "node$exe" "$basedir/../sshpk/bin/sshpk-sign" $args
16 + $ret=$LASTEXITCODE
17 +}
18 +exit $ret
1 +#!/bin/sh
2 +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3 +
4 +case `uname` in
5 + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
6 +esac
7 +
8 +if [ -x "$basedir/node" ]; then
9 + "$basedir/node" "$basedir/../sshpk/bin/sshpk-verify" "$@"
10 + ret=$?
11 +else
12 + node "$basedir/../sshpk/bin/sshpk-verify" "$@"
13 + ret=$?
14 +fi
15 +exit $ret
1 +@ECHO off
2 +SETLOCAL
3 +CALL :find_dp0
4 +
5 +IF EXIST "%dp0%\node.exe" (
6 + SET "_prog=%dp0%\node.exe"
7 +) ELSE (
8 + SET "_prog=node"
9 + SET PATHEXT=%PATHEXT:;.JS;=;%
10 +)
11 +
12 +"%_prog%" "%dp0%\..\sshpk\bin\sshpk-verify" %*
13 +ENDLOCAL
14 +EXIT /b %errorlevel%
15 +:find_dp0
16 +SET dp0=%~dp0
17 +EXIT /b
1 +#!/usr/bin/env pwsh
2 +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
3 +
4 +$exe=""
5 +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
6 + # Fix case when both the Windows and Linux builds of Node
7 + # are installed in the same directory
8 + $exe=".exe"
9 +}
10 +$ret=0
11 +if (Test-Path "$basedir/node$exe") {
12 + & "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-verify" $args
13 + $ret=$LASTEXITCODE
14 +} else {
15 + & "node$exe" "$basedir/../sshpk/bin/sshpk-verify" $args
16 + $ret=$LASTEXITCODE
17 +}
18 +exit $ret
1 +#!/bin/sh
2 +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3 +
4 +case `uname` in
5 + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
6 +esac
7 +
8 +if [ -x "$basedir/node" ]; then
9 + "$basedir/node" "$basedir/../uuid/bin/uuid" "$@"
10 + ret=$?
11 +else
12 + node "$basedir/../uuid/bin/uuid" "$@"
13 + ret=$?
14 +fi
15 +exit $ret
1 +@ECHO off
2 +SETLOCAL
3 +CALL :find_dp0
4 +
5 +IF EXIST "%dp0%\node.exe" (
6 + SET "_prog=%dp0%\node.exe"
7 +) ELSE (
8 + SET "_prog=node"
9 + SET PATHEXT=%PATHEXT:;.JS;=;%
10 +)
11 +
12 +"%_prog%" "%dp0%\..\uuid\bin\uuid" %*
13 +ENDLOCAL
14 +EXIT /b %errorlevel%
15 +:find_dp0
16 +SET dp0=%~dp0
17 +EXIT /b
1 +#!/usr/bin/env pwsh
2 +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
3 +
4 +$exe=""
5 +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
6 + # Fix case when both the Windows and Linux builds of Node
7 + # are installed in the same directory
8 + $exe=".exe"
9 +}
10 +$ret=0
11 +if (Test-Path "$basedir/node$exe") {
12 + & "$basedir/node$exe" "$basedir/../uuid/bin/uuid" $args
13 + $ret=$LASTEXITCODE
14 +} else {
15 + & "node$exe" "$basedir/../uuid/bin/uuid" $args
16 + $ret=$LASTEXITCODE
17 +}
18 +exit $ret
1 +## 6.4.0 (19 Nov 2018)
2 +
3 +### Feature
4 +
5 +* Add `getLinkToken` API (#96)
6 +* Handle `req.rawBody` in Google Cloud Functions (#101)
7 +* [Kitchensink] Add ngrok functionality (#99)
8 +
9 +### Type
10 +
11 +* Add types for video in imagemap message (#100)
12 +* Add `contentProvider` fields to content messages (#103)
13 +* Add `destination` field to webhook request body (#102)
14 +* Add `MemberJoinEvent` and `MemberLeaveEvent` types (#107)
15 +
16 +### Misc
17 +
18 +* Don't include doc in released source
19 +* Upgrade TypeScript to 3.1.6 (#94)
20 +* Refactoring (#94, #98, #99)
21 +* Remove webhook-tester tool
22 +
23 +
24 +## 6.3.0 (21 Sep 2018)
25 +
26 +### Feature
27 +
28 +* Add default rich menu APIs (#87)
29 +
30 +### Type
31 +
32 +* Add missing `defaultAction` field to `TemplateColumn`
33 +
34 +### Misc
35 +
36 +* Use VuePress as documentation engine (#85)
37 +* Upgrade minimum supported Node.js version to 6
38 +
39 +
40 +## 6.2.1 (16 Aug 2018)
41 +
42 +### Misc
43 +
44 +* Remove gitbook-cli from dev dependencies
45 +
46 +
47 +## 6.2.0 (15 Aug 2018)
48 +
49 +#### Type
50 +
51 +* Add QuickReply types (#83)
52 +* Format type comments
53 +
54 +#### Misc
55 +
56 +* Upgrade TypeScript to 3
57 +
58 +
59 +## 6.1.1 (14 Aug 2018)
60 +
61 +#### Type
62 +
63 +* Update FlexMessage types (#81)
64 +
65 +#### Misc
66 +
67 +* Add test coverage (#78)
68 +* Add JSDoc comments (#80)
69 +
70 +
71 +## 6.1.0 (19 June 2018)
72 +
73 +#### Type
74 +
75 +* Add types for flex message (#74)
76 +* Simplify type definition for `Action`
77 +
78 +
79 +## 6.0.3 (18 June 2018)
80 +
81 +#### Misc
82 +
83 +* Move get-audio-duration dep to proper package.json (#73)
84 +* Vulnerability fix with `npm audit fix`
85 +
86 +
87 +## 6.0.2 (21 May 2018)
88 +
89 +#### Type
90 +
91 +* Add missing `displayText` field to postback action (#63)
92 +* Add missing `FileEventMessage` to `EventMessage` (#71)
93 +
94 +#### Misc
95 +
96 +* Add audio duration lib to kitchensink example (#68)
97 +
98 +
99 +## 6.0.1 (13 Mar 2018)
100 +
101 +#### Type
102 +
103 +* Fix misimplemented 'AudioMessage' type (#61)
104 +
105 +
106 +## 6.0.0 (27 Feb 2018)
107 +
108 +#### Major
109 +
110 +* Fix misimplemented 'unlinkRichMenuFromUser' API
111 +
112 +#### Type
113 +
114 +* Fix TemplateColumn type definition (#48)
115 +
116 +#### Misc
117 +
118 +* Update GitHub issue template (#43)
119 +* Add Code of Conduct (#50)
120 +* Catch errors properly in examples (#52)
121 +
122 +
123 +## 5.2.0 (11 Dec 2017)
124 +
125 +#### Minor
126 +
127 +* Set Content-Length manually for postBinary (#42)
128 +
129 +
130 +## 5.1.0 (7 Dec 2017)
131 +
132 +#### Minor
133 +
134 +* Add new fields (#39)
135 +
136 +#### Misc
137 +
138 +* Fix Windows build (#38)
139 +* Add start scripts and webhook info to examples
140 +
141 +
142 +## 5.0.1 (14 Nov 2017)
143 +
144 +#### Minor
145 +
146 +* Fix typo in `ImageMapMessage` type
147 +* Add kitchensink example (#36)
148 +
149 +
150 +## 5.0.0 (2 Nov 2017)
151 +
152 +#### Major
153 +
154 +* Implement rich menu API (#34)
155 +
156 +#### Type
157 +
158 +* Rename `ImageMapArea` and `TemplateAction`s into general ones
159 +
160 +#### Misc
161 +
162 +* Do not enforce `checkJSON` for some APIs where it means nothing
163 +* Change how to check request object in test cases
164 +
165 +
166 +## 4.0.0 (25 Oct 2017)
167 +
168 +#### Major
169 +
170 +* Make index script export exceptions and types (#31)
171 +
172 +#### Type
173 +
174 +* Simplify config types for client and middleware (#31)
175 +
176 +#### Misc
177 +
178 +* Fix information and links in doc
179 +* Use Prettier instead of TSLint (#30)
180 +* Install git hooks for precommit and prepush (#30)
181 +
182 +
183 +## 3.1.1 (19 Sep 2017)
184 +
185 +#### Type
186 +
187 +* Fix type of postback.params
188 +
189 +
190 +## 3.1.0 (19 Sep 2017)
191 +
192 +#### Major
193 +
194 +* Make middleware return `SignatureValidationFailed` for no signature (#26)
195 +
196 +#### Type
197 +
198 +* Add `FileEventMessage` type
199 +
200 +
201 +## 3.0.0 (8 Sep 2017)
202 +
203 +#### Major
204 +
205 +* Implement "Get group/room member profile" API (#15)
206 +* Implement "Get group/room member IDs" API (#23)
207 +* `getMessageContent` now returns `Promise<ReadableStream>` (#20)
208 +
209 +#### Type
210 +
211 +* Add "datetimepicker" support (#21)
212 +* Fix typo in `TemplateURIAction` type (#21)
213 +
214 +#### Misc
215 +
216 +* Package updates and corresponding fixes
217 +* Use npm 5 instead of Yarn in dev
218 +* Fix `clean` script to work in Windows
219 +* Use "axios" for internal HTTP client instead of "got" (#20)
220 +
221 +
222 +## 2.0.0 (12 June 2017)
223 +
224 +#### Type
225 +
226 +* Use literal types for 'type' fields
227 +
228 +#### Misc
229 +
230 +* Update yarn.lock with the latest Yarn
231 +
232 +
233 +## 1.1.0 (31 May 2017)
234 +
235 +* Handle pre-parsed body (string and buffer only)
236 +
237 +#### Type
238 +
239 +* Separate config type into client and middleware types
240 +* Add `userId` to group and room event sources
241 +
242 +#### Misc
243 +
244 +* Create issue template (#4)
245 +
246 +
247 +## 1.0.0 (11 May 2017)
248 +
249 +* Initial release
This diff is collapsed. Click to expand it.
1 +# line-bot-sdk-nodejs
2 +
3 +[![Travis CI](https://travis-ci.org/line/line-bot-sdk-nodejs.svg?branch=master)](https://travis-ci.org/line/line-bot-sdk-nodejs)
4 +[![npmjs](https://badge.fury.io/js/%40line%2Fbot-sdk.svg)](https://www.npmjs.com/package/@line/bot-sdk)
5 +
6 +Node.js SDK for LINE Messaging API
7 +
8 +## Getting Started
9 +
10 +### Install
11 +
12 +Using [npm](https://www.npmjs.com/):
13 +
14 +``` bash
15 +$ npm install @line/bot-sdk --save
16 +```
17 +
18 +### Documentation
19 +
20 +For guide, API reference, and other information, please refer to
21 +the [documentation](https://line.github.io/line-bot-sdk-nodejs/).
22 +
23 +### LINE Messaging API References
24 +
25 +Here are links to official references for LINE Messaging API. It is recommended
26 +reading them beforehand.
27 +
28 +* LINE API Reference [EN](https://developers.line.me/en/docs/messaging-api/reference/) [JA](https://developers.line.me/ja/docs/messaging-api/reference/)
29 +* LINE Developers - Messaging API
30 + * [Overview](https://developers.line.me/messaging-api/overview)
31 + * [Getting started](https://developers.line.me/messaging-api/getting-started)
32 + * [Joining groups and rooms](https://developers.line.me/messaging-api/joining-groups-and-rooms)
33 +
34 +## Requirements
35 +
36 +* **Node.js** 6 or higher
37 +
38 +## Contributing
39 +
40 +Please check [CONTRIBUTING](CONTRIBUTING.md) before making a contribution.
41 +
42 +## License
43 +
44 +[Apache License Version 2.0](LICENSE)
1 +/// <reference types="node" />
2 +import { Readable } from "stream";
3 +import * as Types from "./types";
4 +export default class Client {
5 + config: Types.ClientConfig;
6 + private http;
7 + constructor(config: Types.ClientConfig);
8 + pushMessage(to: string, messages: Types.Message | Types.Message[]): Promise<any>;
9 + replyMessage(replyToken: string, messages: Types.Message | Types.Message[]): Promise<any>;
10 + multicast(to: string[], messages: Types.Message | Types.Message[]): Promise<any>;
11 + getProfile(userId: string): Promise<Types.Profile>;
12 + private getChatMemberProfile;
13 + getGroupMemberProfile(groupId: string, userId: string): Promise<Types.Profile>;
14 + getRoomMemberProfile(roomId: string, userId: string): Promise<Types.Profile>;
15 + private getChatMemberIds;
16 + getGroupMemberIds(groupId: string): Promise<string[]>;
17 + getRoomMemberIds(roomId: string): Promise<string[]>;
18 + getMessageContent(messageId: string): Promise<Readable>;
19 + private leaveChat;
20 + leaveGroup(groupId: string): Promise<any>;
21 + leaveRoom(roomId: string): Promise<any>;
22 + getRichMenu(richMenuId: string): Promise<Types.RichMenuResponse>;
23 + createRichMenu(richMenu: Types.RichMenu): Promise<string>;
24 + deleteRichMenu(richMenuId: string): Promise<any>;
25 + getRichMenuIdOfUser(userId: string): Promise<string>;
26 + linkRichMenuToUser(userId: string, richMenuId: string): Promise<any>;
27 + unlinkRichMenuFromUser(userId: string): Promise<any>;
28 + getRichMenuImage(richMenuId: string): Promise<Readable>;
29 + setRichMenuImage(richMenuId: string, data: Buffer | Readable, contentType?: string): Promise<any>;
30 + getRichMenuList(): Promise<Array<Types.RichMenuResponse>>;
31 + setDefaultRichMenu(richMenuId: string): Promise<{}>;
32 + getDefaultRichMenuId(): Promise<string>;
33 + deleteDefaultRichMenu(): Promise<{}>;
34 + getLinkToken(userId: string): Promise<string>;
35 +}
1 +"use strict";
2 +Object.defineProperty(exports, "__esModule", { value: true });
3 +const http_1 = require("./http");
4 +const exceptions_1 = require("./exceptions");
5 +function toArray(maybeArr) {
6 + return Array.isArray(maybeArr) ? maybeArr : [maybeArr];
7 +}
8 +function checkJSON(raw) {
9 + if (typeof raw === "object") {
10 + return raw;
11 + }
12 + else {
13 + throw new exceptions_1.JSONParseError("Failed to parse response body as JSON", raw);
14 + }
15 +}
16 +class Client {
17 + constructor(config) {
18 + if (!config.channelAccessToken) {
19 + throw new Error("no channel access token");
20 + }
21 + this.config = config;
22 + this.http = new http_1.default(process.env.API_BASE_URL || "https://api.line.me/v2/bot/", {
23 + Authorization: "Bearer " + this.config.channelAccessToken,
24 + });
25 + }
26 + pushMessage(to, messages) {
27 + return this.http.post("/message/push", {
28 + messages: toArray(messages),
29 + to,
30 + });
31 + }
32 + replyMessage(replyToken, messages) {
33 + return this.http.post("/message/reply", {
34 + messages: toArray(messages),
35 + replyToken,
36 + });
37 + }
38 + multicast(to, messages) {
39 + return this.http.post("/message/multicast", {
40 + messages: toArray(messages),
41 + to,
42 + });
43 + }
44 + getProfile(userId) {
45 + return this.http.get(`/profile/${userId}`).then(checkJSON);
46 + }
47 + getChatMemberProfile(chatType, chatId, userId) {
48 + return this.http
49 + .get(`/${chatType}/${chatId}/member/${userId}`)
50 + .then(checkJSON);
51 + }
52 + getGroupMemberProfile(groupId, userId) {
53 + return this.getChatMemberProfile("group", groupId, userId);
54 + }
55 + getRoomMemberProfile(roomId, userId) {
56 + return this.getChatMemberProfile("room", roomId, userId);
57 + }
58 + getChatMemberIds(chatType, chatId) {
59 + const load = (start) => this.http
60 + .get(`/${chatType}/${chatId}/members/ids`, start ? { start } : null)
61 + .then(checkJSON)
62 + .then((res) => {
63 + if (!res.next) {
64 + return res.memberIds;
65 + }
66 + return load(res.next).then(extraIds => res.memberIds.concat(extraIds));
67 + });
68 + return load();
69 + }
70 + getGroupMemberIds(groupId) {
71 + return this.getChatMemberIds("group", groupId);
72 + }
73 + getRoomMemberIds(roomId) {
74 + return this.getChatMemberIds("room", roomId);
75 + }
76 + getMessageContent(messageId) {
77 + return this.http.getStream(`/message/${messageId}/content`);
78 + }
79 + leaveChat(chatType, chatId) {
80 + return this.http.post(`/${chatType}/${chatId}/leave`);
81 + }
82 + leaveGroup(groupId) {
83 + return this.leaveChat("group", groupId);
84 + }
85 + leaveRoom(roomId) {
86 + return this.leaveChat("room", roomId);
87 + }
88 + getRichMenu(richMenuId) {
89 + return this.http
90 + .get(`/richmenu/${richMenuId}`)
91 + .then(checkJSON);
92 + }
93 + createRichMenu(richMenu) {
94 + return this.http
95 + .post("/richmenu", richMenu)
96 + .then(checkJSON)
97 + .then(res => res.richMenuId);
98 + }
99 + deleteRichMenu(richMenuId) {
100 + return this.http.delete(`/richmenu/${richMenuId}`);
101 + }
102 + getRichMenuIdOfUser(userId) {
103 + return this.http
104 + .get(`/user/${userId}/richmenu`)
105 + .then(checkJSON)
106 + .then(res => res.richMenuId);
107 + }
108 + linkRichMenuToUser(userId, richMenuId) {
109 + return this.http.post(`/user/${userId}/richmenu/${richMenuId}`);
110 + }
111 + unlinkRichMenuFromUser(userId) {
112 + return this.http.delete(`/user/${userId}/richmenu`);
113 + }
114 + getRichMenuImage(richMenuId) {
115 + return this.http.getStream(`/richmenu/${richMenuId}/content`);
116 + }
117 + setRichMenuImage(richMenuId, data, contentType) {
118 + return this.http.postBinary(`/richmenu/${richMenuId}/content`, data, contentType);
119 + }
120 + getRichMenuList() {
121 + return this.http
122 + .get(`/richmenu/list`)
123 + .then(checkJSON)
124 + .then(res => res.richmenus);
125 + }
126 + setDefaultRichMenu(richMenuId) {
127 + return this.http.post(`/user/all/richmenu/${richMenuId}`);
128 + }
129 + getDefaultRichMenuId() {
130 + return this.http
131 + .get("/user/all/richmenu")
132 + .then(checkJSON)
133 + .then(res => res.richMenuId);
134 + }
135 + deleteDefaultRichMenu() {
136 + return this.http.delete("/user/all/richmenu");
137 + }
138 + getLinkToken(userId) {
139 + return this.http
140 + .post(`/user/${userId}/linkToken`)
141 + .then(checkJSON)
142 + .then(res => res.linkToken);
143 + }
144 +}
145 +exports.default = Client;
1 +export declare class SignatureValidationFailed extends Error {
2 + signature?: string;
3 + constructor(message: string, signature?: string);
4 +}
5 +export declare class JSONParseError extends Error {
6 + raw: any;
7 + constructor(message: string, raw: any);
8 +}
9 +export declare class RequestError extends Error {
10 + code: string;
11 + private originalError;
12 + constructor(message: string, code: string, originalError: Error);
13 +}
14 +export declare class ReadError extends Error {
15 + private originalError;
16 + constructor(originalError: Error);
17 +}
18 +export declare class HTTPError extends Error {
19 + statusCode: number;
20 + statusMessage: string;
21 + originalError: any;
22 + constructor(message: string, statusCode: number, statusMessage: string, originalError: any);
23 +}
1 +"use strict";
2 +Object.defineProperty(exports, "__esModule", { value: true });
3 +class SignatureValidationFailed extends Error {
4 + constructor(message, signature) {
5 + super(message);
6 + this.signature = signature;
7 + }
8 +}
9 +exports.SignatureValidationFailed = SignatureValidationFailed;
10 +class JSONParseError extends Error {
11 + constructor(message, raw) {
12 + super(message);
13 + this.raw = raw;
14 + }
15 +}
16 +exports.JSONParseError = JSONParseError;
17 +class RequestError extends Error {
18 + constructor(message, code, originalError) {
19 + super(message);
20 + this.code = code;
21 + this.originalError = originalError;
22 + }
23 +}
24 +exports.RequestError = RequestError;
25 +class ReadError extends Error {
26 + constructor(originalError) {
27 + super(originalError.message);
28 + this.originalError = originalError;
29 + }
30 +}
31 +exports.ReadError = ReadError;
32 +class HTTPError extends Error {
33 + constructor(message, statusCode, statusMessage, originalError) {
34 + super(message);
35 + this.statusCode = statusCode;
36 + this.statusMessage = statusMessage;
37 + this.originalError = originalError;
38 + }
39 +}
40 +exports.HTTPError = HTTPError;
1 +/// <reference types="node" />
2 +import { Readable } from "stream";
3 +export default class HTTPClient {
4 + private instance;
5 + constructor(baseURL?: string, defaultHeaders?: any);
6 + get<T>(url: string, params?: any): Promise<T>;
7 + getStream(url: string, params?: any): Promise<Readable>;
8 + post<T>(url: string, data?: any): Promise<T>;
9 + postBinary<T>(url: string, data: Buffer | Readable, contentType?: string): Promise<T>;
10 + delete<T>(url: string, params?: any): Promise<T>;
11 + private wrapError;
12 +}
1 +"use strict";
2 +Object.defineProperty(exports, "__esModule", { value: true });
3 +const axios_1 = require("axios");
4 +const stream_1 = require("stream");
5 +const exceptions_1 = require("./exceptions");
6 +const fileType = require("file-type");
7 +const pkg = require("../package.json");
8 +class HTTPClient {
9 + constructor(baseURL, defaultHeaders) {
10 + this.instance = axios_1.default.create({
11 + baseURL,
12 + headers: Object.assign({}, defaultHeaders, {
13 + "User-Agent": `${pkg.name}/${pkg.version}`,
14 + }),
15 + });
16 + this.instance.interceptors.response.use(res => res, err => Promise.reject(this.wrapError(err)));
17 + }
18 + get(url, params) {
19 + return this.instance.get(url, { params }).then(res => res.data);
20 + }
21 + getStream(url, params) {
22 + return this.instance
23 + .get(url, { params, responseType: "stream" })
24 + .then(res => res.data);
25 + }
26 + post(url, data) {
27 + return this.instance
28 + .post(url, data, { headers: { "Content-Type": "application/json" } })
29 + .then(res => res.data);
30 + }
31 + postBinary(url, data, contentType) {
32 + let getBuffer;
33 + if (Buffer.isBuffer(data)) {
34 + getBuffer = Promise.resolve(data);
35 + }
36 + else {
37 + getBuffer = new Promise((resolve, reject) => {
38 + if (data instanceof stream_1.Readable) {
39 + const buffers = [];
40 + let size = 0;
41 + data.on("data", (chunk) => {
42 + buffers.push(chunk);
43 + size += chunk.length;
44 + });
45 + data.on("end", () => resolve(Buffer.concat(buffers, size)));
46 + data.on("error", reject);
47 + }
48 + else {
49 + reject(new Error("invalid data type for postBinary"));
50 + }
51 + });
52 + }
53 + return getBuffer.then(data => {
54 + return this.instance
55 + .post(url, data, {
56 + headers: {
57 + "Content-Type": contentType || fileType(data).mime,
58 + "Content-Length": data.length,
59 + },
60 + })
61 + .then(res => res.data);
62 + });
63 + }
64 + delete(url, params) {
65 + return this.instance.delete(url, { params }).then(res => res.data);
66 + }
67 + wrapError(err) {
68 + if (err.response) {
69 + return new exceptions_1.HTTPError(err.message, err.response.status, err.response.statusText, err);
70 + }
71 + else if (err.code) {
72 + return new exceptions_1.RequestError(err.message, err.code, err);
73 + }
74 + else if (err.config) {
75 + // unknown, but from axios
76 + return new exceptions_1.ReadError(err);
77 + }
78 + // otherwise, just rethrow
79 + return err;
80 + }
81 +}
82 +exports.default = HTTPClient;
1 +import Client from "./client";
2 +import middleware from "./middleware";
3 +import validateSignature from "./validate-signature";
4 +export { Client, middleware, validateSignature };
5 +export * from "./exceptions";
6 +export * from "./types";
1 +"use strict";
2 +function __export(m) {
3 + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
4 +}
5 +Object.defineProperty(exports, "__esModule", { value: true });
6 +const client_1 = require("./client");
7 +exports.Client = client_1.default;
8 +const middleware_1 = require("./middleware");
9 +exports.middleware = middleware_1.default;
10 +const validate_signature_1 = require("./validate-signature");
11 +exports.validateSignature = validate_signature_1.default;
12 +// re-export exceptions and types
13 +__export(require("./exceptions"));
1 +/// <reference types="node" />
2 +import * as http from "http";
3 +import * as Types from "./types";
4 +export declare type Request = http.IncomingMessage & {
5 + body: any;
6 +};
7 +export declare type Response = http.ServerResponse;
8 +export declare type NextCallback = (err?: Error) => void;
9 +export declare type Middleware = (req: Request, res: Response, next: NextCallback) => void;
10 +export default function middleware(config: Types.MiddlewareConfig): Middleware;
1 +"use strict";
2 +Object.defineProperty(exports, "__esModule", { value: true });
3 +const body_parser_1 = require("body-parser");
4 +const exceptions_1 = require("./exceptions");
5 +const validate_signature_1 = require("./validate-signature");
6 +function isValidBody(body) {
7 + return (body && typeof body === "string") || Buffer.isBuffer(body);
8 +}
9 +function middleware(config) {
10 + if (!config.channelSecret) {
11 + throw new Error("no channel secret");
12 + }
13 + const secret = config.channelSecret;
14 + return (req, res, next) => {
15 + // header names are lower-cased
16 + // https://nodejs.org/api/http.html#http_message_headers
17 + const signature = req.headers["x-line-signature"];
18 + if (!signature) {
19 + next(new exceptions_1.SignatureValidationFailed("no signature"));
20 + return;
21 + }
22 + let getBody;
23 + if (isValidBody(req.rawBody)) {
24 + // rawBody is provided in Google Cloud Functions and others
25 + getBody = Promise.resolve(req.rawBody);
26 + }
27 + else if (isValidBody(req.body)) {
28 + getBody = Promise.resolve(req.body);
29 + }
30 + else {
31 + // body may not be parsed yet, parse it to a buffer
32 + getBody = new Promise(resolve => {
33 + body_parser_1.raw({ type: "*/*" })(req, res, () => resolve(req.body));
34 + });
35 + }
36 + getBody.then(body => {
37 + if (!validate_signature_1.default(body, secret, signature)) {
38 + next(new exceptions_1.SignatureValidationFailed("signature validation failed", signature));
39 + return;
40 + }
41 + const strBody = Buffer.isBuffer(body) ? body.toString() : body;
42 + try {
43 + req.body = JSON.parse(strBody);
44 + next();
45 + }
46 + catch (err) {
47 + next(new exceptions_1.JSONParseError(err.message, strBody));
48 + }
49 + });
50 + };
51 +}
52 +exports.default = middleware;
This diff is collapsed. Click to expand it.
1 +"use strict";
2 +Object.defineProperty(exports, "__esModule", { value: true });
1 +/// <reference types="node" />
2 +export default function validateSignature(body: string | Buffer, channelSecret: string, signature: string): boolean;
1 +"use strict";
2 +Object.defineProperty(exports, "__esModule", { value: true });
3 +const crypto_1 = require("crypto");
4 +function s2b(str, encoding) {
5 + if (Buffer.from) {
6 + try {
7 + return Buffer.from(str, encoding);
8 + }
9 + catch (err) {
10 + if (err.name === "TypeError") {
11 + return new Buffer(str, encoding);
12 + }
13 + throw err;
14 + }
15 + }
16 + else {
17 + return new Buffer(str, encoding);
18 + }
19 +}
20 +function safeCompare(a, b) {
21 + if (a.length !== b.length) {
22 + return false;
23 + }
24 + if (crypto_1.timingSafeEqual) {
25 + return crypto_1.timingSafeEqual(a, b);
26 + }
27 + else {
28 + let result = 0;
29 + for (let i = 0; i < a.length; i++) {
30 + result |= a[i] ^ b[i];
31 + }
32 + return result === 0;
33 + }
34 +}
35 +function validateSignature(body, channelSecret, signature) {
36 + return safeCompare(crypto_1.createHmac("SHA256", channelSecret)
37 + .update(body)
38 + .digest(), s2b(signature, "base64"));
39 +}
40 +exports.default = validateSignature;
1 +import { Readable } from "stream";
2 +import HTTPClient from "./http";
3 +import * as Types from "./types";
4 +import { JSONParseError } from "./exceptions";
5 +
6 +function toArray<T>(maybeArr: T | T[]): T[] {
7 + return Array.isArray(maybeArr) ? maybeArr : [maybeArr];
8 +}
9 +
10 +function checkJSON<T>(raw: T): T {
11 + if (typeof raw === "object") {
12 + return raw;
13 + } else {
14 + throw new JSONParseError("Failed to parse response body as JSON", raw);
15 + }
16 +}
17 +
18 +type ChatType = "group" | "room";
19 +
20 +export default class Client {
21 + public config: Types.ClientConfig;
22 + private http: HTTPClient;
23 +
24 + constructor(config: Types.ClientConfig) {
25 + if (!config.channelAccessToken) {
26 + throw new Error("no channel access token");
27 + }
28 +
29 + this.config = config;
30 + this.http = new HTTPClient(
31 + process.env.API_BASE_URL || "https://api.line.me/v2/bot/",
32 + {
33 + Authorization: "Bearer " + this.config.channelAccessToken,
34 + },
35 + );
36 + }
37 +
38 + public pushMessage(
39 + to: string,
40 + messages: Types.Message | Types.Message[],
41 + ): Promise<any> {
42 + return this.http.post("/message/push", {
43 + messages: toArray(messages),
44 + to,
45 + });
46 + }
47 +
48 + public replyMessage(
49 + replyToken: string,
50 + messages: Types.Message | Types.Message[],
51 + ): Promise<any> {
52 + return this.http.post("/message/reply", {
53 + messages: toArray(messages),
54 + replyToken,
55 + });
56 + }
57 +
58 + public multicast(
59 + to: string[],
60 + messages: Types.Message | Types.Message[],
61 + ): Promise<any> {
62 + return this.http.post("/message/multicast", {
63 + messages: toArray(messages),
64 + to,
65 + });
66 + }
67 +
68 + public getProfile(userId: string): Promise<Types.Profile> {
69 + return this.http.get<Types.Profile>(`/profile/${userId}`).then(checkJSON);
70 + }
71 +
72 + private getChatMemberProfile(
73 + chatType: ChatType,
74 + chatId: string,
75 + userId: string,
76 + ): Promise<Types.Profile> {
77 + return this.http
78 + .get<Types.Profile>(`/${chatType}/${chatId}/member/${userId}`)
79 + .then(checkJSON);
80 + }
81 +
82 + public getGroupMemberProfile(
83 + groupId: string,
84 + userId: string,
85 + ): Promise<Types.Profile> {
86 + return this.getChatMemberProfile("group", groupId, userId);
87 + }
88 +
89 + public getRoomMemberProfile(
90 + roomId: string,
91 + userId: string,
92 + ): Promise<Types.Profile> {
93 + return this.getChatMemberProfile("room", roomId, userId);
94 + }
95 +
96 + private getChatMemberIds(
97 + chatType: ChatType,
98 + chatId: string,
99 + ): Promise<string[]> {
100 + const load = (start?: string): Promise<string[]> =>
101 + this.http
102 + .get(`/${chatType}/${chatId}/members/ids`, start ? { start } : null)
103 + .then(checkJSON)
104 + .then((res: { memberIds: string[]; next?: string }) => {
105 + if (!res.next) {
106 + return res.memberIds;
107 + }
108 +
109 + return load(res.next).then(extraIds =>
110 + res.memberIds.concat(extraIds),
111 + );
112 + });
113 + return load();
114 + }
115 +
116 + public getGroupMemberIds(groupId: string): Promise<string[]> {
117 + return this.getChatMemberIds("group", groupId);
118 + }
119 +
120 + public getRoomMemberIds(roomId: string): Promise<string[]> {
121 + return this.getChatMemberIds("room", roomId);
122 + }
123 +
124 + public getMessageContent(messageId: string): Promise<Readable> {
125 + return this.http.getStream(`/message/${messageId}/content`);
126 + }
127 +
128 + private leaveChat(chatType: ChatType, chatId: string): Promise<any> {
129 + return this.http.post(`/${chatType}/${chatId}/leave`);
130 + }
131 +
132 + public leaveGroup(groupId: string): Promise<any> {
133 + return this.leaveChat("group", groupId);
134 + }
135 +
136 + public leaveRoom(roomId: string): Promise<any> {
137 + return this.leaveChat("room", roomId);
138 + }
139 +
140 + public getRichMenu(richMenuId: string): Promise<Types.RichMenuResponse> {
141 + return this.http
142 + .get<Types.RichMenuResponse>(`/richmenu/${richMenuId}`)
143 + .then(checkJSON);
144 + }
145 +
146 + public createRichMenu(richMenu: Types.RichMenu): Promise<string> {
147 + return this.http
148 + .post<any>("/richmenu", richMenu)
149 + .then(checkJSON)
150 + .then(res => res.richMenuId);
151 + }
152 +
153 + public deleteRichMenu(richMenuId: string): Promise<any> {
154 + return this.http.delete(`/richmenu/${richMenuId}`);
155 + }
156 +
157 + public getRichMenuIdOfUser(userId: string): Promise<string> {
158 + return this.http
159 + .get<any>(`/user/${userId}/richmenu`)
160 + .then(checkJSON)
161 + .then(res => res.richMenuId);
162 + }
163 +
164 + public linkRichMenuToUser(userId: string, richMenuId: string): Promise<any> {
165 + return this.http.post(`/user/${userId}/richmenu/${richMenuId}`);
166 + }
167 +
168 + public unlinkRichMenuFromUser(userId: string): Promise<any> {
169 + return this.http.delete(`/user/${userId}/richmenu`);
170 + }
171 +
172 + public getRichMenuImage(richMenuId: string): Promise<Readable> {
173 + return this.http.getStream(`/richmenu/${richMenuId}/content`);
174 + }
175 +
176 + public setRichMenuImage(
177 + richMenuId: string,
178 + data: Buffer | Readable,
179 + contentType?: string,
180 + ): Promise<any> {
181 + return this.http.postBinary(
182 + `/richmenu/${richMenuId}/content`,
183 + data,
184 + contentType,
185 + );
186 + }
187 +
188 + public getRichMenuList(): Promise<Array<Types.RichMenuResponse>> {
189 + return this.http
190 + .get<any>(`/richmenu/list`)
191 + .then(checkJSON)
192 + .then(res => res.richmenus);
193 + }
194 +
195 + public setDefaultRichMenu(richMenuId: string): Promise<{}> {
196 + return this.http.post(`/user/all/richmenu/${richMenuId}`);
197 + }
198 +
199 + public getDefaultRichMenuId(): Promise<string> {
200 + return this.http
201 + .get<any>("/user/all/richmenu")
202 + .then(checkJSON)
203 + .then(res => res.richMenuId);
204 + }
205 +
206 + public deleteDefaultRichMenu(): Promise<{}> {
207 + return this.http.delete("/user/all/richmenu");
208 + }
209 +
210 + public getLinkToken(userId: string): Promise<string> {
211 + return this.http
212 + .post<any>(`/user/${userId}/linkToken`)
213 + .then(checkJSON)
214 + .then(res => res.linkToken);
215 + }
216 +}
1 +export class SignatureValidationFailed extends Error {
2 + constructor(message: string, public signature?: string) {
3 + super(message);
4 + }
5 +}
6 +
7 +export class JSONParseError extends Error {
8 + constructor(message: string, public raw: any) {
9 + super(message);
10 + }
11 +}
12 +
13 +export class RequestError extends Error {
14 + constructor(
15 + message: string,
16 + public code: string,
17 + private originalError: Error,
18 + ) {
19 + super(message);
20 + }
21 +}
22 +
23 +export class ReadError extends Error {
24 + constructor(private originalError: Error) {
25 + super(originalError.message);
26 + }
27 +}
28 +
29 +export class HTTPError extends Error {
30 + constructor(
31 + message: string,
32 + public statusCode: number,
33 + public statusMessage: string,
34 + public originalError: any,
35 + ) {
36 + super(message);
37 + }
38 +}
1 +import axios, { AxiosInstance, AxiosError } from "axios";
2 +import { Readable } from "stream";
3 +import { HTTPError, ReadError, RequestError } from "./exceptions";
4 +import * as fileType from "file-type";
5 +
6 +const pkg = require("../package.json");
7 +
8 +export default class HTTPClient {
9 + private instance: AxiosInstance;
10 +
11 + constructor(baseURL?: string, defaultHeaders?: any) {
12 + this.instance = axios.create({
13 + baseURL,
14 + headers: Object.assign({}, defaultHeaders, {
15 + "User-Agent": `${pkg.name}/${pkg.version}`,
16 + }),
17 + });
18 +
19 + this.instance.interceptors.response.use(
20 + res => res,
21 + err => Promise.reject(this.wrapError(err)),
22 + );
23 + }
24 +
25 + public get<T>(url: string, params?: any): Promise<T> {
26 + return this.instance.get(url, { params }).then(res => res.data);
27 + }
28 +
29 + public getStream(url: string, params?: any): Promise<Readable> {
30 + return this.instance
31 + .get(url, { params, responseType: "stream" })
32 + .then(res => res.data as Readable);
33 + }
34 +
35 + public post<T>(url: string, data?: any): Promise<T> {
36 + return this.instance
37 + .post(url, data, { headers: { "Content-Type": "application/json" } })
38 + .then(res => res.data);
39 + }
40 +
41 + public postBinary<T>(
42 + url: string,
43 + data: Buffer | Readable,
44 + contentType?: string,
45 + ): Promise<T> {
46 + let getBuffer: Promise<Buffer>;
47 +
48 + if (Buffer.isBuffer(data)) {
49 + getBuffer = Promise.resolve(data);
50 + } else {
51 + getBuffer = new Promise((resolve, reject) => {
52 + if (data instanceof Readable) {
53 + const buffers: Buffer[] = [];
54 + let size = 0;
55 + data.on("data", (chunk: Buffer) => {
56 + buffers.push(chunk);
57 + size += chunk.length;
58 + });
59 + data.on("end", () => resolve(Buffer.concat(buffers, size)));
60 + data.on("error", reject);
61 + } else {
62 + reject(new Error("invalid data type for postBinary"));
63 + }
64 + });
65 + }
66 +
67 + return getBuffer.then(data => {
68 + return this.instance
69 + .post(url, data, {
70 + headers: {
71 + "Content-Type": contentType || fileType(data).mime,
72 + "Content-Length": data.length,
73 + },
74 + })
75 + .then(res => res.data);
76 + });
77 + }
78 +
79 + public delete<T>(url: string, params?: any): Promise<T> {
80 + return this.instance.delete(url, { params }).then(res => res.data);
81 + }
82 +
83 + private wrapError(err: AxiosError): Error {
84 + if (err.response) {
85 + return new HTTPError(
86 + err.message,
87 + err.response.status,
88 + err.response.statusText,
89 + err,
90 + );
91 + } else if (err.code) {
92 + return new RequestError(err.message, err.code, err);
93 + } else if (err.config) {
94 + // unknown, but from axios
95 + return new ReadError(err);
96 + }
97 +
98 + // otherwise, just rethrow
99 + return err;
100 + }
101 +}
1 +import Client from "./client";
2 +import middleware from "./middleware";
3 +import validateSignature from "./validate-signature";
4 +
5 +export { Client, middleware, validateSignature };
6 +
7 +// re-export exceptions and types
8 +export * from "./exceptions";
9 +export * from "./types";
1 +import { raw } from "body-parser";
2 +import * as http from "http";
3 +import { JSONParseError, SignatureValidationFailed } from "./exceptions";
4 +import * as Types from "./types";
5 +import validateSignature from "./validate-signature";
6 +
7 +export type Request = http.IncomingMessage & { body: any };
8 +export type Response = http.ServerResponse;
9 +export type NextCallback = (err?: Error) => void;
10 +
11 +export type Middleware = (
12 + req: Request,
13 + res: Response,
14 + next: NextCallback,
15 +) => void;
16 +
17 +function isValidBody(body?: any): body is string | Buffer {
18 + return (body && typeof body === "string") || Buffer.isBuffer(body);
19 +}
20 +
21 +export default function middleware(config: Types.MiddlewareConfig): Middleware {
22 + if (!config.channelSecret) {
23 + throw new Error("no channel secret");
24 + }
25 +
26 + const secret = config.channelSecret;
27 +
28 + return (req, res, next) => {
29 + // header names are lower-cased
30 + // https://nodejs.org/api/http.html#http_message_headers
31 + const signature = req.headers["x-line-signature"] as string;
32 +
33 + if (!signature) {
34 + next(new SignatureValidationFailed("no signature"));
35 + return;
36 + }
37 +
38 + let getBody: Promise<string | Buffer>;
39 + if (isValidBody((req as any).rawBody)) {
40 + // rawBody is provided in Google Cloud Functions and others
41 + getBody = Promise.resolve((req as any).rawBody);
42 + } else if (isValidBody(req.body)) {
43 + getBody = Promise.resolve(req.body);
44 + } else {
45 + // body may not be parsed yet, parse it to a buffer
46 + getBody = new Promise(resolve => {
47 + raw({ type: "*/*" })(req as any, res as any, () => resolve(req.body));
48 + });
49 + }
50 +
51 + getBody.then(body => {
52 + if (!validateSignature(body, secret, signature)) {
53 + next(
54 + new SignatureValidationFailed(
55 + "signature validation failed",
56 + signature,
57 + ),
58 + );
59 + return;
60 + }
61 +
62 + const strBody = Buffer.isBuffer(body) ? body.toString() : body;
63 +
64 + try {
65 + req.body = JSON.parse(strBody);
66 + next();
67 + } catch (err) {
68 + next(new JSONParseError(err.message, strBody));
69 + }
70 + });
71 + };
72 +}
This diff is collapsed. Click to expand it.
1 +import { createHmac, timingSafeEqual } from "crypto";
2 +
3 +function s2b(str: string, encoding: string): Buffer {
4 + if (Buffer.from) {
5 + try {
6 + return Buffer.from(str, encoding);
7 + } catch (err) {
8 + if (err.name === "TypeError") {
9 + return new Buffer(str, encoding);
10 + }
11 + throw err;
12 + }
13 + } else {
14 + return new Buffer(str, encoding);
15 + }
16 +}
17 +
18 +function safeCompare(a: Buffer, b: Buffer): boolean {
19 + if (a.length !== b.length) {
20 + return false;
21 + }
22 +
23 + if (timingSafeEqual) {
24 + return timingSafeEqual(a, b);
25 + } else {
26 + let result = 0;
27 + for (let i = 0; i < a.length; i++) {
28 + result |= a[i] ^ b[i];
29 + }
30 + return result === 0;
31 + }
32 +}
33 +
34 +export default function validateSignature(
35 + body: string | Buffer,
36 + channelSecret: string,
37 + signature: string,
38 +): boolean {
39 + return safeCompare(
40 + createHmac("SHA256", channelSecret)
41 + .update(body)
42 + .digest(),
43 + s2b(signature, "base64"),
44 + );
45 +}
1 +{
2 + "_from": "@line/bot-sdk",
3 + "_id": "@line/bot-sdk@6.4.0",
4 + "_inBundle": false,
5 + "_integrity": "sha512-N0FkrqFxTTleOpD6y7DTK8qbMYHr9Q8qZfrAmSYEFAGedM1HLJdbNNkStj5GT+svx+w+/ePF/n7nAEts0aJwkA==",
6 + "_location": "/@line/bot-sdk",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "tag",
10 + "registry": true,
11 + "raw": "@line/bot-sdk",
12 + "name": "@line/bot-sdk",
13 + "escapedName": "@line%2fbot-sdk",
14 + "scope": "@line",
15 + "rawSpec": "",
16 + "saveSpec": null,
17 + "fetchSpec": "latest"
18 + },
19 + "_requiredBy": [
20 + "#USER",
21 + "/"
22 + ],
23 + "_resolved": "https://registry.npmjs.org/@line/bot-sdk/-/bot-sdk-6.4.0.tgz",
24 + "_shasum": "18aa7659da26d3a8487614c74ad9ccb80ec4ca59",
25 + "_spec": "@line/bot-sdk",
26 + "_where": "C:\\Users\\KSI\\Desktop\\3-2\\OSS\\LineBot",
27 + "bugs": {
28 + "url": "https://github.com/line/line-bot-sdk-nodejs/issues"
29 + },
30 + "bundleDependencies": false,
31 + "dependencies": {
32 + "@types/body-parser": "^1.16.8",
33 + "@types/file-type": "^5.2.1",
34 + "@types/node": "^7.0.31",
35 + "axios": "^0.16.2",
36 + "body-parser": "^1.18.2",
37 + "file-type": "^7.2.0"
38 + },
39 + "deprecated": false,
40 + "description": "Node.js SDK for LINE Messaging API",
41 + "devDependencies": {
42 + "@types/express": "^4.0.35",
43 + "@types/mocha": "^2.2.41",
44 + "del-cli": "^1.1.0",
45 + "express": "^4.16.3",
46 + "husky": "^0.14.3",
47 + "mocha": "^5.2.0",
48 + "nyc": "^12.0.2",
49 + "prettier": "^1.15.2",
50 + "ts-node": "^3.3.0",
51 + "typescript": "^3.1.6",
52 + "vuepress": "^0.14.2"
53 + },
54 + "engines": {
55 + "node": ">=6"
56 + },
57 + "files": [
58 + "dist",
59 + "lib"
60 + ],
61 + "homepage": "https://github.com/line/line-bot-sdk-nodejs#readme",
62 + "keywords": [
63 + "node",
64 + "line",
65 + "sdk"
66 + ],
67 + "license": "Apache-2.0",
68 + "main": "dist/index.js",
69 + "name": "@line/bot-sdk",
70 + "nyc": {
71 + "require": [
72 + "ts-node/register"
73 + ],
74 + "extension": [
75 + ".ts"
76 + ],
77 + "reporter": [
78 + "lcov",
79 + "text-summary"
80 + ],
81 + "sourceMap": true,
82 + "instrument": true
83 + },
84 + "repository": {
85 + "type": "git",
86 + "url": "git+ssh://git@github.com/line/line-bot-sdk-nodejs.git"
87 + },
88 + "scripts": {
89 + "build": "tsc",
90 + "clean": "del-cli dist",
91 + "docs": "vuepress dev docs",
92 + "docs:build": "vuepress build docs",
93 + "docs:deploy": "./deploy-docs.sh",
94 + "format": "npm run prettier -- --write",
95 + "format:check": "npm run prettier -- -l",
96 + "prebuild": "npm run format:check && npm run clean",
97 + "precommit": "npm run format:check",
98 + "prepush": "npm run format:check && npm run build && npm run test",
99 + "pretest": "npm run build",
100 + "prettier": "prettier --parser typescript --trailing-comma all \"{lib,test}/**/*.ts\"",
101 + "release": "npm run build && npm publish --access public",
102 + "test": "API_BASE_URL=http://localhost:1234/ TEST_PORT=1234 TS_NODE_CACHE=0 nyc mocha"
103 + },
104 + "types": "dist/index.d.ts",
105 + "version": "6.4.0"
106 +}
1 + MIT License
2 +
3 + Copyright (c) Microsoft Corporation. All rights reserved.
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
1 +# Installation
2 +> `npm install --save @types/body-parser`
3 +
4 +# Summary
5 +This package contains type definitions for body-parser (https://github.com/expressjs/body-parser).
6 +
7 +# Details
8 +Files were exported from https://www.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/body-parser
9 +
10 +Additional Details
11 + * Last updated: Wed, 25 Apr 2018 00:24:37 GMT
12 + * Dependencies: connect, http, node
13 + * Global values: none
14 +
15 +# Credits
16 +These definitions were written by Santi Albo <https://github.com/santialbo>, Vilic Vane <https://github.com/vilic>, Jonathan Häberle <https://github.com/dreampulse>, Gevik Babakhani <https://github.com/blendsdk>, Tomasz Łaziuk <https://github.com/tlaziuk>, Jason Walton <https://github.com/jwalton>.
1 +// Type definitions for body-parser 1.17
2 +// Project: https://github.com/expressjs/body-parser
3 +// Definitions by: Santi Albo <https://github.com/santialbo>
4 +// Vilic Vane <https://github.com/vilic>
5 +// Jonathan Häberle <https://github.com/dreampulse>
6 +// Gevik Babakhani <https://github.com/blendsdk>
7 +// Tomasz Łaziuk <https://github.com/tlaziuk>
8 +// Jason Walton <https://github.com/jwalton>
9 +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
10 +// TypeScript Version: 2.2
11 +
12 +/// <reference types="node" />
13 +
14 +import { NextHandleFunction } from 'connect';
15 +import * as http from 'http';
16 +
17 +// for docs go to https://github.com/expressjs/body-parser/tree/1.16.0#body-parser
18 +
19 +// @deprecated
20 +declare function bodyParser(options?: bodyParser.OptionsJson & bodyParser.OptionsText & bodyParser.OptionsUrlencoded): NextHandleFunction;
21 +
22 +declare namespace bodyParser {
23 + interface Options {
24 + inflate?: boolean;
25 + limit?: number | string;
26 + type?: string | string[] | ((req: http.IncomingMessage) => any);
27 + verify?(req: http.IncomingMessage, res: http.ServerResponse, buf: Buffer, encoding: string): void;
28 + }
29 +
30 + interface OptionsJson extends Options {
31 + reviver?(key: string, value: any): any;
32 + strict?: boolean;
33 + }
34 +
35 + interface OptionsText extends Options {
36 + defaultCharset?: string;
37 + }
38 +
39 + interface OptionsUrlencoded extends Options {
40 + extended?: boolean;
41 + parameterLimit?: number;
42 + }
43 +
44 + function json(options?: OptionsJson): NextHandleFunction;
45 +
46 + function raw(options?: Options): NextHandleFunction;
47 +
48 + function text(options?: OptionsText): NextHandleFunction;
49 +
50 + function urlencoded(options?: OptionsUrlencoded): NextHandleFunction;
51 +}
52 +
53 +export = bodyParser;
1 +{
2 + "_from": "@types/body-parser@^1.16.8",
3 + "_id": "@types/body-parser@1.17.0",
4 + "_inBundle": false,
5 + "_integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==",
6 + "_location": "/@types/body-parser",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "@types/body-parser@^1.16.8",
12 + "name": "@types/body-parser",
13 + "escapedName": "@types%2fbody-parser",
14 + "scope": "@types",
15 + "rawSpec": "^1.16.8",
16 + "saveSpec": null,
17 + "fetchSpec": "^1.16.8"
18 + },
19 + "_requiredBy": [
20 + "/@line/bot-sdk"
21 + ],
22 + "_resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz",
23 + "_shasum": "9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c",
24 + "_spec": "@types/body-parser@^1.16.8",
25 + "_where": "C:\\Users\\KSI\\Desktop\\3-2\\OSS\\LineBot\\node_modules\\@line\\bot-sdk",
26 + "bugs": {
27 + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/issues"
28 + },
29 + "bundleDependencies": false,
30 + "contributors": [
31 + {
32 + "name": "Santi Albo",
33 + "url": "https://github.com/santialbo"
34 + },
35 + {
36 + "name": "Vilic Vane",
37 + "url": "https://github.com/vilic"
38 + },
39 + {
40 + "name": "Jonathan Häberle",
41 + "url": "https://github.com/dreampulse"
42 + },
43 + {
44 + "name": "Gevik Babakhani",
45 + "url": "https://github.com/blendsdk"
46 + },
47 + {
48 + "name": "Tomasz Łaziuk",
49 + "url": "https://github.com/tlaziuk"
50 + },
51 + {
52 + "name": "Jason Walton",
53 + "url": "https://github.com/jwalton"
54 + }
55 + ],
56 + "dependencies": {
57 + "@types/connect": "*",
58 + "@types/node": "*"
59 + },
60 + "deprecated": false,
61 + "description": "TypeScript definitions for body-parser",
62 + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped#readme",
63 + "license": "MIT",
64 + "main": "",
65 + "name": "@types/body-parser",
66 + "repository": {
67 + "type": "git",
68 + "url": "git+https://github.com/DefinitelyTyped/DefinitelyTyped.git"
69 + },
70 + "scripts": {},
71 + "typeScriptVersion": "2.2",
72 + "typesPublisherContentHash": "d50d69303022e9f76f6d905e480a7dc98120bbcedb696a9722a4a2e9f08473e6",
73 + "version": "1.17.0"
74 +}
1 + MIT License
2 +
3 + Copyright (c) Microsoft Corporation. All rights reserved.
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
1 +# Installation
2 +> `npm install --save @types/connect`
3 +
4 +# Summary
5 +This package contains type definitions for connect (https://github.com/senchalabs/connect).
6 +
7 +# Details
8 +Files were exported from https://www.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/connect
9 +
10 +Additional Details
11 + * Last updated: Tue, 17 Apr 2018 01:01:05 GMT
12 + * Dependencies: http, node
13 + * Global values: none
14 +
15 +# Credits
16 +These definitions were written by Maxime LUCE <https://github.com/SomaticIT>, Evan Hahn <https://github.com/EvanHahn>.
1 +// Type definitions for connect v3.4.0
2 +// Project: https://github.com/senchalabs/connect
3 +// Definitions by: Maxime LUCE <https://github.com/SomaticIT>
4 +// Evan Hahn <https://github.com/EvanHahn>
5 +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
6 +
7 +/// <reference types="node" />
8 +
9 +
10 +import * as http from "http";
11 +
12 +/**
13 + * Create a new connect server.
14 + * @public
15 + */
16 +declare function createServer(): createServer.Server;
17 +
18 +declare namespace createServer {
19 + export type ServerHandle = HandleFunction | http.Server;
20 +
21 + type NextFunction = (err?: any) => void;
22 +
23 + export type SimpleHandleFunction = (req: http.IncomingMessage, res: http.ServerResponse) => void;
24 + export type NextHandleFunction = (req: http.IncomingMessage, res: http.ServerResponse, next: NextFunction) => void;
25 + export type ErrorHandleFunction = (err: any, req: http.IncomingMessage, res: http.ServerResponse, next: NextFunction) => void;
26 + export type HandleFunction = SimpleHandleFunction | NextHandleFunction | ErrorHandleFunction;
27 +
28 + export interface ServerStackItem {
29 + route: string;
30 + handle: ServerHandle;
31 + }
32 +
33 + export interface Server extends NodeJS.EventEmitter {
34 + (req: http.IncomingMessage, res: http.ServerResponse, next?: Function): void;
35 +
36 + route: string;
37 + stack: ServerStackItem[];
38 +
39 + /**
40 + * Utilize the given middleware `handle` to the given `route`,
41 + * defaulting to _/_. This "route" is the mount-point for the
42 + * middleware, when given a value other than _/_ the middleware
43 + * is only effective when that segment is present in the request's
44 + * pathname.
45 + *
46 + * For example if we were to mount a function at _/admin_, it would
47 + * be invoked on _/admin_, and _/admin/settings_, however it would
48 + * not be invoked for _/_, or _/posts_.
49 + *
50 + * @public
51 + */
52 + use(fn: HandleFunction): Server;
53 + use(route: string, fn: HandleFunction): Server;
54 +
55 + /**
56 + * Handle server requests, punting them down
57 + * the middleware stack.
58 + *
59 + * @private
60 + */
61 + handle(req: http.IncomingMessage, res: http.ServerResponse, next: Function): void;
62 +
63 + /**
64 + * Listen for connections.
65 + *
66 + * This method takes the same arguments
67 + * as node's `http.Server#listen()`.
68 + *
69 + * HTTP and HTTPS:
70 + *
71 + * If you run your application both as HTTP
72 + * and HTTPS you may wrap them individually,
73 + * since your Connect "server" is really just
74 + * a JavaScript `Function`.
75 + *
76 + * var connect = require('connect')
77 + * , http = require('http')
78 + * , https = require('https');
79 + *
80 + * var app = connect();
81 + *
82 + * http.createServer(app).listen(80);
83 + * https.createServer(options, app).listen(443);
84 + *
85 + * @api public
86 + */
87 + listen(port: number, hostname?: string, backlog?: number, callback?: Function): http.Server;
88 + listen(port: number, hostname?: string, callback?: Function): http.Server;
89 + listen(path: string, callback?: Function): http.Server;
90 + listen(handle: any, listeningListener?: Function): http.Server;
91 + }
92 +}
93 +
94 +export = createServer;
1 +{
2 + "_from": "@types/connect@*",
3 + "_id": "@types/connect@3.4.32",
4 + "_inBundle": false,
5 + "_integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==",
6 + "_location": "/@types/connect",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "@types/connect@*",
12 + "name": "@types/connect",
13 + "escapedName": "@types%2fconnect",
14 + "scope": "@types",
15 + "rawSpec": "*",
16 + "saveSpec": null,
17 + "fetchSpec": "*"
18 + },
19 + "_requiredBy": [
20 + "/@types/body-parser"
21 + ],
22 + "_resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz",
23 + "_shasum": "aa0e9616b9435ccad02bc52b5b454ffc2c70ba28",
24 + "_spec": "@types/connect@*",
25 + "_where": "C:\\Users\\KSI\\Desktop\\3-2\\OSS\\LineBot\\node_modules\\@types\\body-parser",
26 + "bugs": {
27 + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/issues"
28 + },
29 + "bundleDependencies": false,
30 + "contributors": [
31 + {
32 + "name": "Maxime LUCE",
33 + "url": "https://github.com/SomaticIT"
34 + },
35 + {
36 + "name": "Evan Hahn",
37 + "url": "https://github.com/EvanHahn"
38 + }
39 + ],
40 + "dependencies": {
41 + "@types/node": "*"
42 + },
43 + "deprecated": false,
44 + "description": "TypeScript definitions for connect",
45 + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped#readme",
46 + "license": "MIT",
47 + "main": "",
48 + "name": "@types/connect",
49 + "repository": {
50 + "type": "git",
51 + "url": "git+https://github.com/DefinitelyTyped/DefinitelyTyped.git"
52 + },
53 + "scripts": {},
54 + "typeScriptVersion": "2.0",
55 + "typesPublisherContentHash": "d988cf1d88b273d694c4fcfe3699c4785f7e60ea0c8e094b598922c43ab3fb4e",
56 + "version": "3.4.32"
57 +}
1 + MIT License
2 +
3 + Copyright (c) Microsoft Corporation. All rights reserved.
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
1 +# Installation
2 +> `npm install --save @types/file-type`
3 +
4 +# Summary
5 +This package contains type definitions for file-type (https://github.com/sindresorhus/file-type).
6 +
7 +# Details
8 +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/file-type
9 +
10 +Additional Details
11 + * Last updated: Thu, 29 Nov 2018 23:28:07 GMT
12 + * Dependencies: node
13 + * Global values: none
14 +
15 +# Credits
16 +These definitions were written by KIM Jaesuck a.k.a. gim tcaesvk <https://github.com/tcaesvk>, BendingBender <https://github.com/BendingBender>.
1 +// Type definitions for file-type 5.2
2 +// Project: https://github.com/sindresorhus/file-type
3 +// Definitions by: KIM Jaesuck a.k.a. gim tcaesvk <https://github.com/tcaesvk>
4 +// BendingBender <https://github.com/BendingBender>
5 +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
6 +
7 +/// <reference types="node" />
8 +
9 +export = FileType;
10 +
11 +declare function FileType(buf: Buffer | Uint8Array): FileType.FileTypeResult;
12 +
13 +declare namespace FileType {
14 + interface FileTypeResult {
15 + ext: string;
16 + mime: string;
17 + }
18 +
19 + const minimumBytes: number;
20 +}
1 +{
2 + "_from": "@types/file-type@^5.2.1",
3 + "_id": "@types/file-type@5.2.2",
4 + "_inBundle": false,
5 + "_integrity": "sha512-GWtM4fyqfb+bec4ocpo51/y4x0b83Je+iA6eV131LT9wL0//G+1UgwbkMg7w61ceOwR+KkZXK00z44jrrNljWg==",
6 + "_location": "/@types/file-type",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "@types/file-type@^5.2.1",
12 + "name": "@types/file-type",
13 + "escapedName": "@types%2ffile-type",
14 + "scope": "@types",
15 + "rawSpec": "^5.2.1",
16 + "saveSpec": null,
17 + "fetchSpec": "^5.2.1"
18 + },
19 + "_requiredBy": [
20 + "/@line/bot-sdk"
21 + ],
22 + "_resolved": "https://registry.npmjs.org/@types/file-type/-/file-type-5.2.2.tgz",
23 + "_shasum": "901cda395f75780c52bbc7a56fd1f5b5bc96f28f",
24 + "_spec": "@types/file-type@^5.2.1",
25 + "_where": "C:\\Users\\KSI\\Desktop\\3-2\\OSS\\LineBot\\node_modules\\@line\\bot-sdk",
26 + "bugs": {
27 + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/issues"
28 + },
29 + "bundleDependencies": false,
30 + "contributors": [
31 + {
32 + "name": "KIM Jaesuck a.k.a. gim tcaesvk",
33 + "url": "https://github.com/tcaesvk"
34 + },
35 + {
36 + "name": "BendingBender",
37 + "url": "https://github.com/BendingBender"
38 + }
39 + ],
40 + "dependencies": {
41 + "@types/node": "*"
42 + },
43 + "deprecated": false,
44 + "description": "TypeScript definitions for file-type",
45 + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped#readme",
46 + "license": "MIT",
47 + "main": "",
48 + "name": "@types/file-type",
49 + "repository": {
50 + "type": "git",
51 + "url": "git+https://github.com/DefinitelyTyped/DefinitelyTyped.git"
52 + },
53 + "scripts": {},
54 + "typeScriptVersion": "2.0",
55 + "types": "index",
56 + "typesPublisherContentHash": "1e124f27ca50dd322d07954510e787e15c6c0a3ac4a8af6cfa551d89015c98ca",
57 + "version": "5.2.2"
58 +}
1 + MIT License
2 +
3 + Copyright (c) Microsoft Corporation. All rights reserved.
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
1 +# Installation
2 +> `npm install --save @types/node`
3 +
4 +# Summary
5 +This package contains type definitions for Node.js (http://nodejs.org/).
6 +
7 +# Details
8 +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node/v7
9 +
10 +Additional Details
11 + * Last updated: Thu, 15 Nov 2018 00:16:17 GMT
12 + * Dependencies: none
13 + * Global values: Buffer, NodeJS, SlowBuffer, Symbol, __dirname, __filename, clearImmediate, clearInterval, clearTimeout, console, exports, global, module, process, require, setImmediate, setInterval, setTimeout
14 +
15 +# Credits
16 +These definitions were written by Microsoft TypeScript <https://github.com/Microsoft>, DefinitelyTyped <https://github.com/DefinitelyTyped>, Parambir Singh <https://github.com/parambirs>, Christian Vaagland Tellnes <https://github.com/tellnes>, Wilco Bakker <https://github.com/WilcoBakker>, Sebastian Silbermann <https://github.com/eps1lon>, Hoàng Văn Khải <https://github.com/KSXGitHub>, Sander Koenders <https://github.com/Archcry>.
This diff could not be displayed because it is too large.
1 +{
2 + "_from": "@types/node@^7.0.31",
3 + "_id": "@types/node@7.10.2",
4 + "_inBundle": false,
5 + "_integrity": "sha512-RO4ig5taKmcrU4Rex8ojG1gpwFkjddzug9iPQSDvbewHN9vDpcFewevkaOK+KT+w1LeZnxbgOyfXwV4pxsQ4GQ==",
6 + "_location": "/@types/node",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "@types/node@^7.0.31",
12 + "name": "@types/node",
13 + "escapedName": "@types%2fnode",
14 + "scope": "@types",
15 + "rawSpec": "^7.0.31",
16 + "saveSpec": null,
17 + "fetchSpec": "^7.0.31"
18 + },
19 + "_requiredBy": [
20 + "/@line/bot-sdk",
21 + "/@types/body-parser",
22 + "/@types/connect",
23 + "/@types/file-type"
24 + ],
25 + "_resolved": "https://registry.npmjs.org/@types/node/-/node-7.10.2.tgz",
26 + "_shasum": "a98845168012d7a63a84d50e738829da43bdb0de",
27 + "_spec": "@types/node@^7.0.31",
28 + "_where": "C:\\Users\\KSI\\Desktop\\3-2\\OSS\\LineBot\\node_modules\\@line\\bot-sdk",
29 + "bugs": {
30 + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/issues"
31 + },
32 + "bundleDependencies": false,
33 + "contributors": [
34 + {
35 + "name": "Microsoft TypeScript",
36 + "url": "https://github.com/Microsoft"
37 + },
38 + {
39 + "name": "DefinitelyTyped",
40 + "url": "https://github.com/DefinitelyTyped"
41 + },
42 + {
43 + "name": "Parambir Singh",
44 + "url": "https://github.com/parambirs"
45 + },
46 + {
47 + "name": "Christian Vaagland Tellnes",
48 + "url": "https://github.com/tellnes"
49 + },
50 + {
51 + "name": "Wilco Bakker",
52 + "url": "https://github.com/WilcoBakker"
53 + },
54 + {
55 + "name": "Sebastian Silbermann",
56 + "url": "https://github.com/eps1lon"
57 + },
58 + {
59 + "name": "Hoàng Văn Khải",
60 + "url": "https://github.com/KSXGitHub"
61 + },
62 + {
63 + "name": "Sander Koenders",
64 + "url": "https://github.com/Archcry"
65 + }
66 + ],
67 + "dependencies": {},
68 + "deprecated": false,
69 + "description": "TypeScript definitions for Node.js",
70 + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped#readme",
71 + "license": "MIT",
72 + "main": "",
73 + "name": "@types/node",
74 + "repository": {
75 + "type": "git",
76 + "url": "git+https://github.com/DefinitelyTyped/DefinitelyTyped.git"
77 + },
78 + "scripts": {},
79 + "typeScriptVersion": "2.0",
80 + "types": "index",
81 + "typesPublisherContentHash": "55896a12ed8765c021f335913ef256ce4eb8ac2fc4b0c93611d7ce514e2906ea",
82 + "version": "7.10.2"
83 +}
1 +1.3.5 / 2018-02-28
2 +==================
3 +
4 + * deps: mime-types@~2.1.18
5 + - deps: mime-db@~1.33.0
6 +
7 +1.3.4 / 2017-08-22
8 +==================
9 +
10 + * deps: mime-types@~2.1.16
11 + - deps: mime-db@~1.29.0
12 +
13 +1.3.3 / 2016-05-02
14 +==================
15 +
16 + * deps: mime-types@~2.1.11
17 + - deps: mime-db@~1.23.0
18 + * deps: negotiator@0.6.1
19 + - perf: improve `Accept` parsing speed
20 + - perf: improve `Accept-Charset` parsing speed
21 + - perf: improve `Accept-Encoding` parsing speed
22 + - perf: improve `Accept-Language` parsing speed
23 +
24 +1.3.2 / 2016-03-08
25 +==================
26 +
27 + * deps: mime-types@~2.1.10
28 + - Fix extension of `application/dash+xml`
29 + - Update primary extension for `audio/mp4`
30 + - deps: mime-db@~1.22.0
31 +
32 +1.3.1 / 2016-01-19
33 +==================
34 +
35 + * deps: mime-types@~2.1.9
36 + - deps: mime-db@~1.21.0
37 +
38 +1.3.0 / 2015-09-29
39 +==================
40 +
41 + * deps: mime-types@~2.1.7
42 + - deps: mime-db@~1.19.0
43 + * deps: negotiator@0.6.0
44 + - Fix including type extensions in parameters in `Accept` parsing
45 + - Fix parsing `Accept` parameters with quoted equals
46 + - Fix parsing `Accept` parameters with quoted semicolons
47 + - Lazy-load modules from main entry point
48 + - perf: delay type concatenation until needed
49 + - perf: enable strict mode
50 + - perf: hoist regular expressions
51 + - perf: remove closures getting spec properties
52 + - perf: remove a closure from media type parsing
53 + - perf: remove property delete from media type parsing
54 +
55 +1.2.13 / 2015-09-06
56 +===================
57 +
58 + * deps: mime-types@~2.1.6
59 + - deps: mime-db@~1.18.0
60 +
61 +1.2.12 / 2015-07-30
62 +===================
63 +
64 + * deps: mime-types@~2.1.4
65 + - deps: mime-db@~1.16.0
66 +
67 +1.2.11 / 2015-07-16
68 +===================
69 +
70 + * deps: mime-types@~2.1.3
71 + - deps: mime-db@~1.15.0
72 +
73 +1.2.10 / 2015-07-01
74 +===================
75 +
76 + * deps: mime-types@~2.1.2
77 + - deps: mime-db@~1.14.0
78 +
79 +1.2.9 / 2015-06-08
80 +==================
81 +
82 + * deps: mime-types@~2.1.1
83 + - perf: fix deopt during mapping
84 +
85 +1.2.8 / 2015-06-07
86 +==================
87 +
88 + * deps: mime-types@~2.1.0
89 + - deps: mime-db@~1.13.0
90 + * perf: avoid argument reassignment & argument slice
91 + * perf: avoid negotiator recursive construction
92 + * perf: enable strict mode
93 + * perf: remove unnecessary bitwise operator
94 +
95 +1.2.7 / 2015-05-10
96 +==================
97 +
98 + * deps: negotiator@0.5.3
99 + - Fix media type parameter matching to be case-insensitive
100 +
101 +1.2.6 / 2015-05-07
102 +==================
103 +
104 + * deps: mime-types@~2.0.11
105 + - deps: mime-db@~1.9.1
106 + * deps: negotiator@0.5.2
107 + - Fix comparing media types with quoted values
108 + - Fix splitting media types with quoted commas
109 +
110 +1.2.5 / 2015-03-13
111 +==================
112 +
113 + * deps: mime-types@~2.0.10
114 + - deps: mime-db@~1.8.0
115 +
116 +1.2.4 / 2015-02-14
117 +==================
118 +
119 + * Support Node.js 0.6
120 + * deps: mime-types@~2.0.9
121 + - deps: mime-db@~1.7.0
122 + * deps: negotiator@0.5.1
123 + - Fix preference sorting to be stable for long acceptable lists
124 +
125 +1.2.3 / 2015-01-31
126 +==================
127 +
128 + * deps: mime-types@~2.0.8
129 + - deps: mime-db@~1.6.0
130 +
131 +1.2.2 / 2014-12-30
132 +==================
133 +
134 + * deps: mime-types@~2.0.7
135 + - deps: mime-db@~1.5.0
136 +
137 +1.2.1 / 2014-12-30
138 +==================
139 +
140 + * deps: mime-types@~2.0.5
141 + - deps: mime-db@~1.3.1
142 +
143 +1.2.0 / 2014-12-19
144 +==================
145 +
146 + * deps: negotiator@0.5.0
147 + - Fix list return order when large accepted list
148 + - Fix missing identity encoding when q=0 exists
149 + - Remove dynamic building of Negotiator class
150 +
151 +1.1.4 / 2014-12-10
152 +==================
153 +
154 + * deps: mime-types@~2.0.4
155 + - deps: mime-db@~1.3.0
156 +
157 +1.1.3 / 2014-11-09
158 +==================
159 +
160 + * deps: mime-types@~2.0.3
161 + - deps: mime-db@~1.2.0
162 +
163 +1.1.2 / 2014-10-14
164 +==================
165 +
166 + * deps: negotiator@0.4.9
167 + - Fix error when media type has invalid parameter
168 +
169 +1.1.1 / 2014-09-28
170 +==================
171 +
172 + * deps: mime-types@~2.0.2
173 + - deps: mime-db@~1.1.0
174 + * deps: negotiator@0.4.8
175 + - Fix all negotiations to be case-insensitive
176 + - Stable sort preferences of same quality according to client order
177 +
178 +1.1.0 / 2014-09-02
179 +==================
180 +
181 + * update `mime-types`
182 +
183 +1.0.7 / 2014-07-04
184 +==================
185 +
186 + * Fix wrong type returned from `type` when match after unknown extension
187 +
188 +1.0.6 / 2014-06-24
189 +==================
190 +
191 + * deps: negotiator@0.4.7
192 +
193 +1.0.5 / 2014-06-20
194 +==================
195 +
196 + * fix crash when unknown extension given
197 +
198 +1.0.4 / 2014-06-19
199 +==================
200 +
201 + * use `mime-types`
202 +
203 +1.0.3 / 2014-06-11
204 +==================
205 +
206 + * deps: negotiator@0.4.6
207 + - Order by specificity when quality is the same
208 +
209 +1.0.2 / 2014-05-29
210 +==================
211 +
212 + * Fix interpretation when header not in request
213 + * deps: pin negotiator@0.4.5
214 +
215 +1.0.1 / 2014-01-18
216 +==================
217 +
218 + * Identity encoding isn't always acceptable
219 + * deps: negotiator@~0.4.0
220 +
221 +1.0.0 / 2013-12-27
222 +==================
223 +
224 + * Genesis
1 +(The MIT License)
2 +
3 +Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
4 +Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
5 +
6 +Permission is hereby granted, free of charge, to any person obtaining
7 +a copy of this software and associated documentation files (the
8 +'Software'), to deal in the Software without restriction, including
9 +without limitation the rights to use, copy, modify, merge, publish,
10 +distribute, sublicense, and/or sell copies of the Software, and to
11 +permit persons to whom the Software is furnished to do so, subject to
12 +the following conditions:
13 +
14 +The above copyright notice and this permission notice shall be
15 +included in all copies or substantial portions of the Software.
16 +
17 +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 +# accepts
2 +
3 +[![NPM Version][npm-image]][npm-url]
4 +[![NPM Downloads][downloads-image]][downloads-url]
5 +[![Node.js Version][node-version-image]][node-version-url]
6 +[![Build Status][travis-image]][travis-url]
7 +[![Test Coverage][coveralls-image]][coveralls-url]
8 +
9 +Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator).
10 +Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
11 +
12 +In addition to negotiator, it allows:
13 +
14 +- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])`
15 + as well as `('text/html', 'application/json')`.
16 +- Allows type shorthands such as `json`.
17 +- Returns `false` when no types match
18 +- Treats non-existent headers as `*`
19 +
20 +## Installation
21 +
22 +This is a [Node.js](https://nodejs.org/en/) module available through the
23 +[npm registry](https://www.npmjs.com/). Installation is done using the
24 +[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
25 +
26 +```sh
27 +$ npm install accepts
28 +```
29 +
30 +## API
31 +
32 +<!-- eslint-disable no-unused-vars -->
33 +
34 +```js
35 +var accepts = require('accepts')
36 +```
37 +
38 +### accepts(req)
39 +
40 +Create a new `Accepts` object for the given `req`.
41 +
42 +#### .charset(charsets)
43 +
44 +Return the first accepted charset. If nothing in `charsets` is accepted,
45 +then `false` is returned.
46 +
47 +#### .charsets()
48 +
49 +Return the charsets that the request accepts, in the order of the client's
50 +preference (most preferred first).
51 +
52 +#### .encoding(encodings)
53 +
54 +Return the first accepted encoding. If nothing in `encodings` is accepted,
55 +then `false` is returned.
56 +
57 +#### .encodings()
58 +
59 +Return the encodings that the request accepts, in the order of the client's
60 +preference (most preferred first).
61 +
62 +#### .language(languages)
63 +
64 +Return the first accepted language. If nothing in `languages` is accepted,
65 +then `false` is returned.
66 +
67 +#### .languages()
68 +
69 +Return the languages that the request accepts, in the order of the client's
70 +preference (most preferred first).
71 +
72 +#### .type(types)
73 +
74 +Return the first accepted type (and it is returned as the same text as what
75 +appears in the `types` array). If nothing in `types` is accepted, then `false`
76 +is returned.
77 +
78 +The `types` array can contain full MIME types or file extensions. Any value
79 +that is not a full MIME types is passed to `require('mime-types').lookup`.
80 +
81 +#### .types()
82 +
83 +Return the types that the request accepts, in the order of the client's
84 +preference (most preferred first).
85 +
86 +## Examples
87 +
88 +### Simple type negotiation
89 +
90 +This simple example shows how to use `accepts` to return a different typed
91 +respond body based on what the client wants to accept. The server lists it's
92 +preferences in order and will get back the best match between the client and
93 +server.
94 +
95 +```js
96 +var accepts = require('accepts')
97 +var http = require('http')
98 +
99 +function app (req, res) {
100 + var accept = accepts(req)
101 +
102 + // the order of this list is significant; should be server preferred order
103 + switch (accept.type(['json', 'html'])) {
104 + case 'json':
105 + res.setHeader('Content-Type', 'application/json')
106 + res.write('{"hello":"world!"}')
107 + break
108 + case 'html':
109 + res.setHeader('Content-Type', 'text/html')
110 + res.write('<b>hello, world!</b>')
111 + break
112 + default:
113 + // the fallback is text/plain, so no need to specify it above
114 + res.setHeader('Content-Type', 'text/plain')
115 + res.write('hello, world!')
116 + break
117 + }
118 +
119 + res.end()
120 +}
121 +
122 +http.createServer(app).listen(3000)
123 +```
124 +
125 +You can test this out with the cURL program:
126 +```sh
127 +curl -I -H'Accept: text/html' http://localhost:3000/
128 +```
129 +
130 +## License
131 +
132 +[MIT](LICENSE)
133 +
134 +[npm-image]: https://img.shields.io/npm/v/accepts.svg
135 +[npm-url]: https://npmjs.org/package/accepts
136 +[node-version-image]: https://img.shields.io/node/v/accepts.svg
137 +[node-version-url]: https://nodejs.org/en/download/
138 +[travis-image]: https://img.shields.io/travis/jshttp/accepts/master.svg
139 +[travis-url]: https://travis-ci.org/jshttp/accepts
140 +[coveralls-image]: https://img.shields.io/coveralls/jshttp/accepts/master.svg
141 +[coveralls-url]: https://coveralls.io/r/jshttp/accepts
142 +[downloads-image]: https://img.shields.io/npm/dm/accepts.svg
143 +[downloads-url]: https://npmjs.org/package/accepts
1 +/*!
2 + * accepts
3 + * Copyright(c) 2014 Jonathan Ong
4 + * Copyright(c) 2015 Douglas Christopher Wilson
5 + * MIT Licensed
6 + */
7 +
8 +'use strict'
9 +
10 +/**
11 + * Module dependencies.
12 + * @private
13 + */
14 +
15 +var Negotiator = require('negotiator')
16 +var mime = require('mime-types')
17 +
18 +/**
19 + * Module exports.
20 + * @public
21 + */
22 +
23 +module.exports = Accepts
24 +
25 +/**
26 + * Create a new Accepts object for the given req.
27 + *
28 + * @param {object} req
29 + * @public
30 + */
31 +
32 +function Accepts (req) {
33 + if (!(this instanceof Accepts)) {
34 + return new Accepts(req)
35 + }
36 +
37 + this.headers = req.headers
38 + this.negotiator = new Negotiator(req)
39 +}
40 +
41 +/**
42 + * Check if the given `type(s)` is acceptable, returning
43 + * the best match when true, otherwise `undefined`, in which
44 + * case you should respond with 406 "Not Acceptable".
45 + *
46 + * The `type` value may be a single mime type string
47 + * such as "application/json", the extension name
48 + * such as "json" or an array `["json", "html", "text/plain"]`. When a list
49 + * or array is given the _best_ match, if any is returned.
50 + *
51 + * Examples:
52 + *
53 + * // Accept: text/html
54 + * this.types('html');
55 + * // => "html"
56 + *
57 + * // Accept: text/*, application/json
58 + * this.types('html');
59 + * // => "html"
60 + * this.types('text/html');
61 + * // => "text/html"
62 + * this.types('json', 'text');
63 + * // => "json"
64 + * this.types('application/json');
65 + * // => "application/json"
66 + *
67 + * // Accept: text/*, application/json
68 + * this.types('image/png');
69 + * this.types('png');
70 + * // => undefined
71 + *
72 + * // Accept: text/*;q=.5, application/json
73 + * this.types(['html', 'json']);
74 + * this.types('html', 'json');
75 + * // => "json"
76 + *
77 + * @param {String|Array} types...
78 + * @return {String|Array|Boolean}
79 + * @public
80 + */
81 +
82 +Accepts.prototype.type =
83 +Accepts.prototype.types = function (types_) {
84 + var types = types_
85 +
86 + // support flattened arguments
87 + if (types && !Array.isArray(types)) {
88 + types = new Array(arguments.length)
89 + for (var i = 0; i < types.length; i++) {
90 + types[i] = arguments[i]
91 + }
92 + }
93 +
94 + // no types, return all requested types
95 + if (!types || types.length === 0) {
96 + return this.negotiator.mediaTypes()
97 + }
98 +
99 + // no accept header, return first given type
100 + if (!this.headers.accept) {
101 + return types[0]
102 + }
103 +
104 + var mimes = types.map(extToMime)
105 + var accepts = this.negotiator.mediaTypes(mimes.filter(validMime))
106 + var first = accepts[0]
107 +
108 + return first
109 + ? types[mimes.indexOf(first)]
110 + : false
111 +}
112 +
113 +/**
114 + * Return accepted encodings or best fit based on `encodings`.
115 + *
116 + * Given `Accept-Encoding: gzip, deflate`
117 + * an array sorted by quality is returned:
118 + *
119 + * ['gzip', 'deflate']
120 + *
121 + * @param {String|Array} encodings...
122 + * @return {String|Array}
123 + * @public
124 + */
125 +
126 +Accepts.prototype.encoding =
127 +Accepts.prototype.encodings = function (encodings_) {
128 + var encodings = encodings_
129 +
130 + // support flattened arguments
131 + if (encodings && !Array.isArray(encodings)) {
132 + encodings = new Array(arguments.length)
133 + for (var i = 0; i < encodings.length; i++) {
134 + encodings[i] = arguments[i]
135 + }
136 + }
137 +
138 + // no encodings, return all requested encodings
139 + if (!encodings || encodings.length === 0) {
140 + return this.negotiator.encodings()
141 + }
142 +
143 + return this.negotiator.encodings(encodings)[0] || false
144 +}
145 +
146 +/**
147 + * Return accepted charsets or best fit based on `charsets`.
148 + *
149 + * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
150 + * an array sorted by quality is returned:
151 + *
152 + * ['utf-8', 'utf-7', 'iso-8859-1']
153 + *
154 + * @param {String|Array} charsets...
155 + * @return {String|Array}
156 + * @public
157 + */
158 +
159 +Accepts.prototype.charset =
160 +Accepts.prototype.charsets = function (charsets_) {
161 + var charsets = charsets_
162 +
163 + // support flattened arguments
164 + if (charsets && !Array.isArray(charsets)) {
165 + charsets = new Array(arguments.length)
166 + for (var i = 0; i < charsets.length; i++) {
167 + charsets[i] = arguments[i]
168 + }
169 + }
170 +
171 + // no charsets, return all requested charsets
172 + if (!charsets || charsets.length === 0) {
173 + return this.negotiator.charsets()
174 + }
175 +
176 + return this.negotiator.charsets(charsets)[0] || false
177 +}
178 +
179 +/**
180 + * Return accepted languages or best fit based on `langs`.
181 + *
182 + * Given `Accept-Language: en;q=0.8, es, pt`
183 + * an array sorted by quality is returned:
184 + *
185 + * ['es', 'pt', 'en']
186 + *
187 + * @param {String|Array} langs...
188 + * @return {Array|String}
189 + * @public
190 + */
191 +
192 +Accepts.prototype.lang =
193 +Accepts.prototype.langs =
194 +Accepts.prototype.language =
195 +Accepts.prototype.languages = function (languages_) {
196 + var languages = languages_
197 +
198 + // support flattened arguments
199 + if (languages && !Array.isArray(languages)) {
200 + languages = new Array(arguments.length)
201 + for (var i = 0; i < languages.length; i++) {
202 + languages[i] = arguments[i]
203 + }
204 + }
205 +
206 + // no languages, return all requested languages
207 + if (!languages || languages.length === 0) {
208 + return this.negotiator.languages()
209 + }
210 +
211 + return this.negotiator.languages(languages)[0] || false
212 +}
213 +
214 +/**
215 + * Convert extnames to mime.
216 + *
217 + * @param {String} type
218 + * @return {String}
219 + * @private
220 + */
221 +
222 +function extToMime (type) {
223 + return type.indexOf('/') === -1
224 + ? mime.lookup(type)
225 + : type
226 +}
227 +
228 +/**
229 + * Check if mime is valid.
230 + *
231 + * @param {String} type
232 + * @return {String}
233 + * @private
234 + */
235 +
236 +function validMime (type) {
237 + return typeof type === 'string'
238 +}
1 +{
2 + "_from": "accepts@~1.3.5",
3 + "_id": "accepts@1.3.5",
4 + "_inBundle": false,
5 + "_integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
6 + "_location": "/accepts",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "accepts@~1.3.5",
12 + "name": "accepts",
13 + "escapedName": "accepts",
14 + "rawSpec": "~1.3.5",
15 + "saveSpec": null,
16 + "fetchSpec": "~1.3.5"
17 + },
18 + "_requiredBy": [
19 + "/express"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
22 + "_shasum": "eb777df6011723a3b14e8a72c0805c8e86746bd2",
23 + "_spec": "accepts@~1.3.5",
24 + "_where": "C:\\Users\\KSI\\Desktop\\3-2\\OSS\\LineBot\\node_modules\\express",
25 + "bugs": {
26 + "url": "https://github.com/jshttp/accepts/issues"
27 + },
28 + "bundleDependencies": false,
29 + "contributors": [
30 + {
31 + "name": "Douglas Christopher Wilson",
32 + "email": "doug@somethingdoug.com"
33 + },
34 + {
35 + "name": "Jonathan Ong",
36 + "email": "me@jongleberry.com",
37 + "url": "http://jongleberry.com"
38 + }
39 + ],
40 + "dependencies": {
41 + "mime-types": "~2.1.18",
42 + "negotiator": "0.6.1"
43 + },
44 + "deprecated": false,
45 + "description": "Higher-level content negotiation",
46 + "devDependencies": {
47 + "eslint": "4.18.1",
48 + "eslint-config-standard": "11.0.0",
49 + "eslint-plugin-import": "2.9.0",
50 + "eslint-plugin-markdown": "1.0.0-beta.6",
51 + "eslint-plugin-node": "6.0.1",
52 + "eslint-plugin-promise": "3.6.0",
53 + "eslint-plugin-standard": "3.0.1",
54 + "istanbul": "0.4.5",
55 + "mocha": "~1.21.5"
56 + },
57 + "engines": {
58 + "node": ">= 0.6"
59 + },
60 + "files": [
61 + "LICENSE",
62 + "HISTORY.md",
63 + "index.js"
64 + ],
65 + "homepage": "https://github.com/jshttp/accepts#readme",
66 + "keywords": [
67 + "content",
68 + "negotiation",
69 + "accept",
70 + "accepts"
71 + ],
72 + "license": "MIT",
73 + "name": "accepts",
74 + "repository": {
75 + "type": "git",
76 + "url": "git+https://github.com/jshttp/accepts.git"
77 + },
78 + "scripts": {
79 + "lint": "eslint --plugin markdown --ext js,md .",
80 + "test": "mocha --reporter spec --check-leaks --bail test/",
81 + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
82 + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
83 + },
84 + "version": "1.3.5"
85 +}
1 +var Ajv = require('ajv');
2 +var ajv = new Ajv({allErrors: true});
3 +
4 +var schema = {
5 + "properties": {
6 + "foo": { "type": "string" },
7 + "bar": { "type": "number", "maximum": 3 }
8 + }
9 +};
10 +
11 +var validate = ajv.compile(schema);
12 +
13 +test({"foo": "abc", "bar": 2});
14 +test({"foo": 2, "bar": 4});
15 +
16 +function test(data) {
17 + var valid = validate(data);
18 + if (valid) console.log('Valid!');
19 + else console.log('Invalid: ' + ajv.errorsText(validate.errors));
20 +}
...\ No newline at end of file ...\ No newline at end of file
1 +The MIT License (MIT)
2 +
3 +Copyright (c) 2015-2017 Evgeny Poberezkin
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 +
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +'use strict';
2 +
3 +
4 +var Cache = module.exports = function Cache() {
5 + this._cache = {};
6 +};
7 +
8 +
9 +Cache.prototype.put = function Cache_put(key, value) {
10 + this._cache[key] = value;
11 +};
12 +
13 +
14 +Cache.prototype.get = function Cache_get(key) {
15 + return this._cache[key];
16 +};
17 +
18 +
19 +Cache.prototype.del = function Cache_del(key) {
20 + delete this._cache[key];
21 +};
22 +
23 +
24 +Cache.prototype.clear = function Cache_clear() {
25 + this._cache = {};
26 +};
1 +'use strict';
2 +
3 +var MissingRefError = require('./error_classes').MissingRef;
4 +
5 +module.exports = compileAsync;
6 +
7 +
8 +/**
9 + * Creates validating function for passed schema with asynchronous loading of missing schemas.
10 + * `loadSchema` option should be a function that accepts schema uri and returns promise that resolves with the schema.
11 + * @this Ajv
12 + * @param {Object} schema schema object
13 + * @param {Boolean} meta optional true to compile meta-schema; this parameter can be skipped
14 + * @param {Function} callback an optional node-style callback, it is called with 2 parameters: error (or null) and validating function.
15 + * @return {Promise} promise that resolves with a validating function.
16 + */
17 +function compileAsync(schema, meta, callback) {
18 + /* eslint no-shadow: 0 */
19 + /* global Promise */
20 + /* jshint validthis: true */
21 + var self = this;
22 + if (typeof this._opts.loadSchema != 'function')
23 + throw new Error('options.loadSchema should be a function');
24 +
25 + if (typeof meta == 'function') {
26 + callback = meta;
27 + meta = undefined;
28 + }
29 +
30 + var p = loadMetaSchemaOf(schema).then(function () {
31 + var schemaObj = self._addSchema(schema, undefined, meta);
32 + return schemaObj.validate || _compileAsync(schemaObj);
33 + });
34 +
35 + if (callback) {
36 + p.then(
37 + function(v) { callback(null, v); },
38 + callback
39 + );
40 + }
41 +
42 + return p;
43 +
44 +
45 + function loadMetaSchemaOf(sch) {
46 + var $schema = sch.$schema;
47 + return $schema && !self.getSchema($schema)
48 + ? compileAsync.call(self, { $ref: $schema }, true)
49 + : Promise.resolve();
50 + }
51 +
52 +
53 + function _compileAsync(schemaObj) {
54 + try { return self._compile(schemaObj); }
55 + catch(e) {
56 + if (e instanceof MissingRefError) return loadMissingSchema(e);
57 + throw e;
58 + }
59 +
60 +
61 + function loadMissingSchema(e) {
62 + var ref = e.missingSchema;
63 + if (added(ref)) throw new Error('Schema ' + ref + ' is loaded but ' + e.missingRef + ' cannot be resolved');
64 +
65 + var schemaPromise = self._loadingSchemas[ref];
66 + if (!schemaPromise) {
67 + schemaPromise = self._loadingSchemas[ref] = self._opts.loadSchema(ref);
68 + schemaPromise.then(removePromise, removePromise);
69 + }
70 +
71 + return schemaPromise.then(function (sch) {
72 + if (!added(ref)) {
73 + return loadMetaSchemaOf(sch).then(function () {
74 + if (!added(ref)) self.addSchema(sch, ref, undefined, meta);
75 + });
76 + }
77 + }).then(function() {
78 + return _compileAsync(schemaObj);
79 + });
80 +
81 + function removePromise() {
82 + delete self._loadingSchemas[ref];
83 + }
84 +
85 + function added(ref) {
86 + return self._refs[ref] || self._schemas[ref];
87 + }
88 + }
89 + }
90 +}
1 +'use strict';
2 +
3 +// do NOT remove this file - it would break pre-compiled schemas
4 +// https://github.com/epoberezkin/ajv/issues/889
5 +module.exports = require('fast-deep-equal');
1 +'use strict';
2 +
3 +var resolve = require('./resolve');
4 +
5 +module.exports = {
6 + Validation: errorSubclass(ValidationError),
7 + MissingRef: errorSubclass(MissingRefError)
8 +};
9 +
10 +
11 +function ValidationError(errors) {
12 + this.message = 'validation failed';
13 + this.errors = errors;
14 + this.ajv = this.validation = true;
15 +}
16 +
17 +
18 +MissingRefError.message = function (baseId, ref) {
19 + return 'can\'t resolve reference ' + ref + ' from id ' + baseId;
20 +};
21 +
22 +
23 +function MissingRefError(baseId, ref, message) {
24 + this.message = message || MissingRefError.message(baseId, ref);
25 + this.missingRef = resolve.url(baseId, ref);
26 + this.missingSchema = resolve.normalizeId(resolve.fullPath(this.missingRef));
27 +}
28 +
29 +
30 +function errorSubclass(Subclass) {
31 + Subclass.prototype = Object.create(Error.prototype);
32 + Subclass.prototype.constructor = Subclass;
33 + return Subclass;
34 +}
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +'use strict';
2 +
3 +var URI = require('uri-js')
4 + , equal = require('fast-deep-equal')
5 + , util = require('./util')
6 + , SchemaObject = require('./schema_obj')
7 + , traverse = require('json-schema-traverse');
8 +
9 +module.exports = resolve;
10 +
11 +resolve.normalizeId = normalizeId;
12 +resolve.fullPath = getFullPath;
13 +resolve.url = resolveUrl;
14 +resolve.ids = resolveIds;
15 +resolve.inlineRef = inlineRef;
16 +resolve.schema = resolveSchema;
17 +
18 +/**
19 + * [resolve and compile the references ($ref)]
20 + * @this Ajv
21 + * @param {Function} compile reference to schema compilation funciton (localCompile)
22 + * @param {Object} root object with information about the root schema for the current schema
23 + * @param {String} ref reference to resolve
24 + * @return {Object|Function} schema object (if the schema can be inlined) or validation function
25 + */
26 +function resolve(compile, root, ref) {
27 + /* jshint validthis: true */
28 + var refVal = this._refs[ref];
29 + if (typeof refVal == 'string') {
30 + if (this._refs[refVal]) refVal = this._refs[refVal];
31 + else return resolve.call(this, compile, root, refVal);
32 + }
33 +
34 + refVal = refVal || this._schemas[ref];
35 + if (refVal instanceof SchemaObject) {
36 + return inlineRef(refVal.schema, this._opts.inlineRefs)
37 + ? refVal.schema
38 + : refVal.validate || this._compile(refVal);
39 + }
40 +
41 + var res = resolveSchema.call(this, root, ref);
42 + var schema, v, baseId;
43 + if (res) {
44 + schema = res.schema;
45 + root = res.root;
46 + baseId = res.baseId;
47 + }
48 +
49 + if (schema instanceof SchemaObject) {
50 + v = schema.validate || compile.call(this, schema.schema, root, undefined, baseId);
51 + } else if (schema !== undefined) {
52 + v = inlineRef(schema, this._opts.inlineRefs)
53 + ? schema
54 + : compile.call(this, schema, root, undefined, baseId);
55 + }
56 +
57 + return v;
58 +}
59 +
60 +
61 +/**
62 + * Resolve schema, its root and baseId
63 + * @this Ajv
64 + * @param {Object} root root object with properties schema, refVal, refs
65 + * @param {String} ref reference to resolve
66 + * @return {Object} object with properties schema, root, baseId
67 + */
68 +function resolveSchema(root, ref) {
69 + /* jshint validthis: true */
70 + var p = URI.parse(ref)
71 + , refPath = _getFullPath(p)
72 + , baseId = getFullPath(this._getId(root.schema));
73 + if (Object.keys(root.schema).length === 0 || refPath !== baseId) {
74 + var id = normalizeId(refPath);
75 + var refVal = this._refs[id];
76 + if (typeof refVal == 'string') {
77 + return resolveRecursive.call(this, root, refVal, p);
78 + } else if (refVal instanceof SchemaObject) {
79 + if (!refVal.validate) this._compile(refVal);
80 + root = refVal;
81 + } else {
82 + refVal = this._schemas[id];
83 + if (refVal instanceof SchemaObject) {
84 + if (!refVal.validate) this._compile(refVal);
85 + if (id == normalizeId(ref))
86 + return { schema: refVal, root: root, baseId: baseId };
87 + root = refVal;
88 + } else {
89 + return;
90 + }
91 + }
92 + if (!root.schema) return;
93 + baseId = getFullPath(this._getId(root.schema));
94 + }
95 + return getJsonPointer.call(this, p, baseId, root.schema, root);
96 +}
97 +
98 +
99 +/* @this Ajv */
100 +function resolveRecursive(root, ref, parsedRef) {
101 + /* jshint validthis: true */
102 + var res = resolveSchema.call(this, root, ref);
103 + if (res) {
104 + var schema = res.schema;
105 + var baseId = res.baseId;
106 + root = res.root;
107 + var id = this._getId(schema);
108 + if (id) baseId = resolveUrl(baseId, id);
109 + return getJsonPointer.call(this, parsedRef, baseId, schema, root);
110 + }
111 +}
112 +
113 +
114 +var PREVENT_SCOPE_CHANGE = util.toHash(['properties', 'patternProperties', 'enum', 'dependencies', 'definitions']);
115 +/* @this Ajv */
116 +function getJsonPointer(parsedRef, baseId, schema, root) {
117 + /* jshint validthis: true */
118 + parsedRef.fragment = parsedRef.fragment || '';
119 + if (parsedRef.fragment.slice(0,1) != '/') return;
120 + var parts = parsedRef.fragment.split('/');
121 +
122 + for (var i = 1; i < parts.length; i++) {
123 + var part = parts[i];
124 + if (part) {
125 + part = util.unescapeFragment(part);
126 + schema = schema[part];
127 + if (schema === undefined) break;
128 + var id;
129 + if (!PREVENT_SCOPE_CHANGE[part]) {
130 + id = this._getId(schema);
131 + if (id) baseId = resolveUrl(baseId, id);
132 + if (schema.$ref) {
133 + var $ref = resolveUrl(baseId, schema.$ref);
134 + var res = resolveSchema.call(this, root, $ref);
135 + if (res) {
136 + schema = res.schema;
137 + root = res.root;
138 + baseId = res.baseId;
139 + }
140 + }
141 + }
142 + }
143 + }
144 + if (schema !== undefined && schema !== root.schema)
145 + return { schema: schema, root: root, baseId: baseId };
146 +}
147 +
148 +
149 +var SIMPLE_INLINED = util.toHash([
150 + 'type', 'format', 'pattern',
151 + 'maxLength', 'minLength',
152 + 'maxProperties', 'minProperties',
153 + 'maxItems', 'minItems',
154 + 'maximum', 'minimum',
155 + 'uniqueItems', 'multipleOf',
156 + 'required', 'enum'
157 +]);
158 +function inlineRef(schema, limit) {
159 + if (limit === false) return false;
160 + if (limit === undefined || limit === true) return checkNoRef(schema);
161 + else if (limit) return countKeys(schema) <= limit;
162 +}
163 +
164 +
165 +function checkNoRef(schema) {
166 + var item;
167 + if (Array.isArray(schema)) {
168 + for (var i=0; i<schema.length; i++) {
169 + item = schema[i];
170 + if (typeof item == 'object' && !checkNoRef(item)) return false;
171 + }
172 + } else {
173 + for (var key in schema) {
174 + if (key == '$ref') return false;
175 + item = schema[key];
176 + if (typeof item == 'object' && !checkNoRef(item)) return false;
177 + }
178 + }
179 + return true;
180 +}
181 +
182 +
183 +function countKeys(schema) {
184 + var count = 0, item;
185 + if (Array.isArray(schema)) {
186 + for (var i=0; i<schema.length; i++) {
187 + item = schema[i];
188 + if (typeof item == 'object') count += countKeys(item);
189 + if (count == Infinity) return Infinity;
190 + }
191 + } else {
192 + for (var key in schema) {
193 + if (key == '$ref') return Infinity;
194 + if (SIMPLE_INLINED[key]) {
195 + count++;
196 + } else {
197 + item = schema[key];
198 + if (typeof item == 'object') count += countKeys(item) + 1;
199 + if (count == Infinity) return Infinity;
200 + }
201 + }
202 + }
203 + return count;
204 +}
205 +
206 +
207 +function getFullPath(id, normalize) {
208 + if (normalize !== false) id = normalizeId(id);
209 + var p = URI.parse(id);
210 + return _getFullPath(p);
211 +}
212 +
213 +
214 +function _getFullPath(p) {
215 + return URI.serialize(p).split('#')[0] + '#';
216 +}
217 +
218 +
219 +var TRAILING_SLASH_HASH = /#\/?$/;
220 +function normalizeId(id) {
221 + return id ? id.replace(TRAILING_SLASH_HASH, '') : '';
222 +}
223 +
224 +
225 +function resolveUrl(baseId, id) {
226 + id = normalizeId(id);
227 + return URI.resolve(baseId, id);
228 +}
229 +
230 +
231 +/* @this Ajv */
232 +function resolveIds(schema) {
233 + var schemaId = normalizeId(this._getId(schema));
234 + var baseIds = {'': schemaId};
235 + var fullPaths = {'': getFullPath(schemaId, false)};
236 + var localRefs = {};
237 + var self = this;
238 +
239 + traverse(schema, {allKeys: true}, function(sch, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex) {
240 + if (jsonPtr === '') return;
241 + var id = self._getId(sch);
242 + var baseId = baseIds[parentJsonPtr];
243 + var fullPath = fullPaths[parentJsonPtr] + '/' + parentKeyword;
244 + if (keyIndex !== undefined)
245 + fullPath += '/' + (typeof keyIndex == 'number' ? keyIndex : util.escapeFragment(keyIndex));
246 +
247 + if (typeof id == 'string') {
248 + id = baseId = normalizeId(baseId ? URI.resolve(baseId, id) : id);
249 +
250 + var refVal = self._refs[id];
251 + if (typeof refVal == 'string') refVal = self._refs[refVal];
252 + if (refVal && refVal.schema) {
253 + if (!equal(sch, refVal.schema))
254 + throw new Error('id "' + id + '" resolves to more than one schema');
255 + } else if (id != normalizeId(fullPath)) {
256 + if (id[0] == '#') {
257 + if (localRefs[id] && !equal(sch, localRefs[id]))
258 + throw new Error('id "' + id + '" resolves to more than one schema');
259 + localRefs[id] = sch;
260 + } else {
261 + self._refs[id] = fullPath;
262 + }
263 + }
264 + }
265 + baseIds[jsonPtr] = baseId;
266 + fullPaths[jsonPtr] = fullPath;
267 + });
268 +
269 + return localRefs;
270 +}
1 +'use strict';
2 +
3 +var ruleModules = require('../dotjs')
4 + , toHash = require('./util').toHash;
5 +
6 +module.exports = function rules() {
7 + var RULES = [
8 + { type: 'number',
9 + rules: [ { 'maximum': ['exclusiveMaximum'] },
10 + { 'minimum': ['exclusiveMinimum'] }, 'multipleOf', 'format'] },
11 + { type: 'string',
12 + rules: [ 'maxLength', 'minLength', 'pattern', 'format' ] },
13 + { type: 'array',
14 + rules: [ 'maxItems', 'minItems', 'items', 'contains', 'uniqueItems' ] },
15 + { type: 'object',
16 + rules: [ 'maxProperties', 'minProperties', 'required', 'dependencies', 'propertyNames',
17 + { 'properties': ['additionalProperties', 'patternProperties'] } ] },
18 + { rules: [ '$ref', 'const', 'enum', 'not', 'anyOf', 'oneOf', 'allOf', 'if' ] }
19 + ];
20 +
21 + var ALL = [ 'type', '$comment' ];
22 + var KEYWORDS = [
23 + '$schema', '$id', 'id', '$data', '$async', 'title',
24 + 'description', 'default', 'definitions',
25 + 'examples', 'readOnly', 'writeOnly',
26 + 'contentMediaType', 'contentEncoding',
27 + 'additionalItems', 'then', 'else'
28 + ];
29 + var TYPES = [ 'number', 'integer', 'string', 'array', 'object', 'boolean', 'null' ];
30 + RULES.all = toHash(ALL);
31 + RULES.types = toHash(TYPES);
32 +
33 + RULES.forEach(function (group) {
34 + group.rules = group.rules.map(function (keyword) {
35 + var implKeywords;
36 + if (typeof keyword == 'object') {
37 + var key = Object.keys(keyword)[0];
38 + implKeywords = keyword[key];
39 + keyword = key;
40 + implKeywords.forEach(function (k) {
41 + ALL.push(k);
42 + RULES.all[k] = true;
43 + });
44 + }
45 + ALL.push(keyword);
46 + var rule = RULES.all[keyword] = {
47 + keyword: keyword,
48 + code: ruleModules[keyword],
49 + implements: implKeywords
50 + };
51 + return rule;
52 + });
53 +
54 + RULES.all.$comment = {
55 + keyword: '$comment',
56 + code: ruleModules.$comment
57 + };
58 +
59 + if (group.type) RULES.types[group.type] = group;
60 + });
61 +
62 + RULES.keywords = toHash(ALL.concat(KEYWORDS));
63 + RULES.custom = {};
64 +
65 + return RULES;
66 +};
1 +'use strict';
2 +
3 +var util = require('./util');
4 +
5 +module.exports = SchemaObject;
6 +
7 +function SchemaObject(obj) {
8 + util.copy(obj, this);
9 +}
1 +'use strict';
2 +
3 +// https://mathiasbynens.be/notes/javascript-encoding
4 +// https://github.com/bestiejs/punycode.js - punycode.ucs2.decode
5 +module.exports = function ucs2length(str) {
6 + var length = 0
7 + , len = str.length
8 + , pos = 0
9 + , value;
10 + while (pos < len) {
11 + length++;
12 + value = str.charCodeAt(pos++);
13 + if (value >= 0xD800 && value <= 0xDBFF && pos < len) {
14 + // high surrogate, and there is a next character
15 + value = str.charCodeAt(pos);
16 + if ((value & 0xFC00) == 0xDC00) pos++; // low surrogate
17 + }
18 + }
19 + return length;
20 +};
1 +'use strict';
2 +
3 +
4 +module.exports = {
5 + copy: copy,
6 + checkDataType: checkDataType,
7 + checkDataTypes: checkDataTypes,
8 + coerceToTypes: coerceToTypes,
9 + toHash: toHash,
10 + getProperty: getProperty,
11 + escapeQuotes: escapeQuotes,
12 + equal: require('fast-deep-equal'),
13 + ucs2length: require('./ucs2length'),
14 + varOccurences: varOccurences,
15 + varReplace: varReplace,
16 + cleanUpCode: cleanUpCode,
17 + finalCleanUpCode: finalCleanUpCode,
18 + schemaHasRules: schemaHasRules,
19 + schemaHasRulesExcept: schemaHasRulesExcept,
20 + schemaUnknownRules: schemaUnknownRules,
21 + toQuotedString: toQuotedString,
22 + getPathExpr: getPathExpr,
23 + getPath: getPath,
24 + getData: getData,
25 + unescapeFragment: unescapeFragment,
26 + unescapeJsonPointer: unescapeJsonPointer,
27 + escapeFragment: escapeFragment,
28 + escapeJsonPointer: escapeJsonPointer
29 +};
30 +
31 +
32 +function copy(o, to) {
33 + to = to || {};
34 + for (var key in o) to[key] = o[key];
35 + return to;
36 +}
37 +
38 +
39 +function checkDataType(dataType, data, negate) {
40 + var EQUAL = negate ? ' !== ' : ' === '
41 + , AND = negate ? ' || ' : ' && '
42 + , OK = negate ? '!' : ''
43 + , NOT = negate ? '' : '!';
44 + switch (dataType) {
45 + case 'null': return data + EQUAL + 'null';
46 + case 'array': return OK + 'Array.isArray(' + data + ')';
47 + case 'object': return '(' + OK + data + AND +
48 + 'typeof ' + data + EQUAL + '"object"' + AND +
49 + NOT + 'Array.isArray(' + data + '))';
50 + case 'integer': return '(typeof ' + data + EQUAL + '"number"' + AND +
51 + NOT + '(' + data + ' % 1)' +
52 + AND + data + EQUAL + data + ')';
53 + default: return 'typeof ' + data + EQUAL + '"' + dataType + '"';
54 + }
55 +}
56 +
57 +
58 +function checkDataTypes(dataTypes, data) {
59 + switch (dataTypes.length) {
60 + case 1: return checkDataType(dataTypes[0], data, true);
61 + default:
62 + var code = '';
63 + var types = toHash(dataTypes);
64 + if (types.array && types.object) {
65 + code = types.null ? '(': '(!' + data + ' || ';
66 + code += 'typeof ' + data + ' !== "object")';
67 + delete types.null;
68 + delete types.array;
69 + delete types.object;
70 + }
71 + if (types.number) delete types.integer;
72 + for (var t in types)
73 + code += (code ? ' && ' : '' ) + checkDataType(t, data, true);
74 +
75 + return code;
76 + }
77 +}
78 +
79 +
80 +var COERCE_TO_TYPES = toHash([ 'string', 'number', 'integer', 'boolean', 'null' ]);
81 +function coerceToTypes(optionCoerceTypes, dataTypes) {
82 + if (Array.isArray(dataTypes)) {
83 + var types = [];
84 + for (var i=0; i<dataTypes.length; i++) {
85 + var t = dataTypes[i];
86 + if (COERCE_TO_TYPES[t]) types[types.length] = t;
87 + else if (optionCoerceTypes === 'array' && t === 'array') types[types.length] = t;
88 + }
89 + if (types.length) return types;
90 + } else if (COERCE_TO_TYPES[dataTypes]) {
91 + return [dataTypes];
92 + } else if (optionCoerceTypes === 'array' && dataTypes === 'array') {
93 + return ['array'];
94 + }
95 +}
96 +
97 +
98 +function toHash(arr) {
99 + var hash = {};
100 + for (var i=0; i<arr.length; i++) hash[arr[i]] = true;
101 + return hash;
102 +}
103 +
104 +
105 +var IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i;
106 +var SINGLE_QUOTE = /'|\\/g;
107 +function getProperty(key) {
108 + return typeof key == 'number'
109 + ? '[' + key + ']'
110 + : IDENTIFIER.test(key)
111 + ? '.' + key
112 + : "['" + escapeQuotes(key) + "']";
113 +}
114 +
115 +
116 +function escapeQuotes(str) {
117 + return str.replace(SINGLE_QUOTE, '\\$&')
118 + .replace(/\n/g, '\\n')
119 + .replace(/\r/g, '\\r')
120 + .replace(/\f/g, '\\f')
121 + .replace(/\t/g, '\\t');
122 +}
123 +
124 +
125 +function varOccurences(str, dataVar) {
126 + dataVar += '[^0-9]';
127 + var matches = str.match(new RegExp(dataVar, 'g'));
128 + return matches ? matches.length : 0;
129 +}
130 +
131 +
132 +function varReplace(str, dataVar, expr) {
133 + dataVar += '([^0-9])';
134 + expr = expr.replace(/\$/g, '$$$$');
135 + return str.replace(new RegExp(dataVar, 'g'), expr + '$1');
136 +}
137 +
138 +
139 +var EMPTY_ELSE = /else\s*{\s*}/g
140 + , EMPTY_IF_NO_ELSE = /if\s*\([^)]+\)\s*\{\s*\}(?!\s*else)/g
141 + , EMPTY_IF_WITH_ELSE = /if\s*\(([^)]+)\)\s*\{\s*\}\s*else(?!\s*if)/g;
142 +function cleanUpCode(out) {
143 + return out.replace(EMPTY_ELSE, '')
144 + .replace(EMPTY_IF_NO_ELSE, '')
145 + .replace(EMPTY_IF_WITH_ELSE, 'if (!($1))');
146 +}
147 +
148 +
149 +var ERRORS_REGEXP = /[^v.]errors/g
150 + , REMOVE_ERRORS = /var errors = 0;|var vErrors = null;|validate.errors = vErrors;/g
151 + , REMOVE_ERRORS_ASYNC = /var errors = 0;|var vErrors = null;/g
152 + , RETURN_VALID = 'return errors === 0;'
153 + , RETURN_TRUE = 'validate.errors = null; return true;'
154 + , RETURN_ASYNC = /if \(errors === 0\) return data;\s*else throw new ValidationError\(vErrors\);/
155 + , RETURN_DATA_ASYNC = 'return data;'
156 + , ROOTDATA_REGEXP = /[^A-Za-z_$]rootData[^A-Za-z0-9_$]/g
157 + , REMOVE_ROOTDATA = /if \(rootData === undefined\) rootData = data;/;
158 +
159 +function finalCleanUpCode(out, async) {
160 + var matches = out.match(ERRORS_REGEXP);
161 + if (matches && matches.length == 2) {
162 + out = async
163 + ? out.replace(REMOVE_ERRORS_ASYNC, '')
164 + .replace(RETURN_ASYNC, RETURN_DATA_ASYNC)
165 + : out.replace(REMOVE_ERRORS, '')
166 + .replace(RETURN_VALID, RETURN_TRUE);
167 + }
168 +
169 + matches = out.match(ROOTDATA_REGEXP);
170 + if (!matches || matches.length !== 3) return out;
171 + return out.replace(REMOVE_ROOTDATA, '');
172 +}
173 +
174 +
175 +function schemaHasRules(schema, rules) {
176 + if (typeof schema == 'boolean') return !schema;
177 + for (var key in schema) if (rules[key]) return true;
178 +}
179 +
180 +
181 +function schemaHasRulesExcept(schema, rules, exceptKeyword) {
182 + if (typeof schema == 'boolean') return !schema && exceptKeyword != 'not';
183 + for (var key in schema) if (key != exceptKeyword && rules[key]) return true;
184 +}
185 +
186 +
187 +function schemaUnknownRules(schema, rules) {
188 + if (typeof schema == 'boolean') return;
189 + for (var key in schema) if (!rules[key]) return key;
190 +}
191 +
192 +
193 +function toQuotedString(str) {
194 + return '\'' + escapeQuotes(str) + '\'';
195 +}
196 +
197 +
198 +function getPathExpr(currentPath, expr, jsonPointers, isNumber) {
199 + var path = jsonPointers // false by default
200 + ? '\'/\' + ' + expr + (isNumber ? '' : '.replace(/~/g, \'~0\').replace(/\\//g, \'~1\')')
201 + : (isNumber ? '\'[\' + ' + expr + ' + \']\'' : '\'[\\\'\' + ' + expr + ' + \'\\\']\'');
202 + return joinPaths(currentPath, path);
203 +}
204 +
205 +
206 +function getPath(currentPath, prop, jsonPointers) {
207 + var path = jsonPointers // false by default
208 + ? toQuotedString('/' + escapeJsonPointer(prop))
209 + : toQuotedString(getProperty(prop));
210 + return joinPaths(currentPath, path);
211 +}
212 +
213 +
214 +var JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/;
215 +var RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/;
216 +function getData($data, lvl, paths) {
217 + var up, jsonPointer, data, matches;
218 + if ($data === '') return 'rootData';
219 + if ($data[0] == '/') {
220 + if (!JSON_POINTER.test($data)) throw new Error('Invalid JSON-pointer: ' + $data);
221 + jsonPointer = $data;
222 + data = 'rootData';
223 + } else {
224 + matches = $data.match(RELATIVE_JSON_POINTER);
225 + if (!matches) throw new Error('Invalid JSON-pointer: ' + $data);
226 + up = +matches[1];
227 + jsonPointer = matches[2];
228 + if (jsonPointer == '#') {
229 + if (up >= lvl) throw new Error('Cannot access property/index ' + up + ' levels up, current level is ' + lvl);
230 + return paths[lvl - up];
231 + }
232 +
233 + if (up > lvl) throw new Error('Cannot access data ' + up + ' levels up, current level is ' + lvl);
234 + data = 'data' + ((lvl - up) || '');
235 + if (!jsonPointer) return data;
236 + }
237 +
238 + var expr = data;
239 + var segments = jsonPointer.split('/');
240 + for (var i=0; i<segments.length; i++) {
241 + var segment = segments[i];
242 + if (segment) {
243 + data += getProperty(unescapeJsonPointer(segment));
244 + expr += ' && ' + data;
245 + }
246 + }
247 + return expr;
248 +}
249 +
250 +
251 +function joinPaths (a, b) {
252 + if (a == '""') return b;
253 + return (a + ' + ' + b).replace(/' \+ '/g, '');
254 +}
255 +
256 +
257 +function unescapeFragment(str) {
258 + return unescapeJsonPointer(decodeURIComponent(str));
259 +}
260 +
261 +
262 +function escapeFragment(str) {
263 + return encodeURIComponent(escapeJsonPointer(str));
264 +}
265 +
266 +
267 +function escapeJsonPointer(str) {
268 + return str.replace(/~/g, '~0').replace(/\//g, '~1');
269 +}
270 +
271 +
272 +function unescapeJsonPointer(str) {
273 + return str.replace(/~1/g, '/').replace(/~0/g, '~');
274 +}
1 +'use strict';
2 +
3 +var KEYWORDS = [
4 + 'multipleOf',
5 + 'maximum',
6 + 'exclusiveMaximum',
7 + 'minimum',
8 + 'exclusiveMinimum',
9 + 'maxLength',
10 + 'minLength',
11 + 'pattern',
12 + 'additionalItems',
13 + 'maxItems',
14 + 'minItems',
15 + 'uniqueItems',
16 + 'maxProperties',
17 + 'minProperties',
18 + 'required',
19 + 'additionalProperties',
20 + 'enum',
21 + 'format',
22 + 'const'
23 +];
24 +
25 +module.exports = function (metaSchema, keywordsJsonPointers) {
26 + for (var i=0; i<keywordsJsonPointers.length; i++) {
27 + metaSchema = JSON.parse(JSON.stringify(metaSchema));
28 + var segments = keywordsJsonPointers[i].split('/');
29 + var keywords = metaSchema;
30 + var j;
31 + for (j=1; j<segments.length; j++)
32 + keywords = keywords[segments[j]];
33 +
34 + for (j=0; j<KEYWORDS.length; j++) {
35 + var key = KEYWORDS[j];
36 + var schema = keywords[key];
37 + if (schema) {
38 + keywords[key] = {
39 + anyOf: [
40 + schema,
41 + { $ref: 'https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/data.json#' }
42 + ]
43 + };
44 + }
45 + }
46 + }
47 +
48 + return metaSchema;
49 +};
1 +'use strict';
2 +
3 +var metaSchema = require('./refs/json-schema-draft-07.json');
4 +
5 +module.exports = {
6 + $id: 'https://github.com/epoberezkin/ajv/blob/master/lib/definition_schema.js',
7 + definitions: {
8 + simpleTypes: metaSchema.definitions.simpleTypes
9 + },
10 + type: 'object',
11 + dependencies: {
12 + schema: ['validate'],
13 + $data: ['validate'],
14 + statements: ['inline'],
15 + valid: {not: {required: ['macro']}}
16 + },
17 + properties: {
18 + type: metaSchema.properties.type,
19 + schema: {type: 'boolean'},
20 + statements: {type: 'boolean'},
21 + dependencies: {
22 + type: 'array',
23 + items: {type: 'string'}
24 + },
25 + metaSchema: {type: 'object'},
26 + modifying: {type: 'boolean'},
27 + valid: {type: 'boolean'},
28 + $data: {type: 'boolean'},
29 + async: {type: 'boolean'},
30 + errors: {
31 + anyOf: [
32 + {type: 'boolean'},
33 + {const: 'full'}
34 + ]
35 + }
36 + }
37 +};
1 +{{# def.definitions }}
2 +{{# def.errors }}
3 +{{# def.setupKeyword }}
4 +{{# def.$data }}
5 +
6 +{{## def.setExclusiveLimit:
7 + $exclusive = true;
8 + $errorKeyword = $exclusiveKeyword;
9 + $errSchemaPath = it.errSchemaPath + '/' + $exclusiveKeyword;
10 +#}}
11 +
12 +{{
13 + var $isMax = $keyword == 'maximum'
14 + , $exclusiveKeyword = $isMax ? 'exclusiveMaximum' : 'exclusiveMinimum'
15 + , $schemaExcl = it.schema[$exclusiveKeyword]
16 + , $isDataExcl = it.opts.$data && $schemaExcl && $schemaExcl.$data
17 + , $op = $isMax ? '<' : '>'
18 + , $notOp = $isMax ? '>' : '<'
19 + , $errorKeyword = undefined;
20 +}}
21 +
22 +{{? $isDataExcl }}
23 + {{
24 + var $schemaValueExcl = it.util.getData($schemaExcl.$data, $dataLvl, it.dataPathArr)
25 + , $exclusive = 'exclusive' + $lvl
26 + , $exclType = 'exclType' + $lvl
27 + , $exclIsNumber = 'exclIsNumber' + $lvl
28 + , $opExpr = 'op' + $lvl
29 + , $opStr = '\' + ' + $opExpr + ' + \'';
30 + }}
31 + var schemaExcl{{=$lvl}} = {{=$schemaValueExcl}};
32 + {{ $schemaValueExcl = 'schemaExcl' + $lvl; }}
33 +
34 + var {{=$exclusive}};
35 + var {{=$exclType}} = typeof {{=$schemaValueExcl}};
36 + if ({{=$exclType}} != 'boolean' && {{=$exclType}} != 'undefined' && {{=$exclType}} != 'number') {
37 + {{ var $errorKeyword = $exclusiveKeyword; }}
38 + {{# def.error:'_exclusiveLimit' }}
39 + } else if ({{# def.$dataNotType:'number' }}
40 + {{=$exclType}} == 'number'
41 + ? (
42 + ({{=$exclusive}} = {{=$schemaValue}} === undefined || {{=$schemaValueExcl}} {{=$op}}= {{=$schemaValue}})
43 + ? {{=$data}} {{=$notOp}}= {{=$schemaValueExcl}}
44 + : {{=$data}} {{=$notOp}} {{=$schemaValue}}
45 + )
46 + : (
47 + ({{=$exclusive}} = {{=$schemaValueExcl}} === true)
48 + ? {{=$data}} {{=$notOp}}= {{=$schemaValue}}
49 + : {{=$data}} {{=$notOp}} {{=$schemaValue}}
50 + )
51 + || {{=$data}} !== {{=$data}}) {
52 + var op{{=$lvl}} = {{=$exclusive}} ? '{{=$op}}' : '{{=$op}}=';
53 + {{
54 + if ($schema === undefined) {
55 + $errorKeyword = $exclusiveKeyword;
56 + $errSchemaPath = it.errSchemaPath + '/' + $exclusiveKeyword;
57 + $schemaValue = $schemaValueExcl;
58 + $isData = $isDataExcl;
59 + }
60 + }}
61 +{{??}}
62 + {{
63 + var $exclIsNumber = typeof $schemaExcl == 'number'
64 + , $opStr = $op; /*used in error*/
65 + }}
66 +
67 + {{? $exclIsNumber && $isData }}
68 + {{ var $opExpr = '\'' + $opStr + '\''; /*used in error*/ }}
69 + if ({{# def.$dataNotType:'number' }}
70 + ( {{=$schemaValue}} === undefined
71 + || {{=$schemaExcl}} {{=$op}}= {{=$schemaValue}}
72 + ? {{=$data}} {{=$notOp}}= {{=$schemaExcl}}
73 + : {{=$data}} {{=$notOp}} {{=$schemaValue}} )
74 + || {{=$data}} !== {{=$data}}) {
75 + {{??}}
76 + {{
77 + if ($exclIsNumber && $schema === undefined) {
78 + {{# def.setExclusiveLimit }}
79 + $schemaValue = $schemaExcl;
80 + $notOp += '=';
81 + } else {
82 + if ($exclIsNumber)
83 + $schemaValue = Math[$isMax ? 'min' : 'max']($schemaExcl, $schema);
84 +
85 + if ($schemaExcl === ($exclIsNumber ? $schemaValue : true)) {
86 + {{# def.setExclusiveLimit }}
87 + $notOp += '=';
88 + } else {
89 + $exclusive = false;
90 + $opStr += '=';
91 + }
92 + }
93 +
94 + var $opExpr = '\'' + $opStr + '\''; /*used in error*/
95 + }}
96 +
97 + if ({{# def.$dataNotType:'number' }}
98 + {{=$data}} {{=$notOp}} {{=$schemaValue}}
99 + || {{=$data}} !== {{=$data}}) {
100 + {{?}}
101 +{{?}}
102 + {{ $errorKeyword = $errorKeyword || $keyword; }}
103 + {{# def.error:'_limit' }}
104 + } {{? $breakOnError }} else { {{?}}
1 +{{# def.definitions }}
2 +{{# def.errors }}
3 +{{# def.setupKeyword }}
4 +{{# def.$data }}
5 +
6 +{{ var $op = $keyword == 'maxItems' ? '>' : '<'; }}
7 +if ({{# def.$dataNotType:'number' }} {{=$data}}.length {{=$op}} {{=$schemaValue}}) {
8 + {{ var $errorKeyword = $keyword; }}
9 + {{# def.error:'_limitItems' }}
10 +} {{? $breakOnError }} else { {{?}}
1 +{{# def.definitions }}
2 +{{# def.errors }}
3 +{{# def.setupKeyword }}
4 +{{# def.$data }}
5 +
6 +{{ var $op = $keyword == 'maxLength' ? '>' : '<'; }}
7 +if ({{# def.$dataNotType:'number' }} {{# def.strLength }} {{=$op}} {{=$schemaValue}}) {
8 + {{ var $errorKeyword = $keyword; }}
9 + {{# def.error:'_limitLength' }}
10 +} {{? $breakOnError }} else { {{?}}
1 +{{# def.definitions }}
2 +{{# def.errors }}
3 +{{# def.setupKeyword }}
4 +{{# def.$data }}
5 +
6 +{{ var $op = $keyword == 'maxProperties' ? '>' : '<'; }}
7 +if ({{# def.$dataNotType:'number' }} Object.keys({{=$data}}).length {{=$op}} {{=$schemaValue}}) {
8 + {{ var $errorKeyword = $keyword; }}
9 + {{# def.error:'_limitProperties' }}
10 +} {{? $breakOnError }} else { {{?}}
1 +{{# def.definitions }}
2 +{{# def.errors }}
3 +{{# def.setupKeyword }}
4 +{{# def.setupNextLevel }}
5 +
6 +{{
7 + var $currentBaseId = $it.baseId
8 + , $allSchemasEmpty = true;
9 +}}
10 +
11 +{{~ $schema:$sch:$i }}
12 + {{? {{# def.nonEmptySchema:$sch }} }}
13 + {{
14 + $allSchemasEmpty = false;
15 + $it.schema = $sch;
16 + $it.schemaPath = $schemaPath + '[' + $i + ']';
17 + $it.errSchemaPath = $errSchemaPath + '/' + $i;
18 + }}
19 +
20 + {{# def.insertSubschemaCode }}
21 +
22 + {{# def.ifResultValid }}
23 + {{?}}
24 +{{~}}
25 +
26 +{{? $breakOnError }}
27 + {{? $allSchemasEmpty }}
28 + if (true) {
29 + {{??}}
30 + {{= $closingBraces.slice(0,-1) }}
31 + {{?}}
32 +{{?}}
33 +
34 +{{# def.cleanUp }}
1 +{{# def.definitions }}
2 +{{# def.errors }}
3 +{{# def.setupKeyword }}
4 +{{# def.setupNextLevel }}
5 +
6 +{{
7 + var $noEmptySchema = $schema.every(function($sch) {
8 + return {{# def.nonEmptySchema:$sch }};
9 + });
10 +}}
11 +{{? $noEmptySchema }}
12 + {{ var $currentBaseId = $it.baseId; }}
13 + var {{=$errs}} = errors;
14 + var {{=$valid}} = false;
15 +
16 + {{# def.setCompositeRule }}
17 +
18 + {{~ $schema:$sch:$i }}
19 + {{
20 + $it.schema = $sch;
21 + $it.schemaPath = $schemaPath + '[' + $i + ']';
22 + $it.errSchemaPath = $errSchemaPath + '/' + $i;
23 + }}
24 +
25 + {{# def.insertSubschemaCode }}
26 +
27 + {{=$valid}} = {{=$valid}} || {{=$nextValid}};
28 +
29 + if (!{{=$valid}}) {
30 + {{ $closingBraces += '}'; }}
31 + {{~}}
32 +
33 + {{# def.resetCompositeRule }}
34 +
35 + {{= $closingBraces }}
36 +
37 + if (!{{=$valid}}) {
38 + {{# def.extraError:'anyOf' }}
39 + } else {
40 + {{# def.resetErrors }}
41 + {{? it.opts.allErrors }} } {{?}}
42 +
43 + {{# def.cleanUp }}
44 +{{??}}
45 + {{? $breakOnError }}
46 + if (true) {
47 + {{?}}
48 +{{?}}
1 +{{## def.coerceType:
2 + {{
3 + var $dataType = 'dataType' + $lvl
4 + , $coerced = 'coerced' + $lvl;
5 + }}
6 + var {{=$dataType}} = typeof {{=$data}};
7 + {{? it.opts.coerceTypes == 'array'}}
8 + if ({{=$dataType}} == 'object' && Array.isArray({{=$data}})) {{=$dataType}} = 'array';
9 + {{?}}
10 +
11 + var {{=$coerced}} = undefined;
12 +
13 + {{ var $bracesCoercion = ''; }}
14 + {{~ $coerceToTypes:$type:$i }}
15 + {{? $i }}
16 + if ({{=$coerced}} === undefined) {
17 + {{ $bracesCoercion += '}'; }}
18 + {{?}}
19 +
20 + {{? it.opts.coerceTypes == 'array' && $type != 'array' }}
21 + if ({{=$dataType}} == 'array' && {{=$data}}.length == 1) {
22 + {{=$coerced}} = {{=$data}} = {{=$data}}[0];
23 + {{=$dataType}} = typeof {{=$data}};
24 + /*if ({{=$dataType}} == 'object' && Array.isArray({{=$data}})) {{=$dataType}} = 'array';*/
25 + }
26 + {{?}}
27 +
28 + {{? $type == 'string' }}
29 + if ({{=$dataType}} == 'number' || {{=$dataType}} == 'boolean')
30 + {{=$coerced}} = '' + {{=$data}};
31 + else if ({{=$data}} === null) {{=$coerced}} = '';
32 + {{?? $type == 'number' || $type == 'integer' }}
33 + if ({{=$dataType}} == 'boolean' || {{=$data}} === null
34 + || ({{=$dataType}} == 'string' && {{=$data}} && {{=$data}} == +{{=$data}}
35 + {{? $type == 'integer' }} && !({{=$data}} % 1){{?}}))
36 + {{=$coerced}} = +{{=$data}};
37 + {{?? $type == 'boolean' }}
38 + if ({{=$data}} === 'false' || {{=$data}} === 0 || {{=$data}} === null)
39 + {{=$coerced}} = false;
40 + else if ({{=$data}} === 'true' || {{=$data}} === 1)
41 + {{=$coerced}} = true;
42 + {{?? $type == 'null' }}
43 + if ({{=$data}} === '' || {{=$data}} === 0 || {{=$data}} === false)
44 + {{=$coerced}} = null;
45 + {{?? it.opts.coerceTypes == 'array' && $type == 'array' }}
46 + if ({{=$dataType}} == 'string' || {{=$dataType}} == 'number' || {{=$dataType}} == 'boolean' || {{=$data}} == null)
47 + {{=$coerced}} = [{{=$data}}];
48 + {{?}}
49 + {{~}}
50 +
51 + {{= $bracesCoercion }}
52 +
53 + if ({{=$coerced}} === undefined) {
54 + {{# def.error:'type' }}
55 + } else {
56 + {{# def.setParentData }}
57 + {{=$data}} = {{=$coerced}};
58 + {{? !$dataLvl }}if ({{=$parentData}} !== undefined){{?}}
59 + {{=$parentData}}[{{=$parentDataProperty}}] = {{=$coerced}};
60 + }
61 +#}}
1 +{{# def.definitions }}
2 +{{# def.setupKeyword }}
3 +
4 +{{ var $comment = it.util.toQuotedString($schema); }}
5 +{{? it.opts.$comment === true }}
6 + console.log({{=$comment}});
7 +{{?? typeof it.opts.$comment == 'function' }}
8 + self._opts.$comment({{=$comment}}, {{=it.util.toQuotedString($errSchemaPath)}}, validate.root.schema);
9 +{{?}}
1 +{{# def.definitions }}
2 +{{# def.errors }}
3 +{{# def.setupKeyword }}
4 +{{# def.$data }}
5 +
6 +{{? !$isData }}
7 + var schema{{=$lvl}} = validate.schema{{=$schemaPath}};
8 +{{?}}
9 +var {{=$valid}} = equal({{=$data}}, schema{{=$lvl}});
10 +{{# def.checkError:'const' }}
11 +{{? $breakOnError }} else { {{?}}
1 +{{# def.definitions }}
2 +{{# def.errors }}
3 +{{# def.setupKeyword }}
4 +{{# def.setupNextLevel }}
5 +
6 +
7 +{{
8 + var $idx = 'i' + $lvl
9 + , $dataNxt = $it.dataLevel = it.dataLevel + 1
10 + , $nextData = 'data' + $dataNxt
11 + , $currentBaseId = it.baseId
12 + , $nonEmptySchema = {{# def.nonEmptySchema:$schema }};
13 +}}
14 +
15 +var {{=$errs}} = errors;
16 +var {{=$valid}};
17 +
18 +{{? $nonEmptySchema }}
19 + {{# def.setCompositeRule }}
20 +
21 + {{
22 + $it.schema = $schema;
23 + $it.schemaPath = $schemaPath;
24 + $it.errSchemaPath = $errSchemaPath;
25 + }}
26 +
27 + var {{=$nextValid}} = false;
28 +
29 + for (var {{=$idx}} = 0; {{=$idx}} < {{=$data}}.length; {{=$idx}}++) {
30 + {{
31 + $it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true);
32 + var $passData = $data + '[' + $idx + ']';
33 + $it.dataPathArr[$dataNxt] = $idx;
34 + }}
35 +
36 + {{# def.generateSubschemaCode }}
37 + {{# def.optimizeValidate }}
38 +
39 + if ({{=$nextValid}}) break;
40 + }
41 +
42 + {{# def.resetCompositeRule }}
43 + {{= $closingBraces }}
44 +
45 + if (!{{=$nextValid}}) {
46 +{{??}}
47 + if ({{=$data}}.length == 0) {
48 +{{?}}
49 +
50 + {{# def.error:'contains' }}
51 + } else {
52 + {{? $nonEmptySchema }}
53 + {{# def.resetErrors }}
54 + {{?}}
55 + {{? it.opts.allErrors }} } {{?}}
56 +
57 +{{# def.cleanUp }}
1 +{{# def.definitions }}
2 +{{# def.errors }}
3 +{{# def.setupKeyword }}
4 +{{# def.$data }}
5 +
6 +{{
7 + var $rule = this
8 + , $definition = 'definition' + $lvl
9 + , $rDef = $rule.definition
10 + , $closingBraces = '';
11 + var $validate = $rDef.validate;
12 + var $compile, $inline, $macro, $ruleValidate, $validateCode;
13 +}}
14 +
15 +{{? $isData && $rDef.$data }}
16 + {{
17 + $validateCode = 'keywordValidate' + $lvl;
18 + var $validateSchema = $rDef.validateSchema;
19 + }}
20 + var {{=$definition}} = RULES.custom['{{=$keyword}}'].definition;
21 + var {{=$validateCode}} = {{=$definition}}.validate;
22 +{{??}}
23 + {{
24 + $ruleValidate = it.useCustomRule($rule, $schema, it.schema, it);
25 + if (!$ruleValidate) return;
26 + $schemaValue = 'validate.schema' + $schemaPath;
27 + $validateCode = $ruleValidate.code;
28 + $compile = $rDef.compile;
29 + $inline = $rDef.inline;
30 + $macro = $rDef.macro;
31 + }}
32 +{{?}}
33 +
34 +{{
35 + var $ruleErrs = $validateCode + '.errors'
36 + , $i = 'i' + $lvl
37 + , $ruleErr = 'ruleErr' + $lvl
38 + , $asyncKeyword = $rDef.async;
39 +
40 + if ($asyncKeyword && !it.async)
41 + throw new Error('async keyword in sync schema');
42 +}}
43 +
44 +
45 +{{? !($inline || $macro) }}{{=$ruleErrs}} = null;{{?}}
46 +var {{=$errs}} = errors;
47 +var {{=$valid}};
48 +
49 +{{## def.callRuleValidate:
50 + {{=$validateCode}}.call(
51 + {{? it.opts.passContext }}this{{??}}self{{?}}
52 + {{? $compile || $rDef.schema === false }}
53 + , {{=$data}}
54 + {{??}}
55 + , {{=$schemaValue}}
56 + , {{=$data}}
57 + , validate.schema{{=it.schemaPath}}
58 + {{?}}
59 + , {{# def.dataPath }}
60 + {{# def.passParentData }}
61 + , rootData
62 + )
63 +#}}
64 +
65 +{{## def.extendErrors:_inline:
66 + for (var {{=$i}}={{=$errs}}; {{=$i}}<errors; {{=$i}}++) {
67 + var {{=$ruleErr}} = vErrors[{{=$i}}];
68 + if ({{=$ruleErr}}.dataPath === undefined)
69 + {{=$ruleErr}}.dataPath = (dataPath || '') + {{= it.errorPath }};
70 + {{# _inline ? 'if (\{\{=$ruleErr\}\}.schemaPath === undefined) {' : '' }}
71 + {{=$ruleErr}}.schemaPath = "{{=$errSchemaPath}}";
72 + {{# _inline ? '}' : '' }}
73 + {{? it.opts.verbose }}
74 + {{=$ruleErr}}.schema = {{=$schemaValue}};
75 + {{=$ruleErr}}.data = {{=$data}};
76 + {{?}}
77 + }
78 +#}}
79 +
80 +
81 +{{? $isData && $rDef.$data }}
82 + {{ $closingBraces += '}'; }}
83 + if ({{=$schemaValue}} === undefined) {
84 + {{=$valid}} = true;
85 + } else {
86 + {{? $validateSchema }}
87 + {{ $closingBraces += '}'; }}
88 + {{=$valid}} = {{=$definition}}.validateSchema({{=$schemaValue}});
89 + if ({{=$valid}}) {
90 + {{?}}
91 +{{?}}
92 +
93 +{{? $inline }}
94 + {{? $rDef.statements }}
95 + {{= $ruleValidate.validate }}
96 + {{??}}
97 + {{=$valid}} = {{= $ruleValidate.validate }};
98 + {{?}}
99 +{{?? $macro }}
100 + {{# def.setupNextLevel }}
101 + {{
102 + $it.schema = $ruleValidate.validate;
103 + $it.schemaPath = '';
104 + }}
105 + {{# def.setCompositeRule }}
106 + {{ var $code = it.validate($it).replace(/validate\.schema/g, $validateCode); }}
107 + {{# def.resetCompositeRule }}
108 + {{= $code }}
109 +{{??}}
110 + {{# def.beginDefOut}}
111 + {{# def.callRuleValidate }}
112 + {{# def.storeDefOut:def_callRuleValidate }}
113 +
114 + {{? $rDef.errors === false }}
115 + {{=$valid}} = {{? $asyncKeyword }}await {{?}}{{= def_callRuleValidate }};
116 + {{??}}
117 + {{? $asyncKeyword }}
118 + {{ $ruleErrs = 'customErrors' + $lvl; }}
119 + var {{=$ruleErrs}} = null;
120 + try {
121 + {{=$valid}} = await {{= def_callRuleValidate }};
122 + } catch (e) {
123 + {{=$valid}} = false;
124 + if (e instanceof ValidationError) {{=$ruleErrs}} = e.errors;
125 + else throw e;
126 + }
127 + {{??}}
128 + {{=$ruleErrs}} = null;
129 + {{=$valid}} = {{= def_callRuleValidate }};
130 + {{?}}
131 + {{?}}
132 +{{?}}
133 +
134 +{{? $rDef.modifying }}
135 + if ({{=$parentData}}) {{=$data}} = {{=$parentData}}[{{=$parentDataProperty}}];
136 +{{?}}
137 +
138 +{{= $closingBraces }}
139 +
140 +{{## def.notValidationResult:
141 + {{? $rDef.valid === undefined }}
142 + !{{? $macro }}{{=$nextValid}}{{??}}{{=$valid}}{{?}}
143 + {{??}}
144 + {{= !$rDef.valid }}
145 + {{?}}
146 +#}}
147 +
148 +{{? $rDef.valid }}
149 + {{? $breakOnError }} if (true) { {{?}}
150 +{{??}}
151 + if ({{# def.notValidationResult }}) {
152 + {{ $errorKeyword = $rule.keyword; }}
153 + {{# def.beginDefOut}}
154 + {{# def.error:'custom' }}
155 + {{# def.storeDefOut:def_customError }}
156 +
157 + {{? $inline }}
158 + {{? $rDef.errors }}
159 + {{? $rDef.errors != 'full' }}
160 + {{# def.extendErrors:true }}
161 + {{?}}
162 + {{??}}
163 + {{? $rDef.errors === false}}
164 + {{= def_customError }}
165 + {{??}}
166 + if ({{=$errs}} == errors) {
167 + {{= def_customError }}
168 + } else {
169 + {{# def.extendErrors:true }}
170 + }
171 + {{?}}
172 + {{?}}
173 + {{?? $macro }}
174 + {{# def.extraError:'custom' }}
175 + {{??}}
176 + {{? $rDef.errors === false}}
177 + {{= def_customError }}
178 + {{??}}
179 + if (Array.isArray({{=$ruleErrs}})) {
180 + if (vErrors === null) vErrors = {{=$ruleErrs}};
181 + else vErrors = vErrors.concat({{=$ruleErrs}});
182 + errors = vErrors.length;
183 + {{# def.extendErrors:false }}
184 + } else {
185 + {{= def_customError }}
186 + }
187 + {{?}}
188 + {{?}}
189 +
190 + } {{? $breakOnError }} else { {{?}}
191 +{{?}}
1 +{{## def.assignDefault:
2 + {{? it.compositeRule }}
3 + {{
4 + if (it.opts.strictDefaults) {
5 + var $defaultMsg = 'default is ignored for: ' + $passData;
6 + if (it.opts.strictDefaults === 'log') it.logger.warn($defaultMsg);
7 + else throw new Error($defaultMsg);
8 + }
9 + }}
10 + {{??}}
11 + if ({{=$passData}} === undefined
12 + {{? it.opts.useDefaults == 'empty' }}
13 + || {{=$passData}} === null
14 + || {{=$passData}} === ''
15 + {{?}}
16 + )
17 + {{=$passData}} = {{? it.opts.useDefaults == 'shared' }}
18 + {{= it.useDefault($sch.default) }}
19 + {{??}}
20 + {{= JSON.stringify($sch.default) }}
21 + {{?}};
22 + {{?}}
23 +#}}
24 +
25 +
26 +{{## def.defaultProperties:
27 + {{
28 + var $schema = it.schema.properties
29 + , $schemaKeys = Object.keys($schema); }}
30 + {{~ $schemaKeys:$propertyKey }}
31 + {{ var $sch = $schema[$propertyKey]; }}
32 + {{? $sch.default !== undefined }}
33 + {{ var $passData = $data + it.util.getProperty($propertyKey); }}
34 + {{# def.assignDefault }}
35 + {{?}}
36 + {{~}}
37 +#}}
38 +
39 +
40 +{{## def.defaultItems:
41 + {{~ it.schema.items:$sch:$i }}
42 + {{? $sch.default !== undefined }}
43 + {{ var $passData = $data + '[' + $i + ']'; }}
44 + {{# def.assignDefault }}
45 + {{?}}
46 + {{~}}
47 +#}}
1 +{{## def.setupKeyword:
2 + {{
3 + var $lvl = it.level;
4 + var $dataLvl = it.dataLevel;
5 + var $schema = it.schema[$keyword];
6 + var $schemaPath = it.schemaPath + it.util.getProperty($keyword);
7 + var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
8 + var $breakOnError = !it.opts.allErrors;
9 + var $errorKeyword;
10 +
11 + var $data = 'data' + ($dataLvl || '');
12 + var $valid = 'valid' + $lvl;
13 + var $errs = 'errs__' + $lvl;
14 + }}
15 +#}}
16 +
17 +
18 +{{## def.setCompositeRule:
19 + {{
20 + var $wasComposite = it.compositeRule;
21 + it.compositeRule = $it.compositeRule = true;
22 + }}
23 +#}}
24 +
25 +
26 +{{## def.resetCompositeRule:
27 + {{ it.compositeRule = $it.compositeRule = $wasComposite; }}
28 +#}}
29 +
30 +
31 +{{## def.setupNextLevel:
32 + {{
33 + var $it = it.util.copy(it);
34 + var $closingBraces = '';
35 + $it.level++;
36 + var $nextValid = 'valid' + $it.level;
37 + }}
38 +#}}
39 +
40 +
41 +{{## def.ifValid:
42 + {{? $breakOnError }}
43 + if ({{=$valid}}) {
44 + {{ $closingBraces += '}'; }}
45 + {{?}}
46 +#}}
47 +
48 +
49 +{{## def.ifResultValid:
50 + {{? $breakOnError }}
51 + if ({{=$nextValid}}) {
52 + {{ $closingBraces += '}'; }}
53 + {{?}}
54 +#}}
55 +
56 +
57 +{{## def.elseIfValid:
58 + {{? $breakOnError }}
59 + {{ $closingBraces += '}'; }}
60 + else {
61 + {{?}}
62 +#}}
63 +
64 +
65 +{{## def.nonEmptySchema:_schema:
66 + (it.opts.strictKeywords
67 + ? typeof _schema == 'object' && Object.keys(_schema).length > 0
68 + : it.util.schemaHasRules(_schema, it.RULES.all))
69 +#}}
70 +
71 +
72 +{{## def.strLength:
73 + {{? it.opts.unicode === false }}
74 + {{=$data}}.length
75 + {{??}}
76 + ucs2length({{=$data}})
77 + {{?}}
78 +#}}
79 +
80 +
81 +{{## def.willOptimize:
82 + it.util.varOccurences($code, $nextData) < 2
83 +#}}
84 +
85 +
86 +{{## def.generateSubschemaCode:
87 + {{
88 + var $code = it.validate($it);
89 + $it.baseId = $currentBaseId;
90 + }}
91 +#}}
92 +
93 +
94 +{{## def.insertSubschemaCode:
95 + {{= it.validate($it) }}
96 + {{ $it.baseId = $currentBaseId; }}
97 +#}}
98 +
99 +
100 +{{## def._optimizeValidate:
101 + it.util.varReplace($code, $nextData, $passData)
102 +#}}
103 +
104 +
105 +{{## def.optimizeValidate:
106 + {{? {{# def.willOptimize}} }}
107 + {{= {{# def._optimizeValidate }} }}
108 + {{??}}
109 + var {{=$nextData}} = {{=$passData}};
110 + {{= $code }}
111 + {{?}}
112 +#}}
113 +
114 +
115 +{{## def.cleanUp: {{ out = it.util.cleanUpCode(out); }} #}}
116 +
117 +
118 +{{## def.finalCleanUp: {{ out = it.util.finalCleanUpCode(out, $async); }} #}}
119 +
120 +
121 +{{## def.$data:
122 + {{
123 + var $isData = it.opts.$data && $schema && $schema.$data
124 + , $schemaValue;
125 + }}
126 + {{? $isData }}
127 + var schema{{=$lvl}} = {{= it.util.getData($schema.$data, $dataLvl, it.dataPathArr) }};
128 + {{ $schemaValue = 'schema' + $lvl; }}
129 + {{??}}
130 + {{ $schemaValue = $schema; }}
131 + {{?}}
132 +#}}
133 +
134 +
135 +{{## def.$dataNotType:_type:
136 + {{?$isData}} ({{=$schemaValue}} !== undefined && typeof {{=$schemaValue}} != _type) || {{?}}
137 +#}}
138 +
139 +
140 +{{## def.check$dataIsArray:
141 + if (schema{{=$lvl}} === undefined) {{=$valid}} = true;
142 + else if (!Array.isArray(schema{{=$lvl}})) {{=$valid}} = false;
143 + else {
144 +#}}
145 +
146 +
147 +{{## def.beginDefOut:
148 + {{
149 + var $$outStack = $$outStack || [];
150 + $$outStack.push(out);
151 + out = '';
152 + }}
153 +#}}
154 +
155 +
156 +{{## def.storeDefOut:_variable:
157 + {{
158 + var _variable = out;
159 + out = $$outStack.pop();
160 + }}
161 +#}}
162 +
163 +
164 +{{## def.dataPath:(dataPath || ''){{? it.errorPath != '""'}} + {{= it.errorPath }}{{?}}#}}
165 +
166 +{{## def.setParentData:
167 + {{
168 + var $parentData = $dataLvl ? 'data' + (($dataLvl-1)||'') : 'parentData'
169 + , $parentDataProperty = $dataLvl ? it.dataPathArr[$dataLvl] : 'parentDataProperty';
170 + }}
171 +#}}
172 +
173 +{{## def.passParentData:
174 + {{# def.setParentData }}
175 + , {{= $parentData }}
176 + , {{= $parentDataProperty }}
177 +#}}
178 +
179 +
180 +{{## def.iterateProperties:
181 + {{? $ownProperties }}
182 + {{=$dataProperties}} = {{=$dataProperties}} || Object.keys({{=$data}});
183 + for (var {{=$idx}}=0; {{=$idx}}<{{=$dataProperties}}.length; {{=$idx}}++) {
184 + var {{=$key}} = {{=$dataProperties}}[{{=$idx}}];
185 + {{??}}
186 + for (var {{=$key}} in {{=$data}}) {
187 + {{?}}
188 +#}}
189 +
190 +
191 +{{## def.noPropertyInData:
192 + {{=$useData}} === undefined
193 + {{? $ownProperties }}
194 + || !{{# def.isOwnProperty }}
195 + {{?}}
196 +#}}
197 +
198 +
199 +{{## def.isOwnProperty:
200 + Object.prototype.hasOwnProperty.call({{=$data}}, '{{=it.util.escapeQuotes($propertyKey)}}')
201 +#}}
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.