From d6bd35287fce69b25884a889dcd49da0b692bd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E8=B5=AB=E6=9F=B1?= Date: Wed, 20 Mar 2019 18:27:04 +0900 Subject: [PATCH 01/11] Add Korean locales files for nodes --- .../nodes/locales/ko/core/20-inject.html | 34 + .../nodes/locales/ko/core/25-catch.html | 36 + .../nodes/locales/ko/core/25-status.html | 33 + .../nodes/locales/ko/core/58-debug.html | 25 + .../nodes/locales/ko/core/60-link.html | 23 + .../nodes/locales/ko/core/75-exec.html | 74 ++ .../nodes/locales/ko/core/80-function.html | 51 + .../nodes/locales/ko/core/80-template.html | 49 + .../nodes/locales/ko/core/89-delay.html | 30 + .../nodes/locales/ko/core/89-trigger.html | 33 + .../nodes/locales/ko/core/90-comment.html | 21 + .../nodes/locales/ko/core/98-unknown.html | 24 + .../locales/ko/hardware/36-rpi-gpio.html | 71 ++ .../@node-red/nodes/locales/ko/io/05-tls.html | 19 + .../nodes/locales/ko/io/06-httpproxy.html | 22 + .../nodes/locales/ko/io/10-mqtt.html | 74 ++ .../nodes/locales/ko/io/21-httpin.html | 81 ++ .../nodes/locales/ko/io/21-httprequest.html | 75 ++ .../nodes/locales/ko/io/22-websocket.html | 36 + .../nodes/locales/ko/io/23-watch.html | 25 + .../nodes/locales/ko/io/31-tcpin.html | 35 + .../@node-red/nodes/locales/ko/io/32-udp.html | 28 + .../nodes/locales/ko/logic/10-switch.html | 39 + .../nodes/locales/ko/logic/15-change.html | 33 + .../nodes/locales/ko/logic/16-range.html | 33 + .../nodes/locales/ko/logic/17-split.html | 138 +++ .../nodes/locales/ko/logic/18-sort.html | 40 + .../nodes/locales/ko/logic/19-batch.html | 34 + .../@node-red/nodes/locales/ko/messages.json | 1005 +++++++++++++++++ .../nodes/locales/ko/parsers/70-CSV.html | 44 + .../nodes/locales/ko/parsers/70-HTML.html | 33 + .../nodes/locales/ko/parsers/70-JSON.html | 43 + .../nodes/locales/ko/parsers/70-XML.html | 49 + .../nodes/locales/ko/parsers/70-YAML.html | 34 + .../nodes/locales/ko/storage/50-file.html | 59 + 35 files changed, 2483 insertions(+) create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/20-inject.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/25-catch.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/25-status.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/58-debug.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/60-link.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/75-exec.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/80-function.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/80-template.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/89-delay.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/89-trigger.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/90-comment.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/core/98-unknown.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/hardware/36-rpi-gpio.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/io/05-tls.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/io/06-httpproxy.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/io/10-mqtt.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/io/21-httpin.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/io/21-httprequest.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/io/22-websocket.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/io/23-watch.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/io/31-tcpin.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/io/32-udp.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/logic/10-switch.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/logic/15-change.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/logic/16-range.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/logic/17-split.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/logic/18-sort.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/logic/19-batch.html create mode 100755 packages/node_modules/@node-red/nodes/locales/ko/messages.json create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/parsers/70-CSV.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/parsers/70-HTML.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/parsers/70-JSON.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/parsers/70-XML.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/parsers/70-YAML.html create mode 100644 packages/node_modules/@node-red/nodes/locales/ko/storage/50-file.html diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/20-inject.html b/packages/node_modules/@node-red/nodes/locales/ko/core/20-inject.html new file mode 100644 index 000000000..254b542f3 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/20-inject.html @@ -0,0 +1,34 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/25-catch.html b/packages/node_modules/@node-red/nodes/locales/ko/core/25-catch.html new file mode 100644 index 000000000..4cd49ff5a --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/25-catch.html @@ -0,0 +1,36 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/25-status.html b/packages/node_modules/@node-red/nodes/locales/ko/core/25-status.html new file mode 100644 index 000000000..fa36d439b --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/25-status.html @@ -0,0 +1,33 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/58-debug.html b/packages/node_modules/@node-red/nodes/locales/ko/core/58-debug.html new file mode 100644 index 000000000..22395c451 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/58-debug.html @@ -0,0 +1,25 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/60-link.html b/packages/node_modules/@node-red/nodes/locales/ko/core/60-link.html new file mode 100644 index 000000000..74aa41416 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/60-link.html @@ -0,0 +1,23 @@ + + + \ No newline at end of file diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/75-exec.html b/packages/node_modules/@node-red/nodes/locales/ko/core/75-exec.html new file mode 100644 index 000000000..eaeb12b31 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/75-exec.html @@ -0,0 +1,74 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/80-function.html b/packages/node_modules/@node-red/nodes/locales/ko/core/80-function.html new file mode 100644 index 000000000..813fb9505 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/80-function.html @@ -0,0 +1,51 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/80-template.html b/packages/node_modules/@node-red/nodes/locales/ko/core/80-template.html new file mode 100644 index 000000000..c3e3d7226 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/80-template.html @@ -0,0 +1,49 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/89-delay.html b/packages/node_modules/@node-red/nodes/locales/ko/core/89-delay.html new file mode 100644 index 000000000..f890ec895 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/89-delay.html @@ -0,0 +1,30 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/89-trigger.html b/packages/node_modules/@node-red/nodes/locales/ko/core/89-trigger.html new file mode 100644 index 000000000..e89aac5fa --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/89-trigger.html @@ -0,0 +1,33 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/90-comment.html b/packages/node_modules/@node-red/nodes/locales/ko/core/90-comment.html new file mode 100644 index 000000000..814bb63ad --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/90-comment.html @@ -0,0 +1,21 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/core/98-unknown.html b/packages/node_modules/@node-red/nodes/locales/ko/core/98-unknown.html new file mode 100644 index 000000000..83868af53 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/core/98-unknown.html @@ -0,0 +1,24 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/hardware/36-rpi-gpio.html b/packages/node_modules/@node-red/nodes/locales/ko/hardware/36-rpi-gpio.html new file mode 100644 index 000000000..dfcde83db --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/hardware/36-rpi-gpio.html @@ -0,0 +1,71 @@ + + + + + + + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/io/05-tls.html b/packages/node_modules/@node-red/nodes/locales/ko/io/05-tls.html new file mode 100644 index 000000000..d800f14c9 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/io/05-tls.html @@ -0,0 +1,19 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/io/06-httpproxy.html b/packages/node_modules/@node-red/nodes/locales/ko/io/06-httpproxy.html new file mode 100644 index 000000000..4357c7f2b --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/io/06-httpproxy.html @@ -0,0 +1,22 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/io/10-mqtt.html b/packages/node_modules/@node-red/nodes/locales/ko/io/10-mqtt.html new file mode 100644 index 000000000..613941c43 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/io/10-mqtt.html @@ -0,0 +1,74 @@ + + + + + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/io/21-httpin.html b/packages/node_modules/@node-red/nodes/locales/ko/io/21-httpin.html new file mode 100644 index 000000000..680b28a79 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/io/21-httpin.html @@ -0,0 +1,81 @@ + + + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/io/21-httprequest.html b/packages/node_modules/@node-red/nodes/locales/ko/io/21-httprequest.html new file mode 100644 index 000000000..674faadcf --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/io/21-httprequest.html @@ -0,0 +1,75 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/io/22-websocket.html b/packages/node_modules/@node-red/nodes/locales/ko/io/22-websocket.html new file mode 100644 index 000000000..09949bffb --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/io/22-websocket.html @@ -0,0 +1,36 @@ + + + + + + + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/io/23-watch.html b/packages/node_modules/@node-red/nodes/locales/ko/io/23-watch.html new file mode 100644 index 000000000..f51ac08f9 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/io/23-watch.html @@ -0,0 +1,25 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/io/31-tcpin.html b/packages/node_modules/@node-red/nodes/locales/ko/io/31-tcpin.html new file mode 100644 index 000000000..1c665bb8d --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/io/31-tcpin.html @@ -0,0 +1,35 @@ + + + + + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/io/32-udp.html b/packages/node_modules/@node-red/nodes/locales/ko/io/32-udp.html new file mode 100644 index 000000000..f6a5889db --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/io/32-udp.html @@ -0,0 +1,28 @@ + + + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/logic/10-switch.html b/packages/node_modules/@node-red/nodes/locales/ko/logic/10-switch.html new file mode 100644 index 000000000..99b886978 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/logic/10-switch.html @@ -0,0 +1,39 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/logic/15-change.html b/packages/node_modules/@node-red/nodes/locales/ko/logic/15-change.html new file mode 100644 index 000000000..f971f0a15 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/logic/15-change.html @@ -0,0 +1,33 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/logic/16-range.html b/packages/node_modules/@node-red/nodes/locales/ko/logic/16-range.html new file mode 100644 index 000000000..5fd179bdb --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/logic/16-range.html @@ -0,0 +1,33 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/logic/17-split.html b/packages/node_modules/@node-red/nodes/locales/ko/logic/17-split.html new file mode 100644 index 000000000..6b2907185 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/logic/17-split.html @@ -0,0 +1,138 @@ + + + + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/logic/18-sort.html b/packages/node_modules/@node-red/nodes/locales/ko/logic/18-sort.html new file mode 100644 index 000000000..d05c253b8 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/logic/18-sort.html @@ -0,0 +1,40 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/logic/19-batch.html b/packages/node_modules/@node-red/nodes/locales/ko/logic/19-batch.html new file mode 100644 index 000000000..b2287245c --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/logic/19-batch.html @@ -0,0 +1,34 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/messages.json b/packages/node_modules/@node-red/nodes/locales/ko/messages.json new file mode 100755 index 000000000..f2e555a1d --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/messages.json @@ -0,0 +1,1005 @@ +{ + "common": { + "label": { + "payload": "페이로드", + "topic": "토픽", + "name": "이름", + "username": "유저", + "password": "패스워드", + "property": "프로퍼티" + }, + "status": { + "connected": "접속됨", + "not-connected": "미접속", + "disconnected": "절단", + "connecting": "접속중", + "error": "에러", + "ok": "OK" + }, + "notification": { + "error": "에러: __message__", + "errors": { + "not-deployed": "노드가 배포되지 않았습니다", + "no-response": "서버의 응답이 없습니다", + "unexpected": "예상치 못한 에러 (__status__) __message__" + } + }, + "errors": { + "nooverride": "경고:메세지에서 설정한 프로퍼티는, 노드의 프로퍼티를 덮어쓸 수 없습니다.자세한 사항은 bit.ly/nr-override-msg-props를 참조해 주세요." + } + }, + "inject": { + "inject": "inject", + "repeat": "repeat = __repeat__", + "crontab": "crontab = __crontab__", + "stopped": "stopped", + "failed": "inject실패: __error__", + "label": { + "repeat": "반복", + "flow": "플로우 컨텍스트", + "global": "글로벌 컨텍스트", + "str": "문자열", + "num": "수치", + "bool": "진위값", + "json": "오브젝트", + "bin": "버퍼", + "date": "타임스탬프", + "env": "환경변수", + "object": "오브젝트", + "string": "문자열", + "boolean": "진위값", + "number": "수치", + "Array": "배열", + "invalid": "올바르지 않은 JSON" + }, + "timestamp": "타임스탬프", + "none": "없음", + "interval": "지정한 시간간격", + "interval-time": "지정한 시간간격, 일시", + "time": "지정한 일시", + "seconds": "초", + "minutes": "분", + "hours": "시간", + "between": "시각", + "previous": "이전의 값", + "at": "시각", + "and": "~", + "every": "시간각격", + "days": [ + "월요일", + "화요일", + "수요일", + "목요일", + "금요일", + "토요일", + "일요일" + ], + "on": "요일", + "onstart": "Node-RED시작의", + "onceDelay": "초 후, 아래를 시행", + "tip": "주석: '지정한 시간간격, 일시'와 '지정한 일시'는 cron을 사용합니다.
'시간간격'에는 596시간 보다 작은 값을 지정합니다.
자세한 사항은 노드의 '정보'를 확인해 주세요.", + "success": "inject처리를 실행했습니다: __label__", + "errors": { + "failed": "inject처리를 실패했습니다. 자세한사항은 로그를 확인해 주세요.", + "toolong": "시간간격이 너무 큽니다." + } + }, + "catch": { + "catch": "catch: 모두", + "catchNodes": "catch: __number__", + "catchUncaught": "catch: 미보충", + "label": { + "source": "에러 취득처", + "node": "노드", + "type": "타입", + "selectAll": "모두 선택", + "sortByLabel": "노드 이름순으로 정렬", + "sortByType": "타입순으로 정렬", + "uncaught": "Catch노드로 처리된 에러를 무시" + }, + "scope": { + "all": "모든 노드", + "selected": "선택한 노드" + } + }, + "status": { + "status": "status: 모두", + "statusNodes": "status: __number__", + "label": { + "source": "상태취득처", + "node": "노드", + "type": "타입", + "selectAll": "모두 선택", + "sortByLabel": "노드 이름순으로 정렬", + "sortByType": "타입순으로 정렬" + }, + "scope": { + "all": "모든 노드", + "selected": "선택한 노드" + } + }, + "debug": { + "output": "대상", + "none": "없음", + "invalid-exp": "JSONata식이 올바르지 않음: __error__", + "msgprop": "메세지 프로퍼티", + "msgobj": "msg오브젝트 전체", + "to": "출력대상", + "debtab": "디버그 탭", + "tabcon": "디버그 탭과 콘솔", + "toSidebar": "디버그 창", + "toConsole": "시스템 콘솔", + "toStatus": "노드 상태(32자)", + "severity": "레벨", + "notification": { + "activated": "유효화 했습니다: __label__", + "deactivated": "무효화 했습니다: __label__" + }, + "sidebar": { + "label": "디버그", + "name": "디버그 메세지", + "filterAll": "모든 플로우", + "filterSelected": "선택한 노드", + "filterCurrent": "현재의 플로우", + "debugNodes": "debug노드", + "clearLog": "로그를 삭제", + "filterLog": "로그 필터링", + "openWindow": "새 창에서 열기" + }, + "messageMenu": { + "collapseAll": "모든 패스 접기", + "clearPinned": "선택한 패스", + "filterNode": "노드를 필터", + "clearFilter": "필터를 초기화" + } + }, + "link": { + "linkIn": "link in", + "linkOut": "link out" + }, + "tls": { + "tls": "TLS설정", + "label": { + "use-local-files": "로컬파일의 비밀키와 인증서를 사용", + "upload": "파일", + "cert": "인증서", + "key": "비밀키", + "passphrase": "패스 프레이즈", + "ca": "CA인증서", + "verify-server-cert": "서버인증서를 확인", + "servername": "서버명" + }, + "placeholder": { + "cert": "인증서(PEM형식) 패스", + "key": "비밀키(PEM형식) 패스", + "ca": "CA인증서(PEM형식) 패스", + "passphrase": "비밀키 패스프레이즈 (임의)", + "servername": "SNI로 사용" + }, + "error": { + "missing-file": "인증서와 비밀키 파일이 설정되지 않았습니다" + } + }, + "exec": { + "exec": "exec", + "spawn": "spawn", + "label": { + "command": "커맨드", + "append": "인수", + "timeout": "타임아웃", + "timeoutplace": "임의", + "return": "출력", + "seconds": "초", + "stdout": "표준 출력", + "stderr": "표준에러 출력", + "retcode": "반환 코드" + }, + "placeholder": { + "extraparams": "추가 인수" + }, + "opt": { + "exec": "커맨드 종료시 - exec모드", + "spawn": "커맨드 실행 중 - spawn모드" + }, + "oldrc": "구 형식의 출력를 사용(호환 모드)" + }, + "function": { + "function": "", + "label": { + "function": "코드", + "outputs": "출력 수" + }, + "error": { + "inputListener": "코드 내에서'input'이벤트의 리스터를 설정할 수 없습니다", + "non-message-returned": "Function노드가 __type__ 타입의 메세지송신을 시도했습니다" + } + }, + "template": { + "template": "template", + "label": { + "template": "템플릿", + "property": "프로퍼티", + "format": "구문", + "syntax": "형식", + "output": "출력형식", + "mustache": "Mustache템플릿", + "plain": "평분", + "json": "JSON", + "yaml": "YAML", + "none": "없음" + }, + "templatevalue": "This is the payload: {{payload}} !" + }, + "delay": { + "action": "동작", + "for": "시간", + "delaymsg": "메세지 지연", + "delayfixed": "지정한 시간 지연", + "delayvarmsg": "msg.delay에 지연을 설정", + "randomdelay": "랜덤 지연", + "limitrate": "메세지의 유량제한", + "limitall": "모든 메세지", + "limittopic": "msg.topic 마다", + "fairqueue": "지정한 시간 후에 큐 선두의 토픽 메세지를 출력", + "timedqueue": "지정한 시간 후에 큐에 있는 모든 토픽 메세지를 출력", + "milisecs": "밀리초", + "secs": "초", + "sec": "초", + "mins": "분", + "min": "분", + "hours": "시간", + "hour": "시간", + "days": "일", + "day": "일", + "between": "빈도", + "and": "번/", + "rate": "유량", + "msgper": "메세지/", + "dropmsg": "중간 메세지를 삭제", + "label": { + "delay": "delay", + "variable": "variable", + "limit": "limit", + "limitTopic": "limit topic", + "random": "random", + "units": { + "second": { + "plural": "초", + "singular": "초" + }, + "minute": { + "plural": "분", + "singular": "분" + }, + "hour": { + "plural": "시간", + "singular": "시간" + }, + "day": { + "plural": "일", + "singular": "일" + } + } + }, + "error": { + "buffer": "버퍼 상한의 1000메세지를 넘었습니다", + "buffer1": "버퍼 상한의 10000메세지를 넘었습니다" + } + }, + "trigger": { + "send": "송신 데이터", + "then": "송신후의 처리", + "then-send": "재송신 데이터", + "output": { + "string": "문자열", + "number": "수치", + "existing": "존재하는 msg오브젝트", + "original": "원래의 msg오브젝트", + "latest": "최신 msg오브젝트", + "nothing": "없음" + }, + "wait-reset": "초기화될 때 까지 대기", + "wait-for": "지정한 시간 대기", + "wait-loop": "지정한 시간 간격마다 송신을 반복", + "for": "처리대상", + "bytopics": "msg.topic 마다", + "alltopics": "모든 메세지", + "duration": { + "ms": "밀리초", + "s": "초", + "m": "분", + "h": "시간" + }, + "extend": "새로운 메세지를 받았을 때 지연을 연장", + "label": { + "trigger": "trigger", + "trigger-block": "trigger & block", + "trigger-loop": "resend every", + "reset": "초기화 조건:", + "resetMessage": "msg.reset을 설정", + "resetPayload": "msg.payload가 다음 값", + "resetprompt": "임의" + } + }, + "comment": { + "comment": "comment" + }, + "unknown": { + "label": { + "unknown": "unknown" + }, + "tip": "

현재의 Node-RED환경에서는 이 노드의 타입을 알 수 없습니다.

현재의 상태에서 이 노드를 배포하면 설정은 보존되지만, 해당 노드가 설치될 때 까지 플로우는 실행되지 않습니다.

자세한 사항은 노드의 '정보'를 참조해 주세요.

" + }, + "mqtt": { + "label": { + "broker": "서버", + "example": "예) localhost", + "output": "출력", + "qos": "QoS", + "retain": "보존", + "clientid": "클라이언트", + "port": "포트", + "keepalive": "킵 얼라이브 시간", + "cleansession": "세션 초기화", + "use-tls": "SSL/TLS접속을 사용", + "tls-config": "TLS설정", + "verify-server-cert": "서버인증서를 확인", + "compatmode": "구 MQTT 3.1서포트" + }, + "sections-label": { + "birth-message": "접속시의 송신메세지(Birth메세지)", + "will-message": "예기치 않은 절단시의 송신메세지(Will메세지)", + "close-message": "절단 전의 송신메세지(Close메세지)" + }, + "tabs-label": { + "connection": "접속", + "security": "세큐리티", + "messages": "메세지" + }, + "placeholder": { + "clientid": "ID를 자동생성하는 경우에는, 기입하지 않습니다", + "clientid-nonclean": "신규가 아닌 세션을 설정해 주세요", + "will-topic": "Will메세지를 무효화하는 경우에는, 기입하지 않습니다", + "birth-topic": "Birth메세지를 무효화하는 경우에는, 기입하지 않습니다", + "close-topic": "Close메세지를 무효화하는 경우에는, 기입하지 않습니다" + }, + "state": { + "connected": "브로커에 접속했습니다: __broker__", + "disconnected": "브로커에서 절단되었습니다: __broker__", + "connect-failed": "브로커에 접속에 실패했습니다: __broker__" + }, + "retain": "보존", + "output": { + "buffer": "바이너리 버퍼", + "string": "문자열", + "base64": "Base64문자열", + "auto": "자동판정(문자열혹은 바이너리버퍼)", + "json": "JSON오브젝트" + }, + "true": "한다", + "false": "하지않는다", + "tip": "주석: 토픽이나 QoS를 메세지의 프로퍼티를 사용하여 설정하는 경우에는, 기입하지 않습니다.", + "errors": { + "not-defined": "토픽이 설정되지 않았습니다", + "missing-config": "브로커가 설정되지 않았습니다", + "invalid-topic": "올바르지 않은 토픽이 설정되어 있습니다", + "nonclean-missingclientid": "’세션 초기화’사용시에,클라이언트ID가 설정되지 않았습니다", + "invalid-json-string": "올바르지 않은 JSON문자열", + "invalid-json-parse": "JSON문자열의 퍼스에 실패했습니다" + } + }, + "httpin": { + "label": { + "method": "메소드", + "url": "URL", + "doc": "Docs", + "return": "출력형식", + "upload": "파일 업로드", + "status": "상태코드", + "headers": "헤더", + "other": "그 외", + "paytoqs" : "msg.payload를 쿼리 파라미터에 추가", + "utf8String": "UTF8문자열", + "binaryBuffer": "바이너리 버퍼", + "jsonObject": "JSON오브젝트", + "authType": "종류별", + "bearerToken": "토큰" + }, + "setby": "- msg.method에 정의 -", + "basicauth": "인증을 사용", + "use-tls": "SSL/TLS접속을 유효화", + "tls-config": "TLS설정", + "basic": "Basic인증", + "digest": "Digest인증", + "bearer": "Bearer인증", + "use-proxy": "프록시를 사용", + "proxy-config": "프록시 설정", + "use-proxyauth": "프록시인증을 사용", + "noproxy-hosts": "예외 호스트", + "utf8": "UTF8문자열", + "binary": "바이너리 버퍼", + "json": "JSON오브젝트", + "tip": { + "in": "URL은 상대 패스가 됩니다.", + "res": "이 노드에 보내지는 메세지는, http input노드를 기점으로 해 주세요.", + "req": "주석: JSON의 구문해석에 실패한 경우에는, 취득한 문자열을 그대로 출력합니다." + }, + "httpreq": "http request", + "errors": { + "not-created": "httpNodeRoot에 false가설정되었을 때에는,http-in노드를 작성할 수 없습니다", + "missing-path": "패스가 설정되지 않았습니다", + "no-response": "응답이 없습니다", + "json-error": "JSON의 구분해석 에러", + "no-url": "URL가 설정되지 않았습니다", + "deprecated-call": "권장하지 않는 호출입니다 __method__", + "invalid-transport": "http가 아닌 트랜스포트가 요구되었습니다", + "timeout-isnan": "타임아웃값이 수치가 아니기 때문에 무시합니다", + "timeout-isnegative": "타임아웃값이 음수이기 때문에 무시합니다", + "invalid-payload": "올바르지 않은 페이로드" + }, + "status": { + "requesting": "요구중" + } + }, + "websocket": { + "label": { + "type": "종류", + "path": "패스", + "url": "URL" + }, + "listenon": "대기", + "connectto": "접속", + "sendrec": "송신/수신", + "payload": "페이로드를 송신/수신", + "message": "메세지 전체를 송신/수신", + "tip": { + "path1": "표준으로는 payload 가 websocket에서 송신, 수신된 데이터를 기다립니다. 클라이언트는 JSON형식의 문자열로 메세지전체를 송신, 수신하도록 설정할 수 있습니다.", + "path2": "This path will be relative to ", + "url1": "URL에는 ws:// 또는 wss:// 스키마를 사용하여, 존재하는 websocket리스너를 설정해 주세요.", + "url2": "표준으로는 payload 가 websocket에서 송신,수신될 데이터를 기다립니다.클라이언트는 JSON형식의 문자열로 메세지전체를 송신, 수신하도록 설정할 수 있습니다." + }, + "status": { + "connected": "접속 수 __count__", + "connected_plural": "접속 수 __count__" + }, + "errors": { + "connect-error": "ws접속에서 에러가 발생했습니다: ", + "send-error": "송신중 에러가 발생했습니다: ", + "missing-conf": "서버설정이 부족합니다", + "duplicate-path": "같은 패스에 대해 2개의 WebSocket리스너는 지정할 수 없습니다: __path__" + } + }, + "watch": { + "watch": "watch", + "label": { + "files": "파일", + "recursive": "서브디렉토리를 재귀적으로 감시" + }, + "placeholder": { + "files": "복수의 파일이나 디렉토리는 콤마로 나누어 입력" + }, + "tip": "Windows인 경우, 디렉토리를 나누는 문자로 2개의 백슬래쉬 \\\\ 를 사용해 주세요." + }, + "tcpin": { + "label": { + "type": "종류", + "output": "출력", + "port": "포트", + "host": "호스트", + "payload": "의 페이로드", + "delimited": "나누는 문자", + "close-connection": "메세지를 송신할 때마다 접속을 절단", + "decode-base64": "Base64메세지의 복호", + "server": "서버", + "return": "반환값", + "ms": "밀리초", + "chars": "문자" + }, + "type": { + "listen": "대기", + "connect": "접속", + "reply": "TCP응답" + }, + "output": { + "stream": "스트림", + "single": "단일", + "buffer": "바이너리 버퍼", + "string": "문자열", + "base64": "Base64문자열" + }, + "return": { + "timeout": "지정시간 후", + "character": "지정문자의 수신時", + "number": "지정 개수의 문자열", + "never": "없음 - 접속을 유지", + "immed": "즉시 - 응답을 기다리지 않음" + }, + "status": { + "connecting": "__host__:__port__ 에 접속하고 있습니다", + "connected": "__host__:__port__ 에 접속했습니다", + "listening-port": "포트 __port__ 에서 접속을 기다리고 있습니다", + "stopped-listening": "포트의 대기를 정지했습니다", + "connection-from": "__host__:__port__ 에서 접속되었습니다", + "connection-closed": "__host__:__port__ 에서의 접속이 절단되었습니다", + "connections": "접속 수 __count__", + "connections_plural": "접속 수 __count__" + }, + "errors": { + "connection-lost": "__host__:__port__ 으로의 접속이 소실되었습니다", + "timeout": "포트 __port__ 의 소켓이 타임아웃에 의해 절단되었습니다", + "cannot-listen": "포트 __port__ 의 대기를 할 수 없습니다 에러: __error__", + "error": "에러: __error__", + "socket-error": "__host__:__port__ 에서 소켓의 에러가 발생했습니다", + "no-host": "호스트명 혹은 포트가 설정되지 않았습니다", + "connect-timeout": "접속이 타임아웃 됐습니다", + "connect-fail": "접속에 실패했습니다" + } + }, + "udp": { + "label": { + "listen": "대기", + "onport": "포트", + "using": "종류", + "output": "출력", + "group": "그룹", + "interface": "로컬IP", + "send": "송신", + "toport": "포트", + "address": "어드레스", + "decode-base64": "Base64형식의 페이로드를 복호" + }, + "placeholder": { + "interface": "(임의) 사용할 로컬인터페이스 혹은 어드레스", + "interfaceprompt": "(임의) 사용할 로컬인터페이스 혹은 어드레스", + "address": "수신IP어드레스" + }, + "udpmsgs": "UDP메세지", + "mcmsgs": "멀티캐스트 메세지", + "udpmsg": "UDP메세지", + "bcmsg": "브로드캐스트 메세지", + "mcmsg": "멀티캐스트 메세지", + "output": { + "buffer": "바이너리 버퍼", + "string": "문자열", + "base64": "Base64문자열" + }, + "bind": { + "random": "로컬포트를 랜덤하게 사용", + "local": "로컬포트를 사용", + "target": "지정한포트를 사용" + }, + "tip": { + "in": "주석: 방화벽이 통신을 허가하고 있는지 확인해 주세요.", + "out": "주석: msg.ipmsg.port 를 사용하여 설정하는 경우에는,’어드레스’나 ’포트’를 기입하지 않습니다.", + "port": "이미 포트가 사용중 입니다: " + }, + "status": { + "listener-at": "udp노드가 __host__:__port__ 에서 접속을 기다리고 있습니다", + "mc-group": "udp노드가 그룹 __group__ 에 멀티캐스트 했습니다", + "listener-stopped": "udp노드가 대기를 정지했습니다", + "output-stopped": "udp노드가 출력을 정지했습니다", + "mc-ready": "udp노드는 멀티캐스트 준비가 끝났습니다: __iface__:__outport__ -> __host__:__port__", + "bc-ready": "udp노드는 브로드캐스트 준비가 끝났습니다: __outport__ -> __host__:__port__", + "ready": "udp노드는 준비되었습니다: __outport__ -> __host__:__port__", + "ready-nolocal": "udp노드는 준비되었습니다: __host__:__port__", + "re-use": "udp재이용 소켓: __outport__ -> __host__:__port__" + }, + "errors": { + "access-error": "UDP접속에러 관리자 권한으로 1024미만의 포트번호에 액세스할 필요가 있습니다", + "error": "에러: __error__", + "bad-mcaddress": "멀티캐스트어드레스가 올바르지 않습니다", + "interface": "인터페이스의 IP어드레스를 설정할 필요가 있습니다 ", + "ip-notset": "udp: IP어드레스가 설정되지 않았습니다", + "port-notset": "udp: 포트가 설정되지 않았습니다", + "port-invalid": "udp: 포트번호가 올바르지 않습니다", + "alreadyused": "udp: 이미 __port__번 포트가 사용중 입니다", + "ifnotfound": "udp: 인터페이스 __iface__ 가 없습니다" + } + }, + "switch": { + "switch": "switch", + "label": { + "property": "프로퍼티", + "rule": "조건", + "repair": "메세지열의 보정" + }, + "and": "~", + "checkall": "모든 조건을 적용", + "stopfirst": "처음 맞은 조건으로 종료", + "ignorecase": "대문자, 소문자를 구별하지 않음", + "rules": { + "btwn": "is between", + "cont": "contains", + "regex": "matches regex", + "true": "is true", + "false": "is false", + "null": "is null", + "nnull": "is not null", + "istype": "is of type", + "empty": "is empty", + "nempty": "is not empty", + "head": "head", + "tail": "tail", + "index": "index between", + "exp": "JSONata식", + "else": "그 외" + }, + "errors": { + "invalid-expr": "올바르지 않은 표현: __error__", + "too-many": "switch노드 내에서 보존하고 있는 메세지가 너무 많습니다" + } + }, + "change": { + "label": { + "rules": "룰", + "rule": "룰", + "set": "set __property__", + "change": "change __property__", + "delete": "delete __property__", + "move": "move __property__", + "changeCount": "change: __count__ rules", + "regex": "정규표현를 사용" + }, + "action": { + "set": "값의 대입", + "change": "값의 치환", + "delete": "값의 삭제", + "move": "값의 이동", + "to": "대상의 값", + "search": "검색할 문자열", + "replace": "치환 후의 문자열" + }, + "errors": { + "invalid-from": "조작대상의 프로퍼티가 올바르지 않음: __error__", + "invalid-json": "대상 값의 JSON프로퍼티가 올바르지 않음", + "invalid-expr": "JSONata식이 올바르지 않음: __error__" + } + }, + "range": { + "range": "range", + "label": { + "action": "동작", + "inputrange": "입력값의 범위", + "resultrange": "출력값의 범위", + "from": "최소값", + "to": "최대값", + "roundresult": "작은 수치를 반올림하여 정수치로 변환" + }, + "placeholder": { + "min": "예) 0", + "maxin": "예) 99", + "maxout": "예) 255" + }, + "scale": { + "payload": "msg.payload의 값을 확대/축소", + "limit": "입력값의 범위외의 값을 최소값/최대값으로 해서 확대/축소", + "wrap": "입력값의 범위외의 값을 범위폭으로 나눈 나머지로 해서 확대/축소" + }, + "tip": "주석: 이 노드는, 수치만 다룰 수 있습니다.", + "errors": { + "notnumber": "수치가 아닙니다" + } + }, + "csv": { + "label": { + "columns": "열 이름", + "separator": "나누는 문자", + "c2o": "CSV에서 오브젝트로 변환", + "o2c": "오브젝트에서 CSV로 변환", + "input": "입력", + "skip-s": "처음의", + "skip-e": "행을 무시한다", + "firstrow": "첫번째 행에 열 이름을 포함", + "output": "출력", + "includerow": "첫번째 행을 열 이름으로 함", + "newline": "줄바꿈 코드" + }, + "placeholder": { + "columns": "콤마로 나누어 열 이름을 입력" + }, + "separator": { + "comma": "콤마", + "tab": "탭", + "space": "공백", + "semicolon": "세미콜론", + "colon": "콜론", + "hashtag": "해쉬태그", + "other": "그 외..." + }, + "output": { + "row": "행마다 메세지를 분할", + "array": "배열화 한 1개의 메세지" + }, + "newline": { + "linux": "Linux (\\n)", + "mac": "Mac (\\r)", + "windows": "Windows (\\r\\n)" + }, + "errors": { + "csv_js": "이 노드가 처리할 수 있는 형식은, CSV문자열 혹은 JSON뿐 입니다", + "obj_csv": "오브젝트를 CSV로 변환할 때의 열 이름이 설정되지 않았습니다" + } + }, + "html": { + "label": { + "select": "추출할 요소", + "output": "출력", + "in": "대상:" + }, + "output": { + "html": "요소 내의 HTML", + "text": "요소의 텍스트만", + "attr": "요소의 모든 속성" + }, + "format": { + "single": "배열화 한 1개의 메세지", + "multi": "요소마다의 복수의 메세지" + } + }, + "json": { + "errors": { + "dropped-object": "오브젝트형식이 아닌 페이로드를 무시했습니다", + "dropped": "대응하지 않는 형식의 페이로드를 무시했습니다", + "dropped-error": "페이로드의 변환처리가 실패했습니다", + "schema-error": "JSON스키마 에러", + "schema-error-compile": "JSON스키마에러: 스키마의 컴파일에 실패했습니다" + }, + "label": { + "o2j": "오브젝트에서 JSON로 변환", + "pretty": "JSON문자열 형식", + "action": "동작", + "property": "프로퍼티", + "actions": { + "toggle": "JSON문자열과 오브젝트간의 상호변환", + "str": "항상 JSON문자열로 변환", + "obj": "항상 JavaScript오브젝트로 변환" + } + } + }, + "yaml": { + "errors": { + "dropped-object": "오브젝트형식이 아닌 페이로드를 무시했습니다", + "dropped": "대응하지 않는 형식의 페이로드를 무시했습니다", + "dropped-error": "페이로드의 변환처리에 실패했습니다" + } + }, + "xml": { + "label": { + "represent": "XML태그속성을 다음 프로퍼티명으로 표현", + "prefix": "문자열를 참조하기 위한 접두사", + "advanced": "상세설정", + "x2o": "XML에서 오브젝트로 변환" + }, + "errors": { + "xml_js": "이 노드는, XML형식의 문자열 혹은 JSON만 처리합니다" + } + }, + "rpi-gpio": { + "label": { + "gpiopin": "GPIO", + "selectpin": "단자의 선택", + "resistor": "저항", + "readinitial": "배포나 재시작시에 단자의 초기상태를 불러옴", + "type": "출력형식", + "initpin": "단자의 상태를 초기화", + "debounce": "디바운스", + "freq": "빈도", + "button": "버튼", + "pimouse": "Pi Mouse", + "pikeyboard": "Pi Keyboard", + "left": "Left", + "right": "Right", + "middle": "Middle" + }, + "resistor": { + "none": "없음", + "pullup": "풀 업", + "pulldown": "풀 다운" + }, + "digout": "디지털 출력", + "pwmout": "PWM 출력", + "servo": "서보 출력", + "initpin0": "단자의 초기레벨 - Low (0)", + "initpin1": "단자의 초기레벨 - High (1)", + "left": "좌", + "right": "우", + "middle": "중간", + "any": "모두", + "pinname": "단자", + "alreadyuse": "사용중", + "alreadyset": "설정됨", + "tip": { + "pin": "사용중인 단자: ", + "in": "주석: 입력값은, 0 혹은 1의 수치만 대응하고 있습니다.", + "dig": "주석: ’출력형식’으로 ’디지털출력’을 사용하는 경우, 입력값은 0 혹은 1의 수치일 필요가 있습니다.", + "pwm": "주석: ’출력형식’으로 ’PWM출력’을 사용하는 경우, 입력값은 0~100의 수치일 필요가 있습니다.", + "ser": "주석: 서보 출력용 - 입력값은 0~100 사이일 필요가 있습니다. 50이 중심값입니다." + }, + "types": { + "digout": "디지털 출력", + "input": "입력", + "pullup": "풀 업 입력", + "pulldown": "풀 다운 입력", + "pwmout": "PWM 출력", + "servo": "서보 출력" + }, + "status": { + "stopped": "정지", + "closed": "절단", + "not-running": "정지중", + "not-available": "이용불가", + "na": "N/A : __value__" + }, + "errors": { + "ignorenode": "Raspberry Pi고유의 노드를 무시했습니다", + "version": "버젼커맨드에 실패했습니다", + "sawpitype": "Saw Pi Type", + "libnotfound": "RPi.GPIO python라이브러리를 발견하지 못했습니다", + "alreadyset": "GPIO단자 __pin__ 은 이미 출력형식이 설정되어 있습니다: __type__", + "invalidpin": "GPIO단자가 올바르지 않습니다", + "invalidinput": "입력이 올바르지 않습니다", + "needtobeexecutable": "__command__ 은 실행가능상태일 필요가 있습니다 ", + "mustbeexecutable": "nrgpio 은 실행가능상태일 필요가 있습니다 ", + "commandnotfound": "nrgpio 커맨드를 찾을수 없습니다", + "commandnotexecutable": "nrgpio 커맨드가 실행가능상태가 아닙니다", + "error": "에러: __error__", + "pythoncommandnotfound": "nrpgio python 커맨드가 실행되지 않았습니다" + } + }, + "file": { + "label": { + "filename": "파일명", + "action": "동작", + "addnewline": "메세지의 입력마다 줄바꿈을 추가", + "createdir": "디렉토리가 존재하지 않는 경우에 작성", + "outputas": "출력형식", + "breakchunks": "청크로 분할", + "breaklines": "행으로 분할", + "filelabel": "file", + "sendError": "에러메세지를 송신(호환모드)", + "deletelabel": "delete __file__", + "utf8String": "UTF8문자열", + "binaryBuffer": "바이너리 버퍼" + }, + "action": { + "append": "파일에 추가", + "overwrite": "파일을 덮어쓰기", + "delete": "파일을 삭제" + }, + "output": { + "utf8": "문자열", + "buffer": "바이너리 버퍼", + "lines": "행 마다의 메세지", + "stream": "버퍼의 스트림" + }, + "status": { + "wrotefile": "파일에 작성했습니다: __file__", + "deletedfile": "파일을 삭제했습니다: __file__", + "appendedfile": "파일에 추가했습니다: __file__" + }, + "encoding": { + "none": "기본값", + "native": "네이티브", + "unicode": "UNICODE", + "japanese": "일본", + "chinese": "중국", + "korean": "한국", + "taiwan": "대만/홍콩", + "windows": "Windows코드 페이지", + "iso": "ISO코드 페이지", + "ibm": "IBM코드 페이지", + "mac": "Mac코드 페이지", + "koi8": "KOI8코드 페이지", + "misc": "그 외" + }, + "errors": { + "nofilename": "파일명이 설정되지 않았습니다", + "invaliddelete": "경고: 삭제가 무효합니다. 설정 다이얼로그에서 특정 삭제설정을 사용해 주세요", + "deletefail": "파일의 삭제처리에 실패했습니다: __error__", + "writefail": "파일의 작성처리에 실패했습니다: __error__", + "appendfail": "파일의 추가처리에 실패했습니다: __error__", + "createfail": "파일의 작성처리에 실패했습니다: __error__" + }, + "tip": "주석: ’파일명’에 풀패스를 설정하지 않는 경우에는, Node-RED프로세스 실행디렉토리에서의 상대패스가 됩니다." + }, + "split": { + "split": "split", + "intro": "타입에 따라 msg.payload 를 분할:", + "object": "오브젝트", + "objectSend": "각 key/value쌍의 메세지를 송신", + "strBuff": "문자열 / 버퍼", + "array": "배열", + "splitUsing": "분할", + "splitLength": "고정장", + "stream": "메세지의 스트림로써 처리", + "addname": " key의 복사처" + }, + "join": { + "join": "join", + "mode": { + "mode": "동작", + "auto": "자동", + "merge": "열의 결합", + "reduce": "열의 집약", + "custom": "수동" + }, + "combine": "결합", + "create": "출력", + "type": { + "string": "문자열", + "array": "배열", + "buffer": "버퍼", + "object": "key/value오브젝트", + "merged": "결합 오브젝트" + }, + "using": "사용할 값", + "key": "를 키로써 사용", + "joinedUsing": "連結문자", + "send": "메세지송신:", + "afterCount": "지정수의 메세지파트를 수신 후", + "count": "합계값", + "subsequent": "후속 메세지마다", + "afterTimeout": "첫 메세지수신부터 타임아웃 후", + "seconds": "초", + "complete": "msg.complete 프로퍼티가 설정된 메세지수신 후", + "tip": "해당 모드에서는, 이 노드가 split 노드와 짝이 되거나, msg.parts 프로퍼티가 설정된 메세지를 수신하는 것을 전제로 합니다.", + "too-many": "join노드내부에서 보존하고 있는 메세지가 너무 많습니다", + "merge": { + "topics-label": "대상토픽", + "topics": "토픽", + "topic": "토픽", + "on-change": "신규토픽을 받으면 메세지를 송신한다" + }, + "reduce": { + "exp": "집약식", + "exp-value": "식", + "init": "초기값", + "right": "평가를 역순으로 행함 (마지막에서 처음으로)", + "fixup": "최종조정식" + }, + "errors": { + "invalid-expr": "JSONata식이 올바르지 않음: __error__" + } + }, + "sort": { + "sort": "sort", + "target": "대상", + "seq": "메세지열", + "key": "키", + "elem": "요소의 값", + "order": "순서", + "ascending": "오름차순", + "descending": "내림차순", + "as-number": "수치로써 비교", + "invalid-exp": "sort노드에서 올바르지 않은 JSONata식이 지정되었습니다: __message__", + "too-many": "sort노드의 처리되지 않은 메세지 수가 허용수를 넘었습니다", + "clear": "sort노드의 처리되지 않는 메세지를 파기했습니다" + }, + "batch": { + "batch": "batch", + "mode": { + "label": "모드", + "num-msgs": "메세지수로 그룹화", + "interval": "시간간격으로 그룹화", + "concat": "열의 결합" + }, + "count": { + "label": "메세지수", + "overlap": "오버랩", + "count": "수", + "invalid": "메세지수와 오버랩수가 올바르지 않음" + }, + "interval": { + "label": "시간간격", + "seconds": "초", + "empty": "메세지를 수신하지 않는 경우, 빈 메세지를 송신" + }, + "concat": { + "topics-label": "토픽", + "topic": "토픽" + }, + "too-many": "batch노드 내에서 보존하고 있는 메세지가 너무 많습니다", + "unexpected": "상정할 수 없는 모드", + "no-parts": "메세지에 parts프로퍼티가 없습니다" + } +} diff --git a/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-CSV.html b/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-CSV.html new file mode 100644 index 000000000..728637559 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-CSV.html @@ -0,0 +1,44 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-HTML.html b/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-HTML.html new file mode 100644 index 000000000..6988c1271 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-HTML.html @@ -0,0 +1,33 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-JSON.html b/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-JSON.html new file mode 100644 index 000000000..05bd29541 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-JSON.html @@ -0,0 +1,43 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-XML.html b/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-XML.html new file mode 100644 index 000000000..1156a3a0c --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-XML.html @@ -0,0 +1,49 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-YAML.html b/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-YAML.html new file mode 100644 index 000000000..8af9321f4 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-YAML.html @@ -0,0 +1,34 @@ + + + diff --git a/packages/node_modules/@node-red/nodes/locales/ko/storage/50-file.html b/packages/node_modules/@node-red/nodes/locales/ko/storage/50-file.html new file mode 100644 index 000000000..4f22308e9 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/locales/ko/storage/50-file.html @@ -0,0 +1,59 @@ + + + + + From 543519d055955f01c0e2315879beeb6ce5cd1204 Mon Sep 17 00:00:00 2001 From: Hiroki Uchikawa Date: Wed, 9 Jan 2019 18:13:33 +0900 Subject: [PATCH 02/11] Add test cases to ensure context API routes are correctly mounted. --- .../editor-api/lib/admin/index_spec.js | 223 ++++++++++++++---- 1 file changed, 180 insertions(+), 43 deletions(-) diff --git a/test/unit/@node-red/editor-api/lib/admin/index_spec.js b/test/unit/@node-red/editor-api/lib/admin/index_spec.js index c20df8d1b..ead5f274a 100644 --- a/test/unit/@node-red/editor-api/lib/admin/index_spec.js +++ b/test/unit/@node-red/editor-api/lib/admin/index_spec.js @@ -26,6 +26,7 @@ var auth = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth"); var nodes = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/nodes"); var flows = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/flows"); var flow = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/flow"); +var context = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/context"); /** * Ensure all API routes are correctly mounted, with the expected permissions checks @@ -34,8 +35,8 @@ describe("api/admin/index", function() { describe("Ensure all API routes are correctly mounted, with the expected permissions checks", function() { var app; var mockList = [ - flows,flow,nodes - ] + flows,flow,nodes,context + ]; var permissionChecks = {}; var lastRequest; var stubApp = function(req,res,next) { @@ -50,7 +51,7 @@ describe("api/admin/index", function() { return function(req,res,next) { permissionChecks[permission] = (permissionChecks[permission]||0)+1; next(); - } + }; }); sinon.stub(flows,"get",stubApp); @@ -70,6 +71,9 @@ describe("api/admin/index", function() { sinon.stub(nodes,"putSet",stubApp); sinon.stub(nodes,"getModuleCatalog",stubApp); sinon.stub(nodes,"getModuleCatalogs",stubApp); + + sinon.stub(context,"get",stubApp); + sinon.stub(context,"delete",stubApp); }); after(function() { mockList.forEach(function(m) { @@ -92,15 +96,19 @@ describe("api/admin/index", function() { nodes.putSet.restore(); nodes.getModuleCatalog.restore(); nodes.getModuleCatalogs.restore(); + context.get.restore(); + context.delete.restore(); }); before(function() { app = adminApi.init({}); }); + beforeEach(function() { permissionChecks = {}; - }) + }); + it('GET /flows', function(done) { request(app).get("/flows").expect(200).end(function(err,res) { if (err) { @@ -108,8 +116,9 @@ describe("api/admin/index", function() { } permissionChecks.should.have.property('flows.read',1); done(); - }) + }); }); + it('POST /flows', function(done) { request(app).post("/flows").expect(200).end(function(err,res) { if (err) { @@ -117,7 +126,7 @@ describe("api/admin/index", function() { } permissionChecks.should.have.property('flows.write',1); done(); - }) + }); }); it('GET /flow/1234', function(done) { @@ -126,10 +135,11 @@ describe("api/admin/index", function() { return done(err); } permissionChecks.should.have.property('flows.read',1); - lastRequest.params.should.have.property('id','1234') + lastRequest.params.should.have.property('id','1234'); done(); - }) + }); }); + it('POST /flow', function(done) { request(app).post("/flow").expect(200).end(function(err,res) { if (err) { @@ -137,27 +147,29 @@ describe("api/admin/index", function() { } permissionChecks.should.have.property('flows.write',1); done(); - }) + }); }); + it('DELETE /flow/1234', function(done) { request(app).del("/flow/1234").expect(200).end(function(err,res) { if (err) { return done(err); } permissionChecks.should.have.property('flows.write',1); - lastRequest.params.should.have.property('id','1234') + lastRequest.params.should.have.property('id','1234'); done(); - }) + }); }); + it('PUT /flow/1234', function(done) { request(app).put("/flow/1234").expect(200).end(function(err,res) { if (err) { return done(err); } permissionChecks.should.have.property('flows.write',1); - lastRequest.params.should.have.property('id','1234') + lastRequest.params.should.have.property('id','1234'); done(); - }) + }); }); it('GET /nodes', function(done) { @@ -167,8 +179,9 @@ describe("api/admin/index", function() { } permissionChecks.should.have.property('nodes.read',1); done(); - }) + }); }); + it('POST /nodes', function(done) { request(app).post("/nodes").expect(200).end(function(err,res) { if (err) { @@ -176,27 +189,29 @@ describe("api/admin/index", function() { } permissionChecks.should.have.property('nodes.write',1); done(); - }) + }); }); + it('GET /nodes/module', function(done) { request(app).get("/nodes/module").expect(200).end(function(err,res) { if (err) { return done(err); } permissionChecks.should.have.property('nodes.read',1); - lastRequest.params.should.have.property(0,'module') + lastRequest.params.should.have.property(0,'module'); done(); - }) + }); }); + it('GET /nodes/@scope/module', function(done) { request(app).get("/nodes/@scope/module").expect(200).end(function(err,res) { if (err) { return done(err); } permissionChecks.should.have.property('nodes.read',1); - lastRequest.params.should.have.property(0,'@scope/module') + lastRequest.params.should.have.property(0,'@scope/module'); done(); - }) + }); }); it('PUT /nodes/module', function(done) { @@ -205,19 +220,20 @@ describe("api/admin/index", function() { return done(err); } permissionChecks.should.have.property('nodes.write',1); - lastRequest.params.should.have.property(0,'module') + lastRequest.params.should.have.property(0,'module'); done(); - }) + }); }); + it('PUT /nodes/@scope/module', function(done) { request(app).put("/nodes/@scope/module").expect(200).end(function(err,res) { if (err) { return done(err); } permissionChecks.should.have.property('nodes.write',1); - lastRequest.params.should.have.property(0,'@scope/module') + lastRequest.params.should.have.property(0,'@scope/module'); done(); - }) + }); }); it('DELETE /nodes/module', function(done) { @@ -226,19 +242,20 @@ describe("api/admin/index", function() { return done(err); } permissionChecks.should.have.property('nodes.write',1); - lastRequest.params.should.have.property(0,'module') + lastRequest.params.should.have.property(0,'module'); done(); - }) + }); }); + it('DELETE /nodes/@scope/module', function(done) { request(app).del("/nodes/@scope/module").expect(200).end(function(err,res) { if (err) { return done(err); } permissionChecks.should.have.property('nodes.write',1); - lastRequest.params.should.have.property(0,'@scope/module') + lastRequest.params.should.have.property(0,'@scope/module'); done(); - }) + }); }); it('GET /nodes/module/set', function(done) { @@ -247,21 +264,22 @@ describe("api/admin/index", function() { return done(err); } permissionChecks.should.have.property('nodes.read',1); - lastRequest.params.should.have.property(0,'module') - lastRequest.params.should.have.property(2,'set') + lastRequest.params.should.have.property(0,'module'); + lastRequest.params.should.have.property(2,'set'); done(); - }) + }); }); + it('GET /nodes/@scope/module/set', function(done) { request(app).get("/nodes/@scope/module/set").expect(200).end(function(err,res) { if (err) { return done(err); } permissionChecks.should.have.property('nodes.read',1); - lastRequest.params.should.have.property(0,'@scope/module') - lastRequest.params.should.have.property(2,'set') + lastRequest.params.should.have.property(0,'@scope/module'); + lastRequest.params.should.have.property(2,'set'); done(); - }) + }); }); it('PUT /nodes/module/set', function(done) { @@ -270,21 +288,22 @@ describe("api/admin/index", function() { return done(err); } permissionChecks.should.have.property('nodes.write',1); - lastRequest.params.should.have.property(0,'module') - lastRequest.params.should.have.property(2,'set') + lastRequest.params.should.have.property(0,'module'); + lastRequest.params.should.have.property(2,'set'); done(); - }) + }); }); + it('PUT /nodes/@scope/module/set', function(done) { request(app).put("/nodes/@scope/module/set").expect(200).end(function(err,res) { if (err) { return done(err); } permissionChecks.should.have.property('nodes.write',1); - lastRequest.params.should.have.property(0,'@scope/module') - lastRequest.params.should.have.property(2,'set') + lastRequest.params.should.have.property(0,'@scope/module'); + lastRequest.params.should.have.property(2,'set'); done(); - }) + }); }); it('GET /nodes/messages', function(done) { @@ -293,10 +312,10 @@ describe("api/admin/index", function() { return done(err); } permissionChecks.should.have.property('nodes.read',1); - done(); - }) + }); }); + it('GET /nodes/module/set/messages', function(done) { request(app).get("/nodes/module/set/messages").expect(200).end(function(err,res) { if (err) { @@ -305,8 +324,9 @@ describe("api/admin/index", function() { permissionChecks.should.have.property('nodes.read',1); lastRequest.params.should.have.property(0,'module/set'); done(); - }) + }); }); + it('GET /nodes/@scope/module/set/messages', function(done) { request(app).get("/nodes/@scope/module/set/messages").expect(200).end(function(err,res) { if (err) { @@ -315,7 +335,124 @@ describe("api/admin/index", function() { permissionChecks.should.have.property('nodes.read',1); lastRequest.params.should.have.property(0,'@scope/module/set'); done(); - }) + }); + }); + + it('GET /context/global', function(done) { + request(app).get("/context/global").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','global'); + done(); + }); + }); + + it('GET /context/global/key?store=memory', function(done) { + request(app).get("/context/global/key?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','global'); + lastRequest.params.should.have.property(0,'key'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); + }); + + it('GET /context/flow/1234', function(done) { + request(app).get("/context/flow/1234").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','flow'); + lastRequest.params.should.have.property('id','1234'); + done(); + }); + }); + + it('GET /context/flow/1234/key?store=memory', function(done) { + request(app).get("/context/flow/1234/key?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','flow'); + lastRequest.params.should.have.property('id','1234'); + lastRequest.params.should.have.property(0,'key'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); + }); + + it('GET /context/node/5678', function(done) { + request(app).get("/context/node/5678").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','node'); + lastRequest.params.should.have.property('id','5678'); + done(); + }); + }); + + it('GET /context/node/5678/foo?store=memory', function(done) { + request(app).get("/context/node/5678/foo?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','node'); + lastRequest.params.should.have.property('id','5678'); + lastRequest.params.should.have.property(0,'foo'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); + }); + + it('DELETE /context/global/key?store=memory', function(done) { + request(app).del("/context/global/key?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.write',1); + lastRequest.params.should.have.property('scope','global'); + lastRequest.params.should.have.property(0,'key'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); + }); + + it('DELETE /context/flow/1234/key?store=memory', function(done) { + request(app).del("/context/flow/1234/key?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.write',1); + lastRequest.params.should.have.property('scope','flow'); + lastRequest.params.should.have.property('id','1234'); + lastRequest.params.should.have.property(0,'key'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); + }); + + it('DELETE /context/node/5678/foo?store=memory', function(done) { + request(app).del("/context/node/5678/foo?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.write',1); + lastRequest.params.should.have.property('scope','node'); + lastRequest.params.should.have.property('id','5678'); + lastRequest.params.should.have.property(0,'foo'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); }); }); }); From f98f4085bfde0c6114cb1c873233b3627c38b229 Mon Sep 17 00:00:00 2001 From: Hiroki Uchikawa Date: Fri, 18 Jan 2019 18:55:54 +0900 Subject: [PATCH 03/11] Add test cases for context admin API --- .../editor-api/lib/admin/context_spec.js | 359 +++++++++--------- 1 file changed, 176 insertions(+), 183 deletions(-) diff --git a/test/unit/@node-red/editor-api/lib/admin/context_spec.js b/test/unit/@node-red/editor-api/lib/admin/context_spec.js index 979c3e6eb..a9dc0f70d 100644 --- a/test/unit/@node-red/editor-api/lib/admin/context_spec.js +++ b/test/unit/@node-red/editor-api/lib/admin/context_spec.js @@ -19,22 +19,15 @@ var request = require('supertest'); var express = require('express'); var bodyParser = require('body-parser'); var sinon = require('sinon'); -var when = require('when'); var NR_TEST_UTILS = require("nr-test-utils"); var context = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/context"); -// var Context = require("../../../../red/runtime/nodes/context"); -// var Util = require("../../../../red/runtime/util"); -describe("api/admin/context", function() { - it.skip("NEEDS TESTS WRITING",function() {}); -}); -/* +describe("api/admin/context", function () { var app = undefined; - before(function (done) { - var node_context = undefined; + before(function () { app = express(); app.use(bodyParser.json()); app.get("/context/:scope(global)", context.get); @@ -42,196 +35,196 @@ describe("api/admin/context", function() { app.get("/context/:scope(node|flow)/:id", context.get); app.get("/context/:scope(node|flow)/:id/*", context.get); - context.init({ - settings: { - }, - log:{warn:function(){},_:function(){},audit:function(){}}, - nodes: { - listContextStores: Context.listStores, - getContext: Context.get, - getNode: function(id) { - if (id === 'NID') { - return { - id: 'NID', - context: function () { - return node_context; - } - }; - } - return null; - } - }, - util: Util - }); - - Context.init({ - contextStorage: { - memory0: { - module: "memory" - }, - memory1: { - module: "memory" - } - } - }); - Context.load().then(function () { - var ctx = Context.get("NID", "FID"); - node_context = ctx; - ctx.set("foo", "n_v00", "memory0"); - ctx.set("bar", "n_v01", "memory0"); - ctx.set("baz", "n_v10", "memory1"); - ctx.set("bar", "n_v11", "memory1"); - ctx.flow.set("foo", "f_v00", "memory0"); - ctx.flow.set("bar", "f_v01", "memory0"); - ctx.flow.set("baz", "f_v10", "memory1"); - ctx.flow.set("bar", "f_v11", "memory1"); - ctx.global.set("foo", "g_v00", "memory0"); - ctx.global.set("bar", "g_v01", "memory0"); - ctx.global.set("baz", "g_v10", "memory1"); - ctx.global.set("bar", "g_v11", "memory1"); - done(); - }); - + app.delete("/context/:scope(global)/*", context.delete); + app.delete("/context/:scope(node|flow)/:id/*", context.delete); }); - after(function () { - Context.clean({allNodes:{}}); - Context.close(); - }); + describe("get", function () { + var gContext = { + default: { abc: { msg: '111', format: 'number' } }, + file: { abc: { msg: '222', format: 'number' } } + }; + var fContext = { + default: { bool: { msg: 'true', format: 'boolean' } }, + file: { string: { msg: 'aaaa', format: 'string[7]' } } + }; + var nContext = { msg: "1", format: "number" }; + var stub = sinon.stub(); - function check_mem(body, mem, name, val) { - var mem0 = body[mem]; - mem0.should.have.property(name); - mem0[name].should.deepEqual(val); - } - - function check_scope(scope, prefix, id) { - describe('# '+scope, function () { - var xid = id ? ("/"+id) : ""; - - it('should return '+scope+' contexts', function (done) { - request(app) - .get('/context/'+scope+xid) - .set('Accept', 'application/json') - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } - var body = res.body; - body.should.have.key('memory0', 'memory1'); - check_mem(body, 'memory0', - 'foo', {msg:prefix+'_v00', format:'string[5]'}); - check_mem(body, 'memory0', - 'bar', {msg:prefix+'_v01', format:'string[5]'}); - check_mem(body, 'memory1', - 'baz', {msg:prefix+'_v10', format:'string[5]'}); - check_mem(body, 'memory1', - 'bar', {msg:prefix+'_v11', format:'string[5]'}); - done(); - }); - }); - - it('should return a value from default '+scope+' context', function (done) { - request(app) - .get('/context/'+scope+xid+'/foo') - .set('Accept', 'application/json') - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } - var body = res.body; - body.should.deepEqual({msg: prefix+'_v00', format: 'string[5]'}); - done(); - }); - }); - - it('should return a value from specified '+scope+' context', function (done) { - request(app) - .get('/context/'+scope+xid+'/bar?store=memory1') - .set('Accept', 'application/json') - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } - var body = res.body; - body.should.deepEqual({msg: prefix+'_v11', format: 'string[5]', store: 'memory1'}); - done(); - }); - }); - - it('should return specified '+scope+' store', function (done) { - request(app) - .get('/context/'+scope+xid+'?store=memory1') - .set('Accept', 'application/json') - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } - var body = res.body; - body.should.deepEqual({ - memory1: { - baz: { msg: prefix+'_v10', format: 'string[5]' }, - bar: { msg: prefix+'_v11', format: 'string[5]' } - } - }); - done(); - }); - }); - - it('should return undefined for unknown key of default '+scope+' store', function (done) { - request(app) - .get('/context/'+scope+xid+'/unknown') - .set('Accept', 'application/json') - .expect(200) - .end(function (err, res) { - if (err) { - return done(err); - } - var body = res.body; - body.should.deepEqual({msg:'(undefined)', format:'undefined'}); - done(); - - }); - }); - - it('should cause error for unknown '+scope+' store', function (done) { - request(app) - .get('/context/'+scope+xid+'?store=unknown') - .set('Accept', 'application/json') - .expect(200) - .end(function (err, res) { - if (err) { - return done(); - } - done("unexpected"); - }); + before(function () { + context.init({ + context: { + getValue: stub + } }); }); - } - check_scope("global", "g", undefined); - check_scope("node", "n", "NID"); - check_scope("flow", "f", "FID"); + afterEach(function () { + stub.reset(); + }); - describe("# errors", function () { - it('should cause error for unknown scope', function (done) { + it('should call context.getValue to get global contexts', function (done) { + stub.returns(Promise.resolve(gContext)); request(app) - .get('/context/scope') + .get('/context/global') .set('Accept', 'application/json') .expect(200) .end(function (err, res) { if (err) { - return done(); + return done(err); } - done("unexpected"); + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'global'); + stub.args[0][0].should.have.property('id', undefined); + stub.args[0][0].should.have.property('key', undefined); + stub.args[0][0].should.have.property('store', undefined); + var body = res.body; + body.should.eql(gContext); + done(); }); }); + it('should call context.getValue to get flow contexts', function (done) { + stub.returns(Promise.resolve(fContext)); + request(app) + .get('/context/flow/1234/') + .set('Accept', 'application/json') + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'flow'); + stub.args[0][0].should.have.property('id', '1234'); + stub.args[0][0].should.have.property('key', undefined); + stub.args[0][0].should.have.property('store', undefined); + var body = res.body; + body.should.eql(fContext); + done(); + }); + }); + + it('should call context.getValue to get a node context', function (done) { + stub.returns(Promise.resolve(nContext)); + request(app) + .get('/context/node/5678/foo?store=file') + .set('Accept', 'application/json') + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'node'); + stub.args[0][0].should.have.property('id', '5678'); + stub.args[0][0].should.have.property('key', 'foo'); + stub.args[0][0].should.have.property('store', 'file'); + var body = res.body; + body.should.eql(nContext); + done(); + }); + }); + + it('should handle error which context.getValue causes', function (done) { + stub.returns(Promise.reject('error')); + request(app) + .get('/context/global') + .set('Accept', 'application/json') + .expect(400) + .end(function (err, res) { + if (err) { + return done(err); + } + res.body.should.has.a.property('code', 'unexpected_error'); + res.body.should.has.a.property('message', 'error'); + done(); + }); + }); }); + describe("delete", function () { + var stub = sinon.stub(); + + before(function () { + context.init({ + context: { + delete: stub + } + }); + }); + + afterEach(function () { + stub.reset(); + }); + + it('should call context.delete to delete a global context', function (done) { + stub.returns(Promise.resolve()); + request(app) + .delete('/context/global/abc?store=default') + .expect(204) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'global'); + stub.args[0][0].should.have.property('id', undefined); + stub.args[0][0].should.have.property('key', 'abc'); + stub.args[0][0].should.have.property('store', 'default'); + done(); + }); + }); + + it('should call context.delete to delete a flow context', function (done) { + stub.returns(Promise.resolve()); + request(app) + .delete('/context/flow/1234/abc?store=file') + .expect(204) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'flow'); + stub.args[0][0].should.have.property('id', '1234'); + stub.args[0][0].should.have.property('key', 'abc'); + stub.args[0][0].should.have.property('store', 'file'); + done(); + }); + }); + + it('should call context.delete to delete a node context', function (done) { + stub.returns(Promise.resolve()); + request(app) + .delete('/context/node/5678/foo?store=file') + .expect(204) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'node'); + stub.args[0][0].should.have.property('id', '5678'); + stub.args[0][0].should.have.property('key', 'foo'); + stub.args[0][0].should.have.property('store', 'file'); + done(); + }); + }); + + it('should handle error which context.delete causes', function (done) { + stub.returns(Promise.reject('error')); + request(app) + .delete('/context/global/abc?store=default') + .expect(400) + .end(function (err, res) { + if (err) { + return done(err); + } + res.body.should.has.a.property('code', 'unexpected_error'); + res.body.should.has.a.property('message', 'error'); + done(); + }); + }); + }); }); -*/ From f7c87e26db99a5a210895f766b8b5f7230afab95 Mon Sep 17 00:00:00 2001 From: Hiroki Uchikawa Date: Fri, 18 Jan 2019 19:53:15 +0900 Subject: [PATCH 04/11] Add test cases for context runtime API --- .../@node-red/runtime/lib/api/context_spec.js | 260 ++++++++++++++---- 1 file changed, 200 insertions(+), 60 deletions(-) diff --git a/test/unit/@node-red/runtime/lib/api/context_spec.js b/test/unit/@node-red/runtime/lib/api/context_spec.js index db604f2a9..bf23e9cc6 100644 --- a/test/unit/@node-red/runtime/lib/api/context_spec.js +++ b/test/unit/@node-red/runtime/lib/api/context_spec.js @@ -19,7 +19,7 @@ var should = require("should"); var sinon = require("sinon"); var NR_TEST_UTILS = require("nr-test-utils"); -var context = NR_TEST_UTILS.require("@node-red/runtime/lib/api/context") +var context = NR_TEST_UTILS.require("@node-red/runtime/lib/api/context"); var mockLog = () => ({ log: sinon.stub(), @@ -29,8 +29,8 @@ var mockLog = () => ({ info: sinon.stub(), metric: sinon.stub(), audit: sinon.stub(), - _: function() { return "abc"} -}) + _: function() { return "abc";} +}); var mockContext = function(contents) { return { @@ -41,51 +41,65 @@ var mockContext = function(contents) { callback(null,undefined); } }, - keys: function(store,callback) { + set: function (key, value, store, callback) { if (contents.hasOwnProperty(store)) { - callback(null,Object.keys(contents[store])); + if (!value) { + delete contents[store][key]; + callback(null); + } + } else { + callback("err store"); + } + }, + keys: function (store, callback) { + if (contents.hasOwnProperty(store)) { + callback(null, Object.keys(contents[store])); } else { callback("err store"); } } - } -} + }; +}; + describe("runtime-api/context", function() { - describe("getValue", function() { - var contexts = { - global: mockContext({ default: {abc:111}, file: {abc:222}}), - flow1: mockContext({ default: {abc:333}, file: {abc:444}}) - } - var nodeContext = mockContext({ default: {abc:555}, file: {abc:666}}) + var globalContext, flowContext, nodeContext, contexts; - beforeEach(function() { - context.init({ - nodes: { - listContextStores: function() { - return { default: 'default', stores: [ 'default', 'file' ] } - }, - getContext: function(id) { - return contexts[id] - }, - getNode: function(id) { - if (id === 'known') { - return { - context: function() { return nodeContext } - } - } else { - return null; - } - } + beforeEach(function() { + globalContext = { default: { abc: 111 }, file: { abc: 222 } }; + flowContext = { default: { abc: 333 }, file: { abc: 444 } }; + nodeContext = { default: { abc: 555 }, file: { abc: 666 } }; + contexts = { + global: mockContext(globalContext), + flow1: mockContext(flowContext) + }; + context.init({ + nodes: { + listContextStores: function() { + return { default: 'default', stores: [ 'default', 'file' ] }; }, - settings: { - functionGlobalContext: { - fgc:1234 - } + getContext: function(id) { + return contexts[id]; }, - log: mockLog() - }) + getNode: function(id) { + if (id === 'known') { + return { + context: function() { return mockContext(nodeContext); } + }; + } else { + return null; + } + } + }, + settings: { + functionGlobalContext: { + fgc:1234 + } + }, + log: mockLog() }); + }); + describe("getValue", function() { it('gets global value of default store', function() { return context.getValue({ scope: 'global', @@ -95,8 +109,9 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','111'); result.should.have.property('format','number'); - }) - }) + }); + }); + it('gets global value of specified store', function() { return context.getValue({ scope: 'global', @@ -106,8 +121,9 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','222'); result.should.have.property('format','number'); - }) - }) + }); + }); + it('gets flow value of default store', function() { return context.getValue({ scope: 'flow', @@ -117,8 +133,9 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','333'); result.should.have.property('format','number'); - }) - }) + }); + }); + it('gets flow value of specified store', function() { return context.getValue({ scope: 'flow', @@ -128,8 +145,9 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','444'); result.should.have.property('format','number'); - }) - }) + }); + }); + it('gets node value of default store', function() { return context.getValue({ scope: 'node', @@ -139,8 +157,9 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','555'); result.should.have.property('format','number'); - }) - }) + }); + }); + it('gets node value of specified store', function() { return context.getValue({ scope: 'node', @@ -150,8 +169,8 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','666'); result.should.have.property('format','number'); - }) - }) + }); + }); it('404s for unknown store', function(done) { context.getValue({ @@ -162,12 +181,11 @@ describe("runtime-api/context", function() { }).then(function(result) { done("getValue for unknown store should not resolve"); }).catch(function(err) { - err.should.have.property('code','not_found') + err.should.have.property('code','not_found'); err.should.have.property('status',404); done(); - }) - }) - + }); + }); it('gets all global value properties', function() { return context.getValue({ @@ -180,8 +198,9 @@ describe("runtime-api/context", function() { default: { abc: { msg: '111', format: 'number' } }, file: { abc: { msg: '222', format: 'number' } } }); - }) - }) + }); + }); + it('gets all flow value properties', function() { return context.getValue({ scope: 'flow', @@ -193,8 +212,9 @@ describe("runtime-api/context", function() { default: { abc: { msg: '333', format: 'number' } }, file: { abc: { msg: '444', format: 'number' } } }); - }) - }) + }); + }); + it('gets all node value properties', function() { return context.getValue({ scope: 'node', @@ -206,8 +226,128 @@ describe("runtime-api/context", function() { default: { abc: { msg: '555', format: 'number' } }, file: { abc: { msg: '666', format: 'number' } } }); - }) - }) + }); + }); - }) + it('gets empty object when specified context doesn\'t exist', function() { + return context.getValue({ + scope: 'node', + id: 'non-existent', + store: 'file', + key: 'abc' + }).then(function(result) { + result.should.be.an.Object(); + result.should.be.empty(); + }); + }); + }); + + describe("delete", function () { + it('deletes global value of default store', function () { + return context.delete({ + scope: 'global', + id: undefined, + store: undefined, // use default + key: 'abc' + }).then(function () { + globalContext.should.eql({ + default: {}, file: { abc: 222 } + }); + }); + }); + + it('deletes global value of specified store', function () { + return context.delete({ + scope: 'global', + id: undefined, + store: 'file', + key: 'abc' + }).then(function () { + globalContext.should.eql({ + default: { abc: 111 }, file: {} + }); + }); + }); + + it('deletes flow value of default store', function () { + return context.delete({ + scope: 'flow', + id: 'flow1', + store: undefined, // use default + key: 'abc' + }).then(function () { + flowContext.should.eql({ + default: {}, file: { abc: 444 } + }); + }); + }); + + it('deletes flow value of specified store', function () { + return context.delete({ + scope: 'flow', + id: 'flow1', + store: 'file', + key: 'abc' + }).then(function () { + flowContext.should.eql({ + default: { abc: 333 }, file: {} + }); + }); + }); + + it('deletes node value of default store', function () { + return context.delete({ + scope: 'node', + id: 'known', + store: undefined, // use default + key: 'abc' + }).then(function () { + nodeContext.should.eql({ + default: {}, file: { abc: 666 } + }); + }); + }); + + it('deletes node value of specified store', function () { + return context.delete({ + scope: 'node', + id: 'known', + store: 'file', + key: 'abc' + }).then(function () { + nodeContext.should.eql({ + default: { abc: 555 }, file: {} + }); + }); + }); + + it('does nothing when specified context doesn\'t exist', function() { + return context.delete({ + scope: 'node', + id: 'non-existent', + store: 'file', + key: 'abc' + }).then(function(result) { + should.not.exist(result); + nodeContext.should.eql({ + default: { abc: 555 }, file: { abc: 666 } + }); + }); + }); + + it('404s for unknown store', function (done) { + context.delete({ + scope: 'global', + id: undefined, + store: 'unknown', + key: 'abc' + }).then(function () { + done("delete for unknown store should not resolve"); + }).catch(function (err) { + err.should.have.property('code', 'not_found'); + err.should.have.property('status', 404); + done(); + }); + }); + }); }); From 5d9fd6dc3ba16c7c13be1ae7922939cfcbdd5e40 Mon Sep 17 00:00:00 2001 From: Andrei Ochmat <38989199+aiot-maker@users.noreply.github.com> Date: Wed, 27 Mar 2019 15:45:28 -0300 Subject: [PATCH 05/11] Add explanation to the help text on the new feature to build query string from msg.payload --- .../@node-red/nodes/locales/en-US/io/21-httprequest.html | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/io/21-httprequest.html b/packages/node_modules/@node-red/nodes/locales/en-US/io/21-httprequest.html index 703ab3ff0..fcc852c65 100644 --- a/packages/node_modules/@node-red/nodes/locales/en-US/io/21-httprequest.html +++ b/packages/node_modules/@node-red/nodes/locales/en-US/io/21-httprequest.html @@ -61,6 +61,7 @@ url to be constructed using values of the incoming message. For example, if the url is set to example.com/{{{topic}}}, it will have the value of msg.topic automatically inserted. Using {{{...}}} prevents mustache from escaping characters like / & etc.

+

The node can optionally automatically encode msg.payload as query string parameters for a GET request, in which case msg.payload has to be an object.

Note: If running behind a proxy, the standard http_proxy=... environment variable should be set and Node-RED restarted, or use Proxy Configuration. If Proxy Configuration was set, the configuration take precedence over environment variable.

Using multiple HTTP Request nodes

In order to use more than one of these nodes in the same flow, care must be taken with From 63829b63822a159951b4d9a11c264944eac75b11 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Fri, 29 Mar 2019 10:30:11 +0000 Subject: [PATCH 06/11] Ensure mqtt message handlers are tidied up properly on partial deploy --- .../@node-red/nodes/core/io/10-mqtt.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/io/10-mqtt.js b/packages/node_modules/@node-red/nodes/core/io/10-mqtt.js index 83132130d..f6702e902 100644 --- a/packages/node_modules/@node-red/nodes/core/io/10-mqtt.js +++ b/packages/node_modules/@node-red/nodes/core/io/10-mqtt.js @@ -315,7 +315,7 @@ module.exports = function(RED) { } }; - this.unsubscribe = function (topic, ref) { + this.unsubscribe = function (topic, ref, removed) { ref = ref||0; var sub = node.subscriptions[topic]; if (sub) { @@ -323,10 +323,12 @@ module.exports = function(RED) { node.client.removeListener('message',sub[ref].handler); delete sub[ref]; } - if (Object.keys(sub).length === 0) { - delete node.subscriptions[topic]; - if (node.connected) { - node.client.unsubscribe(topic); + if (removed) { + if (Object.keys(sub).length === 0) { + delete node.subscriptions[topic]; + if (node.connected) { + node.client.unsubscribe(topic); + } } } } @@ -430,10 +432,7 @@ module.exports = function(RED) { } this.on('close', function(removed, done) { if (node.brokerConn) { - if (removed) { - // This node has been removed so remove any subscriptions - node.brokerConn.unsubscribe(node.topic,node.id); - } + node.brokerConn.unsubscribe(node.topic,node.id, removed); node.brokerConn.deregister(node,done); } }); From 0f57d1a433f0a469c577b59ce7121408d3347171 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Tue, 2 Apr 2019 21:35:41 +0900 Subject: [PATCH 07/11] Fix encoding menu in file node --- .../@node-red/nodes/core/storage/50-file.html | 11 ++++++++--- .../@node-red/nodes/locales/en-US/messages.json | 1 + .../@node-red/nodes/locales/ja/messages.json | 5 +++-- 3 files changed, 12 insertions(+), 5 deletions(-) mode change 100644 => 100755 packages/node_modules/@node-red/nodes/core/storage/50-file.html diff --git a/packages/node_modules/@node-red/nodes/core/storage/50-file.html b/packages/node_modules/@node-red/nodes/core/storage/50-file.html old mode 100644 new mode 100755 index 85d793cf7..cbf7c9b5c --- a/packages/node_modules/@node-red/nodes/core/storage/50-file.html +++ b/packages/node_modules/@node-red/nodes/core/storage/50-file.html @@ -22,7 +22,7 @@ -

+
@@ -246,8 +246,13 @@ }); encSel.val(node.encoding); $("#node-input-overwriteFile").on("change",function() { - if (this.value === "delete") { $(".form-row-file-write-options").hide(); } - else { $(".form-row-file-write-options").show(); } + if (this.value === "delete") { + $(".form-row-file-write-options").hide(); + $(".form-row-file-encoding").hide(); + } else { + $(".form-row-file-write-options").show(); + $(".form-row-file-encoding").show(); + } }); } }); diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json index d18708e41..82e466fdb 100755 --- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json @@ -859,6 +859,7 @@ "breaklines": "Break into lines", "filelabel": "file", "sendError": "Send message on error (legacy mode)", + "encoding": "Encoding", "deletelabel": "delete __file__", "utf8String": "UTF8 string", "binaryBuffer": "binary buffer" diff --git a/packages/node_modules/@node-red/nodes/locales/ja/messages.json b/packages/node_modules/@node-red/nodes/locales/ja/messages.json index 82b622b06..156612108 100755 --- a/packages/node_modules/@node-red/nodes/locales/ja/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/ja/messages.json @@ -143,7 +143,7 @@ "filterCurrent": "現在のフロー", "debugNodes": "debugノード", "clearLog": "ログを削除", - "filterLog": "ログのフィルタリング", + "filterLog": "ログのフィルタリング", "openWindow": "新しいウィンドウで開く" }, "messageMenu": { @@ -398,7 +398,7 @@ "status": "状態コード", "headers": "ヘッダ", "other": "その他", - "paytoqs" : "msg.payloadをクエリパラメータに追加", + "paytoqs": "msg.payloadをクエリパラメータに追加", "utf8String": "UTF8文字列", "binaryBuffer": "バイナリバッファ", "jsonObject": "JSONオブジェクト", @@ -857,6 +857,7 @@ "breaklines": "行へ分割", "filelabel": "file", "sendError": "エラーメッセージを送信(互換モード)", + "encoding": "文字コード", "deletelabel": "delete __file__", "utf8String": "UTF8文字列", "binaryBuffer": "バイナリバッファ" From fbec803129a0a065deebb3d76e7165861594bd0b Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 2 Apr 2019 14:06:37 +0100 Subject: [PATCH 08/11] Use userObj.username and not .name for ssh key lookup Closes #2109 --- .../runtime/lib/storage/localfilesystem/projects/Project.js | 4 ++-- .../runtime/lib/storage/localfilesystem/projects/git/index.js | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/Project.js b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/Project.js index 86fd13775..7ba3bd2f3 100644 --- a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/Project.js +++ b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/Project.js @@ -35,8 +35,8 @@ var authCache = require("./git/authCache"); // TODO: DRY - red/api/editor/sshkeys ! function getSSHKeyUsername(userObj) { var username = '__default'; - if ( userObj && userObj.name ) { - username = userObj.name; + if ( userObj && userObj.username ) { + username = userObj.username; } return username; } diff --git a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/index.js b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/index.js index 05780f392..b9f114698 100644 --- a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/index.js +++ b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/index.js @@ -76,6 +76,7 @@ function runGitCommand(args,cwd,env,emit) { }) } function runGitCommandWithAuth(args,cwd,auth,emit) { + log.trace("runGitCommandWithAuth "+JSON.stringify(auth).replace(/("pass.*?"\s*:\s*").+?"/g,'$1[hidden]"')); return authResponseServer(auth).then(function(rs) { var commandEnv = clone(process.env); commandEnv.GIT_ASKPASS = path.join(__dirname,"node-red-ask-pass.sh"); @@ -93,6 +94,7 @@ function runGitCommandWithAuth(args,cwd,auth,emit) { } function runGitCommandWithSSHCommand(args,cwd,auth,emit) { + log.trace("runGitCommandWithSSHCommand "+JSON.stringify(auth).replace(/("pass.*?"\s*:\s*").+?"/g,'$1[hidden]"')); return sshResponseServer(auth).then(function(rs) { var commandEnv = clone(process.env); commandEnv.SSH_ASKPASS = path.join(__dirname,"node-red-ask-pass.sh"); From f11d4ccd458c4619c8ba0bd4e5069ae15fef9549 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 2 Apr 2019 16:45:30 +0100 Subject: [PATCH 09/11] Switch media-typer to content-type module Fixes #2122 #2123 --- package.json | 2 +- packages/node_modules/@node-red/nodes/core/io/21-httpin.js | 2 +- packages/node_modules/@node-red/nodes/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 7d6775651..6c8b86bca 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "body-parser": "1.18.3", "cheerio": "0.22.0", "clone": "2.1.2", + "content-type": "1.0.4", "cookie": "0.3.1", "cookie-parser": "1.4.4", "cors": "2.8.5", @@ -47,7 +48,6 @@ "js-yaml": "3.13.0", "json-stringify-safe": "5.0.1", "jsonata": "1.6.4", - "media-typer": "1.0.1", "memorystore": "1.6.1", "mime": "2.4.0", "mqtt": "2.18.8", diff --git a/packages/node_modules/@node-red/nodes/core/io/21-httpin.js b/packages/node_modules/@node-red/nodes/core/io/21-httpin.js index 43e25b56f..7e90478f7 100644 --- a/packages/node_modules/@node-red/nodes/core/io/21-httpin.js +++ b/packages/node_modules/@node-red/nodes/core/io/21-httpin.js @@ -22,7 +22,7 @@ module.exports = function(RED) { var getBody = require('raw-body'); var cors = require('cors'); var onHeaders = require('on-headers'); - var typer = require('media-typer'); + var typer = require('content-type'); var isUtf8 = require('is-utf8'); var hashSum = require("hash-sum"); diff --git a/packages/node_modules/@node-red/nodes/package.json b/packages/node_modules/@node-red/nodes/package.json index 47f81d724..7ae62500c 100644 --- a/packages/node_modules/@node-red/nodes/package.json +++ b/packages/node_modules/@node-red/nodes/package.json @@ -18,6 +18,7 @@ "ajv": "6.10.0", "body-parser": "1.18.3", "cheerio": "0.22.0", + "content-type": "1.0.4", "cookie-parser": "1.4.4", "cookie": "0.3.1", "cors": "2.8.5", @@ -29,7 +30,6 @@ "https-proxy-agent": "2.2.1", "is-utf8": "0.2.1", "js-yaml": "3.13.0", - "media-typer": "1.0.1", "mqtt": "2.18.8", "multer": "1.4.1", "mustache": "3.0.1", From fab632da62db650e006ce04dc4b7ec279ed845cd Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 3 Apr 2019 10:11:20 +0100 Subject: [PATCH 10/11] Bump for 0.20.4 --- CHANGELOG.md | 14 ++++++++++++++ package.json | 8 ++++---- packages/node_modules/@node-red/nodes/package.json | 2 +- .../node_modules/@node-red/registry/package.json | 2 +- packages/node_modules/@node-red/util/package.json | 2 +- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be882f9d9..353979198 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +#### 0.20.4: Maintenance Release + +- Switch media-typer to content-type module Fixes #2122 #2123 +- Use userObj.username and not .name for ssh key lookup Closes #2109 +- Ensure mqtt message handlers are tidied up properly on partial deploy +- Update package dependencies +- Update ACE to 1.4.3-src-min-noconflict Fixes #2106 +- Fix creating missing package.json when existing project imported Fixes #2115 +- Allow subflow instance to override env var with falsey values Fixes #2113 +- Prevent wire from normal node to link virtual port Fixes #2114 +- Add explanation to the help text on the new feature to build query string from msg.payload #2116 +- Bump bcrypt to latest +- Add Korean locales files for nodes + #### 0.20.3: Maintenance Release - Do not dynamically add/remove upgrade listener in ws nodes diff --git a/package.json b/package.json index 6c8b86bca..245f70e8d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red", - "version": "0.20.3", + "version": "0.20.4", "description": "A visual tool for wiring the Internet of Things", "homepage": "http://nodered.org", "license": "Apache-2.0", @@ -35,14 +35,14 @@ "cookie-parser": "1.4.4", "cors": "2.8.5", "cron": "1.7.0", - "denque": "1.4.0", + "denque": "1.4.1", "express": "4.16.4", "express-session": "1.15.6", "fs-extra": "7.0.1", "fs.notify": "0.0.4", "hash-sum": "1.0.2", "https-proxy-agent": "2.2.1", - "i18next": "15.0.8", + "i18next": "15.0.9", "iconv-lite": "0.4.24", "is-utf8": "0.2.1", "js-yaml": "3.13.0", @@ -68,7 +68,7 @@ "raw-body": "2.3.3", "request": "2.88.0", "semver": "6.0.0", - "uglify-js": "3.5.2", + "uglify-js": "3.5.3", "when": "3.7.8", "ws": "6.2.1", "xml2js": "0.4.19" diff --git a/packages/node_modules/@node-red/nodes/package.json b/packages/node_modules/@node-red/nodes/package.json index 7ae62500c..b6a00ad9f 100644 --- a/packages/node_modules/@node-red/nodes/package.json +++ b/packages/node_modules/@node-red/nodes/package.json @@ -23,7 +23,7 @@ "cookie": "0.3.1", "cors": "2.8.5", "cron": "1.7.0", - "denque": "1.4.0", + "denque": "1.4.1", "fs-extra": "7.0.1", "fs.notify": "0.0.4", "hash-sum": "1.0.2", diff --git a/packages/node_modules/@node-red/registry/package.json b/packages/node_modules/@node-red/registry/package.json index d66349ead..17a0f6b71 100644 --- a/packages/node_modules/@node-red/registry/package.json +++ b/packages/node_modules/@node-red/registry/package.json @@ -18,7 +18,7 @@ "dependencies": { "@node-red/util": "0.20.3", "semver": "6.0.0", - "uglify-js": "3.5.2", + "uglify-js": "3.5.3", "when": "3.7.8" } } diff --git a/packages/node_modules/@node-red/util/package.json b/packages/node_modules/@node-red/util/package.json index 4aa3813bd..2aae7bc04 100644 --- a/packages/node_modules/@node-red/util/package.json +++ b/packages/node_modules/@node-red/util/package.json @@ -16,7 +16,7 @@ ], "dependencies": { "clone": "2.1.2", - "i18next": "15.0.8", + "i18next": "15.0.9", "json-stringify-safe": "5.0.1", "jsonata": "1.6.4", "when": "3.7.8" From 6175fecdd8857eb1edb5e30f3dcb873e5576c122 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 3 Apr 2019 10:12:12 +0100 Subject: [PATCH 11/11] Update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 353979198..79847be90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,14 @@ - Use userObj.username and not .name for ssh key lookup Closes #2109 - Ensure mqtt message handlers are tidied up properly on partial deploy - Update package dependencies +- Fix encoding menu in file node #2125 - Update ACE to 1.4.3-src-min-noconflict Fixes #2106 - Fix creating missing package.json when existing project imported Fixes #2115 - Allow subflow instance to override env var with falsey values Fixes #2113 - Prevent wire from normal node to link virtual port Fixes #2114 - Add explanation to the help text on the new feature to build query string from msg.payload #2116 - Bump bcrypt to latest -- Add Korean locales files for nodes +- Add Korean locales files for nodes #2100 #### 0.20.3: Maintenance Release